diff --git a/repos/gems/src/app/sculpt_manager/depot_query.h b/repos/gems/src/app/sculpt_manager/depot_query.h index d85fa61ba..f9746d3cc 100644 --- a/repos/gems/src/app/sculpt_manager/depot_query.h +++ b/repos/gems/src/app/sculpt_manager/depot_query.h @@ -22,6 +22,7 @@ namespace Sculpt { static inline bool blueprint_missing (Xml_node, Path const &); static inline bool blueprint_any_missing (Xml_node); + static inline bool blueprint_rom_missing (Xml_node, Path const &); static inline bool blueprint_any_rom_missing(Xml_node); } @@ -53,10 +54,21 @@ static inline bool Sculpt::blueprint_any_missing(Xml_node blueprint) } -static inline bool Sculpt::blueprint_any_rom_missing(Xml_node blueprint) +/** + * Return true if one or more ROMs of the pkg 'path' are missing from the + * blueprint + * + * If 'path' is an invalid string, all pkgs of the blueprint are checked. + */ +static inline bool Sculpt::blueprint_rom_missing(Xml_node blueprint, Path const &path) { bool result = false; blueprint.for_each_sub_node("pkg", [&] (Xml_node pkg) { + + /* skip pkgs that we are not interested in */ + if (path.valid() && pkg.attribute_value("path", Path()) != path) + return; + pkg.for_each_sub_node("missing_rom", [&] (Xml_node missing_rom) { /* ld.lib.so is always taken from the base system */ @@ -71,4 +83,10 @@ static inline bool Sculpt::blueprint_any_rom_missing(Xml_node blueprint) return result; } + +static inline bool Sculpt::blueprint_any_rom_missing(Xml_node blueprint) +{ + return blueprint_rom_missing(blueprint, Path()); +} + #endif /* _DEPOT_QUERY_H_ */ diff --git a/repos/gems/src/app/sculpt_manager/view/popup_dialog.cc b/repos/gems/src/app/sculpt_manager/view/popup_dialog.cc index 61e5faad1..4cbe59501 100644 --- a/repos/gems/src/app/sculpt_manager/view/popup_dialog.cc +++ b/repos/gems/src/app/sculpt_manager/view/popup_dialog.cc @@ -201,11 +201,11 @@ void Popup_dialog::_gen_menu_elements(Xml_generator &xml) const }); String<100> const text(Pretty(name), " " "(", version, ")", - installing ? " installing... " : "..."); + installing ? " installing... " : "... "); _gen_menu_entry(xml, id, text, selected); - if (selected && _pkg_missing && !installing) { + if (selected && !installing) { _construction_info.with_construction([&] (Component const &component) { @@ -213,7 +213,25 @@ void Popup_dialog::_gen_menu_elements(Xml_generator &xml) const gen_named_node(xml, "vbox", "vbox", [&] () { - if (_nic_ready()) { + /* + * Package is installed but content is missing + * + * This can happen when the pkg's runtime is + * inconsistent with the content contained in + * the pkg's archives. + */ + if (!_pkg_missing && _pkg_rom_missing) { + _gen_info_label(xml, "pad2", ""); + _gen_info_label(xml, "path", component.path); + _gen_info_label(xml, "pad3", ""); + xml.node("label", [&] () { + xml.attribute("text", "installed but incomplete"); }); + } + + /* + * Package is missing but can be installed + */ + else if (_pkg_missing && _nic_ready()) { _gen_pkg_info(xml, component); _gen_info_label(xml, "pad2", ""); @@ -226,8 +244,13 @@ void Popup_dialog::_gen_menu_elements(Xml_generator &xml) const }); }); }); + } - } else { + /* + * Package is missing and we cannot do anything + * about it + */ + else if (_pkg_missing) { _gen_info_label(xml, "pad2", ""); _gen_info_label(xml, "path", component.path); _gen_info_label(xml, "pad3", ""); diff --git a/repos/gems/src/app/sculpt_manager/view/popup_dialog.h b/repos/gems/src/app/sculpt_manager/view/popup_dialog.h index 8f290e4e2..b02b0c621 100644 --- a/repos/gems/src/app/sculpt_manager/view/popup_dialog.h +++ b/repos/gems/src/app/sculpt_manager/view/popup_dialog.h @@ -126,7 +126,8 @@ struct Sculpt::Popup_dialog typedef Depot::Archive::User User; User _selected_user { }; - bool _pkg_missing = false; + bool _pkg_missing = false; + bool _pkg_rom_missing = false; Component::Name _construction_name { }; @@ -465,11 +466,11 @@ struct Sculpt::Popup_dialog if (_state < PKG_REQUESTED) return; - _pkg_missing = blueprint_missing(blueprint, construction.path) - || blueprint_any_rom_missing(blueprint); + _pkg_rom_missing = blueprint_rom_missing(blueprint, construction.path); + _pkg_missing = blueprint_missing (blueprint, construction.path); construction.try_apply_blueprint(blueprint); - if (construction.blueprint_known && !_pkg_missing) + if (construction.blueprint_known && !_pkg_missing && !_pkg_rom_missing) _state = PKG_SHOWN; generate(); @@ -480,7 +481,7 @@ struct Sculpt::Popup_dialog if (_state == DEPOT_SELECTION) return true; - return _state >= PKG_REQUESTED && _pkg_missing; + return _state >= PKG_REQUESTED && (_pkg_missing || _pkg_rom_missing); } bool interested_in_file_operations() const