From 654a14c7d32f5cde599329936e9675caa8834016 Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Fri, 30 Mar 2018 00:09:07 +0100 Subject: New release A few more changes: - enables 'QA Testing' as an updates repository (fixes regression in v1.1) - ignores leading/trailing white space in entries - discards duplicates in RPMs list (so T.J.'s wildcard list is handled properly now) - reports errors in a pop-up dialogue window --- qarepo.pl | 181 +++++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 132 insertions(+), 49 deletions(-) diff --git a/qarepo.pl b/qarepo.pl index 957ce12..fe623dd 100644 --- a/qarepo.pl +++ b/qarepo.pl @@ -25,7 +25,7 @@ use Glib qw(TRUE FALSE); use Gtk3 '-init'; use MDK::Common; -my $release = 'v1.1'; +my $release = 'v1.2'; ############################################################################### # States and Status @@ -44,7 +44,7 @@ my $state; # Initial Configuration ############################################################################### -my $home = $ENV{HOME} or die "ERROR: the HOME environment variable is not set.\n"; +my $home = $ENV{HOME} || './'; # Only use sudo if not run by root. my $sudo = $> ? 'sudo' : ''; @@ -81,7 +81,7 @@ my $last_version = $version; my $last_arch = $arch; ############################################################################### -# GUI +# GUI Main Window ############################################################################### my $window = Gtk3::Window->new('toplevel'); @@ -200,9 +200,55 @@ if ($active_qa_repo) { set_state('disabled'); } -$window->show_all; +############################################################################### +# GUI Error Dialogue +############################################################################### + +my $error_window = Gtk3::Window->new('toplevel'); + +my $error_grid = Gtk3::Grid->new(); + +my $error_label = Gtk3::Label->new('The following error(s) occurred:'); + +my $error_text = Gtk3::TextView->new(); + +my $error_scroll = Gtk3::ScrolledWindow->new(); + +my $error_button = Gtk3::Button->new('Dismiss'); + +$error_window->set_title("Error"); +$error_window->set_default_size(600, 300); +$error_window->set_border_width(10); +$error_window->set_type_hint('dialog'); +$error_window->signal_connect(delete_event => sub { $error_window->hide_on_delete() }); + +$error_grid->set_row_spacing(10); +$error_grid->set_column_spacing(10); + +$error_label->set_halign('GTK_ALIGN_START'); + +$error_text->set_editable(FALSE); + +$error_scroll->set_hexpand(TRUE); +$error_scroll->set_vexpand(TRUE); +$error_scroll->add($error_text); + +$error_button->signal_connect(clicked => sub { $error_window->hide() }); +$error_button->set_halign('GTK_ALIGN_CENTER'); + +$error_grid->attach($error_label, 0, 0, 1, 1); +$error_grid->attach($error_scroll, 0, 1, 1, 1); +$error_grid->attach($error_button, 0, 2, 1, 1); + +$error_window->add($error_grid); + +############################################################################### +# GUI Start +############################################################################### + +$window->show_all(); -Gtk3->main; +Gtk3->main(); ############################################################################### # GUI Callbacks @@ -252,7 +298,7 @@ sub enable { } sub clear { - $entry5->get_buffer()->set_text(""); + $entry5->get_buffer()->set_text(''); } ############################################################################### @@ -283,10 +329,10 @@ sub disable_buttons { } sub get_settings { - $mirror = $entry1->get_text(); - $version = $entry2->get_text(); - $arch = $entry3->get_active_text(); - $qa_repo = $entry4->get_text(); + $mirror = trim($entry1->get_text()); + $version = trim($entry2->get_text()); + $arch = trim($entry3->get_active_text()); + $qa_repo = trim($entry4->get_text()); if ($active_qa_repo && $active_qa_repo ne $qa_repo) { disable_repo(); } @@ -297,7 +343,10 @@ sub get_required_rpms { my $start = $buffer->get_start_iter(); my $end = $buffer->get_end_iter(); - grep { $_ ne '' } split("\n", $buffer->get_text($start, $end, FALSE)); + 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 + grep { $_ ne '' } @lines; # and discard blank lines } sub get_existing_rpms { @@ -305,23 +354,31 @@ sub get_existing_rpms { } sub disable_repo { - system("$sudo urpmi.removemedia '$qa_repo_name'") == 0 - or die "ERROR: couldn't disable the $qa_repo_name media.\n"; - $active_qa_repo = ''; + if (system("$sudo urpmi.removemedia '$qa_repo_name'") == 0) { + $active_qa_repo = ''; + } else { + my $message = "couldn't disable the $qa_repo_name media"; + show_error_dialogue($message); + die "ERROR: $message.\n"; + } } sub enable_repo { - if (system("$sudo urpmi.addmedia '$qa_repo_name' $qa_repo") == 0) { + if (system("$sudo urpmi.addmedia --update '$qa_repo_name' $qa_repo") == 0) { $active_qa_repo = $qa_repo; } else { - print "ERROR: couldn't enable the $qa_repo_name media.\n"; + my $message = "couldn't enable the $qa_repo_name media"; + show_error_dialogue($message); + print "ERROR: $message.\n"; $active_qa_repo = ''; } } sub update_repo { if (system("$sudo urpmi.update '$qa_repo_name'") != 0) { - print "ERROR: couldn't update the $qa_repo_name media.\n"; + my $message = "couldn't update the $qa_repo_name media"; + show_error_dialogue($message); + print "ERROR: $message.\n"; disable_repo(); } } @@ -329,18 +386,19 @@ sub update_repo { sub clear_repo { my @existing_rpms = get_existing_rpms(); if (@existing_rpms) { - unlink(map { "$qa_repo/$_" } @existing_rpms) - or die "ERROR: couldn't delete/unlink existing RPMs in the QA repo.\n"; + if (!unlink(map { "$qa_repo/$_" } @existing_rpms)) { + my $message = "couldn't delete existing RPMs in the QA repo"; + show_error_dialogue($message); + die "ERROR: $message.\n"; + } } } -my @available_rpms; - -my $sync_ok; +my @sync_errors; sub sync_repo { $status->set_label('Updating'); - $sync_ok = 1; + @sync_errors = (); my $sync_file; if ($mirror =~ /^rsync:/) { @@ -351,12 +409,13 @@ sub sync_repo { } elsif ($mirror !~ /^\w+:/) { $sync_file = \&sync_file_link; } else { - sync_error("unsupported mirror URL type"); + my $message = "unsupported mirror URL type"; + show_error_dialogue($message); + print "ERROR: $message.\n"; return 0; } if ($version ne $last_version || $arch ne $last_arch) { - @available_rpms = (); $last_version = $version; $last_arch = $arch; clear_repo(); @@ -365,21 +424,24 @@ sub sync_repo { my $remote_repo = "$mirror/distrib/$version/$arch/media"; - if (@available_rpms == 0) { - my $download_dir = "$qa_repo/.download"; - mkdir_p($download_dir); - foreach my $media_type (qw(core nonfree tainted)) { - 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"); - } - unlink("$download_dir/$synthesis") - or die "ERROR: couldn't delete/unlink $download_dir/$synthesis in the QA repo.\n"; - gtk_update(); + my $download_dir = "$qa_repo/.download"; + mkdir_p($download_dir); + + my @available_rpms = (); + foreach my $media_type (qw(core nonfree tainted)) { + 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"); + } + if (!unlink("$download_dir/$synthesis")) { + my $message = "couldn't delete $download_dir/$synthesis in the QA repo.\n"; + show_error_dialogue($message); + die "ERROR: $message.\n"; } + gtk_update(); } my @required_rpms = (); @@ -388,22 +450,30 @@ sub sync_repo { my $matched = 0; foreach my $candidate (@available_rpms) { if ($candidate =~ /^$pattern/) { - push(@required_rpms, $candidate); + push(@required_rpms, $candidate) if !member($candidate, @required_rpms); $matched = 1; } } - $matched or sync_error("no match for $request in the remote repository"); + $matched or sync_error("$request not found in the remote repository"); } + my @existing_rpms = get_existing_rpms(); + my @unwanted_rpms = difference2(\@existing_rpms, \@required_rpms); if (@unwanted_rpms) { - unlink(map { "$qa_repo/$_" } @unwanted_rpms) - or die "ERROR: couldn't delete/unlink unwanted RPMs in the QA repo.\n"; + if (!unlink(map { "$qa_repo/$_" } @unwanted_rpms)) { + my $message = "couldn't delete unwanted RPMs in the QA repo.\n"; + show_error_dialogue($message); + die "ERROR: $message.\n"; + } } my $old_pubkey = "$qa_repo/media_info/pubkey"; if (-e $old_pubkey) { - unlink($old_pubkey) - or die "ERROR: couldn't delete/unlink old pubkey in the QA repo.\n"; + if (!unlink($old_pubkey)) { + my $message = "couldn't delete old pubkey in the QA repo.\n"; + show_error_dialogue($message); + die "ERROR: $message.\n"; + } } mkdir_p("$qa_repo/media_info"); @@ -424,14 +494,15 @@ sub sync_repo { &$sync_file("$remote_repo/core/updates_testing/media_info/pubkey", "$qa_repo/media_info"); gtk_update(); - if ($sync_ok) { + if (@sync_errors == 0) { system("genhdlist2 --allow-empty-media $qa_repo") == 0 or sync_error("failed to update hdlist"); } else { - print "ERROR: failed to download all the files.\n" + print "ERROR: failed to download all the files.\n"; + show_error_dialogue(@sync_errors); } - $sync_ok; + @sync_errors == 0; } sub sync_file_rsync { @@ -462,11 +533,18 @@ sub sync_file_link { sub sync_error { my ($message) = @_; + push(@sync_errors, $message); print "ERROR: $message.\n"; - $sync_ok = 0; 0; } +sub trim { + my ($text) = @_; + $text =~ s/^\s+//; + $text =~ s/\s+$//; + $text; +} + sub wildcard_to_regexp { my ($pattern) = @_; $pattern =~ s/\./\\./g; @@ -475,6 +553,11 @@ sub wildcard_to_regexp { $pattern; } +sub show_error_dialogue { + $error_text->get_buffer()->set_text(join("\n", @_)); + $error_window->show_all(); +} + sub gtk_update { while (Gtk3::events_pending()) { Gtk3::main_iteration(); -- cgit v1.2.1