Skip to content

Commit 87d650b

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 87d650b

File tree

8 files changed

+106
-13
lines changed

8 files changed

+106
-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: 60 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,49 @@ 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+
root: &str,
519+
cwd: &str,
520+
ignore_cargo_config: bool,
521+
) -> Result<()> {
522+
let is_cargo_home_parent = paths
523+
.cargo_home()
524+
.parent()
525+
.map(|x| x == paths.host_root())
526+
.unwrap_or_default();
527+
if ignore_cargo_config && !is_cargo_home_parent {
528+
let root_path = Path::new(root);
529+
let cwd_path = Path::new(cwd);
530+
docker.args(&["-v", &cwd_path.join(".cargo").as_posix()?]);
531+
let mut relpath = Path::new(cwd).strip_prefix(root_path).wrap_err_with(|| {
532+
eyre::eyre!("cwd \"{cwd}\" must be a subdirectory of root \"{root}\"")
533+
})?;
534+
535+
while let Some(parent) = relpath.parent() {
536+
let path = root_path.join(parent);
537+
docker.args(&["-v", &path.join(".cargo").as_posix()?]);
538+
relpath = parent;
539+
}
540+
}
541+
542+
Ok(())
543+
}
544+
545+
pub(crate) fn docker_cwd(
546+
docker: &mut Command,
547+
paths: &DockerPaths,
548+
ignore_cargo_config: bool,
549+
) -> Result<()> {
503550
docker.args(&["-w", paths.mount_cwd()]);
551+
mount_to_ignore_cargo_config(
552+
docker,
553+
paths,
554+
paths.mount_root(),
555+
paths.mount_cwd(),
556+
ignore_cargo_config,
557+
)?;
504558

505559
Ok(())
506560
}
@@ -788,9 +842,6 @@ mod tests {
788842
use super::*;
789843
use crate::id;
790844

791-
#[cfg(not(target_os = "windows"))]
792-
use crate::file::PathExt;
793-
794845
#[test]
795846
fn test_docker_user_id() {
796847
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)