diff options
author | Melody Horn <melody@boringcactus.com> | 2024-11-17 18:20:20 -0700 |
---|---|---|
committer | Melody Horn <melody@boringcactus.com> | 2024-11-17 18:20:20 -0700 |
commit | 2254b27cbeabd7f9e656a79afc7e0343d72f0685 (patch) | |
tree | 85f41f1b00603264616c14d0f4e4e5000ae1ffe0 /src | |
parent | 5b31b0fb68a751afa349450a1fc8c3870d13e1dc (diff) | |
download | makers-canon.tar.gz makers-canon.zip |
Diffstat (limited to 'src')
-rw-r--r-- | src/args.rs | 51 |
1 files changed, 36 insertions, 15 deletions
diff --git a/src/args.rs b/src/args.rs index f5097f8..f0892cb 100644 --- a/src/args.rs +++ b/src/args.rs @@ -1,6 +1,7 @@ use std::env; use std::ffi::OsString; use std::iter; +use std::ops::AddAssign; use std::path::PathBuf; use clap::Parser; @@ -158,14 +159,13 @@ impl Args { // POSIX spec says "Any options specified in the MAKEFLAGS environment variable // shall be evaluated before any options specified on the make utility command // line." - // TODO allow macro definitions in MAKEFLAGS // POSIX says we have to accept // > The characters are option letters without the leading <hyphen-minus> // > characters or <blank> separation used on a make utility command line. let makeflags_given = !env_makeflags.is_empty(); let makeflags_spaces = env_makeflags.contains(' '); let makeflags_leading_dash = env_makeflags.starts_with('-'); - let makeflags_has_equals = env_makeflags.starts_with('='); + let makeflags_has_equals = env_makeflags.contains('='); let makeflags_obviously_full = makeflags_spaces || makeflags_leading_dash || makeflags_has_equals; let env_makeflags = if makeflags_given && !makeflags_obviously_full { @@ -211,38 +211,58 @@ impl Args { } pub fn makeflags(&self) -> String { - let mut result = String::new(); + let mut flags = String::new(); if self.environment_overrides { - result.push('e'); + flags.push('e'); } if self.ignore_errors { - result.push('i'); + flags.push('i'); } if self.keep_going { - result.push('k'); + flags.push('k'); } if self.dry_run { - result.push('n'); + flags.push('n'); } if self.print_everything { - result.push('p'); + flags.push('p'); } if self.question { - result.push('q'); + flags.push('q'); } if self.no_builtin_rules { - result.push('r'); + flags.push('r'); } if self.no_keep_going { - result.push('S'); + flags.push('S'); } if self.silent { - result.push('s'); + flags.push('s'); } if self.touch { - result.push('t'); + flags.push('t'); } // TODO decide whether or not print_directory should go here too + + let macros = self + .targets_or_macros + .iter() + .map(|x| x.as_ref()) + .filter(|x: &&str| x.contains('=')) + .collect::<Vec<&str>>() + .join(" "); + + let mut result = String::new(); + if !flags.is_empty() && !macros.is_empty() { + result.push('-'); + } + result.add_assign(&flags); + // TODO consider -- to separate flags from macros - GNU does it but it would require + // gnarly splicing to not override recursive macros + if !flags.is_empty() && !macros.is_empty() { + result += " "; + } + result.add_assign(¯os); result } } @@ -477,7 +497,7 @@ mod test { #[test] fn nightmare() { - let makeflags = "-nrs -k foo=bar"; + let makeflags = "-nrs -k -- foo=bar"; let args = "makers -eipqtSf foo -f bruh bar baz=yeet"; let args = Args::from_given_args_and_given_env( args.split_whitespace().map(OsString::from), @@ -503,8 +523,9 @@ mod test { print_directory: false, #[cfg(feature = "full")] no_print_directory: false, - targets_or_macros: vec!["foo=bar".into(), "bar".into(), "baz=yeet".into()], + targets_or_macros: vec!["bar".into(), "baz=yeet".into(), "foo=bar".into()], } ); + assert_eq!(args.makeflags(), "-einpqrSst -- baz=yeet foo=bar"); } } |