Skip to content

Commit 1d18b6b

Browse files
committed
Fork StringOrBool into new TomlPackageBuild type and update manifest.schema.json
1 parent 72a657a commit 1d18b6b

File tree

5 files changed

+69
-25
lines changed

5 files changed

+69
-25
lines changed

crates/cargo-util-schemas/manifest.schema.json

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@
269269
"build": {
270270
"anyOf": [
271271
{
272-
"$ref": "#/$defs/StringOrBool"
272+
"$ref": "#/$defs/TomlPackageBuild"
273273
},
274274
{
275275
"type": "null"
@@ -540,13 +540,15 @@
540540
}
541541
]
542542
},
543-
"StringOrBool": {
543+
"TomlPackageBuild": {
544544
"anyOf": [
545545
{
546-
"type": "string"
546+
"description": "If build scripts are disabled or enabled.\n If true, `build.rs` in the root folder will be the build script.",
547+
"type": "boolean"
547548
},
548549
{
549-
"type": "boolean"
550+
"description": "Path of Build Script if there's just one script.",
551+
"type": "string"
550552
}
551553
]
552554
},
@@ -596,6 +598,16 @@
596598
}
597599
]
598600
},
601+
"StringOrBool": {
602+
"anyOf": [
603+
{
604+
"type": "string"
605+
},
606+
{
607+
"type": "boolean"
608+
}
609+
]
610+
},
599611
"TomlValue": true,
600612
"TomlTarget": {
601613
"type": "object",

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

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ pub struct TomlPackage {
182182
pub name: Option<PackageName>,
183183
pub version: Option<InheritableSemverVersion>,
184184
pub authors: Option<InheritableVecString>,
185-
pub build: Option<StringOrBool>,
185+
pub build: Option<TomlPackageBuild>,
186186
pub metabuild: Option<StringOrVec>,
187187
pub default_target: Option<String>,
188188
pub forced_target: Option<String>,
@@ -257,9 +257,9 @@ impl TomlPackage {
257257
pub fn normalized_build(&self) -> Result<Option<&String>, UnresolvedError> {
258258
let build = self.build.as_ref().ok_or(UnresolvedError)?;
259259
match build {
260-
StringOrBool::Bool(false) => Ok(None),
261-
StringOrBool::Bool(true) => Err(UnresolvedError),
262-
StringOrBool::String(value) => Ok(Some(value)),
260+
TomlPackageBuild::Auto(false) => Ok(None),
261+
TomlPackageBuild::Auto(true) => Err(UnresolvedError),
262+
TomlPackageBuild::SingleScript(value) => Ok(Some(value)),
263263
}
264264
}
265265

@@ -1700,6 +1700,30 @@ impl<'de> Deserialize<'de> for StringOrBool {
17001700
}
17011701
}
17021702

1703+
#[derive(Clone, Debug, Serialize, Eq, PartialEq)]
1704+
#[serde(untagged)]
1705+
#[cfg_attr(feature = "unstable-schema", derive(schemars::JsonSchema))]
1706+
pub enum TomlPackageBuild {
1707+
/// If build scripts are disabled or enabled.
1708+
/// If true, `build.rs` in the root folder will be the build script.
1709+
Auto(bool),
1710+
1711+
/// Path of Build Script if there's just one script.
1712+
SingleScript(String),
1713+
}
1714+
1715+
impl<'de> Deserialize<'de> for TomlPackageBuild {
1716+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1717+
where
1718+
D: de::Deserializer<'de>,
1719+
{
1720+
UntaggedEnumVisitor::new()
1721+
.bool(|b| Ok(TomlPackageBuild::Auto(b)))
1722+
.string(|s| Ok(TomlPackageBuild::SingleScript(s.to_owned())))
1723+
.deserialize(deserializer)
1724+
}
1725+
}
1726+
17031727
#[derive(PartialEq, Clone, Debug, Serialize)]
17041728
#[serde(untagged)]
17051729
#[cfg_attr(feature = "unstable-schema", derive(schemars::JsonSchema))]

src/cargo/ops/vendor.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use crate::util::{try_canonicalize, CargoResult, GlobalContext};
1212
use anyhow::{bail, Context as _};
1313
use cargo_util::{paths, Sha256};
1414
use cargo_util_schemas::core::SourceKind;
15+
use cargo_util_schemas::manifest::TomlPackageBuild;
1516
use serde::Serialize;
1617
use walkdir::WalkDir;
1718

@@ -513,7 +514,8 @@ fn prepare_toml_for_vendor(
513514
.package
514515
.as_mut()
515516
.expect("venedored manifests must have packages");
516-
if let Some(cargo_util_schemas::manifest::StringOrBool::String(path)) = &package.build {
517+
// Validates if build script file exists. If not, warn and ignore.
518+
if let Some(TomlPackageBuild::SingleScript(path)) = &package.build {
517519
let path = paths::normalize_path(Path::new(path));
518520
let included = packaged_files.contains(&path);
519521
let build = if included {
@@ -522,13 +524,13 @@ fn prepare_toml_for_vendor(
522524
.into_string()
523525
.map_err(|_err| anyhow::format_err!("non-UTF8 `package.build`"))?;
524526
let path = crate::util::toml::normalize_path_string_sep(path);
525-
cargo_util_schemas::manifest::StringOrBool::String(path)
527+
TomlPackageBuild::SingleScript(path)
526528
} else {
527529
gctx.shell().warn(format!(
528530
"ignoring `package.build` as `{}` is not included in the published package",
529531
path.display()
530532
))?;
531-
cargo_util_schemas::manifest::StringOrBool::Bool(false)
533+
TomlPackageBuild::Auto(false)
532534
};
533535
package.build = Some(build);
534536
}

src/cargo/util/toml/mod.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use cargo_platform::Platform;
1313
use cargo_util::paths;
1414
use cargo_util_schemas::manifest::{
1515
self, PackageName, PathBaseName, TomlDependency, TomlDetailedDependency, TomlManifest,
16-
TomlWorkspace,
16+
TomlPackageBuild, TomlWorkspace,
1717
};
1818
use cargo_util_schemas::manifest::{RustVersion, StringOrBool};
1919
use itertools::Itertools;
@@ -670,7 +670,7 @@ fn normalize_package_toml<'a>(
670670
.transpose()?
671671
.map(manifest::InheritableField::Value);
672672
let build = if is_embedded {
673-
Some(StringOrBool::Bool(false))
673+
Some(TomlPackageBuild::Auto(false))
674674
} else {
675675
targets::normalize_build(original_package.build.as_ref(), package_root)
676676
};
@@ -2885,7 +2885,8 @@ fn prepare_toml_for_publish(
28852885

28862886
let mut package = me.package().unwrap().clone();
28872887
package.workspace = None;
2888-
if let Some(StringOrBool::String(path)) = &package.build {
2888+
// Validates if build script file exists. If not, warn and ignore.
2889+
if let Some(TomlPackageBuild::SingleScript(path)) = &package.build {
28892890
let path = Path::new(path).to_path_buf();
28902891
let included = packaged_files.map(|i| i.contains(&path)).unwrap_or(true);
28912892
let build = if included {
@@ -2894,13 +2895,13 @@ fn prepare_toml_for_publish(
28942895
.into_string()
28952896
.map_err(|_err| anyhow::format_err!("non-UTF8 `package.build`"))?;
28962897
let path = normalize_path_string_sep(path);
2897-
StringOrBool::String(path)
2898+
TomlPackageBuild::SingleScript(path)
28982899
} else {
28992900
ws.gctx().shell().warn(format!(
29002901
"ignoring `package.build` as `{}` is not included in the published package",
29012902
path.display()
29022903
))?;
2903-
StringOrBool::Bool(false)
2904+
TomlPackageBuild::Auto(false)
29042905
};
29052906
package.build = Some(build);
29062907
}

src/cargo/util/toml/targets.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ use std::path::{Path, PathBuf};
1717
use anyhow::Context as _;
1818
use cargo_util::paths;
1919
use cargo_util_schemas::manifest::{
20-
PathValue, StringOrBool, StringOrVec, TomlBenchTarget, TomlBinTarget, TomlExampleTarget,
21-
TomlLibTarget, TomlManifest, TomlTarget, TomlTestTarget,
20+
PathValue, StringOrVec, TomlBenchTarget, TomlBinTarget, TomlExampleTarget, TomlLibTarget,
21+
TomlManifest, TomlPackageBuild, TomlTarget, TomlTestTarget,
2222
};
2323

2424
use crate::core::compiler::rustdoc::RustdocScrapeExamples;
@@ -1076,29 +1076,34 @@ Cargo doesn't know which to use because multiple target files found at `{}` and
10761076

10771077
/// Returns the path to the build script if one exists for this crate.
10781078
#[tracing::instrument(skip_all)]
1079-
pub fn normalize_build(build: Option<&StringOrBool>, package_root: &Path) -> Option<StringOrBool> {
1079+
pub fn normalize_build(
1080+
build: Option<&TomlPackageBuild>,
1081+
package_root: &Path,
1082+
) -> Option<TomlPackageBuild> {
10801083
const BUILD_RS: &str = "build.rs";
10811084
match build {
10821085
None => {
10831086
// If there is a `build.rs` file next to the `Cargo.toml`, assume it is
10841087
// a build script.
10851088
let build_rs = package_root.join(BUILD_RS);
10861089
if build_rs.is_file() {
1087-
Some(StringOrBool::String(BUILD_RS.to_owned()))
1090+
Some(TomlPackageBuild::SingleScript(BUILD_RS.to_owned()))
10881091
} else {
1089-
Some(StringOrBool::Bool(false))
1092+
Some(TomlPackageBuild::Auto(false))
10901093
}
10911094
}
10921095
// Explicitly no build script.
1093-
Some(StringOrBool::Bool(false)) => build.cloned(),
1094-
Some(StringOrBool::String(build_file)) => {
1096+
Some(TomlPackageBuild::Auto(false)) => build.cloned(),
1097+
Some(TomlPackageBuild::SingleScript(build_file)) => {
10951098
let build_file = paths::normalize_path(Path::new(build_file));
10961099
let build = build_file.into_os_string().into_string().expect(
10971100
"`build_file` started as a String and `normalize_path` shouldn't have changed that",
10981101
);
1099-
Some(StringOrBool::String(build))
1102+
Some(TomlPackageBuild::SingleScript(build))
1103+
}
1104+
Some(TomlPackageBuild::Auto(true)) => {
1105+
Some(TomlPackageBuild::SingleScript(BUILD_RS.to_owned()))
11001106
}
1101-
Some(StringOrBool::Bool(true)) => Some(StringOrBool::String(BUILD_RS.to_owned())),
11021107
}
11031108
}
11041109

0 commit comments

Comments
 (0)