make_announce 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. #!/usr/bin/perl -w
  2. #
  3. # Update the ANNOUNCE file for a new release.
  4. #
  5. # Usage: make_announce [new_version]
  6. #
  7. # Copyright 2016 Alexandre Julliard
  8. #
  9. # This library is free software; you can redistribute it and/or
  10. # modify it under the terms of the GNU Lesser General Public
  11. # License as published by the Free Software Foundation; either
  12. # version 2.1 of the License, or (at your option) any later version.
  13. #
  14. # This library is distributed in the hope that it will be useful,
  15. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. # Lesser General Public License for more details.
  18. #
  19. # You should have received a copy of the GNU Lesser General Public
  20. # License along with this library; if not, write to the Free Software
  21. # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  22. #
  23. use strict;
  24. use locale;
  25. use POSIX;
  26. use Text::CSV::Encoded;
  27. use open ':encoding(utf8)';
  28. sub unescape($)
  29. {
  30. my $str = shift;
  31. $str =~ s/"/\"/g;
  32. $str =~ s/'/\'/g;
  33. $str =~ s/&/&/g;
  34. $str =~ s/&lt;/</g;
  35. $str =~ s/&gt;/>/g;
  36. $str =~ s/&#64;/\@/g;
  37. return $str;
  38. }
  39. # update a file if changed
  40. sub update_file($)
  41. {
  42. my $file = shift;
  43. if (!(-f $file) || system "cmp $file $file.new >/dev/null")
  44. {
  45. rename "$file.new", "$file";
  46. print "$file updated\n";
  47. }
  48. else
  49. {
  50. unlink "$file.new";
  51. }
  52. }
  53. # determine the current version number
  54. sub get_current_version()
  55. {
  56. my $version;
  57. open VERSION, "<VERSION" or die "cannot open VERSION";
  58. if (<VERSION> =~ /Wine version (\S+)/) { $version = $1; }
  59. close VERSION;
  60. die "failed to parse VERSION" unless $version;
  61. return $version;
  62. }
  63. # retrieve a list of bugs with the specified filter
  64. sub get_bugs($)
  65. {
  66. my $filter = shift;
  67. my $csv = Text::CSV::Encoded->new({ encoding_in => "utf-8", encoding_out => "utf-8" });
  68. my %bugs;
  69. open QUERY, "-|" or exec "wget", "-qO-", "https://bugs.winehq.org/buglist.cgi?columnlist=short_desc&query_format=advanced&ctype=csv&$filter"
  70. or die "cannot query bug list";
  71. <QUERY>; # skip header line
  72. while (<QUERY>)
  73. {
  74. next unless $csv->parse($_);
  75. my ($id, $descr) = $csv->fields();
  76. $bugs{$id} = $descr;
  77. }
  78. close QUERY;
  79. return %bugs;
  80. }
  81. # retrieve the current list of authors
  82. sub get_authors()
  83. {
  84. my %authors;
  85. open AUTHORS, "<AUTHORS" or die "cannot open AUTHORS";
  86. <AUTHORS>; # skip header line
  87. while (<AUTHORS>)
  88. {
  89. chomp;
  90. next if /^$/;
  91. $authors{$_} = 1;
  92. }
  93. close AUTHORS;
  94. return %authors;
  95. }
  96. # determine the version number
  97. my $old = get_current_version();
  98. my $new = $ARGV[0];
  99. unless ($new)
  100. {
  101. if ($old =~ /^([0-9]+)\.([0-9]+)$/) { $new = "$1." . ($2 + 1); }
  102. elsif ($old =~ /^([0-9]+)\.([0-9]+)\.([0-9]+)$/) { $new = "$1.$2." . ($3 + 1); }
  103. elsif ($old =~ /^([0-9]+)\.([0-9]+)-rc([0-9]+)$/) { $new = "$1.$2-rc" . ($3 + 1); }
  104. else { die "unknown version format $old"; }
  105. }
  106. print "Updating files for release $new\n";
  107. my $reldir = $new;
  108. if ($reldir =~ /^([0-9]+\.0)/) { $reldir = $1; }
  109. elsif ($reldir =~ /^([0-9]+)\./) { $reldir = "$1.x"; }
  110. else { die "unknown version format $reldir"; }
  111. my $is_stable = ($new =~ /^([0-9]+)\.0\.([0-9]+)$/); # stable releases have a 0 minor number
  112. my $filter = "product=Wine&resolution=FIXED&" . ($is_stable ? "target_milestone=$reldir.x" : "bug_status=RESOLVED");
  113. my %bugs = get_bugs( $filter );
  114. my %authors = get_authors();
  115. # update the ANNOUNCE file
  116. open ANNOUNCE, "<ANNOUNCE" or die "cannot open ANNOUNCE";
  117. open NEW, ">ANNOUNCE.new" or die "cannot create ANNOUNCE.new";
  118. # replace version number in first line
  119. $_ = <ANNOUNCE>;
  120. s/(([0-9]+)\.)+[0-9]+(-rc[0-9]+)?/$new/;
  121. print NEW $_;
  122. while (<ANNOUNCE>)
  123. {
  124. last if /^------------------/;
  125. s!(https?://.*/wine/source/).*\.tar!$1$reldir/wine-$new.tar!;
  126. print NEW $_;
  127. }
  128. print NEW "----------------------------------------------------------------\n\n";
  129. printf NEW "Bugs fixed in %s (total %u):\n\n", $new, scalar( keys %bugs );
  130. foreach my $id (sort {$a <=> $b} keys %bugs)
  131. {
  132. printf NEW " %6d %s\n", $id, unescape( $bugs{$id} );
  133. }
  134. print NEW "\n----------------------------------------------------------------\n\n";
  135. print NEW "Changes since $old:\n\n";
  136. open LOG, "-|" or exec "git", "shortlog", "wine-$old..HEAD" or die "cannot run git shortlog";
  137. while (<LOG>)
  138. {
  139. if (/^(\S.*)\s\(\d+\):$/) { $authors{$1} = 1; }
  140. print NEW $_;
  141. }
  142. close LOG;
  143. while (<ANNOUNCE>) { last if /^--$/; }
  144. print NEW "--\n";
  145. while (<ANNOUNCE>) { print NEW $_; }
  146. close ANNOUNCE;
  147. close NEW;
  148. update_file( "ANNOUNCE" );
  149. # update the AUTHORS file
  150. setlocale( LC_COLLATE, "en_US.UTF-8" );
  151. open AUTHORS, ">AUTHORS.new" or die "cannot create AUTHORS.new";
  152. print AUTHORS "Wine is available thanks to the work of:\n\n", join( "\n", sort keys %authors ), "\n";
  153. close AUTHORS;
  154. update_file( "AUTHORS" );