From 4ddda8130379eb783aaa70434e9f0dbb63beaad1 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sun, 21 Jun 2020 12:47:31 +0100 Subject: [PATCH] New scheme for subcommand handling - wip Does not work yet. Signed-off-by: Ian Jackson --- README.md | 102 +++++++++++++++++++++----------------------------- nailing-cargo | 84 ++++++++++++++++++++++------------------- 2 files changed, 87 insertions(+), 99 deletions(-) diff --git a/README.md b/README.md index 7351b9e..28db367 100644 --- a/README.md +++ b/README.md @@ -267,13 +267,20 @@ Options * `-c` Behave as if the build command were `cargo `. - This influences the logic which tries to determine which options to pass to cargo, whether cargo needs to be online, and whether cargo might want to update `Cargo.lock`. - But this option does not affect which build command (and which + 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. + + 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` @@ -285,6 +292,17 @@ Options 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`. + + * `-o` | `--online` | `-O` | `--offline` + + Whether to allow cargo to make network access. nailing-cargo + always passes `--offline` to cargo, unless `--online` is in + force. The default value depends on the configuration and the + cargo subcommand - see `[misc]` `online` in "Configuration". + * `-u` | `--cargo-lock-update` | `-U` | `--no-cargo-lock-update` Enables, or disables, the dance to allow `Cargo.lock` (or @@ -299,66 +317,18 @@ Options Default is no update unless the cargo subcommand will want it. - * `--cargo-args=[,...]` - - Overrides the logic for choosing which cargo options should be - passed to the build command. - The value is a comma-separated list of ``. - - `` is one of the arguments that nailing-cargo might pass - to cargo: `manifest-path`, `locked`, `target-dir`, `offline`, - `arch`. - (Note these must be specified - without the leading `--` and without any value.) `` may - also be `all` in which case the setting for all options is - changed. + * `--subcommand-props=,...` - The specs (maybe multiple `--cargo-args` options) are - cumulative and are processed in order. These options override - `-c`, `-C`. They can also effectively override other options - to nailing-cargo, such as `--offline` or `--target`. + Specify the properties of the subcommand. This is an + alternative to `-c`. The properties are: - `` is one of: - - * `@`: Decide automatically for this option (default). - * `+`: Definitely pass this option - * `-`: Definitely do not pass this option - * `_`: Definitely do not pass this option - and do not mind if `` is not known to nailing-cargo. - - * `-T` | `--no-cargo-target-dir-arg` | `-t` | `--cargo-target-dir-arg` - - `-T` suppresses `--target-dir`; `-t` un-suppresses it. Only - makes any difference with `-m`, since otherwise no - `--target-dir` would be passed anyway. Additionally this is - done automatically when nailing-cargo sees that the cargo - subcommand is one which needs it, eg `fetch`. - - * `-o` | `--online` | `-O` | `--offline` - - Whether to allow cargo to make network access. nailing-cargo - always passes `--offline` to cargo, unless `--online` is in - force. The default value depends on the configuration and the - cargo subcommand - see `[misc]` `online` in "Configuration". - -Arguments to the build command ------------------------------- - -xxx - * `-m` | `--cargo-manifest-args` | `-M` | `--no-cargo-manifest-args` - - Controls whether we add cargo command line options, relating to - finding `Cargo.toml`, to the command to run. - - Default is to add them if we are doing an out-of-tree build, - unless we are doing the dance to update the `Cargo.lock` (see - above) since in that case all the relevant files can be found - by cargo in the build directory. - - The arguments added are - - --manifest-path= - --locked - --target-dir=target + * `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. Environment of the build command -------------------------------- @@ -372,6 +342,11 @@ nailing-cargo passes these environment variables to the build command: 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=`. + Configuration reference ======================= @@ -512,6 +487,13 @@ Limitations and bugs At least, running nailing-cargo again will clean up any mess left by an interrupted run. + * 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 + add an entry to `@subcmd_propss` in the source, or use + `--subcommand-props`. + * Out of tree builds require a unified filesystem view: eg, different users on the same host, NFS, or something. diff --git a/nailing-cargo b/nailing-cargo index c9cdbb8..829d279 100755 --- a/nailing-cargo +++ b/nailing-cargo @@ -38,18 +38,24 @@ our $src_absdir = getcwd() // die "$self: getcwd failed: $!\n"; our $worksphere = $src_absdir; $worksphere =~ s{/([^/]+)$}{} - or die "$self: cwd \`$worksphere' unsupported!\n"; + or die "$self: cwd \`$worksphere' unsupported!\n";e our $subdir = $1; # leafname our $lockfile = "../.nailing-cargo.lock"; our $cargo_subcmd; -our $cargo_lock_update; -our $cargo_manifest_args; -our $cargo_target_arg=1; 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 ); +}; + our @configs; our $verbose=1; our ($noact,$dump); @@ -347,29 +353,21 @@ sub calculate () { } sub addargs () { + $online = 1 if subcmd_p('online'); $online //= cfg_bool qw(misc online); - - if ($cargo_subcmd =~ m/^(?:generate-lockfile|update)$/) { - $cargo_lock_update //= 1; - $target = undef; - } - if ($cargo_subcmd =~ m/^(?:fetch)$/) { - $cargo_target_arg=0; - $online //= 1; - } - $cargo_lock_update //= 0; - $cargo_manifest_args //= - (defined $oot_dir) && !$cargo_lock_update; - $online //= 0; - if ($cargo_manifest_args) { - push @ARGV, "--manifest-path=${src_absdir}/Cargo.toml", - qw(--locked); - push @ARGV, qw(--target-dir=target) if $cargo_target_arg; + $cargo_lock_update //= subcmd_p('lock-update'); + + if (!$cargo_lock_update) { + push @ARGV, 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'); + } } - if (defined $target) { + if (defined($target) && !subcmd_p('!target')) { if ($target =~ m{^[A-Z]}) { $target = (cfgs 'arch', $target) // $archmap{$target} // die "$self: --target=$target alias specified; not in cfg or map\n"; @@ -377,7 +375,7 @@ sub addargs () { push @ARGV, "--target=$target"; } - push @ARGV, "--offline" unless $online; + push @ARGV, "--offline" unless $online || subcmd_p('!offline'); } our $oot_absdir; @@ -687,16 +685,14 @@ sub parse_args () { $verbose=0; } elsif (s{^-n}{-}) { $noact++; + } elsif (s{^-c(.+)}{-}s) { + $cargo_subcmd = $1; + } elsif (s{^-C}{-}) { + $cargo_subcmd = ''; } elsif (s{^-D}{-}) { $dump++; - } elsif (s{^-A(.+)}{-}s) { + } elsif (s{^-T(.+)}{-}s) { $target = $1; - } elsif (s{^-([uU])}{-}) { - $cargo_lock_update= $1=~m/[a-z]/; - } elsif (s{^-([mM])}{-}) { - $cargo_manifest_args= $1=~m/[a-z]/; - } elsif (s{^-([tT])}{-}) { - $cargo_target_arg= $1=~m/[a-z]/; } elsif (s{^-([oO])}{-}) { $online= $1=~m/[a-z]/; } else { @@ -704,16 +700,22 @@ sub parse_args () { $not_a_nailing_opt->(); } } - } elsif (s{^--(?:target|arch)=}{}) { + } elsif (s{^--target=}{}) { $target = $_; - } elsif (m{^--(no-)?cargo-lock-update}) { - $cargo_lock_update= !!$1; - } elsif (m{^--(no-)?cargo-manifest-args}) { - $cargo_manifest_args= !!$1; - } elsif (m{^--(no-)?cargo-target-dir-arg}) { - $cargo_target_arg= !!$1; } elsif (m{^--(on|off)line$}) { $online = $1 eq 'on'; + } elsif (s{^--subcommand-props=}{}) { + my @props = split /\,/, $_; + our %subcmd_prop_ok; + if (!%subcmd_prop_ok) { + for $v in (%subcmd_props) { $subcmd_prop_ok{$_}=1 foreach @$v; }; + } + $subcmd_prop_ok{$_} + or die "$self: unknown subcommand property \`$_'\n" + foreach @props; + $cargo_subcmd = \@props; + } elsif (m{^--(no-)?cargo-lock-update}) { + $cargo_lock_update= !!$1; } else { $not_a_nailing_opt->(); } @@ -730,10 +732,14 @@ sub parse_args () { push @cargo_and_opts, $_; } @ARGV || die "$self: need cargo subcommand\n"; - $cargo_subcmd = $ARGV[0]; + $cargo_subcmd //= $ARGV[0]; unshift @ARGV, @cargo_and_opts; } else { - $cargo_subcmd = ''; + $cargo_subcmd //= ''; + } + + if (!ref($cargo_subcmd)) { + $cargo_subcmd = $subcmd_props{$cargo_subcmd} // [ ]; } } -- 2.30.2