diff --git a/Cargo.lock b/Cargo.lock index 51b3623..171ca6a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -127,9 +127,9 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ceed8ef69d8518a5dda55c07425450b58a4e1946f4951eab6d7191ee86c2443d" +checksum = "694c8807f2ae16faecc43dc17d74b3eb042482789fd0eb64b39a2e04e087053f" dependencies = [ "serde", ] @@ -196,9 +196,9 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" dependencies = [ "cfg-if", ] @@ -274,9 +274,9 @@ checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" [[package]] name = "either" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" [[package]] name = "encoding_rs" @@ -1189,9 +1189,9 @@ checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" [[package]] name = "hermit-abi" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c62115964e08cb8039170eb33c1d0e2388a256930279edca206fff675f82c3" +checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd" [[package]] name = "home" @@ -1286,9 +1286,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.2" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824b2ae422412366ba479e8111fd301f7b5faece8149317bb81925979a53f520" +checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" dependencies = [ "equivalent", "hashbrown", @@ -1412,9 +1412,9 @@ checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ "autocfg", ] @@ -1788,15 +1788,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_spanned" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" -dependencies = [ - "serde", -] - [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -1940,7 +1931,7 @@ dependencies = [ "thiserror", "tiny-bench", "tokio", - "toml", + "toml-span", "twox-hash", ] @@ -1958,18 +1949,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.56" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" dependencies = [ "proc-macro2", "quote", @@ -2071,37 +2062,12 @@ dependencies = [ ] [[package]] -name = "toml" -version = "0.8.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a9aad4a3066010876e8dcf5a8a06e70a558751117a145c6ce2b82c2e2054290" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", -] - -[[package]] -name = "toml_datetime" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.22.4" +name = "toml-span" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c9ffdf896f8daaabf9b66ba8e77ea1ed5ed0f72821b398aba62352e95062951" +checksum = "32c5896fa509a428e0ffcb1e37c7954f183a507784cd2999cb76c3b7544bf52d" dependencies = [ - "indexmap", - "serde", - "serde_spanned", - "toml_datetime", - "winnow", + "smallvec", ] [[package]] @@ -2473,9 +2439,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "winnow" -version = "0.5.39" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5389a154b01683d28c77f8f68f49dea75f0a4da32557a58f68ee51ebba472d29" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" dependencies = [ "memchr", ] diff --git a/Cargo.toml b/Cargo.toml index d10aa3b..789af71 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,7 +53,7 @@ tokio = { version = "1.0", default-features = false, features = [ "time", ], optional = true } # cargo config parsing -toml = "0.8" +toml-span = "0.1" # Faster hashing twox-hash = { version = "1.6", default-features = false } diff --git a/src/error.rs b/src/error.rs index d26b660..2c5b192 100644 --- a/src/error.rs +++ b/src/error.rs @@ -32,7 +32,7 @@ pub enum Error { Json(#[from] serde_json::Error), /// Failed to deserialize TOML #[error(transparent)] - Toml(#[from] Box), + Toml(#[from] Box), /// An index entry did not contain any versions #[error("index entry contained no versions for the crate")] NoCrateVersions, diff --git a/src/index/location.rs b/src/index/location.rs index aa507af..2d004bb 100644 --- a/src/index/location.rs +++ b/src/index/location.rs @@ -68,18 +68,17 @@ impl<'iu> IndexUrl<'iu> { Some("sparse") => true, Some("git") => false, _ => { - let sparse_index = read_cargo_config(config_root, cargo_home, |config| { - config - .get("registries") - .and_then(|v| v.get("crates-io")) - .and_then(|v| v.get("protocol")) - .and_then(|v| v.as_str()) - .and_then(|v| match v { + let sparse_index = + read_cargo_config(config_root, cargo_home, |config| { + match config + .pointer("/registries/crates-io/protocol") + .and_then(|p| p.as_str())? + { "sparse" => Some(true), "git" => Some(false), _ => None, - }) - })?; + } + })?; if let Some(si) = sparse_index { si @@ -196,7 +195,7 @@ impl<'il> IndexLocation<'il> { pub(crate) fn read_cargo_config( root: Option, cargo_home: Option<&Path>, - callback: impl Fn(&toml::Value) -> Option, + callback: impl Fn(&toml_span::value::Value<'_>) -> Option, ) -> Result, Error> { if let Some(mut path) = root.or_else(|| { std::env::current_dir() @@ -211,7 +210,7 @@ pub(crate) fn read_cargo_config( Err(err) => return Err(Error::IoPath(err, path)), }; - let toml: toml::Value = toml::from_str(&contents).map_err(Box::new)?; + let toml = toml_span::parse(&contents).map_err(Box::new)?; if let Some(value) = callback(&toml) { return Ok(Some(value)); } @@ -232,8 +231,8 @@ pub(crate) fn read_cargo_config( { let path = home.join("config.toml"); if path.exists() { - let toml: toml::Value = - toml::from_str(&std::fs::read_to_string(&path)?).map_err(Box::new)?; + let fc = std::fs::read_to_string(&path)?; + let toml = toml_span::parse(&fc).map_err(Box::new)?; if let Some(value) = callback(&toml) { return Ok(Some(value)); } @@ -252,25 +251,19 @@ pub(crate) fn get_crates_io_replacement<'iu>( cargo_home: Option<&Path>, ) -> Result>, Error> { read_cargo_config(root, cargo_home, |config| { - config.get("source").and_then(|sources| { - sources - .get("crates-io") - .and_then(|v| v.get("replace-with")) - .and_then(|v| v.as_str()) - .and_then(|v| sources.get(v)) - .and_then(|v| { - v.get("registry") - .and_then(|reg| { - reg.as_str() - .map(|r| IndexUrl::NonCratesIo(r.to_owned().into())) - }) - .or_else(|| { - v.get("local-registry").and_then(|l| { - l.as_str().map(|l| IndexUrl::Local(PathBuf::from(l).into())) - }) - }) - }) - }) + let repw = config.pointer("/source/crates-io/replace-with")?.as_str()?; + let sources = config.pointer("/source")?.as_table()?; + let replace_src = sources.get(&repw.into())?.as_table()?; + + if let Some(rr) = replace_src.get(&"registry".into()) { + rr.as_str() + .map(|r| IndexUrl::NonCratesIo(r.to_owned().into())) + } else if let Some(rlr) = replace_src.get(&"local-registry".into()) { + rlr.as_str() + .map(|l| IndexUrl::Local(PathBuf::from(l).into())) + } else { + None + } }) } @@ -288,4 +281,47 @@ mod test { crate::index::ComboIndexCache::Sparse(_) )); } + + /// Verifies we can parse .cargo/config.toml files to either use the crates-io + /// protocol set, or source replacements + #[test] + fn parses_from_file() { + assert!(std::env::var_os("CARGO_REGISTRIES_CRATES_IO_PROTOCOL").is_none()); + + let td = tempfile::tempdir().unwrap(); + let root = crate::PathBuf::from_path_buf(td.path().to_owned()).unwrap(); + let cfg_toml = td.path().join(".cargo/config.toml"); + + std::fs::create_dir_all(cfg_toml.parent().unwrap()).unwrap(); + + const GIT: &str = r#"[registries.crates-io] +protocol = "git" +"#; + + // First just set the protocol from the sparse default to git + std::fs::write(&cfg_toml, GIT).unwrap(); + + let iurl = super::IndexUrl::crates_io(Some(root.clone()), None, None).unwrap(); + assert_eq!(iurl.as_str(), crate::CRATES_IO_INDEX); + assert!(!iurl.is_sparse()); + + // Next set replacement registries + for (i, (kind, url)) in [ + ( + "registry", + "sparse+https://sparse-registry-parses-from-file.com", + ), + ("registry", "https://sparse-registry-parses-from-file.git"), + ("local-registry", root.as_str()), + ] + .iter() + .enumerate() + { + std::fs::write(&cfg_toml, format!("{GIT}\n[source.crates-io]\nreplace-with = 'replacement'\n[source.replacement]\n{kind} = '{url}'")).unwrap(); + + let iurl = super::IndexUrl::crates_io(Some(root.clone()), None, None).unwrap(); + assert_eq!(i == 0, iurl.is_sparse()); + assert_eq!(iurl.as_str(), *url); + } + } } diff --git a/tests/local.rs b/tests/local.rs index 6a0faf0..3569144 100644 --- a/tests/local.rs +++ b/tests/local.rs @@ -36,7 +36,13 @@ fn builds_local_registry() { let ip = krates.entry(pkg.name.clone()).or_insert_with(|| { let ik = sparse .cached_krate(pkg.name.as_str().try_into().unwrap(), &lock) + .map_err(|e| { + panic!("failed to read cache entry for {}: {e}", pkg.name); + }) .unwrap() + .ok_or_else(|| { + panic!("no cache entry for {}", pkg.name); + }) .unwrap(); IndexPkg {