Commit 54114d0948916fe427ed99a83ede6e382cfd230a

Authored by Henry Schreiner
Committed by GitHub
1 parent b88f1f2a

Travis improvements and updates (#28)

* Adding check for style

* Adding reformats

* Fix syntax error in travis

* Support clang-format 3.9

* Adding clang-tidy check
.ci/check_style.sh 0 → 100755
  1 +#!/usr/bin/env sh
  2 +set -evx
  3 +
  4 +clang-format --version
  5 +
  6 +git ls-files -- '*.cpp' '*.hpp' | xargs clang-format -i -style=file
  7 +
  8 +git diff --exit-code --color
  9 +
  10 +mkdir build || true
  11 +cd build
  12 +CXX_FLAGS="-Werror -Wall -Wextra -pedantic -std=c++11" cmake .. -DCLANG_TIDY_FIX=ON
  13 +cmake --build .
  14 +
  15 +git diff --exit-code --color
  16 +
  17 +set +evx
... ...
.ci/prepare_altern.sh
... ... @@ -9,6 +9,8 @@ if [ "$CXX" = "g++" ] ; then
9 9 else
10 10 ln -s `which clang-$COMPILER` clang
11 11 ln -s `which clang++-$COMPILER` clang++
  12 + ln -s `which clang-format-$COMPILER` clang-format
  13 + ln -s `which clang-tidy-$COMPILER` clang-tidy
12 14 fi
13 15  
14 16 export PATH="${DEPS_DIR}/extrabin":$PATH
... ...
.ci/travis.sh
... ... @@ -6,3 +6,5 @@ cd build
6 6 cmake .. -DCLI_SINGLE_FILE_TESTS=ON -DCMAKE_BUILD_TYPE=Debug
7 7 cmake --build . -- -j2
8 8 ctest --output-on-failure
  9 +
  10 +set +evx
... ...
.travis.yml
... ... @@ -13,9 +13,16 @@ matrix:
13 13 - compiler: clang
14 14 addons:
15 15 apt:
16   - sources:
17   - - llvm-toolchain-precise-3.5
18   - - ubuntu-toolchain-r-test
  16 + packages:
  17 + - clang-3.9
  18 + - clang-format-3.9
  19 + - clang-tidy-3.9
  20 + env:
  21 + - COMPILER=3.9
  22 + - CHECK_STYLE=yes
  23 + - compiler: clang
  24 + addons:
  25 + apt:
19 26 packages:
20 27 - clang-3.5
21 28 env:
... ... @@ -37,8 +44,6 @@ matrix:
37 44 - compiler: gcc
38 45 addons:
39 46 apt:
40   - sources:
41   - - ubuntu-toolchain-r-test
42 47 packages:
43 48 - g++-4.7
44 49 env:
... ... @@ -48,19 +53,21 @@ matrix:
48 53 install:
49 54 - python -c 'import sys; print(sys.version_info[:])'
50 55 - DEPS_DIR="${TRAVIS_BUILD_DIR}/deps"
51   -- if [ "$TRAVIS_OS_NAME" = "linux" ]; then cd $TRAVIS_BUILD_DIR && . .ci/prepare_altern.sh
52   - ; fi
53   -- if [ "$TRAVIS_OS_NAME" = "linux" ] ; then cd $TRAVIS_BUILD_DIR && . .ci/build_cmake.sh
54   - ; fi
55   -- if [ "$TRAVIS_OS_NAME" = "linux" ] ; then cd $TRAVIS_BUILD_DIR && . .ci/build_doxygen.sh
56   - ; fi
  56 +- if [ "$TRAVIS_OS_NAME" = "linux" ]; then cd $TRAVIS_BUILD_DIR && . .ci/prepare_altern.sh ; fi
  57 +- if [ "$TRAVIS_OS_NAME" = "linux" ] ; then cd $TRAVIS_BUILD_DIR && . .ci/build_cmake.sh ; fi
  58 +- if [ "$TRAVIS_OS_NAME" = "linux" ] ; then cd $TRAVIS_BUILD_DIR && . .ci/build_doxygen.sh ; fi
57 59 - if [ -n "$COVERALLS" ] ; then cd $TRAVIS_BUILD_DIR && . .ci/build_lcov.sh ; fi
58 60 - cd "${DEPS_DIR}"
59   -- if [ "$(python -c 'import sys; print(sys.version_info[0])')" = "2" ] ; then pip
60   - install --user pathlib; fi
  61 +- if [ "$(python -c 'import sys; print(sys.version_info[0])')" = "2" ] ; then pip install --user pathlib ; fi
61 62 script:
62 63 - cd "${TRAVIS_BUILD_DIR}"
63   -- .ci/travis.sh
  64 +- |
  65 + if [ -n "$CHECK_STYLE" ]
  66 + then
  67 + .ci/check_style.sh
  68 + else
  69 + .ci/travis.sh
  70 + fi
64 71 after_success:
65 72 - if [ -n "$COVERALLS" ] ; then cd $TRAVIS_BUILD_DIR && .ci/run_codecov.sh ; fi
66 73 - echo "${TRAVIS_BRANCH}"
... ... @@ -68,7 +75,7 @@ after_success:
68 75 - |
69 76 if [ "${TRAVIS_BRANCH}" == "master" ] && [ "${TRAVIS_PULL_REQUEST}" == "false" ] && [ -n "$DEPLOY_MAT" ]
70 77 then
71   - echo "Updating docs" && cd $TRAVIS_BUILD_DIR && .ci/build_docs.sh
  78 + echo "Updating docs" && cd $TRAVIS_BUILD_DIR && .ci/build_docs.sh
72 79 fi
73 80 deploy:
74 81 provider: releases
... ...
examples/enum.cpp
1 1 #include <CLI/CLI.hpp>
2 2  
3   -enum Level : std::int32_t {
4   - High,
5   - Medium,
6   - Low
7   -};
  3 +enum Level : std::int32_t { High, Medium, Low };
8 4  
9   -int main(int argc, char** argv) {
  5 +int main(int argc, char **argv) {
10 6 CLI::App app;
11 7  
12 8 Level level;
... ... @@ -15,9 +11,8 @@ int main(int argc, char** argv) {
15 11  
16 12 try {
17 13 app.parse(argc, argv);
18   - } catch (CLI::Error const& e) {
  14 + } catch(CLI::Error const &e) {
19 15 app.exit(e);
20 16 }
21 17 return 0;
22 18 }
23   -
... ...
examples/prefix_command.cpp
... ... @@ -6,8 +6,7 @@ int main(int argc, char **argv) {
6 6 app.prefix_command();
7 7  
8 8 std::vector<int> vals;
9   - app.add_option("--vals,-v", vals)
10   - ->expected(1);
  9 + app.add_option("--vals,-v", vals)->expected(1);
11 10  
12 11 std::vector<std::string> more_comms;
13 12 try {
... ... @@ -19,7 +18,7 @@ int main(int argc, char **argv) {
19 18 std::cout << "Prefix:";
20 19 for(int v : vals)
21 20 std::cout << v << ":";
22   -
  21 +
23 22 std::cout << std::endl << "Remaining commands: ";
24 23  
25 24 // Perfer to loop over from beginning, not "pop" order
... ...
include/CLI/App.hpp
... ... @@ -59,7 +59,7 @@ class App {
59 59  
60 60 /// If true, return immediatly on an unrecognised option (implies allow_extras)
61 61 bool prefix_command_{false};
62   -
  62 +
63 63 /// This is a function that runs when complete. Great for subcommands. Can throw.
64 64 std::function<void()> callback_;
65 65  
... ... @@ -160,7 +160,7 @@ class App {
160 160 prefix_command_ = allow;
161 161 return this;
162 162 }
163   -
  163 +
164 164 /// Ignore case. Subcommand inherit value.
165 165 App *ignore_case(bool value = true) {
166 166 ignore_case_ = value;
... ... @@ -225,8 +225,6 @@ class App {
225 225 } else
226 226 throw OptionAlreadyAdded(myopt.get_name());
227 227 }
228   -
229   -
230 228  
231 229 /// Add option for non-vectors (duplicate copy needed without defaulted to avoid `iostream << value`)
232 230 template <typename T, enable_if_t<!is_vector<T>::value, detail::enabler> = detail::dummy>
... ... @@ -251,13 +249,13 @@ class App {
251 249 T &variable, ///< The variable to set
252 250 std::string description,
253 251 bool defaulted) {
254   -
  252 +
255 253 CLI::callback_t fun = [&variable](CLI::results_t res) {
256 254 if(res.size() != 1)
257 255 return false;
258 256 return detail::lexical_cast(res[0], variable);
259 257 };
260   -
  258 +
261 259 Option *opt = add_option(name, fun, description, defaulted);
262 260 opt->set_custom_option(detail::type_name<T>());
263 261 if(defaulted) {
... ... @@ -267,13 +265,13 @@ class App {
267 265 }
268 266 return opt;
269 267 }
270   -
  268 +
271 269 /// Add option for vectors (no default)
272 270 template <typename T>
273 271 Option *add_option(std::string name,
274 272 std::vector<T> &variable, ///< The variable vector to set
275 273 std::string description = "") {
276   -
  274 +
277 275 CLI::callback_t fun = [&variable](CLI::results_t res) {
278 276 bool retval = true;
279 277 variable.clear();
... ... @@ -283,12 +281,12 @@ class App {
283 281 }
284 282 return (!variable.empty()) && retval;
285 283 };
286   -
  284 +
287 285 Option *opt = add_option(name, fun, description, false);
288 286 opt->set_custom_option(detail::type_name<T>(), -1, true);
289 287 return opt;
290 288 }
291   -
  289 +
292 290 /// Add option for vectors
293 291 template <typename T>
294 292 Option *add_option(std::string name,
... ... @@ -386,7 +384,7 @@ class App {
386 384 opt->set_custom_option(typeval);
387 385 return opt;
388 386 }
389   -
  387 +
390 388 /// Add set of options
391 389 template <typename T>
392 390 Option *add_set(std::string name,
... ... @@ -394,7 +392,7 @@ class App {
394 392 std::set<T> options, ///< The set of posibilities
395 393 std::string description,
396 394 bool defaulted) {
397   -
  395 +
398 396 CLI::callback_t fun = [&member, options](CLI::results_t res) {
399 397 if(res.size() != 1) {
400 398 return false;
... ... @@ -404,7 +402,7 @@ class App {
404 402 return false;
405 403 return std::find(std::begin(options), std::end(options), member) != std::end(options);
406 404 };
407   -
  405 +
408 406 Option *opt = add_option(name, fun, description, defaulted);
409 407 std::string typeval = detail::type_name<T>();
410 408 typeval += " in {" + detail::join(options) + "}";
... ... @@ -443,17 +441,17 @@ class App {
443 441 std::string typeval = detail::type_name<std::string>();
444 442 typeval += " in {" + detail::join(options) + "}";
445 443 opt->set_custom_option(typeval);
446   -
  444 +
447 445 return opt;
448 446 }
449   -
  447 +
450 448 /// Add set of options, string only, ignore case
451 449 Option *add_set_ignore_case(std::string name,
452 450 std::string &member, ///< The selected member of the set
453 451 std::set<std::string> options, ///< The set of posibilities
454 452 std::string description,
455 453 bool defaulted) {
456   -
  454 +
457 455 CLI::callback_t fun = [&member, options](CLI::results_t res) {
458 456 if(res.size() != 1) {
459 457 return false;
... ... @@ -469,7 +467,7 @@ class App {
469 467 return true;
470 468 }
471 469 };
472   -
  470 +
473 471 Option *opt = add_option(name, fun, description, defaulted);
474 472 std::string typeval = detail::type_name<std::string>();
475 473 typeval += " in {" + detail::join(options) + "}";
... ... @@ -912,19 +910,19 @@ class App {
912 910 char *buffer = nullptr;
913 911 std::string ename_string;
914 912  
915   - #ifdef _MSC_VER
  913 +#ifdef _MSC_VER
916 914 // Windows version
917 915 size_t sz = 0;
918 916 if(_dupenv_s(&buffer, &sz, opt->envname_.c_str()) == 0 && buffer != nullptr) {
919 917 ename_string = std::string(buffer);
920 918 free(buffer);
921 919 }
922   - #else
  920 +#else
923 921 // This also works on Windows, but gives a warning
924 922 buffer = std::getenv(opt->envname_.c_str());
925 923 if(buffer != nullptr)
926 924 ename_string = std::string(buffer);
927   - #endif
  925 +#endif
928 926  
929 927 if(!ename_string.empty()) {
930 928 opt->add_result(ename_string);
... ... @@ -1068,10 +1066,8 @@ class App {
1068 1066 size_t _count_remaining_required_positionals() const {
1069 1067 size_t retval = 0;
1070 1068 for(const Option_p &opt : options_)
1071   - if(opt->get_positional()
1072   - && opt->get_required()
1073   - && opt->get_expected() > 0
1074   - && static_cast<int>(opt->count()) < opt->get_expected())
  1069 + if(opt->get_positional() && opt->get_required() && opt->get_expected() > 0 &&
  1070 + static_cast<int>(opt->count()) < opt->get_expected())
1075 1071 retval = static_cast<size_t>(opt->get_expected()) - opt->count();
1076 1072  
1077 1073 return retval;
... ... @@ -1098,7 +1094,7 @@ class App {
1098 1094 else {
1099 1095 args.pop_back();
1100 1096 missing()->emplace_back(detail::Classifer::NONE, positional);
1101   -
  1097 +
1102 1098 if(prefix_command_) {
1103 1099 while(!args.empty()) {
1104 1100 missing()->emplace_back(detail::Classifer::NONE, args.back());
... ... @@ -1106,7 +1102,6 @@ class App {
1106 1102 }
1107 1103 }
1108 1104 }
1109   -
1110 1105 }
1111 1106  
1112 1107 /// Parse a subcommand, modify args and continue
... ...
include/CLI/Option.hpp
... ... @@ -433,9 +433,8 @@ class Option {
433 433 /// Set the default value string representation
434 434 void set_default_val(std::string val) { defaultval_ = val; }
435 435  
436   -
437 436 /// Set the type name displayed on this option
438   - void set_type_name(std::string val) {typeval_ = val;}
  437 + void set_type_name(std::string val) { typeval_ = val; }
439 438  
440 439 ///@}
441 440  
... ...
include/CLI/TypeTools.hpp
... ... @@ -75,9 +75,8 @@ constexpr const char *type_name() {
75 75 // Lexical cast
76 76  
77 77 /// Integers / enums
78   -template <typename T, enable_if_t<std::is_integral<T>::value
79   - || std::is_enum<T>::value
80   - , detail::enabler> = detail::dummy>
  78 +template <typename T,
  79 + enable_if_t<std::is_integral<T>::value || std::is_enum<T>::value, detail::enabler> = detail::dummy>
81 80 bool lexical_cast(std::string input, T &output) {
82 81 try {
83 82 output = static_cast<T>(std::stoll(input));
... ... @@ -103,11 +102,9 @@ bool lexical_cast(std::string input, T &amp;output) {
103 102 }
104 103  
105 104 /// String and similar
106   -template <
107   - typename T,
108   - enable_if_t<!std::is_floating_point<T>::value
109   - && !std::is_integral<T>::value
110   - && !std::is_enum<T>::value, detail::enabler> = detail::dummy>
  105 +template <typename T,
  106 + enable_if_t<!std::is_floating_point<T>::value && !std::is_integral<T>::value && !std::is_enum<T>::value,
  107 + detail::enabler> = detail::dummy>
111 108 bool lexical_cast(std::string input, T &output) {
112 109 output = input;
113 110 return true;
... ...
tests/AppTest.cpp
... ... @@ -204,34 +204,25 @@ TEST_F(TApp, DefaultOpts) {
204 204 }
205 205  
206 206 TEST_F(TApp, EnumTest) {
207   - enum Level : std::int32_t {
208   - High,
209   - Medium,
210   - Low
211   - };
  207 + enum Level : std::int32_t { High, Medium, Low };
212 208 Level level = Level::Low;
213 209 app.add_option("--level", level);
214   -
  210 +
215 211 args = {"--level", "1"};
216 212 run();
217 213 EXPECT_EQ(level, Level::Medium);
218 214 }
219 215  
220 216 TEST_F(TApp, NewEnumTest) {
221   - enum class Level2 : std::int32_t {
222   - High,
223   - Medium,
224   - Low
225   - };
  217 + enum class Level2 : std::int32_t { High, Medium, Low };
226 218 Level2 level = Level2::Low;
227 219 app.add_option("--level", level);
228   -
  220 +
229 221 args = {"--level", "1"};
230 222 run();
231 223 EXPECT_EQ(level, Level2::Medium);
232 224 }
233 225  
234   -
235 226 TEST_F(TApp, RequiredFlags) {
236 227 app.add_flag("-a")->required();
237 228 app.add_flag("-b")->mandatory(); // Alternate term
... ... @@ -440,7 +431,6 @@ TEST_F(TApp, InSetWithDefault) {
440 431 EXPECT_THROW(run(), CLI::ConversionError);
441 432 }
442 433  
443   -
444 434 TEST_F(TApp, InCaselessSetWithDefault) {
445 435  
446 436 std::string choice = "one";
... ... @@ -532,7 +522,6 @@ TEST_F(TApp, VectorFixedString) {
532 522 EXPECT_EQ(answer, strvec);
533 523 }
534 524  
535   -
536 525 TEST_F(TApp, VectorDefaultedFixedString) {
537 526 std::vector<std::string> strvec{"one"};
538 527 std::vector<std::string> answer{"mystring", "mystring2", "mystring3"};
... ... @@ -895,40 +884,40 @@ TEST_F(TApp, CheckSubcomFail) {
895 884  
896 885 // Added to test defaults on dual method
897 886 TEST_F(TApp, OptionWithDefaults) {
898   - int someint=2;
  887 + int someint = 2;
899 888 app.add_option("-a", someint, "", true);
900   -
  889 +
901 890 args = {"-a1", "-a2"};
902   -
  891 +
903 892 EXPECT_THROW(run(), CLI::ConversionError);
904 893 }
905 894  
906 895 // Added to test defaults on dual method
907 896 TEST_F(TApp, SetWithDefaults) {
908   - int someint=2;
909   - app.add_set("-a", someint, {1,2,3,4}, "", true);
910   -
  897 + int someint = 2;
  898 + app.add_set("-a", someint, {1, 2, 3, 4}, "", true);
  899 +
911 900 args = {"-a1", "-a2"};
912   -
  901 +
913 902 EXPECT_THROW(run(), CLI::ConversionError);
914 903 }
915 904  
916 905 // Added to test defaults on dual method
917 906 TEST_F(TApp, SetWithDefaultsConversion) {
918   - int someint=2;
919   - app.add_set("-a", someint, {1,2,3,4}, "", true);
920   -
  907 + int someint = 2;
  908 + app.add_set("-a", someint, {1, 2, 3, 4}, "", true);
  909 +
921 910 args = {"-a", "hi"};
922   -
  911 +
923 912 EXPECT_THROW(run(), CLI::ConversionError);
924 913 }
925 914  
926 915 // Added to test defaults on dual method
927 916 TEST_F(TApp, SetWithDefaultsIC) {
928   - std::string someint="ho";
  917 + std::string someint = "ho";
929 918 app.add_set_ignore_case("-a", someint, {"Hi", "Ho"}, "", true);
930   -
  919 +
931 920 args = {"-aHi", "-aHo"};
932   -
  921 +
933 922 EXPECT_THROW(run(), CLI::ConversionError);
934 923 }
... ...
tests/SubcommandTest.cpp
... ... @@ -307,16 +307,15 @@ TEST_F(TApp, BadSubcomSearch) {
307 307 }
308 308  
309 309 TEST_F(TApp, PrefixProgram) {
310   -
  310 +
311 311 app.prefix_command();
312   -
  312 +
313 313 app.add_flag("--simple");
314   -
  314 +
315 315 args = {"--simple", "other", "--simple", "--mine"};
316 316 auto ret_args = run();
317   -
  317 +
318 318 EXPECT_EQ(ret_args, std::vector<std::string>({"--mine", "--simple", "other"}));
319   -
320 319 }
321 320  
322 321 struct SubcommandProgram : public TApp {
... ...