3 # Update an older edition of What's Cooking with the latest data.
5 # Usage: UWC [--keep-master] [ old [ new ] ]
7 # Giving no parameter is the same as giving a single "-" to the command.
9 # The command reads the old edition of (annotated) "What's Cooking"
10 # message from "old", and "new". If "old" is "-", it is read from
11 # the standard input. If "new" is not specified, WC script is run
12 # and its output is used.
14 # An annotated "What's Cooking" message can have group header (a line
15 # that has the group name enclosed in "[" and "]"), and annotatation
16 # paragraphs after each topic's commit list, in addition to the bare
19 # The group headers, topics in each group and their order in the group,
20 # and annotation to topics are preserved from the "old" message. The
21 # list of commits in each topic is replaced with the one taken from the
22 # "new" message. Any topic in "new" that did not exist in "old" appear
23 # in "New Topics" group. Also, topics that do not appear in the "new"
24 # message are marked with <<deleted>>, topics whose commit list are
25 # different from "old" are marked with <<updated from...>>>.
27 # Typically the maintainer would place the What's Cooking message
28 # previously sent in a buffer in Emacs, and filter the buffer contents
29 # with this script, to prepare an up-to-date message.
33 sub parse_whats_cooking
{
37 my %wc = ("group list" => [], "topic hash" => {});
39 my $skipping_comment = 0;
48 if (/^Here are the topics that have been/) {
58 if ($skipping_comment) {
60 $skipping_comment = 0;
65 if (!$skipping_comment && /^<</) {
66 $skipping_comment = 1;
72 push @
{$wc{"group list"}}, $group;
78 if (!defined $group) {
79 if (/^\* (\S+) (\(.*\) \d+ commits?)$/) {
82 push @
{$wc{"group list"}}, $group;
90 if (/^\* (\S+) (\(.*\) \d+ commits?)$/) {
97 $wc{"topic hash"}{$topic->{"topic"}} = $topic;
98 push @
{$wc{" $group"}}, $topic;
102 if (/^ [-+.?*] / || /^ \S/) {
103 $topic->{"names"} .= $_;
106 $topic->{"text"} .= $_;
113 $wc{"head text"} = $head;
114 for $topic (values %{$wc{"topic hash"}}) {
115 for ($topic->{"text"}) {
123 sub print_whats_cooking
{
126 print $wc->{"head text"}, "\n";
128 for my $group (@
{$wc->{"group list"}}) {
129 print "\n", "-" x
64, "\n";
131 for my $topic (@
{$wc->{" $group"}}) {
132 next if ($topic->{"head"} eq '');
133 print "\n", $topic->{"head"};
134 print $topic->{"names"};
135 if ($topic->{"text"} ne '') {
136 print "\n", $topic->{"text"}, "\n";
143 my ($wc, $topic) = @_;
144 $topic->{"status"} = "deleted";
147 sub merge_whats_cooking
{
148 my ($old_wc, $new_wc) = @_;
152 for $group (@
{$old_wc->{"group list"}}) {
153 for my $topic (@
{$old_wc->{" $group"}}) {
154 my $name = $topic->{"topic"};
155 my $newtopic = delete $new_wc->{"topic hash"}{$name};
157 if (!defined $newtopic) {
158 push @gone, +{ @
{[ %$topic ]} };
159 $topic->{"text"} = "";
160 $topic->{"names"} = "";
161 $topic->{"head"} = "";
164 if (($newtopic->{"names"} ne $topic->{"names"}) ||
165 ($newtopic->{"head"} ne $topic->{"head"})) {
166 my $text = ("<<updated from\n" .
168 $topic->{"names"} . ">>");
170 if ($topic->{"text"} ne '') {
171 $text .= "\n\n" . $topic->{"text"};
177 $topic->{"text"} = $text;
178 $topic->{"names"} = $newtopic->{"names"};
179 $topic->{"head"} = $newtopic->{"head"};
185 $group = 'Graduated to "master"';
187 print STDERR
"Not Keeping Master\n";
188 my $o = delete $old_wc->{" $group"};
190 print STDERR
" Dropping: ", $_->{'topic'}, "\n";
192 print STDERR
"Gone are\n";
194 print STDERR
" Gone: ", $_->{'topic'}, "\n";
198 if (!exists $old_wc->{" $group"}) {
199 unshift @
{$old_wc->{"group list"}}, $group;
200 $old_wc->{" $group"} = [];
202 push @
{$old_wc->{" $group"}}, @gone;
204 if (%{$new_wc->{"topic hash"}}) {
205 $group = "New Topics";
206 if (!exists $old_wc->{" $group"}) {
207 unshift @
{$old_wc->{"group list"}}, $group;
208 $old_wc->{" $group"} = [];
210 for my $topic (values %{$new_wc->{"topic hash"}}) {
211 my $name = $topic->{"topic"};
212 $old_wc->{"topic hash"}{$name} = $topic;
213 push @
{$old_wc->{" $group"}}, $topic;
214 $topic->{"text"} = $topic->{"text"};
221 } elsif ($ARGV[0] eq '--keep-master') {
225 if (@ARGV != 2 && @ARGV != 1) {
226 die "Usage: $0 old [new]\n";
229 my ($old_wc, $new_wc);
231 if ($ARGV[0] eq '-') {
236 $old_wc = parse_whats_cooking
(\
*FH
);
242 open FH
, "Meta/WC generate |";
244 $new_wc = parse_whats_cooking
(\
*FH
);
247 merge_whats_cooking
($old_wc, $new_wc);
248 print_whats_cooking
($old_wc);