Skip to content

Commit

Permalink
resolve and mount path dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
Emilgardis committed May 26, 2022
1 parent 56a229f commit 6010092
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 21 deletions.
37 changes: 37 additions & 0 deletions src/cargo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,40 @@ impl<'a> From<&'a str> for Subcommand {
pub struct CargoMetadata {
pub workspace_root: PathBuf,
pub target_directory: PathBuf,
pub packages: Vec<Package>,
pub workspace_members: Vec<String>,
}

impl CargoMetadata {
fn non_workspace_members(&self) -> impl Iterator<Item = &Package> {
self.packages
.iter()
.filter(|p| !self.workspace_members.iter().any(|m| m == &p.id))
}

pub fn path_dependencies(&self) -> impl Iterator<Item = &Path> {
// TODO: Also filter out things that are in workspace, but not a workspace member
self.non_workspace_members().filter_map(|p| p.crate_path())
}
}

#[derive(Debug, Deserialize)]
pub struct Package {
id: String,
manifest_path: PathBuf,
source: Option<String>,
}

impl Package {
/// Returns the absolute path to the packages manifest "folder"
fn crate_path(&self) -> Option<&Path> {
// when source is none, this package is a path dependency or a workspace member
if self.source.is_none() {
self.manifest_path.parent()
} else {
None
}
}
}

/// Cargo metadata with specific invocation
Expand All @@ -78,6 +112,9 @@ pub fn cargo_metadata_with_args(
} else {
command.arg("--no-deps");
}
if let Some(target) = args.and_then(|a| a.target.as_ref()) {
command.args(["--filter-platform", target.triple()]);
}
let output = command.output()?;
let manifest: Option<CargoMetadata> =
serde_json::from_slice(&output.stdout).wrap_err_with(|| {
Expand Down
52 changes: 31 additions & 21 deletions src/docker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,26 @@ pub fn register(target: &Target, verbose: bool) -> Result<()> {
.run(verbose)
}

pub fn mount(cmd: &mut Command, val: &Path, verbose: bool) -> Result<PathBuf> {
let host_path =
file::canonicalize(&val).wrap_err_with(|| format!("when canonicalizing path `{val:?}`"))?;
let mount_path: PathBuf;
#[cfg(target_os = "windows")]
{
// On Windows, we can not mount the directory name directly. Instead, we use wslpath to convert the path to a linux compatible path.
mount_path = wslpath(&host_path, verbose)?;
}
#[cfg(not(target_os = "windows"))]
{
mount_path = host_path.clone();
}
cmd.args(&[
"-v",
&format!("{}:{}", host_path.display(), mount_path.display()),
]);
Ok(mount_path)
}

#[allow(clippy::too_many_arguments)] // TODO: refactor
pub fn run(
target: &Target,
Expand Down Expand Up @@ -147,38 +167,28 @@ pub fn run(
// flag forwards the value from the parent shell
docker.args(&["-e", var]);
}
let mut env_volumes = false;
let mut mount_volumes = false;
// FIXME(emilgardis 2022-04-07): This is a fallback so that if it's hard for use to do mounting logic, make it simple(r)
// Preferably we would not have to do this.
if cwd.strip_prefix(&metadata.workspace_root).is_err() {
env_volumes = true;
mount_volumes = true;
}

for ref var in config.env_volumes(target)? {
validate_env_var(var)?;

if let Ok(val) = env::var(var) {
let host_path = file::canonicalize(&val)
.wrap_err_with(|| format!("when canonicalizing path `{val}`"))?;
let mount_path: PathBuf;
#[cfg(target_os = "windows")]
{
// On Windows, we can not mount the directory name directly. Instead, we use wslpath to convert the path to a linux compatible path.
mount_path = wslpath(&host_path, verbose)?;
}
#[cfg(not(target_os = "windows"))]
{
mount_path = host_path.clone();
}
docker.args(&[
"-v",
&format!("{}:{}", host_path.display(), mount_path.display()),
]);
let mount_path = mount(&mut docker, val.as_ref(), verbose)?;
docker.args(&["-e", &format!("{}={}", var, mount_path.display())]);
env_volumes = true;
mount_volumes = true;
}
}

for path in metadata.path_dependencies() {
mount(&mut docker, path, verbose)?;
mount_volumes = true;
}

docker.args(&["-e", "PKG_CONFIG_ALLOW_CROSS=1"]);

docker.arg("--rm");
Expand Down Expand Up @@ -232,7 +242,7 @@ pub fn run(
.args(&["-v", &format!("{}:/cargo:Z", cargo_dir.display())])
// Prevent `bin` from being mounted inside the Docker container.
.args(&["-v", "/cargo/bin"]);
if env_volumes {
if mount_volumes {
docker.args(&[
"-v",
&format!("{}:{}:Z", host_root.display(), mount_root.display()),
Expand All @@ -244,7 +254,7 @@ pub fn run(
.args(&["-v", &format!("{}:/rust:Z,ro", sysroot.display())])
.args(&["-v", &format!("{}:/target:Z", target_dir.display())]);

if env_volumes {
if mount_volumes {
docker.args(&["-w".as_ref(), mount_cwd.as_os_str()]);
} else if mount_cwd == metadata.workspace_root {
docker.args(&["-w", "/project"]);
Expand Down

0 comments on commit 6010092

Please sign in to comment.