diff --git a/.appveyor.yml b/.appveyor.yml
deleted file mode 100644
index 247a550d9f0..00000000000
--- a/.appveyor.yml
+++ /dev/null
@@ -1,17 +0,0 @@
-environment:
- matrix:
- - TARGET: x86_64-pc-windows-msvc
- - TARGET: i686-pc-windows-msvc
- - TARGET: x86_64-pc-windows-gnu
- - TARGET: i686-pc-windows-gnu
- RUST_BACKTRACE: full
-install:
- - curl -sSf -o rustup-init.exe https://win.rustup.rs/
- - rustup-init.exe -y --default-host %TARGET%
- - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
- - rustc -vV
- - cargo -vV
-build: false
-test_script:
- - cargo build --verbose --features yaml
- - cargo test --verbose --features yaml
diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml
new file mode 100644
index 00000000000..464b792f2cb
--- /dev/null
+++ b/.azure-pipelines.yml
@@ -0,0 +1,61 @@
+name: $(Build.BuildId)
+trigger:
+ # Always build master
+ - v2-master
+pr:
+ # Enable building pull requests.
+ - v2-master
+stages:
+ - stage: Testing
+ jobs:
+ - job:
+ variables:
+ rust: 1.36.0
+ strategy:
+ matrix:
+ Windows 32-bit (MSVC):
+ image: vs2017-win2016
+ target: i686-pc-windows-msvc
+ Windows 64-bit (MSVC):
+ image: vs2017-win2016
+ target: x86_64-pc-windows-msvc
+ Windows 32-bit (MinGW):
+ image: vs2017-win2016
+ target: i686-pc-windows-gnu
+ Windows 64-bit (MinGW):
+ image: vs2017-win2016
+ target: x86_64-pc-windows-gnu
+ pool:
+ vmImage: $(image)
+ steps:
+ - checkout: self
+ fetchDepth: 1
+ path: clap
+ displayName: Checkout repository
+ - task: Cache@2
+ inputs:
+ key: cargo | "$(rust)" | $(target) | Cargo.toml
+ path: C:\Rust\.cargo
+ displayName: Caching cargo
+ - task: Cache@2
+ inputs:
+ key: compiled | "$(rust)" | $(target) | Cargo.toml
+ path: target
+ displayName: Caching compiled
+ - script: rustup default $(rust)-$(target)
+ displayName: Install rust
+ - script: cargo test --no-default-features
+ displayName: Test without default features
+ env:
+ RUST_BACKTRACE: full
+ - script: cargo test --features "yaml unstable"
+ displayName: Test with most features
+ env:
+ RUST_BACKTRACE: full
+ - script: |
+ rmdir /Q /S C:\Rust\.cargo\registry\src
+ rmdir /Q /S target\.rustc_info.json
+ rmdir /Q /S target\debug\examples
+ rmdir /Q /S target\debug\incremental
+ displayName: Cleaning for cache
+ continueOnError: true
diff --git a/.mention-bot b/.mention-bot
deleted file mode 100644
index f339f59cd0f..00000000000
--- a/.mention-bot
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "findPotentialReviewers": false,
- "alwaysNotifyForPaths": [
- {
- "name": "kbknapp",
- "files": ["**/*.rs", "**/*.md", "*"]
- }
- ]
-}
diff --git a/.travis.yml b/.travis.yml
index 30ee1359169..f3cf7b7e046 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,67 +1,66 @@
-sudo: true
+os: linux
language: rust
-cache:
- directories:
- - $HOME/.cargo
- - $HOME/.rustup
+cache: cargo
before_cache:
- - rm -rf /home/travis/.cargo/registry
-rust:
- - nightly
- - nightly-2019-06-18
- - beta
- - stable
- - 1.33.0
-matrix:
- allow_failures:
- - rust: nightly
- nightly-2019-06-18:
- - script: cargo clippy
-before_script:
- - |
- pip install git+git://github.com/kbknapp/travis-cargo.git --user &&
- export PATH=$HOME/.local/bin:$PATH
- - |
- if [[ "$TRAVIS_RUST_VERSION" == "1.13.0" ]]; then
- echo "Old Rust detected, removing version-sync dependency"
- sed -i "/^version-sync =/d" Cargo.toml
- rm "tests/version-numbers.rs"
- fi
+ - find target/debug -type f -maxdepth 1 -delete
+ - rm -rf target/.rustc_info.json
+ - rm -rf target/debug/examples
+ - rm -rf target/debug/incremental
+ - rm -rf target/tests/target/debug/incremental
+ - rm -rf target/tests/target/debug/deps/{clap*, trybuild*}
+ - rm -rf target/debug/{deps,.fingerpint}/clap*
+ - find target/debug/deps -name "clap*" -exec rm -rf {} +
+ - ls -1 examples/ | sed -e 's/\.rs$//' | xargs -I "{{}}" find target/debug/deps -name "{{}}*" -exec rm -rf {} +
+ - ls -1 tests/ | sed -e 's/\.rs$//' | xargs -I "{{}}" find target/debug/deps -name "{{}}*" -exec rm -rf {} +
+rust: stable
+branches:
+ only:
+ # Always build master & Enable building pull requests.
+ - v2-master
+jobs:
+ allow_failures:
+ - rust: nightly
+ - env:
+ - SHARD=coverage
+ fast_finish: true
+ include:
+ - os: osx
+ rust: 1.36.0
+ - rust: 1.36.0
+ - {}
+ - rust: beta
+ - rust: nightly
+ - env:
+ - SHARD=lint
+ before_script:
+ - rustup component add clippy
+ - rustup component add rustfmt
+ script:
+ - echo "Checking codebase with Clippy release `cargo clippy --version`."
+ - cargo clippy --lib --features "yaml unstable"
+ - cargo clippy --tests --examples --features "yaml unstable"
+ - cargo fmt -- --check
+ - rust: nightly
+ env:
+ - SHARD=bench
+ script:
+ - cargo bench
+ - env:
+ - SHARD=coverage
+ addons:
+ apt:
+ packages:
+ - libssl-dev
+ - cmake
+ - pkg-config
+ - zlib1g-dev
+ update: true
+ before_script:
+ - cargo install cargo-tarpaulin
+ script:
+ - cargo tarpaulin --features "yaml unstable" --ciserver travis-ci --coveralls $TRAVIS_JOB_ID
script:
- - |
- travis-cargo --only stable test -- --verbose --no-default-features &&
- travis-cargo --skip nightly test -- --verbose --features "yaml unstable" &&
- travis-cargo --only nightly test -- --verbose --features "yaml unstable nightly" &&
- travis-cargo --only nightly bench -- --no-run
-addons:
- apt:
- packages:
- - binutils-dev
- - libcurl4-openssl-dev
- - libelf-dev
- - libdw-dev
- - libiberty-dev
- - cmake
- - gcc
- - zlib1g-dev
-after_success:
- - |
- wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz &&
- tar xzf master.tar.gz &&
- cd kcov-master &&
- mkdir build &&
- cd build &&
- cmake .. &&
- make &&
- sudo make install &&
- cd ../.. &&
- rm -rf kcov-master &&
- cargo clean &&
- cargo test --no-run --features "yaml unstable" &&
- for file in target/debug/*-*; do mkdir -p "target/cov/$(basename $file)"; kcov --exclude-pattern=/.cargo --verify "target/cov/$(basename $file)" "$file"; done &&
- kcov --coveralls-id=$TRAVIS_JOB_ID --merge target/cov target/cov/* &&
- echo "Uploaded code coverage"
-env:
- global:
- - TRAVIS_CARGO_NIGHTLY_FEATURE=lints
- - secure: JLBlgHY6OEmhJ8woewNJHmuBokTNUv7/WvLkJGV8xk0t6bXBwSU0jNloXwlH7FiQTc4TccX0PumPDD4MrMgxIAVFPmmmlQOCmdpYP4tqZJ8xo189E5zk8lKF5OyaVYCs5SMmFC3cxCsKjfwGIexNu3ck5Uhwe9jI0tqgkgM3URA=
+ - cargo test --no-default-features
+ - cargo test --features yaml unstable
+notifications:
+ email: false
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 65cec2d89f7..965b653ac5f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,7 +2,7 @@
#### Minimum Required Rust
-* As of this release, `clap` requires `rustc 1.33.0` or greater.
+* As of this release, `clap` requires `rustc 1.36.0` or greater.
## v2.33.0 (2019-04-06)
diff --git a/README.md b/README.md
index 5a0840211ee..e3a91424679 100644
--- a/README.md
+++ b/README.md
@@ -455,9 +455,9 @@ This is inherently an unresolvable crate graph in Cargo right now. Cargo require
#### Minimum Version of Rust
-`clap` will officially support current stable Rust, minus two releases, but may work with prior releases as well. For example, current stable Rust at the time of this writing is 1.35.0, meaning `clap` is guaranteed to compile with 1.33.0 and beyond.
+`clap` will officially support current stable Rust, minus two releases, but may work with prior releases as well. For example, current stable Rust at the time of this writing is 1.41.0, meaning `clap` is guaranteed to compile with 1.39.0 and beyond.
-At the 1.36.0 stable release, `clap` will be guaranteed to compile with 1.34.0 and beyond, etc.
+At the 1.42.0 stable release, `clap` will be guaranteed to compile with 1.40.0 and beyond, etc.
Upon bumping the minimum version of Rust (assuming it's within the stable-2 range), it *must* be clearly annotated in the `CHANGELOG.md`
diff --git a/benches/02_simple.rs b/benches/02_simple.rs
index 010fa866fa7..aa9fd483d93 100644
--- a/benches/02_simple.rs
+++ b/benches/02_simple.rs
@@ -8,20 +8,21 @@ use clap::{App, Arg};
use test::Bencher;
macro_rules! create_app {
- () => ({
+ () => {{
App::new("claptests")
- .version("0.1")
- .about("tests clap library")
- .author("Kevin K. ")
- .args_from_usage("-f --flag 'tests flags'
+ .version("0.1")
+ .about("tests clap library")
+ .author("Kevin K. ")
+ .args_from_usage(
+ "-f --flag 'tests flags'
-o --option=[opt] 'tests options'
- [positional] 'tests positional'")
- })
+ [positional] 'tests positional'",
+ )
+ }};
}
#[bench]
fn build_app(b: &mut Bencher) {
-
b.iter(|| create_app!());
}
diff --git a/benches/03_complex.rs b/benches/03_complex.rs
index b00fc4eac56..744d7dd6910 100644
--- a/benches/03_complex.rs
+++ b/benches/03_complex.rs
@@ -4,7 +4,7 @@
extern crate clap;
extern crate test;
-use clap::{App, Arg, SubCommand, AppSettings};
+use clap::{App, AppSettings, Arg, SubCommand};
use test::Bencher;
@@ -14,37 +14,45 @@ static OPT3_VALS: [&'static str; 2] = ["fast", "slow"];
static POS3_VALS: [&'static str; 2] = ["vi", "emacs"];
macro_rules! create_app {
- () => ({
+ () => {{
App::new("claptests")
- .version("0.1")
- .about("tests clap library")
- .author("Kevin K. ")
- .args_from_usage(ARGS)
- .arg(Arg::from_usage("-f --flag... 'tests flags'")
- .global(true))
- .args(&[
- Arg::from_usage("[flag2] -F 'tests flags with exclusions'").conflicts_with("flag").requires("option2"),
- Arg::from_usage("--long-option-2 [option2] 'tests long options with exclusions'").conflicts_with("option").requires("positional2"),
- Arg::from_usage("[positional2] 'tests positionals with exclusions'"),
- Arg::from_usage("-O --Option [option3] 'tests options with specific value sets'").possible_values(&OPT3_VALS),
- Arg::from_usage("[positional3]... 'tests positionals with specific values'").possible_values(&POS3_VALS),
- Arg::from_usage("--multvals [one] [two] 'Tests multiple values, not mult occs'"),
- Arg::from_usage("--multvalsmo... [one] [two] 'Tests multiple values, not mult occs'"),
- Arg::from_usage("--minvals2 [minvals]... 'Tests 2 min vals'").min_values(2),
- Arg::from_usage("--maxvals3 [maxvals]... 'Tests 3 max vals'").max_values(3)
- ])
- .subcommand(SubCommand::with_name("subcmd")
- .about("tests subcommands")
- .version("0.1")
- .author("Kevin K. ")
- .arg_from_usage("-o --option [scoption]... 'tests options'")
- .arg_from_usage("[scpositional] 'tests positionals'"))
- })
+ .version("0.1")
+ .about("tests clap library")
+ .author("Kevin K. ")
+ .args_from_usage(ARGS)
+ .arg(Arg::from_usage("-f --flag... 'tests flags'").global(true))
+ .args(&[
+ Arg::from_usage("[flag2] -F 'tests flags with exclusions'")
+ .conflicts_with("flag")
+ .requires("option2"),
+ Arg::from_usage("--long-option-2 [option2] 'tests long options with exclusions'")
+ .conflicts_with("option")
+ .requires("positional2"),
+ Arg::from_usage("[positional2] 'tests positionals with exclusions'"),
+ Arg::from_usage("-O --Option [option3] 'tests options with specific value sets'")
+ .possible_values(&OPT3_VALS),
+ Arg::from_usage("[positional3]... 'tests positionals with specific values'")
+ .possible_values(&POS3_VALS),
+ Arg::from_usage("--multvals [one] [two] 'Tests multiple values, not mult occs'"),
+ Arg::from_usage(
+ "--multvalsmo... [one] [two] 'Tests multiple values, not mult occs'",
+ ),
+ Arg::from_usage("--minvals2 [minvals]... 'Tests 2 min vals'").min_values(2),
+ Arg::from_usage("--maxvals3 [maxvals]... 'Tests 3 max vals'").max_values(3),
+ ])
+ .subcommand(
+ SubCommand::with_name("subcmd")
+ .about("tests subcommands")
+ .version("0.1")
+ .author("Kevin K. ")
+ .arg_from_usage("-o --option [scoption]... 'tests options'")
+ .arg_from_usage("[scpositional] 'tests positionals'"),
+ )
+ }};
}
#[bench]
fn create_app_from_usage(b: &mut Bencher) {
-
b.iter(|| create_app!());
}
@@ -52,85 +60,115 @@ fn create_app_from_usage(b: &mut Bencher) {
fn create_app_builder(b: &mut Bencher) {
b.iter(|| {
App::new("claptests")
- .version("0.1")
- .about("tests clap library")
- .author("Kevin K. ")
- .arg(Arg::with_name("opt")
+ .version("0.1")
+ .about("tests clap library")
+ .author("Kevin K. ")
+ .arg(
+ Arg::with_name("opt")
.help("tests options")
.short("o")
.long("option")
.takes_value(true)
- .multiple(true))
- .arg(Arg::with_name("positional")
+ .multiple(true),
+ )
+ .arg(
+ Arg::with_name("positional")
.help("tests positionals")
- .index(1))
- .arg(Arg::with_name("flag")
- .short("f")
- .help("tests flags")
- .long("flag")
- .multiple(true)
- .global(true))
- .arg(Arg::with_name("flag2")
+ .index(1),
+ )
+ .arg(
+ Arg::with_name("flag")
+ .short("f")
+ .help("tests flags")
+ .long("flag")
+ .multiple(true)
+ .global(true),
+ )
+ .arg(
+ Arg::with_name("flag2")
.short("F")
.help("tests flags with exclusions")
.conflicts_with("flag")
- .requires("option2"))
- .arg(Arg::with_name("option2")
+ .requires("option2"),
+ )
+ .arg(
+ Arg::with_name("option2")
.help("tests long options with exclusions")
.conflicts_with("option")
.requires("positional2")
.takes_value(true)
- .long("long-option-2"))
- .arg(Arg::with_name("positional2")
+ .long("long-option-2"),
+ )
+ .arg(
+ Arg::with_name("positional2")
.index(3)
- .help("tests positionals with exclusions"))
- .arg(Arg::with_name("option3")
+ .help("tests positionals with exclusions"),
+ )
+ .arg(
+ Arg::with_name("option3")
.short("O")
.long("Option")
.takes_value(true)
.help("tests options with specific value sets")
- .possible_values(&OPT3_VALS))
- .arg(Arg::with_name("positional3")
+ .possible_values(&OPT3_VALS),
+ )
+ .arg(
+ Arg::with_name("positional3")
.multiple(true)
.help("tests positionals with specific values")
.index(4)
- .possible_values(&POS3_VALS))
- .arg(Arg::with_name("multvals")
+ .possible_values(&POS3_VALS),
+ )
+ .arg(
+ Arg::with_name("multvals")
.long("multvals")
.takes_value(true)
.help("Tests multiple values, not mult occs")
- .value_names(&["one", "two"]))
- .arg(Arg::with_name("multvalsmo")
+ .value_names(&["one", "two"]),
+ )
+ .arg(
+ Arg::with_name("multvalsmo")
.long("multvalsmo")
.takes_value(true)
.multiple(true)
.help("Tests multiple values, not mult occs")
- .value_names(&["one", "two"]))
- .arg(Arg::with_name("minvals")
+ .value_names(&["one", "two"]),
+ )
+ .arg(
+ Arg::with_name("minvals")
.long("minvals2")
.multiple(true)
.takes_value(true)
.help("Tests 2 min vals")
- .min_values(2))
- .arg(Arg::with_name("maxvals")
+ .min_values(2),
+ )
+ .arg(
+ Arg::with_name("maxvals")
.long("maxvals3")
.takes_value(true)
.multiple(true)
.help("Tests 3 max vals")
- .max_values(3))
- .subcommand(SubCommand::with_name("subcmd")
+ .max_values(3),
+ )
+ .subcommand(
+ SubCommand::with_name("subcmd")
.about("tests subcommands")
.version("0.1")
.author("Kevin K. ")
- .arg(Arg::with_name("scoption")
- .short("o")
- .long("option")
- .multiple(true)
- .takes_value(true)
- .help("tests options"))
- .arg(Arg::with_name("scpositional")
- .index(1)
- .help("tests positionals")));
+ .arg(
+ Arg::with_name("scoption")
+ .short("o")
+ .long("option")
+ .multiple(true)
+ .takes_value(true)
+ .help("tests options"),
+ )
+ .arg(
+ Arg::with_name("scpositional")
+ .index(1)
+ .help("tests positionals"),
+ ),
+ );
});
}
@@ -211,20 +249,75 @@ fn parse_sc_positional(b: &mut Bencher) {
#[bench]
fn parse_complex1(b: &mut Bencher) {
- b.iter(|| create_app!().get_matches_from(vec!["myprog", "-ff", "-o", "option1", "arg1", "-O", "fast", "arg2", "--multvals", "one", "two", "emacs"]));
+ b.iter(|| {
+ create_app!().get_matches_from(vec![
+ "myprog",
+ "-ff",
+ "-o",
+ "option1",
+ "arg1",
+ "-O",
+ "fast",
+ "arg2",
+ "--multvals",
+ "one",
+ "two",
+ "emacs",
+ ])
+ });
}
#[bench]
fn parse_complex2(b: &mut Bencher) {
- b.iter(|| create_app!().get_matches_from(vec!["myprog", "arg1", "-f", "arg2", "--long-option-2", "some", "-O", "slow", "--multvalsmo", "one", "two", "--minvals2", "3", "2", "1"]));
+ b.iter(|| {
+ create_app!().get_matches_from(vec![
+ "myprog",
+ "arg1",
+ "-f",
+ "arg2",
+ "--long-option-2",
+ "some",
+ "-O",
+ "slow",
+ "--multvalsmo",
+ "one",
+ "two",
+ "--minvals2",
+ "3",
+ "2",
+ "1",
+ ])
+ });
}
#[bench]
fn parse_complex2_with_args_negate_scs(b: &mut Bencher) {
- b.iter(|| create_app!().setting(AppSettings::ArgsNegateSubcommands).get_matches_from(vec!["myprog", "arg1", "-f", "arg2", "--long-option-2", "some", "-O", "slow", "--multvalsmo", "one", "two", "--minvals2", "3", "2", "1"]));
+ b.iter(|| {
+ create_app!()
+ .setting(AppSettings::ArgsNegateSubcommands)
+ .get_matches_from(vec![
+ "myprog",
+ "arg1",
+ "-f",
+ "arg2",
+ "--long-option-2",
+ "some",
+ "-O",
+ "slow",
+ "--multvalsmo",
+ "one",
+ "two",
+ "--minvals2",
+ "3",
+ "2",
+ "1",
+ ])
+ });
}
#[bench]
fn parse_sc_complex(b: &mut Bencher) {
- b.iter(|| create_app!().get_matches_from(vec!["myprog", "subcmd", "-f", "-o", "option1", "arg1"]));
+ b.iter(|| {
+ create_app!().get_matches_from(vec!["myprog", "subcmd", "-f", "-o", "option1", "arg1"])
+ });
}
diff --git a/benches/04_new_help.rs b/benches/04_new_help.rs
index f033efb5a19..ad64fd87229 100644
--- a/benches/04_new_help.rs
+++ b/benches/04_new_help.rs
@@ -22,12 +22,16 @@ fn app_example1<'b, 'c>() -> App<'b, 'c> {
.version("1.0")
.author("Kevin K. ")
.about("Does awesome things")
- .args_from_usage("-c, --config=[FILE] 'Sets a custom config file'
+ .args_from_usage(
+ "-c, --config=[FILE] 'Sets a custom config file'