mirror of
https://github.com/CLIUtils/CLI11.git
synced 2025-05-07 23:33:52 +00:00
style: add mdlint
This commit is contained in:
parent
f27f6f2070
commit
4698131216
8
.github/CONTRIBUTING.md
vendored
8
.github/CONTRIBUTING.md
vendored
@ -1,8 +1,11 @@
|
||||
# Contributing
|
||||
|
||||
Thanks for considering to write a Pull Request (PR) for CLI11! Here are a few guidelines to get you started:
|
||||
|
||||
Make sure you are comfortable with the license; all contributions are licensed under the original license.
|
||||
|
||||
## Adding functionality
|
||||
|
||||
Make sure any new functions you add are are:
|
||||
|
||||
* Documented by `///` documentation for Doxygen
|
||||
@ -20,10 +23,9 @@ In general, make sure the addition is well thought out and does not increase the
|
||||
* Everything must pass clang-tidy as well, run with `-DCLI11_CLANG_TIDY=ON` (if you set `-DCLI11_CLANG_TIDY_OPTIONS="-fix"`, make sure you use a single threaded build process, or just build one example target).
|
||||
* Your changes must also conform to most of the [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html) rules checked by [cpplint](https://github.com/cpplint/cpplint). For unused cpplint filters and justifications, see [CPPLINT.cfg](/CPPLINT.cfg).
|
||||
|
||||
|
||||
## Pre-commit
|
||||
|
||||
Format is handled by pre-commit. You should install it:
|
||||
Format is handled by pre-commit. You should install it (or use [pipx](https://pypa.github.io/pipx/)):
|
||||
|
||||
```bash
|
||||
python3 -m pip install pre-commit
|
||||
@ -37,7 +39,6 @@ pre-commit run
|
||||
pre-commit run --all-files
|
||||
```
|
||||
|
||||
|
||||
And, if you want to always use it, you can install it as a git hook (hence the name, pre-commit):
|
||||
|
||||
```bash
|
||||
@ -72,6 +73,7 @@ yarn all-contributors add username code,bug
|
||||
Remember to replace the emoji in the readme, being careful not to replace the ones in all-contributors if any overlap.
|
||||
|
||||
Steps:
|
||||
|
||||
* Update changelog if needed
|
||||
* Update the version in `.appveyor.yml` and `include/CLI/Version.hpp`.
|
||||
* Find and replace in README:
|
||||
|
@ -1,5 +1,6 @@
|
||||
ci:
|
||||
autoupdate_commit_msg: "chore(deps): pre-commit.ci autoupdate"
|
||||
autofix_commit_msg: "style: pre-commit.ci fixes"
|
||||
skip:
|
||||
- docker-clang-format
|
||||
|
||||
@ -40,6 +41,12 @@ repos:
|
||||
- id: cmake-format
|
||||
additional_dependencies: [pyyaml]
|
||||
|
||||
- repo: https://github.com/markdownlint/markdownlint
|
||||
rev: v0.11.0
|
||||
hooks:
|
||||
- id: markdownlint
|
||||
args: ["--style=scripts/mdlint_style.rb"]
|
||||
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: disallow-caps
|
||||
|
218
CHANGELOG.md
218
CHANGELOG.md
@ -1,7 +1,4 @@
|
||||
### Version 2.0.1: Single header fix
|
||||
|
||||
The single header file was missing the include guard. #620
|
||||
|
||||
# Changelog
|
||||
|
||||
## Version 2.0: Simplification
|
||||
|
||||
@ -14,9 +11,9 @@ release contains a lot of backend cleanup, including a complete overhaul of the
|
||||
testing system and single file generation system.
|
||||
|
||||
* Built-in config format is TOML compliant now [#435][]
|
||||
* Support multiline TOML [#528][]
|
||||
* Support for configurable quotes [#599][]
|
||||
* Support short/positional options in config mode [#443][]
|
||||
* Support multiline TOML [#528][]
|
||||
* Support for configurable quotes [#599][]
|
||||
* Support short/positional options in config mode [#443][]
|
||||
* More powerful containers, support for `%%` separator [#423][]
|
||||
* Support atomic types [#520][] and complex types natively [#423][]
|
||||
* Add a type validator `CLI::TypeValidator<TYPE>` [#526][]
|
||||
@ -34,14 +31,13 @@ testing system and single file generation system.
|
||||
* Bugfix: fix description of non-configurable subcommands in config [#604][]
|
||||
* Build: support pkg-config [#523][]
|
||||
|
||||
#### Converting from CLI11 1.9:
|
||||
|
||||
* Removed deprecated set commands, use validators instead. [#565][]
|
||||
* The final "defaulted" bool has been removed, use `->capture_default_str()`
|
||||
instead. Use `app.option_defaults()->always_capture_default()` to set this for
|
||||
all future options. [#597][]
|
||||
* Use `add_option` on a complex number instead of `add_complex`, which has been removed.
|
||||
|
||||
> ### Converting from CLI11 1.9
|
||||
>
|
||||
> * Removed deprecated set commands, use validators instead. [#565][]
|
||||
> * The final "defaulted" bool has been removed, use `->capture_default_str()`
|
||||
> instead. Use `app.option_defaults()->always_capture_default()` to set this for
|
||||
> all future options. [#597][]
|
||||
> * Use `add_option` on a complex number instead of `add_complex`, which has been removed.
|
||||
|
||||
[#423]: https://github.com/CLIUtils/CLI11/pull/423
|
||||
[#435]: https://github.com/CLIUtils/CLI11/pull/435
|
||||
@ -67,27 +63,11 @@ testing system and single file generation system.
|
||||
[#605]: https://github.com/CLIUtils/CLI11/pull/605
|
||||
[#606]: https://github.com/CLIUtils/CLI11/pull/606
|
||||
|
||||
### Version 2.0.1: Single header fix
|
||||
|
||||
### Version 1.9.1: Backporting fixes
|
||||
|
||||
This is a patch version that backports fixes from the development of 2.0.
|
||||
|
||||
* Support relative inclusion [#475][]
|
||||
* Fix cases where spaces in paths could break CMake support [#471][]
|
||||
* Fix an issue with string conversion [#421][]
|
||||
* Cross-compiling improvement for Conan.io [#430][]
|
||||
* Fix option group default propagation [#450][]
|
||||
* Fix for C++20 [#459][]
|
||||
* Support compiling with RTTI off [#461][]
|
||||
|
||||
[#421]: https://github.com/CLIUtils/CLI11/pull/421
|
||||
[#430]: https://github.com/CLIUtils/CLI11/pull/430
|
||||
[#450]: https://github.com/CLIUtils/CLI11/pull/450
|
||||
[#459]: https://github.com/CLIUtils/CLI11/pull/459
|
||||
[#461]: https://github.com/CLIUtils/CLI11/pull/461
|
||||
[#471]: https://github.com/CLIUtils/CLI11/pull/471
|
||||
[#475]: https://github.com/CLIUtils/CLI11/pull/475
|
||||
The single header file was missing the include guard. [#620][]
|
||||
|
||||
[#620]: https://github.com/CLIUtils/CLI11/pull/620
|
||||
|
||||
## Version 1.9: Config files and cleanup
|
||||
|
||||
@ -127,11 +107,11 @@ configuration options were added to facilitate a wider variety of apps. GCC
|
||||
* Build: GCC 4.7 is no longer supported, due mostly to GoogleTest. GCC 4.8+ is now required. [#160][]
|
||||
* Build: Restructured significant portions of CMake build system [#394][]
|
||||
|
||||
> ### Converting from CLI11 1.8:
|
||||
> ### Converting from CLI11 1.8
|
||||
>
|
||||
> * Some deprecated methods dropped
|
||||
> - `add_set*` should be replaced with `->check`/`->transform` and `CLI::IsMember` since 1.8
|
||||
> - `get_defaultval` was replaced by `get_default_str` in 1.8
|
||||
> * `add_set*` should be replaced with `->check`/`->transform` and `CLI::IsMember` since 1.8
|
||||
> * `get_defaultval` was replaced by `get_default_str` in 1.8
|
||||
> * The true/false 4th argument to `add_option` is expected to be removed in 2.0, use `->capture_default_str()` since 1.8
|
||||
|
||||
[#160]: https://github.com/CLIUtils/CLI11/pull/160
|
||||
@ -147,7 +127,6 @@ configuration options were added to facilitate a wider variety of apps. GCC
|
||||
[#307]: https://github.com/CLIUtils/CLI11/pull/307
|
||||
[#309]: https://github.com/CLIUtils/CLI11/pull/309
|
||||
[#310]: https://github.com/CLIUtils/CLI11/pull/310
|
||||
[#312]: https://github.com/CLIUtils/CLI11/pull/312
|
||||
[#313]: https://github.com/CLIUtils/CLI11/pull/313
|
||||
[#317]: https://github.com/CLIUtils/CLI11/pull/317
|
||||
[#318]: https://github.com/CLIUtils/CLI11/pull/318
|
||||
@ -155,6 +134,7 @@ configuration options were added to facilitate a wider variety of apps. GCC
|
||||
[#325]: https://github.com/CLIUtils/CLI11/pull/325
|
||||
[#333]: https://github.com/CLIUtils/CLI11/pull/333
|
||||
[#336]: https://github.com/CLIUtils/CLI11/pull/336
|
||||
[#341]: https://github.com/CLIUtils/CLI11/pull/341
|
||||
[#342]: https://github.com/CLIUtils/CLI11/pull/342
|
||||
[#348]: https://github.com/CLIUtils/CLI11/pull/348
|
||||
[#349]: https://github.com/CLIUtils/CLI11/pull/349
|
||||
@ -173,6 +153,25 @@ configuration options were added to facilitate a wider variety of apps. GCC
|
||||
[#394]: https://github.com/CLIUtils/CLI11/pull/394
|
||||
[#400]: https://github.com/CLIUtils/CLI11/pull/400
|
||||
|
||||
### Version 1.9.1: Backporting fixes
|
||||
|
||||
This is a patch version that backports fixes from the development of 2.0.
|
||||
|
||||
* Support relative inclusion [#475][]
|
||||
* Fix cases where spaces in paths could break CMake support [#471][]
|
||||
* Fix an issue with string conversion [#421][]
|
||||
* Cross-compiling improvement for Conan.io [#430][]
|
||||
* Fix option group default propagation [#450][]
|
||||
* Fix for C++20 [#459][]
|
||||
* Support compiling with RTTI off [#461][]
|
||||
|
||||
[#421]: https://github.com/CLIUtils/CLI11/pull/421
|
||||
[#430]: https://github.com/CLIUtils/CLI11/pull/430
|
||||
[#450]: https://github.com/CLIUtils/CLI11/pull/450
|
||||
[#459]: https://github.com/CLIUtils/CLI11/pull/459
|
||||
[#461]: https://github.com/CLIUtils/CLI11/pull/461
|
||||
[#471]: https://github.com/CLIUtils/CLI11/pull/471
|
||||
[#475]: https://github.com/CLIUtils/CLI11/pull/475
|
||||
|
||||
## Version 1.8: Transformers, default strings, and flags
|
||||
|
||||
@ -201,7 +200,7 @@ Set handling has been completely replaced by a new backend that works as a Valid
|
||||
* Respect `BUILD_TESTING` only if CLI11 is the main project; otherwise, `CLI11_TESTING` must be used [#277][]
|
||||
* Drop auto-detection of experimental optional and boost::optional; must be enabled explicitly (too fragile) [#277][] [#279][]
|
||||
|
||||
> ### Converting from CLI11 1.7:
|
||||
> ### Converting from CLI11 1.7
|
||||
>
|
||||
> * `.add_option(..., true)` should be replaced by `.add_option(...)->capture_default_str()` or `app.option_defaults()->always_capture_default()` can be used
|
||||
> * `app.add_set("--name", value, {"choice1", "choice2"})` should become `app.add_option("--name", value)->check(CLI::IsMember({"choice1", "choice2"}))`
|
||||
@ -237,20 +236,6 @@ Set handling has been completely replaced by a new backend that works as a Valid
|
||||
[#277]: https://github.com/CLIUtils/CLI11/pull/277
|
||||
[#279]: https://github.com/CLIUtils/CLI11/pull/279
|
||||
|
||||
|
||||
## Version 1.7.1: Quick patch
|
||||
|
||||
This version provides a quick patch for a (correct) warning from GCC 8 for the windows options code.
|
||||
|
||||
|
||||
* Fix for Windows style option parsing [#201][]
|
||||
* Improve `add_subcommand` when throwing an exception [#204][]
|
||||
* Better metadata for Conan package [#202][]
|
||||
|
||||
[#201]: https://github.com/CLIUtils/CLI11/pull/201
|
||||
[#202]: https://github.com/CLIUtils/CLI11/pull/202
|
||||
[#204]: https://github.com/CLIUtils/CLI11/pull/204
|
||||
|
||||
## Version 1.7: Parse breakup
|
||||
|
||||
The parsing procedure now maps much more sensibly to complex, nested subcommand structures. Each phase of the parsing happens on all subcommands before moving on with the next phase of the parse. This allows several features, like required environment variables, to work properly even through subcommand boundaries.
|
||||
@ -271,7 +256,7 @@ Passing the same subcommand multiple times is better supported. Several new feat
|
||||
* Cleanup warnings [#191][]
|
||||
* Remove deprecated names: `set_footer`, `set_name`, `set_callback`, and `set_type_name`. Use without the `set_` instead. [#192][]
|
||||
|
||||
> ### Converting from CLI11 1.6:
|
||||
> ### Converting from CLI11 1.6
|
||||
>
|
||||
> * `->short_circuit()` is no longer needed, just remove it if you were using it - raising an exception will happen in the proper place now without it.
|
||||
> * `->add_set*` becomes `->add_mutable_set*` if you were using the editable set feature
|
||||
@ -290,44 +275,17 @@ Passing the same subcommand multiple times is better supported. Several new feat
|
||||
[#199]: https://github.com/CLIUtils/CLI11/pull/199
|
||||
[#200]: https://github.com/CLIUtils/CLI11/pull/200
|
||||
|
||||
## Version 1.6.2: Help-all
|
||||
### Version 1.7.1: Quick patch
|
||||
|
||||
This version fixes some formatting bugs with help-all. It also adds fixes for several warnings, including an experimental optional error on Clang 7. Several smaller fixes.
|
||||
This version provides a quick patch for a (correct) warning from GCC 8 for the windows options code.
|
||||
|
||||
* Fixed help-all formatting [#163][]
|
||||
* Printing help-all on nested command now fixed (App)
|
||||
* Missing space after help-all restored (Default formatter)
|
||||
* More detail printed on help all (Default formatter)
|
||||
* Help-all subcommands get indented with inner blank lines removed (Default formatter)
|
||||
* `detail::find_and_replace` added to utilities
|
||||
* Fixed CMake install as subproject with `CLI11_INSTALL` flag. [#156][]
|
||||
* Fixed warning about local variable hiding class member with MSVC [#157][]
|
||||
* Fixed compile error with default settings on Clang 7 and libc++ [#158][]
|
||||
* Fixed special case of `--help` on subcommands (general fix planned for 1.7) [#168][]
|
||||
* Removing an option with links [#179][]
|
||||
* Fix for Windows style option parsing [#201][]
|
||||
* Improve `add_subcommand` when throwing an exception [#204][]
|
||||
* Better metadata for Conan package [#202][]
|
||||
|
||||
[#156]: https://github.com/CLIUtils/CLI11/issues/156
|
||||
[#157]: https://github.com/CLIUtils/CLI11/issues/157
|
||||
[#158]: https://github.com/CLIUtils/CLI11/issues/158
|
||||
[#163]: https://github.com/CLIUtils/CLI11/pull/163
|
||||
[#168]: https://github.com/CLIUtils/CLI11/issues/168
|
||||
[#179]: https://github.com/CLIUtils/CLI11/pull/179
|
||||
|
||||
|
||||
## Version 1.6.1: Platform fixes
|
||||
|
||||
This version provides a few fixes for special cases, such as mixing with `Windows.h` and better defaults
|
||||
for systems like Hunter. The one new feature is the ability to produce "branded" single file output for
|
||||
providing custom namespaces or custom macro names.
|
||||
|
||||
* Added fix and test for including Windows.h [#145][]
|
||||
* No longer build single file by default if main project, supports systems stuck on Python 2.6 [#149][], [#151][]
|
||||
* Branding support for single file output [#150][]
|
||||
|
||||
[#145]: https://github.com/CLIUtils/CLI11/pull/145
|
||||
[#149]: https://github.com/CLIUtils/CLI11/pull/149
|
||||
[#150]: https://github.com/CLIUtils/CLI11/pull/150
|
||||
[#151]: https://github.com/CLIUtils/CLI11/pull/151
|
||||
[#201]: https://github.com/CLIUtils/CLI11/pull/201
|
||||
[#202]: https://github.com/CLIUtils/CLI11/pull/202
|
||||
[#204]: https://github.com/CLIUtils/CLI11/pull/204
|
||||
|
||||
## Version 1.6: Formatting help
|
||||
|
||||
@ -349,7 +307,6 @@ Changes to the help system (most normal users will not notice this):
|
||||
* Added getters for the missing parts of options (help no longer uses any private parts).
|
||||
* Help flags now use new `short_circuit` property to simplify parsing. [#121][]
|
||||
|
||||
|
||||
New for Config file reading and writing [#121][]:
|
||||
|
||||
* Overridable, bidirectional Config.
|
||||
@ -360,7 +317,6 @@ New for Config file reading and writing [#121][]:
|
||||
* Added `ConfigItem`.
|
||||
* Added an example of a custom config format using [nlohmann/json]. [#138]
|
||||
|
||||
|
||||
Validators are now much more powerful [#118][], all built in validators upgraded to the new form:
|
||||
|
||||
* A subclass of `CLI::Validator` is now also accepted.
|
||||
@ -413,33 +369,43 @@ Backend and testing changes:
|
||||
|
||||
[nlohmann/json]: https://github.com/nlohmann/json
|
||||
|
||||
### Version 1.5.4: Optionals
|
||||
This version fixes the optional search in the single file version; some macros were not yet defined when it did the search. You can define the `CLI11_*_OPTIONAL` macros to 0 if needed to eliminate the search.
|
||||
### Version 1.6.1: Platform fixes
|
||||
|
||||
### Version 1.5.3: Compiler compatibility
|
||||
This version fixes older AppleClang compilers by removing the optimization for casting. The minimum version of Boost Optional supported has been clarified to be 1.58. CUDA 7.0 NVCC is now supported.
|
||||
This version provides a few fixes for special cases, such as mixing with `Windows.h` and better defaults
|
||||
for systems like Hunter. The one new feature is the ability to produce "branded" single file output for
|
||||
providing custom namespaces or custom macro names.
|
||||
|
||||
### Version 1.5.2: LICENSE in single header mode
|
||||
* Added fix and test for including Windows.h [#145][]
|
||||
* No longer build single file by default if main project, supports systems stuck on Python 2.6 [#149][], [#151][]
|
||||
* Branding support for single file output [#150][]
|
||||
|
||||
This is a quick patch release that makes LICENSE part of the single header file, making it easier to include. Minor cleanup from codacy. No significant code changes from 1.5.1.
|
||||
[#145]: https://github.com/CLIUtils/CLI11/pull/145
|
||||
[#149]: https://github.com/CLIUtils/CLI11/pull/149
|
||||
[#150]: https://github.com/CLIUtils/CLI11/pull/150
|
||||
[#151]: https://github.com/CLIUtils/CLI11/pull/151
|
||||
|
||||
### Version 1.5.1: Access
|
||||
### Version 1.6.2: Help-all
|
||||
|
||||
This patch release adds better access to the App programmatically, to assist with writing custom converters to other formats. It also improves the help output, and uses a new feature in CLI11 1.5 to fix an old "quirk" in the way unlimited options and positionals interact.
|
||||
This version fixes some formatting bugs with help-all. It also adds fixes for several warnings, including an experimental optional error on Clang 7. Several smaller fixes.
|
||||
|
||||
* Make mixing unlimited positionals and options more intuitive [#102][]
|
||||
* Add missing getters `get_options` and `get_description` to App [#105][]
|
||||
* The app name now can be set, and will override the auto name if present [#105][]
|
||||
* Add `(REQUIRED)` for required options [#104][]
|
||||
* Print simple name for Needs/Excludes [#104][]
|
||||
* Use Needs instead of Requires in help print [#104][]
|
||||
* Groups now are listed in the original definition order [#106][]
|
||||
|
||||
[#102]: https://github.com/CLIUtils/CLI11/issues/102
|
||||
[#104]: https://github.com/CLIUtils/CLI11/pull/104
|
||||
[#105]: https://github.com/CLIUtils/CLI11/pull/105
|
||||
[#106]: https://github.com/CLIUtils/CLI11/pull/106
|
||||
* Fixed help-all formatting [#163][]
|
||||
* Printing help-all on nested command now fixed (App)
|
||||
* Missing space after help-all restored (Default formatter)
|
||||
* More detail printed on help all (Default formatter)
|
||||
* Help-all subcommands get indented with inner blank lines removed (Default formatter)
|
||||
* `detail::find_and_replace` added to utilities
|
||||
* Fixed CMake install as subproject with `CLI11_INSTALL` flag. [#156][]
|
||||
* Fixed warning about local variable hiding class member with MSVC [#157][]
|
||||
* Fixed compile error with default settings on Clang 7 and libc++ [#158][]
|
||||
* Fixed special case of `--help` on subcommands (general fix planned for 1.7) [#168][]
|
||||
* Removing an option with links [#179][]
|
||||
|
||||
[#156]: https://github.com/CLIUtils/CLI11/issues/156
|
||||
[#157]: https://github.com/CLIUtils/CLI11/issues/157
|
||||
[#158]: https://github.com/CLIUtils/CLI11/issues/158
|
||||
[#163]: https://github.com/CLIUtils/CLI11/pull/163
|
||||
[#168]: https://github.com/CLIUtils/CLI11/issues/168
|
||||
[#179]: https://github.com/CLIUtils/CLI11/pull/179
|
||||
|
||||
## Version 1.5: Optionals
|
||||
|
||||
@ -474,6 +440,34 @@ Other, non-user facing changes:
|
||||
[#99]: https://github.com/CLIUtils/CLI11/pull/99
|
||||
[#100]: https://github.com/CLIUtils/CLI11/pull/100
|
||||
|
||||
### Version 1.5.1: Access
|
||||
|
||||
This patch release adds better access to the App programmatically, to assist with writing custom converters to other formats. It also improves the help output, and uses a new feature in CLI11 1.5 to fix an old "quirk" in the way unlimited options and positionals interact.
|
||||
|
||||
* Make mixing unlimited positionals and options more intuitive [#102][]
|
||||
* Add missing getters `get_options` and `get_description` to App [#105][]
|
||||
* The app name now can be set, and will override the auto name if present [#105][]
|
||||
* Add `(REQUIRED)` for required options [#104][]
|
||||
* Print simple name for Needs/Excludes [#104][]
|
||||
* Use Needs instead of Requires in help print [#104][]
|
||||
* Groups now are listed in the original definition order [#106][]
|
||||
|
||||
[#102]: https://github.com/CLIUtils/CLI11/issues/102
|
||||
[#104]: https://github.com/CLIUtils/CLI11/pull/104
|
||||
[#105]: https://github.com/CLIUtils/CLI11/pull/105
|
||||
[#106]: https://github.com/CLIUtils/CLI11/pull/106
|
||||
|
||||
### Version 1.5.2: LICENSE in single header mode
|
||||
|
||||
This is a quick patch release that makes LICENSE part of the single header file, making it easier to include. Minor cleanup from codacy. No significant code changes from 1.5.1.
|
||||
|
||||
### Version 1.5.3: Compiler compatibility
|
||||
|
||||
This version fixes older AppleClang compilers by removing the optimization for casting. The minimum version of Boost Optional supported has been clarified to be 1.58. CUDA 7.0 NVCC is now supported.
|
||||
|
||||
### Version 1.5.4: Optionals
|
||||
|
||||
This version fixes the optional search in the single file version; some macros were not yet defined when it did the search. You can define the `CLI11_*_OPTIONAL` macros to 0 if needed to eliminate the search.
|
||||
|
||||
## Version 1.4: More feedback
|
||||
|
||||
@ -539,7 +533,7 @@ favorite CLI programs. Error messages and help messages are better and more flex
|
||||
* Single internal arg parse function [#56](https://github.com/CLIUtils/CLI11/pull/56)
|
||||
* Allow options to be disabled from INI file, rename `add_config` to `set_config` [#60](https://github.com/CLIUtils/CLI11/pull/60)
|
||||
|
||||
> ### Converting from CLI11 1.2:
|
||||
> ### Converting from CLI11 1.2
|
||||
>
|
||||
> * `app.parse` no longer returns a vector. Instead, use `app.remaining(true)`.
|
||||
> * `"hidden"` is no longer a special group name, instead use `""`
|
||||
|
335
README.md
335
README.md
@ -8,7 +8,7 @@
|
||||
[![Actions Status][actions-badge]][actions-link]
|
||||
[![Code Coverage][codecov-badge]][codecov]
|
||||
[![Codacy Badge][codacy-badge]][codacy-link]
|
||||
[![Join the chat at https://gitter.im/CLI11gitter/Lobby][gitter-badge]][gitter]
|
||||
[![Gitter chat][gitter-badge]][gitter]
|
||||
[![License: BSD][license-badge]](./LICENSE)
|
||||
[![Latest release][releases-badge]][github releases]
|
||||
[![DOI][doi-badge]][doi-link]
|
||||
@ -24,38 +24,38 @@ CLI11 is a command line parser for C++11 and beyond that provides a rich feature
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Background](#background)
|
||||
- [Introduction](#introduction)
|
||||
- [Why write another CLI parser?](#why-write-another-cli-parser)
|
||||
- [Other parsers](#other-parsers)
|
||||
- [Features not supported by this library](#features-not-supported-by-this-library)
|
||||
- [Install](#install)
|
||||
- [Usage](#usage)
|
||||
- [Adding options](#adding-options)
|
||||
- [Option types](#option-types)
|
||||
- [Example](#example)
|
||||
- [Option options](#option-options)
|
||||
- [Validators](#validators)
|
||||
- [Transforming Validators](#transforming-validators)
|
||||
- [Validator operations](#validator-operations)
|
||||
- [Custom Validators](#custom-validators)
|
||||
- [Querying Validators](#querying-validators)
|
||||
- [Getting Results](#getting-results)
|
||||
- [Subcommands](#subcommands)
|
||||
- [Subcommand options](#subcommand-options)
|
||||
- [Option groups](#option-groups)
|
||||
- [Callbacks](#callbacks)
|
||||
- [Configuration file](#configuration-file)
|
||||
- [Inheriting defaults](#inheriting-defaults)
|
||||
- [Formatting](#formatting)
|
||||
- [Subclassing](#subclassing)
|
||||
- [How it works](#how-it-works)
|
||||
- [Utilities](#utilities)
|
||||
- [Other libraries](#other-libraries)
|
||||
- [API](#api)
|
||||
- [Examples](#Examples)
|
||||
- [Contribute](#contribute)
|
||||
- [License](#license)
|
||||
* [Background](#background)
|
||||
* [Introduction](#introduction)
|
||||
* [Why write another CLI parser?](#why-write-another-cli-parser)
|
||||
* [Other parsers](#other-parsers)
|
||||
* [Features not supported by this library](#features-not-supported-by-this-library)
|
||||
* [Install](#install)
|
||||
* [Usage](#usage)
|
||||
* [Adding options](#adding-options)
|
||||
* [Option types](#option-types)
|
||||
* [Example](#example)
|
||||
* [Option options](#option-options)
|
||||
* [Validators](#validators)
|
||||
* [Transforming Validators](#transforming-validators)
|
||||
* [Validator operations](#validator-operations)
|
||||
* [Custom Validators](#custom-validators)
|
||||
* [Querying Validators](#querying-validators)
|
||||
* [Getting Results](#getting-results)
|
||||
* [Subcommands](#subcommands)
|
||||
* [Subcommand options](#subcommand-options)
|
||||
* [Option groups](#option-groups)
|
||||
* [Callbacks](#callbacks)
|
||||
* [Configuration file](#configuration-file)
|
||||
* [Inheriting defaults](#inheriting-defaults)
|
||||
* [Formatting](#formatting)
|
||||
* [Subclassing](#subclassing)
|
||||
* [How it works](#how-it-works)
|
||||
* [Utilities](#utilities)
|
||||
* [Other libraries](#other-libraries)
|
||||
* [API](#api)
|
||||
* [Examples](#Examples)
|
||||
* [Contribute](#contribute)
|
||||
* [License](#license)
|
||||
|
||||
Features that were added in the last released major version are marked with "🆕". Features only available in master are marked with "🚧".
|
||||
|
||||
@ -73,21 +73,21 @@ You can be notified when new releases are made by subscribing to <https://github
|
||||
|
||||
An acceptable CLI parser library should be all of the following:
|
||||
|
||||
- Easy to include (i.e., header only, one file if possible, **no external requirements**).
|
||||
- Short, simple syntax: This is one of the main reasons to use a CLI parser, it should make variables from the command line nearly as easy to define as any other variables. If most of your program is hidden in CLI parsing, this is a problem for readability.
|
||||
- C++11 or better: Should work with GCC 4.8+ (default on CentOS/RHEL 7), Clang 3.4+, AppleClang 7+, NVCC 7.0+, or MSVC 2015+.
|
||||
- Work on Linux, macOS, and Windows.
|
||||
- Well tested using [Travis][] (Linux) and [AppVeyor][] (Windows) or [Azure][] (all three). "Well" is defined as having good coverage measured by [CodeCov][].
|
||||
- Clear help printing.
|
||||
- Nice error messages.
|
||||
- Standard shell idioms supported naturally, like grouping flags, a positional separator, etc.
|
||||
- Easy to execute, with help, parse errors, etc. providing correct exit and details.
|
||||
- Easy to extend as part of a framework that provides "applications" to users.
|
||||
- Usable subcommand syntax, with support for multiple subcommands, nested subcommands, option groups, and optional fallthrough (explained later).
|
||||
- Ability to add a configuration file (`TOML`, `INI`, or custom format), and produce it as well.
|
||||
- Produce real values that can be used directly in code, not something you have pay compute time to look up, for HPC applications.
|
||||
- Work with standard types, simple custom types, and extensible to exotic types.
|
||||
- Permissively licensed.
|
||||
* Easy to include (i.e., header only, one file if possible, **no external requirements**).
|
||||
* Short, simple syntax: This is one of the main reasons to use a CLI parser, it should make variables from the command line nearly as easy to define as any other variables. If most of your program is hidden in CLI parsing, this is a problem for readability.
|
||||
* C++11 or better: Should work with GCC 4.8+ (default on CentOS/RHEL 7), Clang 3.4+, AppleClang 7+, NVCC 7.0+, or MSVC 2015+.
|
||||
* Work on Linux, macOS, and Windows.
|
||||
* Well tested using [Travis][] (Linux) and [AppVeyor][] (Windows) or [Azure][] (all three). "Well" is defined as having good coverage measured by [CodeCov][].
|
||||
* Clear help printing.
|
||||
* Nice error messages.
|
||||
* Standard shell idioms supported naturally, like grouping flags, a positional separator, etc.
|
||||
* Easy to execute, with help, parse errors, etc. providing correct exit and details.
|
||||
* Easy to extend as part of a framework that provides "applications" to users.
|
||||
* Usable subcommand syntax, with support for multiple subcommands, nested subcommands, option groups, and optional fallthrough (explained later).
|
||||
* Ability to add a configuration file (`TOML`, `INI`, or custom format), and produce it as well.
|
||||
* Produce real values that can be used directly in code, not something you have pay compute time to look up, for HPC applications.
|
||||
* Work with standard types, simple custom types, and extensible to exotic types.
|
||||
* Permissively licensed.
|
||||
|
||||
### Other parsers
|
||||
|
||||
@ -127,32 +127,36 @@ So, this library was designed to provide a great syntax, good compiler compatibi
|
||||
|
||||
There are some other possible "features" that are intentionally not supported by this library:
|
||||
|
||||
- Non-standard variations on syntax, like `-long` options. This is non-standard and should be avoided, so that is enforced by this library.
|
||||
- Completion of partial options, such as Python's `argparse` supplies for incomplete arguments. It's better not to guess. Most third party command line parsers for python actually reimplement command line parsing rather than using argparse because of this perceived design flaw.
|
||||
- Autocomplete: This might eventually be added to both Plumbum and CLI11, but it is not supported yet.
|
||||
- Wide strings / unicode: Since this uses the standard library only, it might be hard to properly implement, but I would be open to suggestions in how to do this.
|
||||
* Non-standard variations on syntax, like `-long` options. This is non-standard and should be avoided, so that is enforced by this library.
|
||||
* Completion of partial options, such as Python's `argparse` supplies for incomplete arguments. It's better not to guess. Most third party command line parsers for python actually reimplement command line parsing rather than using argparse because of this perceived design flaw.
|
||||
* Autocomplete: This might eventually be added to both Plumbum and CLI11, but it is not supported yet.
|
||||
* Wide strings / unicode: Since this uses the standard library only, it might be hard to properly implement, but I would be open to suggestions in how to do this.
|
||||
|
||||
## Install
|
||||
|
||||
To use, there are several methods:
|
||||
|
||||
1. All-in-one local header: Copy `CLI11.hpp` from the [most recent release][github releases] into your include directory, and you are set. This is combined from the source files for every release. This includes the entire command parser library, but does not include separate utilities (like `Timer`, `AutoTimer`). The utilities are completely self contained and can be copied separately.
|
||||
2. All-in-one global header: Like above, but copying the file to a shared folder location like `/opt/CLI11`. Then, the C++ include path has to be extended to point at this folder. With CMake, use `include_directories(/opt/CLI11)`
|
||||
3. Local headers and target: Use `CLI/*.hpp` files. You could check out the repository as a git submodule, for example. With CMake, you can use `add_subdirectory` and the `CLI11::CLI11` interface target when linking. If not using a submodule, you must ensure that the copied files are located inside the same tree directory than your current project, to prevent an error with CMake and `add_subdirectory`.
|
||||
4. Global headers: Use `CLI/*.hpp` files stored in a shared folder. You could check out the git repository in a system-wide folder, for example `/opt/`. With CMake, you could add to the include path via:
|
||||
* All-in-one local header: Copy `CLI11.hpp` from the [most recent release][github releases] into your include directory, and you are set. This is combined from the source files for every release. This includes the entire command parser library, but does not include separate utilities (like `Timer`, `AutoTimer`). The utilities are completely self contained and can be copied separately.
|
||||
* All-in-one global header: Like above, but copying the file to a shared folder location like `/opt/CLI11`. Then, the C++ include path has to be extended to point at this folder. With CMake, use `include_directories(/opt/CLI11)`
|
||||
* Local headers and target: Use `CLI/*.hpp` files. You could check out the repository as a git submodule, for example. With CMake, you can use `add_subdirectory` and the `CLI11::CLI11` interface target when linking. If not using a submodule, you must ensure that the copied files are located inside the same tree directory than your current project, to prevent an error with CMake and `add_subdirectory`.
|
||||
* Global headers: Use `CLI/*.hpp` files stored in a shared folder. You could check out the git repository in a system-wide folder, for example `/opt/`. With CMake, you could add to the include path via:
|
||||
|
||||
```bash
|
||||
if(NOT DEFINED CLI11_DIR)
|
||||
set (CLI11_DIR "/opt/CLI11" CACHE STRING "CLI11 git repository")
|
||||
endif()
|
||||
include_directories(${CLI11_DIR}/include)
|
||||
```
|
||||
|
||||
And then in the source code (adding several headers might be needed to prevent linker errors):
|
||||
|
||||
```cpp
|
||||
#include "CLI/App.hpp"
|
||||
#include "CLI/Formatter.hpp"
|
||||
#include "CLI/Config.hpp"
|
||||
```
|
||||
5. Global headers and target: configuring and installing the project is required for linking CLI11 to your project in the same way as you would do with any other external library. With CMake, this step allows using `find_package(CLI11 CONFIG REQUIRED)` and then using the `CLI11::CLI11` target when linking. If `CMAKE_INSTALL_PREFIX` was changed during install to a specific folder like `/opt/CLI11`, then you have to pass `-DCLI11_DIR=/opt/CLI11` when building your current project. You can also use [Conan.io][conan-link] or [Hunter][].
|
||||
|
||||
* Global headers and target: configuring and installing the project is required for linking CLI11 to your project in the same way as you would do with any other external library. With CMake, this step allows using `find_package(CLI11 CONFIG REQUIRED)` and then using the `CLI11::CLI11` target when linking. If `CMAKE_INSTALL_PREFIX` was changed during install to a specific folder like `/opt/CLI11`, then you have to pass `-DCLI11_DIR=/opt/CLI11` when building your current project. You can also use [Conan.io][conan-link] or [Hunter][].
|
||||
(These are just conveniences to allow you to use your favorite method of managing packages; it's just header only so including the correct path and
|
||||
using C++11 is all you really need.)
|
||||
|
||||
@ -315,14 +319,13 @@ app.add_flag("-1{1},-2{2},-3{3}",result,"numerical flag")
|
||||
|
||||
using any of those flags on the command line will result in the specified number in the output. Similar things can be done for string values, and enumerations, as long as the default value can be converted to the given type.
|
||||
|
||||
|
||||
On a `C++14` compiler, you can pass a callback function directly to `.add_flag`, while in C++11 mode you'll need to use `.add_flag_function` if you want a callback function. The function will be given the number of times the flag was passed. You can throw a relevant `CLI::ParseError` to signal a failure.
|
||||
|
||||
#### Example
|
||||
|
||||
- `"one,-o,--one"`: Valid as long as not a flag, would create an option that can be specified positionally, or with `-o` or `--one`
|
||||
- `"this"` Can only be passed positionally
|
||||
- `"-a,-b,-c"` No limit to the number of non-positional option names
|
||||
* `"one,-o,--one"`: Valid as long as not a flag, would create an option that can be specified positionally, or with `-o` or `--one`
|
||||
* `"this"` Can only be passed positionally
|
||||
* `"-a,-b,-c"` No limit to the number of non-positional option names
|
||||
|
||||
The add commands return a pointer to an internally stored `Option`.
|
||||
This option can be used directly to check for the count (`->count()`) after parsing to avoid a string based lookup.
|
||||
@ -331,57 +334,57 @@ This option can be used directly to check for the count (`->count()`) after pars
|
||||
|
||||
Before parsing, you can set the following options:
|
||||
|
||||
- `->required()`: The program will quit if this option is not present. This is `mandatory` in Plumbum, but required options seems to be a more standard term. For compatibility, `->mandatory()` also works.
|
||||
- `->expected(N)`: Take `N` values instead of as many as possible, only for vector args. If negative, require at least `-N`; end with `--` or another recognized option or subcommand.
|
||||
- `->type_name(typename)`: Set the name of an Option's type (`type_name_fn` allows a function instead)
|
||||
- `->type_size(N)`: Set the intrinsic size of an option. The parser will require multiples of this number if negative.
|
||||
- `->needs(opt)`: This option requires another option to also be present, opt is an `Option` pointer.
|
||||
- `->excludes(opt)`: This option cannot be given with `opt` present, opt is an `Option` pointer.
|
||||
- `->envname(name)`: Gets the value from the environment if present and not passed on the command line.
|
||||
- `->group(name)`: The help group to put the option in. No effect for positional options. Defaults to `"Options"`. `""` will not show up in the help print (hidden).
|
||||
- `->ignore_case()`: Ignore the case on the command line (also works on subcommands, does not affect arguments).
|
||||
- `->ignore_underscore()`: Ignore any underscores in the options names (also works on subcommands, does not affect arguments). For example "option_one" will match with "optionone". This does not apply to short form options since they only have one character
|
||||
- `->disable_flag_override()`: From the command line long form flag options can be assigned a value on the command line using the `=` notation `--flag=value`. If this behavior is not desired, the `disable_flag_override()` disables it and will generate an exception if it is done on the command line. The `=` does not work with short form flag options.
|
||||
- `->allow_extra_args(true/false)`: 🆕 If set to true the option will take an unlimited number of arguments like a vector, if false it will limit the number of arguments to the size of the type used in the option. Default value depends on the nature of the type use, containers default to true, others default to false.
|
||||
- `->delimiter(char)`: Allows specification of a custom delimiter for separating single arguments into vector arguments, for example specifying `->delimiter(',')` on an option would result in `--opt=1,2,3` producing 3 elements of a vector and the equivalent of --opt 1 2 3 assuming opt is a vector value.
|
||||
- `->description(str)`: Set/change the description.
|
||||
- `->multi_option_policy(CLI::MultiOptionPolicy::Throw)`: Set the multi-option policy. Shortcuts available: `->take_last()`, `->take_first()`,`->take_all()`, and `->join()`. This will only affect options expecting 1 argument or bool flags (which do not inherit their default but always start with a specific policy).
|
||||
- `->check(std::string(const std::string &), validator_name="",validator_description="")`: Define a check function. The function should return a non empty string with the error message if the check fails
|
||||
- `->check(Validator)`: Use a Validator object to do the check see [Validators](#validators) for a description of available Validators and how to create new ones.
|
||||
- `->transform(std::string(std::string &), validator_name="",validator_description=")`: Converts the input string into the output string, in-place in the parsed options.
|
||||
- `->transform(Validator)`: Uses a Validator object to do the transformation see [Validators](#validators) for a description of available Validators and how to create new ones.
|
||||
- `->each(void(const std::string &)>`: Run this function on each value received, as it is received. It should throw a `ValidationError` if an error is encountered.
|
||||
- `->configurable(false)`: Disable this option from being in a configuration file.
|
||||
`->capture_default_str()`: Store the current value attached and display it in the help string.
|
||||
- `->default_function(std::string())`: Advanced: Change the function that `capture_default_str()` uses.
|
||||
- `->always_capture_default()`: Always run `capture_default_str()` when creating new options. Only useful on an App's `option_defaults`.
|
||||
- `->default_str(string)`: Set the default string directly. This string will also be used as a default value if no arguments are passed and the value is requested.
|
||||
- `->default_val(value)`: Generate the default string from a value and validate that the value is also valid. For options that assign directly to a value type the value in that type is also updated. Value must be convertible to a string(one of known types or have a stream operator).
|
||||
- `->option_text(string)`: Sets the text between the option name and description.
|
||||
|
||||
* `->required()`: The program will quit if this option is not present. This is `mandatory` in Plumbum, but required options seems to be a more standard term. For compatibility, `->mandatory()` also works.
|
||||
* `->expected(N)`: Take `N` values instead of as many as possible, only for vector args. If negative, require at least `-N`; end with `--` or another recognized option or subcommand.
|
||||
* `->type_name(typename)`: Set the name of an Option's type (`type_name_fn` allows a function instead)
|
||||
* `->type_size(N)`: Set the intrinsic size of an option. The parser will require multiples of this number if negative.
|
||||
* `->needs(opt)`: This option requires another option to also be present, opt is an `Option` pointer.
|
||||
* `->excludes(opt)`: This option cannot be given with `opt` present, opt is an `Option` pointer.
|
||||
* `->envname(name)`: Gets the value from the environment if present and not passed on the command line.
|
||||
* `->group(name)`: The help group to put the option in. No effect for positional options. Defaults to `"Options"`. `""` will not show up in the help print (hidden).
|
||||
* `->ignore_case()`: Ignore the case on the command line (also works on subcommands, does not affect arguments).
|
||||
* `->ignore_underscore()`: Ignore any underscores in the options names (also works on subcommands, does not affect arguments). For example "option_one" will match with "optionone". This does not apply to short form options since they only have one character
|
||||
* `->disable_flag_override()`: From the command line long form flag options can be assigned a value on the command line using the `=` notation `--flag=value`. If this behavior is not desired, the `disable_flag_override()` disables it and will generate an exception if it is done on the command line. The `=` does not work with short form flag options.
|
||||
* `->allow_extra_args(true/false)`: 🆕 If set to true the option will take an unlimited number of arguments like a vector, if false it will limit the number of arguments to the size of the type used in the option. Default value depends on the nature of the type use, containers default to true, others default to false.
|
||||
* `->delimiter(char)`: Allows specification of a custom delimiter for separating single arguments into vector arguments, for example specifying `->delimiter(',')` on an option would result in `--opt=1,2,3` producing 3 elements of a vector and the equivalent of --opt 1 2 3 assuming opt is a vector value.
|
||||
* `->description(str)`: Set/change the description.
|
||||
* `->multi_option_policy(CLI::MultiOptionPolicy::Throw)`: Set the multi-option policy. Shortcuts available: `->take_last()`, `->take_first()`,`->take_all()`, and `->join()`. This will only affect options expecting 1 argument or bool flags (which do not inherit their default but always start with a specific policy).
|
||||
* `->check(std::string(const std::string &), validator_name="",validator_description="")`: Define a check function. The function should return a non empty string with the error message if the check fails
|
||||
* `->check(Validator)`: Use a Validator object to do the check see [Validators](#validators) for a description of available Validators and how to create new ones.
|
||||
* `->transform(std::string(std::string &), validator_name="",validator_description=")`: Converts the input string into the output string, in-place in the parsed options.
|
||||
* `->transform(Validator)`: Uses a Validator object to do the transformation see [Validators](#validators) for a description of available Validators and how to create new ones.
|
||||
* `->each(void(const std::string &)>`: Run this function on each value received, as it is received. It should throw a `ValidationError` if an error is encountered.
|
||||
* `->configurable(false)`: Disable this option from being in a configuration file.
|
||||
* `->capture_default_str()`: Store the current value attached and display it in the help string.
|
||||
* `->default_function(std::string())`: Advanced: Change the function that `capture_default_str()` uses.
|
||||
* `->always_capture_default()`: Always run `capture_default_str()` when creating new options. Only useful on an App's `option_defaults`.
|
||||
* `->default_str(string)`: Set the default string directly. This string will also be used as a default value if no arguments are passed and the value is requested.
|
||||
* `->default_val(value)`: Generate the default string from a value and validate that the value is also valid. For options that assign directly to a value type the value in that type is also updated. Value must be convertible to a string(one of known types or have a stream operator).
|
||||
* `->option_text(string)`: Sets the text between the option name and description.
|
||||
|
||||
These options return the `Option` pointer, so you can chain them together, and even skip storing the pointer entirely. The `each` function takes any function that has the signature `void(const std::string&)`; it should throw a `ValidationError` when validation fails. The help message will have the name of the parent option prepended. Since `each`, `check` and `transform` use the same underlying mechanism, you can chain as many as you want, and they will be executed in order. Operations added through `transform` are executed first in reverse order of addition, and `check` and `each` are run following the transform functions in order of addition. If you just want to see the unconverted values, use `.results()` to get the `std::vector<std::string>` of results.
|
||||
|
||||
On the command line, options can be given as:
|
||||
|
||||
- `-a` (flag)
|
||||
- `-abc` (flags can be combined)
|
||||
- `-f filename` (option)
|
||||
- `-ffilename` (no space required)
|
||||
- `-abcf filename` (flags and option can be combined)
|
||||
- `--long` (long flag)
|
||||
- `--long_flag=true` (long flag with equals to override default value)
|
||||
- `--file filename` (space)
|
||||
- `--file=filename` (equals)
|
||||
* `-a` (flag)
|
||||
* `-abc` (flags can be combined)
|
||||
* `-f filename` (option)
|
||||
* `-ffilename` (no space required)
|
||||
* `-abcf filename` (flags and option can be combined)
|
||||
* `--long` (long flag)
|
||||
* `--long_flag=true` (long flag with equals to override default value)
|
||||
* `--file filename` (space)
|
||||
* `--file=filename` (equals)
|
||||
|
||||
If `allow_windows_style_options()` is specified in the application or subcommand options can also be given as:
|
||||
- `/a` (flag)
|
||||
- `/f filename` (option)
|
||||
- `/long` (long flag)
|
||||
- `/file filename` (space)
|
||||
- `/file:filename` (colon)
|
||||
- `/long_flag:false` (long flag with : to override the default value)
|
||||
= Windows style options do not allow combining short options or values not separated from the short option like with `-` options
|
||||
|
||||
* `/a` (flag)
|
||||
* `/f filename` (option)
|
||||
* `/long` (long flag)
|
||||
* `/file filename` (space)
|
||||
* `/file:filename` (colon)
|
||||
* `/long_flag:false` (long flag with : to override the default value)
|
||||
* Windows style options do not allow combining short options or values not separated from the short option like with `-` options
|
||||
|
||||
Long flag options may be given with an `=<value>` to allow specifying a false value, or some other value to the flag. See [config files](#configuration-file) for details on the values supported. NOTE: only the `=` or `:` for windows-style options may be used for this, using a space will result in the argument being interpreted as a positional argument. This syntax can override the default values, and can be disabled by using `disable_flag_override()`.
|
||||
|
||||
@ -437,32 +440,34 @@ will produce a check to ensure a value is between 0 and 10 or 20 and 30.
|
||||
will produce a check for a number less than or equal to 0.
|
||||
|
||||
##### Transforming Validators
|
||||
There are a few built in Validators that let you transform values if used with the `transform` function. If they also do some checks then they can be used `check` but some may do nothing in that case.
|
||||
- `CLI::Bounded(min,max)` will bound values between min and max and values outside of that range are limited to min or max, it will fail if the value cannot be converted and produce a `ValidationError`
|
||||
- The `IsMember` Validator lets you specify a set of predefined options. You can pass any container or copyable pointer (including `std::shared_ptr`) to a container to this Validator; the container just needs to be iterable and have a `::value_type`. The key type should be convertible from a string, You can use an initializer list directly if you like. If you need to modify the set later, the pointer form lets you do that; the type message and check will correctly refer to the current version of the set. The container passed in can be a set, vector, or a map like structure. If used in the `transform` method the output value will be the matching key as it could be modified by filters.
|
||||
After specifying a set of options, you can also specify "filter" functions of the form `T(T)`, where `T` is the type of the values. The most common choices probably will be `CLI::ignore_case` an `CLI::ignore_underscore`, and `CLI::ignore_space`. These all work on strings but it is possible to define functions that work on other types.
|
||||
Here are some examples
|
||||
of `IsMember`:
|
||||
|
||||
- `CLI::IsMember({"choice1", "choice2"})`: Select from exact match to choices.
|
||||
- `CLI::IsMember({"choice1", "choice2"}, CLI::ignore_case, CLI::ignore_underscore)`: Match things like `Choice_1`, too.
|
||||
- `CLI::IsMember(std::set<int>({2,3,4}))`: Most containers and types work; you just need `std::begin`, `std::end`, and `::value_type`.
|
||||
- `CLI::IsMember(std::map<std::string, TYPE>({{"one", 1}, {"two", 2}}))`: You can use maps; in `->transform()` these replace the matched value with the matched key. The value member of the map is not used in `IsMember`, so it can be any type.
|
||||
- `auto p = std::make_shared<std::vector<std::string>>(std::initializer_list<std::string>("one", "two")); CLI::IsMember(p)`: You can modify `p` later.
|
||||
- The `Transformer` and `CheckedTransformer` Validators transform one value into another. Any container or copyable pointer (including `std::shared_ptr`) to a container that generates pairs of values can be passed to these `Validator's`; the container just needs to be iterable and have a `::value_type` that consists of pairs. The key type should be convertible from a string, and the value type should be convertible to a string You can use an initializer list directly if you like. If you need to modify the map later, the pointer form lets you do that; the description message will correctly refer to the current version of the map. `Transformer` does not do any checking so values not in the map are ignored. `CheckedTransformer` takes an extra step of verifying that the value is either one of the map key values, in which case it is transformed, or one of the expected output values, and if not will generate a `ValidationError`. A Transformer placed using `check` will not do anything.
|
||||
There are a few built in Validators that let you transform values if used with the `transform` function. If they also do some checks then they can be used `check` but some may do nothing in that case.
|
||||
|
||||
* `CLI::Bounded(min,max)` will bound values between min and max and values outside of that range are limited to min or max, it will fail if the value cannot be converted and produce a `ValidationError`
|
||||
* The `IsMember` Validator lets you specify a set of predefined options. You can pass any container or copyable pointer (including `std::shared_ptr`) to a container to this Validator; the container just needs to be iterable and have a `::value_type`. The key type should be convertible from a string, You can use an initializer list directly if you like. If you need to modify the set later, the pointer form lets you do that; the type message and check will correctly refer to the current version of the set. The container passed in can be a set, vector, or a map like structure. If used in the `transform` method the output value will be the matching key as it could be modified by filters.
|
||||
|
||||
After specifying a set of options, you can also specify "filter" functions of the form `T(T)`, where `T` is the type of the values. The most common choices probably will be `CLI::ignore_case` an `CLI::ignore_underscore`, and `CLI::ignore_space`. These all work on strings but it is possible to define functions that work on other types. Here are some examples of `IsMember`:
|
||||
|
||||
* `CLI::IsMember({"choice1", "choice2"})`: Select from exact match to choices.
|
||||
* `CLI::IsMember({"choice1", "choice2"}, CLI::ignore_case, CLI::ignore_underscore)`: Match things like `Choice_1`, too.
|
||||
* `CLI::IsMember(std::set<int>({2,3,4}))`: Most containers and types work; you just need `std::begin`, `std::end`, and `::value_type`.
|
||||
* `CLI::IsMember(std::map<std::string, TYPE>({{"one", 1}, {"two", 2}}))`: You can use maps; in `->transform()` these replace the matched value with the matched key. The value member of the map is not used in `IsMember`, so it can be any type.
|
||||
* `auto p = std::make_shared<std::vector<std::string>>(std::initializer_list<std::string>("one", "two")); CLI::IsMember(p)`: You can modify `p` later.
|
||||
* The `Transformer` and `CheckedTransformer` Validators transform one value into another. Any container or copyable pointer (including `std::shared_ptr`) to a container that generates pairs of values can be passed to these `Validator's`; the container just needs to be iterable and have a `::value_type` that consists of pairs. The key type should be convertible from a string, and the value type should be convertible to a string You can use an initializer list directly if you like. If you need to modify the map later, the pointer form lets you do that; the description message will correctly refer to the current version of the map. `Transformer` does not do any checking so values not in the map are ignored. `CheckedTransformer` takes an extra step of verifying that the value is either one of the map key values, in which case it is transformed, or one of the expected output values, and if not will generate a `ValidationError`. A Transformer placed using `check` will not do anything.
|
||||
|
||||
After specifying a map of options, you can also specify "filter" just like in `CLI::IsMember`.
|
||||
Here are some examples (`Transformer` and `CheckedTransformer` are interchangeable in the examples)
|
||||
of `Transformer`:
|
||||
|
||||
- `CLI::Transformer({{"key1", "map1"},{"key2","map2"}})`: Select from key values and produce map values.
|
||||
|
||||
- `CLI::Transformer(std::map<std::string,int>({"two",2},{"three",3},{"four",4}}))`: most maplike containers work, the `::value_type` needs to produce a pair of some kind.
|
||||
- `CLI::CheckedTransformer(std::map<std::string, int>({{"one", 1}, {"two", 2}}))`: You can use maps; in `->transform()` these replace the matched key with the value. `CheckedTransformer` also requires that the value either match one of the keys or match one of known outputs.
|
||||
- `auto p = std::make_shared<CLI::TransformPairs<std::string>>(std::initializer_list<std::pair<std::string,std::string>>({"key1", "map1"},{"key2","map2"})); CLI::Transformer(p)`: You can modify `p` later. `TransformPairs<T>` is an alias for `std::vector<std::pair<<std::string,T>>`
|
||||
* `CLI::Transformer({{"key1", "map1"},{"key2","map2"}})`: Select from key values and produce map values.
|
||||
* `CLI::Transformer(std::map<std::string,int>({"two",2},{"three",3},{"four",4}}))`: most maplike containers work, the `::value_type` needs to produce a pair of some kind.
|
||||
* `CLI::CheckedTransformer(std::map<std::string, int>({{"one", 1}, {"two", 2}}))`: You can use maps; in `->transform()` these replace the matched key with the value. `CheckedTransformer` also requires that the value either match one of the keys or match one of known outputs.
|
||||
* `auto p = std::make_shared<CLI::TransformPairs<std::string>>(std::initializer_list<std::pair<std::string,std::string>>({"key1", "map1"},{"key2","map2"})); CLI::Transformer(p)`: You can modify `p` later. `TransformPairs<T>` is an alias for `std::vector<std::pair<<std::string,T>>`
|
||||
|
||||
NOTES: If the container used in `IsMember`, `Transformer`, or `CheckedTransformer` has a `find` function like `std::unordered_map` or `std::map` then that function is used to do the searching. If it does not have a `find` function a linear search is performed. If there are filters present, the fast search is performed first, and if that fails a linear search with the filters on the key values is performed.
|
||||
|
||||
##### Validator operations
|
||||
|
||||
Validators are copyable and have a few operations that can be performed on them to alter settings. Most of the built in Validators have a default description that is displayed in the help. This can be altered via `.description(validator_description)`.
|
||||
The name of a Validator, which is useful for later reference from the `get_validator(name)` method of an `Option` can be set via `.name(validator_name)`
|
||||
The operation function of a Validator can be set via
|
||||
@ -519,12 +524,13 @@ opt->get_validator(index);
|
||||
```
|
||||
|
||||
Which will return a validator in the index it is applied which isn't necessarily the order in which was defined. The pointer can be `nullptr` if an invalid index is given.
|
||||
Validators have a few functions to query the current values
|
||||
- `get_description()`: Will return a description string
|
||||
- `get_name()`: Will return the Validator name
|
||||
- `get_active()`: Will return the current active state, true if the Validator is active.
|
||||
- `get_application_index()`: Will return the current application index.
|
||||
- `get_modifying()`: Will return true if the Validator is allowed to modify the input, this can be controlled via the `non_modifying()` method, though it is recommended to let `check` and `transform` option methods manipulate it if needed.
|
||||
Validators have a few functions to query the current values:
|
||||
|
||||
* `get_description()`: Will return a description string
|
||||
* `get_name()`: Will return the Validator name
|
||||
* `get_active()`: Will return the current active state, true if the Validator is active.
|
||||
* `get_application_index()`: Will return the current application index.
|
||||
* `get_modifying()`: Will return true if the Validator is allowed to modify the input, this can be controlled via the `non_modifying()` method, though it is recommended to let `check` and `transform` option methods manipulate it if needed.
|
||||
|
||||
#### Getting results
|
||||
|
||||
@ -614,7 +620,6 @@ There are several options that are supported on the main app and subcommands and
|
||||
|
||||
> Note: if you have a fixed number of required positional options, that will match before subcommand names. `{}` is an empty filter function, and any positional argument will match before repeated subcommand names.
|
||||
|
||||
|
||||
#### Callbacks
|
||||
|
||||
A subcommand has three optional callbacks that are executed at different stages of processing. The `preparse_callback` is executed once after the first argument of a subcommand or application is processed and gives an argument for the number of remaining arguments to process. For the main app the first argument is considered the program name, for subcommands the first argument is the subcommand name. For Option groups and nameless subcommands the first argument is after the first argument or subcommand is processed from that group.
|
||||
@ -629,7 +634,6 @@ auto sub2=app.add_subcommand("sub2")->final_callback(c2)->preparse_callback(pc2)
|
||||
app.preparse_callback( pa);
|
||||
|
||||
... A bunch of other options
|
||||
|
||||
```
|
||||
|
||||
Then the command line is given as
|
||||
@ -638,14 +642,14 @@ Then the command line is given as
|
||||
program --opt1 opt1_val sub1 --sub1opt --sub1optb val sub2 --sub2opt sub1 --sub1opt2 sub2 --sub2opt2 val
|
||||
```
|
||||
|
||||
- `pa` will be called prior to parsing any values with an argument of 13.
|
||||
- `pc1` will be called immediately after processing the `sub1` command with a value of 10.
|
||||
- `c1` will be called when the `sub2` command is encountered.
|
||||
- `pc2` will be called with value of 6 after the `sub2` command is encountered.
|
||||
- `c1` will be called again after the second `sub2` command is encountered.
|
||||
- `ac1` will be called after processing of all arguments
|
||||
- `c2` will be called once after processing all arguments.
|
||||
- `ac2` will be called last after completing all lower level callbacks have been executed.
|
||||
* `pa` will be called prior to parsing any values with an argument of 13.
|
||||
* `pc1` will be called immediately after processing the `sub1` command with a value of 10.
|
||||
* `c1` will be called when the `sub2` command is encountered.
|
||||
* `pc2` will be called with value of 6 after the `sub2` command is encountered.
|
||||
* `c1` will be called again after the second `sub2` command is encountered.
|
||||
* `ac1` will be called after processing of all arguments
|
||||
* `c2` will be called once after processing all arguments.
|
||||
* `ac2` will be called last after completing all lower level callbacks have been executed.
|
||||
|
||||
A subcommand is considered terminated when one of the following conditions are met.
|
||||
|
||||
@ -656,8 +660,6 @@ A subcommand is considered terminated when one of the following conditions are m
|
||||
|
||||
Prior to executed a `parse_complete_callback` all contained options are processed before the callback is triggered. If a subcommand with a `parse_complete_callback` is called again, then the contained options are reset, and can be triggered again.
|
||||
|
||||
|
||||
|
||||
#### Option groups
|
||||
|
||||
The subcommand method
|
||||
@ -695,16 +697,19 @@ CLI::TriggerOff(group2_pointer, disabled_group);
|
||||
These functions make use of `preparse_callback`, `enabled_by_default()` and `disabled_by_default`. The triggered group may be a vector of group pointers. These methods should only be used once per group and will override any previous use of the underlying functions. More complex arrangements can be accomplished using similar methodology with a custom `preparse_callback` function that does more.
|
||||
|
||||
Additional helper functions `deprecate_option` and `retire_option` are available to deprecate or retire options
|
||||
|
||||
```cpp
|
||||
CLI::deprecate_option(option *, replacement_name="");
|
||||
CLI::deprecate_option(App,option_name,replacement_name="");
|
||||
```
|
||||
|
||||
will specify that the option is deprecated which will display a message in the help and a warning on first usage. Deprecated options function normally but will add a message in the help and display a warning on first use.
|
||||
|
||||
```cpp
|
||||
CLI::retire_option(App,option *);
|
||||
CLI::retire_option(App,option_name);
|
||||
```
|
||||
|
||||
will create an option that does nothing by default and will display a warning on first usage that the option is retired and has no effect. If the option exists it is replaces with a dummy option that takes the same arguments.
|
||||
|
||||
If an empty string is passed the option group name the entire group will be hidden in the help results. For example.
|
||||
@ -712,6 +717,7 @@ If an empty string is passed the option group name the entire group will be hidd
|
||||
```cpp
|
||||
auto hidden_group=app.add_option_group("");
|
||||
```
|
||||
|
||||
will create a group such that no options in that group are displayed in the help string.
|
||||
|
||||
### Configuration file
|
||||
@ -739,7 +745,9 @@ str_vector = ["one","two","and three"]
|
||||
in_subcommand = Wow
|
||||
sub.subcommand = true
|
||||
```
|
||||
|
||||
or equivalently in INI format
|
||||
|
||||
```ini
|
||||
; Comments are supported, using a ;
|
||||
; The default section is [default], case insensitive
|
||||
@ -879,29 +887,28 @@ The API is [documented here][api-docs]. Also see the [CLI11 tutorial GitBook][gi
|
||||
|
||||
Several short examples of different features are included in the repository. A brief description of each is included here
|
||||
|
||||
- [callback_passthrough](https://github.com/CLIUtils/CLI11/blob/master/examples/callback_passthrough.cpp): Example of directly passing remaining arguments through to a callback function which generates a CLI11 application based on existing arguments.
|
||||
- [custom_parse](https://github.com/CLIUtils/CLI11/blob/master/examples/custom_parse.cpp): Based on [Issue #566](https://github.com/CLIUtils/CLI11/issues/566), example of custom parser
|
||||
- [digit_args](https://github.com/CLIUtils/CLI11/blob/master/examples/digit_args.cpp): Based on [Issue #123](https://github.com/CLIUtils/CLI11/issues/123), uses digit flags to pass a value
|
||||
- [enum](https://github.com/CLIUtils/CLI11/blob/master/examples/enum.cpp): Using enumerations in an option, and the use of [CheckedTransformer](#transforming-validators)
|
||||
- [enum_ostream](https://github.com/CLIUtils/CLI11/blob/master/examples/enum_ostream.cpp): In addition to the contents of example enum.cpp, this example shows how a custom ostream operator overrides CLI11's enum streaming.
|
||||
- [formatter](https://github.com/CLIUtils/CLI11/blob/master/examples/formatter.cpp): Illustrating usage of a custom formatter
|
||||
- [groups](https://github.com/CLIUtils/CLI11/blob/master/examples/groups.cpp): Example using groups of options for help grouping and a the timer helper class
|
||||
- [inter_argument_order](https://github.com/CLIUtils/CLI11/blob/master/examples/inter_argument_order.cpp): An app to practice mixing unlimited arguments, but still recover the original order.
|
||||
- [json](https://github.com/CLIUtils/CLI11/blob/master/examples/json.cpp): Using JSON as a config file parser
|
||||
- [modhelp](https://github.com/CLIUtils/CLI11/blob/master/examples/modhelp.cpp): How to modify the help flag to do something other than default
|
||||
- [nested](https://github.com/CLIUtils/CLI11/blob/master/examples/nested.cpp): Nested subcommands
|
||||
- [option_groups](https://github.com/CLIUtils/CLI11/blob/master/examples/option_groups.cpp): illustrating the use of option groups and a required number of options.
|
||||
based on [Issue #88](https://github.com/CLIUtils/CLI11/issues/88) to set interacting groups of options
|
||||
- [positional_arity](https://github.com/CLIUtils/CLI11/blob/master/examples/positional_arity.cpp): Illustrating use of `preparse_callback` to handle situations where the number of arguments can determine which should get parsed, Based on [Issue #166](https://github.com/CLIUtils/CLI11/issues/166)
|
||||
- [positional_validation](https://github.com/CLIUtils/CLI11/blob/master/examples/positional_validation.cpp): Example of how positional arguments are validated using the `validate_positional` flag, also based on [Issue #166](https://github.com/CLIUtils/CLI11/issues/166)
|
||||
- [prefix_command](https://github.com/CLIUtils/CLI11/blob/master/examples/prefix_command.cpp): illustrating use of the `prefix_command` flag.
|
||||
- [ranges](https://github.com/CLIUtils/CLI11/blob/master/examples/ranges.cpp): App to demonstrate exclusionary option groups based on [Issue #88](https://github.com/CLIUtils/CLI11/issues/88)
|
||||
- [shapes](https://github.com/CLIUtils/CLI11/blob/master/examples/shapes.cpp): illustrating how to set up repeated subcommands Based on [gitter discussion](https://gitter.im/CLI11gitter/Lobby?at=5c7af6b965ffa019ea788cd5)
|
||||
- [simple](https://github.com/CLIUtils/CLI11/blob/master/examples/simple.cpp): a simple example of how to set up a CLI11 Application with different flags and options
|
||||
- [subcom_help](https://github.com/CLIUtils/CLI11/blob/master/examples/subcom_help.cpp): configuring help for subcommands
|
||||
- [subcom_partitioned](https://github.com/CLIUtils/CLI11/blob/master/examples/subcom_partitioned.cpp): Example with a timer and subcommands generated separately and added to the main app later.
|
||||
- [subcommands](https://github.com/CLIUtils/CLI11/blob/master/examples/subcommands.cpp): Short example of subcommands
|
||||
- [validators](https://github.com/CLIUtils/CLI11/blob/master/examples/validators.cpp): Example illustrating use of validators
|
||||
* [callback_passthrough](https://github.com/CLIUtils/CLI11/blob/master/examples/callback_passthrough.cpp): Example of directly passing remaining arguments through to a callback function which generates a CLI11 application based on existing arguments.
|
||||
* [custom_parse](https://github.com/CLIUtils/CLI11/blob/master/examples/custom_parse.cpp): Based on [Issue #566](https://github.com/CLIUtils/CLI11/issues/566), example of custom parser
|
||||
* [digit_args](https://github.com/CLIUtils/CLI11/blob/master/examples/digit_args.cpp): Based on [Issue #123](https://github.com/CLIUtils/CLI11/issues/123), uses digit flags to pass a value
|
||||
* [enum](https://github.com/CLIUtils/CLI11/blob/master/examples/enum.cpp): Using enumerations in an option, and the use of [CheckedTransformer](#transforming-validators)
|
||||
* [enum_ostream](https://github.com/CLIUtils/CLI11/blob/master/examples/enum_ostream.cpp): In addition to the contents of example enum.cpp, this example shows how a custom ostream operator overrides CLI11's enum streaming.
|
||||
* [formatter](https://github.com/CLIUtils/CLI11/blob/master/examples/formatter.cpp): Illustrating usage of a custom formatter
|
||||
* [groups](https://github.com/CLIUtils/CLI11/blob/master/examples/groups.cpp): Example using groups of options for help grouping and a the timer helper class
|
||||
* [inter_argument_order](https://github.com/CLIUtils/CLI11/blob/master/examples/inter_argument_order.cpp): An app to practice mixing unlimited arguments, but still recover the original order.
|
||||
* [json](https://github.com/CLIUtils/CLI11/blob/master/examples/json.cpp): Using JSON as a config file parser
|
||||
* [modhelp](https://github.com/CLIUtils/CLI11/blob/master/examples/modhelp.cpp): How to modify the help flag to do something other than default
|
||||
* [nested](https://github.com/CLIUtils/CLI11/blob/master/examples/nested.cpp): Nested subcommands
|
||||
* [option_groups](https://github.com/CLIUtils/CLI11/blob/master/examples/option_groups.cpp): Illustrating the use of option groups and a required number of options. Based on [Issue #88](https://github.com/CLIUtils/CLI11/issues/88) to set interacting groups of options
|
||||
* [positional_arity](https://github.com/CLIUtils/CLI11/blob/master/examples/positional_arity.cpp): Illustrating use of `preparse_callback` to handle situations where the number of arguments can determine which should get parsed, Based on [Issue #166](https://github.com/CLIUtils/CLI11/issues/166)
|
||||
* [positional_validation](https://github.com/CLIUtils/CLI11/blob/master/examples/positional_validation.cpp): Example of how positional arguments are validated using the `validate_positional` flag, also based on [Issue #166](https://github.com/CLIUtils/CLI11/issues/166)
|
||||
* [prefix_command](https://github.com/CLIUtils/CLI11/blob/master/examples/prefix_command.cpp): Illustrating use of the `prefix_command` flag.
|
||||
* [ranges](https://github.com/CLIUtils/CLI11/blob/master/examples/ranges.cpp): App to demonstrate exclusionary option groups based on [Issue #88](https://github.com/CLIUtils/CLI11/issues/88)
|
||||
* [shapes](https://github.com/CLIUtils/CLI11/blob/master/examples/shapes.cpp): Illustrating how to set up repeated subcommands Based on [gitter discussion](https://gitter.im/CLI11gitter/Lobby?at=5c7af6b965ffa019ea788cd5)
|
||||
* [simple](https://github.com/CLIUtils/CLI11/blob/master/examples/simple.cpp): A simple example of how to set up a CLI11 Application with different flags and options
|
||||
* [subcom_help](https://github.com/CLIUtils/CLI11/blob/master/examples/subcom_help.cpp): Configuring help for subcommands
|
||||
* [subcom_partitioned](https://github.com/CLIUtils/CLI11/blob/master/examples/subcom_partitioned.cpp): Example with a timer and subcommands generated separately and added to the main app later.
|
||||
* [subcommands](https://github.com/CLIUtils/CLI11/blob/master/examples/subcommands.cpp): Short example of subcommands
|
||||
* [validators](https://github.com/CLIUtils/CLI11/blob/master/examples/validators.cpp): Example illustrating use of validators
|
||||
|
||||
## Contribute
|
||||
|
||||
@ -910,7 +917,6 @@ This readme roughly follows the [Standard Readme Style][] and includes a mention
|
||||
|
||||
This project was created by [Henry Schreiner](https://github.com/henryiii) and major features were added by [Philip Top](https://github.com/phlptp). Special thanks to all the contributors ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
|
||||
|
||||
|
||||
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
||||
<!-- prettier-ignore-start -->
|
||||
<!-- markdownlint-disable -->
|
||||
@ -987,7 +993,6 @@ This project was created by [Henry Schreiner](https://github.com/henryiii) and m
|
||||
<!-- prettier-ignore-end -->
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
||||
|
||||
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
|
||||
|
||||
## License
|
||||
|
@ -1,6 +1,5 @@
|
||||
# Advanced topics
|
||||
|
||||
|
||||
## Environment variables
|
||||
|
||||
Environment variables can be used to fill in the value of an option:
|
||||
@ -9,6 +8,7 @@ Environment variables can be used to fill in the value of an option:
|
||||
std::string opt;
|
||||
app.add_option("--my_option", opt)->envname("MY_OPTION");
|
||||
```
|
||||
|
||||
If not given on the command line, the environment variable will be checked and read from if it exists. All the standard tools, like default and required, work as expected.
|
||||
If passed on the command line, this will ignore the environment variable.
|
||||
|
||||
@ -55,7 +55,7 @@ add_option(CLI::App &app, std::string name, cx &variable, std::string descriptio
|
||||
|
||||
Then you could use it like this:
|
||||
|
||||
```
|
||||
```cpp
|
||||
std::complex<double> comp{0, 0};
|
||||
add_option(app, "-c,--complex", comp);
|
||||
```
|
||||
@ -89,7 +89,6 @@ template <typename T> std::istringstream &operator>>(std::istringstream &in, boo
|
||||
|
||||
This is an example of how to use the system only; if you are just looking for a way to activate `boost::optional` support on older compilers, you should define `CLI11_BOOST_OPTIONAL` before including a CLI11 file, you'll get the `boost::optional` support.
|
||||
|
||||
|
||||
## Custom converters and type names: std::chrono example
|
||||
|
||||
An example of adding a custom converter and typename for `std::chrono` follows:
|
||||
@ -97,40 +96,40 @@ An example of adding a custom converter and typename for `std::chrono` follows:
|
||||
```cpp
|
||||
namespace CLI
|
||||
{
|
||||
template <typename T, typename R>
|
||||
std::istringstream &operator>>(std::istringstream &in, std::chrono::duration<T,R> &val)
|
||||
{
|
||||
T v;
|
||||
in >> v;
|
||||
val = std::chrono::duration<T,R>(v);
|
||||
return in;
|
||||
}
|
||||
template <typename T, typename R>
|
||||
std::istringstream &operator>>(std::istringstream &in, std::chrono::duration<T,R> &val)
|
||||
{
|
||||
T v;
|
||||
in >> v;
|
||||
val = std::chrono::duration<T,R>(v);
|
||||
return in;
|
||||
}
|
||||
|
||||
template <typename T, typename R>
|
||||
std::stringstream &operator<<(std::stringstream &in, std::chrono::duration<T,R> &val)
|
||||
{
|
||||
in << val.count();
|
||||
return in;
|
||||
}
|
||||
template <typename T, typename R>
|
||||
std::stringstream &operator<<(std::stringstream &in, std::chrono::duration<T,R> &val)
|
||||
{
|
||||
in << val.count();
|
||||
return in;
|
||||
}
|
||||
}
|
||||
|
||||
#include <CLI/CLI.hpp>
|
||||
|
||||
namespace CLI
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template <>
|
||||
constexpr const char *type_name<std::chrono::hours>()
|
||||
{
|
||||
return "TIME [H]";
|
||||
}
|
||||
namespace detail
|
||||
{
|
||||
template <>
|
||||
constexpr const char *type_name<std::chrono::hours>()
|
||||
{
|
||||
return "TIME [H]";
|
||||
}
|
||||
|
||||
template <>
|
||||
constexpr const char *type_name<std::chrono::minutes>()
|
||||
{
|
||||
return "TIME [MIN]";
|
||||
}
|
||||
template <>
|
||||
constexpr const char *type_name<std::chrono::minutes>()
|
||||
{
|
||||
return "TIME [MIN]";
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
@ -1,7 +1,5 @@
|
||||
# Making a git clone
|
||||
|
||||
|
||||
|
||||
Let's try our hand at a little `git` clone, called `geet`. It will just print it's intent, rather than running actual code, since it's just a demonstration. Let's start by adding an app and requiring 1 subcommand to run:
|
||||
|
||||
[include:"Intro"](../code/geet.cpp)
|
||||
|
@ -5,36 +5,42 @@
|
||||
You can tell your app to allow configure files with `set_config("--config")`. There are arguments: the first is the option name. If empty, it will clear the config flag. The second item is the default file name. If that is specified, the config will try to read that file. The third item is the help string, with a reasonable default, and the final argument is a boolean (default: false) that indicates that the configuration file is required and an error will be thrown if the file is not found and this is set to true.
|
||||
|
||||
### Extra fields
|
||||
|
||||
Sometimes configuration files are used for multiple purposes so CLI11 allows options on how to deal with extra fields
|
||||
|
||||
```cpp
|
||||
app.allow_config_extras(true);
|
||||
```
|
||||
|
||||
will allow capture the extras in the extras field of the app. (NOTE: This also sets the `allow_extras` in the app to true)
|
||||
|
||||
```cpp
|
||||
app.allow_config_extras(false);
|
||||
```
|
||||
will generate an error if there are any extra fields
|
||||
|
||||
for slightly finer control there is a scoped enumeration of the modes
|
||||
or
|
||||
will generate an error if there are any extra fields
|
||||
for slightly finer control there is a scoped enumeration of the modes or
|
||||
|
||||
```cpp
|
||||
app.allow_config_extras(CLI::config_extras_mode::ignore);
|
||||
```
|
||||
|
||||
will completely ignore extra parameters in the config file. This mode is the default.
|
||||
|
||||
```cpp
|
||||
app.allow_config_extras(CLI::config_extras_mode::capture);
|
||||
```
|
||||
|
||||
will store the unrecognized options in the app extras fields. This option is the closest equivalent to `app.allow_config_extras(true);` with the exception that it does not also set the `allow_extras` flag so using this option without also setting `allow_extras(true)` will generate an error which may or may not be the desired behavior.
|
||||
|
||||
```cpp
|
||||
app.allow_config_extras(CLI::config_extras_mode::error);
|
||||
```
|
||||
|
||||
is equivalent to `app.allow_config_extras(false);`
|
||||
|
||||
### Getting the used configuration file name
|
||||
|
||||
If it is needed to get the configuration file name used this can be obtained via
|
||||
`app.get_config_ptr()->as<std::string>()` or
|
||||
`app["--config"]->as<std::string>()` assuming `--config` was the configuration option name.
|
||||
@ -93,7 +99,6 @@ Where X is some positive integer and will allow up to `X` configuration files to
|
||||
To print a configuration file from the passed arguments, use `.config_to_str(default_also=false, write_description=false)`, where `default_also` will also show any defaulted arguments, and `write_description` will include option descriptions and the App description
|
||||
|
||||
```cpp
|
||||
|
||||
CLI::App app;
|
||||
app.add_option(...);
|
||||
// several other options
|
||||
@ -105,7 +110,6 @@ To print a configuration file from the passed arguments, use `.config_to_str(def
|
||||
if a prefix is needed to print before the options, for example to print a config for just a subcommand, the config formatter can be obtained directly.
|
||||
|
||||
```cpp
|
||||
|
||||
auto fmtr=app.get_config_formatter();
|
||||
//std::string to_config(const App *app, bool default_also, bool write_description, std::string prefix)
|
||||
fmtr->to_config(&app,true,true,"sub.");
|
||||
@ -113,7 +117,9 @@ if a prefix is needed to print before the options, for example to print a config
|
||||
```
|
||||
|
||||
### Customization of configure file output
|
||||
|
||||
The default config parser/generator has some customization points that allow variations on the TOML format. The default formatter has a base configuration that matches the TOML format. It defines 5 characters that define how different aspects of the configuration are handled
|
||||
|
||||
```cpp
|
||||
/// the character used for comments
|
||||
char commentChar = '#';
|
||||
@ -129,12 +135,12 @@ char valueDelimiter = '=';
|
||||
|
||||
These can be modified via setter functions
|
||||
|
||||
- ` ConfigBase *comment(char cchar)` Specify the character to start a comment block
|
||||
- `ConfigBase *arrayBounds(char aStart, char aEnd)` Specify the start and end characters for an array
|
||||
- `ConfigBase *arrayDelimiter(char aSep)` Specify the delimiter character for an array
|
||||
- `ConfigBase *valueSeparator(char vSep)` Specify the delimiter between a name and value
|
||||
* `ConfigBase *comment(char cchar)`: Specify the character to start a comment block
|
||||
* `ConfigBase *arrayBounds(char aStart, char aEnd)`: Specify the start and end characters for an array
|
||||
* `ConfigBase *arrayDelimiter(char aSep)`: Specify the delimiter character for an array
|
||||
* `ConfigBase *valueSeparator(char vSep)`: Specify the delimiter between a name and value
|
||||
|
||||
For example to specify reading a configure file that used `:` to separate name and values
|
||||
For example, to specify reading a configure file that used `:` to separate name and values:
|
||||
|
||||
```cpp
|
||||
auto config_base=app.get_config_formatter_base();
|
||||
@ -142,9 +148,11 @@ config_base->valueSeparator(':');
|
||||
```
|
||||
|
||||
The default configuration file will read INI files, but will write out files in the TOML format. To specify outputting INI formatted files use
|
||||
|
||||
```cpp
|
||||
app.config_formatter(std::make_shared<CLI::ConfigINI>());
|
||||
```
|
||||
|
||||
which makes use of a predefined modification of the ConfigBase class which TOML also uses. If a custom formatter is used that is not inheriting from the from ConfigBase class `get_config_formatter_base() will return a nullptr if RTTI is on (usually the default), or garbage if RTTI is off, so some care must be exercised in its use with custom configurations.
|
||||
|
||||
## Custom formats
|
||||
@ -166,16 +174,17 @@ app.config_formatter(std::make_shared<NewConfig>());
|
||||
|
||||
See [`examples/json.cpp`](https://github.com/CLIUtils/CLI11/blob/master/examples/json.cpp) for a complete JSON config example.
|
||||
|
||||
|
||||
## Triggering Subcommands
|
||||
|
||||
Configuration files can be used to trigger subcommands if a subcommand is set to configure. By default configuration file just set the default values of a subcommand. But if the `configure()` option is set on a subcommand then the if the subcommand is utilized via a `[subname]` block in the configuration file it will act as if it were called from the command line. Subsubcommands can be triggered via [subname.subsubname]. Using the `[[subname]]` will be as if the subcommand were triggered multiple times from the command line. This functionality can allow the configuration file to act as a scripting file.
|
||||
|
||||
For custom configuration files this behavior can be triggered by specifying the parent subcommands in the structure and `++` as the name to open a new subcommand scope and `--` to close it. These names trigger the different callbacks of configurable subcommands.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The config file input works with any form of the option given: Long, short, positional, or the environment variable name. When generating a config file it will create a name in following priority.
|
||||
|
||||
1. First long name
|
||||
2. Positional name
|
||||
3. First short name
|
||||
4. Environment name
|
||||
1. First long name
|
||||
2. Positional name
|
||||
3. First short name
|
||||
4. Environment name
|
||||
|
@ -13,7 +13,6 @@ app.add_flag("-f", my_flag, "Optional description");
|
||||
|
||||
This will bind the flag `-f` to the boolean `my_flag`. After the parsing step, `my_flag` will be `false` if the flag was not found on the command line, or `true` if it was. By default, it will be allowed any number of times, but if you explicitly[^1] request `->take_last(false)`, it will only be allowed once; passing something like `./my_app -f -f` or `./my_app -ff` will throw a `ParseError` with a nice help description.
|
||||
|
||||
|
||||
## Integer flags
|
||||
|
||||
If you want to allow multiple flags, simply use any integer-like instead of a bool:
|
||||
@ -70,7 +69,6 @@ auto callback = [](int count){std::cout << "This was called " << count << " time
|
||||
app.add_flag_function("-c", callback, "Optional description");
|
||||
```
|
||||
|
||||
|
||||
## Aliases
|
||||
|
||||
The name string, the first item of every `add_` method, can contain as many short and long names as you want, separated by commas. For example, `"-a,--alpha,-b,--beta"` would allow any of those to be recognized on the command line. If you use the same name twice, or if you use the same name in multiple flags, CLI11 will immediately throw a `CLI::ConstructionError` describing your problem (it will not wait until the parsing step).
|
||||
@ -122,5 +120,4 @@ Flag int: 3
|
||||
Flag plain: 1
|
||||
```
|
||||
|
||||
|
||||
[^1]: It will not inherit this from the parent defaults, since this is often useful even if you don't want all options to allow multiple passed options.
|
||||
|
@ -4,13 +4,12 @@
|
||||
New in CLI11 1.6
|
||||
{% endhint %}
|
||||
|
||||
## Customizing an existing formatter
|
||||
## Customizing an existing formatter
|
||||
|
||||
In CLI11, you can control the output of the help printout in full or in part. The default formatter was written in such a way as to be customizable. You can use `app.get_formatter()` to get the current formatter. The formatter you set will be inherited by subcommands that are created after you set the formatter.
|
||||
|
||||
There are several configuration options that you can set:
|
||||
|
||||
|
||||
| Set method | Description | Availability |
|
||||
|------------|-------------|--------------|
|
||||
| `column_width(width)` | The width of the columns | Both |
|
||||
@ -60,7 +59,7 @@ This is a normal printout, with `<>` indicating the methods used to produce each
|
||||
|
||||
The `make_groups` print the group name then call `make_option(o)` on the options listed in that group. The normal printout for an option looks like this:
|
||||
|
||||
```
|
||||
```text
|
||||
make_option_opts(o)
|
||||
┌───┴────┐
|
||||
-n,--name (REQUIRED) This is a description
|
||||
|
@ -1,8 +1,8 @@
|
||||
# Options
|
||||
|
||||
## Simple options
|
||||
The most versatile addition to a command line program is a option. This is like a flag, but it takes an argument. CLI11 handles all the details for many types of options for you, based on their type. To add an option:
|
||||
|
||||
The most versatile addition to a command line program is a option. This is like a flag, but it takes an argument. CLI11 handles all the details for many types of options for you, based on their type. To add an option:
|
||||
|
||||
```cpp
|
||||
int int_option{0};
|
||||
@ -73,6 +73,7 @@ Vectors will be replaced by the parsed content if the option is given on the com
|
||||
A definition of a container for purposes of CLI11 is a type with a `end()`, `insert(...)`, `clear()` and `value_type` definitions. This includes `vector`, `set`, `deque`, `list`, `forward_iist`, `map`, `unordered_map` and a few others from the standard library, and many other containers from the boost library.
|
||||
|
||||
### Containers of containers
|
||||
|
||||
Containers of containers are also supported.
|
||||
|
||||
```cpp
|
||||
@ -85,6 +86,7 @@ CLI11 inserts a separator sequence at the start of each argument call to separat
|
||||
```bash
|
||||
cmd --vec_of_vec 1 2 3 4 %% 1 2
|
||||
```
|
||||
|
||||
would then result in a container of size 2 with the first element containing 4 values and the second 2.
|
||||
|
||||
This separator is also the only way to get values into something like
|
||||
@ -99,7 +101,9 @@ without calling the argument twice.
|
||||
Further levels of nesting containers should compile but intermediate layers will only have a single element in the container, so is probably not that useful.
|
||||
|
||||
### Nested types
|
||||
Types can be nested For example
|
||||
|
||||
Types can be nested. For example:
|
||||
|
||||
```cpp
|
||||
std::map<int, std::pair<int,std::string>> map;
|
||||
app.add_option("--dict", map, "map of pairs");
|
||||
@ -111,6 +115,7 @@ will require 3 arguments for each invocation, and multiple sets of 3 arguments c
|
||||
std::map<int, std::pair<int,std::vector<std::string>>> map;
|
||||
app.add_option("--dict", map, "map of pairs");
|
||||
```
|
||||
|
||||
will result in a requirement for 2 integers on each invocation and absorb an unlimited number of strings including 0.
|
||||
|
||||
## Option modifiers
|
||||
@ -166,19 +171,19 @@ if(* opt)
|
||||
|
||||
One of CLI11's systems to allow customizability without high levels of verbosity is the inheritance system. You can set default values on the parent `App`, and all options and subcommands created from it remember the default values at the point of creation. The default value for Options, specifically, are accessible through the `option_defaults()` method. There are a number of settings that can be set and inherited:
|
||||
|
||||
* `group`: The group name starts as "Options"
|
||||
* `required`: If the option must be given. Defaults to `false`. Is ignored for flags.
|
||||
* `multi_option_policy`: What to do if several copies of an option are passed and one value is expected. Defaults to `CLI::MultiOptionPolicy::Throw`. This is also used for bool flags, but they always are created with the value `CLI::MultiOptionPolicy::TakeLast` regardless of the default, so that multiple bool flags does not cause an error. But you can override that flag by flag.
|
||||
* `ignore_case`: Allow any mixture of cases for the option or flag name
|
||||
* `ignore_underscore`: Allow any number of underscores in the option or flag name
|
||||
* `configurable`: Specify whether an option can be configured through a config file
|
||||
* `disable_flag_override`: do not allow flag values to be overridden on the command line
|
||||
* `always_capture_default`: specify that the default values should be automatically captured.
|
||||
* `delimiter`: A delimiter to use for capturing multiple values in a single command line string (e.g. --flag="flag,-flag2,flag3")
|
||||
* `group`: The group name starts as "Options"
|
||||
* `required`: If the option must be given. Defaults to `false`. Is ignored for flags.
|
||||
* `multi_option_policy`: What to do if several copies of an option are passed and one value is expected. Defaults to `CLI::MultiOptionPolicy::Throw`. This is also used for bool flags, but they always are created with the value `CLI::MultiOptionPolicy::TakeLast` regardless of the default, so that multiple bool flags does not cause an error. But you can override that flag by flag.
|
||||
* `ignore_case`: Allow any mixture of cases for the option or flag name
|
||||
* `ignore_underscore`: Allow any number of underscores in the option or flag name
|
||||
* `configurable`: Specify whether an option can be configured through a config file
|
||||
* `disable_flag_override`: do not allow flag values to be overridden on the command line
|
||||
* `always_capture_default`: specify that the default values should be automatically captured.
|
||||
* `delimiter`: A delimiter to use for capturing multiple values in a single command line string (e.g. --flag="flag,-flag2,flag3")
|
||||
|
||||
An example of usage:
|
||||
|
||||
```
|
||||
```cpp
|
||||
app.option_defaults()->ignore_case()->group("Required");
|
||||
|
||||
app.add_flag("--CaSeLeSs");
|
||||
@ -187,17 +192,16 @@ app.get_group() // is "Required"
|
||||
|
||||
Groups are mostly for visual organization, but an empty string for a group name will hide the option.
|
||||
|
||||
|
||||
### Windows style options
|
||||
|
||||
You can also set the app setting `app->allow_windows_style_options()` to allow windows style options to also be recognized on the command line:
|
||||
|
||||
* `/a` (flag)
|
||||
* `/f filename` (option)
|
||||
* `/long` (long flag)
|
||||
* `/file filename` (space)
|
||||
* `/file:filename` (colon)
|
||||
* `/long_flag:false` (long flag with : to override the default value)
|
||||
* `/a` (flag)
|
||||
* `/f filename` (option)
|
||||
* `/long` (long flag)
|
||||
* `/file filename` (space)
|
||||
* `/file:filename` (colon)
|
||||
* `/long_flag:false` (long flag with : to override the default value)
|
||||
|
||||
Windows style options do not allow combining short options or values not separated from the short option like with `-` options. You still specify option names in the same manner as on Linux with single and double dashes when you use the `add_*` functions, and the Linux style on the command line will still work. If a long and a short option share the same name, the option will match on the first one defined.
|
||||
|
||||
@ -205,15 +209,19 @@ Windows style options do not allow combining short options or values not separat
|
||||
|
||||
How an option and its arguments are parsed depends on a set of controls that are part of the option structure. In most circumstances these controls are set automatically based on the type or function used to create the option and the type the arguments are parsed into. The variables define the size of the underlying type (essentially how many strings make up the type), the expected size (how many groups are expected) and a flag indicating if multiple groups are allowed with a single option. And these interact with the `multi_option_policy` when it comes time to parse.
|
||||
|
||||
### examples
|
||||
How options manage this is best illustrated through some examples
|
||||
### Examples
|
||||
|
||||
How options manage this is best illustrated through some examples.
|
||||
|
||||
```cpp
|
||||
std::string val;
|
||||
app.add_option("--opt",val,"description");
|
||||
```
|
||||
|
||||
creates an option that assigns a value to a `std::string` When this option is constructed it sets a type_size min and max of 1. Meaning that the assignment uses a single string. The Expected size is also set to 1 by default, and `allow_extra_args` is set to false. meaning that each time this option is called 1 argument is expected. This would also be the case if val were a `double`, `int` or any other single argument types.
|
||||
|
||||
now for example
|
||||
|
||||
```cpp
|
||||
std::pair<int, std::string> val;
|
||||
app.add_option("--opt",val,"description");
|
||||
@ -232,6 +240,7 @@ detects a type size of 1, since the underlying element type is a single string,
|
||||
std::vector<std::tuple<int, double, std::string>> val;
|
||||
app.add_option("--opt",val,"description");
|
||||
```
|
||||
|
||||
gets into the complicated cases where the type size is now 3. and the expected max is set to a large number and `allow_extra_args` is set to true. In this case at least 3 arguments are required to follow the option, and subsequent groups must come in groups of three, otherwise an error will result.
|
||||
|
||||
```cpp
|
||||
@ -248,11 +257,11 @@ app.add_option("--opt",val,"description");
|
||||
|
||||
triggers the complex number type which has a min of 1 and max of 2, so 1 or 2 strings can be passed. Complex number conversion supports arguments of the form "1+2j" or "1","2", or "1" "2i". The imaginary number symbols `i` and `j` are interchangeable in this context.
|
||||
|
||||
|
||||
```cpp
|
||||
std::vector<std::vector<int>> val;
|
||||
app.add_option("--opt",val,"description");
|
||||
```
|
||||
|
||||
has a type size of 1 to (1<<30).
|
||||
|
||||
### Customization
|
||||
@ -264,10 +273,13 @@ std::string val;
|
||||
auto opt=app.add_flag("--opt{vvv}",val,"description");
|
||||
opt->expected(0,1);
|
||||
```
|
||||
|
||||
will create a hybrid option, that can exist on its own in which case the value "vvv" is used or if a value is given that value will be used.
|
||||
|
||||
There are some additional options that can be specified to modify an option for specific cases
|
||||
- `->run_callback_for_default()` will specify that the callback should be executed when a default_val is set. This is set automatically when appropriate though it can be turned on or off and any user specified callback for an option will be executed when the default value for an option is set.
|
||||
There are some additional options that can be specified to modify an option for specific cases:
|
||||
|
||||
* `->run_callback_for_default()` will specify that the callback should be executed when a default_val is set. This is set automatically when appropriate though it can be turned on or off and any user specified callback for an option will be executed when the default value for an option is set.
|
||||
|
||||
## Unusual circumstances
|
||||
|
||||
There are a few cases where some things break down in the type system managing options and definitions. Using the `add_option` method defines a lambda function to extract a default value if required. In most cases this either straightforward or a failure is detected automatically and handled. But in a few cases a streaming template is available that several layers down may not actually be defined. The conditions in CLI11 cannot detect this circumstance automatically and will result in compile error. One specific known case is `boost::optional` if the boost optional_io header is included. This header defines a template for all boost optional values even if they do no actually have a streaming operator. For example `boost::optional<std::vector>` does not have a streaming operator but one is detected since it is part of a template. For these cases a secondary method `app->add_option_no_stream(...)` is provided that bypasses this operation completely and should compile in these cases.
|
||||
|
@ -53,6 +53,7 @@ Each App has controls to set the number of subcommands you expect. This is contr
|
||||
```cpp
|
||||
app.require_subcommand(/* min */ 0, /* max */ 1);
|
||||
```
|
||||
|
||||
If you set the max to 0, CLI11 will allow an unlimited number of subcommands. After the (non-unlimited) maximum
|
||||
is reached, CLI11 will stop trying to match subcommands. So the if you pass "`one two`" to a command, and both `one`
|
||||
and `two` are subcommands, it will depend on the maximum number as to whether the "`two`" is a subcommand or an argument to the
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
CLI11 was designed to be integrate into a toolkit, providing a native experience for users. This was used in GooFit to provide `GooFit::Application`, an class designed to make ROOT users feel at home.
|
||||
|
||||
# Custom namespace
|
||||
## Custom namespace
|
||||
|
||||
If you want to provide CLI11 in a custom namespace, you'll want to at least put `using CLI::App` in your namespace. You can also include Option, some errors, and validators. You can also put `using namespace CLI` inside your namespace to import everything.
|
||||
|
||||
@ -17,14 +17,12 @@ You may also want to make your own copy of the `CLI11_PARSE` macro. Something li
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
# Subclassing App
|
||||
## Subclassing App
|
||||
|
||||
If you subclass `App`, you'll just need to do a few things. You'll need a constructor; calling the base `App` constructor is a good idea, but not necessary (it just sets a description and adds a help flag.
|
||||
|
||||
You can call anything you would like to configure in the constructor, like `option_defaults()->take_last()` or `fallthrough()`, and it will be set on all user instances. You can add flags and options, as well.
|
||||
|
||||
|
||||
# Virtual functions provided
|
||||
## Virtual functions provided
|
||||
|
||||
You are given a few virtual functions that you can change (only on the main App). `pre_callback` runs right before the callbacks run, letting you print out custom messages at the top of your app.
|
||||
|
@ -49,7 +49,6 @@ The built-in validators for CLI11 are:
|
||||
| `NonexistentPath` | Check for an non-existing path |
|
||||
| `Range(min=0, max)` | Produce a range (factory). Min and max are inclusive. |
|
||||
|
||||
|
||||
And, the protected members that you can set when you make your own are:
|
||||
|
||||
| Type | Member | Description |
|
||||
|
@ -14,7 +14,6 @@ The main classes are:
|
||||
|CLI::Timer | A timer class, only in CLI/Timer.hpp (not in `CLI11.hpp`) |
|
||||
|CLI::AutoTimer | A timer that prints on deletion |
|
||||
|
||||
|
||||
Groups of related topics:
|
||||
|
||||
| Name | Description |
|
||||
|
8
scripts/mdlint_style.rb
Normal file
8
scripts/mdlint_style.rb
Normal file
@ -0,0 +1,8 @@
|
||||
all
|
||||
|
||||
exclude_rule 'MD013' # Line length
|
||||
exclude_rule 'MD033' # Inline HTML
|
||||
exclude_rule 'MD034' # Bare URL (for now)
|
||||
|
||||
rule 'MD026', punctuation: '.,;:!' # Trailing punctuation in header (& in this case)
|
||||
rule 'MD029', style: :ordered
|
Loading…
x
Reference in New Issue
Block a user