Skip to content

Commit 7e93d02

Browse files
committed
Allow users to ignore config files in the package.
Adds the `CROSS_BUILD_ENV_IGNORE_CARGO_CONFIG` environment variable, which if set will mount an anoymous data volume for each `.cargo` subdirectory for the current directory and any parent directories up to the workspace root. If the build is called outside the workspace root or at the workspace root, only mount at the `$PWD/.cargo`.
1 parent 37d4252 commit 7e93d02

File tree

8 files changed

+101
-13
lines changed

8 files changed

+101
-13
lines changed

.changes/936.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"type": "added",
3+
"description": "allow users to ignore config files in the package.",
4+
"issues": [621]
5+
}

docs/cross_toml.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ For example:
2121

2222
```toml
2323
[build.env]
24+
ignore-cargo-config = false
2425
volumes = ["VOL1_ARG", "VOL2_ARG"]
2526
passthrough = ["IMPORTANT_ENV_VARIABLES"]
2627
```

src/config.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ impl Environment {
9696
self.get_target_var(target, "RUNNER")
9797
}
9898

99+
fn ignore_cargo_config(&self, target: &Target) -> (Option<bool>, Option<bool>) {
100+
self.get_values_for("ENV_IGNORE_CARGO_CONFIG", target, bool_from_envvar)
101+
}
102+
99103
fn passthrough(&self, target: &Target) -> (Option<Vec<String>>, Option<Vec<String>>) {
100104
self.get_values_for("ENV_PASSTHROUGH", target, split_to_cloned_by_ws)
101105
}
@@ -275,6 +279,14 @@ impl Config {
275279
self.bool_from_config(target, Environment::build_std, CrossToml::build_std)
276280
}
277281

282+
pub fn ignore_cargo_config(&self, target: &Target) -> Option<bool> {
283+
self.bool_from_config(
284+
target,
285+
Environment::ignore_cargo_config,
286+
CrossToml::ignore_cargo_config,
287+
)
288+
}
289+
278290
pub fn image(&self, target: &Target) -> Result<Option<String>> {
279291
self.string_from_config(target, Environment::image, CrossToml::image)
280292
}

src/cross_toml.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ use std::str::FromStr;
1111

1212
/// Environment configuration
1313
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Default)]
14+
#[serde(rename_all = "kebab-case")]
1415
pub struct CrossEnvConfig {
16+
ignore_cargo_config: Option<bool>,
1517
volumes: Option<Vec<String>>,
1618
passthrough: Option<Vec<String>>,
1719
}
@@ -273,6 +275,15 @@ impl CrossToml {
273275
self.get_value(target, |b| b.build_std, |t| t.build_std)
274276
}
275277

278+
/// Returns the whether to ignore cargo config files.
279+
pub fn ignore_cargo_config(&self, target: &Target) -> (Option<bool>, Option<bool>) {
280+
self.get_value(
281+
target,
282+
|b| b.env.ignore_cargo_config,
283+
|t| t.env.ignore_cargo_config,
284+
)
285+
}
286+
276287
/// Returns the list of environment variables to pass through for `build` and `target`
277288
pub fn env_passthrough(&self, target: &Target) -> (Option<&[String]>, Option<&[String]>) {
278289
self.get_ref(
@@ -489,6 +500,7 @@ mod tests {
489500
targets: HashMap::new(),
490501
build: CrossBuildConfig {
491502
env: CrossEnvConfig {
503+
ignore_cargo_config: Some(false),
492504
volumes: Some(vec![s!("VOL1_ARG"), s!("VOL2_ARG")]),
493505
passthrough: Some(vec![s!("VAR1"), s!("VAR2")]),
494506
},
@@ -506,6 +518,7 @@ mod tests {
506518
pre-build = ["echo 'Hello World!'"]
507519
508520
[build.env]
521+
ignore-cargo-config = false
509522
volumes = ["VOL1_ARG", "VOL2_ARG"]
510523
passthrough = ["VAR1", "VAR2"]
511524
"#;
@@ -526,6 +539,7 @@ mod tests {
526539
},
527540
CrossTargetConfig {
528541
env: CrossEnvConfig {
542+
ignore_cargo_config: None,
529543
passthrough: Some(vec![s!("VAR1"), s!("VAR2")]),
530544
volumes: Some(vec![s!("VOL1_ARG"), s!("VOL2_ARG")]),
531545
},
@@ -580,6 +594,7 @@ mod tests {
580594
pre_build: Some(PreBuild::Lines(vec![s!("echo 'Hello'")])),
581595
runner: None,
582596
env: CrossEnvConfig {
597+
ignore_cargo_config: None,
583598
passthrough: None,
584599
volumes: Some(vec![s!("VOL")]),
585600
},
@@ -590,6 +605,7 @@ mod tests {
590605
targets: target_map,
591606
build: CrossBuildConfig {
592607
env: CrossEnvConfig {
608+
ignore_cargo_config: Some(true),
593609
volumes: None,
594610
passthrough: Some(vec![]),
595611
},
@@ -607,6 +623,7 @@ mod tests {
607623
pre-build = []
608624
609625
[build.env]
626+
ignore-cargo-config = true
610627
passthrough = []
611628
612629
[target.aarch64-unknown-linux-gnu]
@@ -648,6 +665,7 @@ mod tests {
648665
targets: HashMap::new(),
649666
build: CrossBuildConfig {
650667
env: CrossEnvConfig {
668+
ignore_cargo_config: None,
651669
passthrough: None,
652670
volumes: None,
653671
},

src/docker/local.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ pub(crate) fn run(
5050
docker
5151
.args(&["-v", &format!("{}:/rust:Z,ro", dirs.sysroot.to_utf8()?)])
5252
.args(&["-v", &format!("{}:/target:Z", dirs.target.to_utf8()?)]);
53-
docker_cwd(&mut docker, &paths)?;
53+
docker_cwd(&mut docker, &paths, options.ignore_cargo_config)?;
5454

5555
// When running inside NixOS or using Nix packaging we need to add the Nix
5656
// Store to the running container so it can load the needed binaries.

src/docker/remote.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1170,7 +1170,7 @@ symlink_recurse \"${{prefix}}\"
11701170
let mut docker = subcommand(engine, "exec");
11711171
docker_user_id(&mut docker, engine.kind);
11721172
docker_envvars(&mut docker, &options.config, target, msg_info)?;
1173-
docker_cwd(&mut docker, &paths)?;
1173+
docker_cwd(&mut docker, &paths, options.ignore_cargo_config)?;
11741174
docker.arg(&container);
11751175
docker.args(&["sh", "-c", &format!("PATH=$PATH:/rust/bin {:?}", cmd)]);
11761176
bail_container_exited!();

src/docker/shared.rs

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,12 @@ use crate::cargo::{cargo_metadata_with_args, CargoMetadata};
99
use crate::config::{bool_from_envvar, Config};
1010
use crate::errors::*;
1111
use crate::extensions::{CommandExt, SafeCommand};
12-
use crate::file::{self, write_file, ToUtf8};
12+
use crate::file::{self, write_file, PathExt, ToUtf8};
1313
use crate::id;
1414
use crate::rustc::{self, VersionMetaExt};
1515
use crate::shell::{MessageInfo, Verbosity};
1616
use crate::Target;
1717

18-
#[cfg(target_os = "windows")]
19-
use crate::file::PathExt;
20-
2118
pub use super::custom::CROSS_CUSTOM_DOCKERFILE_IMAGE_PREFIX;
2219

2320
pub const CROSS_IMAGE: &str = "ghcr.io/cross-rs";
@@ -37,15 +34,23 @@ pub struct DockerOptions {
3734
pub target: Target,
3835
pub config: Config,
3936
pub uses_xargo: bool,
37+
pub ignore_cargo_config: bool,
4038
}
4139

4240
impl DockerOptions {
43-
pub fn new(engine: Engine, target: Target, config: Config, uses_xargo: bool) -> DockerOptions {
41+
pub fn new(
42+
engine: Engine,
43+
target: Target,
44+
config: Config,
45+
uses_xargo: bool,
46+
ignore_cargo_config: bool,
47+
) -> DockerOptions {
4448
DockerOptions {
4549
engine,
4650
target,
4751
config,
4852
uses_xargo,
53+
ignore_cargo_config,
4954
}
5055
}
5156

@@ -220,10 +225,18 @@ impl DockerPaths {
220225
self.workspace_from_cwd().is_ok()
221226
}
222227

228+
pub fn cargo_home(&self) -> &Path {
229+
&self.directories.cargo
230+
}
231+
223232
pub fn mount_cwd(&self) -> &str {
224233
&self.directories.mount_cwd
225234
}
226235

236+
pub fn mount_root(&self) -> &str {
237+
&self.directories.mount_root
238+
}
239+
227240
pub fn host_root(&self) -> &Path {
228241
&self.directories.host_root
229242
}
@@ -499,8 +512,44 @@ pub(crate) fn docker_envvars(
499512
Ok(())
500513
}
501514

502-
pub(crate) fn docker_cwd(docker: &mut Command, paths: &DockerPaths) -> Result<()> {
515+
fn mount_to_ignore_cargo_config(
516+
docker: &mut Command,
517+
paths: &DockerPaths,
518+
ignore_cargo_config: bool,
519+
) -> Result<()> {
520+
let check_mount =
521+
|cmd: &mut Command, host: &Path, mount: &Path, relpath: &Path| -> Result<()> {
522+
let cargo_dir = relpath.join(".cargo");
523+
if host.join(&cargo_dir).exists() {
524+
// this is fine, since it has to be a POSIX path on the mount.
525+
cmd.args(&["-v", &mount.join(&cargo_dir).as_posix()?]);
526+
}
527+
528+
Ok(())
529+
};
530+
if ignore_cargo_config {
531+
let mount_root = Path::new(paths.mount_root());
532+
let mount_cwd = Path::new(paths.mount_cwd());
533+
check_mount(docker, &paths.cwd, mount_cwd, Path::new(""))?;
534+
// CWD isn't guaranteed to be a subdirectory of the mount root.
535+
if let Ok(mut relpath) = mount_cwd.strip_prefix(mount_root) {
536+
while let Some(parent) = relpath.parent() {
537+
check_mount(docker, paths.host_root(), mount_root, parent)?;
538+
relpath = parent;
539+
}
540+
}
541+
}
542+
543+
Ok(())
544+
}
545+
546+
pub(crate) fn docker_cwd(
547+
docker: &mut Command,
548+
paths: &DockerPaths,
549+
ignore_cargo_config: bool,
550+
) -> Result<()> {
503551
docker.args(&["-w", paths.mount_cwd()]);
552+
mount_to_ignore_cargo_config(docker, paths, ignore_cargo_config)?;
504553

505554
Ok(())
506555
}
@@ -788,9 +837,6 @@ mod tests {
788837
use super::*;
789838
use crate::id;
790839

791-
#[cfg(not(target_os = "windows"))]
792-
use crate::file::PathExt;
793-
794840
#[test]
795841
fn test_docker_user_id() {
796842
let var = "CROSS_ROOTLESS_CONTAINER_ENGINE";

src/lib.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -532,8 +532,14 @@ pub fn run() -> Result<ExitStatus> {
532532
}
533533

534534
let paths = docker::DockerPaths::create(&engine, metadata, cwd, sysroot)?;
535-
let options =
536-
docker::DockerOptions::new(engine, target.clone(), config, uses_xargo);
535+
let ignore_cargo_config = config.ignore_cargo_config(&target).unwrap_or_default();
536+
let options = docker::DockerOptions::new(
537+
engine,
538+
target.clone(),
539+
config,
540+
uses_xargo,
541+
ignore_cargo_config,
542+
);
537543
let status = docker::run(options, paths, &filtered_args, &mut msg_info)
538544
.wrap_err("could not run container")?;
539545
let needs_host = args.subcommand.map_or(false, |sc| sc.needs_host(is_remote));

0 commit comments

Comments
 (0)