diff --git a/src/decman/app.py b/src/decman/app.py index b588d10..bd9b92c 100644 --- a/src/decman/app.py +++ b/src/decman/app.py @@ -78,17 +78,26 @@ def main(): try: store = l.Store.restore() + except err.UserFacingError as error: + l.print_error(error.user_facing_msg) + for line in traceback.format_exc().splitlines(): + l.print_debug(line) + sys.exit(1) + + errored = False + + try: opts = _set_up(store, args) Core(store, opts).run() except err.UserFacingError as error: l.print_error(error.user_facing_msg) for line in traceback.format_exc().splitlines(): l.print_debug(line) - sys.exit(1) + errored = True except decman.UserRaisedError as user_error: l.print_error( f"Error encountered while running the source: {user_error}") - sys.exit(1) + errored = True # Save even when an error has occurred, since this avoids repeating steps like building pkgs. try: @@ -97,9 +106,11 @@ def main(): l.print_error(error.user_facing_msg) for line in traceback.format_exc().splitlines(): l.print_debug(line) - sys.exit(1) + errored = True os.chdir(original_wd) + if errored: + sys.exit(2) def _set_up(store: l.Store, args): diff --git a/src/decman/lib/__init__.py b/src/decman/lib/__init__.py index b86f446..8f94897 100644 --- a/src/decman/lib/__init__.py +++ b/src/decman/lib/__init__.py @@ -188,12 +188,45 @@ class Store: self.source_file: typing.Optional[str] = None self.allow_running_source_without_prompt: bool = False self.enabled_systemd_units: list[str] = [] - self.enabled_user_systemd_units: list[tuple[str, str]] = [] + self._enabled_user_systemd_units: list[str] = [] self.enabled_modules: dict[str, str] = {} self.created_files: list[str] = [] self.pkgbuild_latest_reviewed_commits: dict[str, str] = {} self._package_file_cache: dict[str, tuple[str, str]] = {} + def add_enabled_user_systemd_unit(self, user: str, unit: str): + """ + Stores a user unit as enabled. + """ + self._enabled_user_systemd_units.append(f"{user}->{unit}") + + def remove_enabled_user_systemd_unit(self, user: str, unit: str): + """ + Removes a user unit from stored units. + """ + try: + self._enabled_user_systemd_units.remove(f"{user}->{unit}") + except ValueError: + pass + + def is_systemd_used_unit_enabled(self, user: str, unit: str) -> bool: + """ + Returns true if the given user unit is stored as enabled. + """ + return f"{user}->{unit}" in self._enabled_user_systemd_units + + def get_enabled_user_systemd_units(self) -> list[tuple[str, str]]: + """ + Returns all enabled systemd units. + """ + result = [] + for unit_str in self._enabled_user_systemd_units: + unit_l = unit_str.split("->") + user = unit_l[0] + unit = unit_l[1] + result.append((user, unit)) + return result + def get_package(self, package: str) -> typing.Optional[tuple[str, str]]: """ Returns the version and the path of a package stored in the built packages cache as a tuple @@ -228,7 +261,7 @@ class Store: "allow_running_source_without_prompt": self.allow_running_source_without_prompt, "enabled_systemd_units": self.enabled_systemd_units, - "enabled_user_systemd_units": self.enabled_user_systemd_units, + "enabled_user_systemd_units": self._enabled_user_systemd_units, "enabled_modules": self.enabled_modules, "created_files": self.created_files, "package_file_cache": self._package_file_cache, @@ -268,7 +301,7 @@ class Store: "enabled_systemd_units", [], ) - store.enabled_user_systemd_units = d.get( + store._enabled_user_systemd_units = d.get( "enabled_user_systemd_units", [], ) @@ -457,8 +490,7 @@ class Source: result = {} for user, units in self._all_user_units().items(): for unit in units: - stored = (user, unit) - if stored not in store.enabled_user_systemd_units: + if not store.is_systemd_used_unit_enabled(user, unit): entry = result.get(user, []) entry.append(unit) result[user] = entry @@ -469,10 +501,8 @@ class Source: Returns all user systemd units that should be disabled. """ result = {} - for stored in store.enabled_user_systemd_units: - user, unit = stored - - if unit not in self._all_user_units().get(user, []): + for user, unit in store.get_enabled_user_systemd_units(): + if unit not in self._all_user_units().get(user, set()): entry = result.get(user, []) entry.append(unit) result[user] = entry @@ -775,7 +805,7 @@ class Systemd: f"Failed to enable systemd units because user {user} doesn't exist." ) from error for unit in units: - self.state.enabled_user_systemd_units.append((user, unit)) + self.state.add_enabled_user_systemd_unit(user, unit) def disable_user_units(self, units: list[str], user: str): """ @@ -801,7 +831,4 @@ class Systemd: ) from error for unit in units: - try: - self.state.enabled_user_systemd_units.remove((user, unit)) - except ValueError: - pass + self.state.remove_enabled_user_systemd_unit(user, unit) diff --git a/tests/test_source_resolution.py b/tests/test_source_resolution.py index e83b879..4084d93 100644 --- a/tests/test_source_resolution.py +++ b/tests/test_source_resolution.py @@ -146,8 +146,8 @@ class TestSource(unittest.TestCase): store = Store() store.enabled_systemd_units.extend( ["1.service", "3.service", "M_1.service"]) - store.enabled_user_systemd_units.extend([("user", "u1.service"), - ("user", "u3.service")]) + store.add_enabled_user_systemd_unit("user", "u1.service") + store.add_enabled_user_systemd_unit("user", "u3.service") store.enabled_modules = { "Existing": "1", "ExistingChanged": "1",