Skip to content

Commit e2e0fb4

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 f38fce5 commit e2e0fb4

File tree

9 files changed

+488
-91
lines changed

9 files changed

+488
-91
lines changed

src/cargo/util/toml/mod.rs

Lines changed: 95 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -263,14 +263,14 @@ fn resolve_toml(
263263
manifest_file: &Path,
264264
gctx: &GlobalContext,
265265
warnings: &mut Vec<String>,
266-
_errors: &mut Vec<String>,
266+
errors: &mut Vec<String>,
267267
) -> CargoResult<manifest::TomlManifest> {
268268
let mut resolved_toml = manifest::TomlManifest {
269269
cargo_features: original_toml.cargo_features.clone(),
270270
package: None,
271271
project: None,
272272
profile: original_toml.profile.clone(),
273-
lib: original_toml.lib.clone(),
273+
lib: None,
274274
bin: original_toml.bin.clone(),
275275
example: original_toml.example.clone(),
276276
test: original_toml.test.clone(),
@@ -301,6 +301,62 @@ fn resolve_toml(
301301
if let Some(original_package) = original_toml.package() {
302302
let resolved_package = resolve_package_toml(original_package, package_root, &inherit)?;
303303
resolved_toml.package = Some(resolved_package);
304+
let edition = if let Some(edition) = resolved_toml
305+
.package
306+
.as_ref()
307+
.expect("in `package` branch")
308+
.resolved_edition()
309+
.expect("previously resolved")
310+
{
311+
let edition: Edition = edition
312+
.parse()
313+
.with_context(|| "failed to parse the `edition` key")?;
314+
edition
315+
} else {
316+
let default_edition = Edition::default();
317+
default_edition
318+
};
319+
320+
resolved_toml.lib = targets::resolve_lib(
321+
original_toml.lib.as_ref(),
322+
package_root,
323+
&original_package.name,
324+
edition,
325+
warnings,
326+
)?;
327+
resolved_toml.bin = Some(targets::resolve_bins(
328+
original_toml.bin.as_ref(),
329+
package_root,
330+
&original_package.name,
331+
edition,
332+
original_package.autobins,
333+
warnings,
334+
resolved_toml.lib.is_some(),
335+
)?);
336+
resolved_toml.example = Some(targets::resolve_examples(
337+
original_toml.example.as_ref(),
338+
package_root,
339+
edition,
340+
original_package.autoexamples,
341+
warnings,
342+
errors,
343+
)?);
344+
resolved_toml.test = Some(targets::resolve_tests(
345+
original_toml.test.as_ref(),
346+
package_root,
347+
edition,
348+
original_package.autotests,
349+
warnings,
350+
errors,
351+
)?);
352+
resolved_toml.bench = Some(targets::resolve_benches(
353+
original_toml.bench.as_ref(),
354+
package_root,
355+
edition,
356+
original_package.autobenches,
357+
warnings,
358+
errors,
359+
)?);
304360

305361
resolved_toml.dependencies = resolve_dependencies(
306362
gctx,
@@ -453,10 +509,10 @@ fn resolve_package_toml<'a>(
453509
.map(manifest::InheritableField::Value),
454510
workspace: original_package.workspace.clone(),
455511
im_a_teapot: original_package.im_a_teapot.clone(),
456-
autobins: original_package.autobins.clone(),
457-
autoexamples: original_package.autoexamples.clone(),
458-
autotests: original_package.autotests.clone(),
459-
autobenches: original_package.autobenches.clone(),
512+
autobins: Some(false),
513+
autoexamples: Some(false),
514+
autotests: Some(false),
515+
autobenches: Some(false),
460516
default_run: original_package.default_run.clone(),
461517
description: original_package
462518
.description
@@ -1093,8 +1149,8 @@ fn to_real_manifest(
10931149
// If we have a lib with no path, use the inferred lib or else the package name.
10941150
let targets = to_targets(
10951151
&features,
1152+
&original_toml,
10961153
&resolved_toml,
1097-
package_name,
10981154
package_root,
10991155
edition,
11001156
&resolved_package.metabuild,
@@ -2471,14 +2527,14 @@ fn prepare_toml_for_publish(
24712527
}
24722528

24732529
let lib = if let Some(target) = &me.lib {
2474-
Some(prepare_target_for_publish(target, "library")?)
2530+
prepare_target_for_publish(target, included, "library", ws.gctx())?
24752531
} else {
24762532
None
24772533
};
2478-
let bin = prepare_targets_for_publish(me.bin.as_ref(), "binary")?;
2479-
let example = prepare_targets_for_publish(me.example.as_ref(), "example")?;
2480-
let test = prepare_targets_for_publish(me.test.as_ref(), "test")?;
2481-
let bench = prepare_targets_for_publish(me.bench.as_ref(), "benchmark")?;
2534+
let bin = prepare_targets_for_publish(me.bin.as_ref(), included, "binary", ws.gctx())?;
2535+
let example = prepare_targets_for_publish(me.example.as_ref(), included, "example", ws.gctx())?;
2536+
let test = prepare_targets_for_publish(me.test.as_ref(), included, "test", ws.gctx())?;
2537+
let bench = prepare_targets_for_publish(me.bench.as_ref(), included, "benchmark", ws.gctx())?;
24822538

24832539
let all = |_d: &manifest::TomlDependency| true;
24842540
let mut manifest = manifest::TomlManifest {
@@ -2636,40 +2692,53 @@ fn prepare_toml_for_publish(
26362692

26372693
fn prepare_targets_for_publish(
26382694
targets: Option<&Vec<manifest::TomlTarget>>,
2695+
included: &[String],
26392696
context: &str,
2697+
gctx: &GlobalContext,
26402698
) -> CargoResult<Option<Vec<manifest::TomlTarget>>> {
26412699
let Some(targets) = targets else {
26422700
return Ok(None);
26432701
};
26442702

26452703
let mut prepared = Vec::with_capacity(targets.len());
26462704
for target in targets {
2647-
let target = prepare_target_for_publish(target, context)?;
2705+
let Some(target) = prepare_target_for_publish(target, included, context, gctx)? else {
2706+
continue;
2707+
};
26482708
prepared.push(target);
26492709
}
26502710

2651-
Ok(Some(prepared))
2711+
if prepared.is_empty() {
2712+
Ok(None)
2713+
} else {
2714+
Ok(Some(prepared))
2715+
}
26522716
}
26532717

26542718
fn prepare_target_for_publish(
26552719
target: &manifest::TomlTarget,
2720+
included: &[String],
26562721
context: &str,
2657-
) -> CargoResult<manifest::TomlTarget> {
2658-
let mut target = target.clone();
2659-
if let Some(path) = target.path {
2660-
let path = normalize_path(&path.0);
2661-
target.path = Some(manifest::PathValue(normalize_path_sep(path, context)?));
2662-
}
2663-
Ok(target)
2664-
}
2665-
2666-
fn normalize_path_sep(path: PathBuf, context: &str) -> CargoResult<PathBuf> {
2722+
gctx: &GlobalContext,
2723+
) -> CargoResult<Option<manifest::TomlTarget>> {
2724+
let path = target.path.as_ref().expect("previously resolved");
2725+
let path = normalize_path(&path.0);
26672726
let path = path
26682727
.into_os_string()
26692728
.into_string()
26702729
.map_err(|_err| anyhow::format_err!("non-UTF8 path for {context}"))?;
2671-
let path = normalize_path_string_sep(path);
2672-
Ok(path.into())
2730+
if !included.contains(&path) {
2731+
let name = target.name.as_ref().expect("previously resolved");
2732+
gctx.shell().warn(format!(
2733+
"ignoring {context} `{name}` as `{path}` is not included in the published package",
2734+
))?;
2735+
return Ok(None);
2736+
}
2737+
2738+
let mut target = target.clone();
2739+
target.path = Some(manifest::PathValue(normalize_path_string_sep(path).into()));
2740+
2741+
Ok(Some(target))
26732742
}
26742743

26752744
fn normalize_path_string_sep(path: String) -> String {

src/cargo/util/toml/targets.rs

Lines changed: 15 additions & 52 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,84 +44,47 @@ 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(),
93-
package_root,
94-
edition,
95-
package.autoexamples,
96-
warnings,
97-
errors,
98-
)?;
9970
targets.extend(to_example_targets(
100-
&toml_examples,
71+
resolved_toml.example.as_deref().unwrap_or_default(),
10172
package_root,
10273
edition,
10374
warnings,
10475
)?);
10576

106-
let toml_tests = resolve_tests(
107-
resolved_toml.test.as_ref(),
77+
targets.extend(to_test_targets(
78+
resolved_toml.test.as_deref().unwrap_or_default(),
10879
package_root,
10980
edition,
110-
package.autotests,
111-
warnings,
112-
errors,
113-
)?;
114-
targets.extend(to_test_targets(&toml_tests, package_root, edition)?);
81+
)?);
11582

116-
let toml_benches = resolve_benches(
117-
resolved_toml.bench.as_ref(),
83+
targets.extend(to_bench_targets(
84+
resolved_toml.bench.as_deref().unwrap_or_default(),
11885
package_root,
11986
edition,
120-
package.autobenches,
121-
warnings,
122-
errors,
123-
)?;
124-
targets.extend(to_bench_targets(&toml_benches, package_root, edition)?);
87+
)?);
12588

12689
// processing the custom build script
12790
if let Some(custom_build) = package.resolved_build().expect("should be resolved") {
@@ -163,7 +126,7 @@ pub(super) fn to_targets(
163126
Ok(targets)
164127
}
165128

166-
fn resolve_lib(
129+
pub fn resolve_lib(
167130
original_lib: Option<&TomlLibTarget>,
168131
package_root: &Path,
169132
package_name: &str,
@@ -286,7 +249,7 @@ fn to_lib_target(
286249
Ok(Some(target))
287250
}
288251

289-
fn resolve_bins(
252+
pub fn resolve_bins(
290253
toml_bins: Option<&Vec<TomlBinTarget>>,
291254
package_root: &Path,
292255
package_name: &str,
@@ -412,7 +375,7 @@ fn legacy_bin_path(package_root: &Path, name: &str, has_lib: bool) -> Option<Pat
412375
None
413376
}
414377

415-
fn resolve_examples(
378+
pub fn resolve_examples(
416379
toml_examples: Option<&Vec<TomlExampleTarget>>,
417380
package_root: &Path,
418381
edition: Edition,
@@ -469,7 +432,7 @@ fn to_example_targets(
469432
Ok(result)
470433
}
471434

472-
fn resolve_tests(
435+
pub fn resolve_tests(
473436
toml_tests: Option<&Vec<TomlTestTarget>>,
474437
package_root: &Path,
475438
edition: Edition,
@@ -517,7 +480,7 @@ fn to_test_targets(
517480
Ok(result)
518481
}
519482

520-
fn resolve_benches(
483+
pub fn resolve_benches(
521484
toml_benches: Option<&Vec<TomlBenchTarget>>,
522485
package_root: &Path,
523486
edition: Edition,

tests/testsuite/artifact_dep.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2165,6 +2165,10 @@ name = "foo"
21652165
version = "0.1.0"
21662166
authors = []
21672167
build = false
2168+
autobins = false
2169+
autoexamples = false
2170+
autotests = false
2171+
autobenches = false
21682172
description = "foo"
21692173
homepage = "foo"
21702174
documentation = "foo"
@@ -2173,6 +2177,10 @@ license = "MIT"
21732177
repository = "foo"
21742178
resolver = "2"
21752179
2180+
[lib]
2181+
name = "foo"
2182+
path = "src/lib.rs"
2183+
21762184
[dependencies.bar]
21772185
version = "1.0"
21782186
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)