Skip to content

Commit

Permalink
Prototype implementation for template requirements
Browse files Browse the repository at this point in the history
  • Loading branch information
rmartin16 committed May 20, 2023
1 parent 97f7395 commit 34e8ead
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 7 deletions.
30 changes: 23 additions & 7 deletions src/briefcase/commands/base.py
@@ -1,4 +1,5 @@
import argparse
import contextlib
import importlib
import inspect
import os
Expand Down Expand Up @@ -105,6 +106,7 @@ class BaseCommand(ABC):
cmd_line = "briefcase {command} {platform} {output_format}"
supported_host_os = {"Darwin", "Linux", "Windows"}
supported_host_os_reason = f"This command is not supported on {platform.system()}."
requires = []
GLOBAL_CONFIG_CLASS = GlobalConfig
APP_CONFIG_CLASS = AppConfig
allows_passthrough = False
Expand Down Expand Up @@ -326,19 +328,33 @@ def binary_path(self, app):
"""
...

def _load_path_index(self, app: BaseConfig):
"""Load the path index from the index file provided by the app template.
:param app: The config object for the app
:return: The contents of the application path index.
"""
@contextlib.contextmanager
def _open_briefcase_toml(self, app: BaseConfig):
try:
with (self.bundle_path(app) / "briefcase.toml").open("rb") as f:
self._path_index[app] = tomllib.load(f)["paths"]
yield f
except OSError as e:
raise BriefcaseCommandError(
f"Unable to find '{self.bundle_path(app) / 'briefcase.toml'}'"
) from e

def build_requirements(self, app: BaseConfig) -> list[str]:
"""The list of requirements to build an app from ``briefcase.toml``."""
with self._open_briefcase_toml(app) as f:
try:
return tomllib.load(f)["briefcase"]["requires"]
except KeyError:
return []

def _load_path_index(self, app: BaseConfig):
"""Load the path index from the index file provided by the app template.
:param app: The config object for the app
:return: The contents of the application path index.
"""
with self._open_briefcase_toml(app) as f:
self._path_index[app] = tomllib.load(f)["paths"]

return self._path_index[app]

def support_path(self, app: BaseConfig):
Expand Down
38 changes: 38 additions & 0 deletions src/briefcase/commands/build.py
@@ -1,5 +1,8 @@
from typing import Optional

from packaging.requirements import Requirement
from packaging.version import Version

from briefcase.config import BaseConfig
from briefcase.exceptions import BriefcaseCommandError

Expand All @@ -21,6 +24,40 @@ def build_app(self, app: BaseConfig, **options):
"""
# Default implementation; nothing to build.

def verify_build_requirements(self, app: BaseConfig):
"""Verify the template satisfies the Command's requirements."""
self.logger.info("Verifying template compatability...", prefix=app.app_name)
with self.input.wait_bar("Verifying build requirements..."):
template_requires = [
Requirement(r) for r in self.build_requirements(app=app)
]
for req in [Requirement(r) for r in self.requires]:
template_reqs = [r for r in template_requires if r.name == req.name]
if len(template_reqs) > 1:
raise BriefcaseCommandError(
f"The requirement {req.name!r} can only be listed once in the template."
)
if len(template_reqs) < 1:
raise BriefcaseCommandError(
f"The requirement {req.name!r} is not provided by the template."
)

template_req = template_reqs[0]
if not str(template_req.specifier).startswith("=="):
raise BriefcaseCommandError(
f"The requirement {template_req!r} is not exact; for example, 'gradle==8.0.1'"
)

if not req.specifier.contains(Version(str(template_req.specifier)[2:])):
raise BriefcaseCommandError(
f"""
The template is not compatible with this version of Briefcase.
Briefcase requires {req!r} from the template.
The template is providing {template_req!r}.
"""
)

def _build_app(
self,
app: BaseConfig,
Expand Down Expand Up @@ -68,6 +105,7 @@ def _build_app(
else:
state = None

self.verify_build_requirements(app)
self.verify_app_tools(app)

state = self.build_app(app, test_mode=test_mode, **full_options(state, options))
Expand Down
1 change: 1 addition & 0 deletions src/briefcase/platforms/android/gradle.py
Expand Up @@ -62,6 +62,7 @@ def android_log_clean_filter(line):
class GradleMixin:
output_format = "gradle"
platform = "android"
requires = ["gradle>=8.0", "android_gradle_plugin>=8.0.1"]

@property
def packaging_formats(self):
Expand Down

0 comments on commit 34e8ead

Please sign in to comment.