Skip to content

Commit

Permalink
make it possible to run from anywhere in workspace
Browse files Browse the repository at this point in the history
  • Loading branch information
Emilgardis committed Jun 3, 2022
1 parent c72b1d7 commit 0eecee1
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 42 deletions.
44 changes: 23 additions & 21 deletions src/cargo.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use serde::Deserialize;
use std::path::{Path, PathBuf};
use std::process::{Command, ExitStatus};
use std::{env, fs};

use crate::errors::*;
use crate::extensions::CommandExt;
Expand Down Expand Up @@ -54,7 +54,7 @@ impl<'a> From<&'a str> for Subcommand {

#[derive(Debug)]
pub struct Root {
path: PathBuf,
pub path: PathBuf,
}

impl Root {
Expand All @@ -64,26 +64,28 @@ impl Root {
}

/// Cargo project root
pub fn root() -> Result<Option<Root>> {
let cd = env::current_dir().wrap_err("couldn't get current directory")?;

let mut dir = &*cd;
loop {
let toml = dir.join("Cargo.toml");

if fs::metadata(&toml).is_ok() {
return Ok(Some(Root {
path: dir.to_owned(),
}));
}

match dir.parent() {
Some(p) => dir = p,
None => break,
}
pub fn root(cd: Option<&Path>) -> Result<Option<Root>> {
#[derive(Deserialize)]
struct Manifest {
workspace_root: PathBuf,
}

Ok(None)
let mut command = std::process::Command::new(
std::env::var("CARGO")
.ok()
.unwrap_or_else(|| "cargo".to_string()),
);
command
.arg("metadata")
.arg("--format-version=1")
.arg("--no-deps");
if let Some(cd) = cd {
command.current_dir(cd);
}
let output = command.output()?;
let manifest: Option<Manifest> = serde_json::from_slice(&output.stdout)?;
Ok(manifest.map(|m| Root {
path: m.workspace_root,
}))
}

/// Pass-through mode
Expand Down
27 changes: 24 additions & 3 deletions src/docker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,17 @@ pub fn run(
}
#[cfg(not(target_os = "windows"))]
{
mount_root = host_root.clone();
mount_root = mount_finder.find_mount_path(host_root.clone());
}
let mount_cwd: 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_cwd = wslpath(&std::env::current_dir()?, verbose)?;
}
#[cfg(not(target_os = "windows"))]
{
mount_cwd = mount_finder.find_mount_path(std::env::current_dir()?);
}
let sysroot = mount_finder.find_mount_path(sysroot);

Expand Down Expand Up @@ -236,9 +246,20 @@ pub fn run(
.args(&["-v", &format!("{}:/target:Z", target_dir.display())]);

if env_volumes {
docker.args(&["-w", &mount_root.display().to_string()]);
} else {
docker.args(&["-w".as_ref(), mount_cwd.as_os_str()]);
} else if mount_cwd == root {
docker.args(&["-w", "/project"]);
} else {
// We do this to avoid clashes with path separators. Windows uses `\` as a path separator on Path::join
let cwd = &std::env::current_dir()?;
let working_dir = Path::new("project").join(cwd.strip_prefix(root)?);
// No [T].join for OsStr
let mut mount_wd = std::ffi::OsString::new();
for part in working_dir.iter() {
mount_wd.push("/");
mount_wd.push(part);
}
docker.args(&["-w".as_ref(), mount_wd.as_os_str()]);
}

// When running inside NixOS or using Nix packaging we need to add the Nix
Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ fn run() -> Result<ExitStatus> {

let host_version_meta =
rustc_version::version_meta().wrap_err("couldn't fetch the `rustc` version")?;
if let Some(root) = cargo::root()? {
if let Some(root) = cargo::root(None)? {
let host = host_version_meta.host();
let toml = toml(&root)?;
let config = Config::new(toml);
Expand Down
21 changes: 4 additions & 17 deletions src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,10 @@ static WORKSPACE: OnceCell<PathBuf> = OnceCell::new();
pub fn get_cargo_workspace() -> &'static Path {
let manifest_dir = env!("CARGO_MANIFEST_DIR");
WORKSPACE.get_or_init(|| {
#[derive(Deserialize)]
struct Manifest {
workspace_root: PathBuf,
}
let output = std::process::Command::new(
std::env::var("CARGO")
.ok()
.unwrap_or_else(|| "cargo".to_string()),
)
.arg("metadata")
.arg("--format-version=1")
.arg("--no-deps")
.current_dir(manifest_dir)
.output()
.unwrap();
let manifest: Manifest = serde_json::from_slice(&output.stdout).unwrap();
manifest.workspace_root
crate::cargo::root(Some(manifest_dir.as_ref()))
.unwrap()
.unwrap()
.path
})
}

Expand Down

0 comments on commit 0eecee1

Please sign in to comment.