2
0
mirror of https://github.com/frappe/bench.git synced 2024-11-16 01:57:08 +00:00

feat: bench validate-dependencies command (#1534)

This validates all `frappe-dependencies` and exits with 1 if any of
specifications fail.

This will be internal feature for FC for now. If this works well we can
make the validation fail during install-app itself without requiring any
additional command/steps.
This commit is contained in:
Ankush Menat 2024-02-07 18:27:54 +05:30 committed by GitHub
parent 1a421758a8
commit ab9b6172a4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 30 additions and 11 deletions

View File

@ -308,7 +308,7 @@ class App(AppMeta):
self.pyproject = get_pyproject(pyproject_path) self.pyproject = get_pyproject(pyproject_path)
return self.pyproject return self.pyproject
def validate_app_dependencies(self) -> None: def validate_app_dependencies(self, throw=False) -> None:
pyproject = self.get_pyproject() or {} pyproject = self.get_pyproject() or {}
deps: Optional[dict] = ( deps: Optional[dict] = (
pyproject.get("tool", {}).get("bench", {}).get("frappe-dependencies") pyproject.get("tool", {}).get("bench", {}).get("frappe-dependencies")
@ -317,7 +317,7 @@ class App(AppMeta):
return return
for dep, version in deps.items(): for dep, version in deps.items():
validate_dependency(self, dep, version) validate_dependency(self, dep, version, throw=throw)
""" """
Get App Cache Get App Cache
@ -489,16 +489,13 @@ def can_frappe_use_cached(app: App) -> bool:
return False return False
def validate_dependency(app: App, dep: str, req_version: str) -> None: def validate_dependency(app: App, dep: str, req_version: str, throw=False) -> None:
dep_path = Path(app.bench.name) / "apps" / dep dep_path = Path(app.bench.name) / "apps" / dep
if not dep_path.is_dir(): if not dep_path.is_dir():
click.secho( click.secho(f"Required frappe-dependency '{dep}' not found.", fg="yellow")
f"Required frappe-dependency '{dep}' not found. " if throw:
f"Aborting '{app.name}' installation. " sys.exit(1)
f"Please install '{dep}' first and retry", return
fg="red",
)
sys.exit(1)
dep_version = get_dep_version(dep, dep_path) dep_version = get_dep_version(dep, dep_path)
if not dep_version: if not dep_version:
@ -508,9 +505,12 @@ def validate_dependency(app: App, dep: str, req_version: str) -> None:
click.secho( click.secho(
f"Installed frappe-dependency '{dep}' version '{dep_version}' " f"Installed frappe-dependency '{dep}' version '{dep_version}' "
f"does not satisfy required version '{req_version}'. " f"does not satisfy required version '{req_version}'. "
f"App '{app.name}' might not work as expected", f"App '{app.name}' might not work as expected.",
fg="yellow", fg="yellow",
) )
if throw:
click.secho(f"Please install '{dep}{req_version}' first and retry", fg="red")
sys.exit(1)
def get_dep_version(dep: str, dep_path: Path) -> Optional[str]: def get_dep_version(dep: str, dep_path: Path) -> Optional[str]:

View File

@ -46,6 +46,7 @@ from bench.commands.make import (
new_app, new_app,
pip, pip,
remove_app, remove_app,
validate_dependencies,
) )
bench_command.add_command(init) bench_command.add_command(init)
@ -56,6 +57,7 @@ bench_command.add_command(remove_app)
bench_command.add_command(exclude_app_for_update) bench_command.add_command(exclude_app_for_update)
bench_command.add_command(include_app_for_update) bench_command.add_command(include_app_for_update)
bench_command.add_command(pip) bench_command.add_command(pip)
bench_command.add_command(validate_dependencies)
from bench.commands.update import ( from bench.commands.update import (

View File

@ -253,3 +253,20 @@ def pip(ctx, args):
env_py = get_env_cmd("python") env_py = get_env_cmd("python")
os.execv(env_py, (env_py, "-m", "pip") + args) os.execv(env_py, (env_py, "-m", "pip") + args)
@click.command(
"validate-dependencies",
help="Validates that all requirements specified in frappe-dependencies are met curently.",
)
@click.pass_context
def validate_dependencies(ctx):
"Validate all specified frappe-dependencies."
from bench.bench import Bench
from bench.app import App
bench = Bench(".")
for app_name in bench.apps:
app = App(app_name, bench=bench)
app.validate_app_dependencies(throw=True)