Skip to content

Commit

Permalink
Add options --git and --path
Browse files Browse the repository at this point in the history
  • Loading branch information
smoelius committed Feb 4, 2024
1 parent 0c57dc7 commit 883e521
Show file tree
Hide file tree
Showing 5 changed files with 213 additions and 40 deletions.
104 changes: 89 additions & 15 deletions cargo-dylint/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,21 @@ struct NameOpts {
#[clap(long, help = "Load all discovered libraries")]
all: bool,

#[clap(
long,
requires("git"),
help = "Branch to use when downloading library packages"
)]
branch: Option<String>,

#[clap(
long,
value_name = "url",
conflicts_with("paths"),
help = "Git url containing library packages"
)]
git: Option<String>,

#[clap(
action = ArgAction::Append,
number_of_values = 1,
Expand Down Expand Up @@ -219,9 +234,31 @@ struct NameOpts {
action = ArgAction::Append,
number_of_values = 1,
long = "path",
hide = true,
value_name = "path",
conflicts_with("git"),
help = "Path containing library packages"
)]
paths: Vec<String>,

#[clap(
long,
help = "Subdirectories of the `--git` or `--path` argument containing library packages"
)]
pattern: Option<String>,

#[clap(
long,
requires("git"),
help = "Specific commit to use when downloading library packages"
)]
rev: Option<String>,

#[clap(
long,
requires("git"),
help = "Tag to use when downloading library packages"
)]
tag: Option<String>,
}

#[allow(deprecated)]
Expand All @@ -232,12 +269,17 @@ impl From<Dylint> for dylint::Dylint {
name_opts:
NameOpts {
all,
libs,
branch,
git,
lib_paths,
libs,
manifest_path,
no_build,
no_metadata,
paths: _,
paths,
pattern,
rev,
tag,
},
allow_downgrade,
bisect,
Expand All @@ -263,8 +305,10 @@ impl From<Dylint> for dylint::Dylint {
all,
allow_downgrade,
bisect,
branch,
fix,
force,
git,
isolate,
keep_going,
lib_paths,
Expand All @@ -276,11 +320,14 @@ impl From<Dylint> for dylint::Dylint {
no_deps,
no_metadata,
packages,
// paths,
paths,
pattern,
pipe_stderr,
pipe_stdout,
quiet,
rev,
rust_version,
tag,
upgrade_path,
workspace,
names,
Expand Down Expand Up @@ -340,20 +387,47 @@ fn process_deprecated_options(mut opts: Dylint) -> Dylint {
opts
}

impl NameOpts {
pub fn absorb(&mut self, other: Self) {
self.all |= other.all;
self.libs.extend(other.libs);
if other.manifest_path.is_some() {
macro_rules! option_absorb {
($this:expr, $other:expr) => {
if $other.is_some() {
assert!(
self.manifest_path.is_none(),
"`--manifest-path` used multiple times"
$this.is_none(),
"`--{}` used multiple times",
stringify!($other).replace("_", "-")
);
self.manifest_path = other.manifest_path;
*$this = $other;
}
self.no_build |= other.no_build;
self.no_metadata |= other.no_metadata;
self.paths.extend(other.paths);
};
}

impl NameOpts {
pub fn absorb(&mut self, other: Self) {
let Self {
all,
branch,
git,
lib_paths,
libs,
manifest_path,
no_build,
no_metadata,
paths,
pattern,
rev,
tag,
} = other;
self.all |= all;
option_absorb!(&mut self.branch, branch);
option_absorb!(&mut self.git, git);
self.lib_paths.extend(lib_paths);
self.libs.extend(libs);
option_absorb!(&mut self.manifest_path, manifest_path);
self.no_build |= no_build;
self.no_metadata |= no_metadata;
self.paths.extend(paths);
option_absorb!(&mut self.pattern, pattern);
option_absorb!(&mut self.rev, rev);
option_absorb!(&mut self.tag, tag);
}
}

Expand Down
5 changes: 4 additions & 1 deletion cargo-dylint/tests/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,10 @@ fn list_by_path() {
.success()
.stdout(
predicate::str::contains("fill_me_in").and(predicate::str::contains("Building").not()),
);
)
.stderr(predicate::str::contains(
"Referring to libraries with `--path` is deprecated. Use `--lib-path`.",
));
}

// smoelius: For the tests to pass on OSX, the paths have to be canonicalized, because `/var` is
Expand Down
57 changes: 49 additions & 8 deletions dylint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use std::{
env::{consts, current_dir},
ffi::OsStr,
fmt::Debug,
fs::OpenOptions,
fs::{metadata, OpenOptions},
path::{Path, PathBuf, MAIN_SEPARATOR},
};

Expand Down Expand Up @@ -63,11 +63,15 @@ pub struct Dylint {
#[deprecated]
pub bisect: bool,

pub branch: Option<String>,

pub fix: bool,

#[deprecated]
pub force: bool,

pub git: Option<String>,

#[deprecated]
pub isolate: bool,

Expand All @@ -93,18 +97,23 @@ pub struct Dylint {

pub packages: Vec<String>,

// smoelius: Temporarily removed to ensure all uses are gone.
// pub paths: Vec<String>,
pub paths: Vec<String>,

pub pattern: Option<String>,

pub pipe_stderr: Option<String>,

pub pipe_stdout: Option<String>,

pub quiet: bool,

pub rev: Option<String>,

#[deprecated]
pub rust_version: Option<String>,

pub tag: Option<String>,

#[deprecated]
pub upgrade_path: Option<String>,

Expand All @@ -116,19 +125,47 @@ pub struct Dylint {
pub args: Vec<String>,
}

impl Dylint {
fn git_or_path(&self) -> bool {
self.git.is_some() || !self.paths.is_empty()
}
}

pub fn run(opts: &Dylint) -> Result<()> {
let opts = {
let mut opts = opts.clone();

if opts.force {
warn(
opts,
&opts,
"`--force` is deprecated and its meaning may change in the future. Use \
`--allow-downgrade`.",
);
opts.allow_downgrade = true;
opts.force = false;
}
Dylint {
allow_downgrade: opts.allow_downgrade || opts.force,
..opts.clone()
}

let path_refers_to_libraries =
opts.paths
.iter()
.try_fold(false, |is_file, path| -> Result<_> {
let metadata =
metadata(path).with_context(|| "Could not read file metadata")?;
Ok(is_file || metadata.is_file())
})?;

if path_refers_to_libraries {
warn(
&opts,
"Referring to libraries with `--path` is deprecated. Use `--lib-path`.",
);
opts.lib_paths.extend(opts.paths.split_off(0));
};

// smoelius: Use of `--git` or `--path` implies `--all`.
opts.all |= opts.git_or_path();

opts
};

if opts.allow_downgrade && opts.upgrade_path.is_none() {
Expand All @@ -151,6 +188,10 @@ pub fn run(opts: &Dylint) -> Result<()> {
bail!("`--isolate` can be used only with `--new`");
}

if opts.pattern.is_some() && !opts.git_or_path() {
bail!("`--pattern` can be used only with `--git` or `--path`");
}

if opts.pipe_stderr.is_some() {
warn(&opts, "`--pipe-stderr` is experimental");
}
Expand Down
52 changes: 50 additions & 2 deletions dylint/src/metadata/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ use dylint_internal::{env, library_filename, rustup::SanitizeEnvironment, Comman
use glob::glob;
use if_chain::if_chain;
use once_cell::sync::OnceCell;
use serde::Deserialize;
use std::path::{Path, PathBuf};
use serde::{de::IntoDeserializer, Deserialize};
use std::{
fs::canonicalize,
path::{Path, PathBuf},
};

// smoelius: If both `__metadata_cargo` and `__metadata_cli` are enabled, assume the user built with
// `--features=metadata-cli` and forgot `--no-default-features`.
Expand Down Expand Up @@ -80,6 +83,51 @@ struct Library {
details: DetailedTomlDependency,
}

pub fn opts_library_packages(opts: &crate::Dylint) -> Result<Vec<Package>> {
let maybe_metadata = cargo_metadata(opts)?;

let metadata = maybe_metadata.ok_or_else(|| anyhow!("Could not read cargo metadata"))?;

ensure!(
opts.paths.len() <= 1,
"At most one library package can be named with `--path`"
);

let path = if let Some(path) = opts.paths.first() {
let canonical_path =
canonicalize(path).with_context(|| format!("Could not canonicalize {path:?}"))?;
Some(canonical_path.to_string_lossy().to_string())
} else {
None
};

let toml: toml::map::Map<_, _> = vec![
to_map_entry("path", path.as_ref()),
to_map_entry("git", opts.git.as_ref()),
to_map_entry("branch", opts.branch.as_ref()),
to_map_entry("tag", opts.tag.as_ref()),
to_map_entry("rev", opts.rev.as_ref()),
]
.into_iter()
.flatten()
.collect();

let details = DetailedTomlDependency::deserialize(toml.into_deserializer())?;

let library = Library {
details,
pattern: opts.pattern.clone(),
};

library_packages(opts, metadata, &[library])
}

fn to_map_entry(key: &str, value: Option<&String>) -> Option<(String, toml::Value)> {
value
.cloned()
.map(|s| (String::from(key), toml::Value::from(s)))
}

pub fn workspace_metadata_packages(opts: &crate::Dylint) -> Result<Vec<Package>> {
if_chain! {
if let Some(metadata) = cargo_metadata(opts)?;
Expand Down
Loading

0 comments on commit 883e521

Please sign in to comment.