Skip to content

Commit

Permalink
Refactor macOS Run to share implementation between app and Xcode
Browse files Browse the repository at this point in the history
  • Loading branch information
freakboy3742 committed Jun 5, 2021
1 parent b60e1f1 commit c60f2a0
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 127 deletions.
63 changes: 62 additions & 1 deletion src/briefcase/platforms/macOS/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,69 @@ class macOSMixin:
platform = 'macOS'


class macOSPackageMixin:
class macOSRunMixin:
def run_app(self, app: BaseConfig, **kwargs):
"""
Start the application.
:param app: The config object for the app
:param base_path: The path to the project directory.
"""
print()
print('[{app.app_name}] Starting app...'.format(
app=app
))
try:
print()
self.subprocess.run(
[
'open',
'-n', # Force a new app to be launched
str(self.binary_path(app)),
],
check=True,
)
except subprocess.CalledProcessError:
print()
raise BriefcaseCommandError(
"Unable to start app {app.app_name}.".format(app=app)
)

# Find the PID of the new instance using pgrep
try:
pid = self.subprocess.check_output(
["pgrep", "-n", app.formal_name],
universal_newlines=True,
).strip()
except subprocess.CalledProcessError:
print()
raise BriefcaseCommandError(
"Unable to find PID for app {app.app_name}.".format(app=app)
)

# Start streaming logs for the app.
try:
print()
print("[{app.app_name}] Following system log output (type CTRL-C to stop log)...".format(app=app))
print("=" * 75)
self.subprocess.run(
[
"log",
"stream",
"--process", pid,
"--style", "compact",
"--type", "log",
],
check=True,
)
except subprocess.CalledProcessError:
print()
raise BriefcaseCommandError(
"Unable to start log stream for app {app.app_name} (pid {pid}).".format(app=app, pid=pid)
)


class macOSPackageMixin:
@property
def packaging_formats(self):
return ['app', 'dmg']
Expand Down
66 changes: 2 additions & 64 deletions src/briefcase/platforms/macOS/app.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import tempfile
import subprocess
from pathlib import Path

from briefcase.commands import (
Expand All @@ -11,8 +10,7 @@
UpdateCommand
)
from briefcase.config import BaseConfig
from briefcase.exceptions import BriefcaseCommandError
from briefcase.platforms.macOS import macOSMixin, macOSPackageMixin
from briefcase.platforms.macOS import macOSMixin, macOSRunMixin, macOSPackageMixin


class macOSAppMixin(macOSMixin):
Expand Down Expand Up @@ -65,69 +63,9 @@ class macOSAppBuildCommand(macOSAppMixin, BuildCommand):
description = "Build a macOS app."


class macOSAppRunCommand(macOSAppMixin, RunCommand):
class macOSAppRunCommand(macOSRunMixin, macOSAppMixin, RunCommand):
description = "Run a macOS app."

def run_app(self, app: BaseConfig, **kwargs):
"""
Start the application.
:param app: The config object for the app
:param base_path: The path to the project directory.
"""
print()
print('[{app.app_name}] Starting app...'.format(
app=app
))
try:
print()
self.subprocess.run(
[
'open',
'-n', # Force a new app to be launched
str(self.binary_path(app)),
],
check=True,
)
except subprocess.CalledProcessError:
print()
raise BriefcaseCommandError(
"Unable to start app {app.app_name}.".format(app=app)
)

# Find the PID of the new instance using pgrep
try:
pid = self.subprocess.check_output(
["pgrep", "-n", app.formal_name],
universal_newlines=True,
).strip()
except subprocess.CalledProcessError:
print()
raise BriefcaseCommandError(
"Unable to find PID for app {app.app_name}.".format(app=app)
)

# Start streaming logs for the app.
try:
print()
print("[{app.app_name}] Following system log output (type CTRL-C to stop log)...".format(app=app))
print("=" * 75)
self.subprocess.run(
[
"log",
"stream",
"--process", pid,
"--style", "compact",
"--type", "log",
],
check=True,
)
except subprocess.CalledProcessError:
print()
raise BriefcaseCommandError(
"Unable to start log stream for app {app.app_name} (pid {pid}).".format(app=app, pid=pid)
)


class macOSAppPackageCommand(macOSPackageMixin, macOSAppMixin, PackageCommand):
description = "Package a macOS app for distribution."
Expand Down
24 changes: 2 additions & 22 deletions src/briefcase/platforms/macOS/xcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
)
from briefcase.config import BaseConfig
from briefcase.exceptions import BriefcaseCommandError
from briefcase.platforms.macOS import macOSMixin, macOSPackageMixin
from briefcase.platforms.macOS import macOSMixin, macOSRunMixin, macOSPackageMixin
from briefcase.integrations.xcode import verify_xcode_install


Expand Down Expand Up @@ -108,29 +108,9 @@ def build_app(self, app: BaseConfig, **kwargs):
)


class macOSXcodeRunCommand(macOSXcodeMixin, RunCommand):
class macOSXcodeRunCommand(macOSRunMixin, macOSXcodeMixin, RunCommand):
description = "Run a macOS app."

def run_app(self, app: BaseConfig, **kwargs):
"""
Start the application.
:param app: The config object for the app
:param base_path: The path to the project directory.
"""
print()
print('[{app.app_name}] Starting app...'.format(
app=app
))
try:
print()
self.subprocess.run(['open', str(self.binary_path(app))], check=True)
except subprocess.CalledProcessError:
print()
raise BriefcaseCommandError(
"Unable to start app {app.app_name}.".format(app=app)
)


class macOSXcodePackageCommand(macOSPackageMixin, macOSXcodeMixin, PackageCommand):
description = "Package a macOS app for distribution."
Expand Down
2 changes: 1 addition & 1 deletion tests/platforms/macOS/xcode/test_package.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
# skip since packing uses the same code as app command
# skip since packaging uses the same code as app command
40 changes: 1 addition & 39 deletions tests/platforms/macOS/xcode/test_run.py
Original file line number Diff line number Diff line change
@@ -1,39 +1 @@
import subprocess
from unittest import mock

import pytest

from briefcase.exceptions import BriefcaseCommandError
from briefcase.platforms.macOS.xcode import macOSXcodeRunCommand


def test_run_app(first_app_config, tmp_path):
"A macOS App can be started"
command = macOSXcodeRunCommand(base_path=tmp_path)
command.subprocess = mock.MagicMock()

command.run_app(first_app_config)

command.subprocess.run.assert_called_with(
['open', str(command.binary_path(first_app_config))],
check=True
)


def test_run_app_failed(first_app_config, tmp_path):
"If there's a problem started the app, an exception is raised"
command = macOSXcodeRunCommand(base_path=tmp_path)
command.subprocess = mock.MagicMock()
command.subprocess.run.side_effect = subprocess.CalledProcessError(
cmd=['open', str(command.binary_path(first_app_config))],
returncode=1
)

with pytest.raises(BriefcaseCommandError):
command.run_app(first_app_config)

# The run command was still invoked, though
command.subprocess.run.assert_called_with(
['open', str(command.binary_path(first_app_config))],
check=True
)
# skip since run uses the same code as app command

0 comments on commit c60f2a0

Please sign in to comment.