From 002996eb6baf93d3a43c9c433049de0298d3dcb1 Mon Sep 17 00:00:00 2001 From: Evgen Druzhynin Date: Thu, 22 Jun 2017 17:13:35 +0300 Subject: [PATCH 1/8] Credentials for multiple hosts. Now `cargo login` stores a token per host. If the host parameter is omitted cargo stores a token as default, i.e. as a token for crates.io. --- src/bin/login.rs | 23 +++++++++-------- src/cargo/core/source.rs | 2 +- src/cargo/ops/registry.rs | 38 +++++++++++++++++++++------- src/cargo/util/config.rs | 25 +++++++++++++----- tests/login.rs | 53 +++++++++++++++++++++++++++++---------- tests/publish.rs | 12 +++++++-- 6 files changed, 112 insertions(+), 41 deletions(-) diff --git a/src/bin/login.rs b/src/bin/login.rs index a9d6b1a710a..468c8453c79 100644 --- a/src/bin/login.rs +++ b/src/bin/login.rs @@ -40,26 +40,29 @@ pub fn execute(options: Options, config: &Config) -> CliResult { &options.flag_color, options.flag_frozen, options.flag_locked)?; - let token = match options.arg_token.clone() { + let token = match options.arg_token { Some(token) => token, None => { - let src = SourceId::crates_io(config)?; - let mut src = RegistrySource::remote(&src, config); - src.update()?; - let config = src.config()?.unwrap(); - let host = options.flag_host.clone().unwrap_or(config.api); + let host = match options.flag_host { + Some(ref host) => host.clone(), + None => { + let src = SourceId::crates_io(config)?; + let mut src = RegistrySource::remote(&src, config); + src.update()?; + src.config()?.unwrap().api + } + }; + println!("please visit {}me and paste the API Token below", host); let mut line = String::new(); let input = io::stdin(); input.lock().read_line(&mut line).chain_err(|| { "failed to read stdin" })?; - line + line.trim().to_string() } }; - let token = token.trim().to_string(); - ops::registry_login(config, token)?; + ops::registry_login(config, token, options.flag_host)?; Ok(()) } - diff --git a/src/cargo/core/source.rs b/src/cargo/core/source.rs index e7a3ce4a2e8..7487b8e9c9b 100644 --- a/src/cargo/core/source.rs +++ b/src/cargo/core/source.rs @@ -206,7 +206,7 @@ impl SourceId { /// This is the main cargo registry by default, but it can be overridden in /// a `.cargo/config`. pub fn crates_io(config: &Config) -> CargoResult { - let cfg = ops::registry_configuration(config)?; + let cfg = ops::registry_configuration(config, None)?; let url = if let Some(ref index) = cfg.index { static WARNED: AtomicBool = ATOMIC_BOOL_INIT; if !WARNED.swap(true, SeqCst) { diff --git a/src/cargo/ops/registry.rs b/src/cargo/ops/registry.rs index 35ec30257c2..cc63cb7530c 100644 --- a/src/cargo/ops/registry.rs +++ b/src/cargo/ops/registry.rs @@ -16,7 +16,7 @@ use core::dependency::Kind; use core::manifest::ManifestMetadata; use ops; use sources::{RegistrySource}; -use util::config::{self, Config}; +use util::config::{self, Config, Value, Definition}; use util::paths; use util::ToUrl; use util::errors::{CargoError, CargoResult, CargoResultExt}; @@ -176,10 +176,24 @@ fn transmit(config: &Config, } } -pub fn registry_configuration(config: &Config) -> CargoResult { - let index = config.get_string("registry.index")?.map(|p| p.val); - let token = config.get_string("registry.token")?.map(|p| p.val); - Ok(RegistryConfig { index: index, token: token }) +pub fn registry_configuration(config: &Config, + host: Option) -> CargoResult { + let (index, token) = match host { + Some(host) => { + (Some(Value { val: host.clone(), definition: Definition::Environment }), + config.get_string(&format!("registry.{}.token", host))?) + } + None => { + // Checking out for default index and token + (config.get_string("registry.index")?, + config.get_string("registry.token")?) + } + }; + + Ok(RegistryConfig { + index: index.map(|p| p.val), + token: token.map(|p| p.val) + }) } pub fn registry(config: &Config, @@ -189,7 +203,7 @@ pub fn registry(config: &Config, let RegistryConfig { token: token_config, index: _index_config, - } = registry_configuration(config)?; + } = registry_configuration(config, index.clone())?; let token = token.or(token_config); let sid = match index { Some(index) => SourceId::for_registry(&index.to_url()?), @@ -280,15 +294,21 @@ pub fn http_timeout(config: &Config) -> CargoResult> { Ok(env::var("HTTP_TIMEOUT").ok().and_then(|s| s.parse().ok())) } -pub fn registry_login(config: &Config, token: String) -> CargoResult<()> { - let RegistryConfig { index: _, token: old_token } = registry_configuration(config)?; +pub fn registry_login(config: &Config, + token: String, + host: Option) -> CargoResult<()> { + let RegistryConfig { + index: _, + token: old_token + } = registry_configuration(config, host.clone())?; + if let Some(old_token) = old_token { if old_token == token { return Ok(()); } } - config::save_credentials(config, token) + config::save_credentials(config, token, host) } pub struct OwnersOptions { diff --git a/src/cargo/util/config.rs b/src/cargo/util/config.rs index 2df174740df..dde70544ec5 100644 --- a/src/cargo/util/config.rs +++ b/src/cargo/util/config.rs @@ -835,23 +835,36 @@ fn walk_tree(pwd: &Path, mut walk: F) -> CargoResult<()> } pub fn save_credentials(cfg: &Config, - token: String) -> CargoResult<()> { + token: String, + host: Option) -> CargoResult<()> { let mut file = { cfg.home_path.create_dir()?; cfg.home_path.open_rw(Path::new("credentials"), cfg, - "credentials' config file")? + "credentials' config file")? + }; + + let (key, value) = { + let key = "token".to_string(); + let value = ConfigValue::String(token, file.path().to_path_buf()); + + if let Some(host) = host { + let mut map = HashMap::new(); + map.insert(key, value); + (host, CV::Table(map, file.path().to_path_buf())) + } else { + (key, value) + } }; let mut contents = String::new(); file.read_to_string(&mut contents).chain_err(|| { - format!("failed to read configuration file `{}`", - file.path().display()) + format!("failed to read configuration file `{}`", file.path().display()) })?; + let mut toml = cargo_toml::parse(&contents, file.path(), cfg)?; toml.as_table_mut() .unwrap() - .insert("token".to_string(), - ConfigValue::String(token, file.path().to_path_buf()).into_toml()); + .insert(key, value.into_toml()); let contents = toml.to_string(); file.seek(SeekFrom::Start(0))?; diff --git a/tests/login.rs b/tests/login.rs index d3b9b601b2f..7907da15763 100644 --- a/tests/login.rs +++ b/tests/login.rs @@ -30,20 +30,35 @@ fn setup_old_credentials() { fn setup_new_credentials() { let config = cargo_home().join("credentials"); t!(fs::create_dir_all(config.parent().unwrap())); - t!(t!(File::create(&config)).write_all(br#" + t!(t!(File::create(&config)).write_all(format!(r#" token = "api-token" - "#)); + + ["{registry}"] + token = "api-token" + "#, registry = registry().to_string()) + .as_bytes())); } -fn check_host_token(toml: toml::Value) -> bool { +fn check_host_token(mut toml: toml::Value, host_key: &str) -> bool { + for &key in [host_key, "token"].into_iter() { + if key.is_empty() { + continue + } + + match toml { + toml::Value::Table(table) => { + if let Some(v) = table.get(key) { + toml = v.clone(); + } else { + return false; + } + } + _ => break, + } + } + match toml { - toml::Value::Table(table) => match table.get("token") { - Some(v) => match v { - &toml::Value::String(ref token) => (token.as_str() == TOKEN), - _ => false, - }, - None => false, - }, + toml::Value::String(token) => (&token == TOKEN), _ => false, } } @@ -68,7 +83,7 @@ fn login_with_old_credentials() { contents.clear(); File::open(&credentials).unwrap().read_to_string(&mut contents).unwrap(); - assert!(check_host_token(contents.parse().unwrap())); + assert!(check_host_token(contents.parse().unwrap(), ®istry().to_string())); } #[test] @@ -87,7 +102,7 @@ fn login_with_new_credentials() { let mut contents = String::new(); File::open(&credentials).unwrap().read_to_string(&mut contents).unwrap(); - assert!(check_host_token(contents.parse().unwrap())); + assert!(check_host_token(contents.parse().unwrap(), ®istry().to_string())); } #[test] @@ -101,6 +116,8 @@ fn login_without_credentials() { assert_that(cargo_process().arg("login") .arg("--host").arg(registry().to_string()).arg(TOKEN), execs().with_status(0)); + assert_that(cargo_process().arg("login").arg(TOKEN), + execs().with_status(0)); let config = cargo_home().join("config"); assert_that(&config, is_not(existing_file())); @@ -110,7 +127,9 @@ fn login_without_credentials() { let mut contents = String::new(); File::open(&credentials).unwrap().read_to_string(&mut contents).unwrap(); - assert!(check_host_token(contents.parse().unwrap())); + let toml: toml::Value = contents.parse().unwrap(); + assert!(check_host_token(toml.clone(), ®istry().to_string())); + assert!(check_host_token(toml, "")); } #[test] @@ -118,11 +137,19 @@ fn new_credentials_is_used_instead_old() { setup_old_credentials(); setup_new_credentials(); + assert_that(cargo_process().arg("login").arg(TOKEN), + execs().with_status(0)); + assert_that(cargo_process().arg("login") .arg("--host").arg(registry().to_string()).arg(TOKEN), execs().with_status(0)); let config = Config::new(Shell::new(), cargo_home(), cargo_home()); + let token = config.get_string("registry.token").unwrap().map(|p| p.val); assert!(token.unwrap() == TOKEN); + + let token_host = config.get_string(&format!(r#"registry.{}.token"#, registry().to_string())) + .unwrap().map(|p| p.val); + assert!(token_host.unwrap() == TOKEN); } diff --git a/tests/publish.rs b/tests/publish.rs index 968281f6219..67ab05e0985 100644 --- a/tests/publish.rs +++ b/tests/publish.rs @@ -13,6 +13,7 @@ use std::path::PathBuf; use cargotest::support::git::repo; use cargotest::support::paths; use cargotest::support::{project, execs}; +use cargotest::install::cargo_home; use flate2::read::GzDecoder; use hamcrest::assert_that; use tar::Archive; @@ -24,14 +25,21 @@ fn upload_path() -> PathBuf { paths::root().join("upload") } fn upload() -> Url { Url::from_file_path(&*upload_path()).ok().unwrap() } fn setup() { - let config = paths::root().join(".cargo/config"); + let config = cargo_home().join("config"); t!(fs::create_dir_all(config.parent().unwrap())); t!(t!(File::create(&config)).write_all(br#" [registry] - token = "api-token" + token = "api-token" "#)); t!(fs::create_dir_all(&upload_path().join("api/v1/crates"))); + let credentials = cargo_home().join("credentials"); + t!(t!(File::create(&credentials)).write_all(format!(r#" + ["{registry}"] + token = "api-token" + "#, registry = registry().to_string()) + .as_bytes())); + repo(®istry_path()) .file("config.json", &format!(r#"{{ "dl": "{0}", From 053b9f9178a3c35612384c9c39ad26f53fafdf53 Mon Sep 17 00:00:00 2001 From: Chris Swindle Date: Mon, 30 Oct 2017 14:29:37 +0000 Subject: [PATCH 2/8] Adding support to provide login credentials for an alternate registry. --- src/bin/login.rs | 13 ++- src/bin/owner.rs | 3 + src/bin/publish.rs | 4 + src/bin/search.rs | 5 +- src/bin/yank.rs | 5 +- src/cargo/core/source/source_id.rs | 21 +++-- src/cargo/ops/registry.rs | 69 +++++++++------ src/cargo/util/config.rs | 14 ++- tests/alt-registry.rs | 47 ++++++++++ tests/login.rs | 132 ++++++++++++++++++----------- 10 files changed, 217 insertions(+), 96 deletions(-) diff --git a/src/bin/login.rs b/src/bin/login.rs index 7a539777875..d55176ca9db 100755 --- a/src/bin/login.rs +++ b/src/bin/login.rs @@ -17,6 +17,7 @@ pub struct Options { flag_locked: bool, #[serde(rename = "flag_Z")] flag_z: Vec, + flag_registry: Option, } pub const USAGE: &'static str = " @@ -34,6 +35,7 @@ Options: --frozen Require Cargo.lock and cache are up to date --locked Require Cargo.lock is up to date -Z FLAG ... Unstable (nightly-only) flags to Cargo + --registry REGISTRY Registry to use "; @@ -47,13 +49,16 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult { let token = match options.arg_token { Some(token) => token, None => { - let host = match options.flag_host { - Some(ref host) => host.clone(), + let host = match options.flag_registry { + Some(ref registry) => { + config.get_registry_index(registry)? + } None => { let src = SourceId::crates_io(config)?; let mut src = RegistrySource::remote(&src, config); src.update()?; - src.config()?.unwrap().api.unwrap() + let config = src.config()?.unwrap(); + options.flag_host.clone().unwrap_or(config.api.unwrap()) } }; println!("please visit {}me and paste the API Token below", host); @@ -66,6 +71,6 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult { } }; - ops::registry_login(config, token, options.flag_host)?; + ops::registry_login(config, token, options.flag_registry)?; Ok(()) } diff --git a/src/bin/owner.rs b/src/bin/owner.rs index 6c76a6fafc5..e5d5e3530fe 100644 --- a/src/bin/owner.rs +++ b/src/bin/owner.rs @@ -16,6 +16,7 @@ pub struct Options { flag_locked: bool, #[serde(rename = "flag_Z")] flag_z: Vec, + flag_registry: Option, } pub const USAGE: &'static str = " @@ -37,6 +38,7 @@ Options: --frozen Require Cargo.lock and cache are up to date --locked Require Cargo.lock is up to date -Z FLAG ... Unstable (nightly-only) flags to Cargo + --registry REGISTRY Registry to use This command will modify the owners for a package on the specified registry (or default). Note that owners of a package can upload new versions, yank old @@ -61,6 +63,7 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult { to_add: options.flag_add, to_remove: options.flag_remove, list: options.flag_list, + registry: options.flag_registry, }; ops::modify_owners(config, &opts)?; Ok(()) diff --git a/src/bin/publish.rs b/src/bin/publish.rs index c34a0e27067..b29ed9155ae 100644 --- a/src/bin/publish.rs +++ b/src/bin/publish.rs @@ -21,6 +21,7 @@ pub struct Options { flag_locked: bool, #[serde(rename = "flag_Z")] flag_z: Vec, + flag_registry: Option, } pub const USAGE: &'static str = " @@ -46,6 +47,7 @@ Options: --frozen Require Cargo.lock and cache are up to date --locked Require Cargo.lock is up to date -Z FLAG ... Unstable (nightly-only) flags to Cargo + --registry REGISTRY Registry to publish to "; @@ -67,6 +69,7 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult { flag_jobs: jobs, flag_dry_run: dry_run, flag_target: target, + flag_registry: registry, .. } = options; @@ -100,6 +103,7 @@ about this warning."; target: target.as_ref().map(|t| &t[..]), jobs: jobs, dry_run: dry_run, + registry: registry, })?; Ok(()) } diff --git a/src/bin/search.rs b/src/bin/search.rs index 165dea1c8b2..8392f9af6c3 100644 --- a/src/bin/search.rs +++ b/src/bin/search.rs @@ -16,6 +16,7 @@ pub struct Options { arg_query: Vec, #[serde(rename = "flag_Z")] flag_z: Vec, + flag_registry: Option, } pub const USAGE: &'static str = " @@ -36,6 +37,7 @@ Options: --frozen Require Cargo.lock and cache are up to date --locked Require Cargo.lock is up to date -Z FLAG ... Unstable (nightly-only) flags to Cargo + --registry REGISTRY Registry to use "; pub fn execute(options: Options, config: &mut Config) -> CliResult { @@ -50,6 +52,7 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult { flag_host: host, // TODO: Depricated, remove flag_limit: limit, arg_query: query, + flag_registry: registry, .. } = options; @@ -77,6 +80,6 @@ about this warning."; host }; - ops::search(&query.join("+"), config, index, cmp::min(100, limit.unwrap_or(10)) as u8)?; + ops::search(&query.join("+"), config, index, cmp::min(100, limit.unwrap_or(10)) as u8, registry)?; Ok(()) } diff --git a/src/bin/yank.rs b/src/bin/yank.rs index a00892a5193..8ddf5242182 100644 --- a/src/bin/yank.rs +++ b/src/bin/yank.rs @@ -15,6 +15,7 @@ pub struct Options { flag_locked: bool, #[serde(rename = "flag_Z")] flag_z: Vec, + flag_registry: Option, } pub static USAGE: &'static str = " @@ -35,6 +36,7 @@ Options: --frozen Require Cargo.lock and cache are up to date --locked Require Cargo.lock is up to date -Z FLAG ... Unstable (nightly-only) flags to Cargo + --registry REGISTRY Registry to use The yank command removes a previously pushed crate's version from the server's index. This command does not delete any data, and the crate will still be @@ -57,7 +59,8 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult { options.flag_vers, options.flag_token, options.flag_index, - options.flag_undo)?; + options.flag_undo, + options.flag_registry)?; Ok(()) } diff --git a/src/cargo/core/source/source_id.rs b/src/cargo/core/source/source_id.rs index 566e9855a62..ed34c95e6c0 100644 --- a/src/cargo/core/source/source_id.rs +++ b/src/cargo/core/source/source_id.rs @@ -183,17 +183,16 @@ impl SourceId { } pub fn alt_registry(config: &Config, key: &str) -> CargoResult { - if let Some(index) = config.get_string(&format!("registries.{}.index", key))? { - let url = index.val.to_url()?; - Ok(SourceId { - inner: Arc::new(SourceIdInner { - kind: Kind::Registry, - canonical_url: git::canonicalize_url(&url)?, - url: url, - precise: None, - }), - }) - } else { Err(format!("No index found for registry: `{}`", key).into()) } + let index = config.get_registry_index(key)?; + let url = index.to_url()?; + Ok(SourceId { + inner: Arc::new(SourceIdInner { + kind: Kind::Registry, + canonical_url: git::canonicalize_url(&url)?, + url: url, + precise: None, + }), + }) } /// Get this source URL diff --git a/src/cargo/ops/registry.rs b/src/cargo/ops/registry.rs index 8119116f624..bb3d5dda8e8 100755 --- a/src/cargo/ops/registry.rs +++ b/src/cargo/ops/registry.rs @@ -16,7 +16,7 @@ use core::dependency::Kind; use core::manifest::ManifestMetadata; use ops; use sources::{RegistrySource}; -use util::config::{self, Config, Value, Definition}; +use util::config::{self, Config, ConfigValue}; use util::paths; use util::ToUrl; use util::errors::{CargoError, CargoResult, CargoResultExt}; @@ -36,6 +36,7 @@ pub struct PublishOpts<'cfg> { pub jobs: Option, pub target: Option<&'cfg str>, pub dry_run: bool, + pub registry: Option, } pub fn publish(ws: &Workspace, opts: &PublishOpts) -> CargoResult<()> { @@ -51,7 +52,8 @@ pub fn publish(ws: &Workspace, opts: &PublishOpts) -> CargoResult<()> { let (mut registry, reg_id) = registry(opts.config, opts.token.clone(), - opts.index.clone())?; + opts.index.clone(), + opts.registry.clone())?; verify_dependencies(pkg, ®_id)?; // Prepare a tarball, with a non-surpressable warning if metadata @@ -190,37 +192,47 @@ fn transmit(config: &Config, } pub fn registry_configuration(config: &Config, - host: Option) -> CargoResult { - let (index, token) = match host { - Some(host) => { - (Some(Value { val: host.clone(), definition: Definition::Environment }), - config.get_string(&format!("registry.{}.token", host))?) + registry: Option) -> CargoResult { + + let (index, token) = match registry { + Some(registry) => { + let index = Some(config.get_registry_index(®istry)?); + let table = config.get_table(&format!("registry.{}", registry))?.map(|t| t.val); + let token = table.and_then(|table| { + match table.get("token".into()) { + Some(&ConfigValue::String(ref i, _)) => Some(i.to_string()), + _ => None, + } + }); + + (index, token) } None => { // Checking out for default index and token - (config.get_string("registry.index")?, - config.get_string("registry.token")?) + (config.get_string("registry.index")?.map(|p| p.val), + config.get_string("registry.token")?.map(|p| p.val)) } }; Ok(RegistryConfig { - index: index.map(|p| p.val), - token: token.map(|p| p.val) + index: index, + token: token }) } pub fn registry(config: &Config, token: Option, - index: Option) -> CargoResult<(Registry, SourceId)> { + index: Option, + registry: Option) -> CargoResult<(Registry, SourceId)> { // Parse all configuration options let RegistryConfig { token: token_config, - index: _index_config, - } = registry_configuration(config, index.clone())?; + index: index_config, + } = registry_configuration(config, registry.clone())?; let token = token.or(token_config); - let sid = match index { - Some(index) => SourceId::for_registry(&index.to_url()?)?, - None => SourceId::crates_io(config)?, + let sid = match (index_config, index) { + (Some(index), _) | (None, Some(index)) => SourceId::for_registry(&index.to_url()?)?, + (None, None) => SourceId::crates_io(config)?, }; let api_host = { let mut src = RegistrySource::remote(&sid, config); @@ -309,11 +321,11 @@ pub fn http_timeout(config: &Config) -> CargoResult> { pub fn registry_login(config: &Config, token: String, - host: Option) -> CargoResult<()> { + registry: Option) -> CargoResult<()> { let RegistryConfig { token: old_token, .. - } = registry_configuration(config, host.clone())?; + } = registry_configuration(config, registry.clone())?; if let Some(old_token) = old_token { if old_token == token { @@ -321,7 +333,7 @@ pub fn registry_login(config: &Config, } } - config::save_credentials(config, token, host) + config::save_credentials(config, token, registry) } pub struct OwnersOptions { @@ -331,6 +343,7 @@ pub struct OwnersOptions { pub to_add: Option>, pub to_remove: Option>, pub list: bool, + pub registry: Option, } pub fn modify_owners(config: &Config, opts: &OwnersOptions) -> CargoResult<()> { @@ -343,8 +356,10 @@ pub fn modify_owners(config: &Config, opts: &OwnersOptions) -> CargoResult<()> { } }; - let (mut registry, _) = registry(config, opts.token.clone(), - opts.index.clone())?; + let (mut registry, _) = registry(config, + opts.token.clone(), + opts.index.clone(), + opts.registry.clone())?; if let Some(ref v) = opts.to_add { let v = v.iter().map(|s| &s[..]).collect::>(); @@ -387,7 +402,8 @@ pub fn yank(config: &Config, version: Option, token: Option, index: Option, - undo: bool) -> CargoResult<()> { + undo: bool, + reg: Option) -> CargoResult<()> { let name = match krate { Some(name) => name, None => { @@ -401,7 +417,7 @@ pub fn yank(config: &Config, None => bail!("a version must be specified to yank") }; - let (mut registry, _) = registry(config, token, index)?; + let (mut registry, _) = registry(config, token, index, reg)?; if undo { config.shell().status("Unyank", format!("{}:{}", name, version))?; @@ -421,7 +437,8 @@ pub fn yank(config: &Config, pub fn search(query: &str, config: &Config, index: Option, - limit: u8) -> CargoResult<()> { + limit: u8, + reg: Option) -> CargoResult<()> { fn truncate_with_ellipsis(s: &str, max_length: usize) -> String { if s.len() < max_length { s.to_string() @@ -430,7 +447,7 @@ pub fn search(query: &str, } } - let (mut registry, _) = registry(config, None, index)?; + let (mut registry, _) = registry(config, None, index, reg)?; let (crates, total_crates) = registry.search(query, limit).map_err(|e| { CargoError::from(format!("failed to retrieve search results from the registry: {}", e)) })?; diff --git a/src/cargo/util/config.rs b/src/cargo/util/config.rs index ba1f21ce47a..47e79baab5b 100644 --- a/src/cargo/util/config.rs +++ b/src/cargo/util/config.rs @@ -545,6 +545,14 @@ impl Config { } } + /// Gets the index for a registry. + pub fn get_registry_index(&self, registry: &str) -> CargoResult { + Ok(match self.get_string(&format!("registries.{}.index", registry))? { + Some(index) => index.val, + None => return Err(CargoError::from(format!("No index found for registry: `{}`", registry)).into()), + }) + } + /// Loads credentials config from the credentials file into the ConfigValue object, if present. fn load_credentials(&self, cfg: &mut ConfigValue) -> CargoResult<()> { let home_path = self.home_path.clone().into_path_unlocked(); @@ -886,7 +894,7 @@ fn walk_tree(pwd: &Path, mut walk: F) -> CargoResult<()> pub fn save_credentials(cfg: &Config, token: String, - host: Option) -> CargoResult<()> { + registry: Option) -> CargoResult<()> { let mut file = { cfg.home_path.create_dir()?; cfg.home_path.open_rw(Path::new("credentials"), cfg, @@ -897,10 +905,10 @@ pub fn save_credentials(cfg: &Config, let key = "token".to_string(); let value = ConfigValue::String(token, file.path().to_path_buf()); - if let Some(host) = host { + if let Some(registry) = registry { let mut map = HashMap::new(); map.insert(key, value); - (host, CV::Table(map, file.path().to_path_buf())) + (registry, CV::Table(map, file.path().to_path_buf())) } else { (key, value) } diff --git a/tests/alt-registry.rs b/tests/alt-registry.rs index 9c1072fd733..c6c6b3ee725 100755 --- a/tests/alt-registry.rs +++ b/tests/alt-registry.rs @@ -262,3 +262,50 @@ fn alt_registry_and_crates_io_deps() { [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] secs")) } + +#[test] +fn block_publish_due_to_no_token() { + let p = project("foo") + .file("Cargo.toml", r#" + [project] + name = "foo" + version = "0.0.1" + authors = [] + "#) + .file("src/main.rs", "fn main() {}") + .build(); + + // Setup the registry by publishing a package + Package::new("bar", "0.0.1").alternative(true).publish(); + + // Now perform the actual publish + assert_that(p.cargo("publish").masquerade_as_nightly_cargo() + .arg("--registry").arg("alternative"), + execs().with_status(101)); +} + +#[test] +fn publish_to_alt_registry() { + let p = project("foo") + .file("Cargo.toml", r#" + [project] + name = "foo" + version = "0.0.1" + authors = [] + "#) + .file("src/main.rs", "fn main() {}") + .build(); + + // Setup the registry by publishing a package + Package::new("bar", "0.0.1").alternative(true).publish(); + + // Login so that we have the token available + assert_that(p.cargo("login") + .arg("--registry").arg("alternative").arg("TOKEN"), + execs().with_status(0)); + + // Now perform the actual publish + assert_that(p.cargo("publish").masquerade_as_nightly_cargo() + .arg("--registry").arg("alternative"), + execs().with_status(0)); +} diff --git a/tests/login.rs b/tests/login.rs index 7153002e6d6..5e6f56192cb 100755 --- a/tests/login.rs +++ b/tests/login.rs @@ -16,9 +16,16 @@ use cargo::core::Shell; use hamcrest::{assert_that, existing_file, is_not}; const TOKEN: &str = "test-token"; +const ORIGINAL_TOKEN: &str = "api-token"; const CONFIG_FILE: &str = r#" [registry] token = "api-token" + + [registries.test-reg] + index = "dummy_index" + + [registries.test.reg] + index = "dummy_index" "#; fn setup_old_credentials() { @@ -31,35 +38,47 @@ fn setup_new_credentials() { let config = cargo_home().join("credentials"); t!(fs::create_dir_all(config.parent().unwrap())); t!(t!(File::create(&config)).write_all(format!(r#" - token = "api-token" - - ["{registry}"] - token = "api-token" - "#, registry = registry().to_string()) + token = "{token}" + "#, token = ORIGINAL_TOKEN) .as_bytes())); } -fn check_host_token(mut toml: toml::Value, host_key: &str) -> bool { - for &key in [host_key, "token"].into_iter() { - if key.is_empty() { - continue - } +fn check_token(expected_token: &str, registry: Option<&str>) -> bool { + + let credentials = cargo_home().join("credentials"); + assert_that(&credentials, existing_file()); - match toml { - toml::Value::Table(table) => { - if let Some(v) = table.get(key) { - toml = v.clone(); - } else { - return false; + let mut contents = String::new(); + File::open(&credentials).unwrap().read_to_string(&mut contents).unwrap(); + let toml: toml::Value = contents.parse().unwrap(); + + let token = match (registry, toml) { + // A registry has been provided, so check that the token exists in a + // table for the registry. + (Some(registry), toml::Value::Table(table)) => { + table.get(registry).and_then(|registry_table| { + match registry_table.get("token") { + Some(&toml::Value::String(ref token)) => Some(token.as_str().to_string()), + _ => None, + } + }) + }, + // There is no registry provided, so check the global token instead. + (None, toml::Value::Table(table)) => { + table.get("token").and_then(|v| { + match v { + &toml::Value::String(ref token) => Some(token.as_str().to_string()), + _ => None, } - } - _ => break, + }) } - } + _ => None + }; - match toml { - toml::Value::String(token) => (&token == TOKEN), - _ => false, + if let Some(token_val) = token { + token_val == expected_token + } else { + false } } @@ -78,12 +97,8 @@ fn login_with_old_credentials() { File::open(&config).unwrap().read_to_string(&mut contents).unwrap(); assert_eq!(CONFIG_FILE, contents); - let credentials = cargo_home().join("credentials"); - assert_that(&credentials, existing_file()); - - contents.clear(); - File::open(&credentials).unwrap().read_to_string(&mut contents).unwrap(); - assert!(check_host_token(contents.parse().unwrap(), ®istry().to_string())); + // Ensure that we get the new token for the registry + assert!(check_token(TOKEN, None)); } #[test] @@ -97,12 +112,8 @@ fn login_with_new_credentials() { let config = cargo_home().join("config"); assert_that(&config, is_not(existing_file())); - let credentials = cargo_home().join("credentials"); - assert_that(&credentials, existing_file()); - - let mut contents = String::new(); - File::open(&credentials).unwrap().read_to_string(&mut contents).unwrap(); - assert!(check_host_token(contents.parse().unwrap(), ®istry().to_string())); + // Ensure that we get the new token for the registry + assert!(check_token(TOKEN, None)); } #[test] @@ -116,20 +127,12 @@ fn login_without_credentials() { assert_that(cargo_process().arg("login") .arg("--host").arg(registry().to_string()).arg(TOKEN), execs().with_status(0)); - assert_that(cargo_process().arg("login").arg(TOKEN), - execs().with_status(0)); let config = cargo_home().join("config"); assert_that(&config, is_not(existing_file())); - let credentials = cargo_home().join("credentials"); - assert_that(&credentials, existing_file()); - - let mut contents = String::new(); - File::open(&credentials).unwrap().read_to_string(&mut contents).unwrap(); - let toml: toml::Value = contents.parse().unwrap(); - assert!(check_host_token(toml.clone(), ®istry().to_string())); - assert!(check_host_token(toml, "")); + // Ensure that we get the new token for the registry + assert!(check_token(TOKEN, None)); } #[test] @@ -137,9 +140,6 @@ fn new_credentials_is_used_instead_old() { setup_old_credentials(); setup_new_credentials(); - assert_that(cargo_process().arg("login").arg(TOKEN), - execs().with_status(0)); - assert_that(cargo_process().arg("login") .arg("--host").arg(registry().to_string()).arg(TOKEN), execs().with_status(0)); @@ -148,8 +148,40 @@ fn new_credentials_is_used_instead_old() { let token = config.get_string("registry.token").unwrap().map(|p| p.val); assert_eq!(token.unwrap(), TOKEN); +} + +#[test] +fn registry_credentials() { + setup_old_credentials(); + setup_new_credentials(); + + let reg = "test-reg"; + + assert_that(cargo_process().arg("login") + .arg("--registry").arg(reg).arg(TOKEN), + execs().with_status(0)); + + // Ensure that we have not updated the default token + assert!(check_token(ORIGINAL_TOKEN, None)); + + // Also ensure that we get the new token for the registry + assert!(check_token(TOKEN, Some(reg))); +} + +#[test] +fn registry_credentials_with_dots() { + setup_old_credentials(); + setup_new_credentials(); + + let reg = "test.reg"; + + assert_that(cargo_process().arg("login") + .arg("--registry").arg(reg).arg(TOKEN), + execs().with_status(0)); + + // Ensure that we have not updated the default token + assert!(check_token(ORIGINAL_TOKEN, None)); - let token_host = config.get_string(&format!(r#"registry.{}.token"#, registry().to_string())) - .unwrap().map(|p| p.val); - assert_eq!(token_host.unwrap(), TOKEN); + // Also ensure that we get the new token for the registry + assert!(check_token(TOKEN, Some(reg))); } From 0f82507ec16a60a0138de35cce7fcd2c211b8699 Mon Sep 17 00:00:00 2001 From: Chris Swindle Date: Mon, 30 Oct 2017 20:56:23 +0000 Subject: [PATCH 3/8] Adding unstable-options flag to feature gate the use of --registry option. --- src/bin/login.rs | 7 ++++++- src/bin/owner.rs | 7 ++++++- src/bin/publish.rs | 5 ++++- src/bin/search.rs | 6 +++++- src/bin/yank.rs | 7 ++++++- src/cargo/core/features.rs | 2 ++ tests/alt-registry.rs | 9 ++++----- tests/login.rs | 10 +++++----- 8 files changed, 38 insertions(+), 15 deletions(-) diff --git a/src/bin/login.rs b/src/bin/login.rs index d55176ca9db..a771d745348 100755 --- a/src/bin/login.rs +++ b/src/bin/login.rs @@ -4,7 +4,7 @@ use std::io; use cargo::ops; use cargo::core::{SourceId, Source}; use cargo::sources::RegistrySource; -use cargo::util::{CliResult, CargoResultExt, Config}; +use cargo::util::{CargoError, CliResult, CargoResultExt, Config}; #[derive(Deserialize)] pub struct Options { @@ -46,6 +46,11 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult { options.flag_frozen, options.flag_locked, &options.flag_z)?; + + if options.flag_registry.is_some() && !config.cli_unstable().unstable_options { + return Err(CargoError::from("registry option is an unstable feature and requires -Zunstable-options to use.").into()); + } + let token = match options.arg_token { Some(token) => token, None => { diff --git a/src/bin/owner.rs b/src/bin/owner.rs index e5d5e3530fe..466d565975e 100644 --- a/src/bin/owner.rs +++ b/src/bin/owner.rs @@ -1,5 +1,5 @@ use cargo::ops; -use cargo::util::{CliResult, Config}; +use cargo::util::{CargoError, CliResult, Config}; #[derive(Deserialize)] pub struct Options { @@ -65,6 +65,11 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult { list: options.flag_list, registry: options.flag_registry, }; + + if opts.registry.is_some() && !config.cli_unstable().unstable_options { + return Err(CargoError::from("registry option is an unstable feature and requires -Zunstable-options to use.").into()); + } + ops::modify_owners(config, &opts)?; Ok(()) } diff --git a/src/bin/publish.rs b/src/bin/publish.rs index b29ed9155ae..6b574cb7f5c 100644 --- a/src/bin/publish.rs +++ b/src/bin/publish.rs @@ -1,6 +1,6 @@ use cargo::core::Workspace; use cargo::ops; -use cargo::util::{CliResult, Config}; +use cargo::util::{CargoError, CliResult, Config}; use cargo::util::important_paths::find_root_manifest_for_wd; #[derive(Deserialize)] @@ -73,6 +73,9 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult { .. } = options; + if registry.is_some() && !config.cli_unstable().unstable_options { + return Err(CargoError::from("registry option is an unstable feature and requires -Zunstable-options to use.").into()); + } // TODO: Deprecated // remove once it has been decided --host can be removed diff --git a/src/bin/search.rs b/src/bin/search.rs index 8392f9af6c3..70b38ecfbfd 100644 --- a/src/bin/search.rs +++ b/src/bin/search.rs @@ -1,5 +1,5 @@ use cargo::ops; -use cargo::util::{CliResult, Config}; +use cargo::util::{CargoError, CliResult, Config}; use std::cmp; @@ -56,6 +56,10 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult { .. } = options; + if registry.is_some() && !config.cli_unstable().unstable_options { + return Err(CargoError::from("registry option is an unstable feature and requires -Zunstable-options to use.").into()); + } + // TODO: Depricated // remove once it has been decided --host can be safely removed // We may instead want to repurpose the host flag, as diff --git a/src/bin/yank.rs b/src/bin/yank.rs index 8ddf5242182..64eb3a04c5b 100644 --- a/src/bin/yank.rs +++ b/src/bin/yank.rs @@ -1,5 +1,5 @@ use cargo::ops; -use cargo::util::{CliResult, Config}; +use cargo::util::{CargoError, CliResult, Config}; #[derive(Deserialize)] pub struct Options { @@ -54,6 +54,11 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult { options.flag_frozen, options.flag_locked, &options.flag_z)?; + + if options.flag_registry.is_some() && !config.cli_unstable().unstable_options { + return Err(CargoError::from("registry option is an unstable feature and requires -Zunstable-options to use.").into()); + } + ops::yank(config, options.arg_crate, options.flag_vers, diff --git a/src/cargo/core/features.rs b/src/cargo/core/features.rs index d4e91c01013..4cb5ac5e44b 100644 --- a/src/cargo/core/features.rs +++ b/src/cargo/core/features.rs @@ -231,6 +231,7 @@ impl Features { #[derive(Default, Debug)] pub struct CliUnstable { pub print_im_a_teapot: bool, + pub unstable_options: bool, } impl CliUnstable { @@ -260,6 +261,7 @@ impl CliUnstable { match k { "print-im-a-teapot" => self.print_im_a_teapot = parse_bool(v)?, + "unstable-options" => self.unstable_options = true, _ => bail!("unknown `-Z` flag specified: {}", k), } diff --git a/tests/alt-registry.rs b/tests/alt-registry.rs index c6c6b3ee725..c7b937d8915 100755 --- a/tests/alt-registry.rs +++ b/tests/alt-registry.rs @@ -1,4 +1,3 @@ -#[macro_use] extern crate cargotest; extern crate hamcrest; @@ -280,7 +279,7 @@ fn block_publish_due_to_no_token() { // Now perform the actual publish assert_that(p.cargo("publish").masquerade_as_nightly_cargo() - .arg("--registry").arg("alternative"), + .arg("--registry").arg("alternative").arg("-Zunstable-options"), execs().with_status(101)); } @@ -300,12 +299,12 @@ fn publish_to_alt_registry() { Package::new("bar", "0.0.1").alternative(true).publish(); // Login so that we have the token available - assert_that(p.cargo("login") - .arg("--registry").arg("alternative").arg("TOKEN"), + assert_that(p.cargo("login").masquerade_as_nightly_cargo() + .arg("--registry").arg("alternative").arg("TOKEN").arg("-Zunstable-options"), execs().with_status(0)); // Now perform the actual publish assert_that(p.cargo("publish").masquerade_as_nightly_cargo() - .arg("--registry").arg("alternative"), + .arg("--registry").arg("alternative").arg("-Zunstable-options"), execs().with_status(0)); } diff --git a/tests/login.rs b/tests/login.rs index 5e6f56192cb..b35c72a619f 100755 --- a/tests/login.rs +++ b/tests/login.rs @@ -7,7 +7,7 @@ extern crate toml; use std::io::prelude::*; use std::fs::{self, File}; -use cargotest::cargo_process; +use cargotest::{ChannelChanger, cargo_process}; use cargotest::support::execs; use cargotest::support::registry::registry; use cargotest::install::cargo_home; @@ -157,8 +157,8 @@ fn registry_credentials() { let reg = "test-reg"; - assert_that(cargo_process().arg("login") - .arg("--registry").arg(reg).arg(TOKEN), + assert_that(cargo_process().arg("login").masquerade_as_nightly_cargo() + .arg("--registry").arg(reg).arg(TOKEN).arg("-Zunstable-options"), execs().with_status(0)); // Ensure that we have not updated the default token @@ -175,8 +175,8 @@ fn registry_credentials_with_dots() { let reg = "test.reg"; - assert_that(cargo_process().arg("login") - .arg("--registry").arg(reg).arg(TOKEN), + assert_that(cargo_process().arg("login").masquerade_as_nightly_cargo() + .arg("--registry").arg(reg).arg(TOKEN).arg("-Zunstable-options"), execs().with_status(0)); // Ensure that we have not updated the default token From 0bda323c0879b2f1f3f1e16616a8a28436b7d7c7 Mon Sep 17 00:00:00 2001 From: Chris Swindle Date: Mon, 30 Oct 2017 21:25:24 +0000 Subject: [PATCH 4/8] Updating based on review comments. --- src/bin/login.rs | 4 ++-- src/cargo/core/source/source_id.rs | 3 +-- src/cargo/ops/registry.rs | 2 +- src/cargo/util/config.rs | 6 ++++-- tests/login.rs | 4 ++-- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/bin/login.rs b/src/bin/login.rs index a771d745348..499980c6d31 100755 --- a/src/bin/login.rs +++ b/src/bin/login.rs @@ -55,8 +55,8 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult { Some(token) => token, None => { let host = match options.flag_registry { - Some(ref registry) => { - config.get_registry_index(registry)? + Some(ref _registry) => { + return Err(CargoError::from("token must be provided when --registry is provided.").into()); } None => { let src = SourceId::crates_io(config)?; diff --git a/src/cargo/core/source/source_id.rs b/src/cargo/core/source/source_id.rs index ed34c95e6c0..955ecca2107 100644 --- a/src/cargo/core/source/source_id.rs +++ b/src/cargo/core/source/source_id.rs @@ -183,8 +183,7 @@ impl SourceId { } pub fn alt_registry(config: &Config, key: &str) -> CargoResult { - let index = config.get_registry_index(key)?; - let url = index.to_url()?; + let url = config.get_registry_index(key)?; Ok(SourceId { inner: Arc::new(SourceIdInner { kind: Kind::Registry, diff --git a/src/cargo/ops/registry.rs b/src/cargo/ops/registry.rs index bb3d5dda8e8..5b127c78d6b 100755 --- a/src/cargo/ops/registry.rs +++ b/src/cargo/ops/registry.rs @@ -196,7 +196,7 @@ pub fn registry_configuration(config: &Config, let (index, token) = match registry { Some(registry) => { - let index = Some(config.get_registry_index(®istry)?); + let index = Some(config.get_registry_index(®istry)?.to_string()); let table = config.get_table(&format!("registry.{}", registry))?.map(|t| t.val); let token = table.and_then(|table| { match table.get("token".into()) { diff --git a/src/cargo/util/config.rs b/src/cargo/util/config.rs index 47e79baab5b..5bf967b1af1 100644 --- a/src/cargo/util/config.rs +++ b/src/cargo/util/config.rs @@ -20,6 +20,8 @@ use toml; use core::shell::Verbosity; use core::{Shell, CliUnstable}; use ops; +use url::Url; +use util::ToUrl; use util::Rustc; use util::errors::{CargoResult, CargoResultExt, CargoError, internal}; use util::paths; @@ -546,9 +548,9 @@ impl Config { } /// Gets the index for a registry. - pub fn get_registry_index(&self, registry: &str) -> CargoResult { + pub fn get_registry_index(&self, registry: &str) -> CargoResult { Ok(match self.get_string(&format!("registries.{}.index", registry))? { - Some(index) => index.val, + Some(index) => index.val.to_url()?, None => return Err(CargoError::from(format!("No index found for registry: `{}`", registry)).into()), }) } diff --git a/tests/login.rs b/tests/login.rs index b35c72a619f..9aa35640896 100755 --- a/tests/login.rs +++ b/tests/login.rs @@ -22,10 +22,10 @@ const CONFIG_FILE: &str = r#" token = "api-token" [registries.test-reg] - index = "dummy_index" + index = "http://dummy_index/" [registries.test.reg] - index = "dummy_index" + index = "http://dummy_index/" "#; fn setup_old_credentials() { From 31cb68df376af7ad2ede1b8dca3b83489c0165b3 Mon Sep 17 00:00:00 2001 From: Chris Swindle Date: Tue, 31 Oct 2017 05:20:41 +0000 Subject: [PATCH 5/8] Switching over to get-string for registry credentials. --- src/cargo/ops/registry.rs | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/cargo/ops/registry.rs b/src/cargo/ops/registry.rs index 5b127c78d6b..d8364c28d29 100755 --- a/src/cargo/ops/registry.rs +++ b/src/cargo/ops/registry.rs @@ -16,7 +16,7 @@ use core::dependency::Kind; use core::manifest::ManifestMetadata; use ops; use sources::{RegistrySource}; -use util::config::{self, Config, ConfigValue}; +use util::config::{self, Config}; use util::paths; use util::ToUrl; use util::errors::{CargoError, CargoResult, CargoResultExt}; @@ -196,16 +196,8 @@ pub fn registry_configuration(config: &Config, let (index, token) = match registry { Some(registry) => { - let index = Some(config.get_registry_index(®istry)?.to_string()); - let table = config.get_table(&format!("registry.{}", registry))?.map(|t| t.val); - let token = table.and_then(|table| { - match table.get("token".into()) { - Some(&ConfigValue::String(ref i, _)) => Some(i.to_string()), - _ => None, - } - }); - - (index, token) + (Some(config.get_registry_index(®istry)?.to_string()), + config.get_string(&format!("registry.{}.token", registry))?.map(|p| p.val)) } None => { // Checking out for default index and token From 3c7a3cb8ef6d2ac60d20ece6c230ac2e958725b1 Mon Sep 17 00:00:00 2001 From: Chris Swindle Date: Tue, 31 Oct 2017 16:00:21 +0000 Subject: [PATCH 6/8] Updated tests based on review comments. --- tests/alt-registry.rs | 3 ++- tests/login.rs | 21 --------------------- tests/publish.rs | 0 3 files changed, 2 insertions(+), 22 deletions(-) mode change 100755 => 100644 tests/alt-registry.rs mode change 100755 => 100644 tests/login.rs mode change 100755 => 100644 tests/publish.rs diff --git a/tests/alt-registry.rs b/tests/alt-registry.rs old mode 100755 new mode 100644 index c7b937d8915..3614d514046 --- a/tests/alt-registry.rs +++ b/tests/alt-registry.rs @@ -280,7 +280,8 @@ fn block_publish_due_to_no_token() { // Now perform the actual publish assert_that(p.cargo("publish").masquerade_as_nightly_cargo() .arg("--registry").arg("alternative").arg("-Zunstable-options"), - execs().with_status(101)); + execs().with_status(101) + .with_stderr_contains("error: no upload token found, please run `cargo login`")); } #[test] diff --git a/tests/login.rs b/tests/login.rs old mode 100755 new mode 100644 index 9aa35640896..ee26411cfae --- a/tests/login.rs +++ b/tests/login.rs @@ -23,9 +23,6 @@ const CONFIG_FILE: &str = r#" [registries.test-reg] index = "http://dummy_index/" - - [registries.test.reg] - index = "http://dummy_index/" "#; fn setup_old_credentials() { @@ -167,21 +164,3 @@ fn registry_credentials() { // Also ensure that we get the new token for the registry assert!(check_token(TOKEN, Some(reg))); } - -#[test] -fn registry_credentials_with_dots() { - setup_old_credentials(); - setup_new_credentials(); - - let reg = "test.reg"; - - assert_that(cargo_process().arg("login").masquerade_as_nightly_cargo() - .arg("--registry").arg(reg).arg(TOKEN).arg("-Zunstable-options"), - execs().with_status(0)); - - // Ensure that we have not updated the default token - assert!(check_token(ORIGINAL_TOKEN, None)); - - // Also ensure that we get the new token for the registry - assert!(check_token(TOKEN, Some(reg))); -} diff --git a/tests/publish.rs b/tests/publish.rs old mode 100755 new mode 100644 From 276e9026b5df7f002ea6727e96bf5da2813be537 Mon Sep 17 00:00:00 2001 From: Chris Swindle Date: Tue, 31 Oct 2017 16:39:56 +0000 Subject: [PATCH 7/8] Sort out remaining file permissions. --- src/bin/login.rs | 0 src/cargo/ops/registry.rs | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 src/bin/login.rs mode change 100755 => 100644 src/cargo/ops/registry.rs diff --git a/src/bin/login.rs b/src/bin/login.rs old mode 100755 new mode 100644 diff --git a/src/cargo/ops/registry.rs b/src/cargo/ops/registry.rs old mode 100755 new mode 100644 From 4ef8f55bac65162d1886790883e7a7252cd56ed3 Mon Sep 17 00:00:00 2001 From: Chris Swindle Date: Tue, 31 Oct 2017 22:11:02 +0000 Subject: [PATCH 8/8] Add verification that an crate has been published to the correct location. --- tests/alt-registry.rs | 5 ++++- tests/cargotest/support/registry.rs | 9 ++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/tests/alt-registry.rs b/tests/alt-registry.rs index 3614d514046..42770296ea0 100644 --- a/tests/alt-registry.rs +++ b/tests/alt-registry.rs @@ -2,7 +2,7 @@ extern crate cargotest; extern crate hamcrest; use cargotest::ChannelChanger; -use cargotest::support::registry::{self, Package}; +use cargotest::support::registry::{self, Package, alt_dl_path}; use cargotest::support::{project, execs}; use hamcrest::assert_that; @@ -308,4 +308,7 @@ fn publish_to_alt_registry() { assert_that(p.cargo("publish").masquerade_as_nightly_cargo() .arg("--registry").arg("alternative").arg("-Zunstable-options"), execs().with_status(0)); + + // Ensure that the crate is uploaded + assert!(alt_dl_path().join("api/v1/crates/new").exists()); } diff --git a/tests/cargotest/support/registry.rs b/tests/cargotest/support/registry.rs index 16b41f8e16c..010552607e5 100644 --- a/tests/cargotest/support/registry.rs +++ b/tests/cargotest/support/registry.rs @@ -20,6 +20,8 @@ pub fn dl_path() -> PathBuf { paths::root().join("dl") } pub fn dl_url() -> Url { Url::from_file_path(&*dl_path()).ok().unwrap() } pub fn alt_registry_path() -> PathBuf { paths::root().join("alternative-registry") } pub fn alt_registry() -> Url { Url::from_file_path(&*alt_registry_path()).ok().unwrap() } +pub fn alt_dl_path() -> PathBuf { paths::root().join("alt_dl") } +pub fn alt_dl_url() -> Url { Url::from_file_path(&*alt_dl_path()).ok().unwrap() } pub struct Package { name: String, @@ -75,9 +77,9 @@ pub fn init() { repo(&alt_registry_path()) .file("config.json", &format!(r#" {{"dl":"{0}","api":"{0}"}} - "#, dl_url())) + "#, alt_dl_url())) .build(); - fs::create_dir_all(dl_path().join("api/v1/crates")).unwrap(); + fs::create_dir_all(alt_dl_path().join("api/v1/crates")).unwrap(); } impl Package { @@ -299,7 +301,8 @@ impl Package { registry_path().join(format!("{}-{}.crate", self.name, self.vers)) } else { - dl_path().join(&self.name).join(&self.vers).join("download") + let dl_path = if self.alternative { alt_dl_path() } else { dl_path() }; + dl_path.join(&self.name).join(&self.vers).join("download") } } }