Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add options to config/cli #466

Merged
merged 4 commits into from
Oct 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ jobs:
name: Minimum Stable Rust Version Check
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: "1.60.0"
Expand Down
2 changes: 1 addition & 1 deletion docs/src/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
cargo-deny:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: EmbarkStudios/cargo-deny-action@v1
```

Expand Down
16 changes: 16 additions & 0 deletions docs/src/checks/cfg.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,22 @@ Note that excluding a crate is recursive, if any of its transitive dependencies

Rust `cfg()` expressions support the [`target_feature = "feature-name"`](https://doc.rust-lang.org/reference/attributes/codegen.html#the-target_feature-attribute) predicate, but at the moment, the only way to actually pass them when compiling is to use the `RUSTFLAGS` environment variable. The `features` field allows you to specify 1 or more `target_feature`s you plan to build with, for a particular target triple. At the time of this writing, cargo-deny does not attempt to validate that the features you specify are actually valid for the target triple, but this is [planned](https://github.com/EmbarkStudios/cfg-expr/issues/1).

### The `all-features` field (optional)

If set to `true`, `--all-features` will be used when collecting metadata.

### The `no-default-features` field (optional)

If set to `true`, `--no-default-features` will be used when collecting metadata.

### The `features` field (optional)

If set, and `--features` is not specified on the cmd line, these features will be used when collecting metadata.

### The `feature-depth` field (optional)

The maximum depth that features will be displayed when inclusion graphs are included in diagnostics, unless specified via `--feature-depth` on the command line. Only applies to diagnostics that actually print features. If not specified defaults to `1`.

### The `[licenses]` section

See the [licenses config](licenses/cfg.html) for more info.
Expand Down
52 changes: 42 additions & 10 deletions docs/src/cli/check.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,53 @@ The check command is the primary subcommand of cargo-deny as it is what actually

### `<which>`

The check(s) to perform. By default, **all** checks will be performed, unless one or more specific checks are specified.
The check(s) to perform. By default, **all** checks will be performed, unless one or more checks are specified here.

See [checks](../checks/index.html) for the list of available checks.

## Flags
## Options

### `-A, --allow <ALLOW>`

Set lint allowed

### `--audit-compatible-output`

To ease transition from cargo-audit to cargo-deny, this flag will tell cargo-deny to output the exact same output as cargo-audit would, to `stdout` instead of `stderr`, just as with cargo-audit.

Note that this flag only applies when the output format is JSON, and note that since cargo-deny supports multiple advisory databases, instead of a single JSON object, there will be 1 for each unique advisory database.

### `-c, --config <CONFIG>`

Path to the config to use

Defaults to `<cwd>/deny.toml` if not specified

### `-d, --disable-fetch`

Disables fetching of advisory databases, if they would be loaded. If disabled, and there is not already an existing advisory database locally, an error will occur.
Disable fetching of the advisory database

When running the `advisories` check, the configured advisory database will be fetched and opened. If this flag is passed, the database won't be fetched, but an error will occur if it doesn't already exist locally.

### `-D, --deny <DENY>`

Set lint denied

### `--feature-depth <FEATURE_DEPTH>`

Specifies the depth at which feature edges are added in inclusion graphs

### `-g, --graph <GRAPH>`

Path to graph_output root directory

If set, a dotviz graph will be created for whenever multiple versions of the same crate are detected.

Each file will be created at `<dir>/graph_output/<crate_name>.dot`. `<dir>/graph_output/*` is deleted and recreated each run.

### `--hide-inclusion-graph`

Hides the inclusion graph when printing out info for a crate.
Hides the inclusion graph when printing out info for a crate

By default, if a diagnostic message pertains to a specific crate, cargo-deny will append an inverse dependency graph to the diagnostic to show you how that crate was pulled into your project.

Expand All @@ -31,12 +65,10 @@ the-crate
└── c-crate
```

## Options

### `-c, --config`
### `-s, --show-stats`

The path to the config file used to determine which crates are allowed or denied. Will default to `<context>/deny.toml` if not specified.
Show stats for all the checks, regardless of the log-level

### `-g, --graph`
### `-W, --warn <WARN>`

A root directory to place dotviz graphs into when duplicate crate versions are detected. Will be `<dir>/graph_output/<crate_name>.dot`. The `/graph_output/*` is deleted and recreated each run.
Set lint warnings
2 changes: 1 addition & 1 deletion src/advisories/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ where
if let Ok(s) = std::env::var("USER").or_else(|_| std::env::var("USERNAME")) {
attempts.push(s);
}
if let Some(ref s) = cred_helper.username {
if let Some(s) = &cred_helper.username {
attempts.push(s.clone());
}

Expand Down
51 changes: 47 additions & 4 deletions src/cargo-deny/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ pub struct Args {
pub show_stats: bool,
#[clap(flatten)]
pub lint_levels: LintLevels,
/// Specifies the depth at which feature edges are added in inclusion graphs
#[clap(long, conflicts_with = "hide-inclusion-graph")]
pub feature_depth: Option<u32>,
/// The check(s) to perform
#[clap(value_enum, action)]
pub which: Vec<WhichCheck>,
Expand All @@ -118,6 +121,13 @@ struct Config {
targets: Vec<crate::common::Target>,
#[serde(default)]
exclude: Vec<String>,
feature_depth: Option<u32>,
#[serde(default)]
all_features: bool,
#[serde(default)]
no_default_features: bool,
#[serde(default)]
features: Vec<String>,
}

struct ValidConfig {
Expand All @@ -127,6 +137,10 @@ struct ValidConfig {
sources: sources::ValidConfig,
targets: Vec<(krates::Target, Vec<String>)>,
exclude: Vec<String>,
feature_depth: Option<u32>,
all_features: bool,
no_default_features: bool,
features: Vec<String>,
}

impl ValidConfig {
Expand Down Expand Up @@ -178,6 +192,10 @@ impl ValidConfig {

let targets = crate::common::load_targets(cfg.targets, &mut diags, id);
let exclude = cfg.exclude;
let feature_depth = cfg.feature_depth;
let all_features = cfg.all_features;
let no_default_features = cfg.no_default_features;
let features = cfg.features;

(
diags,
Expand All @@ -188,6 +206,10 @@ impl ValidConfig {
sources,
targets,
exclude,
feature_depth,
all_features,
no_default_features,
features,
},
)
};
Expand All @@ -197,7 +219,7 @@ impl ValidConfig {
return;
}

if let Some(printer) = crate::common::DiagPrinter::new(log_ctx, None) {
if let Some(printer) = crate::common::DiagPrinter::new(log_ctx, None, None) {
let mut lock = printer.lock();
for diag in diags {
lock.print(diag, files);
Expand Down Expand Up @@ -226,7 +248,7 @@ impl ValidConfig {
pub(crate) fn cmd(
log_ctx: crate::common::LogContext,
args: Args,
krate_ctx: crate::common::KrateContext,
mut krate_ctx: crate::common::KrateContext,
) -> anyhow::Result<AllStats> {
let mut files = Files::new();
let ValidConfig {
Expand All @@ -236,6 +258,10 @@ pub(crate) fn cmd(
sources,
targets,
exclude,
feature_depth,
all_features,
no_default_features,
features,
} = ValidConfig::load(
krate_ctx.get_config_path(args.config.clone()),
&mut files,
Expand Down Expand Up @@ -265,6 +291,21 @@ pub(crate) fn cmd(
.iter()
.any(|w| *w == WhichCheck::Sources || *w == WhichCheck::All);

let feature_depth = args.feature_depth.or(feature_depth);

// If not specified on the cmd line, fallback to the feature related config options
if !krate_ctx.all_features {
krate_ctx.all_features = all_features;
}

if !krate_ctx.no_default_features {
krate_ctx.no_default_features = no_default_features;
}

if krate_ctx.features.is_empty() {
krate_ctx.features = features;
}

let mut krates = None;
let mut license_store = None;
let mut advisory_dbs = None;
Expand Down Expand Up @@ -328,7 +369,7 @@ pub(crate) fn cmd(
s.spawn(|_| {
let gathered = krate_ctx.gather_krates(targets, exclude);

if let Ok(ref krates) = gathered {
if let Ok(krates) = &gathered {
rayon::scope(|s| {
if check_advisories {
s.spawn(|_| {
Expand Down Expand Up @@ -461,6 +502,7 @@ pub(crate) fn cmd(
},
files,
&mut stats,
feature_depth,
);
});

Expand Down Expand Up @@ -607,10 +649,11 @@ fn print_diagnostics(
krates: Option<&cargo_deny::Krates>,
files: Files,
stats: &mut AllStats,
feature_depth: Option<u32>,
) {
use cargo_deny::diag::Check;

match crate::common::DiagPrinter::new(log_ctx, krates) {
match crate::common::DiagPrinter::new(log_ctx, krates, feature_depth) {
Some(printer) => {
for pack in rx {
let check_stats = match pack.check {
Expand Down
35 changes: 26 additions & 9 deletions src/cargo-deny/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ impl KrateContext {
}
});

if let Ok(ref krates) = graph {
if let Ok(krates) = &graph {
log::info!(
"gathered {} crates in {}ms",
krates.len(),
Expand Down Expand Up @@ -287,6 +287,7 @@ pub struct Human<'a> {
stream: term::termcolor::StandardStream,
grapher: Option<diag::InclusionGrapher<'a>>,
config: term::Config,
feature_depth: Option<u32>,
}

pub enum StdioStream {
Expand Down Expand Up @@ -317,8 +318,13 @@ enum OutputFormat<'a> {
impl<'a> OutputFormat<'a> {
fn lock(&'a self, max_severity: Severity) -> OutputLock<'a, '_> {
match self {
Self::Human(ref human) => OutputLock::Human(human, max_severity, human.stream.lock()),
Self::Json(ref json) => OutputLock::Json(json, max_severity, json.stream.lock()),
Self::Human(human) => OutputLock::Human(
human,
max_severity,
human.stream.lock(),
human.feature_depth,
),
Self::Json(json) => OutputLock::Json(json, max_severity, json.stream.lock()),
}
}
}
Expand Down Expand Up @@ -349,14 +355,15 @@ pub enum OutputLock<'a, 'b> {
&'a Human<'a>,
Severity,
term::termcolor::StandardStreamLock<'b>,
Option<u32>,
),
Json(&'a Json<'a>, Severity, StdLock<'b>),
}

impl<'a, 'b> OutputLock<'a, 'b> {
pub fn print(&mut self, diag: CsDiag, files: &Files) {
match self {
Self::Human(cfg, max, l) => {
Self::Human(cfg, max, l, _) => {
if diag.severity < *max {
return;
}
Expand Down Expand Up @@ -385,7 +392,7 @@ impl<'a, 'b> OutputLock<'a, 'b> {
let mut emitted = std::collections::BTreeSet::new();

match self {
Self::Human(cfg, max, l) => {
Self::Human(cfg, max, l, fd) => {
for mut diag in pack {
if diag.diag.severity < *max {
continue;
Expand All @@ -399,9 +406,14 @@ impl<'a, 'b> OutputLock<'a, 'b> {
diag.diag
.notes
.push(format!("{} v{} (*)", krate.name, krate.version));
} else if let Ok(graph) =
grapher.build_graph(&gn, if diag.with_features { 1 } else { 0 })
{
} else if let Ok(graph) = grapher.build_graph(
&gn,
if diag.with_features {
fd.unwrap_or(1) as usize
} else {
0
},
) {
let graph_text = diag::write_graph_as_text(&graph);
diag.diag.notes.push(graph_text);
emitted.insert(gn.kid);
Expand Down Expand Up @@ -446,7 +458,11 @@ pub struct DiagPrinter<'a> {
}

impl<'a> DiagPrinter<'a> {
pub fn new(ctx: LogContext, krates: Option<&'a cargo_deny::Krates>) -> Option<Self> {
pub fn new(
ctx: LogContext,
krates: Option<&'a cargo_deny::Krates>,
feature_depth: Option<u32>,
) -> Option<Self> {
let max_severity = log_level_to_severity(ctx.log_level);

max_severity.map(|max_severity| match ctx.format {
Expand All @@ -461,6 +477,7 @@ impl<'a> DiagPrinter<'a> {
stream,
grapher: krates.map(diag::InclusionGrapher::new),
config: term::Config::default(),
feature_depth,
}),
max_severity,
}
Expand Down
2 changes: 1 addition & 1 deletion src/cargo-deny/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ impl ValidConfig {
return;
}

if let Some(printer) = crate::common::DiagPrinter::new(log_ctx, None) {
if let Some(printer) = crate::common::DiagPrinter::new(log_ctx, None, None) {
let mut lock = printer.lock();
for diag in diags {
lock.print(diag, files);
Expand Down
2 changes: 1 addition & 1 deletion src/cargo-deny/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ impl ValidConfig {
return;
}

if let Some(printer) = crate::common::DiagPrinter::new(log_ctx, None) {
if let Some(printer) = crate::common::DiagPrinter::new(log_ctx, None, None) {
let mut lock = printer.lock();
for diag in diags {
lock.print(diag, files);
Expand Down
2 changes: 1 addition & 1 deletion src/diag/grapher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ impl<'a> InclusionGrapher<'a> {
Node::Krate { krate, .. } => {
let kind = np.edge.and_then(|eid| match self.krates.graph()[eid] {
Edge::Dep { kind, .. } | Edge::DepFeature { kind, .. } => match kind {
DepKind::Normal => None, //Some("feature (normal)"),
DepKind::Normal => None,
DepKind::Dev => Some("dev"),
DepKind::Build => Some("build"),
},
Expand Down
2 changes: 1 addition & 1 deletion src/licenses/gather.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ impl LicensePack {

// Add the explicitly specified license if it wasn't
// already found in the root directory
if let Some(ref lf) = krate.license_file {
if let Some(lf) = &krate.license_file {
if !lic_paths.iter().any(|l| l.ends_with(lf)) {
// The `krate.license_file` is relative to the crate, while files found with
// `find_license_files()` are absolute. We prepend the directory of the current
Expand Down
Loading