The MinGW.OSDN Installation Manager Tool
Revision | 9894a37a511ab8e3d6ec488a2fc79d7aefd184ff (tree) |
---|---|
Zeit | 2012-12-19 23:16:43 |
Autor | Keith Marshall <keithmarshall@user...> |
Commiter | Keith Marshall |
Make the "Apply Changes" dialogue "failure-aware".
@@ -1,5 +1,28 @@ | ||
1 | 1 | 2012-12-19 Keith Marshall <keithmarshall@users.sourceforge.net> |
2 | 2 | |
3 | + Make the "Apply Changes" dialogue "failure-aware". | |
4 | + | |
5 | + * src/pkgtask.h (ACTION_APPLY_FAILED): Redefine, in terms of... | |
6 | + (ACTION_INSTALL_FAILED, ACTION_REMOVE_FAILED): New manifest defines. | |
7 | + (ACTION_UNSUCCESSFUL): New manifest constant; define it. | |
8 | + | |
9 | + * src/pkgdata.cpp (pkgActionItem::EnumeratePendingActions): | |
10 | + [ACTION_UNSUCCESSFUL]: Make it a special case for enumeration. | |
11 | + | |
12 | + * src/guixmld.cpp (pkgApplyChanges): Enumerate... | |
13 | + [ACTION_UNSUCCESSFUL > 0]: ...all such cases; when true... | |
14 | + [IDD_AUTO_CLOSE_OPTION]: ...this; select alternative close-out | |
15 | + messages, as appropriate. | |
16 | + (pkgActionItem::Assert): Factor out; relocate to... | |
17 | + * src/pkgexec.cpp (pkgActionItem::Assert): ...here; this moves its | |
18 | + object code into the mingw-get DLL. | |
19 | + | |
20 | + * src/pkgunst.cpp (pkgRemove) [ACTION_REMOVE_FAILED]: | |
21 | + * src/pkginst.cpp (pkgInstall) [ACTION_INSTALL_FAILED]: | |
22 | + Assert as appropriate. | |
23 | + | |
24 | +2012-12-19 Keith Marshall <keithmarshall@users.sourceforge.net> | |
25 | + | |
3 | 26 | Improve progress reporting in "Apply Changes" dialogue. |
4 | 27 | |
5 | 28 | * src/pkgstat.h: New header file; it declares... |
@@ -344,15 +344,18 @@ static void pkgApplyChanges( void *window ) | ||
344 | 344 | app->ExecuteScheduledActions(); |
345 | 345 | dmh_setpty( NULL ); |
346 | 346 | |
347 | + /* Check for successful application of all scheduled changes. | |
348 | + */ | |
349 | + int error_count = app->EnumerateActions( ACTION_UNSUCCESSFUL ); | |
350 | + | |
347 | 351 | /* During processing, the user may have selected the option for |
348 | 352 | * automatic dismissal of the dialogue box on completion... |
349 | - * | |
350 | - * FIXME: We need to adapt this, so that auto-close is ignored | |
351 | - * when any scheduled action fails to complete successfully. | |
352 | 353 | */ |
353 | - if( IsDlgButtonChecked( (HWND)(window), IDD_AUTO_CLOSE_OPTION ) ) | |
354 | + if( (error_count == 0) | |
355 | + && IsDlgButtonChecked( (HWND)(window), IDD_AUTO_CLOSE_OPTION ) ) | |
354 | 356 | /* |
355 | - * ...in which case, we dismiss it without further ado... | |
357 | + * ...in which case, and provided all changes were applied | |
358 | + * successfully, we dismiss it without further ado... | |
356 | 359 | */ |
357 | 360 | SendMessage( (HWND)(window), WM_COMMAND, (WPARAM)(IDOK), 0 ); |
358 | 361 |
@@ -365,8 +368,11 @@ static void pkgApplyChanges( void *window ) | ||
365 | 368 | |
366 | 369 | /* ...and notify the user that it must be clicked to continue. |
367 | 370 | */ |
368 | - stat.Report( "All changes have been successfully applied;" | |
369 | - " you may now close this dialogue." | |
371 | + stat.Report( (error_count == 0) | |
372 | + ? "All changes were applied successfully;" | |
373 | + " you may now close this dialogue." | |
374 | + : "Not all changes were applied successfully;" | |
375 | + " please refer to details below." | |
370 | 376 | ); |
371 | 377 | } |
372 | 378 | } |
@@ -477,36 +483,6 @@ pkgActionItem | ||
477 | 483 | return residual; |
478 | 484 | } |
479 | 485 | |
480 | -void pkgActionItem::Assert | |
481 | -( unsigned long set, unsigned long mask, pkgActionItem *schedule ) | |
482 | -{ | |
483 | - /* A method to manipulate the control, error trapping, and state | |
484 | - * flags for all items in the specified schedule of actions. | |
485 | - * | |
486 | - * Starting at the specified item, or the invoking class object | |
487 | - * item if no starting point is specified... | |
488 | - */ | |
489 | - if( (schedule != NULL) || ((schedule = this) != NULL) ) | |
490 | - { | |
491 | - /* ...and provided this starting point is not NULL, walk back | |
492 | - * to the first item in the associated task schedule... | |
493 | - */ | |
494 | - while( schedule->prev != NULL ) schedule = schedule->prev; | |
495 | - while( schedule != NULL ) | |
496 | - { | |
497 | - /* ...then, processing each scheduled task item in sequence, | |
498 | - * update the flags according to the specified mask and new | |
499 | - * bits to be set... | |
500 | - */ | |
501 | - schedule->flags = (schedule->flags & mask) | set; | |
502 | - /* | |
503 | - * ...before moving on to the next item in the sequence. | |
504 | - */ | |
505 | - schedule = schedule->next; | |
506 | - } | |
507 | - } | |
508 | -} | |
509 | - | |
510 | 486 | static int pkgActionCount( HWND dlg, int id, const char *fmt, int classified ) |
511 | 487 | { |
512 | 488 | /* Helper function to itemise the currently scheduled actions |
@@ -1284,11 +1284,16 @@ unsigned long pkgActionItem::EnumeratePendingActions( int classified ) | ||
1284 | 1284 | ++count; |
1285 | 1285 | } |
1286 | 1286 | } |
1287 | - else if( classified == 0 ) | |
1287 | + else if( (classified == 0) | |
1288 | 1288 | /* |
1289 | - * ...otherwise, when we aren't interested in any | |
1290 | - * particular class of action, just count all those | |
1291 | - * which are found, regardless of classification. | |
1289 | + * ...otherwise, when we aren't interested in any particular | |
1290 | + * class of action regardless of classification... | |
1291 | + */ | |
1292 | + || ((classified == ACTION_UNSUCCESSFUL) && ((flags & classified) != 0)) ) | |
1293 | + /* | |
1294 | + * ...or when we are checking for unsuccessful actions, we | |
1295 | + * count all those which are found, either unclassified, or | |
1296 | + * marked as unsuccessful, respectively. | |
1292 | 1297 | */ |
1293 | 1298 | ++count; |
1294 | 1299 | } |
@@ -306,6 +306,36 @@ pkgActionItem::Schedule( unsigned long action, pkgActionItem& item ) | ||
306 | 306 | return rtn; |
307 | 307 | } |
308 | 308 | |
309 | +void pkgActionItem::Assert | |
310 | +( unsigned long set, unsigned long mask, pkgActionItem *schedule ) | |
311 | +{ | |
312 | + /* A method to manipulate the control, error trapping, and state | |
313 | + * flags for all items in the specified schedule of actions. | |
314 | + * | |
315 | + * Starting at the specified item, or the invoking class object | |
316 | + * item if no starting point is specified... | |
317 | + */ | |
318 | + if( (schedule != NULL) || ((schedule = this) != NULL) ) | |
319 | + { | |
320 | + /* ...and provided this starting point is not NULL, walk back | |
321 | + * to the first item in the associated task schedule... | |
322 | + */ | |
323 | + while( schedule->prev != NULL ) schedule = schedule->prev; | |
324 | + while( schedule != NULL ) | |
325 | + { | |
326 | + /* ...then, processing each scheduled task item in sequence, | |
327 | + * update the flags according to the specified mask and new | |
328 | + * bits to be set... | |
329 | + */ | |
330 | + schedule->flags = (schedule->flags & mask) | set; | |
331 | + /* | |
332 | + * ...before moving on to the next item in the sequence. | |
333 | + */ | |
334 | + schedule = schedule->next; | |
335 | + } | |
336 | + } | |
337 | +} | |
338 | + | |
309 | 339 | pkgActionItem* |
310 | 340 | pkgActionItem::GetReference( pkgActionItem& item ) |
311 | 341 | { |
@@ -4,7 +4,7 @@ | ||
4 | 4 | * $Id$ |
5 | 5 | * |
6 | 6 | * Written by Keith Marshall <keithmarshall@users.sourceforge.net> |
7 | - * Copyright (C) 2010, 2011, 2012, MinGW Project | |
7 | + * Copyright (C) 2010, 2011, 2012, MinGW.org Project | |
8 | 8 | * |
9 | 9 | * |
10 | 10 | * Implementation of the primary package installation and package |
@@ -378,9 +378,12 @@ EXTERN_C void pkgRegister | ||
378 | 378 | |
379 | 379 | EXTERN_C void pkgInstall( pkgActionItem *current ) |
380 | 380 | { |
381 | - /* Common handler for all package installation tasks... | |
381 | + /* Common handler for all package installation tasks; note that we | |
382 | + * initially assert failure, and will revert this assertion in the | |
383 | + * event of subsequent successful installation... | |
382 | 384 | */ |
383 | 385 | pkgXmlNode *pkg; |
386 | + current->Assert( ACTION_INSTALL_FAILED ); | |
384 | 387 | if( (pkg = current->Selection()) != NULL ) |
385 | 388 | { |
386 | 389 | /* The current action item has a valid package association... |
@@ -451,6 +454,11 @@ EXTERN_C void pkgInstall( pkgActionItem *current ) | ||
451 | 454 | * we may now run its post-install script, (if any). |
452 | 455 | */ |
453 | 456 | pkg->InvokeScript( "post-install" ); |
457 | + | |
458 | + /* When we get to here, the package should have been installed | |
459 | + * successfully; revert our original assertion of failure. | |
460 | + */ | |
461 | + current->Assert( 0UL, ~ACTION_INSTALL_FAILED ); | |
454 | 462 | } |
455 | 463 | else |
456 | 464 | /* There is a prior installation of the selected package, which |
@@ -86,7 +86,11 @@ enum | ||
86 | 86 | * could not be completed successfully. |
87 | 87 | */ |
88 | 88 | #define ACTION_DOWNLOAD_FAILED (ACTION_PRIMARY << 5) |
89 | -#define ACTION_APPLY_FAILED (ACTION_PRIMARY << 6) | |
89 | +#define ACTION_INSTALL_FAILED (ACTION_PRIMARY << 6) | |
90 | +#define ACTION_REMOVE_FAILED (ACTION_PRIMARY << 7) | |
91 | + | |
92 | +#define ACTION_APPLY_FAILED (ACTION_INSTALL_FAILED | ACTION_REMOVE_FAILED) | |
93 | +#define ACTION_UNSUCCESSFUL (ACTION_DOWNLOAD_FAILED | ACTION_APPLY_FAILED) | |
90 | 94 | |
91 | 95 | #ifndef EXTERN_C |
92 | 96 | /* A convenience macro, to facilitate declaration of functions |
@@ -301,9 +301,11 @@ int pkg_unlink( const char *sysroot, const char *pathname ) | ||
301 | 301 | |
302 | 302 | EXTERN_C void pkgRemove( pkgActionItem *current ) |
303 | 303 | { |
304 | - /* Common handler for all package removal tasks... | |
304 | + /* Common handler for all package removal tasks; note that we | |
305 | + * initially assert failure, pending reversion on success... | |
305 | 306 | */ |
306 | 307 | pkgXmlNode *pkg; |
308 | + current->Assert( ACTION_REMOVE_FAILED ); | |
307 | 309 | if( ((pkg = current->Selection( to_remove )) != NULL) |
308 | 310 | && (current->HasAttribute( ACTION_DOWNLOAD_OK ) == ACTION_REMOVE_OK) ) |
309 | 311 | { |
@@ -399,6 +401,12 @@ EXTERN_C void pkgRemove( pkgActionItem *current ) | ||
399 | 401 | "%s: unreferenced in %s\n", sysname, id_lookup( manifest, value_unknown ) |
400 | 402 | ); |
401 | 403 | } |
404 | + else | |
405 | + /* Removal should be successful: revert our original | |
406 | + * assertion of failure... | |
407 | + */ | |
408 | + current->Assert( 0UL, ~ACTION_REMOVE_FAILED ); | |
409 | + | |
402 | 410 | /* Now, we've validated the manifest, and confirmed that it |
403 | 411 | * correctly records its association with the current sysroot, |
404 | 412 | * (or we've reported the inconsistency; we may proceed with |