Skip to content

Commit 1e60477

Browse files
committed
fix(toml): Warn, rather than fail publish, if build.rs is excluded
This could offer a minor performance gain when reading this manifest since the target doesn't need to be discovered.
1 parent 39f1a21 commit 1e60477

File tree

11 files changed

+119
-26
lines changed

11 files changed

+119
-26
lines changed

crates/cargo-util-schemas/src/manifest/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,15 @@ impl TomlPackage {
215215
self.authors.as_ref().map(|v| v.resolved()).transpose()
216216
}
217217

218+
pub fn resolved_build(&self) -> Result<Option<&String>, UnresolvedError> {
219+
let readme = self.build.as_ref().ok_or(UnresolvedError)?;
220+
match readme {
221+
StringOrBool::Bool(false) => Ok(None),
222+
StringOrBool::Bool(true) => Err(UnresolvedError),
223+
StringOrBool::String(value) => Ok(Some(value)),
224+
}
225+
}
226+
218227
pub fn resolved_exclude(&self) -> Result<Option<&Vec<String>>, UnresolvedError> {
219228
self.exclude.as_ref().map(|v| v.resolved()).transpose()
220229
}

src/cargo/ops/cargo_package.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -689,7 +689,11 @@ fn tar(
689689

690690
let base_name = format!("{}-{}", pkg.name(), pkg.version());
691691
let base_path = Path::new(&base_name);
692-
let publish_pkg = prepare_for_publish(pkg, ws)?;
692+
let included = ar_files
693+
.iter()
694+
.map(|ar_file| ar_file.rel_path.clone())
695+
.collect::<Vec<_>>();
696+
let publish_pkg = prepare_for_publish(pkg, ws, &included)?;
693697

694698
let mut uncompressed_size = 0;
695699
for ar_file in ar_files {

src/cargo/util/toml/mod.rs

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,7 @@ fn resolve_package_toml<'a>(
494494
.map(|value| field_inherit_with(value, "authors", || inherit()?.authors()))
495495
.transpose()?
496496
.map(manifest::InheritableField::Value),
497-
build: original_package.build.clone(),
497+
build: targets::resolve_build(original_package.build.as_ref(), package_root),
498498
metabuild: original_package.metabuild.clone(),
499499
default_target: original_package.default_target.clone(),
500500
forced_target: original_package.forced_target.clone(),
@@ -1153,7 +1153,6 @@ fn to_real_manifest(
11531153
package_name,
11541154
package_root,
11551155
edition,
1156-
&resolved_package.build,
11571156
&resolved_package.metabuild,
11581157
warnings,
11591158
errors,
@@ -2360,10 +2359,15 @@ fn unused_dep_keys(
23602359
}
23612360
}
23622361

2363-
pub fn prepare_for_publish(me: &Package, ws: &Workspace<'_>) -> CargoResult<Package> {
2362+
pub fn prepare_for_publish(
2363+
me: &Package,
2364+
ws: &Workspace<'_>,
2365+
included: &[PathBuf],
2366+
) -> CargoResult<Package> {
23642367
let contents = me.manifest().contents();
23652368
let document = me.manifest().document();
2366-
let original_toml = prepare_toml_for_publish(me.manifest().resolved_toml(), ws, me.root())?;
2369+
let original_toml =
2370+
prepare_toml_for_publish(me.manifest().resolved_toml(), ws, me.root(), included)?;
23672371
let resolved_toml = original_toml.clone();
23682372
let features = me.manifest().unstable_features().clone();
23692373
let workspace_config = me.manifest().workspace_config().clone();
@@ -2395,6 +2399,7 @@ fn prepare_toml_for_publish(
23952399
me: &manifest::TomlManifest,
23962400
ws: &Workspace<'_>,
23972401
package_root: &Path,
2402+
included: &[PathBuf],
23982403
) -> CargoResult<manifest::TomlManifest> {
23992404
let gctx = ws.gctx();
24002405

@@ -2411,11 +2416,21 @@ fn prepare_toml_for_publish(
24112416
package.workspace = None;
24122417
if let Some(StringOrBool::String(path)) = &package.build {
24132418
let path = paths::normalize_path(Path::new(path));
2414-
let path = path
2415-
.into_os_string()
2416-
.into_string()
2417-
.map_err(|_err| anyhow::format_err!("non-UTF8 `package.build`"))?;
2418-
package.build = Some(StringOrBool::String(normalize_path_string_sep(path)));
2419+
let build = if included.contains(&path) {
2420+
let path = path
2421+
.into_os_string()
2422+
.into_string()
2423+
.map_err(|_err| anyhow::format_err!("non-UTF8 `package.build`"))?;
2424+
let path = normalize_path_string_sep(path);
2425+
StringOrBool::String(path)
2426+
} else {
2427+
ws.gctx().shell().warn(format!(
2428+
"ignoring `package.build` as `{}` is not included in the published package",
2429+
path.display()
2430+
))?;
2431+
StringOrBool::Bool(false)
2432+
};
2433+
package.build = Some(build);
24192434
}
24202435
let current_resolver = package
24212436
.resolver

src/cargo/util/toml/targets.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ pub(super) fn to_targets(
3838
package_name: &str,
3939
package_root: &Path,
4040
edition: Edition,
41-
custom_build: &Option<StringOrBool>,
4241
metabuild: &Option<StringOrVec>,
4342
warnings: &mut Vec<String>,
4443
errors: &mut Vec<String>,
@@ -120,10 +119,11 @@ pub(super) fn to_targets(
120119
targets.extend(to_bench_targets(&toml_benches, package_root, edition)?);
121120

122121
// processing the custom build script
123-
if let Some(custom_build) = maybe_custom_build(custom_build, package_root) {
122+
if let Some(custom_build) = package.resolved_build().expect("should be resolved") {
124123
if metabuild.is_some() {
125124
anyhow::bail!("cannot specify both `metabuild` and `build`");
126125
}
126+
let custom_build = Path::new(custom_build);
127127
let name = format!(
128128
"build-script-{}",
129129
custom_build
@@ -1072,22 +1072,22 @@ Cargo doesn't know which to use because multiple target files found at `{}` and
10721072
}
10731073

10741074
/// Returns the path to the build script if one exists for this crate.
1075-
fn maybe_custom_build(build: &Option<StringOrBool>, package_root: &Path) -> Option<PathBuf> {
1076-
let build_rs = package_root.join("build.rs");
1077-
match *build {
1078-
// Explicitly no build script.
1079-
Some(StringOrBool::Bool(false)) => None,
1080-
Some(StringOrBool::Bool(true)) => Some(build_rs),
1081-
Some(StringOrBool::String(ref s)) => Some(PathBuf::from(s)),
1075+
pub fn resolve_build(build: Option<&StringOrBool>, package_root: &Path) -> Option<StringOrBool> {
1076+
const BUILD_RS: &str = "build.rs";
1077+
match build {
10821078
None => {
10831079
// If there is a `build.rs` file next to the `Cargo.toml`, assume it is
10841080
// a build script.
1081+
let build_rs = package_root.join(BUILD_RS);
10851082
if build_rs.is_file() {
1086-
Some(build_rs)
1083+
Some(StringOrBool::String(BUILD_RS.to_owned()))
10871084
} else {
1088-
None
1085+
Some(StringOrBool::Bool(false))
10891086
}
10901087
}
1088+
// Explicitly no build script.
1089+
Some(StringOrBool::Bool(false)) | Some(StringOrBool::String(_)) => build.cloned(),
1090+
Some(StringOrBool::Bool(true)) => Some(StringOrBool::String(BUILD_RS.to_owned())),
10911091
}
10921092
}
10931093

tests/testsuite/artifact_dep.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2214,6 +2214,7 @@ edition = "2015"
22142214
name = "foo"
22152215
version = "0.1.0"
22162216
authors = []
2217+
build = false
22172218
description = "foo"
22182219
homepage = "foo"
22192220
documentation = "foo"

tests/testsuite/features2.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1703,6 +1703,7 @@ edition = "2015"
17031703
name = "a"
17041704
version = "0.1.0"
17051705
authors = ["Zzz"]
1706+
build = false
17061707
description = "foo"
17071708
homepage = "https://example.com/"
17081709
readme = false

tests/testsuite/features_namespaced.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -985,6 +985,7 @@ You may press ctrl-c [..]
985985
edition = "2015"
986986
name = "foo"
987987
version = "0.1.0"
988+
build = false
988989
description = "foo"
989990
homepage = "https://example.com/"
990991
readme = false
@@ -1104,6 +1105,7 @@ You may press ctrl-c [..]
11041105
edition = "2015"
11051106
name = "foo"
11061107
version = "0.1.0"
1108+
build = false
11071109
description = "foo"
11081110
homepage = "https://example.com/"
11091111
readme = false

tests/testsuite/inheritable_workspace_fields.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ rust-version = "1.60"
217217
name = "foo"
218218
version = "1.2.3"
219219
authors = ["Rustaceans"]
220+
build = false
220221
exclude = ["foo.txt"]
221222
include = [
222223
"bar.txt",
@@ -384,6 +385,7 @@ edition = "2015"
384385
name = "bar"
385386
version = "0.2.0"
386387
authors = []
388+
build = false
387389
readme = false
388390
389391
[dependencies.dep]
@@ -516,6 +518,7 @@ edition = "2015"
516518
name = "bar"
517519
version = "0.2.0"
518520
authors = []
521+
build = false
519522
readme = false
520523
521524
[dependencies.dep]
@@ -758,6 +761,7 @@ rust-version = "1.60"
758761
name = "bar"
759762
version = "1.2.3"
760763
authors = ["Rustaceans"]
764+
build = false
761765
exclude = ["foo.txt"]
762766
include = [
763767
"bar.txt",
@@ -930,6 +934,7 @@ edition = "2015"
930934
name = "bar"
931935
version = "0.2.0"
932936
authors = []
937+
build = false
933938
readme = false
934939
935940
[dependencies.dep]

0 commit comments

Comments
 (0)