Skip to content

Commit

Permalink
Support verbose logging for third-party tools
Browse files Browse the repository at this point in the history
  • Loading branch information
rmartin16 committed Jul 28, 2023
1 parent 5483fd9 commit b4916a4
Show file tree
Hide file tree
Showing 22 changed files with 229 additions and 90 deletions.
1 change: 1 addition & 0 deletions changes/1384.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Using the ``-vv`` switch, verbose logging can now be enabled for the third-party tools, such as Gradle, linuxdeploy, etc.
5 changes: 5 additions & 0 deletions src/briefcase/console.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,11 @@ def error(self, message="", *, prefix="", markup=False):
"""Log message at error level; always included in output."""
self._log(prefix=prefix, message=message, markup=markup, style="bold red")

@property
def is_tool_debug(self):
"""Returns ``True`` if tools' debug/verbose output should be enabled."""
return self.verbosity >= 3

def capture_stacktrace(self, label="Main thread"):
"""Preserve Rich stacktrace from exception while in except block.
Expand Down
26 changes: 16 additions & 10 deletions src/briefcase/integrations/flatpak.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,8 @@ def verify_repo(self, repo_alias: str, url: str):
"--if-not-exists",
repo_alias,
url,
],
]
+ (["--verbose"] if self.tools.logger.is_tool_debug else []),
check=True,
)
except subprocess.CalledProcessError as e:
Expand Down Expand Up @@ -186,7 +187,8 @@ def verify_runtime(
repo_alias,
f"{runtime}/{self.tools.host_arch}/{runtime_version}",
f"{sdk}/{self.tools.host_arch}/{runtime_version}",
],
]
+ (["--verbose"] if self.tools.logger.is_tool_debug else []),
check=True,
# flatpak install uses many animations that cannot be disabled
stream_output=False,
Expand Down Expand Up @@ -222,7 +224,8 @@ def build(self, bundle_identifier: str, app_name: str, path: Path):
"--user",
"build",
"manifest.yml",
],
]
+ (["--verbose"] if self.tools.logger.is_tool_debug else []),
check=True,
cwd=path,
)
Expand Down Expand Up @@ -269,13 +272,15 @@ def run(
else:
kwargs = {}

flatpak_run_cmd = ["flatpak", "run", bundle_identifier]
flatpak_run_cmd.extend([] if args is None else args)

if self.tools.logger.is_tool_debug:
# Must come before bundle identifier; otherwise, it's passed as an arg to app
flatpak_run_cmd.insert(2, "--verbose")

return self.tools.subprocess.Popen(
[
"flatpak",
"run",
bundle_identifier,
]
+ ([] if args is None else args),
flatpak_run_cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
bufsize=1,
Expand Down Expand Up @@ -319,7 +324,8 @@ def bundle(
output_path,
bundle_identifier,
version,
],
]
+ (["--verbose"] if self.tools.logger.is_tool_debug else []),
check=True,
cwd=build_path,
)
Expand Down
50 changes: 23 additions & 27 deletions src/briefcase/platforms/android/gradle.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from __future__ import annotations

import datetime
import re
import subprocess
import time
from pathlib import Path
from typing import List

from briefcase.commands import (
BuildCommand,
Expand All @@ -17,6 +18,7 @@
from briefcase.config import BaseConfig, parsed_version
from briefcase.exceptions import BriefcaseCommandError
from briefcase.integrations.android_sdk import AndroidSDK
from briefcase.integrations.subprocess import SubprocessArgT


def safe_formal_name(name):
Expand Down Expand Up @@ -88,17 +90,14 @@ def binary_path(self, app):
)

def distribution_path(self, app):
packaging_format_extension = {
extension = {
"aab": "aab",
"apk": "apk",
"debug-apk": "apk",
}
return (
self.dist_path
/ f"{app.formal_name}-{app.version}.{packaging_format_extension[app.packaging_format]}"
)
"debug-apk": "debug.apk",
}[app.packaging_format]
return self.dist_path / f"{app.formal_name}-{app.version}.{extension}"

def run_gradle(self, app, args):
def run_gradle(self, app, args: list[SubprocessArgT]):
# Gradle may install the emulator via the dependency chain build-tools > tools >
# emulator. (The `tools` package only shows up in sdkmanager if you pass
# `--include_obsolete`.) However, the old sdkmanager built into Android Gradle
Expand All @@ -115,7 +114,13 @@ def run_gradle(self, app, args):
# Windows needs the full path to `gradlew`; macOS & Linux can find it
# via `./gradlew`. For simplicity of implementation, we always provide
# the full path.
[self.bundle_path(app) / gradlew] + args + ["--console", "plain"],
[
self.bundle_path(app) / gradlew,
"--console",
"plain",
]
+ (["--debug"] if self.tools.logger.is_tool_debug else [])
+ args,
env=self.tools.android_sdk.env,
# Set working directory so gradle can use the app bundle path as its
# project root, i.e., to avoid 'Task assembleDebug not found'.
Expand Down Expand Up @@ -250,7 +255,7 @@ def run_app(
self,
app: BaseConfig,
test_mode: bool,
passthrough: List[str],
passthrough: list[str],
device_or_avd=None,
extra_emulator_args=None,
shutdown_on_exit=False,
Expand Down Expand Up @@ -379,27 +384,18 @@ def package_app(self, app: BaseConfig, **kwargs):
prefix=app.app_name,
)
with self.input.wait_bar("Bundling..."):
build_type, build_artefact_path = {
"aab": ("bundleRelease", "bundle/release/app-release.aab"),
"apk": ("assembleRelease", "apk/release/app-release-unsigned.apk"),
"debug-apk": ("assembleDebug", "apk/debug/app-debug.apk"),
}[app.packaging_format]

try:
self.run_gradle(
app,
[
{
"aab": "bundleRelease",
"apk": "assembleRelease",
"debug-apk": "assembleDebug",
}[app.packaging_format]
],
)
self.run_gradle(app, [build_type])
except subprocess.CalledProcessError as e:
raise BriefcaseCommandError("Error while building project.") from e

# Move artefact to final location.
build_artefact_path = {
"aab": Path("bundle") / "release" / "app-release.aab",
"apk": Path("apk") / "release" / "app-release-unsigned.apk",
"debug-apk": Path("apk") / "debug" / "app-debug.apk",
}[app.packaging_format]

self.tools.shutil.move(
self.bundle_path(app) / "app" / "build" / "outputs" / build_artefact_path,
self.distribution_path(app),
Expand Down
2 changes: 1 addition & 1 deletion src/briefcase/platforms/iOS/xcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ def build_app(self, app: BaseConfig, test_mode: bool = False, **kwargs):
self.tools.host_arch,
"-sdk",
"iphonesimulator",
"-quiet",
"-verbose" if self.tools.logger.is_tool_debug else "-quiet",
],
check=True,
)
Expand Down
5 changes: 5 additions & 0 deletions src/briefcase/platforms/linux/appimage.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,10 @@ def build_app(self, app: AppConfig, **kwargs): # pragma: no-cover-if-is-windows
# This can be used by some linuxdeploy plugins.
env["ARCH"] = self.tools.host_arch

# Enable debug logging for linuxdeploy GTK and Qt plugins
if self.logger.is_tool_debug:
env["DEBUG"] = "1"

# Find all the .so files in app and app_packages,
# so they can be passed in to linuxdeploy to have their
# requirements added to the AppImage. Looks for any .so file
Expand Down Expand Up @@ -302,6 +306,7 @@ def build_app(self, app: AppConfig, **kwargs): # pragma: no-cover-if-is-windows
),
"--output",
"appimage",
"-v0" if self.logger.is_tool_debug else "-v1",
]
+ additional_args,
env=env,
Expand Down
2 changes: 1 addition & 1 deletion src/briefcase/platforms/macOS/xcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def build_app(self, app: BaseConfig, **kwargs):
"xcodebuild",
"-project",
self.project_path(app),
"-quiet",
"-verbose" if self.tools.logger.is_tool_debug else "-quiet",
"-configuration",
"Release",
"build",
Expand Down
3 changes: 3 additions & 0 deletions src/briefcase/platforms/windows/visualstudio.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ def build_app(self, app: BaseConfig, **kwargs):
"-property:RestorePackagesConfig=true",
f"-target:{app.formal_name}",
"-property:Configuration=Release",
"-verbosity:detailed"
if self.logger.is_tool_debug
else "-verbosity:normal",
],
check=True,
cwd=self.bundle_path(app),
Expand Down
8 changes: 8 additions & 0 deletions tests/console/test_Log.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ def command(mock_now, tmp_path) -> DevCommand:
return command


@pytest.mark.parametrize(
"verbosity, enabled", [(1, False), (2, False), (3, True), (4, True)]
)
def test_is_tool_debug(verbosity, enabled):
"""Verbose tool logging is enabled at =>3 verbosity."""
assert Log(verbosity=verbosity).is_tool_debug is enabled


def test_capture_stacktrace():
"""capture_stacktrace sets Log.stacktrace."""
logger = Log()
Expand Down
10 changes: 8 additions & 2 deletions tests/integrations/flatpak/test_Flatpak__build.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@
from briefcase.exceptions import BriefcaseCommandError


def test_build(flatpak, tmp_path):
@pytest.mark.parametrize("tool_debug_mode", (True, False))
def test_build(flatpak, tool_debug_mode, tmp_path):
"""A Flatpak project can be built."""
# Enable verbose tool logging
if tool_debug_mode:
flatpak.tools.logger.verbosity = 3

flatpak.build(
bundle_identifier="com.example.my-app",
app_name="my-app",
Expand All @@ -24,7 +29,8 @@ def test_build(flatpak, tmp_path):
"--user",
"build",
"manifest.yml",
],
]
+ (["--verbose"] if tool_debug_mode else []),
check=True,
cwd=tmp_path,
)
Expand Down
9 changes: 7 additions & 2 deletions tests/integrations/flatpak/test_Flatpak__bundle.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@
from briefcase.exceptions import BriefcaseCommandError


def test_bundle(flatpak, tmp_path):
@pytest.mark.parametrize("tool_debug_mode", (True, False))
def test_bundle(flatpak, tool_debug_mode, tmp_path):
"""A Flatpak project can be bundled."""
# Enable verbose tool logging
if tool_debug_mode:
flatpak.tools.logger.verbosity = 3

flatpak.bundle(
repo_url="https://example.com/flatpak",
Expand All @@ -28,7 +32,8 @@ def test_bundle(flatpak, tmp_path):
tmp_path / "output" / "MyApp.flatpak",
"com.example.my-app",
"1.2.3",
],
]
+ (["--verbose"] if tool_debug_mode else []),
check=True,
cwd=tmp_path / "build",
)
Expand Down
29 changes: 21 additions & 8 deletions tests/integrations/flatpak/test_Flatpak__run.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import subprocess
from unittest import mock

import pytest

def test_run(flatpak):

@pytest.mark.parametrize("tool_debug_mode", (True, False))
def test_run(flatpak, tool_debug_mode):
"""A Flatpak project can be executed."""
# Enable verbose tool logging
if tool_debug_mode:
flatpak.tools.logger.verbosity = 3

# Set up the log streamer to return a known stream
log_popen = mock.MagicMock()
flatpak.tools.subprocess.Popen.return_value = log_popen
Expand All @@ -16,8 +23,9 @@ def test_run(flatpak):
[
"flatpak",
"run",
"com.example.my-app",
],
]
+ (["--verbose"] if tool_debug_mode else [])
+ ["com.example.my-app"],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
bufsize=1,
Expand All @@ -27,8 +35,13 @@ def test_run(flatpak):
assert result == log_popen


def test_run_with_args(flatpak):
@pytest.mark.parametrize("tool_debug_mode", (True, False))
def test_run_with_args(flatpak, tool_debug_mode):
"""A Flatpak project can be executed with additional arguments."""
# Enable verbose tool logging
if tool_debug_mode:
flatpak.tools.logger.verbosity = 3

# Set up the log streamer to return a known stream
log_popen = mock.MagicMock()
flatpak.tools.subprocess.Popen.return_value = log_popen
Expand All @@ -44,10 +57,10 @@ def test_run_with_args(flatpak):
[
"flatpak",
"run",
"com.example.my-app",
"foo",
"bar",
],
]
+ (["--verbose"] if tool_debug_mode else [])
+ ["com.example.my-app"]
+ ["foo", "bar"],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
bufsize=1,
Expand Down
9 changes: 7 additions & 2 deletions tests/integrations/flatpak/test_Flatpak__verify_repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@
from briefcase.exceptions import BriefcaseCommandError


def test_verify_repo(flatpak):
@pytest.mark.parametrize("tool_debug_mode", (True, False))
def test_verify_repo(flatpak, tool_debug_mode):
"""A Flatpak repo can be verified."""
# Enable verbose tool logging
if tool_debug_mode:
flatpak.tools.logger.verbosity = 3

flatpak.verify_repo(
repo_alias="test-alias",
Expand All @@ -22,7 +26,8 @@ def test_verify_repo(flatpak):
"--if-not-exists",
"test-alias",
"https://example.com/flatpak",
],
]
+ (["--verbose"] if tool_debug_mode else []),
check=True,
)

Expand Down
9 changes: 7 additions & 2 deletions tests/integrations/flatpak/test_Flatpak__verify_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@
from briefcase.exceptions import BriefcaseCommandError


def test_verify_runtime(flatpak):
@pytest.mark.parametrize("tool_debug_mode", (True, False))
def test_verify_runtime(flatpak, tool_debug_mode):
"""A Flatpak runtime and SDK can be verified."""
# Enable verbose tool logging
if tool_debug_mode:
flatpak.tools.logger.verbosity = 3

flatpak.verify_runtime(
repo_alias="test-alias",
Expand All @@ -25,7 +29,8 @@ def test_verify_runtime(flatpak):
"test-alias",
"org.beeware.flatpak.Platform/gothic/37.42",
"org.beeware.flatpak.SDK/gothic/37.42",
],
]
+ (["--verbose"] if tool_debug_mode else []),
check=True,
stream_output=False,
)
Expand Down
Loading

0 comments on commit b4916a4

Please sign in to comment.