Releases: felixSchl/neodoc
v2.0.0
Changes
- BREAKING CHANGE - Fix [#94]: Long options no longer bind
implicit arguments through substring matches.
Before this change, the programusage: foo --foo=<arg>
allowed
passing in--foobar
, which would yield--foo => "bar"
, which
was found to have undesirable side-effects as explored in [#94].
Since changing this behavior has not only follow on effects for
users of neodoc, but also users of users, a major version bump
was necessary.
v1.4.0
v1.3.0
New features
- It is now possible to capture any unknown options, while still validating
known options and positional/command arguments. Withopts.allowUnknown
toggled on, any unknown options are collected into a special key "?" in the
output mapping. Note that, unknown input is collected "verbatim", i.e. as it
was passed on the command line. This closes #42.
v1.2.0
This release focused mostly on performance. While performance is drastically
improved with this release, it won't be the end of things in a continous effort
to get neodoc as snappy as possible, while retaining it's strong parsing
capabilities and feature set.
Changes
- Update to purescript 0.10.x
- Improve overall performance #81
- To give an idea, the uglify example now runs about 140ms faster than
before! - Optimize large parts of the code-base (lexer, solver, arg-parser)
- Pre-trim descriptions section to speed up descriptions lexing
- Let go of purescript-parsing, use own parser everywhere
- Avoid partial function application where feasible, especially if function
takes many arguments. - Optimize many parser combinators to work especially well with chars
- Run the compiled output through the closure compiler to bring down require
times. This comes at the cost of readable output, but provides a rough
20ms boost requiring neodoc, which is now around 50ms on the machines I
tested on. Still not ideal, maybe we can shed more bloat.
- To give an idea, the uglify example now runs about 140ms faster than
v1.1.0
Fix
- Fix #72: Add special flags to spec implicitely
Changes
- Improve special flags behavior with
opts.dontExit
. Instead of just returning
a string, return the output and add a special key.help
foropts.helpFlags
and.version
foropts.versionFlags
, respectively. - Allow dots in option names
- Improve
OptionAlias
JS representation. It is now just a string. This makes
it easy to write, read and validateopts.helpFlags
andopts.versionFlags
.
v1.0.2
v1.0.1
v1.0.0
🎉 The first major release of neodoc.
Where the project is at
As a run up to v1, I decided to spend a lot of my time refactoring the code-base
for various reasons. Primarily the core data structures that were employed prior
to the refactor were insufficiently flexible and, looking back, clearly the
wrong choice. The new core data structure, which resembles a tree, is by far
more elegant and flexible, allows transformations and traversals and is more
obviously "correct". Secondly, I acknowledged that the code was hard to follow
and hindered adoption / contributors from getting into the code base. The most
important pieces of the codebase are now documented and hopefully approachable
enough.
New features
- Neodoc now sports a couple of hooks that allow devs to hook into the
transformation of the spec. Seeopts.transforms
in the README for more
information. --version
will now simply return the version as a string ifopts.dontExit
is true.--help
will now simply return the help as a string ifopts.dontExit
is
true.- A new option
options.repeatableOptions
is introduced that allows consuming
excess options. Many command line utilities do not care about excess options,
so now neodoc can be told to not care either. This means that after
successfully parsing a bunch of options, any option may-reoccur again. - Better error reporting. The parser now tracks the deepest error across all
branches, making for more intuitive error messages. - The spec is now being canonicalised internally which helps create (a) better
error messages and (b) to speed up the parser. - considerably better performance under difficult configurations and edge
cases, i.e. when combiningopts.laxPlacement
withopts.requiredFlags
and
so on.
Changes
- The "specification" format has changed drastically. If you've been using
neodoc.parse
, it's output is now entirely different and likewise the input
to run expects the newneodoc.parse
output. If you used this method to
change the spec on-the-fly, you should have a look at the new
opts.transforms
option which allows you to easily hook into the
transformation of the neodoc spec.
Internals
- Major overhaul of the internals. The core data structures have changed and
are now more composable.- The arg parser has been rewritten from the ground up, with next to none code
sharing. The goal was a more efficient, simpler and better documented
solution that is easier to reason about and debug. - Instead of representing a group as an argument, we now have a
Layout
data
type which looks more like a classical tree:
haskell data Layout a = Group IsOptional IsRepeatable Branches | Elem a
It turns out that this structure holds true throught all the various stages
of transformation. - There's finally a
Spec
datatype that formalises what a specification is:
haskell type Branch a = NonEmpty List a type Toplevel a = List (Branch a) newtype Spec a = Spec { program :: String , layouts :: NonEmpty List (Toplevel a) , descriptions :: List Description , helpText :: String , shortHelp :: String }
- A custom parser monad for arg-parsing that does not use monad
transformers. It enables neodoc to better handle errors and should generally
run faster. It allows the parser to keep read-only state, state that
isolated in alternatives and when backtracking, as well as state that is
"mutable", i.e. state that survives failures. In terms of running faster,
the worst case that previously required adding in a cache now runs fine and
the cache was removed. - Branches in groupings as well as top-levels are now encoded at the type
level asNonEmpty
- Move away from records to ADTs for speed and ease of use in many scenarios
- Use
AsForeign
andIsForeign
for FFI needs - Improve test bed readability all over, make it more easy to add tests
- Overall add more comments and document entire modules in an effort to make
the code "contributable"
- The arg parser has been rewritten from the ground up, with next to none code
v0.10.1
Fixes
-
Fix #70 - Ignore ANSI escape codes in parser. This allows the neodoc to
be colored. For example:neodoc.run(` ${chalk.blue('Usage:')} prog <command> [<args>...] `);
Thanks @matthewmueller for reporting
-
Fix #71 - Do not trim help text. This allows the developer to keep some left
padding on the help text. The leading and trailing newlines are still removed,
however, in order to make working with JS template strings easy.Thanks @matthewmueller for reporting
-
Fix optional positionals in lax-placement mode.
For example:
usage: prog [foo] -a
Would fail:-a foo
before this patch because[foo]
simply fails at-a
and gets omitted. The added tests cover these cases. -
Fix 'stop-at' not working in groups in certain cases
v0.10.0
New features
- Fix [#48] - Implement special support for
--help
and--version
. If--help
is encountered, print the original, full help text. The flags that trigger
this behavior can be overridden usingoptions.helpFlags
(ex.{ helpFlags: ["-h"] }
). To disable this behavior, pass it the empty list. Likewise, if
--version
is met, print the version of the CLI. The version can be
explicitly set viaoptions.version
, but neodoc will otherwise fall back to
look for a package.json of the executing main module (seerequire.main
).
The flags that trigger this behavior can be overriden using
options.versionFlags
. Again, use the empty list to turn this behavior of
entirely.
Changes
-
Only parse repeating option-arguments repeatedly if the first argument is
NOT bound explicitly. Ex:usage: prog --foo=<bar>... qux $ prog --foo=10 qux => {"--foo": [10], "qux": true } $ prog --foo 10 qux => error! missing 'qux' (got consumed by --foo).
Fixes
- Fix case where parsing became extremely slow when
options.laxPlacement
was
enabled.