Skip to content

Release update #974

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 67 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,79 @@
# Changelog

## Version 2.4: Unicode and TOML support

This version adds Unicode support, support for TOML standard including multiline
strings, digit separators, string escape sequences,and dot notation. An initial
round of a fuzzer was added to testing which has caught several bugs related to
config file processing, and a few other edge cases not previously observed.

- Add Unicode support and bug fixes [#804][], [#923][], [#876][], [#848][],
[#832][], [#987][]
- Match TOML standard for string and numerical entries, multiline strings
[#968][], [#967][],[#964][], [#935][]
- Add validation for environmental variables [#926][]
- Add an escape string transform [#970][]
- Add A REVERSE multi-option policy to support multiple config files and other
applications [#918][]
- Add usage message replacement [#768][]
- Allow using dot notation for subcommand arguments such as `--sub1.field`
[#789][]
- Bugfix: Fuzzing tests and fixes [#930][], [#905][], [#874][], [#846][]
- Bugfix: Missing coverage tests [#928][]
- Bugfix: CMake package and package config tests and fixes [#916][]
- Bugfix: Support for Windows ARM compilation and tests [#913][], [#914][]
- Bugfix: Environmental variable checks in non-triggered subcommands [#904][]
- Bugfix: Environmental variables were not being correctly process by config
pointer [#891][]
- Bugfix: Undefined behavior in `sum_string_vector` [#893][]
- Bugfix: Warnings and updates for CUDA 11 support [#851][]
- Backend: Add tests for newer compilers (lost with Travis CI) [#972][]
- Backend: Increase minimum CMake to 3.5 [#898][]
- Backend: Remove integrated Conan support (provided now by Conan center)
[#853][]
- Tests: Support Catch2 Version 3 [#896][], [#980][]

[#768]: https://github.com/CLIUtils/CLI11/pull/768
[#789]: https://github.com/CLIUtils/CLI11/pull/789
[#804]: https://github.com/CLIUtils/CLI11/pull/804
[#832]: https://github.com/CLIUtils/CLI11/pull/832
[#846]: https://github.com/CLIUtils/CLI11/pull/846
[#848]: https://github.com/CLIUtils/CLI11/pull/848
[#851]: https://github.com/CLIUtils/CLI11/pull/851
[#853]: https://github.com/CLIUtils/CLI11/pull/853
[#874]: https://github.com/CLIUtils/CLI11/pull/874
[#876]: https://github.com/CLIUtils/CLI11/pull/876
[#891]: https://github.com/CLIUtils/CLI11/pull/891
[#893]: https://github.com/CLIUtils/CLI11/pull/893
[#896]: https://github.com/CLIUtils/CLI11/pull/896
[#898]: https://github.com/CLIUtils/CLI11/pull/898
[#904]: https://github.com/CLIUtils/CLI11/pull/904
[#905]: https://github.com/CLIUtils/CLI11/pull/905
[#913]: https://github.com/CLIUtils/CLI11/pull/913
[#914]: https://github.com/CLIUtils/CLI11/pull/914
[#916]: https://github.com/CLIUtils/CLI11/pull/916
[#918]: https://github.com/CLIUtils/CLI11/pull/918
[#923]: https://github.com/CLIUtils/CLI11/pull/923
[#926]: https://github.com/CLIUtils/CLI11/pull/926
[#928]: https://github.com/CLIUtils/CLI11/pull/928
[#930]: https://github.com/CLIUtils/CLI11/pull/930
[#935]: https://github.com/CLIUtils/CLI11/pull/935
[#964]: https://github.com/CLIUtils/CLI11/pull/964
[#967]: https://github.com/CLIUtils/CLI11/pull/967
[#968]: https://github.com/CLIUtils/CLI11/pull/968
[#970]: https://github.com/CLIUtils/CLI11/pull/970
[#972]: https://github.com/CLIUtils/CLI11/pull/972
[#980]: https://github.com/CLIUtils/CLI11/pull/980
[#987]: https://github.com/CLIUtils/CLI11/pull/987

## Version 2.3: Precompilation Support

This version adds a pre-compiled mode to CLI11, which allows you to precompile
the library, saving time on incremental rebuilds, making CLI11 more competitive
on compile time with classic compiled CLI libraries. The header-only mode is
still default, and is not yet distributed via binaries.

- Add `CLI11_PRECOMPILED` as an option. [#762][]
- Add `CLI11_PRECOMPILED` as an option [#762][]
- Bugfix: Include `<functional>` in `FormatterFwd` [#727][]
- Bugfix: Add missing `Macros.hpp` to `Error.hpp` [#755][]
- Bugfix: Fix subcommand callback trigger [#733][]
Expand Down
81 changes: 27 additions & 54 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,8 @@ int main(int argc, char** argv) {
}
```

For more information about 🚧`ensure_utf8` the section on
[Unicode support](#unicode-support) below. The 🚧`ensure_utf8` function is only
For more information about 🆕`ensure_utf8` the section on
[Unicode support](#unicode-support) below. The 🆕`ensure_utf8` function is only
available in main currently and not in a release.

<details><summary>Note: If you don't like macros, this is what that macro expands to: (click to expand)</summary><p>
Expand Down Expand Up @@ -416,7 +416,7 @@ Before parsing, you can set the following options:
option. Options can be removed from the excludes list with
`->remove_excludes(opt)`
- `->envname(name)`: Gets the value from the environment if present and not
passed on the command line. 🚧 The value must also pass any validators to be
passed on the command line. 🆕 The value must also pass any validators to be
used.
- `->group(name)`: The help group to put the option in. No effect for positional
options. Defaults to `"Options"`. Options given an empty string will not show
Expand Down Expand Up @@ -452,7 +452,7 @@ Before parsing, you can set the following options:
are `CLI::MultiOptionPolicy::Throw`, `CLI::MultiOptionPolicy::Throw`,
`CLI::MultiOptionPolicy::TakeLast`, `CLI::MultiOptionPolicy::TakeFirst`,
`CLI::MultiOptionPolicy::Join`, `CLI::MultiOptionPolicy::TakeAll`,
`CLI::MultiOptionPolicy::Sum` 🆕, and `CLI::MultiOptionPolicy::Reverse` 🚧.
`CLI::MultiOptionPolicy::Sum`, and `CLI::MultiOptionPolicy::Reverse` 🆕.
- `->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
Expand Down Expand Up @@ -694,15 +694,15 @@ NOTES: If the container used in `IsMember`, `Transformer`, or
fast search is performed first, and if that fails a linear search with the
filters on the key values is performed.

- `CLI::FileOnDefaultPath(default_path)`: 🆕 can be used to check for files in a
- `CLI::FileOnDefaultPath(default_path)`: can be used to check for files in a
default path. If used as a transform it will first check that a file exists,
if it does nothing further is done, if it does not it tries to add a default
Path to the file and search there again. If the file does not exist an error
is returned normally but this can be disabled using
`CLI::FileOnDefaultPath(default_path, false)`. This allows multiple paths to
be chained using multiple transform calls.

- `CLI::EscapedString`: 🚧 can be used to process an escaped string. The
- `CLI::EscapedString`: 🆕 can be used to process an escaped string. The
processing is equivalent to that used for TOML config files, see
[TOML strings](https://toml.io/en/v1.0.0#string). With 2 notable exceptions.
\` can also be used as a literal string notation, and it also allows binary
Expand Down Expand Up @@ -874,7 +874,7 @@ nameless subcommands are allowed. Callbacks for nameless subcommands are only
triggered if any options from the subcommand were parsed. Subcommand names given
through the `add_subcommand` method have the same restrictions as option names.

🚧 Options or flags in a subcommand may be directly specified using dot notation
🆕 Options or flags in a subcommand may be directly specified using dot notation

- `--subcommand.long=val` (long subcommand option)
- `--subcommand.long val` (long subcommand option)
Expand All @@ -886,7 +886,7 @@ through the `add_subcommand` method have the same restrictions as option names.
The use of dot notation in this form is equivalent `--subcommand.long <args>` =>
`subcommand --long <args> ++`. Nested subcommands also work `sub1.subsub` would
trigger the subsub subcommand in `sub1`. This is equivalent to "sub1 subsub".
Quotes around the subcommand names are permitted 🚧 following the TOML standard
Quotes around the subcommand names are permitted 🆕 following the TOML standard
for such specification. This includes allowing escape sequences. For example
`"subcommand".'f'` or `"subcommand.with.dots".arg1 = value`.

Expand Down Expand Up @@ -926,9 +926,9 @@ option_groups. These are:
before matching. Validation is specified through `transform`, `check`, and
`each` for an option. If an argument fails validation it is not an error and
matching proceeds to the next available positional or extra arguments.
- `.validate_optional_arguments()`:🆕 Specify that optional arguments should
pass validation before being assigned to an option. Validation is specified
through `transform`, `check`, and `each` for an option. If an argument fails
- `.validate_optional_arguments()`: Specify that optional arguments should pass
validation before being assigned to an option. Validation is specified through
`transform`, `check`, and `each` for an option. If an argument fails
validation it is not an error and matching proceeds to the next available
positional subcommand or extra arguments.
- `.excludes(option_or_subcommand)`: If given an option pointer or pointer to
Expand Down Expand Up @@ -1014,9 +1014,9 @@ option_groups. These are:
- `.prefix_command()`: Like `allow_extras`, but stop immediately on the first
unrecognized item. It is ideal for allowing your app or subcommand to be a
"prefix" to calling another app.
- `.usage(message)`: 🚧 Replace text to appear at the start of the help string
- `.usage(message)`: 🆕 Replace text to appear at the start of the help string
after description.
- `.usage(std::string())`: 🚧 Set a callback to generate a string that will
- `.usage(std::string())`: 🆕 Set a callback to generate a string that will
appear at the start of the help string after description.
- `.footer(message)`: Set text to appear at the bottom of the help string.
- `.footer(std::string())`: Set a callback to generate a string that will appear
Expand Down Expand Up @@ -1223,8 +1223,8 @@ is present, it will be read along with the normal command line arguments. The
file will be read if it exists, and does not throw an error unless `required` is
`true`. Configuration files are in [TOML][] format by default, though the
default reader can also accept files in INI format as well. The config reader
can read most aspects of TOML files including strings both literal 🚧 and with
potential escape sequences 🚧, digit separators 🚧, and multi-line strings 🚧,
can read most aspects of TOML files including strings both literal 🆕 and with
potential escape sequences 🆕, digit separators 🆕, and multi-line strings 🆕,
and run them through the CLI11 parser. Other formats can be added by an adept
user, some variations are available through customization points in the default
formatter. An example of a TOML file:
Expand Down Expand Up @@ -1297,9 +1297,9 @@ boolean values are not quoted.

For options or flags which allow 0 arguments to be passed using an empty string
in the config file, `{}`, or `[]` will convert the result to the default value
specified via `default_str` or `default_val` on the option 🆕. If no user
specified default is given the result is an empty string or the converted value
of an empty string.
specified via `default_str` or `default_val` on the option. If no user specified
default is given the result is an empty string or the converted value of an
empty string.

NOTE: Transforms and checks can be used with the option pointer returned from
set_config like any other option to validate the input if needed. It can also be
Expand Down Expand Up @@ -1427,8 +1427,8 @@ CLI11 supports Unicode and wide strings as defined in the

When using the command line on Windows with unicode arguments, your `main`
function may already receive broken Unicode. Parsing `argv` at that point will
not give you a correct string. To fix this, you have three good options and two
bad ones:
not give you a correct string. To fix this, you have three options; the first is
recommended for cross-platform support:

1\. Replace `argv` with `app.ensure_utf8(argv)` before any arguments are parsed.
`ensure_utf8` will do nothing on systems where `argv` is already in UTF-8 (Such
Expand All @@ -1445,40 +1445,13 @@ int main(int argc, char** argv) {
}
```

2\. If you pass unmodified command-line arguments to CLI11, call `app.parse()`
instead of `app.parse(argc, argv)` (or `CLI11_PARSE(app)` instead of
`CLI11_PARSE(app, argc, argv)`). The library will find correct arguments by
itself.
Be sure you do not modify `argv` before this function call, as the correct
values will be reconstructed using Windows APIs and produced by this call. It
has no effect on other platforms and just passes through `argv`.

> [!NOTE]
>
> This approach may not work on weird OS configurations, such as when the
> `/proc` dir is missing on Linux systems (see also
> [#845](https://github.com/CLIUtils/CLI11/issues/845)).
>
> ```cpp
> int main() {
> CLI::App app;
> // ...
> CLI11_PARSE(app);
> }
> ```

3\. Get correct arguments with which the program was originally executed using
provided functions: `CLI::argc()` and `CLI::argv()`. These three methods are the
only cross-platform ways of handling unicode correctly.

```cpp
int main() {
CLI::App app;
// ...
CLI11_PARSE(app, CLI::argc(), CLI::argv());
}
```

<details><summary>Bad options (click to expand)</summary><p>
<details><summary>Other options (click to expand)</summary><p>

4\. Use the Windows-only non-standard `wmain` function, which accepts
2\. Use the Windows-only non-standard `wmain` function, which accepts
`wchar_t *argv[]` instead of `char* argv[]`. Parsing this will allow CLI to
convert wide strings to UTF-8 without losing information.

Expand All @@ -1490,10 +1463,10 @@ int wmain(int argc, wchar_t *argv[]) {
}
```

5\. Retrieve arguments yourself by using Windows APIs like
3\. Retrieve arguments yourself by using Windows APIs like
[`CommandLineToArgvW`](https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-commandlinetoargvw)
and pass them to CLI. This is what the library is doing under the hood in
`CLI::argv()`.
`ensure_utf8`.

</p></details>
</br>
Expand Down