Skip to content

Commit 06a5714

Browse files
committed
fix(toml): Warn, rather than fail publish, if targets are excluded
This could offer performance gains when parsing a published manifest since the targets don't need to be discovered. To see this, we'd first need to stop discovering potential targets even when it isn't needed.
1 parent 1e60477 commit 06a5714

File tree

9 files changed

+500
-90
lines changed

9 files changed

+500
-90
lines changed

src/cargo/util/toml/mod.rs

Lines changed: 85 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ fn resolve_toml(
264264
manifest_file: &Path,
265265
gctx: &GlobalContext,
266266
warnings: &mut Vec<String>,
267-
_errors: &mut Vec<String>,
267+
errors: &mut Vec<String>,
268268
) -> CargoResult<manifest::TomlManifest> {
269269
if let Some(workspace) = &original_toml.workspace {
270270
if workspace.resolver.as_deref() == Some("3") {
@@ -277,11 +277,11 @@ fn resolve_toml(
277277
package: None,
278278
project: None,
279279
profile: original_toml.profile.clone(),
280-
lib: original_toml.lib.clone(),
281-
bin: original_toml.bin.clone(),
282-
example: original_toml.example.clone(),
283-
test: original_toml.test.clone(),
284-
bench: original_toml.bench.clone(),
280+
lib: None,
281+
bin: None,
282+
example: None,
283+
test: None,
284+
bench: None,
285285
dependencies: None,
286286
dev_dependencies: None,
287287
dev_dependencies2: None,
@@ -318,6 +318,47 @@ fn resolve_toml(
318318
});
319319
resolved_toml.package = Some(resolved_package);
320320

321+
resolved_toml.lib = targets::resolve_lib(
322+
original_toml.lib.as_ref(),
323+
package_root,
324+
&original_package.name,
325+
edition,
326+
warnings,
327+
)?;
328+
resolved_toml.bin = Some(targets::resolve_bins(
329+
original_toml.bin.as_ref(),
330+
package_root,
331+
&original_package.name,
332+
edition,
333+
original_package.autobins,
334+
warnings,
335+
resolved_toml.lib.is_some(),
336+
)?);
337+
resolved_toml.example = Some(targets::resolve_examples(
338+
original_toml.example.as_ref(),
339+
package_root,
340+
edition,
341+
original_package.autoexamples,
342+
warnings,
343+
errors,
344+
)?);
345+
resolved_toml.test = Some(targets::resolve_tests(
346+
original_toml.test.as_ref(),
347+
package_root,
348+
edition,
349+
original_package.autotests,
350+
warnings,
351+
errors,
352+
)?);
353+
resolved_toml.bench = Some(targets::resolve_benches(
354+
original_toml.bench.as_ref(),
355+
package_root,
356+
edition,
357+
original_package.autobenches,
358+
warnings,
359+
errors,
360+
)?);
361+
321362
let activated_opt_deps = resolved_toml
322363
.features
323364
.as_ref()
@@ -519,10 +560,10 @@ fn resolve_package_toml<'a>(
519560
.map(manifest::InheritableField::Value),
520561
workspace: original_package.workspace.clone(),
521562
im_a_teapot: original_package.im_a_teapot.clone(),
522-
autobins: original_package.autobins.clone(),
523-
autoexamples: original_package.autoexamples.clone(),
524-
autotests: original_package.autotests.clone(),
525-
autobenches: original_package.autobenches.clone(),
563+
autobins: Some(false),
564+
autoexamples: Some(false),
565+
autotests: Some(false),
566+
autobenches: Some(false),
526567
default_run: original_package.default_run.clone(),
527568
description: original_package
528569
.description
@@ -1149,8 +1190,8 @@ fn to_real_manifest(
11491190
// If we have a lib with no path, use the inferred lib or else the package name.
11501191
let targets = to_targets(
11511192
&features,
1193+
&original_toml,
11521194
&resolved_toml,
1153-
package_name,
11541195
package_root,
11551196
edition,
11561197
&resolved_package.metabuild,
@@ -2520,14 +2561,14 @@ fn prepare_toml_for_publish(
25202561
}
25212562

25222563
let lib = if let Some(target) = &me.lib {
2523-
Some(prepare_target_for_publish(target, "library")?)
2564+
prepare_target_for_publish(target, included, "library", ws.gctx())?
25242565
} else {
25252566
None
25262567
};
2527-
let bin = prepare_targets_for_publish(me.bin.as_ref(), "binary")?;
2528-
let example = prepare_targets_for_publish(me.example.as_ref(), "example")?;
2529-
let test = prepare_targets_for_publish(me.test.as_ref(), "test")?;
2530-
let bench = prepare_targets_for_publish(me.bench.as_ref(), "benchmark")?;
2568+
let bin = prepare_targets_for_publish(me.bin.as_ref(), included, "binary", ws.gctx())?;
2569+
let example = prepare_targets_for_publish(me.example.as_ref(), included, "example", ws.gctx())?;
2570+
let test = prepare_targets_for_publish(me.test.as_ref(), included, "test", ws.gctx())?;
2571+
let bench = prepare_targets_for_publish(me.bench.as_ref(), included, "benchmark", ws.gctx())?;
25312572

25322573
let all = |_d: &manifest::TomlDependency| true;
25332574
let mut manifest = manifest::TomlManifest {
@@ -2685,31 +2726,51 @@ fn prepare_toml_for_publish(
26852726

26862727
fn prepare_targets_for_publish(
26872728
targets: Option<&Vec<manifest::TomlTarget>>,
2729+
included: &[PathBuf],
26882730
context: &str,
2731+
gctx: &GlobalContext,
26892732
) -> CargoResult<Option<Vec<manifest::TomlTarget>>> {
26902733
let Some(targets) = targets else {
26912734
return Ok(None);
26922735
};
26932736

26942737
let mut prepared = Vec::with_capacity(targets.len());
26952738
for target in targets {
2696-
let target = prepare_target_for_publish(target, context)?;
2739+
let Some(target) = prepare_target_for_publish(target, included, context, gctx)? else {
2740+
continue;
2741+
};
26972742
prepared.push(target);
26982743
}
26992744

2700-
Ok(Some(prepared))
2745+
if prepared.is_empty() {
2746+
Ok(None)
2747+
} else {
2748+
Ok(Some(prepared))
2749+
}
27012750
}
27022751

27032752
fn prepare_target_for_publish(
27042753
target: &manifest::TomlTarget,
2754+
included: &[PathBuf],
27052755
context: &str,
2706-
) -> CargoResult<manifest::TomlTarget> {
2707-
let mut target = target.clone();
2708-
if let Some(path) = target.path {
2709-
let path = normalize_path(&path.0);
2710-
target.path = Some(manifest::PathValue(normalize_path_sep(path, context)?));
2756+
gctx: &GlobalContext,
2757+
) -> CargoResult<Option<manifest::TomlTarget>> {
2758+
let path = target.path.as_ref().expect("previously resolved");
2759+
let path = normalize_path(&path.0);
2760+
if !included.contains(&path) {
2761+
let name = target.name.as_ref().expect("previously resolved");
2762+
gctx.shell().warn(format!(
2763+
"ignoring {context} `{name}` as `{}` is not included in the published package",
2764+
path.display()
2765+
))?;
2766+
return Ok(None);
27112767
}
2712-
Ok(target)
2768+
2769+
let mut target = target.clone();
2770+
let path = normalize_path_sep(path, context)?;
2771+
target.path = Some(manifest::PathValue(path.into()));
2772+
2773+
Ok(Some(target))
27132774
}
27142775

27152776
fn normalize_path_sep(path: PathBuf, context: &str) -> CargoResult<PathBuf> {

src/cargo/util/toml/targets.rs

Lines changed: 17 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ const DEFAULT_EXAMPLE_DIR_NAME: &'static str = "examples";
3434
#[tracing::instrument(skip_all)]
3535
pub(super) fn to_targets(
3636
features: &Features,
37+
original_toml: &TomlManifest,
3738
resolved_toml: &TomlManifest,
38-
package_name: &str,
3939
package_root: &Path,
4040
edition: Edition,
4141
metabuild: &Option<StringOrVec>,
@@ -44,79 +44,46 @@ pub(super) fn to_targets(
4444
) -> CargoResult<Vec<Target>> {
4545
let mut targets = Vec::new();
4646

47-
let has_lib;
48-
49-
let lib = resolve_lib(
50-
resolved_toml.lib.as_ref(),
51-
package_root,
52-
package_name,
53-
edition,
54-
warnings,
55-
)?;
5647
if let Some(target) = to_lib_target(
48+
original_toml.lib.as_ref(),
5749
resolved_toml.lib.as_ref(),
58-
lib.as_ref(),
5950
package_root,
6051
edition,
6152
warnings,
6253
)? {
6354
targets.push(target);
64-
has_lib = true;
65-
} else {
66-
has_lib = false;
6755
}
6856

6957
let package = resolved_toml
7058
.package
7159
.as_ref()
7260
.ok_or_else(|| anyhow::format_err!("manifest has no `package` (or `project`)"))?;
7361

74-
let bins = resolve_bins(
75-
resolved_toml.bin.as_ref(),
76-
package_root,
77-
package_name,
78-
edition,
79-
package.autobins,
80-
warnings,
81-
has_lib,
82-
)?;
8362
targets.extend(to_bin_targets(
8463
features,
85-
&bins,
64+
resolved_toml.bin.as_deref().unwrap_or_default(),
8665
package_root,
8766
edition,
8867
errors,
8968
)?);
9069

91-
let toml_examples = resolve_examples(
92-
resolved_toml.example.as_ref(),
70+
targets.extend(to_example_targets(
71+
resolved_toml.example.as_deref().unwrap_or_default(),
9372
package_root,
9473
edition,
95-
package.autoexamples,
96-
warnings,
97-
errors,
98-
)?;
99-
targets.extend(to_example_targets(&toml_examples, package_root, edition)?);
74+
)?);
10075

101-
let toml_tests = resolve_tests(
102-
resolved_toml.test.as_ref(),
76+
targets.extend(to_test_targets(
77+
resolved_toml.test.as_deref().unwrap_or_default(),
10378
package_root,
10479
edition,
105-
package.autotests,
106-
warnings,
107-
errors,
108-
)?;
109-
targets.extend(to_test_targets(&toml_tests, package_root, edition)?);
80+
)?);
11081

111-
let toml_benches = resolve_benches(
112-
resolved_toml.bench.as_ref(),
82+
targets.extend(to_bench_targets(
83+
resolved_toml.bench.as_deref().unwrap_or_default(),
11384
package_root,
11485
edition,
115-
package.autobenches,
116-
warnings,
117-
errors,
118-
)?;
119-
targets.extend(to_bench_targets(&toml_benches, package_root, edition)?);
86+
)?);
12087

12188
// processing the custom build script
12289
if let Some(custom_build) = package.resolved_build().expect("should be resolved") {
@@ -158,7 +125,7 @@ pub(super) fn to_targets(
158125
Ok(targets)
159126
}
160127

161-
fn resolve_lib(
128+
pub fn resolve_lib(
162129
original_lib: Option<&TomlLibTarget>,
163130
package_root: &Path,
164131
package_name: &str,
@@ -283,7 +250,7 @@ fn to_lib_target(
283250
Ok(Some(target))
284251
}
285252

286-
fn resolve_bins(
253+
pub fn resolve_bins(
287254
toml_bins: Option<&Vec<TomlBinTarget>>,
288255
package_root: &Path,
289256
package_name: &str,
@@ -409,7 +376,7 @@ fn legacy_bin_path(package_root: &Path, name: &str, has_lib: bool) -> Option<Pat
409376
None
410377
}
411378

412-
fn resolve_examples(
379+
pub fn resolve_examples(
413380
toml_examples: Option<&Vec<TomlExampleTarget>>,
414381
package_root: &Path,
415382
edition: Edition,
@@ -464,7 +431,7 @@ fn to_example_targets(
464431
Ok(result)
465432
}
466433

467-
fn resolve_tests(
434+
pub fn resolve_tests(
468435
toml_tests: Option<&Vec<TomlTestTarget>>,
469436
package_root: &Path,
470437
edition: Edition,
@@ -512,7 +479,7 @@ fn to_test_targets(
512479
Ok(result)
513480
}
514481

515-
fn resolve_benches(
482+
pub fn resolve_benches(
516483
toml_benches: Option<&Vec<TomlBenchTarget>>,
517484
package_root: &Path,
518485
edition: Edition,

tests/testsuite/artifact_dep.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2215,6 +2215,10 @@ name = "foo"
22152215
version = "0.1.0"
22162216
authors = []
22172217
build = false
2218+
autobins = false
2219+
autoexamples = false
2220+
autotests = false
2221+
autobenches = false
22182222
description = "foo"
22192223
homepage = "foo"
22202224
documentation = "foo"
@@ -2223,6 +2227,10 @@ license = "MIT"
22232227
repository = "foo"
22242228
resolver = "2"
22252229
2230+
[lib]
2231+
name = "foo"
2232+
path = "src/lib.rs"
2233+
22262234
[dependencies.bar]
22272235
version = "1.0"
22282236
artifact = ["bin"]

tests/testsuite/features2.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1704,11 +1704,19 @@ name = "a"
17041704
version = "0.1.0"
17051705
authors = ["Zzz"]
17061706
build = false
1707+
autobins = false
1708+
autoexamples = false
1709+
autotests = false
1710+
autobenches = false
17071711
description = "foo"
17081712
homepage = "https://example.com/"
17091713
readme = false
17101714
license = "MIT"
17111715
resolver = "2"
1716+
1717+
[lib]
1718+
name = "a"
1719+
path = "src/lib.rs"
17121720
"#,
17131721
cargo::core::manifest::MANIFEST_PREAMBLE
17141722
);

0 commit comments

Comments
 (0)