diff --git a/src/args.rs b/src/args.rs index 2048c34..d620137 100644 --- a/src/args.rs +++ b/src/args.rs @@ -1,5 +1,8 @@ //! Cli manager +// Imports +use std::path::PathBuf; + /// Data from the command line #[derive(PartialEq, Eq, Clone, Debug)] #[derive(clap::Parser)] @@ -10,6 +13,12 @@ pub struct Args { /// If empty, uses default targets. pub targets: Vec, + /// Zbuild path + /// + /// Changes process working directory to parent directory of this file + #[clap(long = "path")] + pub zbuild_path: Option, + /// Number of concurrent jobs. /// /// Defaults to available parallelism diff --git a/src/main.rs b/src/main.rs index 8319515..4ce9979 100644 --- a/src/main.rs +++ b/src/main.rs @@ -34,7 +34,7 @@ use { args::Args, clap::StructOpt, futures::{stream::FuturesUnordered, TryStreamExt}, - std::{collections::HashMap, env, fs}, + std::{collections::HashMap, env, fs, path::PathBuf}, }; @@ -48,10 +48,7 @@ async fn main() -> Result<(), anyhow::Error> { tracing::trace!(?args, "Arguments"); // Parse the ast - let ast = { - let file = self::find_zbuild()?; - serde_yaml::from_reader::<_, Ast>(file).context("Unable to parse `zbuild.yaml`")? - }; + let ast = self::find_parse_zbuild_with_working_dir(args.zbuild_path)?; tracing::trace!(target: "zbuild_ast", ?ast, "Parsed ast"); // Build the rules @@ -109,6 +106,24 @@ async fn main() -> Result<(), anyhow::Error> { Ok(()) } +/// Finds and parses the `zbuild` path. +/// +/// Also sets the working directory to it's containing directory +pub fn find_parse_zbuild_with_working_dir(zbuild_path: Option) -> Result { + // Open the file + let file = match zbuild_path { + Some(path) => { + let parent = path.parent().context("`zbuild` path has no parent directory")?; + env::set_current_dir(parent).context("Unable to set current directory")?; + fs::File::open("zbuild.yaml").context("Unable to open `zbuild.yaml` file")? + }, + None => self::find_zbuild().context("Unable to find `zbuild.yaml` file")?, + }; + + // Then parse it + serde_yaml::from_reader::<_, Ast>(file).context("Unable to parse `zbuild.yaml`") +} + /// Finds and sets the working directory to the nearest zbuild file pub fn find_zbuild() -> Result { match fs::File::open("zbuild.yaml") { @@ -118,7 +133,10 @@ pub fn find_zbuild() -> Result { env::set_current_dir(parent).context("Unable to set current directory")?; self::find_zbuild() }, - None => anyhow::bail!("No `zbuild.yaml` file found in current or parent directories"), + None => anyhow::bail!( + "No `zbuild.yaml` file found in current or parent directories.\nYou can use `--path {{zbuild-path}}` \ + in order to specify the manifest's path" + ), }, } }