From 92d231c2ec63966fe451949f776ad3a1aacf6dc5 Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Sun, 23 Oct 2016 19:56:30 -0700 Subject: [PATCH] Add --justfile and --working-directory flags --- notes | 14 +++++------ src/app.rs | 71 +++++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 57 insertions(+), 28 deletions(-) diff --git a/notes b/notes index 7beabd5..b81e134 100644 --- a/notes +++ b/notes @@ -14,6 +14,11 @@ notes - just ../foo # ../justfile:foo - just xyz/foo # xyz/justfile:foo - just xyz/ # xyz/justfile:DEFAULT +- assignment + . export environment variables + . no barewords +- indentation is line continuation +- static errors when variables are missing {{}}, even if recipe isn't run - change name back to 'just' . suggest j as alias @@ -35,6 +40,7 @@ notes . habit of using clever commands and writing little scripts . very low friction to write a script (no new file, chmod, add to rcs) . make list of contributors, include travis + . alias .j='just -j ~/.justfile -d ~' - vim and emacs syntax hilighting (use makefile syntax hilighting for now) - split up code into modules for easier reading . parsing @@ -48,11 +54,6 @@ notes . r/rust later: -- indentation is line continuation -- assignment - . export environment variables - . no barewords -- static errors when variables are missing {{}}, even if recipe isn't run - preludes: may be nice to allow all recipes in a given langauge to share functions, variables, etc. could have a "prelude" recipe @@ -60,8 +61,5 @@ later: - windows support: currently calling 'sh', which won't work on windows the answer will probably be to write a 'sh' clone and to only call binaries from cargo -- allow specifying justfile on command line with --justfile/-j - and dir with --directory/-d, so i can do: - alias .j='just -j ~/.justfile -d ~' - run recipes asyncronously - lint with clippy once it runs on stable diff --git a/src/app.rs b/src/app.rs index dd31f87..6003edd 100644 --- a/src/app.rs +++ b/src/app.rs @@ -32,37 +32,68 @@ pub fn app() { .short("s") .long("show") .takes_value(true) - .help("Show information about a recipe")) + .value_name("recipe") + .help("Show information about ")) + .arg(Arg::with_name("working-directory") + .long("working-directory") + .takes_value(true) + .help("Use as working directory. --justfile must also be set")) + .arg(Arg::with_name("justfile") + .long("justfile") + .takes_value(true) + .help("Use as justfile. --working-directory must also be set")) .arg(Arg::with_name("recipe") .multiple(true) .help("recipe(s) to run, defaults to the first recipe in the justfile")) .get_matches(); - loop { - match fs::metadata("justfile") { - Ok(metadata) => if metadata.is_file() { break; }, - Err(error) => { - if error.kind() != io::ErrorKind::NotFound { - die!("Error fetching justfile metadata: {}", error) + // it is not obvious to me what we should do if only one of --justfile and + // --working-directory are passed. refuse to run in that case to avoid + // suprises. + if matches.is_present("justfile") ^ matches.is_present("working-directory") { + die!("--justfile and --working-directory may only be used together"); + } + + let justfile_option = matches.value_of("justfile"); + let working_directory_option = matches.value_of("working-directory"); + + let text; + if let (Some(file), Some(directory)) = (justfile_option, working_directory_option) { + text = fs::File::open(file) + .unwrap_or_else(|error| die!("Error opening justfile: {}", error)) + .slurp() + .unwrap_or_else(|error| die!("Error reading justfile: {}", error)); + + if let Err(error) = env::set_current_dir(directory) { + die!("Error changing directory to {}: {}", directory, error); + } + } else { + loop { + match fs::metadata("justfile") { + Ok(metadata) => if metadata.is_file() { break; }, + Err(error) => { + if error.kind() != io::ErrorKind::NotFound { + die!("Error fetching justfile metadata: {}", error) + } } } + + match env::current_dir() { + Ok(pathbuf) => if pathbuf.as_os_str() == "/" { die!("No justfile found."); }, + Err(error) => die!("Error getting current dir: {}", error), + } + + if let Err(error) = env::set_current_dir("..") { + die!("Error changing directory: {}", error); + } } - match env::current_dir() { - Ok(pathbuf) => if pathbuf.as_os_str() == "/" { die!("No justfile found."); }, - Err(error) => die!("Error getting current dir: {}", error), - } - - if let Err(error) = env::set_current_dir("..") { - die!("Error changing directory: {}", error); - } + text = fs::File::open("justfile") + .unwrap_or_else(|error| die!("Error opening justfile: {}", error)) + .slurp() + .unwrap_or_else(|error| die!("Error reading justfile: {}", error)); } - let text = fs::File::open("justfile") - .unwrap_or_else(|error| die!("Error opening justfile: {}", error)) - .slurp() - .unwrap_or_else(|error| die!("Error reading justfile: {}", error)); - let justfile = super::parse(&text).unwrap_or_else(|error| die!("{}", error)); if matches.is_present("list") {