1
0
mirror of https://github.com/CLIUtils/CLI11.git synced 2025-04-29 20:23:55 +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

@ -69,7 +69,7 @@ IndentWidth: 4
# PenaltyReturnTypeOnItsOwnLine: 60 # PenaltyReturnTypeOnItsOwnLine: 60
# PointerAlignment: Right # PointerAlignment: Right
# ReflowComments: true # ReflowComments: true
SortIncludes: false SortIncludes: true
# SpaceAfterCStyleCast: false # SpaceAfterCStyleCast: false
# SpaceAfterTemplateKeyword: true # SpaceAfterTemplateKeyword: true
# SpaceBeforeAssignmentOperators: true # SpaceBeforeAssignmentOperators: true

View File

@ -15,7 +15,24 @@ variables:
jobs: 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: 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" 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 cli11.options: -DCLANG_TIDY_FIX=ON
@ -26,8 +43,6 @@ jobs:
vmImage: 'ubuntu-16.04' vmImage: 'ubuntu-16.04'
container: silkeh/clang:5 container: silkeh/clang:5
steps: steps:
- script: scripts/check_style.sh
displayName: Check format
- template: .ci/azure-cmake.yml - template: .ci/azure-cmake.yml
- template: .ci/azure-build.yml - template: .ci/azure-build.yml
- script: git diff --exit-code --color - script: git diff --exit-code --color

View File

@ -2,6 +2,7 @@ from conans import ConanFile, CMake
from conans.tools import load from conans.tools import load
import re import re
def get_version(): def get_version():
try: try:
content = load("include/CLI/Version.hpp") content = load("include/CLI/Version.hpp")
@ -10,6 +11,7 @@ def get_version():
except Exception: except Exception:
return None return None
class CLI11Conan(ConanFile): class CLI11Conan(ConanFile):
name = "CLI11" name = "CLI11"
version = get_version() version = get_version()
@ -21,9 +23,17 @@ class CLI11Conan(ConanFile):
license = "BSD-3-Clause" license = "BSD-3-Clause"
settings = "os", "compiler", "arch", "build_type" 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 = CMake(self)
cmake.definitions["CLI11_EXAMPLES"] = "OFF" cmake.definitions["CLI11_EXAMPLES"] = "OFF"
cmake.definitions["CLI11_SINGLE_FILE"] = "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 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 using iteration_type_t = typename detail::pair_adaptor<element_t>::value_type; // the type of the object pair
std::string out(1, '{'); std::string out(1, '{');
out.append(detail::join(detail::smart_deref(set), out.append(detail::join(
[](const iteration_type_t &v) { return detail::pair_adaptor<element_t>::first(v); }, detail::smart_deref(set),
",")); [](const iteration_type_t &v) { return detail::pair_adaptor<element_t>::first(v); },
","));
out.push_back('}'); out.push_back('}');
return out; 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 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 using iteration_type_t = typename detail::pair_adaptor<element_t>::value_type; // the type of the object pair
std::string out(1, '{'); std::string out(1, '{');
out.append(detail::join(detail::smart_deref(map), out.append(detail::join(
[key_only](const iteration_type_t &v) { detail::smart_deref(map),
std::string res{detail::to_string(detail::pair_adaptor<element_t>::first(v))}; [key_only](const iteration_type_t &v) {
std::string res{detail::to_string(detail::pair_adaptor<element_t>::first(v))};
if(!key_only) { if(!key_only) {
res.append("->"); res.append("->");
res += detail::to_string(detail::pair_adaptor<element_t>::second(v)); res += detail::to_string(detail::pair_adaptor<element_t>::second(v));
} }
return res; return res;
}, },
",")); ","));
out.push_back('}'); out.push_back('}');
return out; 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) /// You can pass in as many filter functions as you like, they nest (string only currently)
template <typename T, typename... Args> template <typename T, typename... Args>
IsMember(T &&set, filter_fn_t filter_fn_1, filter_fn_t filter_fn_2, Args &&... other) IsMember(T &&set, filter_fn_t filter_fn_1, filter_fn_t filter_fn_2, Args &&... other)
: IsMember(std::forward<T>(set), : IsMember(
[filter_fn_1, filter_fn_2](std::string a) { return filter_fn_2(filter_fn_1(a)); }, std::forward<T>(set),
other...) {} [filter_fn_1, filter_fn_2](std::string a) { return filter_fn_2(filter_fn_1(a)); },
other...) {}
}; };
/// definition of the default transformation object /// 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 /// You can pass in as many filter functions as you like, they nest
template <typename T, typename... Args> template <typename T, typename... Args>
Transformer(T &&mapping, filter_fn_t filter_fn_1, filter_fn_t filter_fn_2, Args &&... other) Transformer(T &&mapping, filter_fn_t filter_fn_1, filter_fn_t filter_fn_2, Args &&... other)
: Transformer(std::forward<T>(mapping), : Transformer(
[filter_fn_1, filter_fn_2](std::string a) { return filter_fn_2(filter_fn_1(a)); }, std::forward<T>(mapping),
other...) {} [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 /// 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 /// You can pass in as many filter functions as you like, they nest
template <typename T, typename... Args> template <typename T, typename... Args>
CheckedTransformer(T &&mapping, filter_fn_t filter_fn_1, filter_fn_t filter_fn_2, Args &&... other) CheckedTransformer(T &&mapping, filter_fn_t filter_fn_1, filter_fn_t filter_fn_2, Args &&... other)
: CheckedTransformer(std::forward<T>(mapping), : CheckedTransformer(
[filter_fn_1, filter_fn_2](std::string a) { return filter_fn_2(filter_fn_1(a)); }, std::forward<T>(mapping),
other...) {} [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 /// Helper function to allow ignore_case to be passed to IsMember or Transform

View File

@ -3,15 +3,15 @@
import os import os
import re import re
base_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) base_path = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
config_h = os.path.join(base_path, 'include', 'CLI', 'Version.hpp') config_h = os.path.join(base_path, "include", "CLI", "Version.hpp")
data = {'MAJOR': 0, 'MINOR': 0, 'PATCH': 0} data = {"MAJOR": 0, "MINOR": 0, "PATCH": 0}
reg = re.compile(r'^\s*#define\s+CLI11_VERSION_([A-Z]+)\s+([0-9]+).*$') reg = re.compile(r"^\s*#define\s+CLI11_VERSION_([A-Z]+)\s+([0-9]+).*$")
with open(config_h, 'r') as fp: with open(config_h, "r") as fp:
for l in fp: for l in fp:
m = reg.match(l) m = reg.match(l)
if m: if m:
data[m.group(1)] = int(m.group(2)) 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 [^\n]* # Up to end of line
$ # End of a line $ # End of a line
""" """
verbatim_all = re.compile(verbatim_tag_str + "(.*)" + verbatim_tag_str, verbatim_all = re.compile(
re.MULTILINE | re.DOTALL | re.VERBOSE) verbatim_tag_str + "(.*)" + verbatim_tag_str, re.MULTILINE | re.DOTALL | re.VERBOSE
)
DIR = os.path.dirname(os.path.abspath(__file__)) DIR = os.path.dirname(os.path.abspath(__file__))
class HeaderFile(object): class HeaderFile(object):
TAG = "Unknown git revision" TAG = "Unknown git revision"
LICENSE = "// BSD 3 clause" LICENSE = "// BSD 3 clause"
@ -43,7 +45,7 @@ class HeaderFile(object):
self.__class__.VERSION = version.groups()[0] self.__class__.VERSION = version.groups()[0]
# add self.verbatim # 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 = ["\n\n// Verbatim copy from {0}:".format(inc)]
self.verbatim += verbatim_all.findall(inner) self.verbatim += verbatim_all.findall(inner)
inner = verbatim_all.sub("", inner) inner = verbatim_all.sub("", inner)
@ -52,7 +54,7 @@ class HeaderFile(object):
self.headers = set(includes_system.findall(inner)) 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 self.namespace = None
@ -65,11 +67,11 @@ class HeaderFile(object):
@property @property
def header_str(self): 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 @property
def verbatim_str(self): def verbatim_str(self):
return '\n'.join(self.verbatim) return "\n".join(self.verbatim)
def insert_namespace(self, namespace): def insert_namespace(self, namespace):
self.namespace = namespace self.namespace = namespace
@ -79,7 +81,7 @@ class HeaderFile(object):
self.body = self.body.replace(before, after) self.body = self.body.replace(before, after)
def __str__(self): def __str__(self):
result = '''\ result = """\
#pragma once #pragma once
// CLI11: Version {self.VERSION} // CLI11: Version {self.VERSION}
@ -96,21 +98,27 @@ class HeaderFile(object):
// Standard combined includes: // Standard combined includes:
{self.header_str} {self.header_str}
'''.format(self=self) """.format(
self=self
)
if self.namespace: if self.namespace:
result += '\nnamespace ' + self.namespace + ' {\n\n' result += "\nnamespace " + self.namespace + " {\n\n"
result += '{self.verbatim_str}\n{self.body}\n'.format(self=self) result += "{self.verbatim_str}\n{self.body}\n".format(self=self)
if self.namespace: if self.namespace:
result += '} // namespace ' + self.namespace + '\n\n' result += "} // namespace " + self.namespace + "\n\n"
return result 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 # Set tag if possible to class variable
try: 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() out, _ = proc.communicate()
except OSError: except OSError:
pass 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)) base_dir = os.path.abspath(os.path.join(DIR, include_dir))
main_header = os.path.join(base_dir, main_header) 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: 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: with open(main_header) as f:
header = f.read() header = f.read()
@ -134,7 +142,7 @@ def MakeHeader(output, main_header, include_dir = '../include', namespace=None,
single_header = reduce(add, headers) single_header = reduce(add, headers)
if macro is not None: if macro is not None:
before = 'CLI11_' before = "CLI11_"
print("Converting macros", before, "->", macro) print("Converting macros", before, "->", macro)
single_header.macro_replacement(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) print("Adding namespace", namespace)
single_header.insert_namespace(namespace) single_header.insert_namespace(namespace)
with open(output, 'w') as f: with open(output, "w") as f:
f.write(str(single_header)) f.write(str(single_header))
print("Created", output) 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("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(
parser.add_argument("--include", default='../include', help="The include directory") "--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("--namespace", help="Add an optional namespace")
parser.add_argument("--macro", help="Replaces CLI11_ with NEW_PREFIX_") parser.add_argument("--macro", help="Replaces CLI11_ with NEW_PREFIX_")
args = parser.parse_args() args = parser.parse_args()
MakeHeader(args.output, args.main, args.include, args.namespace, args.macro) 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 import local, cli, FG
from plumbum.cmd import curl from plumbum.cmd import curl
FILES = [ 'https://raw.githubusercontent.com/Crascit/DownloadProject/master/DownloadProject.cmake', FILES = [
'https://raw.githubusercontent.com/Crascit/DownloadProject/master/DownloadProject.CMakeLists.cmake.in'] "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 DIR = local.path(__file__).dirname
def download_file(path): def download_file(path):
name = path.split('/')[-1] name = path.split("/")[-1]
(curl[path] > name) & FG (curl[path] > name) & FG
class UpdateDownloadProj(cli.Application): class UpdateDownloadProj(cli.Application):
def main(self): def main(self):
with local.cwd(DIR / '../cmake'): with local.cwd(DIR / "../cmake"):
for f in FILES: for f in FILES:
download_file(f) download_file(f)
if __name__ == "__main__": if __name__ == "__main__":
UpdateDownloadProj() UpdateDownloadProj()

View File

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

View File

@ -162,7 +162,8 @@ TEST_F(TApp, BoostOptionalEnumTest) {
TEST_F(TApp, BoostOptionalVector) { TEST_F(TApp, BoostOptionalVector) {
boost::optional<std::vector<int>> opt; 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); ->expected(3);
run(); run();
EXPECT_FALSE(opt); EXPECT_FALSE(opt);