mirror of
https://gitlab.computer.surgery/matrix/grapevine.git
synced 2025-12-19 08:41:24 +01:00
xtask-specific binaries in GRAPEVINE_XTASK_PATH
Some possible alternatives to this: - Keep putting them in PATH. - Make xtask a nix derivation. We would lose out on incremental compilation this way, and would end up recompiling xtask from scratch whenever something in the main package changed. - Have xtask call `nix build --inputs-from $toplevel nixpkgs#go` and such. Slow and tedious.
This commit is contained in:
parent
102430cc79
commit
f76806655f
4 changed files with 63 additions and 18 deletions
|
|
@ -1,8 +1,10 @@
|
|||
mod complement;
|
||||
|
||||
use std::process::ExitCode;
|
||||
use std::{env, ffi::OsString, process::ExitCode};
|
||||
|
||||
use clap::{Parser, Subcommand};
|
||||
use miette::{miette, IntoDiagnostic, Result, WrapErr};
|
||||
use xshell::Shell;
|
||||
|
||||
#[derive(Parser)]
|
||||
struct Args {
|
||||
|
|
@ -16,11 +18,7 @@ enum Command {
|
|||
}
|
||||
|
||||
fn main() -> ExitCode {
|
||||
let args = Args::parse();
|
||||
let result = match args.command {
|
||||
Command::Complement(args) => complement::main(args),
|
||||
};
|
||||
let Err(e) = result else {
|
||||
let Err(e) = try_main() else {
|
||||
return ExitCode::SUCCESS;
|
||||
};
|
||||
// Include a leading newline because sometimes an error will occur in
|
||||
|
|
@ -28,3 +26,49 @@ fn main() -> ExitCode {
|
|||
eprintln!("\n{e:?}");
|
||||
ExitCode::FAILURE
|
||||
}
|
||||
|
||||
fn try_main() -> Result<()> {
|
||||
let args = Args::parse();
|
||||
let sh = new_shell()?;
|
||||
match args.command {
|
||||
Command::Complement(args) => complement::main(args, &sh),
|
||||
}
|
||||
}
|
||||
|
||||
fn new_shell() -> Result<Shell> {
|
||||
let path = get_shell_path()?;
|
||||
let sh = Shell::new()
|
||||
.into_diagnostic()
|
||||
.wrap_err("failed to initialize internal xshell::Shell wrapper")?;
|
||||
sh.set_var("PATH", path);
|
||||
Ok(sh)
|
||||
}
|
||||
|
||||
/// Returns the value to set the `PATH` environment variable to in
|
||||
/// [`xshell::Shell`] instances.
|
||||
///
|
||||
/// This function appends the paths from the `GRAPEVINE_XTASK_PATH` environment
|
||||
/// variable to the existing value of `PATH` set in the xtask process.
|
||||
///
|
||||
/// Executable dependencies that are only called by commands in xtask should be
|
||||
/// added to `GRAPEVINE_XTASK_PATH` instead of `PATH` in the devshell, to avoid
|
||||
/// polluting the devshell path with extra entries.
|
||||
fn get_shell_path() -> Result<OsString> {
|
||||
let xtask_path = env::var_os("GRAPEVINE_XTASK_PATH").ok_or(miette!(
|
||||
help = "This tool must be run from inside the Grapevine devshell. \
|
||||
Make sure you didn't interrupt direnv or something similar.",
|
||||
"GRAPEVINE_XTASK_PATH environment variable is unset"
|
||||
))?;
|
||||
if let Some(path) = env::var_os("PATH") {
|
||||
let old_paths = env::split_paths(&path);
|
||||
let xtask_paths = env::split_paths(&xtask_path);
|
||||
env::join_paths(old_paths.chain(xtask_paths))
|
||||
.into_diagnostic()
|
||||
.wrap_err(
|
||||
"error constructing new PATH value to include the paths from \
|
||||
GRAPEVINE_XTASK_PATH",
|
||||
)
|
||||
} else {
|
||||
Ok(xtask_path)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue