Skip to content

Commit

Permalink
fix!: Use the sparse registry
Browse files Browse the repository at this point in the history
BREAKING CHANGE: This removes some features related to git
  • Loading branch information
epage committed Sep 16, 2024
1 parent 1babc04 commit ce36ff5
Show file tree
Hide file tree
Showing 42 changed files with 1,244 additions and 228 deletions.
1,027 changes: 946 additions & 81 deletions Cargo.lock

Large diffs are not rendered by default.

11 changes: 6 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,15 @@ required-features = ["set-version"]
[dependencies]
concolor-control = { version = "0.0.7", default-features = false }
cargo_metadata = "0.15.4"
crates-index = "0.19.13"
# Use this with default-features set to "true" (implicitly) so that reqwest,
# a transitive dependency, is compiled with support for both webpki
# certificates AND native certificates. We want support for both to be
# present, and then to let the user _select_ through configuration which
# one they want to be used.
tame-index = { version = "0.13", features = ["sparse", "native-certs", "local"] }
dunce = "1.0"
env_proxy = "0.4.1"
anyhow = "1.0"
git2 = "0.17"
hex = "0.4.3"
home = "0.5.5"
regex = "1.9.4"
Expand Down Expand Up @@ -99,7 +103,6 @@ default = [
"rm",
"upgrade",
"set-version",
"vendored-libgit2",
]
add = ["cli"]
rm = ["cli"]
Expand All @@ -108,5 +111,3 @@ set-version = ["cli"]
cli = ["color", "clap"]
color = ["concolor-control/auto"]
test-external-apis = []
vendored-openssl = ["git2/vendored-openssl"]
vendored-libgit2 = ["git2/vendored-libgit2"]
49 changes: 15 additions & 34 deletions src/bin/upgrade/upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ use std::path::PathBuf;

use anyhow::Context as _;
use cargo_edit::{
find, get_compatible_dependency, get_latest_dependency, registry_url, set_dep_version,
shell_note, shell_status, shell_warn, shell_write_stdout, update_registry_index, CargoResult,
CrateSpec, Dependency, LocalManifest, RustVersion, Source,
get_compatible_dependency, get_latest_dependency, registry_url, set_dep_version, shell_note,
shell_status, shell_warn, shell_write_stdout, CargoResult, CertsSource, CrateSpec, Dependency,
IndexCache, LocalManifest, RustVersion, Source,
};
use clap::Args;
use indexmap::IndexMap;
Expand Down Expand Up @@ -157,10 +157,7 @@ enum UnstableOptions {}
/// messages.
fn exec(args: UpgradeArgs) -> CargoResult<()> {
let offline = false;
if !offline {
let url = registry_url(&find(args.manifest_path.as_deref())?, None)?;
update_registry_index(&url, false)?;
}
let mut index = IndexCache::new(CertsSource::Native);

let metadata = resolve_ws(args.manifest_path.as_deref(), args.locked, offline)?;
let root_manifest_path = metadata.workspace_root.as_std_path().join("Cargo.toml");
Expand Down Expand Up @@ -209,7 +206,6 @@ fn exec(args: UpgradeArgs) -> CargoResult<()> {
.collect::<CargoResult<IndexMap<_, Option<_>>>>()?;
let mut processed_keys = BTreeSet::new();

let mut updated_registries = BTreeSet::new();
let mut modified_crates = BTreeSet::new();
let mut git_crates = BTreeSet::new();
let mut pinned_present = false;
Expand Down Expand Up @@ -292,26 +288,16 @@ fn exec(args: UpgradeArgs) -> CargoResult<()> {
{
// Update indices for any alternative registries, unless
// we're offline.
let registry_url = dependency
.registry()
.map(|registry| registry_url(&manifest_path, Some(registry)))
.transpose()?;
if !offline {
if let Some(registry_url) = &registry_url {
if updated_registries.insert(registry_url.to_owned()) {
update_registry_index(registry_url, false)?;
}
}
}
let registry_url = registry_url(&manifest_path, dependency.registry())?;
let index = index.index(&registry_url)?;
let latest_compatible = VersionReq::parse(&old_version_req)
.ok()
.and_then(|old_version_req| {
get_compatible_dependency(
&dependency.name,
&old_version_req,
rust_version,
&manifest_path,
registry_url.as_ref(),
index,
)
.ok()
})
Expand All @@ -321,19 +307,14 @@ fn exec(args: UpgradeArgs) -> CargoResult<()> {
.to_owned()
});
let is_prerelease = old_version_req.contains('-');
let latest_version = get_latest_dependency(
&dependency.name,
is_prerelease,
rust_version,
&manifest_path,
registry_url.as_ref(),
)
.map(|d| {
d.version()
.expect("registry packages always have a version")
.to_owned()
})
.ok();
let latest_version =
get_latest_dependency(&dependency.name, is_prerelease, rust_version, index)
.map(|d| {
d.version()
.expect("registry packages always have a version")
.to_owned()
})
.ok();
let latest_incompatible = if latest_version != latest_compatible {
latest_version
} else {
Expand Down
83 changes: 15 additions & 68 deletions src/fetch.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
use std::path::Path;
use std::time::Duration;

use url::Url;

use super::errors::*;
use super::registry::registry_url;
use super::shell_status;
use super::AnyIndexCache;
use super::Dependency;
use super::RegistrySource;
use super::VersionExt;
Expand All @@ -24,19 +18,13 @@ pub fn get_latest_dependency(
crate_name: &str,
flag_allow_prerelease: bool,
rust_version: Option<RustVersion>,
manifest_path: &Path,
registry: Option<&Url>,
index: &mut AnyIndexCache,
) -> CargoResult<Dependency> {
if crate_name.is_empty() {
anyhow::bail!("Found empty crate name");
}

let registry = match registry {
Some(url) => url.clone(),
None => registry_url(manifest_path, None)?,
};

let crate_versions = fuzzy_query_registry_index(crate_name, &registry)?;
let crate_versions = fuzzy_query_registry_index(crate_name, index)?;

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

Expand All @@ -52,19 +40,13 @@ pub fn get_compatible_dependency(
crate_name: &str,
version_req: &semver::VersionReq,
rust_version: Option<RustVersion>,
manifest_path: &Path,
registry: Option<&Url>,
index: &mut AnyIndexCache,
) -> CargoResult<Dependency> {
if crate_name.is_empty() {
anyhow::bail!("Found empty crate name");
}

let registry = match registry {
Some(url) => url.clone(),
None => registry_url(manifest_path, None)?,
};

let crate_versions = fuzzy_query_registry_index(crate_name, &registry)?;
let crate_versions = fuzzy_query_registry_index(crate_name, index)?;

let dep = read_compatible_version(&crate_versions, version_req, rust_version)?;

Expand Down Expand Up @@ -156,10 +138,8 @@ struct CrateVersion {
/// Fuzzy query crate from registry index
fn fuzzy_query_registry_index(
crate_name: impl Into<String>,
registry: &Url,
index: &mut AnyIndexCache,
) -> CargoResult<Vec<CrateVersion>> {
let index = crates_index::Index::from_url(registry.as_str())?;

let crate_name = crate_name.into();
let mut names = gen_fuzzy_crate_names(crate_name.clone())?;
if let Some(index) = names.iter().position(|x| *x == crate_name) {
Expand All @@ -168,19 +148,19 @@ fn fuzzy_query_registry_index(
}

for the_name in names {
let crate_ = match index.crate_(&the_name) {
Some(crate_) => crate_,
None => continue,
let krate = match index.krate(&the_name) {
Ok(Some(krate)) => krate,
_ => continue,
};
return crate_
.versions()
return krate
.versions
.iter()
.map(|v| {
Ok(CrateVersion {
name: v.name().to_owned(),
version: v.version().parse()?,
rust_version: v.rust_version().map(|r| r.parse()).transpose()?,
yanked: v.is_yanked(),
name: v.name.to_string(),
version: v.version.as_ref().parse()?,
rust_version: v.rust_version.as_ref().map(|r| r.parse()).transpose()?,
yanked: v.yanked,
})
})
.collect();
Expand Down Expand Up @@ -295,39 +275,6 @@ fn read_compatible_version(
Ok(Dependency::new(name).set_source(RegistrySource::new(version)))
}

/// update registry index for given project
pub fn update_registry_index(registry: &Url, quiet: bool) -> CargoResult<()> {
let mut index = crates_index::Index::from_url(registry.as_str())?;
if !quiet {
shell_status("Updating", &format!("'{registry}' index"))?;
}

while need_retry(index.update())? {
shell_status("Blocking", "waiting for lock on registry index")?;
std::thread::sleep(REGISTRY_BACKOFF);
}

Ok(())
}

/// Time between retries for retrieving the registry.
const REGISTRY_BACKOFF: Duration = Duration::from_secs(1);

/// Check if we need to retry retrieving the Index.
fn need_retry(res: Result<(), crates_index::Error>) -> CargoResult<bool> {
match res {
Ok(()) => Ok(false),
Err(crates_index::Error::Git(err)) => {
if err.class() == git2::ErrorClass::Index && err.code() == git2::ErrorCode::Locked {
Ok(true)
} else {
Err(crates_index::Error::Git(err).into())
}
}
Err(err) => Err(err.into()),
}
}

#[test]
fn test_gen_fuzzy_crate_names() {
fn test_helper(input: &str, expect: &[&str]) {
Expand Down
Loading

0 comments on commit ce36ff5

Please sign in to comment.