diff --git a/repos/libports/src/app/extract/README b/repos/libports/src/app/extract/README index f0e9e566f2..ccc6ebdd62 100644 --- a/repos/libports/src/app/extract/README +++ b/repos/libports/src/app/extract/README @@ -26,3 +26,15 @@ how many path elements should be removed from the files stored in the archive during extraction. In this example the top directory would be omitted. The 'name' attribute is used for naming compressed files that are not part of an archive. + +The 'ignore_failures' attribute of the 'config' node instructs the component +to attempt to extract all given archives and even in the case of failures to +report success. This option is intended for batch-operations where only the +overall success is of importance. + +The 'stop_on_failure' attribute of the 'config' node instructs the component +to stop processing any archive after the extraction of one has already failed. + +In the default configuration 'ignore_failures' is 'false' while 'stop_on_failure' +is 'true' so processing a batch of archives will stop on the first failure and +leads to exiting with a non-zero exit-value. diff --git a/repos/libports/src/app/extract/main.cc b/repos/libports/src/app/extract/main.cc index 0e949c909b..f86cc2ebe8 100644 --- a/repos/libports/src/app/extract/main.cc +++ b/repos/libports/src/app/extract/main.cc @@ -242,14 +242,28 @@ struct Extract::Main bool _verbose = false; - void _process_config() + bool _ignore_failures = false; + + bool _stop_on_failure = false; + + bool _process_config() { Xml_node const config = _config.xml(); _verbose = config.attribute_value("verbose", false); + _ignore_failures = config.attribute_value("ignore_failures", false); + + _stop_on_failure = config.attribute_value("stop_on_failure", true); + + bool overall_success = true; + config.for_each_sub_node("extract", [&] (Xml_node node) { + /* ignore any following archives after one failed */ + if (!overall_success && _stop_on_failure) + return; + Path const src_path = node.attribute_value("archive", Path()); Path const dst_path = node.attribute_value("to", Path()); Raw_name const raw_name = node.attribute_value("name", Raw_name()); @@ -280,20 +294,27 @@ struct Extract::Main catch (Extracted_archive::Write_failed) { warning("writing to directory ", dst_path, " failed"); } - /* abort on first error */ - if (!success) - throw Exception(); + if (!success) { + overall_success = false; + return; + } if (_verbose) log("extracted '", src_path, "' to '", dst_path, "'"); }); + + return overall_success; } Main(Env &env) : _env(env) { - Libc::with_libc([&] () { _process_config(); }); + bool success = false; - env.parent().exit(0); + Libc::with_libc([&] () { success = _process_config(); }); + + env.parent().exit(_ignore_failures ? 0 + : success ? 0 + : 1); } };