From: Ian Jackson Date: Sun, 21 Jun 2020 12:43:14 +0000 (+0100) Subject: New scheme for subcommand handling - wip X-Git-Tag: nailing-cargo/1.0.0~126 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=0c38873cc0ee44e2427138044239fc3333cb8924;p=nailing-cargo.git New scheme for subcommand handling - wip Does not work yet. Signed-off-by: Ian Jackson --- diff --git a/README.md b/README.md index 28db367..f989ab6 100644 --- a/README.md +++ b/README.md @@ -264,7 +264,7 @@ Options then in the builtin arch alias list. The builtin list is equivalent to: `[arch]` `RPI='arm-unknown-linux-gnueabihf'`. - * `-c` + * `-s` Behave as if the build command were `cargo `. This influences the logic which tries to determine which @@ -272,29 +272,31 @@ Options whether cargo might want to update `Cargo.lock`. nailing-cargo knows about `update`, `generate-lockfile` and - `fetch`; all other subcommands are (silently) treated the - same way as `build`. See `--subcommand-props`, below, for - more detail about how the subcommand affects nailing-cargo's - behaviour. + `fetch`; all other subcommands are (silently) treated the same + way as `build` (ie, no subcommand properties). See + `--subcommand-props`, below, for more detail about how the + subcommand affects nailing-cargo's behaviour. This option does not affect which build command (and which - cargo subcommand) is actually run. - The default is to look into the command line to find the cargo - subcommand. - - * `-C` - - Behave as if the build command will not run cargo. - - This suppresses the addition of cargo command line options and - makes nailing-cargo assumes that the build command will not - need to update `Cargo.lock`. - But this option does not affect which build command is actually - run. - - The default is to treat the build command as cargo unless a - build command is specified whose leafname does not contains the - string `cargo`. + cargo subcommand) is actually run. The default is to use the + cargo subcommand found from parsing nailing-cargo's + command line. + + * `-c` | `-C` + + Controls the addition of cargo command line options; ie, + whether nailing-cargo should treat the build command as if it + were cargo. + With `-C`, nailing-cargo will not add additional options + to the build command. With `-c` it will pass those options + at the end of the build command. + The cargo options are in any case also passed in the + environment - see [Environment of the build command]. + + The default is to pass cargo options if the command line + parsing yielded a cargo command and options (usages 1 and 2), + rather than a non-cargo build command (usage 3). `-C` and `-c` + do not affect the parsing of nailing-cargo's command line. * `-o` | `--online` | `-O` | `--offline` @@ -320,32 +322,53 @@ Options * `--subcommand-props=,...` Specify the properties of the subcommand. This is an - alternative to `-c`. The properties are: + alternative to `-s`. The usual properties are: * `lock_update`: cargo will want to update `Cargo.lock`. (The `-u` and `-U` options override this.) * `online`: this subcommand makes no sense to run offline. (The `-o` and `-O` options, and the configuration, can override this.) * `!target`: cargo would reject `--target=`; in this case nailing-cargo's `-T` option is ineffective. * `!target-dir`: cargo would reject `--target-dir`, so don't pass it. (Usually we pass `--target-dir=target` when we pass `--manifest-path`, since cargo's default is `target` in the same directory as `Cargo.toml`.) - * `!manifest-path`: cargo would reject `--manifest-path`, so don't pass it (and don't pass `--target-dir` either). Only makes any difference for out-of-tree builds. Things will probably go wrong unless the build command looks at `NAILINGCARGO_MANIFEST_DIR`. - * `!locked`: cargo would reject `--locked`, so don't pass it (hazardous). - * `!offline`: the build command would reject `--offline`, so never pass it. *Not* overridden by configuration or command line. Primarily for non-cargo build commands. + + There are also some properties which should not be needed, but are + provided for completeness. Do not use these to solve the problem + of nailing-cargo passing cargo options to a build command which is + not cargo - use `-C` for that. The properties whose use is discouraged: + + * `!manifest-path`: cargo would reject `--manifest-path`, so don't pass it (and don't pass `--target-dir` either). Only makes any difference for out-of-tree builds. Things will probably go wrong unless the build command looks at `[NAILING]CARGO_MANIFEST_DIR`. + * `!locked`: cargo would reject `--locked`, so don't pass it. Hazardous. + * `!offline`: the build command would reject `--offline`, so never pass it. *Not* overridden by configuration or command line. Environment of the build command -------------------------------- nailing-cargo passes these environment variables to the build command: + * `CARGO_MANIFEST_DIR`: invocation `.` (invocation directory) + * `NAILINGCARGO_MANIFEST_DIR`: same as `CARGO_MANIFEST_DIR` * `NAILINGCARGO_WORKSPHERE`: invocation `..` (parent) - * `NAILINGCARGO_MANIFEST_DIR`: invocation `.` (invocation directory) * `NAILINGCARGO_BUILD_DIR`: build directory (even if same as source) - * `NAILINGCARGO_BUILDSPHERE`: only set if out of tree: parent of build dir. + * `NAILINGCARGO_BUILDSPHERE`: parent of build dir (only set if out-of-tree) + * `NAILINGCARGO_CARGO_OPTIONS`: additional options that nailing-cargo passed (or would pass) to cargo. Space-separated; does not include `--manifest-path`. All of these are absolute paths. -For out-of-tree builds it is always necessary to pass --manifest-path -to cargo, so non-cargo build commands will need to look at -`NAILINGCARGO_MANIFEST_DIR` and turn that back into a cargo option; -they may also need to pass `--target-dir=`. +### Build commands which wrap cargo ### + +If you specify a build command which eventually runs cargo, you may +wish to pass on to your cargo the options which nailing-cargo would +have passed. This will definitely be necessary if you are using nailing-cargo's out-of-tree facility. + +In such a situation, do it like this: +``` + cargo build --manifest-path="${CARGO_MANIFEST_DIR-.}"/Cargo.toml $NAILINGCARGO_CARGO_OPTIONS +``` + +If you need to run a cargo subcommand which doesn't understand some of +nailing-cargo's options, currently, you must strip them out of +`NAILINGCARGO_CARGO_OPTIONS` yourself - or pass some `-s` or +`--subcmd-props` option to nailing-cargo (but that is a layering +violation and may not work if one build command runs various different +cargo runes). Configuration reference ======================= @@ -490,7 +513,7 @@ Limitations and bugs * nailing-cargo needs to understand the behaviour of the cargo subcommand you are running - especially for out-of-tree builds. nailing-cargo only has a short builtin list of commands it knows - about (see the `-c` option). For other commands, you may need to + about (see the `-s` option). For other commands, you may need to add an entry to `@subcmd_propss` in the source, or use `--subcommand-props`. diff --git a/nailing-cargo b/nailing-cargo index 829d279..58a777e 100755 --- a/nailing-cargo +++ b/nailing-cargo @@ -44,17 +44,19 @@ our $subdir = $1; # leafname our $lockfile = "../.nailing-cargo.lock"; our $cargo_subcmd; +our $command_is_cargo; our $alt_cargo_lock; our $online; # our %subcmd_props = { # build (default) =>qw( ), - update =>qw( !target lock-update ), -'generate-lockfile'=>qw( !target lock-update ), - fetch =>qw( !target online !target-dir ), - '' =>qw( !target !manifest-path !locked !offline ); -}; + update =>qw( lock-update !target ), +'generate-lockfile'=>qw( lock-update !target ), + fetch =>qw( !target online !target-dir ), + }; + +our @subcmd_xprops = qw(!manifest-path !offline !locked); our @configs; our $verbose=1; @@ -359,11 +361,13 @@ sub addargs () { $cargo_lock_update //= subcmd_p('lock-update'); + our @add; + if (!$cargo_lock_update) { - push @ARGV, qw(--locked) unless subcmd_p('!locked'); + push @add, qw(--locked) unless subcmd_p('!locked'); if (defined($oot_dir) && !subcmd_p('!manifest-path')) { - push @ARGV, "--manifest-path=${src_absdir}/Cargo.toml"; - push @ARGV, qw(--target-dir=target) unless subcmd_p('!target'); + push @ARGV, "--manifest-path=${src_absdir}/Cargo.toml" if $pass_options; + push @add, qw(--target-dir=target) unless subcmd_p('!target'); } } @@ -372,10 +376,14 @@ sub addargs () { $target = (cfgs 'arch', $target) // $archmap{$target} // die "$self: --target=$target alias specified; not in cfg or map\n"; } - push @ARGV, "--target=$target"; + push @add, "--target=$target"; } - push @ARGV, "--offline" unless $online || subcmd_p('!offline'); + push @add, "--offline" unless $online || subcmd_p('!offline'); + + push @ARGV, @add if $pass_options; + die if grep { m/ / } @add; + $ENV{NAILINGCARGO_CARGO_OPTIONS} = "@add"; } our $oot_absdir; @@ -479,8 +487,9 @@ END } sub setenvs () { - $ENV{NAILINGCARGO_WORKSPHERE} = $worksphere; + $ENV{CARGO_MANIFEST_DIR} = $src_absdir; $ENV{NAILINGCARGO_MANIFEST_DIR} = $src_absdir; + $ENV{NAILINGCARGO_WORKSPHERE} = $worksphere; $ENV{NAILINGCARGO_BUILDSPHERE} = $oot_absdir; delete $ENV{NAILINGCARGO_BUILDSPHERE} unless $oot_absdir; $ENV{NAILINGCARGO_BUILD_DIR} = $build_absdir // $src_absdir; @@ -685,16 +694,16 @@ sub parse_args () { $verbose=0; } elsif (s{^-n}{-}) { $noact++; - } elsif (s{^-c(.+)}{-}s) { + } elsif (s{^-s(.+)}{-}s) { $cargo_subcmd = $1; - } elsif (s{^-C}{-}) { - $cargo_subcmd = ''; + } elsif (s{^-([cC])}{-}) { + $pass_options = $1=~m/[a-z]/; } elsif (s{^-D}{-}) { $dump++; } elsif (s{^-T(.+)}{-}s) { $target = $1; } elsif (s{^-([oO])}{-}) { - $online= $1=~m/[a-z]/; + $online = $1=~m/[a-z]/; } else { die "$self: unknown short option(s) $_\n" unless $_ eq $orgopt; $not_a_nailing_opt->(); @@ -708,7 +717,9 @@ sub parse_args () { my @props = split /\,/, $_; our %subcmd_prop_ok; if (!%subcmd_prop_ok) { - for $v in (%subcmd_props) { $subcmd_prop_ok{$_}=1 foreach @$v; }; + for $v in (\@subcmd_xprops, values %subcmd_props) { + $subcmd_prop_ok{$_}=1 foreach @$v; + }; } $subcmd_prop_ok{$_} or die "$self: unknown subcommand property \`$_'\n" @@ -733,9 +744,11 @@ sub parse_args () { } @ARGV || die "$self: need cargo subcommand\n"; $cargo_subcmd //= $ARGV[0]; + $pass_options //= 1; unshift @ARGV, @cargo_and_opts; } else { $cargo_subcmd //= ''; + $pass_options //= 0; } if (!ref($cargo_subcmd)) {