Skip to content

Commit 119477c

Browse files
committed
fix(add): strip feature dep when dep is dev dep or target dev dep
1 parent 465e361 commit 119477c

File tree

3 files changed

+268
-10
lines changed

3 files changed

+268
-10
lines changed

src/cargo/ops/registry/publish.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use crate::core::dependency::DepKind;
2020
use crate::core::manifest::ManifestMetadata;
2121
use crate::core::resolver::CliFeatures;
2222
use crate::core::Dependency;
23+
use crate::core::FeatureValue;
2324
use crate::core::Package;
2425
use crate::core::PackageIdSpecQuery;
2526
use crate::core::SourceId;
@@ -33,6 +34,7 @@ use crate::sources::CRATES_IO_REGISTRY;
3334
use crate::util::auth;
3435
use crate::util::cache_lock::CacheLockMode;
3536
use crate::util::context::JobsConfig;
37+
use crate::util::interning::InternedString;
3638
use crate::util::Progress;
3739
use crate::util::ProgressStyle;
3840
use crate::CargoResult;
@@ -412,13 +414,36 @@ fn transmit(
412414
return Ok(());
413415
}
414416

417+
let deps_map = pkg
418+
.dependencies()
419+
.iter()
420+
.map(|dep| (InternedString::new(dep.name_in_toml().as_str()), dep))
421+
.collect::<BTreeMap<InternedString, &Dependency>>();
422+
415423
let string_features = match manifest.original().features() {
416424
Some(features) => features
417425
.iter()
418426
.map(|(feat, values)| {
419427
(
420428
feat.to_string(),
421-
values.iter().map(|fv| fv.to_string()).collect(),
429+
values
430+
.iter()
431+
.filter(|fv| {
432+
let feature_value = FeatureValue::new(InternedString::new(fv));
433+
match feature_value {
434+
FeatureValue::Dep { dep_name }
435+
| FeatureValue::DepFeature { dep_name, .. } => {
436+
if let Some(dep) = deps_map.get(&dep_name) {
437+
dep.is_transitive() || dep.specified_req()
438+
} else {
439+
true
440+
}
441+
}
442+
_ => true,
443+
}
444+
})
445+
.map(|fv| fv.to_string())
446+
.collect(),
422447
)
423448
})
424449
.collect::<BTreeMap<String, Vec<String>>>(),

src/cargo/util/toml/mod.rs

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ use crate::AlreadyPrintedError;
99
use anyhow::{anyhow, bail, Context as _};
1010
use cargo_platform::Platform;
1111
use cargo_util::paths;
12-
use cargo_util_schemas::manifest;
1312
use cargo_util_schemas::manifest::RustVersion;
13+
use cargo_util_schemas::manifest::{self, TomlManifest};
1414
use itertools::Itertools;
1515
use lazycell::LazyCell;
1616
use pathdiff::diff_paths;
@@ -21,7 +21,7 @@ use crate::core::compiler::{CompileKind, CompileTarget};
2121
use crate::core::dependency::{Artifact, ArtifactTarget, DepKind};
2222
use crate::core::manifest::{ManifestMetadata, TargetSourcePath, Warnings};
2323
use crate::core::resolver::ResolveBehavior;
24-
use crate::core::{find_workspace_root, resolve_relative_path, CliUnstable};
24+
use crate::core::{find_workspace_root, resolve_relative_path, CliUnstable, FeatureValue};
2525
use crate::core::{Dependency, Manifest, PackageId, Summary, Target};
2626
use crate::core::{Edition, EitherManifest, Feature, Features, VirtualManifest, Workspace};
2727
use crate::core::{GitReference, PackageIdSpec, SourceId, WorkspaceConfig, WorkspaceRootConfig};
@@ -316,7 +316,7 @@ pub fn prepare_for_publish(
316316
}
317317
}
318318
let all = |_d: &manifest::TomlDependency| true;
319-
return Ok(manifest::TomlManifest {
319+
let mut manifest = manifest::TomlManifest {
320320
package: Some(package),
321321
project: None,
322322
profile: me.profile.clone(),
@@ -366,7 +366,52 @@ pub fn prepare_for_publish(
366366
badges: me.badges.clone(),
367367
cargo_features: me.cargo_features.clone(),
368368
lints: me.lints.clone(),
369-
});
369+
};
370+
strip_features(&mut manifest);
371+
return Ok(manifest);
372+
373+
fn strip_features(manifest: &mut TomlManifest) {
374+
fn insert_dep_name(
375+
dep_name_set: &mut BTreeSet<manifest::PackageName>,
376+
deps: Option<&BTreeMap<manifest::PackageName, manifest::InheritableDependency>>,
377+
) {
378+
let Some(deps) = deps else {
379+
return;
380+
};
381+
deps.iter().for_each(|(k, _v)| {
382+
dep_name_set.insert(k.clone());
383+
});
384+
}
385+
let mut dep_name_set = BTreeSet::new();
386+
insert_dep_name(&mut dep_name_set, manifest.dependencies.as_ref());
387+
insert_dep_name(&mut dep_name_set, manifest.dev_dependencies());
388+
insert_dep_name(&mut dep_name_set, manifest.build_dependencies());
389+
if let Some(target_map) = manifest.target.as_ref() {
390+
target_map.iter().for_each(|(_k, v)| {
391+
insert_dep_name(&mut dep_name_set, v.dependencies.as_ref());
392+
insert_dep_name(&mut dep_name_set, v.dev_dependencies());
393+
insert_dep_name(&mut dep_name_set, v.build_dependencies());
394+
});
395+
}
396+
397+
let features = manifest.features.as_mut();
398+
let Some(features) = features else {
399+
return;
400+
};
401+
402+
for (_name, feature_deps) in features.iter_mut() {
403+
feature_deps.retain(|feature_dep| {
404+
let feature_value = FeatureValue::new(InternedString::new(feature_dep));
405+
match feature_value {
406+
FeatureValue::Dep { dep_name } | FeatureValue::DepFeature { dep_name, .. } => {
407+
let k = &manifest::PackageName::new(dep_name.to_string()).unwrap();
408+
dep_name_set.contains(k)
409+
}
410+
_ => true,
411+
}
412+
});
413+
}
414+
}
370415

371416
fn map_deps(
372417
gctx: &GlobalContext,

tests/testsuite/publish.rs

Lines changed: 193 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1782,19 +1782,207 @@ fn publish_with_feature_point_diff_kinds_dep() {
17821782
.build();
17831783

17841784
p.cargo("publish --no-verify")
1785+
.env("RUSTFLAGS", "--cfg unix")
17851786
.replace_crates_io(registry.index_url())
1786-
.with_status(101)
17871787
.with_stderr(
17881788
"\
17891789
[UPDATING] [..]
17901790
[PACKAGING] foo v0.1.0 [..]
1791-
[ERROR] failed to prepare local package for uploading
1792-
1793-
Caused by:
1794-
feature `foo_feature` includes `dev-only/cat`, but `dev-only` is not a dependency
1791+
[UPDATING] [..]
1792+
[PACKAGED] [..] files, [..] ([..] compressed)
1793+
[UPLOADING] foo v0.1.0 [..]
1794+
[UPLOADED] foo v0.1.0 [..]
1795+
[NOTE] waiting [..]
1796+
You may press ctrl-c [..]
1797+
[PUBLISHED] foo v0.1.0 [..]
17951798
",
17961799
)
17971800
.run();
1801+
1802+
publish::validate_upload_with_contents(
1803+
r#"
1804+
{
1805+
"authors": [],
1806+
"badges": {},
1807+
"categories": [],
1808+
"deps": [
1809+
{
1810+
"default_features": true,
1811+
"features": [
1812+
"cat"
1813+
],
1814+
"kind": "normal",
1815+
"name": "normal-and-dev",
1816+
"optional": false,
1817+
"target": null,
1818+
"version_req": "^1.0"
1819+
},
1820+
{
1821+
"default_features": true,
1822+
"features": [
1823+
"cat"
1824+
],
1825+
"kind": "normal",
1826+
"name": "normal-only",
1827+
"optional": false,
1828+
"target": null,
1829+
"version_req": "^1.0"
1830+
},
1831+
{
1832+
"default_features": true,
1833+
"features": [
1834+
"cat"
1835+
],
1836+
"kind": "dev",
1837+
"name": "normal-and-dev",
1838+
"optional": false,
1839+
"target": null,
1840+
"version_req": "^1.0"
1841+
},
1842+
{
1843+
"default_features": true,
1844+
"features": [
1845+
"cat"
1846+
],
1847+
"kind": "build",
1848+
"name": "build-only",
1849+
"optional": false,
1850+
"target": null,
1851+
"version_req": "^1.0"
1852+
},
1853+
{
1854+
"default_features": true,
1855+
"features": [
1856+
"cat"
1857+
],
1858+
"kind": "normal",
1859+
"name": "target-normal-and-dev",
1860+
"optional": false,
1861+
"target": "cfg(unix)",
1862+
"version_req": "^1.0"
1863+
},
1864+
{
1865+
"default_features": true,
1866+
"features": [
1867+
"cat"
1868+
],
1869+
"kind": "normal",
1870+
"name": "target-normal-only",
1871+
"optional": false,
1872+
"target": "cfg(unix)",
1873+
"version_req": "^1.0"
1874+
},
1875+
{
1876+
"default_features": true,
1877+
"features": [
1878+
"cat"
1879+
],
1880+
"kind": "build",
1881+
"name": "target-build-only",
1882+
"optional": false,
1883+
"target": "cfg(unix)",
1884+
"version_req": "^1.0"
1885+
},
1886+
{
1887+
"default_features": true,
1888+
"features": [
1889+
"cat"
1890+
],
1891+
"kind": "dev",
1892+
"name": "target-normal-and-dev",
1893+
"optional": false,
1894+
"target": "cfg(unix)",
1895+
"version_req": "^1.0"
1896+
}
1897+
],
1898+
"description": "foo",
1899+
"documentation": "foo",
1900+
"features": {
1901+
"foo_feature": [
1902+
"normal-only/cat",
1903+
"build-only/cat",
1904+
"normal-and-dev/cat",
1905+
"target-normal-only/cat",
1906+
"target-build-only/cat",
1907+
"target-normal-and-dev/cat"
1908+
]
1909+
},
1910+
"homepage": "foo",
1911+
"keywords": [],
1912+
"license": "MIT",
1913+
"license_file": null,
1914+
"links": null,
1915+
"name": "foo",
1916+
"readme": null,
1917+
"readme_file": null,
1918+
"repository": "foo",
1919+
"rust_version": null,
1920+
"vers": "0.1.0"
1921+
}
1922+
"#,
1923+
"foo-0.1.0.crate",
1924+
&["Cargo.lock", "Cargo.toml", "Cargo.toml.orig", "src/main.rs"],
1925+
&[(
1926+
"Cargo.toml",
1927+
&format!(
1928+
r#"{}
1929+
[package]
1930+
edition = "2015"
1931+
name = "foo"
1932+
version = "0.1.0"
1933+
authors = []
1934+
description = "foo"
1935+
homepage = "foo"
1936+
documentation = "foo"
1937+
license = "MIT"
1938+
repository = "foo"
1939+
1940+
[dependencies.normal-and-dev]
1941+
version = "1.0"
1942+
features = ["cat"]
1943+
1944+
[dependencies.normal-only]
1945+
version = "1.0"
1946+
features = ["cat"]
1947+
1948+
[dev-dependencies.normal-and-dev]
1949+
version = "1.0"
1950+
features = ["cat"]
1951+
1952+
[build-dependencies.build-only]
1953+
version = "1.0"
1954+
features = ["cat"]
1955+
1956+
[features]
1957+
foo_feature = [
1958+
"normal-only/cat",
1959+
"build-only/cat",
1960+
"normal-and-dev/cat",
1961+
"target-normal-only/cat",
1962+
"target-build-only/cat",
1963+
"target-normal-and-dev/cat",
1964+
]
1965+
1966+
[target."cfg(unix)".dependencies.target-normal-and-dev]
1967+
version = "1.0"
1968+
features = ["cat"]
1969+
1970+
[target."cfg(unix)".dependencies.target-normal-only]
1971+
version = "1.0"
1972+
features = ["cat"]
1973+
1974+
[target."cfg(unix)".build-dependencies.target-build-only]
1975+
version = "1.0"
1976+
features = ["cat"]
1977+
1978+
[target."cfg(unix)".dev-dependencies.target-normal-and-dev]
1979+
version = "1.0"
1980+
features = ["cat"]
1981+
"#,
1982+
cargo::core::package::MANIFEST_PREAMBLE
1983+
),
1984+
)],
1985+
);
17981986
}
17991987
#[cargo_test]
18001988
fn credentials_ambiguous_filename() {

0 commit comments

Comments
 (0)