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 }