-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Support login tokens for multiple registries #4680
Changes from 3 commits
002996e
e911a25
053b9f9
0f82507
0bda323
31cb68d
3c7a3cb
276e902
4ef8f55
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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, ConfigValue}; | ||
use util::paths; | ||
use util::ToUrl; | ||
use util::errors::{CargoError, CargoResult, CargoResultExt}; | ||
|
@@ -36,6 +36,7 @@ pub struct PublishOpts<'cfg> { | |
pub jobs: Option<u32>, | ||
pub target: Option<&'cfg str>, | ||
pub dry_run: bool, | ||
pub registry: Option<String>, | ||
} | ||
|
||
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 | ||
|
@@ -189,24 +191,48 @@ fn transmit(config: &Config, | |
} | ||
} | ||
|
||
pub fn registry_configuration(config: &Config) -> CargoResult<RegistryConfig> { | ||
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, | ||
registry: Option<String>) -> CargoResult<RegistryConfig> { | ||
|
||
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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could this use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I did originally try using get_string, but that caused problems if there was a '.' in the registry name (which I think is allowed). I will have a play and see if I can get something working. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Turns out it does just work switching to get_string, so I have made the change. |
||
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")?.map(|p| p.val), | ||
config.get_string("registry.token")?.map(|p| p.val)) | ||
} | ||
}; | ||
|
||
Ok(RegistryConfig { | ||
index: index, | ||
token: token | ||
}) | ||
} | ||
|
||
pub fn registry(config: &Config, | ||
token: Option<String>, | ||
index: Option<String>) -> CargoResult<(Registry, SourceId)> { | ||
index: Option<String>, | ||
registry: Option<String>) -> CargoResult<(Registry, SourceId)> { | ||
// Parse all configuration options | ||
let RegistryConfig { | ||
token: token_config, | ||
index: _index_config, | ||
} = registry_configuration(config)?; | ||
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); | ||
|
@@ -293,15 +319,21 @@ pub fn http_timeout(config: &Config) -> CargoResult<Option<i64>> { | |
Ok(env::var("HTTP_TIMEOUT").ok().and_then(|s| s.parse().ok())) | ||
} | ||
|
||
pub fn registry_login(config: &Config, token: String) -> CargoResult<()> { | ||
let RegistryConfig { token: old_token, .. } = registry_configuration(config)?; | ||
pub fn registry_login(config: &Config, | ||
token: String, | ||
registry: Option<String>) -> CargoResult<()> { | ||
let RegistryConfig { | ||
token: old_token, | ||
.. | ||
} = registry_configuration(config, registry.clone())?; | ||
|
||
if let Some(old_token) = old_token { | ||
if old_token == token { | ||
return Ok(()); | ||
} | ||
} | ||
|
||
config::save_credentials(config, token) | ||
config::save_credentials(config, token, registry) | ||
} | ||
|
||
pub struct OwnersOptions { | ||
|
@@ -311,6 +343,7 @@ pub struct OwnersOptions { | |
pub to_add: Option<Vec<String>>, | ||
pub to_remove: Option<Vec<String>>, | ||
pub list: bool, | ||
pub registry: Option<String>, | ||
} | ||
|
||
pub fn modify_owners(config: &Config, opts: &OwnersOptions) -> CargoResult<()> { | ||
|
@@ -323,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::<Vec<_>>(); | ||
|
@@ -367,7 +402,8 @@ pub fn yank(config: &Config, | |
version: Option<String>, | ||
token: Option<String>, | ||
index: Option<String>, | ||
undo: bool) -> CargoResult<()> { | ||
undo: bool, | ||
reg: Option<String>) -> CargoResult<()> { | ||
let name = match krate { | ||
Some(name) => name, | ||
None => { | ||
|
@@ -381,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))?; | ||
|
@@ -401,7 +437,8 @@ pub fn yank(config: &Config, | |
pub fn search(query: &str, | ||
config: &Config, | ||
index: Option<String>, | ||
limit: u8) -> CargoResult<()> { | ||
limit: u8, | ||
reg: Option<String>) -> CargoResult<()> { | ||
fn truncate_with_ellipsis(s: &str, max_length: usize) -> String { | ||
if s.len() < max_length { | ||
s.to_string() | ||
|
@@ -410,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)) | ||
})?; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm I think this should only get printed for the crates.io registry, right? We may not want to assume the layout of another registry per se just yet, and instead we could probably just return an error if no token was passed and
--registry
was passed?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wondering if the /me API should be required for publish, I am happy to switch to just return an error stating that the token should be provided.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah this is one where we haven't done much to sketch out the path towards "what does a custom registry need HTTP-wise", so I think it's ok to err on the side of caution for now and just return an error