/[soft]/rpm/urpmi/trunk/gurpmi2
ViewVC logotype

Contents of /rpm/urpmi/trunk/gurpmi2

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7727 - (show annotations) (download)
Sat Mar 30 14:54:42 2013 UTC (11 years ago) by tv
File size: 13321 byte(s)
remove debug statement
1 #!/usr/bin/perl
2
3 #- Copyright (C) 2005 MandrakeSoft SA
4 #- Copyright (C) 2005-2010 Mandriva SA
5
6 use strict;
7
8 BEGIN { #- set up a safe path and environment
9 $ENV{PATH} = "/sbin:/usr/sbin:/bin:/usr/bin";
10 delete @ENV{qw(ENV BASH_ENV IFS CDPATH)};
11 }
12
13 use gurpmi;
14 use gurpm::RPMProgressDialog;
15 use urpm::install;
16 use urpm::media;
17 use urpm::signature;
18 use urpm::get_pkgs;
19 use urpm::msg;
20 use urpm::select;
21 use urpm::main_loop;
22 use Gtk2;
23
24 #- default options.
25 our $allow_medium_change = 0;
26 our $auto_select = 0;
27 our $force = 0;
28 our $test = 0;
29 our $use_provides = 1;
30
31 # For other distros w/o exception support:
32 eval { Glib->enable_exceptions2 };
33 if (my $err = $@) {
34 warn "Error: $err\n";
35 }
36
37 #- GUI globals
38 my $mainw;
39
40 my @all_rpms = gurpmi::parse_command_line();
41
42 $> and fatal(N("Must be root"));
43
44 #- Now, the graphical stuff.
45
46 Gtk2->init;
47
48 #- Initialize urpm
49
50 my $urpm;
51 {
52 local @ARGV = @ARGV;
53 $urpm = urpm->new_parse_cmdline;
54 }
55
56 #- Create main window
57
58 $mainw = gurpm::RPMProgressDialog->new($urpm, \&quit);
59
60 #- Performs installation
61
62 configure_urpm($urpm);
63
64 my $state = {};
65 my %requested = $urpm->register_rpms(@all_rpms);
66 if (@gurpmi::names) {
67 urpm::select::search_packages($urpm, \%requested, [ @gurpmi::names ],
68 use_provides => $use_provides,
69 ) || $force or exit 1;
70 }
71
72 $mainw->label(N("Preparing packages installation..."));
73
74 #- return value is true if program should be restarted (in order to take care of important
75 #- packages being upgraded (problably urpmi and perl-URPM, but maybe rpm too, and glibc also ?).
76 my $restart_itself = urpm::select::resolve_dependencies($urpm,
77 $state,
78 \%requested,
79 callback_choices => \&ask_choice,
80 auto_select => $::auto_select,
81 priority_upgrade => $urpm->{options}{'priority-upgrade'},
82 );
83 my @ask_unselect = urpm::select::unselected_packages($state);
84
85 # If there are some unselected packages, designate that we are going to return nonzero code.
86 if (@ask_unselect) {
87 my $unselect_msg = N("Some requested packages cannot be installed:\n%s",
88 urpm::select::translate_why_unselected($urpm, $state, @ask_unselect));
89 $urpm::postponed_msg .= $unselect_msg . "\n";
90 $urpm::postponed_code = 17;
91 }
92
93 @ask_unselect
94 ? ask_continue(N(
95 "Some requested packages cannot be installed:\n%s\nContinue installation anyway?",
96 urpm::select::translate_why_unselected($urpm, $state, @ask_unselect)
97 ), \&do_install)
98 : do_install();
99
100 $mainw->show_all;
101 Gtk2->main;
102
103 my ($rpm_lock, $urpmi_lock);
104
105 #- Creates and configure an urpm object for this application to use.
106 sub configure_urpm {
107 my ($urpm) = @_;
108
109 $urpm->{fatal} = sub {
110 printf STDERR "%s\n", $_[1];
111 Gtk2::MessageDialog->new($mainw, [qw(modal destroy-with-parent)], 'error', 'ok', Locale::gettext::iconv($_[1], undef, 'UTF-8'))->run;
112 quit();
113 exit $_[0];
114 };
115 $urpm->{log} = sub { printf "%s\n", $_[0] };
116 $urpm->{error} = sub {
117 my ($message) = @_;
118 printf STDERR "%s\n", $message;
119
120 if (my $download_errors = delete $urpm->{download_errors}) {
121 $message = join("\n", @$download_errors, $message);
122 }
123 my $nb_lines = $message =~ tr/\n/\n/;
124 my $w;
125 if ($nb_lines > 30 || $message =~ /^transaction is too small/) {
126 $w = Gtk2::Dialog->new(N("Warning"), $mainw, [qw(modal destroy-with-parent)], N("Ok"), 'ok');
127 $w->vbox->add(my $f = Gtk2::Frame->new);
128 my $sw = create_scrolled_window(my $text = Gtk2::TextView->new);
129 $sw->set_border_width(2);
130 $text->set_wrap_mode('word');
131 $f->add($sw);
132 $text->get_buffer->set_text($message);
133 $text->set_editable(0);
134 $_->show foreach $f, $sw, $text;
135 $w->set_size_request(400, 400);
136 $w->set_default_response('ok');
137 } else {
138 $w = Gtk2::MessageDialog->new($mainw, [qw(modal destroy-with-parent)], 'warning', 'ok', $message);
139 }
140 $w->run;
141 $w->destroy;
142 };
143 urpm::select::set_priority_upgrade_option($urpm, $gurpmi::options{previous_priority_upgrade});
144 $rpm_lock = urpm::lock::rpm_db($urpm, 'exclusive');
145 $urpmi_lock = urpm::lock::urpmi_db($urpm);
146 urpm::media::configure($urpm,
147 media => $gurpmi::options{media},
148 searchmedia => $gurpmi::options{searchmedia},
149 update => $::update,
150 );
151 $urpm->{options}{'verify-rpm'} = 0 if $gurpmi::options{'no-verify-rpm'};
152 }
153
154 #- Callback for choices
155 sub ask_choice {
156 my (undef, undef, undef, $choices) = @_;
157 return $choices->[0] if $gurpmi::options{auto};
158 my $radio;
159 my @radios = map {
160 $radio = Gtk2::RadioButton->new_with_label(
161 $radio ? $radio->get_group : undef,
162 (scalar $_->fullname) . " : " . $_->summary
163 . ($_->flag_installed ? N(" (to upgrade)") : '')
164 . ($_->flag_upgrade ? N(" (to install)") : '')
165 );
166 } @$choices;
167 my $d = Gtk2::Dialog->new(N("Package choice"), $mainw, [], N("_Cancel") => 0, N("_Ok") => 1);
168 my $label = Gtk2::Label->new(N("One of the following packages is needed:"));
169 $label->set_alignment(0.5, 0.5);
170 $d->vbox->pack_start($label, 1, 1, 0);
171 $d->vbox->pack_start($_, 1, 1, 0) foreach @radios;
172 my $n = 0;
173 $d->signal_connect(response => sub {
174 if ($_[1] == 1) { #- "ok"
175 foreach (@radios) { last if $_->get_active; ++$n }
176 }
177 $d->destroy;
178 exit(1) if $_[1] == 0; #- "cancel"
179 });
180 $radios[0]->set_active(1);
181 $d->set_default_response(1); # defaults to ok
182 $d->show_all;
183 $d->run;
184 $choices->[$n];
185 }
186
187 sub ask_continue {
188 my ($msg, $nextclosure, $o_list, $o_end_msg) = @_;
189 my $vbox = Gtk2::VBox->new(0, 5);
190 $vbox->pack_start(new_label($msg), 1, 1, 0);
191 $urpm->{log}($msg);
192 warn ">> o_list='$o_list'\n";
193 if ($o_end_msg) {
194 $vbox->pack_start(new_label($o_list), 1, 1, 0);
195 $vbox->pack_start(new_label($o_end_msg), 1, 1, 0);
196 }
197 my $continue_button = Gtk2::Button->new(but(N("_Ok")));
198 my $quit_button = Gtk2::Button->new(but(N("_Abort")));
199 $quit_button->signal_connect(clicked => sub { $urpm->{log}("=> cancel"); &quit(); exit 1 });
200 $continue_button->signal_connect(clicked => sub { $urpm->{log}("=> ok"); goto &$nextclosure });
201 add_button_box($vbox, $quit_button, $continue_button);
202 $mainw->change_widget($vbox);
203 # default is to continue, but according to some HIG, warning should reverse the choise and defaults to abort
204 $mainw->set_focus($continue_button); # also set_default should be called but it gives a warning!
205 }
206
207 sub ask_continue_if_no_auto {
208 my ($msg, $nextclosure, $o_list, $o_end_msg) = @_;
209 if ($gurpmi::options{auto}) {
210 $urpm->{log}($msg);
211 $urpm->{log}("=> ok(auto)");
212 goto &$nextclosure;
213 } else {
214 ask_continue($msg, $nextclosure, $o_list, $o_end_msg);
215 }
216 }
217
218 sub ask_continue_blocking {
219 my ($msg) = @_;
220 my $w = Gtk2::MessageDialog->new($mainw, [qw(modal destroy-with-parent)], 'question', 'yes-no', $msg);
221 my $answer = $w->run;
222 $w->destroy;
223 $urpm->{log}($msg . " => " . $answer);
224 exit(1) if $answer eq 'no';
225 1;
226 }
227
228 sub do_install {
229 $mainw->label;
230 my @ask_remove = urpm::select::removed_packages($state);
231 @ask_remove
232 ? ask_continue_if_no_auto(N(
233 "The following packages have to be removed for others to be upgraded:\n%s\nContinue installation anyway?",
234 urpm::select::translate_why_removed($urpm, $state, @ask_remove)
235 ), \&do_install_2)
236 : goto &do_install_2;
237 }
238
239 sub do_install_2 () {
240 my @to_install = map { scalar $_->fullname } @{$urpm->{depslist}}[sort { $a <=> $b } keys %{$state->{selected}}]; # sorted by medium for format_selected_packages
241 $urpm->{nb_install} = @to_install;
242 my ($size, $filesize) = $urpm->selected_size_filesize($state);
243 my $msg2 = $size >= 0 ?
244 N("%s of additional disk space will be used.", formatXiB($size)) :
245 N("%s of disk space will be freed.", formatXiB(-$size));
246 my $msg2_ = $filesize ? "\n" . N("%s of packages will be retrieved.", formatXiB($filesize)) . "\n" : '';
247 my $msg3 = P("Proceed with the installation of one package?",
248 "Proceed with the installation of the %d packages?",
249 $urpm->{nb_install}, $urpm->{nb_install});
250 @to_install > 1
251 ? ask_continue_if_no_auto(
252 (scalar(@to_install) == 1 ?
253 N("To satisfy dependencies, the following package is going to be installed:")
254 : N("To satisfy dependencies, the following packages are going to be installed:")),
255 \&do_install_3,
256 join("\n", @to_install),
257 $msg2 . $msg2_ . $msg3)
258 : goto \&do_install_3;
259 }
260
261 sub do_install_3 () {
262 $mainw->label($mainw->title);
263 my ($local_sources, $blists) = urpm::get_pkgs::selected2local_and_blists($urpm, $state->{selected});
264 $local_sources || $blists or $urpm->{fatal}(3, N("unable to get source packages, aborting"));
265
266 $mainw->init_progressbar;
267
268 my $exit_code;
269 $exit_code = urpm::main_loop::run($urpm, $state, scalar(@gurpmi::names), \@ask_unselect, {
270 bad_signature => sub {
271 my ($msg, $msg2) = @_;
272 $urpm->{log}("$msg\n$msg2");
273 ask_continue_blocking("$msg\n$msg2");
274 },
275 copy_removable => sub {
276 #FIXME: use use udisks to wait-for/mount cdroms:
277 my $w = Gtk2::MessageDialog->new($mainw, [qw(modal destroy-with-parent)], 'warning', 'ok-cancel',
278 N("Please insert the medium named \"%s\"", $_[0])
279 );
280 my $response = $w->run;
281 $w->destroy;
282 exit 1 if $response eq 'cancel';
283 1;
284 },
285 trans_log => \&gurpm::RPMProgressDialog::callback_download,
286 post_download => sub {
287 if ($mainw->canceled) {
288 $exit_code = 10;
289 goto return_with_exit_code;
290 }
291 $mainw->invalidate_cancel_forever;
292 },
293
294 ask_yes_or_no => \&ask_yes_or_no,
295
296 completed => sub {
297 $urpmi_lock->unlock;
298 $rpm_lock->unlock;
299 urpm::removable::try_umounting_removables($urpm);
300 my $vbox = Gtk2::VBox->new(0, 5); # FIXME: should it be change_widget???
301 my $progress_label = Gtk2::Label->new('-'); # TEST ME
302 return 0 if $gurpmi::options{auto};
303 my $sw = create_scrolled_window($progress_label);
304 $sw->set_size_request(500, 200);
305 $vbox->pack_start($sw, 1, 1, 0);
306 my $quit_button = Gtk2::Button->new(but(N("_Done")));
307 $quit_button->signal_connect(clicked => \&quit);
308 add_button_box($vbox, $quit_button);
309 $mainw->change_widget($vbox);
310 $mainw->set_focus($quit_button);
311 },
312 need_restart => sub {
313 return if $gurpmi::options{auto};
314 my ($need_restart_formatted) = @_;
315 my $w = Gtk2::MessageDialog->new($mainw, [qw(modal destroy-with-parent)], 'warning', 'ok',
316 join("\n", values %$need_restart_formatted)
317 );
318 $w->run;
319 $w->destroy;
320 },
321 missing_files_summary => sub {
322 my ($error_sources) = @_;
323 $mainw->set_progresslabel(N("Installation failed, some files are missing:\n%s",
324 join("\n", map { s|([^:]*://[^/:\@]*:)[^/:\@]*(\@.*)|$1xxxx$2|; " $_" }
325 values %$error_sources))
326 . "\n" . N("You may want to update your urpmi database."));
327 },
328 trans_error_summary => sub {
329 my ($_nok, $errors) = @_;
330 $mainw->set_progresslabel(N("Installation failed:") . "\n" . join("\n", map { "\t$_" } @$errors));
331 },
332 # TODO: use urpmi strings:
333 already_installed_or_not_installable => sub {
334 my ($_msg1, $_msg2) = @_;
335 $mainw->set_progresslabel(N("The package(s) are already installed"));
336 },
337 success_summary => sub { $mainw->set_progresslabel(N("Installation finished")) },
338 pre_check_sig => \&gurpm::RPMProgressDialog::callback_pre_check_sig,
339 uninst => \&gurpm::RPMProgressDialog::callback_inst,
340 inst => \&gurpm::RPMProgressDialog::callback_inst,
341 trans => \&gurpm::RPMProgressDialog::callback_inst,
342 }
343 );
344
345 # Merge postponed exit code to the result of package installation.
346 $exit_code ||= $urpm::postponed_code;
347
348 #- restart gurpmi if needed, keep command line for that.
349 if ($restart_itself && !$exit_code) {
350 print N("restarting urpmi"), "\n";
351 #- it seems to work correctly with exec instead of system, provided
352 #- added --previous-priority-upgrade to allow checking if yet if
353 #- priority-upgrade list has changed. and make sure we don't uselessly restart
354 @ARGV = ('--previous-priority-upgrade=' . $urpm->{options}{'priority-upgrade'},
355 grep { !/^--no-priority-upgrade$|--previous-priority-upgrade=/ } @ARGV);
356 exec $0, @ARGV;
357 }
358
359 return_with_exit_code:
360 # Show postponed message before exiting
361 $urpm->{error}->($urpm::postponed_msg) if $urpm::postponed_code != 0;
362
363 exit $exit_code;
364 }
365
366 sub ask_yes_or_no {
367 my ($_title, $msg) = @_;
368 # MessageDialogs have no titles unless using 'secondary-text'
369 my $w = Gtk2::MessageDialog->new($mainw, [qw(modal destroy-with-parent)], 'warning', 'yes-no', $msg);
370 my $response = $w->run;
371 $w->destroy;
372 $response eq 'yes';
373 }
374
375

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.30