diff options
author | Martin Whitaker <mageia@martin-whitaker.me.uk> | 2018-03-30 19:09:35 +0100 |
---|---|---|
committer | Neal Gompa <ngompa13@gmail.com> | 2018-03-30 14:15:14 -0400 |
commit | d7e77fdefb37e2b1244c7c38b544d6c893a671ed (patch) | |
tree | 4def6486ac8fa79132d7087487fdf4a2434acbed | |
parent | 654a14c7d32f5cde599329936e9675caa8834016 (diff) | |
download | qarepo-d7e77fdefb37e2b1244c7c38b544d6c893a671ed.tar qarepo-d7e77fdefb37e2b1244c7c38b544d6c893a671ed.tar.gz qarepo-d7e77fdefb37e2b1244c7c38b544d6c893a671ed.tar.bz2 qarepo-d7e77fdefb37e2b1244c7c38b544d6c893a671ed.tar.xz qarepo-d7e77fdefb37e2b1244c7c38b544d6c893a671ed.zip |
New release
I've added a couple of extra options:
1. "fuzzy version" will automatically replace the package
version/release in each requested package with a wildcard.
If there are multiple versions in the remote repository,
you'll get them all (and MageiaUpdate will then select the newest).
Note this only happens if the requested package name includes
the Mageia release (e.g. mga6) and if the package version
starts with a digit, to avoid false matches.
2. "add deps" will automatically add all dependencies of the
requested packages that can be satisfied from the updates_testing
repositories.
If you want to see what's actually been selected,
either quit the app. and restart it, or use
urpmq --list --media 'QA Testing'
I would only use these options whilst things are in a state of flux.
You really want to test against a definitive package list before you
finally validate an update.
I've also added a couple of check boxes to let you enable/disable use
of the nonfree and tainted repositories.
-rw-r--r-- | qarepo.pl | 196 |
1 files changed, 137 insertions, 59 deletions
@@ -20,12 +20,12 @@ use strict; use warnings; -use File::Temp qw(tmpnam); use Glib qw(TRUE FALSE); use Gtk3 '-init'; use MDK::Common; +use URPM; -my $release = 'v1.2'; +my $release = 'v1.3'; ############################################################################### # States and Status @@ -51,6 +51,7 @@ my $sudo = $> ? 'sudo' : ''; my %config; +# Settings are stored in the config file in key=value format. my $config_file = "$home/.qareporc"; if (open(my $f, '<', $config_file)) { while (my $line = <$f>) { @@ -61,10 +62,13 @@ if (open(my $f, '<', $config_file)) { close($f); } -my $mirror = $config{MIRROR} || 'rsync://mirrors.kernel.org/mirrors/mageia'; -my $version = $config{VERSION} || '6'; -my $arch = $config{ARCH} || 'x86_64'; -my $qa_repo = $config{QA_REPO} || "$home/qa-testing"; +# Use sensible defaults for settings not in the config file. +my $mirror = $config{MIRROR} // 'rsync://mirrors.kernel.org/mirrors/mageia'; +my $version = $config{VERSION} // '6'; +my $arch = $config{ARCH} // 'x86_64'; +my $nonfree = $config{NONFREE} // 1; +my $tainted = $config{TAINTED} // 1; +my $qa_repo = $config{QA_REPO} // "$home/qa-testing"; my $qa_repo_name = 'QA Testing'; @@ -84,35 +88,41 @@ my $last_arch = $arch; # GUI Main Window ############################################################################### -my $window = Gtk3::Window->new('toplevel'); +my $window = Gtk3::Window->new('toplevel'); -my $grid = Gtk3::Grid->new(); +my $grid = Gtk3::Grid->new(); -my $label1 = Gtk3::Label->new('Mirror:'); -my $entry1 = Gtk3::Entry->new(); +my $label1 = Gtk3::Label->new('Mirror:'); +my $entry1 = Gtk3::Entry->new(); -my $label2 = Gtk3::Label->new('Version:'); -my $entry2 = Gtk3::Entry->new(); +my $label2 = Gtk3::Label->new('Version:'); +my $entry2 = Gtk3::Entry->new(); -my $label3 = Gtk3::Label->new('Arch:'); -my $entry3 = Gtk3::ComboBoxText->new(); +my $label3 = Gtk3::Label->new('Arch:'); +my $entry3 = Gtk3::ComboBoxText->new(); -my $label4 = Gtk3::Label->new('QA Repo:'); -my $entry4 = Gtk3::Entry->new(); +my $label4 = Gtk3::Label->new('QA Repo:'); +my $entry4 = Gtk3::Entry->new(); -my $label5 = Gtk3::Label->new('RPMs:'); -my $entry5 = Gtk3::TextView->new(); +my $label5 = Gtk3::Label->new('RPMs:'); +my $entry5 = Gtk3::TextView->new(); -my $scroll = Gtk3::ScrolledWindow->new(); +my $scroll = Gtk3::ScrolledWindow->new(); -my $label6 = Gtk3::Label->new('Status:'); -my $status = Gtk3::Label->new(''); +my $label6 = Gtk3::Label->new('Status:'); +my $status = Gtk3::Label->new(''); my $button1 = Gtk3::Button->new('Quit'); my $button2 = Gtk3::Button->new('Disable'); my $button3 = Gtk3::Button->new('Enable'); my $button4 = Gtk3::Button->new('Clear'); +my $check1 = Gtk3::CheckButton->new_with_label("nonfree"); +my $check2 = Gtk3::CheckButton->new_with_label("tainted"); + +my $check3 = Gtk3::CheckButton->new_with_label("fuzzy\nversion"); +my $check4 = Gtk3::CheckButton->new_with_label("add\ndeps"); + $window->set_title("QA Repo $release"); $window->set_default_size(600, 400); $window->set_border_width(10); @@ -130,7 +140,8 @@ $entry1->signal_connect(changed => \&changed); $label2->set_halign('GTK_ALIGN_END'); $entry2->set_text($version); -$entry2->set_hexpand(FALSE); +$entry2->set_width_chars(2); +$entry2->set_hexpand(TRUE); $entry2->signal_connect(changed => \&changed); $label3->set_halign('GTK_ALIGN_END'); @@ -169,28 +180,46 @@ $button1->signal_connect(clicked => \&quit); $button2->signal_connect(clicked => \&disable); $button3->signal_connect(clicked => \&enable); -$button3->set_valign('GTK_ALIGN_START'); -$button4->signal_connect(clicked => \&clear); +$button4->set_vexpand(TRUE); $button4->set_valign('GTK_ALIGN_END'); +$button4->signal_connect(clicked => \&clear); + +$check1->signal_connect(clicked => \&changed); +$check1->set_active($nonfree); + +$check2->signal_connect(clicked => \&changed); +$check2->set_active($tainted); + +$check3->signal_connect(clicked => \&changed); +$check3->set_active(FALSE); + +$check4->signal_connect(clicked => \&changed); +$check4->set_active(FALSE); $grid->attach($label1, 0, 0, 1, 1); -$grid->attach($entry1, 1, 0, 4, 1); +$grid->attach($entry1, 1, 0, 6, 1); + $grid->attach($label2, 1, 1, 1, 1); $grid->attach($entry2, 2, 1, 1, 1); $grid->attach($label3, 3, 1, 1, 1); $grid->attach($entry3, 4, 1, 1, 1); +$grid->attach($check1, 5, 1, 1, 1); +$grid->attach($check2, 6, 1, 1, 1); + $grid->attach($label4, 0, 2, 1, 1); -$grid->attach($entry4, 1, 2, 4, 1); +$grid->attach($entry4, 1, 2, 6, 1); $grid->attach($label5, 0, 3, 1, 1); -$grid->attach($scroll, 1, 3, 4, 2); -$grid->attach($label6, 0, 5, 1, 1); -$grid->attach($status, 1, 5, 4, 1); +$grid->attach($scroll, 1, 3, 6, 4); +$grid->attach($label6, 0, 7, 1, 1); +$grid->attach($status, 1, 7, 6, 1); -$grid->attach($button1, 5, 0, 1, 1); -$grid->attach($button2, 5, 2, 1, 1); -$grid->attach($button3, 5, 3, 1, 1); -$grid->attach($button4, 5, 4, 1, 1); +$grid->attach($button1, 7, 0, 1, 1); +$grid->attach($button2, 7, 2, 1, 1); +$grid->attach($button3, 7, 3, 1, 1); +$grid->attach($check3, 7, 4, 1, 1); +$grid->attach($check4, 7, 5, 1, 1); +$grid->attach($button4, 7, 6, 1, 1); $window->add($grid); @@ -261,10 +290,12 @@ sub changed { sub quit { get_settings(); if (open(my $f, '>', $config_file)) { - print $f "MIRROR=$mirror\n"; - print $f "VERSION=$version\n"; - print $f "ARCH=$arch\n"; - print $f "QA_REPO=$qa_repo\n"; + printf $f "MIRROR=%s\n", $mirror; + printf $f "VERSION=%s\n", $version; + printf $f "ARCH=%s\n", $arch; + printf $f "NONFREE=%d\n", $nonfree; + printf $f "TAINTED=%d\n", $tainted; + printf $f "QA_REPO=%s\n", $qa_repo; close($f); } Gtk3->main_quit; @@ -332,20 +363,28 @@ sub get_settings { $mirror = trim($entry1->get_text()); $version = trim($entry2->get_text()); $arch = trim($entry3->get_active_text()); + $nonfree = $check1->get_active(); + $tainted = $check2->get_active(); $qa_repo = trim($entry4->get_text()); if ($active_qa_repo && $active_qa_repo ne $qa_repo) { disable_repo(); } } -sub get_required_rpms { +sub get_requested_rpms { my $buffer = $entry5->get_buffer(); my $start = $buffer->get_start_iter(); my $end = $buffer->get_end_iter(); + my $fuzzy_version = $check3->get_active(); + my @lines = split("\n", $buffer->get_text($start, $end, FALSE)); - s/^\s+// foreach @lines; # skip leading white space - s/\s+$// foreach @lines; # skip leading white space + if ($fuzzy_version) { + # replace version-release with wildcard + s/-\d.*-.+(\.mga$version(?:(?:\.$arch|\.noarch)(?:\.rpm)?)?)$/-\\d*$1/ foreach @lines; + } + s/^\s+// foreach @lines; # trim leading white space + s/\s+$// foreach @lines; # trim trailing white space grep { $_ ne '' } @lines; # and discard blank lines } @@ -384,7 +423,8 @@ sub update_repo { } sub clear_repo { - my @existing_rpms = get_existing_rpms(); + my ($type) = @_; + my @existing_rpms = grep { $_ =~ /$type/ } get_existing_rpms(); if (@existing_rpms) { if (!unlink(map { "$qa_repo/$_" } @existing_rpms)) { my $message = "couldn't delete existing RPMs in the QA repo"; @@ -422,20 +462,41 @@ sub sync_repo { gtk_update(); } + my $add_dependencies = $check4->get_active(); + my $remote_repo = "$mirror/distrib/$version/$arch/media"; + my @mediatypes = ( 'core' ); + push @mediatypes, 'nonfree' if $nonfree; + push @mediatypes, 'tainted' if $tainted; + my $download_dir = "$qa_repo/.download"; mkdir_p($download_dir); - my @available_rpms = (); - foreach my $media_type (qw(core nonfree tainted)) { + my %rpm_dependencies; + foreach my $media_type (@mediatypes) { my $synthesis = 'synthesis.hdlist.cz'; my $remote_dir = "$remote_repo/$media_type/updates_testing/media_info"; &$sync_file("$remote_dir/$synthesis", $download_dir) or next; - my @package_list = split("\n", `urpmq --synthesis $download_dir/$synthesis --list -f`); - foreach my $package (@package_list) { - push(@available_rpms, "$package.rpm"); - } + gtk_update(); + + my $urpm = new URPM; + $urpm->parse_synthesis("$download_dir/$synthesis"); + $urpm->traverse(sub { + my ($pkg) = @_; + my $name = $pkg->fullname(); + my $rpm = "$name.rpm"; + %{$rpm_dependencies{$rpm}} = (); + if ($add_dependencies) { + my @requires = ( $pkg->requires_nosense(), $pkg->recommends_nosense ); + $urpm->traverse_tag('whatprovides', \@requires, sub { + my ($pkg) = @_; + my $name = $pkg->fullname(); + ${$rpm_dependencies{$rpm}}{"$name.rpm"} = 1; + }); + } + }); + if (!unlink("$download_dir/$synthesis")) { my $message = "couldn't delete $download_dir/$synthesis in the QA repo.\n"; show_error_dialogue($message); @@ -444,21 +505,34 @@ sub sync_repo { gtk_update(); } - my @required_rpms = (); - foreach my $request (get_required_rpms()) { - my $pattern = wildcard_to_regexp($request); - my $matched = 0; - foreach my $candidate (@available_rpms) { - if ($candidate =~ /^$pattern/) { - push(@required_rpms, $candidate) if !member($candidate, @required_rpms); - $matched = 1; + my %selection; + my @requests = get_requested_rpms(); + while (@requests) { + foreach my $request (@requests) { + my $pattern = wildcard_to_regexp($request); + my $matched = 0; + foreach my $candidate (keys %rpm_dependencies) { + if ($candidate =~ /^$pattern/) { + $selection{$candidate} = 1; + $selection{$_} ||= 2 foreach keys %{$rpm_dependencies{$candidate}}; + $matched = 1; + } } + $matched or sync_error("$request not found in the remote repository"); } - $matched or sync_error("$request not found in the remote repository"); + # avoid infinite loop if we haven't found a match + last if @sync_errors; + # recurse through any new dependencies + @requests = grep { $selection{$_} == 2 } keys %selection; } - my @existing_rpms = get_existing_rpms(); + if (@sync_errors) { + show_error_dialogue(@sync_errors); + return 0; + } + my @required_rpms = keys %selection; + my @existing_rpms = get_existing_rpms(); my @unwanted_rpms = difference2(\@existing_rpms, \@required_rpms); if (@unwanted_rpms) { if (!unlink(map { "$qa_repo/$_" } @unwanted_rpms)) { @@ -499,10 +573,14 @@ sub sync_repo { or sync_error("failed to update hdlist"); } else { print "ERROR: failed to download all the files.\n"; + } + + if (@sync_errors) { show_error_dialogue(@sync_errors); + return 0; } - @sync_errors == 0; + 1; } sub sync_file_rsync { @@ -533,7 +611,7 @@ sub sync_file_link { sub sync_error { my ($message) = @_; - push(@sync_errors, $message); + push @sync_errors, $message; print "ERROR: $message.\n"; 0; } |