[packages/cargo-vendor-filterer] fix missing required packages in some cases; rel 2

atler atler at pld-linux.org
Thu Feb 12 16:12:33 CET 2026


commit 428bcb0903a1de19aa0bf53793d20eaf4e5256f3
Author: Jan Palus <atler at pld-linux.org>
Date:   Thu Feb 12 16:07:38 2026 +0100

    fix missing required packages in some cases; rel 2
    
    from: https://github.com/coreos/cargo-vendor-filterer/pull/128
    upstream report: https://github.com/coreos/cargo-vendor-filterer/issues/120

 cargo-vendor-filterer.spec |   4 +-
 missing-packages.patch     | 153 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 156 insertions(+), 1 deletion(-)
---
diff --git a/cargo-vendor-filterer.spec b/cargo-vendor-filterer.spec
index e957763..cf4a1b0 100644
--- a/cargo-vendor-filterer.spec
+++ b/cargo-vendor-filterer.spec
@@ -4,7 +4,7 @@ Summary:	Tool to "cargo vendor" with filtering
 Summary(pl.UTF-8):	Narzędzie do "cargo vendor" z filtrowaniem
 Name:		cargo-vendor-filterer
 Version:	0.5.18
-Release:	1
+Release:	2
 License:	Apache v2.0
 Group:		Applications
 Source0:	https://github.com/coreos/cargo-vendor-filterer/archive/v%{version}/%{name}-%{version}.tar.gz
@@ -12,6 +12,7 @@ Source0:	https://github.com/coreos/cargo-vendor-filterer/archive/v%{version}/%{n
 Source1:	%{name}-crates-%{crates_ver}.tar.xz
 # Source1-md5:	3a187bef2982d868e3afefe3ac895af1
 Patch0:		tier2-platforms-without-host-tools.patch
+Patch1:		missing-packages.patch
 URL:		https://github.com/coreos/cargo-vendor-filterer
 BuildRequires:	cargo
 BuildRequires:	openssl-devel
@@ -39,6 +40,7 @@ wymagają np. tylko linuksowych.
 %prep
 %setup -q -a1
 %patch -P0 -p1
+%patch -P1 -p1
 
 %{__mv} %{name}-%{crates_ver}/* .
 sed -i -e 's/@@VERSION@@/%{version}/' Cargo.lock
diff --git a/missing-packages.patch b/missing-packages.patch
new file mode 100644
index 0000000..12cb8b4
--- /dev/null
+++ b/missing-packages.patch
@@ -0,0 +1,153 @@
+From 5d252f75eab29c38218a34d786f249c6e16558dc Mon Sep 17 00:00:00 2001
+From: Jan Palus <jpalus at fastmail.com>
+Date: Thu, 12 Feb 2026 15:18:57 +0100
+Subject: [PATCH] Fix required packages being replaced with stub in some cases
+
+So far packages directory locations were determined based on already
+limited set of features (ie default feature set) which might not reflect
+what `cargo vendor` does with all features enabled. Paired with cargo's
+naming convention for multiple versions of same package -- highest
+version uses "name" while lower versions use "name-version" -- it caused
+required package to be replaced with stub if highest version turned to
+be optional and excluded with filtered feature set.
+
+Instead first create map for all packages and their directories with all
+features enabled and use it as reference.
+
+Fixes #120
+---
+ src/main.rs | 105 +++++++++++++++++++++++++++++++----------------------
+ 1 file changed, 61 insertions(+), 44 deletions(-)
+
+diff --git a/src/main.rs b/src/main.rs
+index 66825fb..d16725f 100644
+--- a/src/main.rs
++++ b/src/main.rs
+@@ -665,7 +665,60 @@ fn new_metadata_cmd(path: Option<&Utf8Path>, offline: bool) -> MetadataCommand {
+     command
+ }
+ 
+-fn get_unfiltered_packages(
++/// Get filesystem locations of packages vendored by `cargo vendor` (all features enabled)
++fn get_vendored_package_dirs(
++    args: &Args,
++) -> Result<HashMap<cargo_metadata::PackageId, String>> {
++    let root = args.get_root_package()?;
++    let all_manifest_paths = args.get_all_manifest_paths();
++    let mut pkgs_by_name: HashMap<_, Vec<_>> = HashMap::new();
++    for manifest_path in all_manifest_paths {
++        let mut command = new_metadata_cmd(manifest_path, args.offline);
++        command.features(AllFeatures);
++        let meta = command.exec().context("Executing cargo metadata")?;
++        meta.packages
++            .into_iter()
++            // Skip ourself
++            .filter(|pkg| root.as_ref().is_none_or(|root| pkg.id != root.id))
++            // Also skip anything local
++            .filter(|pkg| {
++                let local = pkg.source.is_none();
++                if local {
++                    eprintln!("Skipping {0}", pkg.name);
++                }
++
++                !local
++            })
++            .for_each(|pkg| {
++                if let Some(pkgs) = pkgs_by_name.get_mut(&pkg.name) {
++                    pkgs.push(pkg);
++                } else {
++                    pkgs_by_name.insert(pkg.name.clone(), vec![pkg]);
++                }
++            });
++    }
++    let mut pkg_dirs = HashMap::new();
++    for (_name, mut pkgs) in pkgs_by_name {
++        // If we use versioned-dirs, we insert all packages with a versioned filename
++        // If not, we split off the first package and insert it without a version-suffix
++        if !args.versioned_dirs {
++            // Reverse sort - greater version is lower index
++            pkgs.sort_by(|a, b| b.version.cmp(&a.version));
++            let first = pkgs.remove(0);
++            pkg_dirs.insert(first.id, first.name);
++        }
++
++        for pkg in pkgs {
++            let dir = package_versioned_filename(&pkg);
++            pkg_dirs.insert(pkg.id, dir);
++        }
++    }
++
++    Ok(pkg_dirs)
++}
++
++/// Retrieve packages needed for selected feature set
++fn get_packages_for_features(
+     args: &Args,
+     config: &VendorFilter,
+ ) -> Result<HashMap<cargo_metadata::PackageId, cargo_metadata::Package>> {
+@@ -893,31 +946,12 @@ pub fn run(args: Args) -> Result<()> {
+         anyhow::bail!("Refusing to operate on extant directory: {}", output_dir);
+     }
+ 
+-    eprintln!("Gathering metadata");
+     // We need to gather the full, unfiltered metadata to canonically know what
+     // `cargo vendor` will do.
+-    let all_packages = get_unfiltered_packages(&args, &config)?;
+-    let root = args.get_root_package()?;
+-
+-    // Create a mapping of name -> [package versions]
+-    let mut pkgs_by_name = BTreeMap::<_, Vec<_>>::new();
+-    for pkg in all_packages.values() {
+-        let name = pkg.name.as_str();
+-        // Skip ourself
+-        if let Some(root) = root.as_ref() {
+-            if pkg.id == root.id {
+-                continue;
+-            }
+-        }
+-        // Also skip anything local
+-        if pkg.source.as_ref().is_none() {
+-            eprintln!("Skipping {name}");
+-            continue;
+-        }
+-
+-        let v = pkgs_by_name.entry(name).or_default();
+-        v.push(pkg);
+-    }
++    eprintln!("Gathering metadata for vendored packages");
++    let vendored_dirs = get_vendored_package_dirs(&args)?;
++    eprintln!("Gathering metadata for selected feature set");
++    let all_packages = get_packages_for_features(&args, &config)?;
+ 
+     // And now do the filtered set
+     let mut packages = HashMap::new();
+@@ -982,26 +1016,9 @@ pub fn run(args: Args) -> Result<()> {
+     // the all_packages map with the filtered one, returning an index by the
+     // directory name that will have been generated by `cargo vendor`.
+     let mut package_filenames = BTreeMap::new();
+-    for (_name, mut pkgs) in pkgs_by_name {
+-        // Reverse sort - greater version is lower index
+-        pkgs.sort_by(|a, b| b.version.cmp(&a.version));
+-        // If we use versioned-dirs, we insert all packages with a versioned filename
+-        // If not, we split off the first package and insert it without a version-suffix
+-        let versioned_pkgs = if !args.versioned_dirs {
+-            // SAFETY: The package set must be non-empty
+-            let (first, rest) = pkgs.split_first().unwrap();
+-            if packages.contains_key(&first.id) {
+-                package_filenames.insert(Cow::Borrowed(first.name.as_str()), *first);
+-            }
+-            rest
+-        } else {
+-            &pkgs
+-        };
+-
+-        for pkg in versioned_pkgs {
+-            if packages.contains_key(&pkg.id) {
+-                package_filenames.insert(Cow::Owned(package_versioned_filename(pkg)), pkg);
+-            }
++    for (id, pkg) in packages {
++        if let Some(dir) = vendored_dirs.get(&id) {
++            package_filenames.insert(Cow::Borrowed(dir.as_str()), pkg);
+         }
+     }
+ 
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/cargo-vendor-filterer.git/commitdiff/428bcb0903a1de19aa0bf53793d20eaf4e5256f3



More information about the pld-cvs-commit mailing list