feat: update depot version to 0.17.1 and enhance command execution with improved error handling and environment variable management
This commit is contained in:
Generated
+1
-1
@@ -418,7 +418,7 @@ checksum = "807800ff3288b621186fe0a8f3392c4652068257302709c24efd918c3dffcdc2"
|
||||
|
||||
[[package]]
|
||||
name = "depot"
|
||||
version = "0.17.0"
|
||||
version = "0.17.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"ar",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "depot"
|
||||
version = "0.17.0"
|
||||
version = "0.17.1"
|
||||
edition = "2024"
|
||||
|
||||
[lints.rust]
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
project(
|
||||
'depot',
|
||||
version: '0.17.0',
|
||||
version: '0.17.1',
|
||||
meson_version: '>=0.60.0',
|
||||
default_options: ['buildtype=release'],
|
||||
)
|
||||
|
||||
+294
-26
@@ -165,7 +165,10 @@ fn command_status_with_sh_fallback(
|
||||
) -> std::io::Result<std::process::ExitStatus> {
|
||||
match cmd.status() {
|
||||
Ok(status) => Ok(status),
|
||||
Err(err) if err.kind() == std::io::ErrorKind::PermissionDenied => {
|
||||
Err(err)
|
||||
if err.kind() == std::io::ErrorKind::PermissionDenied
|
||||
|| err.raw_os_error() == Some(26) =>
|
||||
{
|
||||
let program = cmd.get_program();
|
||||
let contents = fs::read(program);
|
||||
let is_script = contents.ok().is_some_and(|bytes| bytes.starts_with(b"#!"));
|
||||
@@ -261,7 +264,43 @@ fn parse_keep_list(metadata: &toml::Value) -> Vec<String> {
|
||||
}
|
||||
|
||||
fn current_process_env_vars() -> Vec<(String, String)> {
|
||||
std::env::vars().collect()
|
||||
const ALLOWED_ENV_VARS: &[&str] = &[
|
||||
"AR",
|
||||
"CARCH",
|
||||
"CBUILD",
|
||||
"CC",
|
||||
"CHOST",
|
||||
"CPP",
|
||||
"CROSS_COMPILE",
|
||||
"CROSS_PREFIX",
|
||||
"CFLAGS",
|
||||
"CXX",
|
||||
"CXXFLAGS",
|
||||
"DEPOT_ROOTFS",
|
||||
"DEPOT_SPECDIR",
|
||||
"DESTDIR",
|
||||
"LD",
|
||||
"LDFLAGS",
|
||||
"LTOFLAGS",
|
||||
"MAKEFLAGS",
|
||||
"NM",
|
||||
"PREFIX",
|
||||
"PYTHONDONTWRITEBYTECODE",
|
||||
"PYTHONNOUSERSITE",
|
||||
"RANLIB",
|
||||
"RUSTFLAGS",
|
||||
"SETUPTOOLS_USE_DISTUTILS",
|
||||
"STRIP",
|
||||
];
|
||||
|
||||
ALLOWED_ENV_VARS
|
||||
.iter()
|
||||
.filter_map(|key| {
|
||||
std::env::var(key)
|
||||
.ok()
|
||||
.map(|value| ((*key).to_string(), value))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn run_internal_command(command: InternalCommands) -> Result<()> {
|
||||
@@ -594,6 +633,28 @@ fn maybe_disable_tests_for_missing_deps(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn maybe_prompt_to_skip_tests_for_missing_requested_deps(
|
||||
pkg_spec: &mut package::PackageSpec,
|
||||
missing_test: &[String],
|
||||
reason: &str,
|
||||
) -> Result<bool> {
|
||||
if pkg_spec.build.flags.skip_tests
|
||||
|| !build_type_runs_automatic_tests(pkg_spec)
|
||||
|| missing_test.is_empty()
|
||||
{
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
ui::warn(format!("{reason}: {}", missing_test.join(", ")));
|
||||
if ui::prompt_yes_no("Continue without tests?", false)? {
|
||||
pkg_spec.build.flags.skip_tests = true;
|
||||
ui::warn("Tests will be skipped for this build.");
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
fn should_install_test_deps(pkg_spec: &package::PackageSpec, install_test_deps: bool) -> bool {
|
||||
install_test_deps && !pkg_spec.build.flags.skip_tests && !pkg_spec.dependencies.test.is_empty()
|
||||
}
|
||||
@@ -3380,27 +3441,33 @@ fn run_direct_install_request(
|
||||
})?;
|
||||
let db_path = config.installed_db_path(options.rootfs);
|
||||
|
||||
if staging_dir.is_none()
|
||||
&& (options.no_deps || !should_install_test_deps(&pkg_spec, options.install_test_deps))
|
||||
if staging_dir.is_none() {
|
||||
if options.no_deps && should_install_test_deps(&pkg_spec, options.install_test_deps) {
|
||||
let missing_test = deps::check_test_deps(&pkg_spec, &db_path)?;
|
||||
if !missing_test.is_empty()
|
||||
&& !maybe_prompt_to_skip_tests_for_missing_requested_deps(
|
||||
&mut pkg_spec,
|
||||
&missing_test,
|
||||
"Requested test dependencies are missing",
|
||||
)?
|
||||
{
|
||||
anyhow::bail!("Missing test dependencies: {}", missing_test.join(", "));
|
||||
}
|
||||
} else if options.no_deps || !should_install_test_deps(&pkg_spec, options.install_test_deps)
|
||||
{
|
||||
maybe_disable_tests_for_missing_deps(&mut pkg_spec, &db_path)?;
|
||||
}
|
||||
}
|
||||
|
||||
// Check dependencies and prompt for auto-install if needed
|
||||
if !options.no_deps {
|
||||
deps::print_dep_status(&pkg_spec, &db_path)?;
|
||||
|
||||
// Collect all missing dependencies (build + runtime)
|
||||
let missing = merge_missing_dependencies(
|
||||
let missing_required = merge_missing_dependencies(
|
||||
deps::check_build_deps(&pkg_spec, &db_path)?,
|
||||
deps::check_runtime_deps(&pkg_spec, &db_path)?,
|
||||
);
|
||||
let missing = if should_install_test_deps(&pkg_spec, options.install_test_deps) {
|
||||
merge_missing_dependencies(missing, deps::check_test_deps(&pkg_spec, &db_path)?)
|
||||
} else {
|
||||
missing
|
||||
};
|
||||
if !missing.is_empty() {
|
||||
if !missing_required.is_empty() {
|
||||
// Check for dependency cycles via DEPOT_DEPCHAIN env var
|
||||
let dep_chain = std::env::var("DEPOT_DEPCHAIN").unwrap_or_default();
|
||||
let chain_set: std::collections::HashSet<&str> =
|
||||
@@ -3414,8 +3481,11 @@ fn run_direct_install_request(
|
||||
);
|
||||
}
|
||||
|
||||
ui::warn(format!("Missing dependencies: {}", missing.join(", ")));
|
||||
if ui::prompt_package_action("dependency installation", &missing, true)? {
|
||||
ui::warn(format!(
|
||||
"Missing dependencies: {}",
|
||||
missing_required.join(", ")
|
||||
));
|
||||
if ui::prompt_package_action("dependency installation", &missing_required, true)? {
|
||||
// Build package index for fast lookups
|
||||
let pkg_index =
|
||||
index::PackageIndex::build_with_repo_dir(Some(config.repo_clone_dir.clone()));
|
||||
@@ -3428,7 +3498,7 @@ fn run_direct_install_request(
|
||||
};
|
||||
|
||||
let mut dep_spec_paths = Vec::new();
|
||||
for dep in missing {
|
||||
for dep in missing_required {
|
||||
// Use package index for O(1) lookup
|
||||
let candidate = pkg_index.find(&dep);
|
||||
|
||||
@@ -3465,9 +3535,81 @@ fn run_direct_install_request(
|
||||
deps::require_build_deps(&pkg_spec, &db_path)?;
|
||||
deps::require_runtime_deps(&pkg_spec, &db_path)?;
|
||||
if should_install_test_deps(&pkg_spec, options.install_test_deps) {
|
||||
let missing_test = deps::check_test_deps(&pkg_spec, &db_path)?;
|
||||
if !missing_test.is_empty() {
|
||||
let pkg_index =
|
||||
index::PackageIndex::build_with_repo_dir(Some(config.repo_clone_dir.clone()));
|
||||
let mut dep_spec_paths = Vec::new();
|
||||
let mut unavailable_test = Vec::new();
|
||||
for dep in &missing_test {
|
||||
if let Some(dep_spec_path) = pkg_index.find(dep) {
|
||||
dep_spec_paths.push(dep_spec_path);
|
||||
} else {
|
||||
unavailable_test.push(dep.clone());
|
||||
}
|
||||
}
|
||||
|
||||
if !unavailable_test.is_empty()
|
||||
&& !maybe_prompt_to_skip_tests_for_missing_requested_deps(
|
||||
&mut pkg_spec,
|
||||
&unavailable_test,
|
||||
"Requested test dependencies could not be resolved",
|
||||
)?
|
||||
{
|
||||
anyhow::bail!("Missing test dependencies: {}", unavailable_test.join(", "));
|
||||
}
|
||||
|
||||
if !pkg_spec.build.flags.skip_tests && !dep_spec_paths.is_empty() {
|
||||
ui::warn(format!(
|
||||
"Missing test dependencies: {}",
|
||||
missing_test.join(", ")
|
||||
));
|
||||
if ui::prompt_package_action("dependency installation", &missing_test, true)? {
|
||||
ui::info(format!(
|
||||
"Installing test dependencies: {}",
|
||||
install_request_display(&dep_spec_paths)
|
||||
));
|
||||
let exe =
|
||||
std::env::current_exe().context("Failed to locate depot executable")?;
|
||||
run_install_command_with_program(
|
||||
&exe,
|
||||
&dep_spec_paths,
|
||||
options.rootfs,
|
||||
ChildInstallCommandOptions {
|
||||
no_deps: options.no_deps,
|
||||
assume_yes: false,
|
||||
no_flags: options.no_flags,
|
||||
cross_prefix: options.cross_prefix,
|
||||
clean: options.clean,
|
||||
install_test_deps: options.install_test_deps,
|
||||
install_context: None,
|
||||
dep_chain: None,
|
||||
},
|
||||
)?;
|
||||
} else if !maybe_prompt_to_skip_tests_for_missing_requested_deps(
|
||||
&mut pkg_spec,
|
||||
&missing_test,
|
||||
"Requested test dependencies were not installed",
|
||||
)? {
|
||||
anyhow::bail!("Aborted");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if should_install_test_deps(&pkg_spec, options.install_test_deps) {
|
||||
let missing_test = deps::check_test_deps(&pkg_spec, &db_path)?;
|
||||
if !missing_test.is_empty()
|
||||
&& !maybe_prompt_to_skip_tests_for_missing_requested_deps(
|
||||
&mut pkg_spec,
|
||||
&missing_test,
|
||||
"Requested test dependencies are still missing",
|
||||
)?
|
||||
{
|
||||
deps::require_test_deps(&pkg_spec, &db_path)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let cross_config = options
|
||||
.cross_prefix
|
||||
@@ -3717,24 +3859,33 @@ pub fn run(cli: Cli) -> Result<()> {
|
||||
})?;
|
||||
let db_path = config.installed_db_path(&cli.rootfs);
|
||||
|
||||
if cli.no_deps || !should_install_test_deps(&pkg_spec, install_test_deps) {
|
||||
if cli.no_deps && should_install_test_deps(&pkg_spec, install_test_deps) {
|
||||
let missing_test = deps::check_test_deps(&pkg_spec, &db_path)?;
|
||||
if !missing_test.is_empty()
|
||||
&& !maybe_prompt_to_skip_tests_for_missing_requested_deps(
|
||||
&mut pkg_spec,
|
||||
&missing_test,
|
||||
"Requested test dependencies are missing",
|
||||
)?
|
||||
{
|
||||
anyhow::bail!("Missing test dependencies: {}", missing_test.join(", "));
|
||||
}
|
||||
} else if cli.no_deps || !should_install_test_deps(&pkg_spec, install_test_deps) {
|
||||
maybe_disable_tests_for_missing_deps(&mut pkg_spec, &db_path)?;
|
||||
}
|
||||
|
||||
// Check build dependencies
|
||||
if !cli.no_deps {
|
||||
deps::print_dep_status(&pkg_spec, &db_path)?;
|
||||
let missing = merge_missing_dependencies(
|
||||
let missing_required = merge_missing_dependencies(
|
||||
deps::check_build_deps(&pkg_spec, &db_path)?,
|
||||
deps::check_runtime_deps(&pkg_spec, &db_path)?,
|
||||
);
|
||||
let missing = if should_install_test_deps(&pkg_spec, install_test_deps) {
|
||||
merge_missing_dependencies(missing, deps::check_test_deps(&pkg_spec, &db_path)?)
|
||||
} else {
|
||||
missing
|
||||
};
|
||||
if !missing.is_empty() {
|
||||
ui::warn(format!("Missing dependencies: {}", missing.join(", ")));
|
||||
if !missing_required.is_empty() {
|
||||
ui::warn(format!(
|
||||
"Missing dependencies: {}",
|
||||
missing_required.join(", ")
|
||||
));
|
||||
let local_sibling_root = spec_path
|
||||
.parent()
|
||||
.and_then(|p| p.parent())
|
||||
@@ -3742,7 +3893,7 @@ pub fn run(cli: Cli) -> Result<()> {
|
||||
let dep_plan = planner::build_dependency_install_plan(
|
||||
&config,
|
||||
&cli.rootfs,
|
||||
&missing,
|
||||
&missing_required,
|
||||
planner::PlannerOptions {
|
||||
assume_yes: cli.yes,
|
||||
prefer_binary: config.repo_settings.prefer_binary,
|
||||
@@ -3751,7 +3902,11 @@ pub fn run(cli: Cli) -> Result<()> {
|
||||
},
|
||||
)?;
|
||||
print_plan_summary(&dep_plan);
|
||||
if !ui::prompt_package_action("dependency installation", &missing, true)? {
|
||||
if !ui::prompt_package_action(
|
||||
"dependency installation",
|
||||
&missing_required,
|
||||
true,
|
||||
)? {
|
||||
anyhow::bail!("Aborted");
|
||||
}
|
||||
if cli.dry_run {
|
||||
@@ -3775,8 +3930,85 @@ pub fn run(cli: Cli) -> Result<()> {
|
||||
deps::require_build_deps(&pkg_spec, &db_path)?;
|
||||
deps::require_runtime_deps(&pkg_spec, &db_path)?;
|
||||
if should_install_test_deps(&pkg_spec, install_test_deps) {
|
||||
let missing_test = deps::check_test_deps(&pkg_spec, &db_path)?;
|
||||
if !missing_test.is_empty() {
|
||||
let local_sibling_root = spec_path
|
||||
.parent()
|
||||
.and_then(|p| p.parent())
|
||||
.map(Path::to_path_buf);
|
||||
let dep_plan = match planner::build_dependency_install_plan(
|
||||
&config,
|
||||
&cli.rootfs,
|
||||
&missing_test,
|
||||
planner::PlannerOptions {
|
||||
assume_yes: cli.yes,
|
||||
prefer_binary: config.repo_settings.prefer_binary,
|
||||
local_sibling_root,
|
||||
include_test_deps: install_test_deps,
|
||||
},
|
||||
) {
|
||||
Ok(plan) => plan,
|
||||
Err(err)
|
||||
if maybe_prompt_to_skip_tests_for_missing_requested_deps(
|
||||
&mut pkg_spec,
|
||||
&missing_test,
|
||||
"Requested test dependencies could not be resolved",
|
||||
)? =>
|
||||
{
|
||||
planner::ExecutionPlan { steps: Vec::new() }
|
||||
}
|
||||
Err(err) => return Err(err),
|
||||
};
|
||||
|
||||
if !pkg_spec.build.flags.skip_tests && !dep_plan.steps.is_empty() {
|
||||
ui::warn(format!(
|
||||
"Missing test dependencies: {}",
|
||||
missing_test.join(", ")
|
||||
));
|
||||
print_plan_summary(&dep_plan);
|
||||
if !ui::prompt_package_action(
|
||||
"dependency installation",
|
||||
&missing_test,
|
||||
true,
|
||||
)? {
|
||||
if !maybe_prompt_to_skip_tests_for_missing_requested_deps(
|
||||
&mut pkg_spec,
|
||||
&missing_test,
|
||||
"Requested test dependencies were not installed",
|
||||
)? {
|
||||
anyhow::bail!("Aborted");
|
||||
}
|
||||
} else if !cli.dry_run {
|
||||
execute_install_plan_with_child_commands(
|
||||
&dep_plan,
|
||||
&cli.rootfs,
|
||||
&config,
|
||||
InstallPlanExecutionOptions {
|
||||
no_flags: cli.no_flags,
|
||||
cross_prefix: cli.cross_prefix.as_deref(),
|
||||
clean: cli.clean,
|
||||
dry_run: cli.dry_run,
|
||||
confirm_installation: false,
|
||||
install_test_deps,
|
||||
},
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
if should_install_test_deps(&pkg_spec, install_test_deps) {
|
||||
let missing_test = deps::check_test_deps(&pkg_spec, &db_path)?;
|
||||
if !missing_test.is_empty()
|
||||
&& !maybe_prompt_to_skip_tests_for_missing_requested_deps(
|
||||
&mut pkg_spec,
|
||||
&missing_test,
|
||||
"Requested test dependencies are still missing",
|
||||
)?
|
||||
{
|
||||
deps::require_test_deps(&pkg_spec, &db_path)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if cli.dry_run {
|
||||
ui::info("Dry run enabled, stopping before build.");
|
||||
return Ok(());
|
||||
@@ -5594,6 +5826,42 @@ optional = []
|
||||
)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn requested_test_deps_prompt_can_disable_tests() -> Result<()> {
|
||||
let mut spec = test_package_spec(package::BuildType::Meson, None, &[]);
|
||||
spec.dependencies.test = vec!["pytest".into()];
|
||||
|
||||
ui::set_assume_yes(true);
|
||||
let prompted = maybe_prompt_to_skip_tests_for_missing_requested_deps(
|
||||
&mut spec,
|
||||
&["pytest".into()],
|
||||
"Requested test dependencies are missing",
|
||||
)?;
|
||||
ui::set_assume_yes(false);
|
||||
|
||||
assert!(prompted);
|
||||
assert!(spec.build.flags.skip_tests);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn requested_test_deps_prompt_is_ignored_for_non_automatic_test_builders() -> Result<()> {
|
||||
let mut spec = test_package_spec(package::BuildType::Custom, None, &[]);
|
||||
spec.dependencies.test = vec!["pytest".into()];
|
||||
|
||||
ui::set_assume_yes(true);
|
||||
let prompted = maybe_prompt_to_skip_tests_for_missing_requested_deps(
|
||||
&mut spec,
|
||||
&["pytest".into()],
|
||||
"Requested test dependencies are missing",
|
||||
)?;
|
||||
ui::set_assume_yes(false);
|
||||
|
||||
assert!(!prompted);
|
||||
assert!(!spec.build.flags.skip_tests);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rootfs_is_system_root_detects_live_rootfs() {
|
||||
assert!(rootfs_is_system_root(Path::new("/")));
|
||||
|
||||
@@ -172,18 +172,6 @@ impl ShellHelpers {
|
||||
self.depot_executable.to_string_lossy().into_owned(),
|
||||
);
|
||||
}
|
||||
|
||||
/// Apply helper-related variables directly to a `std::process::Command`.
|
||||
pub fn apply_to_command(&self, cmd: &mut std::process::Command) {
|
||||
cmd.env("PATH", &self.path_value)
|
||||
.env("DEPOT_OUTPUTS_DIR", &self.outputs_dir)
|
||||
.env("DEPOT_INTERNAL_DIR", INTERNAL_DEPOT_DIR)
|
||||
.env(DEPOT_HAUL_HELPER_ENV, &self.haul_path)
|
||||
.env(DEPOT_SUBDESTDIR_HELPER_ENV, &self.subdestdir_path)
|
||||
.env(DEPOT_PYTHON_BUILD_HELPER_ENV, &self.python_build_path)
|
||||
.env(DEPOT_PYTHON_INSTALL_HELPER_ENV, &self.python_install_path)
|
||||
.env(DEPOT_EXECUTABLE_ENV, &self.depot_executable);
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrap a shell command with helper functions that invoke the helper scripts
|
||||
|
||||
+92
-28
@@ -10,6 +10,15 @@ use std::process::Command;
|
||||
|
||||
use crate::builder::state::{BuildStep, StateTracker};
|
||||
|
||||
fn hook_env_vars(
|
||||
spec: &PackageSpec,
|
||||
shell_helpers: &crate::shell_helpers::ShellHelpers,
|
||||
) -> crate::builder::EnvVars {
|
||||
let mut env_vars = crate::builder::standard_build_env(spec, None, true, true);
|
||||
shell_helpers.apply_to_env_vars(&mut env_vars);
|
||||
env_vars
|
||||
}
|
||||
|
||||
/// Apply patches and run `post_extract` commands in the extracted source tree.
|
||||
pub fn post_extract(
|
||||
spec: &PackageSpec,
|
||||
@@ -85,23 +94,27 @@ fn run_post_extract_commands(spec: &PackageSpec, source: &Source, src_dir: &Path
|
||||
"Running {} post-extract command(s)...",
|
||||
source.post_extract.len()
|
||||
);
|
||||
let helper_root = tempfile::tempdir().context("Failed to create post-extract helper root")?;
|
||||
let shell_helpers = crate::shell_helpers::ShellHelpers::new(helper_root.path())?;
|
||||
let env_vars = hook_env_vars(spec, &shell_helpers);
|
||||
|
||||
for cmd in &source.post_extract {
|
||||
let cmd = spec.expand_vars(cmd);
|
||||
crate::log_info!(" post_extract: {}", cmd);
|
||||
let cmd_str = spec.expand_vars(cmd);
|
||||
crate::log_info!(" post_extract: {}", cmd_str);
|
||||
let wrapped_cmd = crate::shell_helpers::wrap_shell_command(&cmd_str);
|
||||
|
||||
// Use a shell for convenience; this is a package manager, so specs are trusted input.
|
||||
let status = Command::new("sh")
|
||||
.current_dir(src_dir)
|
||||
.env("DEPOT_SPECDIR", &spec.spec_dir)
|
||||
.env("PATH", crate::runtime_env::safe_script_path())
|
||||
let mut shell_cmd = Command::new("sh");
|
||||
shell_cmd.current_dir(src_dir);
|
||||
crate::builder::prepare_command(&mut shell_cmd, &env_vars);
|
||||
let status = shell_cmd
|
||||
.arg("-c")
|
||||
.arg(&cmd)
|
||||
.arg(&wrapped_cmd)
|
||||
.status()
|
||||
.with_context(|| format!("Failed to run post_extract command: {}", cmd))?;
|
||||
.with_context(|| format!("Failed to run post_extract command: {}", cmd_str))?;
|
||||
|
||||
if !status.success() {
|
||||
bail!("post_extract command failed: {}", cmd);
|
||||
bail!("post_extract command failed: {}", cmd_str);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,6 +134,12 @@ pub fn run_post_configure_commands(
|
||||
|
||||
crate::log_info!("Running {} post-configure command(s)...", commands.len());
|
||||
let shell_helpers = crate::shell_helpers::ShellHelpers::new(destdir)?;
|
||||
let mut env_vars = hook_env_vars(spec, &shell_helpers);
|
||||
crate::builder::set_env_var(
|
||||
&mut env_vars,
|
||||
"DESTDIR",
|
||||
destdir.to_string_lossy().into_owned(),
|
||||
);
|
||||
|
||||
for cmd in commands {
|
||||
let cmd_str = spec.expand_vars(cmd);
|
||||
@@ -129,13 +148,8 @@ pub fn run_post_configure_commands(
|
||||
|
||||
let mut shell_cmd = Command::new("sh");
|
||||
shell_cmd.current_dir(src_dir);
|
||||
shell_helpers.apply_to_command(&mut shell_cmd);
|
||||
crate::builder::prepare_command(&mut shell_cmd, &env_vars);
|
||||
let status = shell_cmd
|
||||
.env("DEPOT_SPECDIR", &spec.spec_dir)
|
||||
.env("DESTDIR", destdir)
|
||||
.env("DEPOT_ROOTFS", &spec.build.flags.rootfs)
|
||||
.env("CC", &spec.build.flags.cc)
|
||||
.env("AR", &spec.build.flags.ar)
|
||||
.arg("-c")
|
||||
.arg(&wrapped_cmd)
|
||||
.status()
|
||||
@@ -158,6 +172,12 @@ pub fn run_post_compile_commands(spec: &PackageSpec, src_dir: &Path, destdir: &P
|
||||
|
||||
crate::log_info!("Running {} post-compile command(s)...", commands.len());
|
||||
let shell_helpers = crate::shell_helpers::ShellHelpers::new(destdir)?;
|
||||
let mut env_vars = hook_env_vars(spec, &shell_helpers);
|
||||
crate::builder::set_env_var(
|
||||
&mut env_vars,
|
||||
"DESTDIR",
|
||||
destdir.to_string_lossy().into_owned(),
|
||||
);
|
||||
|
||||
for cmd in commands {
|
||||
let cmd_str = spec.expand_vars(cmd);
|
||||
@@ -166,13 +186,8 @@ pub fn run_post_compile_commands(spec: &PackageSpec, src_dir: &Path, destdir: &P
|
||||
|
||||
let mut shell_cmd = Command::new("sh");
|
||||
shell_cmd.current_dir(src_dir);
|
||||
shell_helpers.apply_to_command(&mut shell_cmd);
|
||||
crate::builder::prepare_command(&mut shell_cmd, &env_vars);
|
||||
let status = shell_cmd
|
||||
.env("DEPOT_SPECDIR", &spec.spec_dir)
|
||||
.env("DESTDIR", destdir)
|
||||
.env("DEPOT_ROOTFS", &spec.build.flags.rootfs)
|
||||
.env("CC", &spec.build.flags.cc)
|
||||
.env("AR", &spec.build.flags.ar)
|
||||
.arg("-c")
|
||||
.arg(&wrapped_cmd)
|
||||
.status()
|
||||
@@ -195,6 +210,12 @@ pub fn run_post_install_commands(spec: &PackageSpec, src_dir: &Path, destdir: &P
|
||||
|
||||
crate::log_info!("Running {} post-install command(s)...", commands.len());
|
||||
let shell_helpers = crate::shell_helpers::ShellHelpers::new(destdir)?;
|
||||
let mut env_vars = hook_env_vars(spec, &shell_helpers);
|
||||
crate::builder::set_env_var(
|
||||
&mut env_vars,
|
||||
"DESTDIR",
|
||||
destdir.to_string_lossy().into_owned(),
|
||||
);
|
||||
|
||||
for cmd in commands {
|
||||
let cmd_str = spec.expand_vars(cmd);
|
||||
@@ -203,13 +224,8 @@ pub fn run_post_install_commands(spec: &PackageSpec, src_dir: &Path, destdir: &P
|
||||
|
||||
let mut shell_cmd = Command::new("sh");
|
||||
shell_cmd.current_dir(src_dir);
|
||||
shell_helpers.apply_to_command(&mut shell_cmd);
|
||||
crate::builder::prepare_command(&mut shell_cmd, &env_vars);
|
||||
let status = shell_cmd
|
||||
.env("DEPOT_SPECDIR", &spec.spec_dir)
|
||||
.env("DESTDIR", destdir)
|
||||
.env("DEPOT_ROOTFS", &spec.build.flags.rootfs)
|
||||
.env("CC", &spec.build.flags.cc)
|
||||
.env("AR", &spec.build.flags.ar)
|
||||
.arg("-c")
|
||||
.arg(&wrapped_cmd)
|
||||
.status()
|
||||
@@ -291,7 +307,7 @@ fn download(url: &str, dest: &Path) -> Result<()> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{resolve_patch_path, run_post_install_commands};
|
||||
use super::{resolve_patch_path, run_post_extract_commands, run_post_install_commands};
|
||||
use crate::package::{
|
||||
Alternatives, Build, BuildFlags, BuildType, Dependencies, PackageInfo, PackageSpec, Source,
|
||||
};
|
||||
@@ -386,4 +402,52 @@ mod tests {
|
||||
.exists()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn post_extract_commands_can_call_python_build_helper() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let spec_dir = tmp.path().join("spec");
|
||||
let src_dir = tmp.path().join("src");
|
||||
std::fs::create_dir_all(&spec_dir).unwrap();
|
||||
std::fs::create_dir_all(&src_dir).unwrap();
|
||||
|
||||
let fake_depot = tmp.path().join("fake-depot");
|
||||
let log_path = tmp.path().join("python-build.log");
|
||||
std::fs::write(
|
||||
&fake_depot,
|
||||
format!(
|
||||
"#!/bin/sh\nset -eu\nprintf '%s\\n' \"$@\" > '{}'\n",
|
||||
log_path.display()
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
#[cfg(unix)]
|
||||
{
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
let mut perms = std::fs::metadata(&fake_depot).unwrap().permissions();
|
||||
perms.set_mode(0o755);
|
||||
std::fs::set_permissions(&fake_depot, perms).unwrap();
|
||||
}
|
||||
|
||||
let spec = dummy_spec(&spec_dir);
|
||||
let source = Source {
|
||||
url: "https://example.com/foo.tar.gz".into(),
|
||||
sha256: "skip".into(),
|
||||
extract_dir: "foo".into(),
|
||||
patches: Vec::new(),
|
||||
post_extract: vec![format!(
|
||||
"DEPOT_EXECUTABLE='{}' python_build --src-dir . --dist-dir dist",
|
||||
fake_depot.display()
|
||||
)],
|
||||
cherry_pick: Vec::new(),
|
||||
};
|
||||
|
||||
run_post_extract_commands(&spec, &source, &src_dir).unwrap();
|
||||
|
||||
let logged = std::fs::read_to_string(&log_path).unwrap();
|
||||
assert!(logged.contains("internal"));
|
||||
assert!(logged.contains("python-build"));
|
||||
assert!(logged.contains("--src-dir"));
|
||||
assert!(logged.contains("--dist-dir"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user