From b6c4e47cc090ac6e349f3ba1c8de6af0b8130252 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 18 Aug 2023 23:45:25 +0100 Subject: [PATCH 1/2] refactor: put `Source` trait under `cargo::sources` --- crates/resolver-tests/src/lib.rs | 3 +- crates/xtask-bump-check/src/xtask.rs | 2 +- src/cargo/core/compiler/future_incompat.rs | 3 +- src/cargo/core/mod.rs | 2 +- src/cargo/core/package.rs | 4 +- src/cargo/core/registry.rs | 5 +- src/cargo/core/resolver/dep_cache.rs | 5 +- src/cargo/core/resolver/errors.rs | 3 +- src/cargo/core/source/mod.rs | 409 ------------------ src/cargo/core/source/source_id.rs | 7 +- src/cargo/lib.rs | 4 +- src/cargo/ops/cargo_add/mod.rs | 2 +- src/cargo/ops/cargo_install.rs | 3 +- .../ops/common_for_install_and_uninstall.rs | 4 +- src/cargo/ops/registry/mod.rs | 2 +- src/cargo/ops/registry/publish.rs | 2 +- src/cargo/ops/resolve.rs | 4 +- src/cargo/sources/config.rs | 3 +- src/cargo/sources/directory.rs | 6 +- src/cargo/sources/git/source.rs | 5 +- src/cargo/sources/mod.rs | 14 +- src/cargo/sources/path.rs | 6 +- src/cargo/sources/registry/mod.rs | 6 +- src/cargo/sources/replaced.rs | 6 +- src/cargo/sources/source.rs | 396 +++++++++++++++++ tests/testsuite/search.rs | 3 +- 26 files changed, 463 insertions(+), 446 deletions(-) create mode 100644 src/cargo/sources/source.rs diff --git a/crates/resolver-tests/src/lib.rs b/crates/resolver-tests/src/lib.rs index baab24371cb..aaf7fa0617e 100644 --- a/crates/resolver-tests/src/lib.rs +++ b/crates/resolver-tests/src/lib.rs @@ -13,9 +13,10 @@ use std::time::Instant; use cargo::core::dependency::DepKind; use cargo::core::resolver::{self, ResolveOpts, VersionPreferences}; -use cargo::core::source::{GitReference, QueryKind, SourceId}; +use cargo::core::source::{GitReference, SourceId}; use cargo::core::Resolve; use cargo::core::{Dependency, PackageId, Registry, Summary}; +use cargo::sources::source::QueryKind; use cargo::util::{CargoResult, Config, Graph, IntoUrl, PartialVersion}; use proptest::collection::{btree_map, vec}; diff --git a/crates/xtask-bump-check/src/xtask.rs b/crates/xtask-bump-check/src/xtask.rs index f891523315d..c50d51efdc3 100644 --- a/crates/xtask-bump-check/src/xtask.rs +++ b/crates/xtask-bump-check/src/xtask.rs @@ -18,10 +18,10 @@ use std::task; use cargo::core::dependency::Dependency; use cargo::core::registry::PackageRegistry; use cargo::core::Package; -use cargo::core::QueryKind; use cargo::core::Registry; use cargo::core::SourceId; use cargo::core::Workspace; +use cargo::sources::source::QueryKind; use cargo::util::command_prelude::*; use cargo::util::ToSemver; use cargo::CargoResult; diff --git a/src/cargo/core/compiler/future_incompat.rs b/src/cargo/core/compiler/future_incompat.rs index ccea28b9416..c1868d92abf 100644 --- a/src/cargo/core/compiler/future_incompat.rs +++ b/src/cargo/core/compiler/future_incompat.rs @@ -34,7 +34,8 @@ //! [2]: https://github.com/rust-lang/rust/blob/9bb6e60d1f1360234aae90c97964c0fa5524f141/compiler/rustc_errors/src/json.rs#L312-L315 use crate::core::compiler::BuildContext; -use crate::core::{Dependency, PackageId, QueryKind, Workspace}; +use crate::core::{Dependency, PackageId, Workspace}; +use crate::sources::source::QueryKind; use crate::sources::SourceConfigMap; use crate::util::{iter_join, CargoResult, Config}; use anyhow::{bail, format_err, Context}; diff --git a/src/cargo/core/mod.rs b/src/cargo/core/mod.rs index e36c678c4cb..b8a27604f9f 100644 --- a/src/cargo/core/mod.rs +++ b/src/cargo/core/mod.rs @@ -8,7 +8,7 @@ pub use self::package_id_spec::PackageIdSpec; pub use self::registry::Registry; pub use self::resolver::{Resolve, ResolveVersion}; pub use self::shell::{Shell, Verbosity}; -pub use self::source::{GitReference, QueryKind, Source, SourceId, SourceMap}; +pub use self::source::{GitReference, SourceId}; pub use self::summary::{FeatureMap, FeatureValue, Summary}; pub use self::workspace::{ find_workspace_root, resolve_relative_path, MaybePackage, Workspace, WorkspaceConfig, diff --git a/src/cargo/core/package.rs b/src/cargo/core/package.rs index aa673e937ce..a4a0eaa3470 100644 --- a/src/cargo/core/package.rs +++ b/src/cargo/core/package.rs @@ -21,9 +21,9 @@ use crate::core::compiler::{CompileKind, RustcTargetData}; use crate::core::dependency::DepKind; use crate::core::resolver::features::ForceAllTargets; use crate::core::resolver::{HasDevUnits, Resolve}; -use crate::core::source::MaybePackage; use crate::core::{Dependency, Manifest, PackageId, SourceId, Target}; -use crate::core::{SourceMap, Summary, Workspace}; +use crate::core::{Summary, Workspace}; +use crate::sources::source::{MaybePackage, SourceMap}; use crate::util::config::PackageCacheLock; use crate::util::errors::{CargoResult, HttpNotSuccessful}; use crate::util::interning::InternedString; diff --git a/src/cargo/core/registry.rs b/src/cargo/core/registry.rs index da3d612d047..2bb19fc6f23 100644 --- a/src/cargo/core/registry.rs +++ b/src/cargo/core/registry.rs @@ -2,8 +2,11 @@ use std::collections::{HashMap, HashSet}; use std::task::{ready, Poll}; use crate::core::PackageSet; -use crate::core::{Dependency, PackageId, QueryKind, Source, SourceId, SourceMap, Summary}; +use crate::core::{Dependency, PackageId, SourceId, Summary}; use crate::sources::config::SourceConfigMap; +use crate::sources::source::QueryKind; +use crate::sources::source::Source; +use crate::sources::source::SourceMap; use crate::util::errors::CargoResult; use crate::util::interning::InternedString; use crate::util::{CanonicalUrl, Config}; diff --git a/src/cargo/core/resolver/dep_cache.rs b/src/cargo/core/resolver/dep_cache.rs index 72757e40911..8c9fcebb475 100644 --- a/src/cargo/core/resolver/dep_cache.rs +++ b/src/cargo/core/resolver/dep_cache.rs @@ -16,9 +16,8 @@ use crate::core::resolver::{ ActivateError, ActivateResult, CliFeatures, RequestedFeatures, ResolveOpts, VersionOrdering, VersionPreferences, }; -use crate::core::{ - Dependency, FeatureValue, PackageId, PackageIdSpec, QueryKind, Registry, Summary, -}; +use crate::core::{Dependency, FeatureValue, PackageId, PackageIdSpec, Registry, Summary}; +use crate::sources::source::QueryKind; use crate::util::errors::CargoResult; use crate::util::interning::InternedString; use crate::util::PartialVersion; diff --git a/src/cargo/core/resolver/errors.rs b/src/cargo/core/resolver/errors.rs index ca5c833f4bc..3353468323e 100644 --- a/src/cargo/core/resolver/errors.rs +++ b/src/cargo/core/resolver/errors.rs @@ -1,7 +1,8 @@ use std::fmt; use std::task::Poll; -use crate::core::{Dependency, PackageId, QueryKind, Registry, Summary}; +use crate::core::{Dependency, PackageId, Registry, Summary}; +use crate::sources::source::QueryKind; use crate::util::edit_distance::edit_distance; use crate::util::{Config, VersionExt}; use anyhow::Error; diff --git a/src/cargo/core/source/mod.rs b/src/cargo/core/source/mod.rs index 2d1db1d5366..3a2f6f6015b 100644 --- a/src/cargo/core/source/mod.rs +++ b/src/cargo/core/source/mod.rs @@ -1,412 +1,3 @@ -//! Fundamental types and traits for sources of Cargo packages. -//! -//! A source is a provider that contains source files and metadata of packages. -//! It provides a number of methods to fetch those package informations, for -//! example, querying metadata or downloading files for a package. These -//! informations then can be used as dependencies for other Cargo packages. -//! -//! Notably, this module contains -//! -//! * [`Source`] trait as an abstraction of different sources -//! * [`SourceMap`] struct as a map of all available sources -//! * [`SourceId`] struct as an unique identifier for a certain source -//! -//! For implementations of `Source` trait, see [`crate::sources`]. - -use std::collections::hash_map::HashMap; -use std::fmt; -use std::task::Poll; - -use crate::core::package::PackageSet; -use crate::core::{Dependency, Package, PackageId, Summary}; -use crate::util::{CargoResult, Config}; - mod source_id; pub use self::source_id::{GitReference, SourceId}; - -/// An abstraction of different sources of Cargo packages. -/// -/// The [`Source`] trait generalizes the API to interact with these providers. -/// For example, -/// -/// * [`Source::query`] is for querying package metadata on a given -/// [`Dependency`] requested by a Cargo manifest. -/// * [`Source::download`] is for fetching the full package information on -/// given names and versions. -/// * [`Source::source_id`] is for defining an unique identifier of a source to -/// distinguish one source from another, keeping Cargo safe from [dependency -/// confusion attack]. -/// -/// Normally, developers don't need to implement their own [`Source`]s. Cargo -/// provides several kinds of sources implementations that should cover almost -/// all use cases. See [`crate::sources`] for implementations provided by Cargo. -/// -/// [dependency confusion attack]: https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610 -pub trait Source { - /// Returns the [`SourceId`] corresponding to this source. - fn source_id(&self) -> SourceId; - - /// Returns the replaced [`SourceId`] corresponding to this source. - fn replaced_source_id(&self) -> SourceId { - self.source_id() - } - - /// Returns whether or not this source will return [`Summary`] items with - /// checksums listed. - fn supports_checksums(&self) -> bool; - - /// Returns whether or not this source will return [`Summary`] items with - /// the `precise` field in the [`SourceId`] listed. - fn requires_precise(&self) -> bool; - - /// Attempts to find the packages that match a dependency request. - /// - /// Usually you should call [`Source::block_until_ready`] somewhere and - /// wait until package informations become available. Otherwise any query - /// may return a [`Poll::Pending`]. - /// - /// The `f` argument is expected to get called when any [`Summary`] becomes available. - fn query( - &mut self, - dep: &Dependency, - kind: QueryKind, - f: &mut dyn FnMut(Summary), - ) -> Poll>; - - /// Gathers the result from [`Source::query`] as a list of [`Summary`] items - /// when they become available. - fn query_vec(&mut self, dep: &Dependency, kind: QueryKind) -> Poll>> { - let mut ret = Vec::new(); - self.query(dep, kind, &mut |s| ret.push(s)).map_ok(|_| ret) - } - - /// Ensure that the source is fully up-to-date for the current session on the next query. - fn invalidate_cache(&mut self); - - /// If quiet, the source should not display any progress or status messages. - fn set_quiet(&mut self, quiet: bool); - - /// Starts the process to fetch a [`Package`] for the given [`PackageId`]. - /// - /// If the source already has the package available on disk, then it - /// should return immediately with [`MaybePackage::Ready`] with the - /// [`Package`]. Otherwise it should return a [`MaybePackage::Download`] - /// to indicate the URL to download the package (this is for remote - /// registry sources only). - /// - /// In the case where [`MaybePackage::Download`] is returned, then the - /// package downloader will call [`Source::finish_download`] after the - /// download has finished. - fn download(&mut self, package: PackageId) -> CargoResult; - - /// Convenience method used to **immediately** fetch a [`Package`] for the - /// given [`PackageId`]. - /// - /// This may trigger a download if necessary. This should only be used - /// when a single package is needed (as in the case for `cargo install`). - /// Otherwise downloads should be batched together via [`PackageSet`]. - fn download_now(self: Box, package: PackageId, config: &Config) -> CargoResult - where - Self: std::marker::Sized, - { - let mut sources = SourceMap::new(); - sources.insert(self); - let pkg_set = PackageSet::new(&[package], sources, config)?; - let pkg = pkg_set.get_one(package)?; - Ok(Package::clone(pkg)) - } - - /// Gives the source the downloaded `.crate` file. - /// - /// When a source has returned [`MaybePackage::Download`] in the - /// [`Source::download`] method, then this function will be called with - /// the results of the download of the given URL. The source is - /// responsible for saving to disk, and returning the appropriate - /// [`Package`]. - fn finish_download(&mut self, pkg_id: PackageId, contents: Vec) -> CargoResult; - - /// Generates a unique string which represents the fingerprint of the - /// current state of the source. - /// - /// This fingerprint is used to determine the "freshness" of the source - /// later on. It must be guaranteed that the fingerprint of a source is - /// constant if and only if the output product will remain constant. - /// - /// The `pkg` argument is the package which this fingerprint should only be - /// interested in for when this source may contain multiple packages. - fn fingerprint(&self, pkg: &Package) -> CargoResult; - - /// If this source supports it, verifies the source of the package - /// specified. - /// - /// Note that the source may also have performed other checksum-based - /// verification during the `download` step, but this is intended to be run - /// just before a crate is compiled so it may perform more expensive checks - /// which may not be cacheable. - fn verify(&self, _pkg: PackageId) -> CargoResult<()> { - Ok(()) - } - - /// Describes this source in a human readable fashion, used for display in - /// resolver error messages currently. - fn describe(&self) -> String; - - /// Returns whether a source is being replaced by another here. - fn is_replaced(&self) -> bool { - false - } - - /// Add a number of crates that should be whitelisted for showing up during - /// queries, even if they are yanked. Currently only applies to registry - /// sources. - fn add_to_yanked_whitelist(&mut self, pkgs: &[PackageId]); - - /// Query if a package is yanked. Only registry sources can mark packages - /// as yanked. This ignores the yanked whitelist. - fn is_yanked(&mut self, _pkg: PackageId) -> Poll>; - - /// Block until all outstanding [`Poll::Pending`] requests are [`Poll::Ready`]. - /// - /// After calling this function, the source should return `Poll::Ready` for - /// any queries that previously returned `Poll::Pending`. - /// - /// If no queries previously returned `Poll::Pending`, and [`Source::invalidate_cache`] - /// was not called, this function should be a no-op. - fn block_until_ready(&mut self) -> CargoResult<()>; -} - -/// Defines how a dependency query will be performed for a [`Source`]. -#[derive(Copy, Clone, PartialEq, Eq)] -pub enum QueryKind { - /// A query for packages exactly matching the given dependency requirement. - /// - /// Each source gets to define what `exact` means for it. - Exact, - /// A query for packages close to the given dependency requirement. - /// - /// Each source gets to define what `close` means for it. - /// - /// Path/Git sources may return all dependencies that are at that URI, - /// whereas an `Registry` source may return dependencies that have the same - /// canonicalization. - Fuzzy, -} - -/// A download status that represents if a [`Package`] has already been -/// downloaded, or if not then a location to download. -pub enum MaybePackage { - /// The [`Package`] is already downloaded. - Ready(Package), - /// Not yet downloaded. Here is the URL to download the [`Package`] from. - Download { - /// URL to download the content. - url: String, - /// Text to display to the user of what is being downloaded. - descriptor: String, - /// Authorization data that may be required to attach when downloading. - authorization: Option, - }, -} - -/// A blanket implementation forwards all methods to [`Source`]. -impl<'a, T: Source + ?Sized + 'a> Source for Box { - fn source_id(&self) -> SourceId { - (**self).source_id() - } - - fn replaced_source_id(&self) -> SourceId { - (**self).replaced_source_id() - } - - fn supports_checksums(&self) -> bool { - (**self).supports_checksums() - } - - fn requires_precise(&self) -> bool { - (**self).requires_precise() - } - - fn query( - &mut self, - dep: &Dependency, - kind: QueryKind, - f: &mut dyn FnMut(Summary), - ) -> Poll> { - (**self).query(dep, kind, f) - } - - fn invalidate_cache(&mut self) { - (**self).invalidate_cache() - } - - fn set_quiet(&mut self, quiet: bool) { - (**self).set_quiet(quiet) - } - - fn download(&mut self, id: PackageId) -> CargoResult { - (**self).download(id) - } - - fn finish_download(&mut self, id: PackageId, data: Vec) -> CargoResult { - (**self).finish_download(id, data) - } - - fn fingerprint(&self, pkg: &Package) -> CargoResult { - (**self).fingerprint(pkg) - } - - fn verify(&self, pkg: PackageId) -> CargoResult<()> { - (**self).verify(pkg) - } - - fn describe(&self) -> String { - (**self).describe() - } - - fn is_replaced(&self) -> bool { - (**self).is_replaced() - } - - fn add_to_yanked_whitelist(&mut self, pkgs: &[PackageId]) { - (**self).add_to_yanked_whitelist(pkgs); - } - - fn is_yanked(&mut self, pkg: PackageId) -> Poll> { - (**self).is_yanked(pkg) - } - - fn block_until_ready(&mut self) -> CargoResult<()> { - (**self).block_until_ready() - } -} - -/// A blanket implementation forwards all methods to [`Source`]. -impl<'a, T: Source + ?Sized + 'a> Source for &'a mut T { - fn source_id(&self) -> SourceId { - (**self).source_id() - } - - fn replaced_source_id(&self) -> SourceId { - (**self).replaced_source_id() - } - - fn supports_checksums(&self) -> bool { - (**self).supports_checksums() - } - - fn requires_precise(&self) -> bool { - (**self).requires_precise() - } - - fn query( - &mut self, - dep: &Dependency, - kind: QueryKind, - f: &mut dyn FnMut(Summary), - ) -> Poll> { - (**self).query(dep, kind, f) - } - - fn invalidate_cache(&mut self) { - (**self).invalidate_cache() - } - - fn set_quiet(&mut self, quiet: bool) { - (**self).set_quiet(quiet) - } - - fn download(&mut self, id: PackageId) -> CargoResult { - (**self).download(id) - } - - fn finish_download(&mut self, id: PackageId, data: Vec) -> CargoResult { - (**self).finish_download(id, data) - } - - fn fingerprint(&self, pkg: &Package) -> CargoResult { - (**self).fingerprint(pkg) - } - - fn verify(&self, pkg: PackageId) -> CargoResult<()> { - (**self).verify(pkg) - } - - fn describe(&self) -> String { - (**self).describe() - } - - fn is_replaced(&self) -> bool { - (**self).is_replaced() - } - - fn add_to_yanked_whitelist(&mut self, pkgs: &[PackageId]) { - (**self).add_to_yanked_whitelist(pkgs); - } - - fn is_yanked(&mut self, pkg: PackageId) -> Poll> { - (**self).is_yanked(pkg) - } - - fn block_until_ready(&mut self) -> CargoResult<()> { - (**self).block_until_ready() - } -} - -/// A [`HashMap`] of [`SourceId`] to `Box`. -#[derive(Default)] -pub struct SourceMap<'src> { - map: HashMap>, -} - -// `impl Debug` on source requires specialization, if even desirable at all. -impl<'src> fmt::Debug for SourceMap<'src> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "SourceMap ")?; - f.debug_set().entries(self.map.keys()).finish() - } -} - -impl<'src> SourceMap<'src> { - /// Creates an empty map. - pub fn new() -> SourceMap<'src> { - SourceMap { - map: HashMap::new(), - } - } - - /// Like `HashMap::get`. - pub fn get(&self, id: SourceId) -> Option<&(dyn Source + 'src)> { - self.map.get(&id).map(|s| s.as_ref()) - } - - /// Like `HashMap::get_mut`. - pub fn get_mut(&mut self, id: SourceId) -> Option<&mut (dyn Source + 'src)> { - self.map.get_mut(&id).map(|s| s.as_mut()) - } - - /// Like `HashMap::insert`, but derives the [`SourceId`] key from the [`Source`]. - pub fn insert(&mut self, source: Box) { - let id = source.source_id(); - self.map.insert(id, source); - } - - /// Like `HashMap::len`. - pub fn len(&self) -> usize { - self.map.len() - } - - /// Like `HashMap::iter_mut`. - pub fn sources_mut<'a>( - &'a mut self, - ) -> impl Iterator { - self.map.iter_mut().map(|(a, b)| (a, &mut **b)) - } - - /// Merge the given map into self. - pub fn add_source_map(&mut self, other: SourceMap<'src>) { - for (key, value) in other.map { - self.map.entry(key).or_insert(value); - } - } -} diff --git a/src/cargo/core/source/source_id.rs b/src/cargo/core/source/source_id.rs index 4c7de19148d..e050c360666 100644 --- a/src/cargo/core/source/source_id.rs +++ b/src/cargo/core/source/source_id.rs @@ -1,5 +1,6 @@ use crate::core::PackageId; use crate::sources::registry::CRATES_IO_HTTP_INDEX; +use crate::sources::source::Source; use crate::sources::{DirectorySource, CRATES_IO_DOMAIN, CRATES_IO_INDEX, CRATES_IO_REGISTRY}; use crate::sources::{GitSource, PathSource, RegistrySource}; use crate::util::{config, CanonicalUrl, CargoResult, Config, IntoUrl, ToSemver}; @@ -29,8 +30,8 @@ static SOURCE_ID_CACHE: OnceLock>> = OnceL /// `SourceId` is usually associated with an instance of [`Source`], which is /// supposed to provide a `SourceId` via [`Source::source_id`] method. /// -/// [`Source`]: super::Source -/// [`Source::source_id`]: super::Source::source_id +/// [`Source`]: crate::sources::source::Source +/// [`Source::source_id`]: crate::sources::source::Source::source_id /// [`PackageId`]: super::super::PackageId #[derive(Clone, Copy, Eq, Debug)] pub struct SourceId { @@ -395,7 +396,7 @@ impl SourceId { self, config: &'a Config, yanked_whitelist: &HashSet, - ) -> CargoResult> { + ) -> CargoResult> { trace!("loading SourceId; {}", self); match self.inner.kind { SourceKind::Git(..) => Ok(Box::new(GitSource::new(self, config)?)), diff --git a/src/cargo/lib.rs b/src/cargo/lib.rs index 9f6edf80d2a..d562667e905 100644 --- a/src/cargo/lib.rs +++ b/src/cargo/lib.rs @@ -51,8 +51,8 @@ //! - [`core::compiler::fingerprint`]: //! The `fingerprint` module contains all the code that handles detecting //! if a crate needs to be recompiled. -//! - [`core::source`]: -//! The [`core::Source`] trait is an abstraction over different sources of packages. +//! - [`sources::source`]: +//! The [`sources::source::Source`] trait is an abstraction over different sources of packages. //! Sources are uniquely identified by a [`core::SourceId`]. Sources are implemented in the [`sources`] //! directory. //! - [`util`]: diff --git a/src/cargo/ops/cargo_add/mod.rs b/src/cargo/ops/cargo_add/mod.rs index d7292f3c328..ccd249d8c13 100644 --- a/src/cargo/ops/cargo_add/mod.rs +++ b/src/cargo/ops/cargo_add/mod.rs @@ -21,11 +21,11 @@ use crate::core::dependency::DepKind; use crate::core::registry::PackageRegistry; use crate::core::FeatureValue; use crate::core::Package; -use crate::core::QueryKind; use crate::core::Registry; use crate::core::Shell; use crate::core::Summary; use crate::core::Workspace; +use crate::sources::source::QueryKind; use crate::util::toml_mut::dependency::Dependency; use crate::util::toml_mut::dependency::GitSource; use crate::util::toml_mut::dependency::MaybeWorkspace; diff --git a/src/cargo/ops/cargo_install.rs b/src/cargo/ops/cargo_install.rs index 83950b9617c..957ab43e6e6 100644 --- a/src/cargo/ops/cargo_install.rs +++ b/src/cargo/ops/cargo_install.rs @@ -5,10 +5,11 @@ use std::{env, fs}; use crate::core::compiler::{CompileKind, DefaultExecutor, Executor, UnitOutput}; use crate::core::{ - Dependency, Edition, Package, PackageId, PackageIdSpec, Source, SourceId, Target, Workspace, + Dependency, Edition, Package, PackageId, PackageIdSpec, SourceId, Target, Workspace, }; use crate::ops::{common_for_install_and_uninstall::*, FilterRule}; use crate::ops::{CompileFilter, Packages}; +use crate::sources::source::Source; use crate::sources::{GitSource, PathSource, SourceConfigMap}; use crate::util::errors::CargoResult; use crate::util::{Config, Filesystem, Rustc}; diff --git a/src/cargo/ops/common_for_install_and_uninstall.rs b/src/cargo/ops/common_for_install_and_uninstall.rs index f33847d5767..0934cbd2943 100644 --- a/src/cargo/ops/common_for_install_and_uninstall.rs +++ b/src/cargo/ops/common_for_install_and_uninstall.rs @@ -12,8 +12,10 @@ use serde::{Deserialize, Serialize}; use crate::core::compiler::{DirtyReason, Freshness}; use crate::core::Target; -use crate::core::{Dependency, FeatureValue, Package, PackageId, QueryKind, Source, SourceId}; +use crate::core::{Dependency, FeatureValue, Package, PackageId, SourceId}; use crate::ops::{self, CompileFilter, CompileOptions}; +use crate::sources::source::QueryKind; +use crate::sources::source::Source; use crate::sources::PathSource; use crate::util::errors::CargoResult; use crate::util::Config; diff --git a/src/cargo/ops/registry/mod.rs b/src/cargo/ops/registry/mod.rs index 94ef1ead271..7d4e99f6bcb 100644 --- a/src/cargo/ops/registry/mod.rs +++ b/src/cargo/ops/registry/mod.rs @@ -17,8 +17,8 @@ use anyhow::{bail, format_err, Context as _}; use cargo_credential::{Operation, Secret}; use crates_io::{self, Registry}; -use crate::core::source::Source; use crate::core::SourceId; +use crate::sources::source::Source; use crate::sources::{RegistrySource, SourceConfigMap}; use crate::util::auth; use crate::util::config::{Config, PathAndArgs}; diff --git a/src/cargo/ops/registry/publish.rs b/src/cargo/ops/registry/publish.rs index 86acb766a4d..6e43ca2dbcc 100644 --- a/src/cargo/ops/registry/publish.rs +++ b/src/cargo/ops/registry/publish.rs @@ -21,12 +21,12 @@ use crate::core::manifest::ManifestMetadata; use crate::core::resolver::CliFeatures; use crate::core::Dependency; use crate::core::Package; -use crate::core::QueryKind; use crate::core::SourceId; use crate::core::Workspace; use crate::ops; use crate::ops::PackageOpts; use crate::ops::Packages; +use crate::sources::source::QueryKind; use crate::sources::SourceConfigMap; use crate::sources::CRATES_IO_REGISTRY; use crate::util::auth; diff --git a/src/cargo/ops/resolve.rs b/src/cargo/ops/resolve.rs index 8fe60d593af..0d9f11068c6 100644 --- a/src/cargo/ops/resolve.rs +++ b/src/cargo/ops/resolve.rs @@ -49,8 +49,8 @@ //! [`Package`]: crate::core::package //! [`Target`]: crate::core::Target //! [`Manifest`]: crate::core::Manifest -//! [`Source`]: crate::core::Source -//! [`SourceMap`]: crate::core::SourceMap +//! [`Source`]: crate::sources::source::Source +//! [`SourceMap`]: crate::sources::source::SourceMap //! [`PackageRegistry`]: crate::core::registry::PackageRegistry //! [source implementations]: crate::sources //! [`Downloads`]: crate::core::package::Downloads diff --git a/src/cargo/sources/config.rs b/src/cargo/sources/config.rs index c51c1f00968..ebe43906219 100644 --- a/src/cargo/sources/config.rs +++ b/src/cargo/sources/config.rs @@ -4,7 +4,8 @@ //! structure usable by Cargo itself. Currently this is primarily used to map //! sources to one another via the `replace-with` key in `.cargo/config`. -use crate::core::{GitReference, PackageId, Source, SourceId}; +use crate::core::{GitReference, PackageId, SourceId}; +use crate::sources::source::Source; use crate::sources::{ReplacedSource, CRATES_IO_REGISTRY}; use crate::util::config::{self, ConfigRelativePath, OptValue}; use crate::util::errors::CargoResult; diff --git a/src/cargo/sources/directory.rs b/src/cargo/sources/directory.rs index a527c6dd789..91c7802f22b 100644 --- a/src/cargo/sources/directory.rs +++ b/src/cargo/sources/directory.rs @@ -3,8 +3,10 @@ use std::fmt::{self, Debug, Formatter}; use std::path::{Path, PathBuf}; use std::task::Poll; -use crate::core::source::MaybePackage; -use crate::core::{Dependency, Package, PackageId, QueryKind, Source, SourceId, Summary}; +use crate::core::{Dependency, Package, PackageId, SourceId, Summary}; +use crate::sources::source::MaybePackage; +use crate::sources::source::QueryKind; +use crate::sources::source::Source; use crate::sources::PathSource; use crate::util::errors::CargoResult; use crate::util::Config; diff --git a/src/cargo/sources/git/source.rs b/src/cargo/sources/git/source.rs index 10796562df0..f39829bd036 100644 --- a/src/cargo/sources/git/source.rs +++ b/src/cargo/sources/git/source.rs @@ -1,9 +1,12 @@ //! See [GitSource]. -use crate::core::source::{MaybePackage, QueryKind, Source, SourceId}; +use crate::core::source::SourceId; use crate::core::GitReference; use crate::core::{Dependency, Package, PackageId, Summary}; use crate::sources::git::utils::GitRemote; +use crate::sources::source::MaybePackage; +use crate::sources::source::QueryKind; +use crate::sources::source::Source; use crate::sources::PathSource; use crate::util::errors::CargoResult; use crate::util::hex::short_hash; diff --git a/src/cargo/sources/mod.rs b/src/cargo/sources/mod.rs index 81eda24ca2d..944e5fec712 100644 --- a/src/cargo/sources/mod.rs +++ b/src/cargo/sources/mod.rs @@ -1,6 +1,14 @@ -//! Implementations of `Source` trait. +//! The trait for sources of Cargo packages and its built-in implemetations. //! -//! Cargo provides several built-in implementations of [`Source`] trait. Namely, +//! A source is a provider that contains source files and metadata of packages. +//! It provides a number of methods to fetch those package informations, for +//! example, querying metadata or downloading files for a package. These +//! informations then can be used as dependencies for other Cargo packages. +//! +//! This module provides [`Source`][source::Source] trait as an abstraction of different sources, +//! as well as [`SourceMap`][source::SourceMap] struct as a map of all available sources. +//! +//! Several built-in implementations of `Source` trait are provided. Namely, //! //! * [`RegistrySource`] --- A source that provides an index for people to query //! a crate's metadata, and fetch files for a certain crate. crates.io falls @@ -16,7 +24,6 @@ //! This module also contains [`SourceConfigMap`], which is effectively the //! representation of the `[source.*]` value in Cargo configuration. //! -//! [`Source`]: crate::core::Source //! [source replacement]: https://doc.rust-lang.org/nightly/cargo/reference/source-replacement.html pub use self::config::SourceConfigMap; @@ -32,3 +39,4 @@ pub mod git; pub mod path; pub mod registry; pub mod replaced; +pub mod source; diff --git a/src/cargo/sources/path.rs b/src/cargo/sources/path.rs index 1d8ffc35c8b..ed602b6af76 100644 --- a/src/cargo/sources/path.rs +++ b/src/cargo/sources/path.rs @@ -3,9 +3,11 @@ use std::fmt::{self, Debug, Formatter}; use std::path::{Path, PathBuf}; use std::task::Poll; -use crate::core::source::MaybePackage; -use crate::core::{Dependency, Package, PackageId, QueryKind, Source, SourceId, Summary}; +use crate::core::{Dependency, Package, PackageId, SourceId, Summary}; use crate::ops; +use crate::sources::source::MaybePackage; +use crate::sources::source::QueryKind; +use crate::sources::source::Source; use crate::util::{internal, CargoResult, Config}; use anyhow::Context as _; use cargo_util::paths; diff --git a/src/cargo/sources/registry/mod.rs b/src/cargo/sources/registry/mod.rs index a5b6972d8dd..2f3787e23dd 100644 --- a/src/cargo/sources/registry/mod.rs +++ b/src/cargo/sources/registry/mod.rs @@ -201,8 +201,10 @@ use tar::Archive; use tracing::debug; use crate::core::dependency::Dependency; -use crate::core::source::MaybePackage; -use crate::core::{Package, PackageId, QueryKind, Source, SourceId, Summary}; +use crate::core::{Package, PackageId, SourceId, Summary}; +use crate::sources::source::MaybePackage; +use crate::sources::source::QueryKind; +use crate::sources::source::Source; use crate::sources::PathSource; use crate::util::hex; use crate::util::network::PollExt; diff --git a/src/cargo/sources/replaced.rs b/src/cargo/sources/replaced.rs index eef30e80cfe..f224e073d33 100644 --- a/src/cargo/sources/replaced.rs +++ b/src/cargo/sources/replaced.rs @@ -1,5 +1,7 @@ -use crate::core::source::MaybePackage; -use crate::core::{Dependency, Package, PackageId, QueryKind, Source, SourceId, Summary}; +use crate::core::{Dependency, Package, PackageId, SourceId, Summary}; +use crate::sources::source::MaybePackage; +use crate::sources::source::QueryKind; +use crate::sources::source::Source; use crate::util::errors::CargoResult; use std::task::Poll; diff --git a/src/cargo/sources/source.rs b/src/cargo/sources/source.rs new file mode 100644 index 00000000000..b8c552d9f94 --- /dev/null +++ b/src/cargo/sources/source.rs @@ -0,0 +1,396 @@ +//! [`Source`] trait for sources of Cargo packages. + +use std::collections::hash_map::HashMap; +use std::fmt; +use std::task::Poll; + +use crate::core::package::PackageSet; +use crate::core::SourceId; +use crate::core::{Dependency, Package, PackageId, Summary}; +use crate::util::{CargoResult, Config}; + +/// An abstraction of different sources of Cargo packages. +/// +/// The [`Source`] trait generalizes the API to interact with these providers. +/// For example, +/// +/// * [`Source::query`] is for querying package metadata on a given +/// [`Dependency`] requested by a Cargo manifest. +/// * [`Source::download`] is for fetching the full package information on +/// given names and versions. +/// * [`Source::source_id`] is for defining an unique identifier of a source to +/// distinguish one source from another, keeping Cargo safe from [dependency +/// confusion attack]. +/// +/// Normally, developers don't need to implement their own [`Source`]s. Cargo +/// provides several kinds of sources implementations that should cover almost +/// all use cases. See [`crate::sources`] for implementations provided by Cargo. +/// +/// [dependency confusion attack]: https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610 +pub trait Source { + /// Returns the [`SourceId`] corresponding to this source. + fn source_id(&self) -> SourceId; + + /// Returns the replaced [`SourceId`] corresponding to this source. + fn replaced_source_id(&self) -> SourceId { + self.source_id() + } + + /// Returns whether or not this source will return [`Summary`] items with + /// checksums listed. + fn supports_checksums(&self) -> bool; + + /// Returns whether or not this source will return [`Summary`] items with + /// the `precise` field in the [`SourceId`] listed. + fn requires_precise(&self) -> bool; + + /// Attempts to find the packages that match a dependency request. + /// + /// Usually you should call [`Source::block_until_ready`] somewhere and + /// wait until package informations become available. Otherwise any query + /// may return a [`Poll::Pending`]. + /// + /// The `f` argument is expected to get called when any [`Summary`] becomes available. + fn query( + &mut self, + dep: &Dependency, + kind: QueryKind, + f: &mut dyn FnMut(Summary), + ) -> Poll>; + + /// Gathers the result from [`Source::query`] as a list of [`Summary`] items + /// when they become available. + fn query_vec(&mut self, dep: &Dependency, kind: QueryKind) -> Poll>> { + let mut ret = Vec::new(); + self.query(dep, kind, &mut |s| ret.push(s)).map_ok(|_| ret) + } + + /// Ensure that the source is fully up-to-date for the current session on the next query. + fn invalidate_cache(&mut self); + + /// If quiet, the source should not display any progress or status messages. + fn set_quiet(&mut self, quiet: bool); + + /// Starts the process to fetch a [`Package`] for the given [`PackageId`]. + /// + /// If the source already has the package available on disk, then it + /// should return immediately with [`MaybePackage::Ready`] with the + /// [`Package`]. Otherwise it should return a [`MaybePackage::Download`] + /// to indicate the URL to download the package (this is for remote + /// registry sources only). + /// + /// In the case where [`MaybePackage::Download`] is returned, then the + /// package downloader will call [`Source::finish_download`] after the + /// download has finished. + fn download(&mut self, package: PackageId) -> CargoResult; + + /// Convenience method used to **immediately** fetch a [`Package`] for the + /// given [`PackageId`]. + /// + /// This may trigger a download if necessary. This should only be used + /// when a single package is needed (as in the case for `cargo install`). + /// Otherwise downloads should be batched together via [`PackageSet`]. + fn download_now(self: Box, package: PackageId, config: &Config) -> CargoResult + where + Self: std::marker::Sized, + { + let mut sources = SourceMap::new(); + sources.insert(self); + let pkg_set = PackageSet::new(&[package], sources, config)?; + let pkg = pkg_set.get_one(package)?; + Ok(Package::clone(pkg)) + } + + /// Gives the source the downloaded `.crate` file. + /// + /// When a source has returned [`MaybePackage::Download`] in the + /// [`Source::download`] method, then this function will be called with + /// the results of the download of the given URL. The source is + /// responsible for saving to disk, and returning the appropriate + /// [`Package`]. + fn finish_download(&mut self, pkg_id: PackageId, contents: Vec) -> CargoResult; + + /// Generates a unique string which represents the fingerprint of the + /// current state of the source. + /// + /// This fingerprint is used to determine the "freshness" of the source + /// later on. It must be guaranteed that the fingerprint of a source is + /// constant if and only if the output product will remain constant. + /// + /// The `pkg` argument is the package which this fingerprint should only be + /// interested in for when this source may contain multiple packages. + fn fingerprint(&self, pkg: &Package) -> CargoResult; + + /// If this source supports it, verifies the source of the package + /// specified. + /// + /// Note that the source may also have performed other checksum-based + /// verification during the `download` step, but this is intended to be run + /// just before a crate is compiled so it may perform more expensive checks + /// which may not be cacheable. + fn verify(&self, _pkg: PackageId) -> CargoResult<()> { + Ok(()) + } + + /// Describes this source in a human readable fashion, used for display in + /// resolver error messages currently. + fn describe(&self) -> String; + + /// Returns whether a source is being replaced by another here. + fn is_replaced(&self) -> bool { + false + } + + /// Add a number of crates that should be whitelisted for showing up during + /// queries, even if they are yanked. Currently only applies to registry + /// sources. + fn add_to_yanked_whitelist(&mut self, pkgs: &[PackageId]); + + /// Query if a package is yanked. Only registry sources can mark packages + /// as yanked. This ignores the yanked whitelist. + fn is_yanked(&mut self, _pkg: PackageId) -> Poll>; + + /// Block until all outstanding [`Poll::Pending`] requests are [`Poll::Ready`]. + /// + /// After calling this function, the source should return `Poll::Ready` for + /// any queries that previously returned `Poll::Pending`. + /// + /// If no queries previously returned `Poll::Pending`, and [`Source::invalidate_cache`] + /// was not called, this function should be a no-op. + fn block_until_ready(&mut self) -> CargoResult<()>; +} + +/// Defines how a dependency query will be performed for a [`Source`]. +#[derive(Copy, Clone, PartialEq, Eq)] +pub enum QueryKind { + /// A query for packages exactly matching the given dependency requirement. + /// + /// Each source gets to define what `exact` means for it. + Exact, + /// A query for packages close to the given dependency requirement. + /// + /// Each source gets to define what `close` means for it. + /// + /// Path/Git sources may return all dependencies that are at that URI, + /// whereas an `Registry` source may return dependencies that have the same + /// canonicalization. + Fuzzy, +} + +/// A download status that represents if a [`Package`] has already been +/// downloaded, or if not then a location to download. +pub enum MaybePackage { + /// The [`Package`] is already downloaded. + Ready(Package), + /// Not yet downloaded. Here is the URL to download the [`Package`] from. + Download { + /// URL to download the content. + url: String, + /// Text to display to the user of what is being downloaded. + descriptor: String, + /// Authorization data that may be required to attach when downloading. + authorization: Option, + }, +} + +/// A blanket implementation forwards all methods to [`Source`]. +impl<'a, T: Source + ?Sized + 'a> Source for Box { + fn source_id(&self) -> SourceId { + (**self).source_id() + } + + fn replaced_source_id(&self) -> SourceId { + (**self).replaced_source_id() + } + + fn supports_checksums(&self) -> bool { + (**self).supports_checksums() + } + + fn requires_precise(&self) -> bool { + (**self).requires_precise() + } + + fn query( + &mut self, + dep: &Dependency, + kind: QueryKind, + f: &mut dyn FnMut(Summary), + ) -> Poll> { + (**self).query(dep, kind, f) + } + + fn invalidate_cache(&mut self) { + (**self).invalidate_cache() + } + + fn set_quiet(&mut self, quiet: bool) { + (**self).set_quiet(quiet) + } + + fn download(&mut self, id: PackageId) -> CargoResult { + (**self).download(id) + } + + fn finish_download(&mut self, id: PackageId, data: Vec) -> CargoResult { + (**self).finish_download(id, data) + } + + fn fingerprint(&self, pkg: &Package) -> CargoResult { + (**self).fingerprint(pkg) + } + + fn verify(&self, pkg: PackageId) -> CargoResult<()> { + (**self).verify(pkg) + } + + fn describe(&self) -> String { + (**self).describe() + } + + fn is_replaced(&self) -> bool { + (**self).is_replaced() + } + + fn add_to_yanked_whitelist(&mut self, pkgs: &[PackageId]) { + (**self).add_to_yanked_whitelist(pkgs); + } + + fn is_yanked(&mut self, pkg: PackageId) -> Poll> { + (**self).is_yanked(pkg) + } + + fn block_until_ready(&mut self) -> CargoResult<()> { + (**self).block_until_ready() + } +} + +/// A blanket implementation forwards all methods to [`Source`]. +impl<'a, T: Source + ?Sized + 'a> Source for &'a mut T { + fn source_id(&self) -> SourceId { + (**self).source_id() + } + + fn replaced_source_id(&self) -> SourceId { + (**self).replaced_source_id() + } + + fn supports_checksums(&self) -> bool { + (**self).supports_checksums() + } + + fn requires_precise(&self) -> bool { + (**self).requires_precise() + } + + fn query( + &mut self, + dep: &Dependency, + kind: QueryKind, + f: &mut dyn FnMut(Summary), + ) -> Poll> { + (**self).query(dep, kind, f) + } + + fn invalidate_cache(&mut self) { + (**self).invalidate_cache() + } + + fn set_quiet(&mut self, quiet: bool) { + (**self).set_quiet(quiet) + } + + fn download(&mut self, id: PackageId) -> CargoResult { + (**self).download(id) + } + + fn finish_download(&mut self, id: PackageId, data: Vec) -> CargoResult { + (**self).finish_download(id, data) + } + + fn fingerprint(&self, pkg: &Package) -> CargoResult { + (**self).fingerprint(pkg) + } + + fn verify(&self, pkg: PackageId) -> CargoResult<()> { + (**self).verify(pkg) + } + + fn describe(&self) -> String { + (**self).describe() + } + + fn is_replaced(&self) -> bool { + (**self).is_replaced() + } + + fn add_to_yanked_whitelist(&mut self, pkgs: &[PackageId]) { + (**self).add_to_yanked_whitelist(pkgs); + } + + fn is_yanked(&mut self, pkg: PackageId) -> Poll> { + (**self).is_yanked(pkg) + } + + fn block_until_ready(&mut self) -> CargoResult<()> { + (**self).block_until_ready() + } +} + +/// A [`HashMap`] of [`SourceId`] to `Box`. +#[derive(Default)] +pub struct SourceMap<'src> { + map: HashMap>, +} + +// `impl Debug` on source requires specialization, if even desirable at all. +impl<'src> fmt::Debug for SourceMap<'src> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "SourceMap ")?; + f.debug_set().entries(self.map.keys()).finish() + } +} + +impl<'src> SourceMap<'src> { + /// Creates an empty map. + pub fn new() -> SourceMap<'src> { + SourceMap { + map: HashMap::new(), + } + } + + /// Like `HashMap::get`. + pub fn get(&self, id: SourceId) -> Option<&(dyn Source + 'src)> { + self.map.get(&id).map(|s| s.as_ref()) + } + + /// Like `HashMap::get_mut`. + pub fn get_mut(&mut self, id: SourceId) -> Option<&mut (dyn Source + 'src)> { + self.map.get_mut(&id).map(|s| s.as_mut()) + } + + /// Like `HashMap::insert`, but derives the [`SourceId`] key from the [`Source`]. + pub fn insert(&mut self, source: Box) { + let id = source.source_id(); + self.map.insert(id, source); + } + + /// Like `HashMap::len`. + pub fn len(&self) -> usize { + self.map.len() + } + + /// Like `HashMap::iter_mut`. + pub fn sources_mut<'a>( + &'a mut self, + ) -> impl Iterator { + self.map.iter_mut().map(|(a, b)| (a, &mut **b)) + } + + /// Merge the given map into self. + pub fn add_source_map(&mut self, other: SourceMap<'src>) { + for (key, value) in other.map { + self.map.entry(key).or_insert(value); + } + } +} diff --git a/tests/testsuite/search.rs b/tests/testsuite/search.rs index 1f6f403272c..dd54a5bcf4b 100644 --- a/tests/testsuite/search.rs +++ b/tests/testsuite/search.rs @@ -89,7 +89,8 @@ fn setup() -> RegistryBuilder { fn not_update() { let registry = setup().build(); - use cargo::core::{Shell, Source, SourceId}; + use cargo::core::{Shell, SourceId}; + use cargo::sources::source::Source; use cargo::sources::RegistrySource; use cargo::util::Config; From e575448574bc3d5dfb406a752b4f6fefeb7aa657 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 18 Aug 2023 23:57:59 +0100 Subject: [PATCH 2/2] refactor: flatten module path of `SourceId` --- crates/resolver-tests/src/lib.rs | 2 +- src/cargo/core/mod.rs | 4 ++-- src/cargo/core/package_id.rs | 4 ++-- src/cargo/core/source/mod.rs | 3 --- src/cargo/core/{source => }/source_id.rs | 2 +- src/cargo/sources/git/source.rs | 2 +- tests/testsuite/profile_config.rs | 2 +- 7 files changed, 8 insertions(+), 11 deletions(-) delete mode 100644 src/cargo/core/source/mod.rs rename src/cargo/core/{source => }/source_id.rs (99%) diff --git a/crates/resolver-tests/src/lib.rs b/crates/resolver-tests/src/lib.rs index aaf7fa0617e..166936dae81 100644 --- a/crates/resolver-tests/src/lib.rs +++ b/crates/resolver-tests/src/lib.rs @@ -13,9 +13,9 @@ use std::time::Instant; use cargo::core::dependency::DepKind; use cargo::core::resolver::{self, ResolveOpts, VersionPreferences}; -use cargo::core::source::{GitReference, SourceId}; use cargo::core::Resolve; use cargo::core::{Dependency, PackageId, Registry, Summary}; +use cargo::core::{GitReference, SourceId}; use cargo::sources::source::QueryKind; use cargo::util::{CargoResult, Config, Graph, IntoUrl, PartialVersion}; diff --git a/src/cargo/core/mod.rs b/src/cargo/core/mod.rs index b8a27604f9f..9b56564a7c9 100644 --- a/src/cargo/core/mod.rs +++ b/src/cargo/core/mod.rs @@ -8,7 +8,7 @@ pub use self::package_id_spec::PackageIdSpec; pub use self::registry::Registry; pub use self::resolver::{Resolve, ResolveVersion}; pub use self::shell::{Shell, Verbosity}; -pub use self::source::{GitReference, SourceId}; +pub use self::source_id::{GitReference, SourceId}; pub use self::summary::{FeatureMap, FeatureValue, Summary}; pub use self::workspace::{ find_workspace_root, resolve_relative_path, MaybePackage, Workspace, WorkspaceConfig, @@ -27,6 +27,6 @@ pub mod profiles; pub mod registry; pub mod resolver; pub mod shell; -pub mod source; +mod source_id; pub mod summary; mod workspace; diff --git a/src/cargo/core/package_id.rs b/src/cargo/core/package_id.rs index e17a73e6805..d1bcb448e6f 100644 --- a/src/cargo/core/package_id.rs +++ b/src/cargo/core/package_id.rs @@ -10,7 +10,7 @@ use std::sync::OnceLock; use serde::de; use serde::ser; -use crate::core::source::SourceId; +use crate::core::SourceId; use crate::util::interning::InternedString; use crate::util::{CargoResult, ToSemver}; @@ -238,7 +238,7 @@ impl fmt::Debug for PackageId { #[cfg(test)] mod tests { use super::PackageId; - use crate::core::source::SourceId; + use crate::core::SourceId; use crate::sources::CRATES_IO_INDEX; use crate::util::IntoUrl; diff --git a/src/cargo/core/source/mod.rs b/src/cargo/core/source/mod.rs deleted file mode 100644 index 3a2f6f6015b..00000000000 --- a/src/cargo/core/source/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -mod source_id; - -pub use self::source_id::{GitReference, SourceId}; diff --git a/src/cargo/core/source/source_id.rs b/src/cargo/core/source_id.rs similarity index 99% rename from src/cargo/core/source/source_id.rs rename to src/cargo/core/source_id.rs index e050c360666..8424f9a3737 100644 --- a/src/cargo/core/source/source_id.rs +++ b/src/cargo/core/source_id.rs @@ -32,7 +32,7 @@ static SOURCE_ID_CACHE: OnceLock>> = OnceL /// /// [`Source`]: crate::sources::source::Source /// [`Source::source_id`]: crate::sources::source::Source::source_id -/// [`PackageId`]: super::super::PackageId +/// [`PackageId`]: super::PackageId #[derive(Clone, Copy, Eq, Debug)] pub struct SourceId { inner: &'static SourceIdInner, diff --git a/src/cargo/sources/git/source.rs b/src/cargo/sources/git/source.rs index f39829bd036..1cdcf9840ec 100644 --- a/src/cargo/sources/git/source.rs +++ b/src/cargo/sources/git/source.rs @@ -1,7 +1,7 @@ //! See [GitSource]. -use crate::core::source::SourceId; use crate::core::GitReference; +use crate::core::SourceId; use crate::core::{Dependency, Package, PackageId, Summary}; use crate::sources::git::utils::GitRemote; use crate::sources::source::MaybePackage; diff --git a/tests/testsuite/profile_config.rs b/tests/testsuite/profile_config.rs index 26104e7e716..37a609e8fc4 100644 --- a/tests/testsuite/profile_config.rs +++ b/tests/testsuite/profile_config.rs @@ -427,7 +427,7 @@ fn named_config_profile() { let ws = Workspace::new(&paths::root().join("Cargo.toml"), &config).unwrap(); let profiles = Profiles::new(&ws, profile_name).unwrap(); - let crates_io = cargo::core::source::SourceId::crates_io(&config).unwrap(); + let crates_io = cargo::core::SourceId::crates_io(&config).unwrap(); let a_pkg = PackageId::new("a", "0.1.0", crates_io).unwrap(); let dep_pkg = PackageId::new("dep", "0.1.0", crates_io).unwrap();