Skip to content

Commit

Permalink
Merge #54 #59
Browse files Browse the repository at this point in the history
54: Support trybuild (take 2) r=taiki-e a=taiki-e

Fixes #32

The following patch is needed until dtolnay/trybuild#123 is merged:

```toml
[patch.crates-io]
trybuild = { git = "https://github.com/taiki-e/trybuild.git", branch = "target" }
```

---

Tested in the same way as #44 (comment)

59: Update clap to 3.0.0-beta.4 r=taiki-e a=taiki-e



Co-authored-by: Taiki Endo <te316e89@gmail.com>
  • Loading branch information
bors[bot] and taiki-e authored Aug 15, 2021
3 parents 3bda53a + ca93cb9 + be38fce commit 36972a1
Show file tree
Hide file tree
Showing 9 changed files with 220 additions and 102 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ anyhow = "1.0.34"
atty = "0.2.11"
camino = "1.0.3"
cargo_metadata = "0.14"
clap = "=3.0.0-beta.2"
clap = "=3.0.0-beta.4"
dirs-next = "2"
duct = "0.13.1"
fs-err = "2.5"
Expand Down
17 changes: 9 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,18 +62,25 @@ brew install taiki-e/tap/cargo-llvm-cov
```console
$ cargo llvm-cov --help
cargo-llvm-cov

Cargo subcommand for LLVM source-based code coverage (-Z instrument-coverage).

Use -h for short descriptions and --help for more details.

USAGE:
cargo llvm-cov [OPTIONS] [-- <args>...]
cargo llvm-cov [OPTIONS] [-- <ARGS>...]

ARGS:
<args>...
<ARGS>...
Arguments for the test binary

OPTIONS:
-h, --help
Print help information

-V, --version
Print version information

--json
Export coverage data in "json" format

Expand Down Expand Up @@ -187,12 +194,6 @@ OPTIONS:

-Z <FLAG>...
Unstable (nightly-only) flags to Cargo

-h, --help
Prints help information

-V, --version
Prints version information
```
<!-- readme-long-help:end -->

Expand Down
153 changes: 113 additions & 40 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use anyhow::Result;
use camino::Utf8PathBuf;
use clap::{AppSettings, Clap};
use clap::{AppSettings, ArgSettings, Clap};
use serde::Deserialize;

pub(crate) fn from_args() -> Result<Args> {
Expand All @@ -17,24 +17,24 @@ const MAX_TERM_WIDTH: usize = 100;
#[derive(Debug, Clap)]
#[clap(
bin_name = "cargo",
max_term_width = MAX_TERM_WIDTH,
setting = AppSettings::DeriveDisplayOrder,
setting = AppSettings::StrictUtf8,
setting = AppSettings::UnifiedHelpMessage,
max_term_width(MAX_TERM_WIDTH),
setting(AppSettings::DeriveDisplayOrder),
setting(AppSettings::StrictUtf8),
setting(AppSettings::UnifiedHelpMessage)
)]
enum Opts {
#[clap(about = ABOUT)]
#[clap(about(ABOUT))]
LlvmCov(Args),
}

#[derive(Debug, Clap)]
#[clap(
bin_name = "cargo llvm-cov",
about = ABOUT,
max_term_width = MAX_TERM_WIDTH,
setting = AppSettings::DeriveDisplayOrder,
setting = AppSettings::StrictUtf8,
setting = AppSettings::UnifiedHelpMessage,
about(ABOUT),
max_term_width(MAX_TERM_WIDTH),
setting(AppSettings::DeriveDisplayOrder),
setting(AppSettings::StrictUtf8),
setting(AppSettings::UnifiedHelpMessage)
)]
pub(crate) struct Args {
#[clap(subcommand)]
Expand Down Expand Up @@ -63,44 +63,57 @@ pub(crate) struct Args {
///
/// This internally calls `llvm-cov show -format=text`.
/// See <https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-show> for more.
#[clap(long, conflicts_with_all = &["json", "lcov"])]
#[clap(long, conflicts_with = "json", conflicts_with = "lcov")]
pub(crate) text: bool,
/// Generate coverage reports in "html" format.
////
/// If --output-dir is not specified, the report will be generated in `target/llvm-cov` directory.
///
/// This internally calls `llvm-cov show -format=html`.
/// See <https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-show> for more.
#[clap(long, conflicts_with_all = &["json", "lcov", "text"])]
#[clap(long, conflicts_with = "json", conflicts_with = "lcov", conflicts_with = "text")]
pub(crate) html: bool,
/// Generate coverage reports in "html" format and open them in a browser after the operation.
///
/// See --html for more.
#[clap(long, conflicts_with_all = &["json", "lcov", "text"])]
#[clap(long, conflicts_with = "json", conflicts_with = "lcov", conflicts_with = "text")]
pub(crate) open: bool,

/// Export only summary information for each file in the coverage data.
///
/// This flag can only be used together with either --json or --lcov.
// If the format flag is not specified, this flag is no-op because the only summary is displayed anyway.
#[clap(long, conflicts_with_all = &["text", "html", "open"])]
#[clap(long, conflicts_with = "text", conflicts_with = "html", conflicts_with = "open")]
pub(crate) summary_only: bool,
/// Specify a file to write coverage data into.
///
/// This flag can only be used together with --json, --lcov, or --text.
/// See --output-dir for --html and --open.
#[clap(long, value_name = "PATH", conflicts_with_all = &["html", "open"])]
#[clap(
long,
value_name = "PATH",
conflicts_with = "html",
conflicts_with = "open",
setting(ArgSettings::ForbidEmptyValues)
)]
pub(crate) output_path: Option<Utf8PathBuf>,
/// Specify a directory to write coverage reports into (default to `target/llvm-cov`).
///
/// This flag can only be used together with --text, --html, or --open.
/// See also --output-path.
// If the format flag is not specified, this flag is no-op.
#[clap(long, value_name = "DIRECTORY", conflicts_with_all = &["json", "lcov", "output-path"])]
#[clap(
long,
value_name = "DIRECTORY",
conflicts_with = "json",
conflicts_with = "lcov",
conflicts_with = "output-path",
setting(ArgSettings::ForbidEmptyValues)
)]
pub(crate) output_dir: Option<Utf8PathBuf>,

/// Skip source code files with file paths that match the given regular expression.
#[clap(long, value_name = "PATTERN")]
#[clap(long, value_name = "PATTERN", setting(ArgSettings::ForbidEmptyValues))]
pub(crate) ignore_filename_regex: Option<String>,
// For debugging (unstable)
#[clap(long, hidden = true)]
Expand Down Expand Up @@ -129,13 +142,26 @@ pub(crate) struct Args {
/// Package to run tests for
// cargo allows the combination of --package and --workspace, but we reject
// it because the situation where both flags are specified is odd.
#[clap(short, long, value_name = "SPEC", conflicts_with = "workspace")]
#[clap(
short,
long,
multiple_occurrences = true,
value_name = "SPEC",
conflicts_with = "workspace",
setting(ArgSettings::ForbidEmptyValues)
)]
pub(crate) package: Vec<String>,
/// Test all packages in the workspace
#[clap(long, visible_alias = "all")]
pub(crate) workspace: bool,
/// Exclude packages from the test
#[clap(long, value_name = "SPEC", requires = "workspace")]
#[clap(
long,
multiple_occurrences = true,
value_name = "SPEC",
requires = "workspace",
setting(ArgSettings::ForbidEmptyValues)
)]
pub(crate) exclude: Vec<String>,
// TODO: Should this only work for cargo's --jobs? Or should it also work
// for llvm-cov's -num-threads?
Expand All @@ -146,7 +172,12 @@ pub(crate) struct Args {
#[clap(long)]
pub(crate) release: bool,
/// Space or comma separated list of features to activate
#[clap(long, value_name = "FEATURES")]
#[clap(
long,
multiple_occurrences = true,
value_name = "FEATURES",
setting(ArgSettings::ForbidEmptyValues)
)]
pub(crate) features: Vec<String>,
/// Activate all available features
#[clap(long)]
Expand All @@ -158,7 +189,7 @@ pub(crate) struct Args {
///
/// When this option is used, coverage for proc-macro and build script will
/// not be displayed because cargo does not pass RUSTFLAGS to them.
#[clap(long, value_name = "TRIPLE")]
#[clap(long, value_name = "TRIPLE", setting(ArgSettings::ForbidEmptyValues))]
pub(crate) target: Option<String>,
// TODO: Currently, we are using a subdirectory of the target directory as
// the actual target directory. What effect should this option have
Expand All @@ -167,7 +198,7 @@ pub(crate) struct Args {
// #[clap(long, value_name = "DIRECTORY")]
// target_dir: Option<Utf8PathBuf>,
/// Path to Cargo.toml
#[clap(long, value_name = "PATH")]
#[clap(long, value_name = "PATH", setting(ArgSettings::ForbidEmptyValues))]
pub(crate) manifest_path: Option<Utf8PathBuf>,
/// Use verbose output (-vv/-vvv propagate verbosity to cargo)
#[clap(short, long, parse(from_occurrences))]
Expand All @@ -184,11 +215,16 @@ pub(crate) struct Args {
pub(crate) locked: bool,

/// Unstable (nightly-only) flags to Cargo
#[clap(short = 'Z', value_name = "FLAG")]
#[clap(
short = 'Z',
multiple_occurrences = true,
value_name = "FLAG",
setting(ArgSettings::ForbidEmptyValues)
)]
pub(crate) unstable_flags: Vec<String>,

/// Arguments for the test binary
#[clap(last = true)]
#[clap(last = true, setting(ArgSettings::ForbidEmptyValues))]
pub(crate) args: Vec<String>,
}

Expand Down Expand Up @@ -221,13 +257,8 @@ pub(crate) enum Coloring {
}

impl Coloring {
// TODO: use clap::ArgEnum::as_arg instead once new version of clap released.
pub(crate) fn cargo_color(self) -> &'static str {
match self {
Self::Auto => "auto",
Self::Always => "always",
Self::Never => "never",
}
clap::ArgEnum::as_arg(&self).unwrap()
}
}

Expand All @@ -236,22 +267,18 @@ mod tests {
use std::{env, panic, path::Path, process::Command};

use anyhow::Result;
use clap::IntoApp;
use clap::{Clap, IntoApp};
use fs_err as fs;
use tempfile::Builder;

use super::{Args, MAX_TERM_WIDTH};
use super::{Args, Opts, MAX_TERM_WIDTH};

// https://github.com/clap-rs/clap/issues/751
#[cfg(unix)]
#[test]
fn non_utf8_arg() {
use std::{ffi::OsStr, os::unix::prelude::OsStrExt};

use clap::Clap;

use super::Opts;

// `cargo llvm-cov -- $'fo\x80o'`
Opts::try_parse_from(&[
"cargo".as_ref(),
Expand All @@ -262,6 +289,55 @@ mod tests {
.unwrap_err();
}

// https://github.com/clap-rs/clap/issues/1772
#[test]
fn multiple_occurrences() {
let Opts::LlvmCov(args) =
Opts::try_parse_from(&["cargo", "llvm-cov", "--features", "a", "--features", "b"])
.unwrap();
assert_eq!(args.features, ["a", "b"]);

let Opts::LlvmCov(args) =
Opts::try_parse_from(&["cargo", "llvm-cov", "--package", "a", "--package", "b"])
.unwrap();
assert_eq!(args.package, ["a", "b"]);

let Opts::LlvmCov(args) = Opts::try_parse_from(&[
"cargo",
"llvm-cov",
"--exclude",
"a",
"--exclude",
"b",
"--all",
])
.unwrap();
assert_eq!(args.exclude, ["a", "b"]);

let Opts::LlvmCov(args) =
Opts::try_parse_from(&["cargo", "llvm-cov", "-Z", "a", "-Zb"]).unwrap();
assert_eq!(args.unstable_flags, ["a", "b"]);

let Opts::LlvmCov(args) =
Opts::try_parse_from(&["cargo", "llvm-cov", "--", "a", "b"]).unwrap();
assert_eq!(args.args, ["a", "b"]);
}

// https://github.com/clap-rs/clap/issues/1740
#[test]
fn empty_value() {
Opts::try_parse_from(&["cargo", "llvm-cov", "--output-path", ""]).unwrap_err();
Opts::try_parse_from(&["cargo", "llvm-cov", "--output-dir", ""]).unwrap_err();
Opts::try_parse_from(&["cargo", "llvm-cov", "--ignore-filename-regex", ""]).unwrap_err();
Opts::try_parse_from(&["cargo", "llvm-cov", "--package", ""]).unwrap_err();
Opts::try_parse_from(&["cargo", "llvm-cov", "--exclude", ""]).unwrap_err();
Opts::try_parse_from(&["cargo", "llvm-cov", "--features", ""]).unwrap_err();
Opts::try_parse_from(&["cargo", "llvm-cov", "--target", ""]).unwrap_err();
Opts::try_parse_from(&["cargo", "llvm-cov", "--manifest-path", ""]).unwrap_err();
Opts::try_parse_from(&["cargo", "llvm-cov", "-Z", ""]).unwrap_err();
Opts::try_parse_from(&["cargo", "llvm-cov", "--", ""]).unwrap_err();
}

fn get_help(long: bool) -> Result<String> {
let mut buf = vec![];
if long {
Expand All @@ -277,9 +353,6 @@ mod tests {
out.push_str(line.trim_end());
out.push('\n');
}
if long {
out.pop();
}
Ok(out)
}

Expand Down
3 changes: 3 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ fn run_test(cx: &Context) -> Result<()> {
" -Z instrument-coverage --remap-path-prefix {}/=",
cx.metadata.workspace_root
));
if cx.target.is_none() {
rustflags.push(" --cfg trybuild_no_target");
}

// https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/instrument-coverage.html#including-doc-tests
let rustdocflags = &mut cx.env.rustdocflags.clone();
Expand Down
Loading

0 comments on commit 36972a1

Please sign in to comment.