github.com/containers/podman/v5@v5.1.0-rc1/hack/markdown-preprocess-review (about)

     1  #!/usr/bin/perl
     2  
     3  (our $ME = $0) =~ s|^.*/||;
     4  
     5  use v5.20;
     6  
     7  our $DSM = 'docs/source/markdown';
     8  
     9  my ($oldname, $newname);
    10  my %oldname;
    11  my %changed;
    12  open my $git_diff, '-|', 'git', 'log', '-1', '-p'
    13      or die "$ME: Cannot fork: $!\n";
    14  while (my $line = <$git_diff>) {
    15      chomp $line;
    16  
    17      if ($line =~ m!^\-\-\-\s+a/$DSM/(podman-\S+\.md(\.in)?)!) {
    18          $oldname = $1;
    19          $newname = undef;
    20      }
    21      elsif ($line =~ m!^\+\+\+\s+b/$DSM/(podman-\S+\.md(\.in)?)!) {
    22          $newname = $1;
    23          $oldname{$newname} = $oldname;
    24      }
    25      elsif ($newname) {
    26          if ($line =~ s/^-####\s+//) {
    27              $line =~ /^\*\*--(\S+?)\*\*/
    28                  or die "$ME: in $newname: weird '$line'";
    29              $changed{$newname}{$1}{name} //= $1;
    30          }
    31          # Usually the same, but not for host.container and host.pod.md
    32          elsif ($line =~ /^\+\@\@option\s+(\S+)/) {
    33              my $optfile = $1;
    34              if ($optfile =~ /^(.*)\.\S+$/) {
    35                  $changed{$newname}{$1}{name} = $optfile;
    36              }
    37          }
    38      }
    39  }
    40  close $git_diff;
    41  
    42  # Pass 2: read each oldfile, parse changed options
    43  for my $f (sort keys %changed) {
    44      my $oldfile = $oldname{$f};
    45      open my $git_fh, '-|', 'git', 'show', "HEAD^:$DSM/$oldfile"
    46          or die "$ME: Cannot fork: $!\n";
    47      my $opt;
    48      while (my $line = <$git_fh>) {
    49          if ($line =~ /^####\s+\*\*--(\S+?)\*\*/) {
    50              $opt = $1;
    51              if ($changed{$f}{$opt}) {
    52                  $changed{$f}{$opt}{text} = $line;
    53              }
    54              else {
    55                  undef $opt;
    56              }
    57          }
    58          elsif ($line =~ /^#/ || $line =~ /^\@\@option\s/) {
    59              undef $opt;
    60          }
    61          elsif ($opt) {
    62              $changed{$f}{$opt}{text} .= $line;
    63          }
    64      }
    65      close $git_fh
    66          or die "$ME: Error running git on $oldfile\n";
    67  }
    68  
    69  # Pass 3: write out files
    70  my $tempdir = "/tmp/$ME.diffs";
    71  system('rm', '-rf', $tempdir);
    72  mkdir $tempdir, 0755;
    73  
    74  for my $md_file (sort keys %changed) {
    75      for my $opt (sort keys %{$changed{$md_file}}) {
    76          my $d = "$tempdir/$changed{$md_file}{$opt}{name}";
    77          mkdir $d, 0755;
    78  
    79          my $outfile = "$d/$md_file";
    80          open my $fh, '>', $outfile
    81              or die "$ME: Cannot create $outfile: $!\n";
    82          # strip all trailing newlines
    83          (my $text = $changed{$md_file}{$opt}{text}) =~ s/\n+$/\n/s;
    84          print { $fh } $text;
    85          close $fh
    86              or die "$ME: Error writing $outfile: $!\n";
    87  
    88          my $new_text = "$DSM/options/$changed{$md_file}{$opt}{name}.md";
    89          die "$ME: $md_file: File does not exist: $new_text\n" if ! -e $new_text;
    90          system('cp', $new_text, "$d/zzz-chosen.md");
    91      }
    92  }
    93  
    94  # Now run diffuse
    95  chdir $tempdir or die;
    96  my @all_opts = glob("*");
    97  for my $i (0..$#all_opts) {
    98      my $opt = $all_opts[$i];
    99      chdir "$tempdir/$opt"
   100          or die "??? Internal error, cannot cd $tempdir/$opt: $!";
   101  
   102      $| = 1; printf "--%s (%d/%d) ", $opt, $i+1, scalar(@all_opts);
   103  
   104      my @all_files = glob("*");
   105      if (all_files_identical(@all_files)) {
   106          pop @all_files;
   107          print "[identical between @all_files]\n";
   108          next;
   109      }
   110  
   111      # Prompt
   112      print "[Y/n/q] ";
   113      my $ans = <STDIN>;
   114      next if $ans =~ /^n/i;
   115      exit 0 if $ans =~ /^q/i;
   116  
   117      # Try to cull the files (remove identical ones)
   118      my @files = glob("*");
   119      my $winner = pop @files;
   120  
   121      for my $f (@files) {
   122          system('cmp', '-s', $f, $winner);
   123          if ($? == 0) {
   124              print "[ $f is the one we went with; removing from list ]\n";
   125              unlink $f;
   126              next;
   127          }
   128  
   129          system('wdiff', '-1', '-2', '-3', $f, $winner);
   130          if ($? == 0) {
   131              print "[ $f is whitespace-identical with what we went with ]\n";
   132              unlink $f;
   133              next;
   134          }
   135      }
   136  
   137      # Recompute @files, in case some were deleted above
   138      @files = glob("*"); pop @files;
   139  
   140      for (my $i=0; $i < $#files; $i++) {
   141          my $f1 = $files[$i];
   142          next unless -e $f1;
   143  
   144          for (my $j=$i+1; $j <= $#files; $j++) {
   145              my $f2 = $files[$j];
   146              next unless -e $f2;
   147  
   148              system('wdiff', '-1', '-2', '-3', $f1, $f2);
   149              if ($? == 0) {
   150                  print "[ $f2 : removing, it =~ $f1 ]\n";
   151                  unlink $f2;
   152              }
   153          }
   154      }
   155  
   156      # Recompute @files, in case some were deleted above
   157      @files = glob("*");
   158  
   159      # diffuse works great for 3-4 files, passable for 5, not at all for >5
   160      if (@files <= 5) {
   161          system("diffuse", "-w", @files) == 0
   162              or die "Diffuse failed\n";
   163      }
   164      else {
   165          # Too many files. Go by threes.
   166          my $winner = pop @files;
   167          for (my $i=0; $i < @files; $i += 3) {
   168              system("diffuse", "-w", @files[$i..$i+2], $winner);
   169          }
   170      }
   171  }
   172  
   173  
   174  sub all_files_identical {
   175      my %sha;
   176      for my $f (@_) {
   177          my $result = qx{sha256sum $f};
   178          $result =~ /^([0-9a-f]+)\s/
   179              or die "Internal error: unexpected result from sha256sum $f: $result";
   180          $sha{$1}++;
   181      }
   182  
   183      return (keys(%sha) == 1);
   184  }