| #!/usr/bin/perl -w | |
| # | |
| # Update the ANNOUNCE file for a new release. | |
| # | |
| # Usage: make_announce [new_version] | |
| # | |
| # Copyright 2016 Alexandre Julliard | |
| # | |
| # This library is free software; you can redistribute it and/or | |
| # modify it under the terms of the GNU Lesser General Public | |
| # License as published by the Free Software Foundation; either | |
| # version 2.1 of the License, or (at your option) any later version. | |
| # | |
| # This library is distributed in the hope that it will be useful, | |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| # Lesser General Public License for more details. | |
| # | |
| # You should have received a copy of the GNU Lesser General Public | |
| # License along with this library; if not, write to the Free Software | |
| # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA | |
| # | |
| use strict; | |
| use locale; | |
| use POSIX; | |
| use Text::CSV::Encoded; | |
| use open ':encoding(utf8)'; | |
| sub unescape($) | |
| { | |
| my $str = shift; | |
| $str =~ s/"/\"/g; | |
| $str =~ s/'/\'/g; | |
| $str =~ s/&/&/g; | |
| $str =~ s/</</g; | |
| $str =~ s/>/>/g; | |
| $str =~ s/@/\@/g; | |
| return $str; | |
| } | |
| # update a file if changed | |
| sub update_file($) | |
| { | |
| my $file = shift; | |
| if (!(-f $file) || system "cmp $file $file.new >/dev/null") | |
| { | |
| rename "$file.new", "$file"; | |
| print "$file updated\n"; | |
| } | |
| else | |
| { | |
| unlink "$file.new"; | |
| } | |
| } | |
| # determine the current version number | |
| sub get_current_version() | |
| { | |
| my $version; | |
| open VERSION, "<VERSION" or die "cannot open VERSION"; | |
| if (<VERSION> =~ /Wine version (\S+)/) { $version = $1; } | |
| close VERSION; | |
| die "failed to parse VERSION" unless $version; | |
| return $version; | |
| } | |
| # retrieve a list of bugs with the specified filter | |
| sub get_bugs($) | |
| { | |
| my $filter = shift; | |
| my $csv = Text::CSV::Encoded->new({ encoding_in => "utf-8", encoding_out => "utf-8" }); | |
| my %bugs; | |
| open QUERY, "-|" or exec "wget", "-qO-", "https://bugs.winehq.org/buglist.cgi?columnlist=short_desc&query_format=advanced&ctype=csv&$filter" | |
| or die "cannot query bug list"; | |
| <QUERY>; # skip header line | |
| while (<QUERY>) | |
| { | |
| next unless $csv->parse($_); | |
| my ($id, $descr) = $csv->fields(); | |
| $bugs{$id} = $descr; | |
| } | |
| close QUERY; | |
| return %bugs; | |
| } | |
| # retrieve the current list of authors | |
| sub get_authors() | |
| { | |
| my %authors; | |
| open AUTHORS, "<AUTHORS" or die "cannot open AUTHORS"; | |
| <AUTHORS>; # skip header line | |
| while (<AUTHORS>) | |
| { | |
| chomp; | |
| next if /^$/; | |
| $authors{$_} = 1; | |
| } | |
| close AUTHORS; | |
| return %authors; | |
| } | |
| # determine the version number | |
| my $old = get_current_version(); | |
| my $new = $ARGV[0]; | |
| unless ($new) | |
| { | |
| if ($old =~ /^([0-9]+)\.([0-9]+)$/) { $new = "$1." . ($2 + 1); } | |
| elsif ($old =~ /^([0-9]+)\.([0-9]+)\.([0-9]+)$/) { $new = "$1.$2." . ($3 + 1); } | |
| elsif ($old =~ /^([0-9]+)\.([0-9]+)-rc([0-9]+)$/) { $new = "$1.$2-rc" . ($3 + 1); } | |
| else { die "unknown version format $old"; } | |
| } | |
| print "Updating files for release $new\n"; | |
| my $reldir = $new; | |
| if ($reldir =~ /^([0-9]+\.0)/) { $reldir = $1; } | |
| elsif ($reldir =~ /^([0-9]+)\./) { $reldir = "$1.x"; } | |
| else { die "unknown version format $reldir"; } | |
| my $is_stable = ($new =~ /^([0-9]+)\.0\.([0-9]+)$/); # stable releases have a 0 minor number | |
| my $filter = "product=Wine&resolution=FIXED&" . ($is_stable ? "target_milestone=$reldir.x" : "bug_status=RESOLVED"); | |
| my %bugs = get_bugs( $filter ); | |
| my %authors = get_authors(); | |
| # update the ANNOUNCE file | |
| open ANNOUNCE, "<ANNOUNCE" or die "cannot open ANNOUNCE"; | |
| open NEW, ">ANNOUNCE.new" or die "cannot create ANNOUNCE.new"; | |
| # replace version number in first line | |
| $_ = <ANNOUNCE>; | |
| s/(([0-9]+)\.)+[0-9]+(-rc[0-9]+)?/$new/; | |
| print NEW $_; | |
| while (<ANNOUNCE>) | |
| { | |
| last if /^------------------/; | |
| s!(https?://.*/wine/source/).*\.tar!$1$reldir/wine-$new.tar!; | |
| print NEW $_; | |
| } | |
| print NEW "----------------------------------------------------------------\n\n"; | |
| printf NEW "Bugs fixed in %s (total %u):\n\n", $new, scalar( keys %bugs ); | |
| foreach my $id (sort {$a <=> $b} keys %bugs) | |
| { | |
| printf NEW " %6d %s\n", $id, unescape( $bugs{$id} ); | |
| } | |
| print NEW "\n----------------------------------------------------------------\n\n"; | |
| print NEW "Changes since $old:\n\n"; | |
| open LOG, "-|" or exec "git", "shortlog", "wine-$old..HEAD" or die "cannot run git shortlog"; | |
| while (<LOG>) | |
| { | |
| if (/^(\S.*)\s\(\d+\):$/) { $authors{$1} = 1; } | |
| print NEW $_; | |
| } | |
| close LOG; | |
| while (<ANNOUNCE>) { last if /^--$/; } | |
| print NEW "--\n"; | |
| while (<ANNOUNCE>) { print NEW $_; } | |
| close ANNOUNCE; | |
| close NEW; | |
| update_file( "ANNOUNCE" ); | |
| # update the AUTHORS file | |
| setlocale( LC_COLLATE, "en_US.UTF-8" ); | |
| open AUTHORS, ">AUTHORS.new" or die "cannot create AUTHORS.new"; | |
| print AUTHORS "Wine is available thanks to the work of:\n\n", join( "\n", sort keys %authors ), "\n"; | |
| close AUTHORS; | |
| update_file( "AUTHORS" ); |