From a6d0fd47a9ab2eca5390936e22939bfc4cb8d93c Mon Sep 17 00:00:00 2001 From: Florian Pritz Date: Wed, 4 Jan 2012 18:57:19 +0100 Subject: add signoffs.pl Signed-off-by: Florian Pritz --- signoffs.pl | 247 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 247 insertions(+) create mode 100644 signoffs.pl diff --git a/signoffs.pl b/signoffs.pl new file mode 100644 index 0000000..d908ada --- /dev/null +++ b/signoffs.pl @@ -0,0 +1,247 @@ +#!/usr/bin/perl +# +# Author: Florian Pritz +# +# Licensed under GPLv3 +# +use warnings; +no warnings 'once'; +use strict; +use diagnostics; +use JSON; +use WWW::Mechanize; +use Data::Dumper; +use Text::Wrap; +use Getopt::Long; +use Pod::Usage; + +my $configfile = "$ENV{HOME}/.signoffsrc"; +{ package Settings; + + # define default values + # these can be overridden from the config file + our $domain = "https://www.archlinux.org"; + our $pacman_db = "/var/lib/pacman"; + chomp (our $system_arch = `uname -m`); + our $display_disabled = 0; + our $only_pending = 0; + our $hide_signed_off = 0; + our $display_comments = 1; + our @target_repos = qw(core unknown); + + unless (my $return = do $configfile) { + die "couldn't parse $configfile: $@" if $@; + die "couldn't do $configfile: $!" unless defined $return; + } +} + +sub make_links { + my $text = shift; + + $text =~ s|FS#([0-9]+)||; + + return $text; +} + +Getopt::Long::Configure ("bundling"); +GetOptions( + "help" => sub {pod2usage(0);}, + "h" => sub {pod2usage(2);}, + "comments|c!" => \$Settings::display_comments +); + +# check if all vars are configured +for my $varname (qw(username password)) { + unless (${$Settings::{$varname}}) { + print STDERR "$varname not defined in config file \"$configfile\"\n"; + exit 1; + } +} + +# sanity checks +if (! -d $Settings::pacman_db) { + print STDERR "\$pacman_db set to non-directory \"$Settings::pacman_db\": $!\n"; + exit 1; +} + +$Text::Wrap::columns = 80; + +# array to hold information of installed packages +my @installed_groups; + +my $mech = WWW::Mechanize->new(cookie_jar => {}); +#$mech->proxy(['https', 'http', 'ftp'], 'http://localhost:8080'); + +# log in +$mech->get("$Settings::domain/login/"); +$mech->submit_form( + form_id => "dev-login-form", + fields => { + username => $Settings::username, + password => $Settings::password + } +); + +if ($mech->content() =~ m/Please enter a correct username and password/) { + print STDERR "Login credentials are incorrect.\n"; + exit 1; +} + +$mech->get("$Settings::domain/packages/signoffs/json"); +my $json = JSON::decode_json($mech->content()); + +my $id = 0; +for my $signoff_groups ($json->{signoff_groups}) { + for my $signoff_group (@{$signoff_groups}) { + # skip packages for different arch + next unless ($signoff_group->{arch} eq $Settings::system_arch + || $signoff_group->{arch} eq "any"); + + my $target_repo = lc $signoff_group->{target_repo}; + + # skip package that are not going to repos listed in the config + if (!grep $_ eq $target_repo, @Settings::target_repos) { + next; + } + + if (!$Settings::display_disabled) { + # skip disabled packages + next if !$signoff_group->{enabled}; + } + + if ($Settings::only_pending) { + # skip packages with enough signoffs + next if $signoff_group->{approved}; + } + + # loop over packages, print some information and push it to @installed_groups + # if the package is installed + for my $pkgname (@{$signoff_group->{pkgnames}}) { + # if package is installed save to @installed_groups, else skip it + next unless -e "$Settings::pacman_db/local/$pkgname-$signoff_group->{version}"; + $installed_groups[$id] = $signoff_group; + + print "\e[1;33m$id\e[0m - \e[0;33m$pkgname $signoff_group->{version}\e[0m\n"; + + if ($signoff_group->{known_bad}) { + print " \e[1;31mKnown bad!\e[0m\n"; + } + + if ($pkgname ne $signoff_group->{pkgbase}) { + print " \e[0;31mPkgbase: $signoff_group->{pkgbase}\e[0m\n"; + } + + unless ($signoff_group->{required} == 2) { + print " Required signoffs: $signoff_group->{required}\n"; + } + + my $i = 0; + my $signoff_count = @{$signoff_group->{signoffs}}; + print " Signoffs: "; + if ($signoff_group->{enabled}) { + for my $signoff (@{$signoff_group->{signoffs}}) { + # if it's our signoff, save that info for later so we can revoke it + if ($signoff->{user} eq $Settings::username && !$signoff->{revoked}) { + $signoff_group->{can_revoke} = 1; + print "\e[0;32m$signoff->{user}\e[0m"; + } else { + print $signoff->{user}; + print " (revoked)" if $signoff->{revoked}; + } + print ", " if $i+1 < $signoff_count; + + $i++; + } + } else { + print ""; + } + print "\n"; + + if ($signoff_group->{comments} ne "" && $Settings::display_comments) { + print " \e[0;35mComment:\e[0m\n"; + print wrap(" ", " ", make_links($signoff_group->{comments})); + print "\n"; + } + + $id++; + } + } +} + +print "\n"; +print STDERR"\e[0;34mPlease enter IDs of packages to sign off/revoke: \e[0m"; +my $input = ; + +# sign off or revoke +for my $id (split(" ", $input)) { + unless ($id =~ /^\d+$/ && exists ($installed_groups[$id])) { + print STDERR "Invalid ID \"$id\". Skipping...\n"; + } + my $pkg = $installed_groups[$id]; + + print "processing pkgbase $pkg->{pkgbase} ... "; + + my $url = "$Settings::domain/packages/$pkg->{repo}/$pkg->{arch}/$pkg->{pkgbase}/signoff/"; + + if ($pkg->{can_revoke}) { + $mech->get("$url/revoke"); + print "revoked.\n"; + } else { + $mech->get($url); + print "signed off.\n"; + } +} + +__END__ +=head1 SYNOPSIS + +signoffs.pl [options] + + Options: + --help, -h display help message + --comments, -c display comments (can be negated) + +=head1 OPTIONS + +=over 8 + +=item B<--help>, B<-h> + +Print a help message. + +=item B<--comments>, B<-c> + +Display comments. This option can be negated with --no: --no-comments + +=back + +=head1 EXAMPLE CONFIG + +Save this as ~/.signoffsrc + + # your login credentials + $username = "whatever"; + $password = "secret"; + # if you want to use a script: + # chomp ($password = `getpw whatever`); + + # Everthing below this line is optional + + # should we display packages that's can't be signed off? + $display_disabled = 1; + + # only display packages that don't have enough signoffs + $only_pending = 0; + + # hide packages you have signed off already + $hide_signed_off = 0; + + # only display packages that will move to these repos + @target_repos = qw(core unknown); + + # you probably don't have to change those + $domain = "https://www.archlinux.org"; + #chomp ($system_arch = `uname -m`); + $pacman_db = "/var/lib/pacman"; + +=cut -- cgit v1.2.3-24-g4f1b