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

read cargo configs with/without .toml extension + make public API clearer #437

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
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
1,473 changes: 987 additions & 486 deletions Cargo.lock

Large diffs are not rendered by default.

32 changes: 16 additions & 16 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ license = "Apache-2.0/MIT"
name = "cargo-edit"
readme = "README.md"
repository = "https://github.com/killercup/cargo-edit"
version = "0.7.0"
version = "0.7.1"
edition = "2018"

[[bin]]
Expand All @@ -51,24 +51,24 @@ repository = "killercup/cargo-edit"

[dependencies]
atty = { version = "0.2.14", optional = true }
cargo_metadata = "0.12.0"
dirs = "3.0.1"
cargo_metadata = "0.18.1"
dirs = "3.0.2"
env_proxy = "0.4.1"
error-chain = "0.12.4"
failure = "0.1.8"
git2 = "0.13.11"
hex = "0.4.2"
regex = "1.3.9"
serde = "1.0.116"
serde_derive = "1.0.116"
serde_json = "1.0.58"
structopt = { version = "0.3.18", optional = true }
subprocess = "0.2.6"
termcolor = "1.1.0"
toml = "0.5.6"
toml_edit = "0.2.0"
url = "2.1.1"
ureq = { version = "1.5.1", default-features = false, features = ["tls", "json", "socks"] }
git2 = "0.18.1"
hex = "0.4.3"
regex = "1.10.2"
serde = "1.0.193"
serde_derive = "1.0.193"
serde_json = "1.0.108"
structopt = { version = "0.3.26", optional = true }
subprocess = "0.2.9"
termcolor = "1.4.0"
toml = "0.8.8"
toml_edit = "0.21.0"
url = "2.5.0"
reqwest = { version = "0.11.22", features = ["blocking"] }

[dependencies.semver]
features = ["serde"]
Expand Down
15 changes: 6 additions & 9 deletions src/bin/add/args.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Handle `cargo add` arguments
use cargo_edit::{find, registry_url, Dependency};
use cargo_edit::{get_latest_dependency, CrateName};
use cargo_edit::{find, Dependency};
use cargo_edit::{get_latest_dependency, CrateName, RegistryReq};
use std::path::PathBuf;
use structopt::StructOpt;

Expand Down Expand Up @@ -201,18 +201,15 @@ impl Args {
if let Some(version) = &self.vers {
dependency = dependency.set_version(parse_version_req(version)?);
}
let registry_url = if let Some(registry) = &self.registry {
Some(registry_url(&find(&self.manifest_path)?, Some(registry))?)
} else {
None
};

if self.git.is_none() && self.path.is_none() && self.vers.is_none() {
let dep = get_latest_dependency(
crate_name.name(),
self.allow_prerelease,
&find(&self.manifest_path)?,
&registry_url,
RegistryReq::project(
self.registry.as_ref().map(String::as_ref),
&find(&self.manifest_path)?,
),
)?;
let v = format!(
"{prefix}{version}",
Expand Down
11 changes: 6 additions & 5 deletions src/bin/add/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ extern crate error_chain;

use crate::args::{Args, Command};
use cargo_edit::{
find, manifest_from_pkgid, registry_url, update_registry_index, Dependency, Manifest,
find, manifest_from_pkgid, update_registry_index, Dependency, Manifest, RegistryReq,
};
use std::borrow::Cow;
use std::io::Write;
Expand Down Expand Up @@ -116,18 +116,19 @@ fn is_sorted(mut it: impl Iterator<Item = impl PartialOrd>) -> bool {
fn handle_add(args: &Args) -> Result<()> {
let manifest_path = if let Some(ref pkgid) = args.pkgid {
let pkg = manifest_from_pkgid(pkgid)?;
Cow::Owned(Some(pkg.manifest_path))
Cow::Owned(Some(pkg.manifest_path.into_std_path_buf()))
} 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() {
let url = registry_url(
&find(&manifest_path)?,
let url = RegistryReq::project(
args.registry.as_ref().map(String::as_ref),
)?;
&find(&manifest_path)?,
)
.index_url()?;
update_registry_index(&url)?;
}

Expand Down
2 changes: 1 addition & 1 deletion src/bin/rm/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ fn print_msg(name: &str, section: &str) -> Result<()> {
fn handle_rm(args: &Args) -> Result<()> {
let manifest_path = if let Some(ref pkgid) = args.pkgid {
let pkg = manifest_from_pkgid(pkgid)?;
Cow::Owned(Some(pkg.manifest_path))
Cow::Owned(Some(pkg.manifest_path.into_std_path_buf()))
} else {
Cow::Borrowed(&args.manifest_path)
};
Expand Down
94 changes: 54 additions & 40 deletions src/bin/upgrade/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ extern crate error_chain;

use crate::errors::*;
use cargo_edit::{
find, get_latest_dependency, manifest_from_pkgid, registry_url, update_registry_index,
CrateName, Dependency, LocalManifest,
find, get_latest_dependency, manifest_from_pkgid, update_registry_index, CrateName, Dependency,
LocalManifest, RegistryIndex, RegistryReq,
};
use failure::Fail;
use std::collections::{HashMap, HashSet};
Expand Down Expand Up @@ -212,7 +212,7 @@ impl Manifests {
let packages = result.packages;
let package = packages
.iter()
.find(|p| p.manifest_path.to_string_lossy() == resolved_manifest_path)
.find(|p| p.manifest_path.as_str() == resolved_manifest_path)
// If we have successfully got metadata, but our manifest path does not correspond to a
// package, we must have been called against a virtual manifest.
.chain_err(|| {
Expand Down Expand Up @@ -393,44 +393,58 @@ impl DesiredUpgrades {
fn get_upgraded(self, allow_prerelease: bool, manifest_path: &Path) -> Result<ActualUpgrades> {
self.0
.into_iter()
.map(
|(
dep,
UpgradeMetadata {
registry,
version,
is_prerelease,
},
)| {
if let Some(v) = version {
Ok((dep, v))
} else {
let registry_url = match registry {
Some(x) => Some(Url::parse(&x).map_err(|_| {
.map(|(dep, meta)| {
match meta.version {
// use previous version
Some(v) => Ok((dep, v)),

// no version exists - get latest
None => {
// if a registry exists on a dependency, parse it as a URL
let registry_url = meta
.registry
.as_ref()
.map(|s| Url::parse(&s))
.transpose()
.map_err(|_| {
ErrorKind::CargoEditLib(::cargo_edit::ErrorKind::InvalidCargoConfig)
})?),
None => None,
})?;

let use_prerelease = allow_prerelease || meta.is_prerelease;

let latest_dep = if let Some(url) = registry_url {
// Configured registry URL
get_latest_dependency(
&dep.name,
use_prerelease,
RegistryReq::custom(url),
)
} else {
// no configured registry - use crates.io
get_latest_dependency(
&dep.name,
use_prerelease,
// specifying registries by name must be qualified with a cargo.toml
// specifying purely by URL may work, but will need to call this function differently for knowing URL vs knowing name
RegistryReq::project(
(&meta.registry).as_ref().map(AsRef::as_ref),
manifest_path.parent().unwrap(),
),
)
};
let allow_prerelease = allow_prerelease || is_prerelease;
get_latest_dependency(
&dep.name,
allow_prerelease,
manifest_path,
&registry_url,
)
.map(|new_dep| {
(
dep,
new_dep

latest_dep
.map(|latest_dep| {
latest_dep
.version()
.expect("Invalid dependency type")
.to_string(),
)
})
.chain_err(|| "Failed to get new version")
.into()
})
.map(|new_version| (dep, new_version))
.chain_err(|| "Failed to get new version")
}
},
)
}
})
.collect::<Result<_>>()
.map(ActualUpgrades)
}
Expand Down Expand Up @@ -459,7 +473,8 @@ fn process(args: Args) -> Result<()> {
let all = workspace || all;

if !args.offline && !to_lockfile && std::env::var("CARGO_IS_TEST").is_err() {
let url = registry_url(&find(&manifest_path)?, None)?;
// get the project's crates.io registry URL
let url = RegistryReq::project(None, &find(&manifest_path)?).index_url()?;
update_registry_index(&url)?;
}

Expand All @@ -485,9 +500,8 @@ fn process(args: Args) -> Result<()> {
.filter_map(|UpgradeMetadata { registry, .. }| registry.as_ref())
.collect::<HashSet<_>>()
{
update_registry_index(&Url::parse(registry_url).map_err(|_| {
ErrorKind::CargoEditLib(::cargo_edit::ErrorKind::InvalidCargoConfig)
})?)?;
let registry_url = RegistryIndex::parse(registry_url)?;
update_registry_index(&registry_url)?;
}
}

Expand Down
5 changes: 5 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ error_chain! {
ReadHomeDirFailure {
description("Failed to read home directory")
}
/// Failed to absolutely resolve a relative directory
DirectoryResolutionFailure(dir: PathBuf) {
description("Failed to canonicalize a directory")
display("The path `{}` has failed to resolve to an absolute path", dir.display())
}
/// Invalid JSON in registry index
InvalidSummaryJson {
description("Invalid JSON in registry index")
Expand Down
60 changes: 26 additions & 34 deletions src/fetch.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use crate::errors::*;
use crate::registry::{registry_path, registry_path_from_url};
use crate::registry::{RegistryIndex, RegistryReq};
use crate::{Dependency, Manifest};
use regex::Regex;
use reqwest::Proxy;
use std::env;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::time::Duration;
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
use url::Url;

#[derive(Deserialize)]
struct CrateVersion {
Expand All @@ -30,8 +30,7 @@ struct CrateVersion {
pub fn get_latest_dependency(
crate_name: &str,
flag_allow_prerelease: bool,
manifest_path: &Path,
registry: &Option<Url>,
registry: RegistryReq,
) -> Result<Dependency> {
if env::var("CARGO_IS_TEST").is_ok() {
// We are in a simulated reality. Nothing is real here.
Expand All @@ -53,12 +52,9 @@ pub fn get_latest_dependency(
return Err(ErrorKind::EmptyCrateName.into());
}

let registry_path = match registry {
Some(url) => registry_path_from_url(url)?,
None => registry_path(manifest_path, None)?,
};
let registry_cache = registry.index_url()?.cache_path()?;

let crate_versions = fuzzy_query_registry_index(crate_name, &registry_path)?;
let crate_versions = fuzzy_query_registry_index(crate_name, &registry_cache)?;

let dep = read_latest_version(&crate_versions, flag_allow_prerelease)?;

Expand Down Expand Up @@ -92,8 +88,8 @@ fn read_latest_version(
}

/// update registry index for given project
pub fn update_registry_index(registry: &Url) -> Result<()> {
let registry_path = registry_path_from_url(registry)?;
pub fn update_registry_index(registry: &RegistryIndex) -> Result<()> {
let registry_path = registry.cache_path()?;

let colorchoice = if atty::is(atty::Stream::Stdout) {
ColorChoice::Auto
Expand All @@ -103,6 +99,7 @@ pub fn update_registry_index(registry: &Url) -> Result<()> {
let mut output = StandardStream::stdout(colorchoice);

if !registry_path.as_path().exists() {
// make new bare git repo at registry_path
output.set_color(ColorSpec::new().set_fg(Some(Color::Green)).set_bold(true))?;
write!(output, "{:>12}", "Initializing")?;
output.reset()?;
Expand All @@ -114,6 +111,7 @@ pub fn update_registry_index(registry: &Url) -> Result<()> {
return Ok(());
}

// use existing git repo at registry_path
let repo = git2::Repository::open(&registry_path)?;
output.set_color(ColorSpec::new().set_fg(Some(Color::Green)).set_bold(true))?;
write!(output, "{:>12}", "Updating")?;
Expand All @@ -124,7 +122,7 @@ pub fn update_registry_index(registry: &Url) -> Result<()> {
"refs/heads/{0}:refs/remotes/origin/{0}",
get_checkout_name(registry_path)?
);
fetch_with_cli(&repo, registry.as_str(), &refspec)?;
fetch_with_cli(&repo, registry.as_ref().as_str(), &refspec)?;

Ok(())
}
Expand Down Expand Up @@ -398,29 +396,23 @@ fn get_name_from_manifest(manifest: &Manifest) -> Result<String> {
}

fn get_cargo_toml_from_git_url(url: &str) -> Result<String> {
let mut req = ureq::get(url);
req.timeout(get_default_timeout());
if let Some(proxy) = env_proxy::for_url_str(url)
.to_url()
.and_then(|url| ureq::Proxy::new(url).ok())
{
req.set_proxy(proxy);
}
let res = req.call();
if res.error() {
return Err(format!(
"HTTP request `{}` failed: {}",
url,
res.synthetic_error()
.as_ref()
.map(|x| x.to_string())
.unwrap_or_else(|| res.status().to_string())
)
.into());
let mut clientb = reqwest::blocking::Client::builder();
clientb = clientb.timeout(get_default_timeout());
clientb = clientb.proxy(Proxy::custom(|u| {
env_proxy::for_url(u).to_url()
}));
let client = clientb.build().unwrap();

match client.get(url).send().and_then(|r| r.error_for_status()) {
Err(e) => {
Err(format!(
"HTTP request `{}` failed: {}", url, e
).into())
},
Ok(res) => {
res.text().chain_err(|| "Git response not a valid `String`")
}
}

res.into_string()
.chain_err(|| "Git response not a valid `String`")
}

const fn get_default_timeout() -> Duration {
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,4 @@ pub use crate::fetch::{
};
pub use crate::manifest::{find, LocalManifest, Manifest};
pub use crate::metadata::manifest_from_pkgid;
pub use crate::registry::registry_url;
pub use crate::registry::{RegistryIndex, RegistryReq};
Loading