Skip to content

Commit

Permalink
Ensure the help provided to the user references the metapackage alias…
Browse files Browse the repository at this point in the history
…, not the constituent package.
  • Loading branch information
freakboy3742 committed Dec 31, 2024
1 parent bed3505 commit 158d8ae
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 18 deletions.
28 changes: 19 additions & 9 deletions src/briefcase/platforms/linux/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -479,11 +479,11 @@ def _system_requirement_tools(self, app: AppConfig):
base_system_packages = [
"python3-dev",
# The consitutent parts of build-essential
"dpkg-dev",
"g++",
"gcc",
"libc6-dev",
"make",
("dpkg-dev", "build-essential"),
("g++", "build-essential"),
("gcc", "build-essential"),
("libc6-dev", "build-essential"),
("make", "build-essential"),
]
system_verify = ["dpkg", "-s"]
system_installer = ["apt", "install"]
Expand Down Expand Up @@ -551,20 +551,30 @@ def verify_system_packages(self, app: AppConfig):

# Run a check for each package listed in the app's system_requires,
# plus the baseline system packages that are required.
missing = []
missing = set()
for package in base_system_packages + getattr(app, "system_requires", []):
# Look for tuples in the package list. If there's a tuple, we're looking
# for the first name in the tuple on the installed list, but we install
# the package using the second name. This is to handle `build-essential`
# style installation aliases. If it's not a tuple, the package name is
# provided by the same name that we're checking for.
if isinstance(package, tuple):
installed, provided_by = package
else:
installed = provided_by = package

try:
self.tools.subprocess.check_output(system_verify + [package])
self.tools.subprocess.check_output(system_verify + [installed])
except subprocess.CalledProcessError:
missing.append(package)
missing.add(provided_by)

# If any required packages are missing, raise an error.
if missing:
raise BriefcaseCommandError(
f"""\
Unable to build {app.app_name} due to missing system dependencies. Run:
sudo {" ".join(system_installer)} {" ".join(missing)}
sudo {" ".join(system_installer)} {" ".join(sorted(missing))}
to install the missing dependencies, and re-run Briefcase.
"""
Expand Down
31 changes: 22 additions & 9 deletions tests/platforms/linux/system/test_mixin__verify_system_packages.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,19 @@ def test_unknown_requirements(build_command, first_app_config, capsys):
def test_missing_packages(build_command, first_app_config, capsys):
"""If there are missing system packages, an error is raised."""
# Mock the system requirement tools; there's a base requirement of
# a packaged called "compiler", verified using "check <pkg>", and
# installed using "system <pkg>"
# packages called "compiler" and "compiler++", plus 3 packages
# provided by an installation alias "alias". These packages are
# verified using "check <pkg>", and installed using "system install_flag <pkg>"
build_command._system_requirement_tools = MagicMock(
return_value=(
["compiler"],
[
"compiler",
"compiler++",
# Three packages provided by the `alias` alias
("aliased-1", "alias"),
("aliased-2", "alias"),
("aliased-3", "alias"),
],
["check"],
["system", "install_flag"],
)
Expand All @@ -116,17 +124,22 @@ def test_missing_packages(build_command, first_app_config, capsys):

# Mock the side effect of checking those requirements.
build_command.tools.subprocess.check_output.side_effect = [
subprocess.CalledProcessError(cmd="check", returncode=1),
"installed",
subprocess.CalledProcessError(cmd="check", returncode=1),
"installed",
subprocess.CalledProcessError(cmd="check", returncode=1), # compiler
"installed", # compiler++
subprocess.CalledProcessError(cmd="check", returncode=1), # aliased-1
"installed", # aliased-2
subprocess.CalledProcessError(cmd="check", returncode=1), # aliased-3
"installed", # first
subprocess.CalledProcessError(cmd="check", returncode=1), # second
"installed", # third
]

# Verify the requirements. This will raise an error, but the error
# message will tell you how to install the system packages.
# message will tell you how to install the system packages. This includes
# using an alias for the install of aliased-1 and aliased-3.
with pytest.raises(
BriefcaseCommandError,
match=r" sudo system install_flag compiler second",
match=r" sudo system install_flag alias compiler second",
):
build_command.verify_system_packages(first_app_config)

Expand Down

0 comments on commit 158d8ae

Please sign in to comment.