X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=nailing-cargo;h=c9ee071e3f578305207da6ba4440408434ff54cf;hb=refs%2Fheads%2Fmain;hp=c1b21ec0d14082b7280ef7d111128ba8a819beb1;hpb=e859006aea057da0d33e48da659638dbb68c65b9;p=nailing-cargo.git diff --git a/nailing-cargo b/nailing-cargo index c1b21ec..c9ee071 100755 --- a/nailing-cargo +++ b/nailing-cargo @@ -27,7 +27,11 @@ options: -h --help Print this message --doc --man --manual Display complete manual (in w3m) --leave-nailed Leave the nailed Cargo.toml in place - --just-linkfarm | --clean-linkfarm | --keep-linkfarm (default) + -E | --edits-sources Allow source edits (repeat: file creation) + -f | --force Override some warnings + --linkfarm[=no|shallow|git|full] (default varies, usually "no") + --just-linkfarm | --clean-linkfarm | --keep-linkfarm (default is keep) + --[no-]preclean-build[=no|src|full] (default is no) --just-run Run the command, don't do cargo stuff --no-nail Do not nail, just run the command. --no-cargo-lock-manip Do not manipulate Cargo.lock. @@ -49,6 +53,7 @@ use Cwd qw(realpath); our $base_path; our %archmap = ( RPI => 'arm-unknown-linux-gnueabihf', + WASM => 'wasm32-unknown-unknown', ); BEGIN { @@ -94,6 +99,7 @@ our $online; our $just_linkfarm; our $leave_nailed; our $oot_clean; +our $oot_preclean; our $do_nail=1; our $do_cargo_lock=1; our $do_lock=1; @@ -101,16 +107,24 @@ our $linkfarm_depth; # our %subcmd_props = ( -# build (default) =>[qw( )], -'generate-lockfile'=>[qw( lock-update !target !target-dir )], - update =>[qw( lock-update !target online )], - fetch =>[qw( online !target-dir )], +# build (default) =>[qw( )], + fetch =>[qw( online !target-dir )], + fmt =>[qw( !locked !target !offline !target-dir edits )], +'generate-lockfile'=>[qw( lock-update !target !target-dir )], + init =>[qw( creates )], + metadata =>[qw( !target-dir )], + miri =>[qw( !locked !offline linkfarm-shallow )], + publish =>[qw( !offline linkfarm-gitclean )], + update =>[qw( lock-update !target online )], + upgrades =>[qw( !locked !target-dir )], ); -our @subcmd_xprops = qw(!manifest-path !offline !locked); +our @subcmd_xprops = qw(!manifest-path); our @configs; our $verbose=1; +our $force=0; +our $forced=0; our ($noact,$dump); our $target; @@ -126,6 +140,17 @@ sub show_manual () { die "$self: exec sh failed: $!"; } +sub forceable_warning ($) { + my ($m) = @_; + print STDERR "$self: *WARNING*: $m\n"; + if ($force) { + print STDERR "$self: continuing because of --force...\n" unless $forced++; + return; + } else { + die "$self: Stopping due to warning (override with -f | --force)\n"; + } +} + sub read_or_enoent ($) { my ($fn) = @_; if (!open R, '<', $fn) { @@ -517,11 +542,12 @@ sub calculate () { my ($toml, $mf_org_subdir) = @{ $manifests{$mf} }; foreach my $deps (get_dependency_tables $toml) { next unless $deps; - foreach my $p (keys %packagemap) { - my $info = $deps->{$p}; - next unless defined $info; + foreach my $dep_key (keys %$deps) { + my $info = $deps->{$dep_key}; + my $p = (ref $info ? $info->{package} : undef) // $dep_key; + next unless defined $packagemap{$p}; next if $packagemap{$p}[1] eq $mf_org_subdir; - $deps->{$p} = $info = { } unless ref $info; + $deps->{$dep_key} = $info = { } unless ref $info; # was just version my $oldpath = $info->{path}; delete $info->{version}; my $newpath = $worksphere.'/'.$packagemap{$p}[0]; @@ -568,8 +594,26 @@ sub addargs () { $online //= 1 if subcmd_p('online'); $online //= 0; + if (($linkfarm_depth//'') eq 'copy-edit-all') { + $oot_preclean //= 'src'; + if ($oot_preclean !~ m/^(?:src|full)$/) { + forceable_warning + "-EE specified, but also --preclean=no; will probably leave your source tree full of junk"; + } + } + + if (subcmd_p('linkfarm-gitclean')) { + $linkfarm_depth //= 'git'; + $oot_preclean //= 'src'; + } + $cargo_lock_update //= subcmd_p('lock-update'); - $linkfarm_depth //= $cargo_lock_update ? 'shallow' : ''; + $linkfarm_depth //= + subcmd_p('linkfarm-shallow') ? 'shallow' : + $cargo_lock_update ? 'shallow' : + ''; + + $oot_preclean //= 'no'; our @add; @@ -594,6 +638,14 @@ sub addargs () { push @add, "--offline" unless $online || subcmd_p('!offline'); + if (subcmd_p('creates') && $linkfarm_depth !~ m/^copy-edit-all/) { + forceable_warning + "this subcommand expects to create new source files; you probably want to specify --edits-sources twice aka -EE (which is not the default even now, for safety reasons)"; + } elsif (subcmd_p('edits') && $linkfarm_depth !~ m/^copy-edit/) { + forceable_warning + "this subcommand expects to edit the source code; you probably want to specify --edits-sources aka -E (which is not the default even now, for safety reasons)"; + } + push @args_preface, @add if $pass_options; die if grep { m/ / } @add; $ENV{NAILINGCARGO_CARGO_OPTIONS} = "@add"; @@ -618,9 +670,14 @@ sub oot_massage_cmdline () { } else { push @xargs, $oot_absdir, $subdir, $src_absdir; $pre = <<'END_BOTH'; - cd "$1"; shift; - mkdir -p -- "$1"; cd "$1"; shift; src="$1"; shift; + bld="$1"; shift; sd="$1"; shift; src="$1"; shift; + cd "$bld"; mkdir -p -- "$sd"; cd "$sd"; END_BOTH + if ($oot_preclean ne 'no') { + $pre.= "find . -maxdepth 1 ! -path ."; + $pre.= " ! -path ./target" if $oot_preclean ne 'full'; + $pre.= " -print0 | xargs -0r rm -r --;" + } if ($linkfarm_depth eq 'shallow') { $pre.= <<'END_SHALLOW'; clean () { find -lname "$src/*" -print0 | xargs -0r rm --; }; clean; @@ -630,7 +687,7 @@ END_BOTH ln -sf -- "$f" .; done'; END_SHALLOW - } else { + } elsif ($linkfarm_depth =~ /full|git/) { $pre .= <<'END_EITHER_DEEP_DIRS'; clean () { find -follow -lname "$src/*" -print0 | xargs -0r rm --; }; (set -e; cd "$src"; find . \! -name Cargo.lock \! \( -name .git -prune \) \! -path . \! -name .git -type d -print0) | @@ -649,10 +706,37 @@ END_FILES_GIT END_FILES_FULL } $pre .= <<'END_DEEP'; - xargs -0r sh -ec 'src="$1"; shift; for f in "$@"; do - ln -sf -- "$src/${f#./}" "$f"; - done' x "$src"; + perl -0 -ne ' + BEGIN { $src=shift @ARGV; } + next if (readlink "$_"//"") eq "$src/$_"; + unlink "$_"; + symlink "$src/$_", "$_" or die "$_ $!"; + ' "$src"; END_DEEP + } elsif ($linkfarm_depth =~ m/^copy-edit/) { + $pre .= <<'END_COPY_EDIT'; + find -lname "$src/*" -print0 | xargs -0r rm --; + (set -e; cd "$src"; git ls-files -c -z | + cpio --quiet -p0m --no-preserve-owner -u --make-directories "$bld/$sd"); + clean () { + (set -e; cd "$src"; git ls-files -c -z) | xargs -0r rm -f --; + }; +END_COPY_EDIT + if ($linkfarm_depth eq 'copy-edit-all') { + $post .= <<'END_COPY_EDIT_GENFILES_ALL'; + find -xdev \( \( -name .git -o -path ./target -o -path ./nailing-cargo-update.tar \) -prune \) -o + \( -type l -o -type f \) -print0 | +END_COPY_EDIT_GENFILES_ALL + } else { + $post .= <<'END_COPY_EDIT_GENFILES_GIT'; + (set -e; cd "$src"; git ls-files -c -z) | +END_COPY_EDIT_GENFILES_GIT + } + $post .= <<'END_COPY_EDIT_BUNDLE'; + cpio -Hustar -o0 --quiet >"nailing-cargo-update.tar"; +END_COPY_EDIT_BUNDLE + } else { + die "$linkfarm_depth ?"; } $pre .= <<'ENDLK' if $do_cargo_lock; if test -e Cargo.lock; then @@ -660,7 +744,7 @@ END_DEEP cp -- "$src"/Cargo.lock .; fi; ENDLK - $post = <<'ENDCLEAN' if $oot_clean && !$just_linkfarm; + $post .= <<'ENDCLEAN' if $oot_clean && !$just_linkfarm; clean; ENDCLEAN } @@ -729,7 +813,7 @@ END } sub setenvs () { - $ENV{CARGO_MANIFEST_DIR} = $src_absdir; + $ENV{CARGO_MANIFEST_DIR} = $src_absdir unless $linkfarm_depth; $ENV{NAILINGCARGO_MANIFEST_DIR} = $src_absdir; $ENV{NAILINGCARGO_WORKSPHERE} = $worksphere; $ENV{NAILINGCARGO_BUILDSPHERE} = $oot_absdir; @@ -858,8 +942,26 @@ sub invoke () { } } -sub cargo_lock_update_after () { - if ($do_cargo_lock && $cargo_lock_update && !$just_linkfarm) { +sub files_return_after_update () { + if ($linkfarm_depth =~ m/^copy-edit/) { + my $tar_source_opts; + my $tar_stdin; + if ($linkfarm_depth eq 'copy-edit-all') { + $tar_source_opts = '--null --files-from=-'; + $tar_stdin = <<'END_GIT_FILES'; + git ls-files -c -z | \ +END_GIT_FILES + } else { + $tar_source_opts = '--anchored --exclude=.git --exclude="*/.git" --exclude=target --exclude=nailing-cargo-update.tar'; + $tar_stdin = ''; + } + system qw(sh -ec), $tar_stdin . <<'END', 'x', "$build_absdir"; + tar -x --keep-newer-files --no-same-permissions --no-same-owner \ + --no-acls --no-selinux --no-xattrs --warning=no-ignore-newer \ + -Hustar $tar_source_opts --force-local \ + -f "$1/nailing-cargo-update.tar" +END + } elsif ($do_cargo_lock && $cargo_lock_update && !$just_linkfarm) { # avoids importing File::Copy and the error handling is about as good $!=0; $?=0; my $r= system qw(cp --), "$build_absdir/Cargo.lock", "Cargo.lock"; @@ -929,6 +1031,11 @@ sub parse_args () { $not_a_nailing_opt->() unless m{^-}; $not_a_nailing_opt->() if $_ eq '--'; + my $edits_sources = sub { + $linkfarm_depth = + ($linkfarm_depth//'') eq 'copy-edit' ? 'copy-edit-all' : 'copy-edit'; + }; + if ($_ eq '---') { # usage 2 or 3 if (!@ARGV) { die "$self: --- must be followed by build command\n" unless $noact; @@ -956,6 +1063,8 @@ sub parse_args () { $verbose=0; } elsif (s{^-n}{-}) { $noact++; + } elsif (s{^-f}{-}) { + $force++; } elsif (s{^-s(.+)}{-}s) { $cargo_subcmd = $1; } elsif (s{^-([uU])}{-}) { @@ -964,6 +1073,8 @@ sub parse_args () { $pass_options = $1=~m/[a-z]/; } elsif (s{^-D}{-}) { $dump++; + } elsif (s{^-E}{-}) { + $edits_sources->(); } elsif (s{^-T(.+)}{-}s) { $target = $1; } elsif (s{^-([oO])}{-}) { @@ -983,19 +1094,27 @@ sub parse_args () { $online = $1 eq 'on'; } elsif (m{^--just-linkfarm(?:=(shallow|git|full))?$}) { $just_linkfarm = 1; - $linkfarm_depth = 1 if $1; + $linkfarm_depth = $1 if $1; $cargo_lock_update= 1; # will set $linkfarm_detph to 1 by default } elsif (m{^--linkfarm(?:=(no|shallow|git|full))?$}) { $linkfarm_depth = $1 || 'git'; + } elsif (m{^--edits?-sources?$}) { + $edits_sources->(); + } elsif (m{^--force$}) { + $force++; } elsif (m{^--just-run$}) { $do_nail = $do_cargo_lock = $do_lock = 0; } elsif (m{^--(clean|keep)-linkfarm$}) { $oot_clean = $1 eq 'clean'; - } elsif (m{^--(no)?-nail$}) { + } elsif (m{^--(no-)?preclean-build$}) { + $oot_preclean = $1 ? 'no' : 'src'; + } elsif (m{^--preclean-build=(no|src|full)$}) { + $oot_preclean = $1; + } elsif (m{^--(no-)?nail$}) { $do_nail = !$1; - } elsif (m{^--(no)?-cargo-lock-manip$}) { + } elsif (m{^--(no-)?cargo-lock-manip$}) { $do_cargo_lock = !$1; - } elsif (m{^--(no)?-concurrency-lock$}) { + } elsif (m{^--(no-)?concurrency-lock$}) { $do_lock = !$1; } elsif (m{^--leave-nailed$}) { $leave_nailed = 1; @@ -1024,7 +1143,7 @@ sub parse_args () { if ($is_cargo) { @args_preface = shift @ARGV; while (defined($_ = shift @ARGV)) { - if (!m{^-}) { unshift @ARGV, $_; last; } + if (!m{^-|^\+}) { unshift @ARGV, $_; last; } if ($_ eq '--') { last; } push @args_preface, $_; } @@ -1072,7 +1191,11 @@ if ($dump) { subdir => $subdir, oot_dir => $oot_dir, oot_absdir => $oot_absdir, - build_absdir => $build_absdir }); + build_absdir => $build_absdir, + linkfarm_depth => $linkfarm_depth, + oot_preclean => $oot_preclean, + force => $force,, + forced => $forced,}); ' or die $@; } @@ -1090,7 +1213,7 @@ printf STDERR "$self: nailed (%s manifests, %s packages)%s\n", print STDERR "$self: invoking: @display_cmd\n" if $verbose; my $estatus = invoke(); -cargo_lock_update_after(); +files_return_after_update(); uninstall() unless $leave_nailed; $want_uninstall = 0;