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 --package <pkgid> to all commands #390

Merged
merged 9 commits into from Mar 19, 2020
12 changes: 11 additions & 1 deletion src/bin/add/args.rs
Expand Up @@ -83,9 +83,18 @@ pub struct Args {
pub optional: bool,

/// Path to the manifest to add a dependency to.
#[structopt(long = "manifest-path", value_name = "path")]
#[structopt(long = "manifest-path", value_name = "path", conflicts_with = "pkgid")]
pub manifest_path: Option<PathBuf>,

/// Package id of the crate to add this dependency to.
#[structopt(
long = "package",
short = "p",
value_name = "pkgid",
conflicts_with = "path"
)]
pub pkgid: Option<String>,

/// Choose method of semantic version upgrade. Must be one of "none" (exact version, `=`
/// modifier), "patch" (`~` modifier), "minor" (`^` modifier), "all" (`>=`), or "default" (no
/// modifier).
Expand Down Expand Up @@ -276,6 +285,7 @@ impl Default for Args {
target: None,
optional: false,
manifest_path: None,
pkgid: None,
upgrade: "minor".to_string(),
allow_prerelease: false,
no_default_features: false,
Expand Down
15 changes: 11 additions & 4 deletions src/bin/add/main.rs
Expand Up @@ -15,7 +15,10 @@
extern crate error_chain;

use crate::args::{Args, Command};
use cargo_edit::{find, registry_url, update_registry_index, Dependency, Manifest};
use cargo_edit::{
find, manifest_from_pkgid, registry_url, update_registry_index, Dependency, Manifest,
};
use std::borrow::Cow;
use std::io::Write;
use std::process;
use structopt::StructOpt;
Expand Down Expand Up @@ -83,8 +86,12 @@ fn print_msg(dep: &Dependency, section: &[String], optional: bool) -> Result<()>
}

fn handle_add(args: &Args) -> Result<()> {
let manifest_path = &args.manifest_path;
let mut manifest = Manifest::open(manifest_path)?;
let manifest_path = if let Some(ref pkgid) = args.pkgid {
Cow::Owned(manifest_from_pkgid(pkgid)?)
} else {
Cow::Borrowed(&args.manifest_path)
};
let mut manifest = Manifest::open(&manifest_path)?;
let deps = &args.parse_dependencies()?;

if !args.offline && std::env::var("CARGO_IS_TEST").is_err() {
Expand Down Expand Up @@ -122,7 +129,7 @@ fn handle_add(args: &Args) -> Result<()> {
err
})?;

let mut file = Manifest::find_file(manifest_path)?;
let mut file = Manifest::find_file(&manifest_path)?;
manifest.write_to_file(&mut file)?;

Ok(())
Expand Down
24 changes: 19 additions & 5 deletions src/bin/rm/main.rs
Expand Up @@ -14,7 +14,8 @@
#[macro_use]
extern crate error_chain;

use cargo_edit::Manifest;
use cargo_edit::{manifest_from_pkgid, Manifest};
use std::borrow::Cow;
use std::io::Write;
use std::path::PathBuf;
use std::process;
Expand Down Expand Up @@ -56,9 +57,18 @@ struct Args {
build: bool,

/// Path to the manifest to remove a dependency from.
#[structopt(long = "manifest-path", value_name = "path")]
#[structopt(long = "manifest-path", value_name = "path", conflicts_with = "pkgid")]
manifest_path: Option<PathBuf>,

/// Package id of the crate to add this dependency to.
#[structopt(
long = "package",
short = "p",
value_name = "pkgid",
conflicts_with = "path"
)]
pkgid: Option<String>,

/// Do not print any output in case of success.
#[structopt(long = "quiet", short = "q")]
quiet: bool,
Expand Down Expand Up @@ -92,8 +102,12 @@ fn print_msg(name: &str, section: &str) -> Result<()> {
}

fn handle_rm(args: &Args) -> Result<()> {
let manifest_path = &args.manifest_path;
let mut manifest = Manifest::open(manifest_path)?;
let manifest_path = if let Some(ref pkgid) = args.pkgid {
Cow::Owned(manifest_from_pkgid(pkgid)?)
} else {
Cow::Borrowed(&args.manifest_path)
};
let mut manifest = Manifest::open(&manifest_path)?;
let deps = &args.crates;

deps.iter()
Expand All @@ -111,7 +125,7 @@ fn handle_rm(args: &Args) -> Result<()> {
err
})?;

let mut file = Manifest::find_file(manifest_path)?;
let mut file = Manifest::find_file(&manifest_path)?;
manifest.write_to_file(&mut file)?;

Ok(())
Expand Down
32 changes: 31 additions & 1 deletion src/bin/upgrade/main.rs
Expand Up @@ -71,9 +71,18 @@ struct Args {
dependency: Vec<String>,

/// Path to the manifest to upgrade
#[structopt(long = "manifest-path", value_name = "path")]
#[structopt(long = "manifest-path", value_name = "path", conflicts_with = "pkgid")]
manifest_path: Option<PathBuf>,

/// Package id of the crate to add this dependency to.
#[structopt(
long = "package",
short = "p",
value_name = "pkgid",
conflicts_with = "path"
)]
pkgid: Option<String>,

/// Upgrade all packages in the workspace.
#[structopt(long = "all")]
all: bool,
Expand Down Expand Up @@ -153,6 +162,24 @@ impl Manifests {
.map(Manifests)
}

fn get_pkgid(pkgid: &str) -> Result<Self> {
let mut cmd = cargo_metadata::MetadataCommand::new();
cmd.no_deps();
let result = cmd
.exec()
.map_err(|e| Error::from(e.compat()).chain_err(|| "Invalid manifest"))?;
let packages = result.packages;
let package = packages
.into_iter()
.find(|pkg| &pkg.name == pkgid)
.chain_err(|| {
"Found virtual manifest, but this command requires running against an \
actual package in this workspace. Try adding `--all`."
})?;
let manifest = LocalManifest::try_new(Path::new(&package.manifest_path))?;
ordian marked this conversation as resolved.
Show resolved Hide resolved
Ok(Manifests(vec![(manifest, package.to_owned())]))
}

/// Get the manifest specified by the manifest path. Try to make an educated guess if no path is
/// provided.
fn get_local_one(manifest_path: &Option<PathBuf>) -> Result<Self> {
Expand Down Expand Up @@ -401,6 +428,7 @@ fn process(args: Args) -> Result<()> {
let Args {
dependency,
manifest_path,
pkgid,
all,
allow_prerelease,
dry_run,
Expand All @@ -416,6 +444,8 @@ fn process(args: Args) -> Result<()> {

let manifests = if all {
Manifests::get_all(&manifest_path)
} else if let Some(ref pkgid) = pkgid {
Manifests::get_pkgid(pkgid)
} else {
Manifests::get_local_one(&manifest_path)
}?;
Expand Down
1 change: 1 addition & 0 deletions src/errors.rs
Expand Up @@ -2,6 +2,7 @@ error_chain! {
foreign_links {
Io(::std::io::Error) #[doc = "An error from the std::io module"];
Git(::git2::Error)#[doc = "An error from the git2 crate"];
CargoMetadata(::failure::Compat<::cargo_metadata::Error>)#[doc = "An error from the cargo_metadata crate"];
}

errors {
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Expand Up @@ -23,6 +23,7 @@ mod dependency;
mod errors;
mod fetch;
mod manifest;
mod metadata;
mod registry;

pub use crate::crate_name::CrateName;
Expand All @@ -33,4 +34,5 @@ pub use crate::fetch::{
get_latest_dependency, update_registry_index,
};
pub use crate::manifest::{find, LocalManifest, Manifest};
pub use crate::metadata::manifest_from_pkgid;
pub use crate::registry::registry_url;
21 changes: 21 additions & 0 deletions src/metadata.rs
@@ -0,0 +1,21 @@
use crate::errors::*;
use failure::Fail;
use std::path::PathBuf;

/// Takes a pkgid and attempts to find the path to it's `Cargo.toml`, using `cargo`'s metadata
pub fn manifest_from_pkgid(pkgid: &str) -> Result<Option<PathBuf>> {
let mut cmd = cargo_metadata::MetadataCommand::new();
cmd.no_deps();
let result = cmd
.exec()
.map_err(|e| Error::from(e.compat()).chain_err(|| "Invalid manifest"))?;
let packages = result.packages;
let package = packages
.into_iter()
.find(|pkg| &pkg.name == pkgid)
.chain_err(|| {
"Found virtual manifest, but this command requires running against an \
actual package in this workspace. Try adding `--all`."
})?;
Ok(Some(PathBuf::from(&package.manifest_path)))
}