diff --git a/bench/bench.py b/bench/bench.py index 0f8d8f627..4aea84b38 100644 --- a/bench/bench.py +++ b/bench/bench.py @@ -10,7 +10,7 @@ # imports - module imports import bench -from bench.exceptions import ValidationError +from bench.exceptions import AppNotInstalledError, InvalidRemoteException from bench.config.common_site_config import setup_config from bench.utils import ( paths_in_bench, @@ -49,7 +49,7 @@ def run(self, cmd, cwd=None): class Validator: def validate_app_uninstall(self, app): if app not in self.apps: - raise ValidationError(f"No app named {app}") + raise AppNotInstalledError(f"No app named {app}") validate_app_installed_on_sites(app, bench_path=self.name) @@ -119,11 +119,16 @@ def install(self, app, branch=None): self.apps.append(app) self.apps.sync() - def uninstall(self, app): + def uninstall(self, app, no_backup=False, force=False): from bench.app import App - self.validate_app_uninstall(app) - self.apps.remove(App(app, bench=self, to_clone=False)) + if not force: + self.validate_app_uninstall(app) + try: + self.apps.remove(App(app, bench=self, to_clone=False), no_backup=no_backup) + except InvalidRemoteException: + if not force: + raise self.apps.sync() # self.build() - removed because it seems unnecessary self.reload() @@ -305,9 +310,10 @@ def add(self, app: "App"): super().append(app.repo) self.apps.sort() - def remove(self, app: "App"): + def remove(self, app: "App", no_backup: bool = False): app.uninstall() - app.remove() + if not no_backup: + app.remove() super().remove(app.repo) def append(self, app: "App"): diff --git a/bench/commands/make.py b/bench/commands/make.py index ac48f410a..8fe6382ba 100755 --- a/bench/commands/make.py +++ b/bench/commands/make.py @@ -180,12 +180,14 @@ def new_app(app_name, no_git=None): "Completely remove app from bench and re-build assets if not installed on any site" ), ) +@click.option("--no-backup", is_flag=True, help="Do not backup app before removing") +@click.option("--force", is_flag=True, help="Force remove app") @click.argument("app-name") -def remove_app(app_name): +def remove_app(app_name, no_backup=False, force=False): from bench.bench import Bench bench = Bench(".") - bench.uninstall(app_name) + bench.uninstall(app_name, no_backup=no_backup, force=force) @click.command("exclude-app", help="Exclude app from updating") diff --git a/bench/exceptions.py b/bench/exceptions.py index b33409154..48cb66688 100644 --- a/bench/exceptions.py +++ b/bench/exceptions.py @@ -21,9 +21,15 @@ class BenchNotFoundError(Exception): class ValidationError(Exception): pass + +class AppNotInstalledError(ValidationError): + pass + + class CannotUpdateReleaseBench(ValidationError): pass + class FeatureDoesNotExistError(CommandFailedError): pass diff --git a/bench/utils/__init__.py b/bench/utils/__init__.py index cacee9fb6..857468771 100644 --- a/bench/utils/__init__.py +++ b/bench/utils/__init__.py @@ -17,7 +17,7 @@ # imports - module imports from bench import PROJECT_NAME, VERSION -from bench.exceptions import CommandFailedError, InvalidRemoteException, ValidationError +from bench.exceptions import CommandFailedError, InvalidRemoteException, AppNotInstalledError logger = logging.getLogger(PROJECT_NAME) @@ -294,7 +294,7 @@ def set_git_remote_url(git_url, bench_path="."): app = git_url.rsplit("/", 1)[1].rsplit(".", 1)[0] if app not in Bench(bench_path).apps: - raise ValidationError(f"No app named {app}") + raise AppNotInstalledError(f"No app named {app}") app_dir = get_repo_dir(app, bench_path=bench_path)