This file describes changes in CLAP codebase, usage, public and private API and documentation. It's mostly useful for developers who use the CLAP library.
- fix: bug fixes,
- upd: updated feature,
- new: new features,
- dep: deprecated features (scheduled for removal in next n versions),
- rem: removed features,
This long awaited release improves both documentation and code. Documentation was expanded with updated examples and README-style articles explaining how to use CLAP.
On the code front, there are several imporvements.
From day-one CLAP supported short and long option names. People who use a piece of software frequently usually memorise short versions of commonly used options, but for a very long time CLAP did not provide a way to shorten the command names. This mean that even long command names must have been written in full:
~]$ program some-nested command-name that-is-too --verbose --and long-to-type --foo --with spam
Now, the above invocation can be shortened to just:
~]$ program s c t --verbose --and l --foo --with spam
CLAP detects that a mode has nested modes, and automatically expands the shortened command name.
Expansion fails if the command name is ambiguous, i.e. when more two or more subcommands exist (e.g. foo
and far
) and
both share a common prefix that, and only this prefix was given to CLAP.
Detailed option help (program help command subcommand --option
) now renders all help available for requested option.
CLAP provides a way to describe individual option arguments, and provide more detailed help messages.
Use argument-name:argument-type
syntax when definition option arguments:
{
"short": "p",
"long": "phone-no",
"arguments": ["use +NN.AAABBBCCC format:str"]
}
This release candidate adds two more parameters to the already available palette of customization options for CLAP options.
Note that however promising the defaults
option may sound it can currently be only used to provide values
for options added by CLAP (when running through implies
hooks).
Support for omitting arguments was not coded to keep the complexity of the parser on an acceptable level.
Said complexity has to be decreased nevertheless, because the implies
hook that became available to developers caused
the complexity level of parser to raise considerably.
Even though, optional arguments should be requested as operands - it is safer and easier to manage them this way.
This release candidate is not big in terms of List of Changes, but is huge in terms of functionality added.
-
new:
implies
parameter inclap.option.Option
, -
new:
defaults
parameter inclap.option.Option
, -
new:
conflicts()
method inclap.option.Option
, -
fix: checker can now correctly detect more cases when not enough arguments are provided to an option (i.e. instead of rising the invalid-type exception it will raise the missing-argument exception when the item that caused it in the first place is an option accepted by parser),
-
fix: fixed bug introduced in 0.9.6 which cause help runner to crash if help was requested by option,
-
upd: examples are no longer included in the full rendering of help screen, they need to be separately viewed,
All deprecated features were removed from code.
-
upd:
addMode()
method ofRedMode
renamed toaddCommand()
, -
upd:
hasmode()
method ofRedMode
renamed tohasCommand()
, -
upd:
getmode()
method ofRedMode
renamed togetCommand()
, -
upd:
modes()
method ofRedMode
renamed tocommands()
, -
upd:
mode
parameter inclap.builder.export()
function renamed tocommand
, -
upd:
RedMode
class renamed toRedCommand
, -
upd:
UnrecognizedModeError
renamed toUnrecognizedCommandError
, -
rem: removed support for features deprecated in 0.9.x line,
-
rem:
readfile()
andreadjson()
functions were removed fromclap.builder
module,
It seems like the 0.9.x line is about to stay for a bit longer than I expected. However, it does not mean there are no improvements in the code.
One new feature is the "examples"
key in "doc"
field of the top-level command.
Apart from usage, which describes more abstract syntax, the examples are used to
provide real-life invocations of the program.
This field may change in future (currently it is built the same way as usage) to incorporate
brief explanation what does the line do:
"examples": [
{
"line": "foo --bar baz -xy",
"desc": "this line does something"
}
]
Would yield something akin to:
Examples:
program foo --bar baz -xy
this line does something
This release brings another new feature: Help Runner.
It is an object which takes parsed UI and analyses it to tell whether user wanted to see help
screen or not; in either case it will act accordingly, and report the outcome to the program
developer (in code).
As such, it shifts the burden of managing help screens yet further away from the developers so
that the library can do even more of the heavy lifting.
Currently, the help runner does not offer many customization hooks (only option-triggers can be adjusted), yet it comes with sane defaults:
-h
and--help
options trigger help screen display,help
as first (second, technically) command triggers help display.
The help runner can be more easily integrated into programs using Builder
object using its insertHelpCommand()
method which,
as the name says, inserts a model of help
command into model of UI as a child of main command.
The call looks this way: mode = clap.builder.Builder(model).insertHelpCommand().build().get()
Apart from these new features, there is a deprecation also: verb commands (akin to Git's commit
, pull
or stash
) are no longer modes
in JSON
representations of UIs, but are commands
.
There is a warning about this in code so CLAP will yell about UIs that are not upgraded.
-
new:
examples
key indoc
field of JSON UI representations, **examples should only be set in doc for the TOP LEVEL command **, -
new:
HelpRunner
object inclap.helper
module, -
new:
top()
method inParsedUI
, -
new:
usage()
andexamples()
methods inHelper
, -
new:
insertHelpCommand()
method added toBuilder
, which makes integration with Help Runner easier and provides unified help interface for users of CLAP library, -
upd:
Helper
was refactored a little bit, -
upd: parser undergone major refactoring, actual parsing logic has been broken down into several smaller, easier to understand methods; maybe a separate class should be created as
Parser
seems to have too much responsibility, -
dep:
modes
field in JSON UI representations, changed tocommands
, -
dep:
gen
method inHelper
, usefull
instead, -
rem:
get()
method fromParser
, -
rem:
getoperands()
method fromParser
, -
rem:
clap_typehandler.py
method of setting typehandlers for CLAP,
CLAP is now building better help screens, greatest improvement can be seen in how descriptions of commands (sub modes) are rendered, i.e. the name of the submode is followed by a two-space break and a description of it so users can quickly check what command they want to use.
This release also fixes a bug which caused an error about unrecognized option to be incorrectly raised.
-
new: command descriptions in abbreviated help screens,
-
new: slightly refactored help screen generator and help screens' look is slightly different,
-
new: new way of building doc in JSON, added
"doc"
field (with"help"
and"usage"
keys), -
dep:
"help":
key of mode is moved to"doc"
field, -
fix: unrecognized option error incorrectly raised when aliases are passed,
CLAP is able to build full or abbreviated help screens. Abbreviated help screens show help only for top-level mode, i.e. its options - local and global - and commands. Full help screen displays help for all sub-commands.
Also, in this release CLAP code was moved back from redclap/
to clap/
.
Finally, 0.9.4 is most probably last release from 0.9.x line and the next version of CLAP will mark the beginning of the 0.10.x line.
-
new: full help screens,
-
new: abbreviated help screens,
-
fix: checker now correctly handles one more case of unrecognized option,
CLAP can build UIs from JSON descriptions and export UIs built directly in Python to JSON (exporting is work-in-progress and needs more testing, though).
Another feature implemented in this release is help screen generation, but currently to only one level of depth. This will be fixed in later releases.
-
new: building interfaces from JSON,
-
new: exporting interfaces written in Python to JSON,
-
new: generating help screens,
-
new: more fluent interface for formatter,
-
fix: bug in parser, which returned items for nested mode even if mode accepted no child modes,
-
rem: old CLAP code,
-
rem: old CLAP tests,
-
rem: old checker code from RedCLAP module,
This is the first version of RedCLAP, i.e. Redesigned CLAP and is not backwards compatible with previous release. However, it brings major improvements to the code.
Notable new features are operand ranges, a method for designer to set a range of operands accepted by CLAP and let CLAP validate them, and plural options - which tell CLAP to not overwrite the previously found value of an options but rather build a list of all values passed (in case of options that take no arguments - to count how many times they occurred). This provides for greater control over user input.
Another feature is just a huge bugfix. Nested modes are finally working properly. The can be nested ad infinitum, all can have operands with set ranges, all can have global and local options.
Successful improvement was done on the front of UI building.
Global options can now be added freely - after or before modes are added and are propagated to nested modes after the
(who would have guessed) .propagate()
method is called on the top level mode.
-
new:
DESIGN.markdown
file has been added, -
new: development moved to
redclap/
directory whileclap/
contains old, untouched code from 0.9.1 release, -
new: operand ranges,
-
new: new behavior of
.get()
method of parsed UI, -
new: plural options,
-
fix: nested modes,
-
fix: global options propagation,
-
rem: old JSON UIs must be ported to new JSON spec,
-
rem: CLAP v0.9.2 changed Python APIs for building UIs,
Deprecated module clap.modes
was removed.
If you haven't changed your code when update 0.9.0 arrived you must do it now.
Now, clap.parser.Parser
supports both single and
nested parsers.
- rem:
clap.modes
module was removed,
From this version clap.modes.Parser
is deprecated - single and nested parsers were unified and
now you can use clap.parser.Parser
with modes (the API was copied from clap.modes.Parser
).
-
new:
clap.parser.Parser().finalize()
method which will define the parser and parse it via a single call, -
new:
clap.shared
module containing functions and variables shared between various CLAP modules, -
new:
clap.base.Base
,clap.parser.Parser
andclap.modes.Parser
got newgetoperands()
method, -
new:
clap.base.Base
andclap.parser.Parser
have__eq__()
method overloaded (comparing with==
will be now possible), -
upd: better help message generation,
-
upd: moved option regular expression patterns from
clap.base
toclap.shared
, -
upd: moved
lookslikeopt()
function fromclap.base
toclap.shared
, -
upd: information about default parser is now private,
-
rem:
lines
parameter fromHelper().help()
method - now it returns only list of strings,
- fix: type handlers are applied also to nested parsers,
- fix: fixed bug which prevented building JSON interfaces with local mode-options,
- new: support for non-global options given to modes (helps writing modes which act more like parsers),
This version is not backwards compatible! You'll need to fix your JSON and/or Python built interfaces
for the new stuff - needs
was renamed to wants
, NeededOptionNotFoundError
was renamed to WantedOption...
.
-
upd: order in which validating methods are called (conflicts are checked just after unrecognized options to prevent typing a lot and getting an error about conflicting options),
-
upd:
needs
arguments renamed towants
in all places, -
upd:
clap.checker.Checker._checkneeds
renamed toclap.checker.Checker._checkwants
, -
upd:
clap.errors.NeededOptionNotFoundError
renamed toclap.errors.WantedOptionNotFoundError
, -
new:
BuilderError
inclap.errors
, raised when builder loads invalid JSON -
new:
UIDesignError
inclap.errors
, raised when one option requires another option which is undefined, -
new:
parser
andmodes
arguments inBuilder.build()
for forcing build of given type, keep in mind that they are provided as a debug feature for JSON interfaces (type-detection should work without them), -
new:
clap.helper.Helper
which can build help information from parsers, -
new:
help
argument for options,
This version fixes type-detection issues with JSON-based interfaces (well, they are still alpha/beta). Pure Python API is free from these bugs.
This version brings support for creating nested modes in JSON interfaces.
Apart from this, some refactoring had been done in clap/builder.py
.
clap.builder.ModesParser()
is no longer there - only object that is needed
to build an interface is clap.builder.Builder()
.
Builder functions, and element-type recognition functions, are exposed so you can
use them directly with no need to initialize builder object.
However, I don't see a need for this - if you would want to translate dicts and
lists to interfaces and bother with all the stuff around them it's easier to just
code the whole interface by hand. This functionality will never be removed.
-
new:
isparser()
,isoption()
andismodesparser()
functions inclap.builder
, -
new:
buildparser()
andbuildmodesparser()
functions inclap.builder
, -
upd:
clap.builder.Builder()
is no longer limited to simple parsers - it can now build also single- and nested-modes parsers. -
rem:
clap.builder.ModesParser()
is removed and it's functionality is now inclap.builder.Builder()
This version debugs stuff (I hope) and let's you create simple-parser interfaces using
clap.builder.Builder()
object (without need for clap.builder.Parser()
.
-
new:
clap.builder.Builder().build()
let's you build simple-parser interfaces, -
new:
clap.builder.Builder()._applyhandlersto()
method returns parser with applied type handlers, -
rem:
clap.builder.Parser()
object is removed,
This version brings support for creating interfaces using JSON.
- new:
clap.builder
module containingParser()
andModesParser()
objects used for building interfaces,
This version is capable of having nested modes, e.g. syntax like foo bar baz --some --fancy options --after --this
.
Such behavior needed some changes in code to be done and this resulted in check()
method of modes.Parser()
automatically calling define before any actual checking is done.
Notice: it's possible that in version 0.7.2 modes.Parser()
will be renamed to prevent it being mistaken for parser.Parser()
and
to improve accuracy of error messages.
-
fix: fixed bug in
clap.modes.Parser().addOption()
(I forgot to port it to the new version of options) -
new:
_append()
method onclap.modes.Parser()
-
new: you can now nest modes,
-
new:
_getarguments()
method inclap.base.Base()
-
upd: there is no need to call
define()
beforecheck()
onmodes.Parser()
- the latter automatically calls the former, -
upd:
type()
now returns empty list if option takes no arguments,
Warning: this release is not backwards compatible, you'll need to port your software to it. However, only small adjustments will be needed and only the in part of the API changes and out remains the same (not quite, it is more powerful now).
-
fix: fixed bug in
base.Base._getinput()
which caused it to return whole argv when it should return empty list -
new: it is possible to specify multiple arguments for an option (defined as a list, returned as a tuple of arguments),
-
upd:
argument
parameter renamed toarguments
in all methods and functions,
-
fix: fixed bug in
Parser._checkneeds()
which causedneeds
param to behave likerequires
-
fix: fixed bug in
Parser._checkneeds()
which caused it to raise an exception if parameterneeds
was empty list, -
upd: updated regular expressions used for option string recognition,
-
new:
clap/base.py
module, -
new:
clap/checker.py
module, -
new: first test suite added,
-
rem:
hint
parameter is removed from all CLAP components,
- upd:
modes.Modes()
renamed tomodes.Parser()
- new:
_getinput()
method inparser.Parser()
added another security layer to checks
- new:
required
optional argument inclap.Parser.add()
, if passed and option is not found in input whencheck()
ing error is raised, - new:
gethint()
method inclap.Parser
,
-
upd: if option requires no argument
None
is returned instead of raisingTypeError
-
fix:
-
new: