Skip to content

Commit

Permalink
refactor: move info into registry mod
Browse files Browse the repository at this point in the history
  • Loading branch information
Rustin170506 committed Jul 3, 2024
1 parent 476969f commit 55db322
Show file tree
Hide file tree
Showing 11 changed files with 87 additions and 183 deletions.
2 changes: 1 addition & 1 deletion src/bin/cargo/commands/info.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use cargo::ops::cargo_info::info;
use cargo::ops::info;
use cargo::util::command_prelude::*;
use cargo_util_schemas::core::PackageIdSpec;

Expand Down
2 changes: 1 addition & 1 deletion src/cargo/ops/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pub use self::cargo_update::write_manifest_upgrades;
pub use self::cargo_update::UpdateOptions;
pub use self::fix::{fix, fix_exec_rustc, fix_get_proxy_lock_addr, FixOptions};
pub use self::lockfile::{load_pkg_lockfile, resolve_to_string, write_pkg_lockfile};
pub use self::registry::info;
pub use self::registry::modify_owners;
pub use self::registry::publish;
pub use self::registry::registry_login;
Expand All @@ -46,7 +47,6 @@ pub(crate) mod cargo_compile;
pub mod cargo_config;
mod cargo_doc;
mod cargo_fetch;
pub mod cargo_info;
mod cargo_install;
mod cargo_new;
mod cargo_output_metadata;
Expand Down
180 changes: 21 additions & 159 deletions src/cargo/ops/cargo_info/mod.rs → src/cargo/ops/registry/info/mod.rs
Original file line number Diff line number Diff line change
@@ -1,39 +1,34 @@
mod view;

use std::collections::HashSet;
use std::task::Poll;
use anyhow::bail;

use anyhow::{bail, Context};
use cargo_credential::Operation;
use cargo_util_schemas::core::{PackageIdSpec, PartialVersion};
use crates_io::Registry as CratesIoRegistry;
use crates_io::User;

use crate::core::registry::PackageRegistry;
use crate::core::{
Dependency, Package, PackageId, PackageIdSpecQuery, Registry, SourceId, Workspace,
};
use crate::ops::cargo_info::view::pretty_view;
use crate::ops::registry::RegistryOrIndex;
use crate::core::{Dependency, Package, PackageId, PackageIdSpecQuery, Registry, Workspace};
use crate::ops::registry::info::view::pretty_view;
use crate::ops::registry::{RegistryOrIndex, RegistrySourceIds};
use crate::ops::resolve_ws;
use crate::sources::source::{QueryKind, Source};
use crate::sources::{IndexSummary, RegistrySource, SourceConfigMap};
use crate::util::auth::{auth_token, AuthorizationErrorReason};
use crate::sources::source::QueryKind;
use crate::sources::{IndexSummary, SourceConfigMap};
use crate::util::cache_lock::CacheLockMode;
use crate::util::command_prelude::root_manifest;
use crate::util::network::http::http_handle;
use crate::{CargoResult, GlobalContext};

use super::registry;

mod view;

pub fn info(
spec: &PackageIdSpec,
gctx: &GlobalContext,
reg_or_index: Option<RegistryOrIndex>,
) -> CargoResult<()> {
let source_config = SourceConfigMap::new(gctx)?;
let mut registry = PackageRegistry::new_with_source_config(gctx, source_config)?;
let mut reg = PackageRegistry::new_with_source_config(gctx, source_config)?;
// Make sure we get the lock before we download anything.
let _lock = gctx.acquire_package_cache_lock(CacheLockMode::DownloadExclusive)?;
registry.lock_patches();
reg.lock_patches();

// If we can find it in workspace, use it as a specific version.
let nearest_manifest_path = root_manifest(None, gctx).ok();
Expand All @@ -46,7 +41,8 @@ pub fn info(
.and_then(|path| ws.members().find(|p| p.manifest_path() == path))
});
let (mut package_id, is_member) = find_pkgid_in_ws(nearest_package, ws.as_ref(), spec);
let (use_package_source_id, source_ids) = get_source_id(gctx, reg_or_index, package_id)?;
let (mut api_registry, use_package_source_id, source_ids) =
registry(gctx, package_id, None, reg_or_index.as_ref(), false, None)?;
// If we don't use the package's source, we need to query the package ID from the specified registry.
if !use_package_source_id {
package_id = None;
Expand Down Expand Up @@ -76,15 +72,15 @@ pub fn info(
// For workspace members, `cargo tree --package <SPEC> --invert` is useless. It only prints itself.
let suggest_cargo_tree_command = package_id.is_some() && !is_member;

let summaries = query_summaries(spec, &mut registry, &source_ids)?;
let summaries = query_summaries(spec, &mut reg, &source_ids)?;
let package_id = match package_id {
Some(id) => id,
None => find_pkgid_in_summaries(&summaries, spec, &rustc_version, &source_ids)?,
};

let package = registry.get(&[package_id])?;
let package = reg.get(&[package_id])?;
let package = package.get_one(package_id)?;
let owners = try_list_owners(gctx, source_ids, package_id.name().as_str())?;
let owners = try_list_owners(&mut api_registry, source_ids, package_id.name().as_str())?;
pretty_view(
package,
&summaries,
Expand Down Expand Up @@ -209,23 +205,17 @@ fn query_summaries(

// Try to list the login and name of all owners of a crate.
fn try_list_owners(
gctx: &GlobalContext,
api_registry: &mut CratesIoRegistry,
source_ids: RegistrySourceIds,
package_name: &str,
) -> CargoResult<Option<Vec<String>>> {
// Only remote registries support listing owners.
if !source_ids.original.is_remote_registry() {
return Ok(None);
}
let registry = api_registry(gctx, source_ids)?;
match registry {
Some(mut registry) => {
let owners = registry.list_owners(package_name)?;
let names = owners.iter().map(get_username).collect();
Ok(Some(names))
}
None => Ok(None),
}
let owners = api_registry.list_owners(package_name)?;
let names = owners.iter().map(get_username).collect();
Ok(Some(names))
}

fn get_username(u: &User) -> String {
Expand All @@ -239,134 +229,6 @@ fn get_username(u: &User) -> String {
)
}

struct RegistrySourceIds {
/// Use when looking up the auth token, or writing out `Cargo.lock`
original: SourceId,
/// Use when interacting with the source (querying / publishing , etc)
///
/// The source for crates.io may be replaced by a built-in source for accessing crates.io with
/// the sparse protocol, or a source for the testing framework (when the replace_crates_io
/// function is used)
///
/// User-defined source replacement is not applied.
/// Note: This will be utilized when interfacing with the registry API.
replacement: SourceId,
}

fn get_source_id(
gctx: &GlobalContext,
reg_or_index: Option<RegistryOrIndex>,
package_id: Option<PackageId>,
) -> CargoResult<(bool, RegistrySourceIds)> {
let (use_package_source_id, sid) = match (&reg_or_index, package_id) {
(None, Some(package_id)) => (true, package_id.source_id()),
(None, None) => (false, SourceId::crates_io(gctx)?),
(Some(RegistryOrIndex::Index(url)), None) => (false, SourceId::for_registry(url)?),
(Some(RegistryOrIndex::Registry(r)), None) => (false, SourceId::alt_registry(gctx, r)?),
(Some(reg_or_index), Some(package_id)) => {
let sid = match reg_or_index {
RegistryOrIndex::Index(url) => SourceId::for_registry(url)?,
RegistryOrIndex::Registry(r) => SourceId::alt_registry(gctx, r)?,
};
let package_source_id = package_id.source_id();
// Same registry, use the package's source.
if sid == package_source_id {
(true, sid)
} else {
let pkg_source_replacement_sid = SourceConfigMap::new(gctx)?
.load(package_source_id, &HashSet::new())?
.replaced_source_id();
// Use the package's source if the specified registry is a replacement for the package's source.
if pkg_source_replacement_sid == sid {
(true, package_source_id)
} else {
(false, sid)
}
}
}
};
// Load source replacements that are built-in to Cargo.
let builtin_replacement_sid = SourceConfigMap::empty(gctx)?
.load(sid, &HashSet::new())?
.replaced_source_id();
let replacement_sid = SourceConfigMap::new(gctx)?
.load(sid, &HashSet::new())?
.replaced_source_id();
// Check if the user has configured source-replacement for the registry we are querying.
if reg_or_index.is_none() && replacement_sid != builtin_replacement_sid {
// Neither --registry nor --index was passed and the user has configured source-replacement.
if let Some(replacement_name) = replacement_sid.alt_registry_key() {
bail!("crates-io is replaced with remote registry {replacement_name};\ninclude `--registry {replacement_name}` or `--registry crates-io`");
} else {
bail!("crates-io is replaced with non-remote-registry source {replacement_sid};\ninclude `--registry crates-io` to use crates.io");
}
} else {
Ok((
use_package_source_id,
RegistrySourceIds {
original: sid,
replacement: builtin_replacement_sid,
},
))
}
}

// Try to get the crates.io registry which is used to access the registry API.
// If the user is not logged in, the function will return None.
fn api_registry(
gctx: &GlobalContext,
source_ids: RegistrySourceIds,
) -> CargoResult<Option<CratesIoRegistry>> {
let cfg = {
let mut src = RegistrySource::remote(source_ids.replacement, &HashSet::new(), gctx)?;
let cfg = loop {
match src.config()? {
Poll::Pending => src
.block_until_ready()
.with_context(|| format!("failed to update {}", source_ids.replacement))?,
Poll::Ready(cfg) => break cfg,
}
};
cfg.expect("remote registries must have config")
};
// This should only happen if the user has a custom registry configured.
// Some registries may not have API support.
let api_host = match cfg.api {
Some(api_host) => api_host,
None => return Ok(None),
};
let token = match auth_token(
gctx,
&source_ids.original,
None,
Operation::Read,
vec![],
false,
) {
Ok(token) => Some(token),
Err(err) => {
// If the token is missing, it means the user is not logged in.
// We don't want to show an error in this case.
if err.to_string().contains(
(AuthorizationErrorReason::TokenMissing)
.to_string()
.as_str(),
) {
return Ok(None);
}
return Err(err);
}
};

let handle = http_handle(gctx)?;
Ok(Some(CratesIoRegistry::new_handle(
api_host,
token,
handle,
cfg.auth_required,
)))
}

fn validate_locked_and_frozen_options(
package_id: Option<PackageId>,
gctx: &GlobalContext,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ fn pretty_source(source: SourceId, ctx: &GlobalContext) -> String {
.local_path()
.and_then(|path| pathdiff::diff_paths(path, ctx.cwd()))
{
let path = std::path::Path::new(".").join(relpath);
let path = std::path::Path::new("../../../../..").join(relpath);
path.display().to_string()
} else {
source.to_string()
Expand Down
13 changes: 10 additions & 3 deletions src/cargo/ops/registry/login.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,17 @@ pub fn registry_login(
reg_or_index: Option<&RegistryOrIndex>,
args: &[&str],
) -> CargoResult<()> {
let source_ids = get_source_id(gctx, reg_or_index)?;
let (_, source_ids) = get_source_id(gctx, None, reg_or_index)?;

let login_url = match registry(gctx, token_from_cmdline.clone(), reg_or_index, false, None) {
Ok((registry, _)) => Some(format!("{}/me", registry.host())),
let login_url = match registry(
gctx,
None,
token_from_cmdline.clone(),
reg_or_index,
false,
None,
) {
Ok((registry, _, _)) => Some(format!("{}/me", registry.host())),
Err(e) if e.is::<AuthorizationError>() => e
.downcast::<AuthorizationError>()
.unwrap()
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/ops/registry/logout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub fn registry_logout(
gctx: &GlobalContext,
reg_or_index: Option<RegistryOrIndex>,
) -> CargoResult<()> {
let source_ids = get_source_id(gctx, reg_or_index.as_ref())?;
let (_, source_ids) = get_source_id(gctx, None, reg_or_index.as_ref())?;
auth::logout(gctx, &source_ids.original)?;
Ok(())
}
Loading

0 comments on commit 55db322

Please sign in to comment.