1
0
mirror of https://github.com/CLIUtils/CLI11.git synced 2025-04-29 12:13:52 +00:00

Adding pre-commit

This commit is contained in:
Henry Fredrick Schreiner 2019-10-23 22:05:23 -04:00 committed by Henry Schreiner
parent 8ecce8fd2c
commit fda6126d7c
16 changed files with 131 additions and 80 deletions

View File

@ -19,7 +19,7 @@ BasedOnStyle: LLVM
# AlwaysBreakTemplateDeclarations: false
BinPackArguments: false
BinPackParameters: false
# BraceWrapping:
# BraceWrapping:
# AfterClass: false
# AfterControlStatement: false
# AfterEnum: false
@ -69,7 +69,7 @@ IndentWidth: 4
# PenaltyReturnTypeOnItsOwnLine: 60
# PointerAlignment: Right
# ReflowComments: true
SortIncludes: false
SortIncludes: true
# SpaceAfterCStyleCast: false
# SpaceAfterTemplateKeyword: true
# SpaceBeforeAssignmentOperators: true

View File

@ -15,7 +15,24 @@ variables:
jobs:
- job: ClangFormatTidy
- job: Formatting
pool:
vmImage: 'ubuntu-16.04'
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '3.7'
architecture: 'x64'
- script: python -m pip install pre-commit
displayName: Install pre-commit
- script: pre-commit run --all
displayName: Run pre-commit
- script: git diff --exit-code
displayName: Display format changes
condition: always()
- job: ClangTidy
variables:
CXX_FLAGS: "-Werror -Wcast-align -Wfloat-equal -Wimplicit-atomic-properties -Wmissing-declarations -Woverlength-strings -Wshadow -Wstrict-selector-match -Wundeclared-selector -Wunreachable-code -std=c++11"
cli11.options: -DCLANG_TIDY_FIX=ON
@ -26,8 +43,6 @@ jobs:
vmImage: 'ubuntu-16.04'
container: silkeh/clang:5
steps:
- script: scripts/check_style.sh
displayName: Check format
- template: .ci/azure-cmake.yml
- template: .ci/azure-build.yml
- script: git diff --exit-code --color

View File

@ -44,10 +44,10 @@ std::vector<CLI::ConfigItem> from_config(std::istream &input) const;
The `CLI::ConfigItem`s that you return are simple structures with a name, a vector of parents, and a vector of results. A optionally customizable `to_flag` method on the formatter lets you change what happens when a ConfigItem turns into a flag.
Finally, set your new class as new config formatter:
Finally, set your new class as new config formatter:
```cpp
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.
See [`examples/json.cpp`](https://github.com/CLIUtils/CLI11/blob/master/examples/json.cpp) for a complete JSON config example.

View File

@ -73,7 +73,7 @@ The values would be used like this:
[include:"usage"](../code/flags.cpp)
[Source code](https://gitlab.com/CLIUtils/CLI11Tutorial/blob/master/code/flags.cpp)
[Source code](https://gitlab.com/CLIUtils/CLI11Tutorial/blob/master/code/flags.cpp)
If you compile and run:

View File

@ -51,7 +51,7 @@ This is a normal printout, with `<>` indicating the methods used to produce each
<make_group(app, "Option Group 2"), false, filter>
...
<make_subcommands(app)>
<make_subcommand(sub1, Mode::Normal)>
<make_subcommand(sub1, Mode::Normal)>
<make_subcommand(sub2, Mode::Normal)>
<make_footer(app)>
```
@ -61,10 +61,10 @@ 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:
```
make_option_opts(o)
┌───┴────┐
-n,--name (REQUIRED) This is a description
└────┬────┘ └──────────┬──────────┘
make_option_opts(o)
┌───┴────┐
-n,--name (REQUIRED) This is a description
└────┬────┘ └──────────┬──────────┘
make_option_name(o,p) make_option_desc(o)
```

View File

@ -1,4 +1,4 @@
# Installation
# Installation
## Single file edition
@ -50,7 +50,7 @@ root:build # cmake ..
root:build # make
Scanning dependencies ...
root:build # make test
[warning]Running tests...
[warning]Running tests...
Test project /CLI11/build
Start 1: HelpersTest
1/10 Test #1: HelpersTest ...................... Passed 0.01 sec

View File

@ -20,7 +20,7 @@ You can use any C++ int-like type, not just `int`. CLI11 understands the followi
| Type | CLI11 |
|-------------|-------|
| int-like | Integer conversion up to 64-bit, can be unsigned |
| int-like | Integer conversion up to 64-bit, can be unsigned |
| float-like | Floating point conversions |
| string-like | Anything else that can be shifted into a StringStream |
| vector-like | A vector of the above three types (see below) |
@ -54,7 +54,7 @@ If you use a vector instead of a plain option, you can accept more than one valu
|-------------------|-----------------|
| `--vec 1 --vec 2` | `--vec 1 2` |
The original version did allow the option system to access information on the grouping of options received, but was removed for simplicity.
The original version did allow the option system to access information on the grouping of options received, but was removed for simplicity.
An example of setting up a vector option:

View File

@ -27,4 +27,4 @@ You can call anything you would like to configure in the constructor, like `opti
# 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.
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.

View File

@ -170,7 +170,7 @@ function(SETUP_TARGET_FOR_COVERAGE)
DEPENDS ${Coverage_DEPENDENCIES}
COMMENT "Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report."
)
# Show where to find the lcov info report
add_custom_command(TARGET ${Coverage_NAME} POST_BUILD
COMMAND ;

View File

@ -2,6 +2,7 @@ from conans import ConanFile, CMake
from conans.tools import load
import re
def get_version():
try:
content = load("include/CLI/Version.hpp")
@ -10,6 +11,7 @@ def get_version():
except Exception:
return None
class CLI11Conan(ConanFile):
name = "CLI11"
version = get_version()
@ -21,9 +23,17 @@ class CLI11Conan(ConanFile):
license = "BSD-3-Clause"
settings = "os", "compiler", "arch", "build_type"
exports_sources = "LICENSE", "README.md", "include/*", "extern/*", "cmake/*", "CMakeLists.txt", "tests/*"
exports_sources = (
"LICENSE",
"README.md",
"include/*",
"extern/*",
"cmake/*",
"CMakeLists.txt",
"tests/*",
)
def build(self): # this is not building a library, just tests
def build(self): # this is not building a library, just tests
cmake = CMake(self)
cmake.definitions["CLI11_EXAMPLES"] = "OFF"
cmake.definitions["CLI11_SINGLE_FILE"] = "OFF"

View File

@ -474,9 +474,10 @@ template <typename T> std::string generate_set(const T &set) {
using element_t = typename detail::element_type<T>::type;
using iteration_type_t = typename detail::pair_adaptor<element_t>::value_type; // the type of the object pair
std::string out(1, '{');
out.append(detail::join(detail::smart_deref(set),
[](const iteration_type_t &v) { return detail::pair_adaptor<element_t>::first(v); },
","));
out.append(detail::join(
detail::smart_deref(set),
[](const iteration_type_t &v) { return detail::pair_adaptor<element_t>::first(v); },
","));
out.push_back('}');
return out;
}
@ -486,17 +487,18 @@ template <typename T> std::string generate_map(const T &map, bool key_only = fal
using element_t = typename detail::element_type<T>::type;
using iteration_type_t = typename detail::pair_adaptor<element_t>::value_type; // the type of the object pair
std::string out(1, '{');
out.append(detail::join(detail::smart_deref(map),
[key_only](const iteration_type_t &v) {
std::string res{detail::to_string(detail::pair_adaptor<element_t>::first(v))};
out.append(detail::join(
detail::smart_deref(map),
[key_only](const iteration_type_t &v) {
std::string res{detail::to_string(detail::pair_adaptor<element_t>::first(v))};
if(!key_only) {
res.append("->");
res += detail::to_string(detail::pair_adaptor<element_t>::second(v));
}
return res;
},
","));
if(!key_only) {
res.append("->");
res += detail::to_string(detail::pair_adaptor<element_t>::second(v));
}
return res;
},
","));
out.push_back('}');
return out;
}
@ -657,9 +659,10 @@ class IsMember : public Validator {
/// You can pass in as many filter functions as you like, they nest (string only currently)
template <typename T, typename... Args>
IsMember(T &&set, filter_fn_t filter_fn_1, filter_fn_t filter_fn_2, Args &&... other)
: IsMember(std::forward<T>(set),
[filter_fn_1, filter_fn_2](std::string a) { return filter_fn_2(filter_fn_1(a)); },
other...) {}
: IsMember(
std::forward<T>(set),
[filter_fn_1, filter_fn_2](std::string a) { return filter_fn_2(filter_fn_1(a)); },
other...) {}
};
/// definition of the default transformation object
@ -717,9 +720,10 @@ class Transformer : public Validator {
/// You can pass in as many filter functions as you like, they nest
template <typename T, typename... Args>
Transformer(T &&mapping, filter_fn_t filter_fn_1, filter_fn_t filter_fn_2, Args &&... other)
: Transformer(std::forward<T>(mapping),
[filter_fn_1, filter_fn_2](std::string a) { return filter_fn_2(filter_fn_1(a)); },
other...) {}
: Transformer(
std::forward<T>(mapping),
[filter_fn_1, filter_fn_2](std::string a) { return filter_fn_2(filter_fn_1(a)); },
other...) {}
};
/// translate named items to other or a value set
@ -793,9 +797,10 @@ class CheckedTransformer : public Validator {
/// You can pass in as many filter functions as you like, they nest
template <typename T, typename... Args>
CheckedTransformer(T &&mapping, filter_fn_t filter_fn_1, filter_fn_t filter_fn_2, Args &&... other)
: CheckedTransformer(std::forward<T>(mapping),
[filter_fn_1, filter_fn_2](std::string a) { return filter_fn_2(filter_fn_1(a)); },
other...) {}
: CheckedTransformer(
std::forward<T>(mapping),
[filter_fn_1, filter_fn_2](std::string a) { return filter_fn_2(filter_fn_1(a)); },
other...) {}
};
/// Helper function to allow ignore_case to be passed to IsMember or Transform

View File

@ -3,15 +3,15 @@
import os
import re
base_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
config_h = os.path.join(base_path, 'include', 'CLI', 'Version.hpp')
data = {'MAJOR': 0, 'MINOR': 0, 'PATCH': 0}
reg = re.compile(r'^\s*#define\s+CLI11_VERSION_([A-Z]+)\s+([0-9]+).*$')
base_path = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
config_h = os.path.join(base_path, "include", "CLI", "Version.hpp")
data = {"MAJOR": 0, "MINOR": 0, "PATCH": 0}
reg = re.compile(r"^\s*#define\s+CLI11_VERSION_([A-Z]+)\s+([0-9]+).*$")
with open(config_h, 'r') as fp:
for l in fp:
m = reg.match(l)
if m:
data[m.group(1)] = int(m.group(2))
with open(config_h, "r") as fp:
for l in fp:
m = reg.match(l)
if m:
data[m.group(1)] = int(m.group(2))
print('{}.{}.{}'.format(data['MAJOR'], data['MINOR'], data['PATCH']))
print("{}.{}.{}".format(data["MAJOR"], data["MINOR"], data["PATCH"]))

View File

@ -24,11 +24,13 @@ CLI11:verbatim # The tag
[^\n]* # Up to end of line
$ # End of a line
"""
verbatim_all = re.compile(verbatim_tag_str + "(.*)" + verbatim_tag_str,
re.MULTILINE | re.DOTALL | re.VERBOSE)
verbatim_all = re.compile(
verbatim_tag_str + "(.*)" + verbatim_tag_str, re.MULTILINE | re.DOTALL | re.VERBOSE
)
DIR = os.path.dirname(os.path.abspath(__file__))
class HeaderFile(object):
TAG = "Unknown git revision"
LICENSE = "// BSD 3 clause"
@ -43,7 +45,7 @@ class HeaderFile(object):
self.__class__.VERSION = version.groups()[0]
# add self.verbatim
if 'CLI11:verbatim' in inner:
if "CLI11:verbatim" in inner:
self.verbatim = ["\n\n// Verbatim copy from {0}:".format(inc)]
self.verbatim += verbatim_all.findall(inner)
inner = verbatim_all.sub("", inner)
@ -52,7 +54,7 @@ class HeaderFile(object):
self.headers = set(includes_system.findall(inner))
self.body = '\n// From {0}:\n\n'.format(inc) + inner[inner.find('namespace'):]
self.body = "\n// From {0}:\n\n".format(inc) + inner[inner.find("namespace") :]
self.namespace = None
@ -65,11 +67,11 @@ class HeaderFile(object):
@property
def header_str(self):
return '\n'.join('#include <'+h+'>' for h in sorted(self.headers))
return "\n".join("#include <" + h + ">" for h in sorted(self.headers))
@property
def verbatim_str(self):
return '\n'.join(self.verbatim)
return "\n".join(self.verbatim)
def insert_namespace(self, namespace):
self.namespace = namespace
@ -79,7 +81,7 @@ class HeaderFile(object):
self.body = self.body.replace(before, after)
def __str__(self):
result = '''\
result = """\
#pragma once
// CLI11: Version {self.VERSION}
@ -96,21 +98,27 @@ class HeaderFile(object):
// Standard combined includes:
{self.header_str}
'''.format(self=self)
""".format(
self=self
)
if self.namespace:
result += '\nnamespace ' + self.namespace + ' {\n\n'
result += '{self.verbatim_str}\n{self.body}\n'.format(self=self)
result += "\nnamespace " + self.namespace + " {\n\n"
result += "{self.verbatim_str}\n{self.body}\n".format(self=self)
if self.namespace:
result += '} // namespace ' + self.namespace + '\n\n'
result += "} // namespace " + self.namespace + "\n\n"
return result
def MakeHeader(output, main_header, include_dir = '../include', namespace=None, macro=None):
def MakeHeader(
output, main_header, include_dir="../include", namespace=None, macro=None
):
# Set tag if possible to class variable
try:
proc = Popen(['git', 'describe', '--tags', '--always'], cwd=str(DIR), stdout=PIPE)
proc = Popen(
["git", "describe", "--tags", "--always"], cwd=str(DIR), stdout=PIPE
)
out, _ = proc.communicate()
except OSError:
pass
@ -120,10 +128,10 @@ def MakeHeader(output, main_header, include_dir = '../include', namespace=None,
base_dir = os.path.abspath(os.path.join(DIR, include_dir))
main_header = os.path.join(base_dir, main_header)
licence_file = os.path.abspath(os.path.join(DIR, '../LICENSE'))
licence_file = os.path.abspath(os.path.join(DIR, "../LICENSE"))
with open(licence_file) as f:
HeaderFile.LICENSE = ''.join('// ' + line for line in f)
HeaderFile.LICENSE = "".join("// " + line for line in f)
with open(main_header) as f:
header = f.read()
@ -134,7 +142,7 @@ def MakeHeader(output, main_header, include_dir = '../include', namespace=None,
single_header = reduce(add, headers)
if macro is not None:
before = 'CLI11_'
before = "CLI11_"
print("Converting macros", before, "->", macro)
single_header.macro_replacement(before, macro)
@ -142,19 +150,25 @@ def MakeHeader(output, main_header, include_dir = '../include', namespace=None,
print("Adding namespace", namespace)
single_header.insert_namespace(namespace)
with open(output, 'w') as f:
with open(output, "w") as f:
f.write(str(single_header))
print("Created", output)
if __name__ == '__main__':
parser = ArgumentParser(usage='Convert source to single header include. Can optionally add namespace and search-replace replacements (for macros).')
if __name__ == "__main__":
parser = ArgumentParser(
usage="Convert source to single header include. Can optionally add namespace and search-replace replacements (for macros)."
)
parser.add_argument("output", help="Single header file output")
parser.add_argument("--main", default='CLI/CLI.hpp', help="The main include file that defines the other files")
parser.add_argument("--include", default='../include', help="The include directory")
parser.add_argument(
"--main",
default="CLI/CLI.hpp",
help="The main include file that defines the other files",
)
parser.add_argument("--include", default="../include", help="The include directory")
parser.add_argument("--namespace", help="Add an optional namespace")
parser.add_argument("--macro", help="Replaces CLI11_ with NEW_PREFIX_")
args = parser.parse_args()
MakeHeader(args.output, args.main, args.include, args.namespace, args.macro)

View File

@ -5,20 +5,25 @@ from __future__ import print_function, division
from plumbum import local, cli, FG
from plumbum.cmd import curl
FILES = [ 'https://raw.githubusercontent.com/Crascit/DownloadProject/master/DownloadProject.cmake',
'https://raw.githubusercontent.com/Crascit/DownloadProject/master/DownloadProject.CMakeLists.cmake.in']
FILES = [
"https://raw.githubusercontent.com/Crascit/DownloadProject/master/DownloadProject.cmake",
"https://raw.githubusercontent.com/Crascit/DownloadProject/master/DownloadProject.CMakeLists.cmake.in",
]
DIR = local.path(__file__).dirname
def download_file(path):
name = path.split('/')[-1]
name = path.split("/")[-1]
(curl[path] > name) & FG
class UpdateDownloadProj(cli.Application):
def main(self):
with local.cwd(DIR / '../cmake'):
with local.cwd(DIR / "../cmake"):
for f in FILES:
download_file(f)
if __name__ == "__main__":
UpdateDownloadProj()

View File

@ -1,6 +1,7 @@
from conans import ConanFile, CMake
import os
class HelloTestConan(ConanFile):
settings = "os", "compiler", "build_type", "arch"
generators = "cmake"

View File

@ -162,7 +162,8 @@ TEST_F(TApp, BoostOptionalEnumTest) {
TEST_F(TApp, BoostOptionalVector) {
boost::optional<std::vector<int>> opt;
app.add_option_function<std::vector<int>>("-v,--vec", [&opt](const std::vector<int> &v) { opt = v; }, "some vector")
app.add_option_function<std::vector<int>>(
"-v,--vec", [&opt](const std::vector<int> &v) { opt = v; }, "some vector")
->expected(3);
run();
EXPECT_FALSE(opt);