aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMelody Horn <melody@boringcactus.com>2024-11-17 18:20:20 -0700
committerMelody Horn <melody@boringcactus.com>2024-11-17 18:20:20 -0700
commit2254b27cbeabd7f9e656a79afc7e0343d72f0685 (patch)
tree85f41f1b00603264616c14d0f4e4e5000ae1ffe0 /src
parent5b31b0fb68a751afa349450a1fc8c3870d13e1dc (diff)
downloadmakers-canon.tar.gz
makers-canon.zip
propagate command line macros through MAKEFLAGS for recursive callsHEADcanon
Diffstat (limited to 'src')
-rw-r--r--src/args.rs51
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(&macros);
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");
}
}