Adding upstream version 2.25.15.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
This commit is contained in:
parent
10737b110a
commit
b543f2e88d
485 changed files with 191459 additions and 0 deletions
429
scripts/plotchangelog.pl
Executable file
429
scripts/plotchangelog.pl
Executable file
|
@ -0,0 +1,429 @@
|
|||
#!/usr/bin/perl
|
||||
#
|
||||
# Plot the history of a debian package from the changelog, displaying
|
||||
# when each release of the package occurred, and who made each release.
|
||||
# To make the graph a little more interesting, the debian revision of the
|
||||
# package is used as the y axis.
|
||||
#
|
||||
# Pass this program the changelog(s) you wish to be plotted.
|
||||
#
|
||||
# Copyright 1999 by Joey Hess <joey@kitenet.net>
|
||||
# Modifications copyright 2003 by Julian Gilbey <jdg@debian.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use 5.006;
|
||||
use strict;
|
||||
use FileHandle;
|
||||
use File::Basename;
|
||||
use File::Temp qw/ tempfile /;
|
||||
use Fcntl;
|
||||
use Getopt::Long qw(:config bundling permute no_getopt_compat);
|
||||
|
||||
BEGIN {
|
||||
pop @INC if $INC[-1] eq '.';
|
||||
eval { require Date::Parse; import Date::Parse(); };
|
||||
if ($@) {
|
||||
my $progname = basename($0);
|
||||
if ($@ =~ /^Can\'t locate Date\/Parse\.pm/) {
|
||||
die
|
||||
"$progname: you must have the libtimedate-perl package installed\nto use this script\n";
|
||||
} else {
|
||||
die
|
||||
"$progname: problem loading the Date::Parse module:\n $@\nHave you installed the libtimedate-perl package?\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
my $progname = basename($0);
|
||||
my $modified_conf_msg;
|
||||
|
||||
sub usage {
|
||||
print <<"EOF";
|
||||
Usage: plotchangelog [options] changelog ...
|
||||
-v --no-version Do not show package version information.
|
||||
-m --no-maint Do not show package maintainer information.
|
||||
-u --urgency Use larger points for higher urgency uploads.
|
||||
-l --linecount Make the Y axis be number of lines in the
|
||||
changelog.
|
||||
-b --bugcount Make the Y axis be number of bugs closed
|
||||
in the changelog.
|
||||
-c --cumulative With -l or -b, graph the cumulative number
|
||||
of lines or bugs closed.
|
||||
-g "commands" Pass "commands" on to gnuplot, they will be
|
||||
--gnuplot="commands" added to the gnuplot script that is used to
|
||||
generate the graph.
|
||||
-s file --save=file Save the graph to the specified file in
|
||||
postscript format.
|
||||
-d --dump Dump gnuplot script to stdout.
|
||||
--verbose Outputs the gnuplot script.
|
||||
--help Show this message.
|
||||
--version Display version and copyright information.
|
||||
--noconf --no-conf Don\'t read devscripts configuration files
|
||||
Must be the first option.
|
||||
|
||||
At most one of -l and -b (or their long equivalents) may be used.
|
||||
|
||||
Default settings modified by devscripts configuration files:
|
||||
$modified_conf_msg
|
||||
EOF
|
||||
}
|
||||
|
||||
my $versioninfo = <<"EOF";
|
||||
This is $progname, from the Debian devscripts package, version ###VERSION###
|
||||
This code is copyright 1999 by Joey Hess <joey\@kitenet.net>.
|
||||
Modifications copyright 1999-2003 by Julian Gilbey <jdg\@debian.org>
|
||||
This program comes with ABSOLUTELY NO WARRANTY.
|
||||
You are free to redistribute this code under the terms of the
|
||||
GNU General Public License, version 2 or later.
|
||||
EOF
|
||||
|
||||
my (
|
||||
$no_version, $no_maintainer, $gnuplot_commands, $dump,
|
||||
$save_filename, $verbose, $linecount, $bugcount,
|
||||
$cumulative, $help, $showversion, $show_urgency,
|
||||
$noconf
|
||||
) = "";
|
||||
|
||||
# Handle config file unless --no-conf or --noconf is specified
|
||||
# The next stuff is boilerplate
|
||||
my $extra_gnuplot_commands = '';
|
||||
if (@ARGV and $ARGV[0] =~ /^--no-?conf$/) {
|
||||
$modified_conf_msg = " (no configuration files read)";
|
||||
shift;
|
||||
} else {
|
||||
my @config_files = ('/etc/devscripts.conf', '~/.devscripts');
|
||||
my %config_vars = (
|
||||
'PLOTCHANGELOG_OPTIONS' => '',
|
||||
'PLOTCHANGELOG_GNUPLOT' => '',
|
||||
);
|
||||
my %config_default = %config_vars;
|
||||
|
||||
my $shell_cmd;
|
||||
# Set defaults
|
||||
foreach my $var (keys %config_vars) {
|
||||
$shell_cmd .= "$var='$config_vars{$var}';\n";
|
||||
}
|
||||
$shell_cmd .= 'for file in ' . join(" ", @config_files) . "; do\n";
|
||||
$shell_cmd .= '[ -f $file ] && . $file; done;' . "\n";
|
||||
# Read back values
|
||||
foreach my $var (keys %config_vars) { $shell_cmd .= "echo \$$var;\n" }
|
||||
my $shell_out = `/bin/bash -c '$shell_cmd'`;
|
||||
@config_vars{ keys %config_vars } = split /\n/, $shell_out, -1;
|
||||
|
||||
foreach my $var (sort keys %config_vars) {
|
||||
if ($config_vars{$var} ne $config_default{$var}) {
|
||||
$modified_conf_msg .= " $var=$config_vars{$var}\n";
|
||||
}
|
||||
}
|
||||
$modified_conf_msg ||= " (none)\n";
|
||||
chomp $modified_conf_msg;
|
||||
|
||||
if ($config_vars{'PLOTCHANGELOG_OPTIONS'}) {
|
||||
unshift @ARGV, split(' ', $config_vars{'PLOTCHANGELOG_OPTIONS'});
|
||||
}
|
||||
$extra_gnuplot_commands = $config_vars{'PLOTCHANGELOG_GNUPLOT'};
|
||||
}
|
||||
|
||||
GetOptions(
|
||||
"no-version|v", \$no_version,
|
||||
"no-maint|m", \$no_maintainer,
|
||||
"gnuplot|g=s", \$gnuplot_commands,
|
||||
"save|s=s", \$save_filename,
|
||||
"dump|d", \$dump,
|
||||
"urgency|u", \$show_urgency,
|
||||
"verbose", \$verbose,
|
||||
"l|linecount", \$linecount,
|
||||
"b|bugcount", \$bugcount,
|
||||
"c|cumulative", \$cumulative,
|
||||
"help", \$help,
|
||||
"version", \$showversion,
|
||||
"noconf" => \$noconf,
|
||||
"no-conf" => \$noconf,
|
||||
)
|
||||
or die
|
||||
"Usage: $progname [options] changelog ...\nRun $progname --help for more details\n";
|
||||
|
||||
if ($noconf) {
|
||||
die
|
||||
"$progname: --no-conf is only acceptable as the first command-line option!\n";
|
||||
}
|
||||
|
||||
if ($help) {
|
||||
usage();
|
||||
exit 0;
|
||||
}
|
||||
|
||||
if ($showversion) {
|
||||
print $versioninfo;
|
||||
exit 0;
|
||||
}
|
||||
|
||||
if ($bugcount && $linecount) {
|
||||
die
|
||||
"$progname: can't use --bugcount and --linecount\nRun $progname --help for usage information.\n";
|
||||
}
|
||||
|
||||
if ($cumulative && !$bugcount && !$linecount) {
|
||||
warn
|
||||
"$progname: --cumulative without --bugcount or --linecount: ignoring\nRun $progname --help for usage information.\n";
|
||||
}
|
||||
|
||||
if (!@ARGV) {
|
||||
die
|
||||
"Usage: $progname [options] changelog ...\nRun $progname --help for more details\n";
|
||||
}
|
||||
|
||||
my %data;
|
||||
my ($package, $version, $maintainer, $date, $urgency) = undef;
|
||||
my ($data_tmpfile, $script_tmpfile);
|
||||
my ($data_fh, $script_fh);
|
||||
|
||||
if (!$dump) {
|
||||
$data_fh = tempfile("plotdataXXXXXX", UNLINK => 1)
|
||||
or die "cannot create temporary file: $!";
|
||||
fcntl $data_fh, Fcntl::F_SETFD(), 0
|
||||
or die "disabling close-on-exec for temporary file: $!";
|
||||
$script_fh = tempfile("plotscriptXXXXXX", UNLINK => 1)
|
||||
or die "cannot create temporary file: $!";
|
||||
fcntl $script_fh, Fcntl::F_SETFD(), 0
|
||||
or die "disabling close-on-exec for temporary file: $!";
|
||||
$data_tmpfile = '/dev/fd/' . fileno($data_fh);
|
||||
$script_tmpfile = '/dev/fd/' . fileno($script_fh);
|
||||
} else {
|
||||
$data_tmpfile = '-';
|
||||
}
|
||||
my %pkgcount;
|
||||
my $c;
|
||||
|
||||
# Changelog parsing.
|
||||
foreach (@ARGV) {
|
||||
if (/\.gz$/) {
|
||||
open F, "zcat $_|" || die "$_: $!";
|
||||
} else {
|
||||
open F, $_ || die "$_: $!";
|
||||
}
|
||||
|
||||
while (<F>) {
|
||||
chomp;
|
||||
# Note that some really old changelogs use priority, not urgency.
|
||||
if (/^(\w+.*?)\s+\((.*?)\)\s+.*?;\s+(?:urgency|priority)=(.*)/i) {
|
||||
$package = lc($1);
|
||||
$version = $2;
|
||||
if ($show_urgency) {
|
||||
$urgency = $3;
|
||||
if ($urgency =~ /high/i) {
|
||||
$urgency = 2;
|
||||
} elsif ($urgency =~ /medium/i) {
|
||||
$urgency = 1.5;
|
||||
} else {
|
||||
$urgency = 1;
|
||||
}
|
||||
} else {
|
||||
$urgency = 1;
|
||||
}
|
||||
undef $maintainer;
|
||||
undef $date;
|
||||
$c = 0;
|
||||
} elsif (/^ -- (.*?) (.*)/) {
|
||||
$maintainer = $1;
|
||||
$date = str2time($2);
|
||||
|
||||
# Strip email address.
|
||||
$maintainer =~ s/<.*>//;
|
||||
$maintainer =~ s/\(.*\)//;
|
||||
$maintainer =~ s/\s+$//;
|
||||
} elsif (/^(\w+.*?)\s+\((.*?)\)\s+/) {
|
||||
print STDERR qq[Parse error on "$_"\n];
|
||||
} elsif ($linecount && /^ /) {
|
||||
$c++; # count changelog size.
|
||||
} elsif ($bugcount && /^ /) {
|
||||
# count bugs that were said to be closed.
|
||||
my @bugs = m/#\d+/g;
|
||||
$c += $#bugs + 1;
|
||||
}
|
||||
|
||||
if ( defined $package
|
||||
&& defined $version
|
||||
&& defined $maintainer
|
||||
&& defined $date
|
||||
&& defined $urgency) {
|
||||
$data{$package}{ $pkgcount{$package}++ } = [
|
||||
$linecount || $bugcount ? $c : $version,
|
||||
$maintainer, $date, $urgency
|
||||
];
|
||||
undef $package;
|
||||
undef $version;
|
||||
undef $maintainer;
|
||||
undef $date;
|
||||
undef $urgency;
|
||||
}
|
||||
}
|
||||
|
||||
close F;
|
||||
}
|
||||
|
||||
if ($cumulative) {
|
||||
# have to massage the data; based on some code from later on
|
||||
foreach $package (keys %data) {
|
||||
my $total = 0;
|
||||
# It's crucial the output is sorted by date.
|
||||
foreach my $i (
|
||||
sort { $data{$package}{$a}[2] <=> $data{$package}{$b}[2] }
|
||||
keys %{ $data{$package} }
|
||||
) {
|
||||
$total += $data{$package}{$i}[0];
|
||||
$data{$package}{$i}[0] = $total;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
my $header = q{
|
||||
set key below title "key" box
|
||||
set timefmt "%m/%d/%Y %H:%M"
|
||||
set xdata time
|
||||
set format x "%m/%y"
|
||||
set yrange [0 to *]
|
||||
};
|
||||
if ($linecount) {
|
||||
if ($cumulative) {
|
||||
$header .= "set ylabel 'Cumulative changelog length'\n";
|
||||
} else {
|
||||
$header .= "set ylabel 'Changelog length'\n";
|
||||
}
|
||||
} elsif ($bugcount) {
|
||||
if ($cumulative) { $header .= "set ylabel 'Cumulative bugs closed'\n"; }
|
||||
else { $header .= "set ylabel 'Bugs closed'\n"; }
|
||||
} else {
|
||||
$header .= "set ylabel 'Debian version'\n";
|
||||
}
|
||||
if ($save_filename) {
|
||||
$header .= "set terminal postscript color solid\n";
|
||||
$header .= "set output '$save_filename'\n";
|
||||
}
|
||||
my $script = "plot ";
|
||||
my $data = '';
|
||||
my $index = 0;
|
||||
my %maintdata;
|
||||
|
||||
# Note that "lines" is used if we are also showing maintainer info,
|
||||
# otherwise we use "linespoints" to make sure points show up for each
|
||||
# release anyway.
|
||||
my $style = $no_maintainer ? "linespoints" : "lines";
|
||||
|
||||
foreach $package (keys %data) {
|
||||
my $oldmaintainer = "";
|
||||
my $oldversion = "";
|
||||
# It's crucial the output is sorted by date.
|
||||
foreach my $i (
|
||||
sort { $data{$package}{$a}[2] <=> $data{$package}{$b}[2] }
|
||||
keys %{ $data{$package} }
|
||||
) {
|
||||
my $v = $data{$package}{$i}[0];
|
||||
$maintainer = $data{$package}{$i}[1];
|
||||
$date = $data{$package}{$i}[2];
|
||||
$urgency = $data{$package}{$i}[3];
|
||||
|
||||
$maintainer =~ s/"/\\"/g;
|
||||
|
||||
my $y;
|
||||
|
||||
# If it's got a debian revision, use that as the y coordinate.
|
||||
if ($v =~ m/(.*)-(.*)/) {
|
||||
$y = $2;
|
||||
$version = $1;
|
||||
} else {
|
||||
$y = $v;
|
||||
}
|
||||
|
||||
# Now make sure the version is a real number. This includes making
|
||||
# sure it has no more than one decimal point in it, and getting rid of
|
||||
# any nonnumeric stuff. Otherwise, the "set label" command below could
|
||||
# fail. Luckily, perl's string -> num conversion is perfect for this job.
|
||||
$y = $y + 0;
|
||||
|
||||
if (lc($maintainer) ne lc($oldmaintainer)) {
|
||||
$oldmaintainer = $maintainer;
|
||||
}
|
||||
|
||||
my ($sec, $min, $hour, $mday, $mon, $year) = localtime($date);
|
||||
my $x = ($mon + 1) . "/$mday/" . (1900 + $year) . " $hour:$min";
|
||||
$data .= "$x\t$y\n";
|
||||
$maintdata{$oldmaintainer}{$urgency} .= "$x\t$y\n";
|
||||
|
||||
if ($oldversion ne $version && !$no_version) {
|
||||
# Upstream version change. Label it.
|
||||
$header .= "set label '$version' at '$x',$y left\n";
|
||||
$oldversion = $version;
|
||||
}
|
||||
}
|
||||
$data .= "\n\n"; # start new dataset
|
||||
# Add to plot command.
|
||||
$script
|
||||
.= "'$data_tmpfile' index $index using 1:3 title '$package' with $style, ";
|
||||
$index++;
|
||||
}
|
||||
|
||||
# Add a title.
|
||||
my $title .= "set title '";
|
||||
$title
|
||||
.= $#ARGV > 1
|
||||
? "Graphing Debian changelogs"
|
||||
: "Graphing Debian changelog";
|
||||
$title .= "'\n";
|
||||
|
||||
if (!$no_maintainer) {
|
||||
foreach $maintainer (sort keys %maintdata) {
|
||||
foreach $urgency (sort keys %{ $maintdata{$maintainer} }) {
|
||||
$data .= $maintdata{$maintainer}{$urgency} . "\n\n";
|
||||
$script
|
||||
.= "'$data_tmpfile' index $index using 1:3 title \"$maintainer\" with points pointsize "
|
||||
. (1.5 * $urgency) . ", ";
|
||||
$index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$script =~ s/, $/\n/;
|
||||
$script = qq{
|
||||
$header
|
||||
$title
|
||||
$extra_gnuplot_commands
|
||||
$gnuplot_commands
|
||||
$script
|
||||
};
|
||||
$script .= "pause -1 'Press Return to continue.'\n"
|
||||
unless $save_filename || $dump;
|
||||
|
||||
if (!$dump) {
|
||||
# Annoyingly, we have to use 2 temp files. I could just send everything to
|
||||
# gnuplot on stdin, but then the pause -1 doesn't work.
|
||||
open(DATA, ">$data_tmpfile") || die "$data_tmpfile: $!";
|
||||
open(SCRIPT, ">$script_tmpfile") || die "$script_tmpfile: $!";
|
||||
} else {
|
||||
open(DATA, ">&STDOUT");
|
||||
open(SCRIPT, ">&STDOUT");
|
||||
}
|
||||
|
||||
print SCRIPT $script;
|
||||
print $script if $verbose && !$dump;
|
||||
print DATA $data;
|
||||
close SCRIPT;
|
||||
close DATA;
|
||||
|
||||
if (!$dump) {
|
||||
unless (system("gnuplot", $script_tmpfile) == 0) {
|
||||
die "gnuplot program failed (is the gnuplot package installed?): $!\n";
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue