Skip to content

Commit 22bbc95

Browse files
committed
Auto merge of #12995 - linyihai:issue_11383, r=weihanglo
Exited with hard error when custom build file no existence or not in package ## What does this PR try to resolve? Fixed #11383 ## How should we test and review this PR? Add test `build_script_outside_pkg_root`, this will check `custom_build.rs` existence and whether in the package root, if not then exited with a hard error ## Additional information The code just handle the `custom build` target that i know how to test it. Other target type is skipped.
2 parents 527b35e + 75aaa40 commit 22bbc95

File tree

2 files changed

+92
-0
lines changed

2 files changed

+92
-0
lines changed

src/cargo/ops/cargo_package.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::sync::Arc;
77
use std::task::Poll;
88

99
use crate::core::compiler::{BuildConfig, CompileMode, DefaultExecutor, Executor};
10+
use crate::core::manifest::Target;
1011
use crate::core::resolver::CliFeatures;
1112
use crate::core::{registry::PackageRegistry, resolver::HasDevUnits};
1213
use crate::core::{Feature, Shell, Verbosity, Workspace};
@@ -331,6 +332,23 @@ fn build_ar_list(
331332
warn_on_nonexistent_file(&pkg, &readme_path, "readme", &ws)?;
332333
}
333334
}
335+
336+
for t in pkg
337+
.manifest()
338+
.targets()
339+
.iter()
340+
.filter(|t| t.is_custom_build())
341+
{
342+
if let Some(custome_build_path) = t.src_path().path() {
343+
let abs_custome_build_path =
344+
paths::normalize_path(&pkg.root().join(custome_build_path));
345+
if !abs_custome_build_path.is_file() || !abs_custome_build_path.starts_with(pkg.root())
346+
{
347+
error_custom_build_file_not_in_package(pkg, &abs_custome_build_path, t)?;
348+
}
349+
}
350+
}
351+
334352
result.sort_unstable_by(|a, b| a.rel_path.cmp(&b.rel_path));
335353

336354
Ok(result)
@@ -405,6 +423,31 @@ fn warn_on_nonexistent_file(
405423
))
406424
}
407425

426+
fn error_custom_build_file_not_in_package(
427+
pkg: &Package,
428+
path: &Path,
429+
target: &Target,
430+
) -> CargoResult<Vec<ArchiveFile>> {
431+
let tip = {
432+
let description_name = target.description_named();
433+
if path.is_file() {
434+
format!("the source file of {description_name} doesn't appear to be a path inside of the package.\n\
435+
It is at `{}`, whereas the root the package is `{}`.\n",
436+
path.display(), pkg.root().display()
437+
)
438+
} else {
439+
format!("the source file of {description_name} doesn't appear to exist.\n",)
440+
}
441+
};
442+
let msg = format!(
443+
"{}\
444+
This may cause issue during packaging, as modules resolution and resources included via macros are often relative to the path of source files.\n\
445+
Please update the `build` setting in the manifest at `{}` and point to a path inside the root of the package.",
446+
tip, pkg.manifest_path().display()
447+
);
448+
anyhow::bail!(msg)
449+
}
450+
408451
/// Construct `Cargo.lock` for the package to be published.
409452
fn build_lock(ws: &Workspace<'_>, orig_pkg: &Package) -> CargoResult<String> {
410453
let config = ws.config();

tests/testsuite/package.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3304,3 +3304,52 @@ fn init_and_add_inner_target(p: ProjectBuilder) -> ProjectBuilder {
33043304
.file("derp/target/foo.txt", "")
33053305
.file("derp/not_target/foo.txt", "")
33063306
}
3307+
3308+
#[cargo_test]
3309+
fn build_script_outside_pkg_root() {
3310+
let p = project()
3311+
.file(
3312+
"Cargo.toml",
3313+
r#"
3314+
[package]
3315+
name = "foo"
3316+
version = "0.0.1"
3317+
license = "MIT"
3318+
description = "foo"
3319+
authors = []
3320+
build = "../t_custom_build/custom_build.rs"
3321+
"#,
3322+
)
3323+
.file("src/main.rs", "fn main() {}")
3324+
.build();
3325+
let mut expect_msg = String::from("\
3326+
warning: manifest has no documentation, homepage or repository.
3327+
See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
3328+
error: the source file of build script doesn't appear to exist.
3329+
This may cause issue during packaging, as modules resolution and resources included via macros are often relative to the path of source files.
3330+
Please update the `build` setting in the manifest at `[CWD]/Cargo.toml` and point to a path inside the root of the package.
3331+
");
3332+
// custom_build.rs does not exist
3333+
p.cargo("package -l")
3334+
.with_status(101)
3335+
.with_stderr(&expect_msg)
3336+
.run();
3337+
3338+
// custom_build.rs outside the package root
3339+
let custom_build_root = paths::root().join("t_custom_build");
3340+
_ = fs::create_dir(&custom_build_root).unwrap();
3341+
_ = fs::write(&custom_build_root.join("custom_build.rs"), "fn main() {}");
3342+
expect_msg = format!(
3343+
"\
3344+
warning: manifest has no documentation, homepage or repository.
3345+
See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
3346+
error: the source file of build script doesn't appear to be a path inside of the package.
3347+
It is at `{}/t_custom_build/custom_build.rs`, whereas the root the package is `[CWD]`.
3348+
This may cause issue during packaging, as modules resolution and resources included via macros are often relative to the path of source files.
3349+
Please update the `build` setting in the manifest at `[CWD]/Cargo.toml` and point to a path inside the root of the package.
3350+
", paths::root().display());
3351+
p.cargo("package -l")
3352+
.with_status(101)
3353+
.with_stderr(&expect_msg)
3354+
.run();
3355+
}

0 commit comments

Comments
 (0)