Skip to content

Commit

Permalink
Update deps (#53)
Browse files Browse the repository at this point in the history
* Update deps

* Update deny

* Update CHANGELOG

* Add features lockfile to prevent test failures

* Only fetch crates for target

* Add support for sparse crates.io index

* Remove commented out line

* Fix test

* Update CHANGELOG

* Split test

* Only need this for --all-features
  • Loading branch information
Jake-Shadle committed Apr 4, 2023
1 parent 6aa02ee commit 7fda552
Show file tree
Hide file tree
Showing 7 changed files with 1,428 additions and 80 deletions.
16 changes: 9 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,22 @@ jobs:
strategy:
matrix:
os: [ubuntu-22.04]
features: ["--all-features", null]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: cargo fetch
- run: cargo fetch --target x86_64-unknown-linux-gnu
# When using the sparse index, we need to do this additional fetch so that
# the entries we want are in the sparse cache, otherwise the bug_repro test
# fails.
- run: cargo fetch --manifest-path tests/bug/Cargo.toml
if: matrix.features == '--all-features'
- name: cargo test build
run: cargo build --tests --release
run: cargo build --tests --release ${{ matrix.features }}
- name: cargo test
run: cargo test --release
- name: cargo test build all-features
run: cargo build --tests --release --all-features
- name: cargo test all-features
run: cargo test --release --all-features
run: cargo test --release ${{ matrix.features }}

deny-check:
name: cargo-deny
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

<!-- next-header -->
## [Unreleased] - ReleaseDate
### Changed
- [PR#53](https://github.com/EmbarkStudios/krates/pull/53) updated `cfg-expr` to 0.14 and `crates-index` to 0.19.

### Fixed
- [PR#53](https://github.com/EmbarkStudios/krates/pull/53) added support for using the HTTP sparse index for crates.io. If the sparse index was enabled and there wasn't a regular git index (for example, if you use `dtolnay/rust-toolchain@stable` in your CI) this would cause no index to be used to fix crate features if `prefer-index` was enabled.

## [0.12.6] - 2022-11-25
### Changed
- [PR#52](https://github.com/EmbarkStudios/krates/pull/52) updated cfg-expr to 0.12.
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ targets = ["cfg-expr/targets"]
# Used for acquiring and/or deserializing `cargo metadata` output
cargo_metadata = "0.15"
# Used to parse and evaluate cfg() expressions for dependencies
cfg-expr = "0.12"
cfg-expr = "0.15"
# Allows inspection of the cargo registry index(ices)
crates-index = { version = "0.18", optional = true, default-features = false, features = [
crates-index = { version = "0.19", optional = true, default-features = false, features = [
"parallel",
] }
# Used to create and traverse graph structures
Expand Down
3 changes: 2 additions & 1 deletion deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ allow = [
"Apache-2.0",
"Apache-2.0 WITH LLVM-exception",
"MIT",
"MPL-2.0",
"Unicode-DFS-2016",
]
copyleft = "deny"
Expand All @@ -19,6 +18,8 @@ multiple-versions = "deny"
skip = [
# Doesn't matter
{ name = "hermit-abi" },
# dev only but still sigh
{ name = "windows-sys", version = "=0.42.0" },
]

[sources]
Expand Down
76 changes: 6 additions & 70 deletions src/builder.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
pub(crate) mod features;

#[cfg(feature = "prefer-index")]
mod index;

use crate::{DepKind, Edge, Error, Kid, Krates};
use cargo_metadata as cm;
use features::{Feature, ParsedFeature};
Expand Down Expand Up @@ -767,8 +770,8 @@ impl Builder {
features: Vec<String>,
}

#[cfg(feature = "crates-index")]
let index = crates_index::Index::new_cargo_default().ok();
#[cfg(feature = "prefer-index")]
let index = index::open();

while let Some(pid) = pid_stack.pop() {
let is_in_workspace = workspace_members.binary_search(pid).is_ok();
Expand Down Expand Up @@ -803,15 +806,12 @@ impl Builder {
if let Some(kid) = kid {
Some(kid)
} else {
//dbg!("failed to find {dep_name} {:#?}", &rnode.deps);
None
}
};

#[cfg(feature = "prefer-index")]
if let Some(index) = &index {
fix_features(index, krate);
}
index::fix_features(&index, krate);

// Cargo puts out a flat list of the enabled features, but we need
// to use the declared features on the crate itself to figure out
Expand Down Expand Up @@ -1464,70 +1464,6 @@ fn dep_names_match(krate_dep_name: &str, resolved_name: &str) -> bool {
}
}

/// Due to <https://github.com/rust-lang/cargo/issues/11319>, we can't actually
/// trust cargo to give us the correct package metadata, so we instead use the
/// (presumably) correct data from the the index
#[cfg(feature = "prefer-index")]
fn fix_features(index: &crates_index::Index, krate: &mut cm::Package) {
if krate
.source
.as_ref()
.map_or(true, |src| !src.is_crates_io())
{
return;
}

if let Some(entry) = index.crate_(&krate.name) {
let features = entry.versions().iter().find_map(|v| {
if let Ok(iv) = v.version().parse::<semver::Version>() {
if iv == krate.version {
Some(v.features())
} else {
None
}
} else {
None
}
});

if let Some(features) = features {
for (ikey, ivalue) in features {
if !krate.features.contains_key(ikey) {
krate.features.insert(ikey.clone(), ivalue.clone());
}
}

// The index entry features might not have the `dep:<crate>`
// used with weak features if the crate version was
// published with cargo <1.60.0 version, so we need to
// manually fix that up since we depend on that format
let missing_deps: Vec<_> = krate
.features
.iter()
.flat_map(|(_, sf)| sf.iter())
.filter_map(|sf| {
let pf = ParsedFeature::from(sf.as_str());

if let Feature::Simple(simple) = pf.feat() {
if krate.features.contains_key(simple) {
None
} else {
Some(simple.to_owned())
}
} else {
None
}
})
.collect();

for missing in missing_deps {
let dep_feature = format!("dep:{missing}");
krate.features.insert(missing, vec![dep_feature]);
}
}
}
}

#[cfg(test)]
mod test {
use super::*;
Expand Down
87 changes: 87 additions & 0 deletions src/builder/index.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
pub(super) struct ComboIndex {
git: Option<crates_index::Index>,
http: Option<crates_index::SparseIndex>,
}

impl ComboIndex {
#[inline]
fn krate(&self, name: &str) -> Option<crates_index::Crate> {
// Attempt http first, as this will be the default in future cargo versions
// and using it when it is not the defaul indicates the user has opted in
self.http
.as_ref()
.and_then(|h| h.crate_from_cache(name).ok())
.or_else(|| self.git.as_ref().and_then(|g| g.crate_(name)))
}
}

#[inline]
pub(super) fn open() -> ComboIndex {
ComboIndex {
git: crates_index::Index::new_cargo_default().ok(),
http: crates_index::SparseIndex::from_url("sparse+https://index.crates.io/").ok(),
}
}

/// Due to <https://github.com/rust-lang/cargo/issues/11319>, we can't actually
/// trust cargo to give us the correct package metadata, so we instead use the
/// (presumably) correct data from the the index
pub(super) fn fix_features(index: &ComboIndex, krate: &mut cargo_metadata::Package) {
if krate
.source
.as_ref()
.map_or(true, |src| !src.is_crates_io())
{
return;
}

if let Some(entry) = index.krate(&krate.name) {
let features = entry.versions().iter().find_map(|v| {
if let Ok(iv) = v.version().parse::<semver::Version>() {
if iv == krate.version {
Some(v.features())
} else {
None
}
} else {
None
}
});

if let Some(features) = features {
for (ikey, ivalue) in features {
if !krate.features.contains_key(ikey) {
krate.features.insert(ikey.clone(), ivalue.clone());
}
}

// The index entry features might not have the `dep:<crate>`
// used with weak features if the crate version was
// published with cargo <1.60.0 version, so we need to
// manually fix that up since we depend on that format
let missing_deps: Vec<_> = krate
.features
.iter()
.flat_map(|(_, sf)| sf.iter())
.filter_map(|sf| {
let pf = crate::ParsedFeature::from(sf.as_str());

if let super::features::Feature::Simple(simple) = pf.feat() {
if krate.features.contains_key(simple) {
None
} else {
Some(simple.to_owned())
}
} else {
None
}
})
.collect();

for missing in missing_deps {
let dep_feature = format!("dep:{missing}");
krate.features.insert(missing, vec![dep_feature]);
}
}
}
}

0 comments on commit 7fda552

Please sign in to comment.