Repository: beeware/briefcase
Pull request #878 (2022-09-27 20:54:49)

PackageCommand: run `verify_app_tools()` after other pre-requisite commands
Got this wrong even after spending too much time thinking about it....or because I spent too much time.

## Changes
The call to `verify_app_tools()` for `PackageCommand` now happens after any per-requisite commands are run.

## PR Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
- [x] All new features have been tested
- [x] All new features have been documented
- [x] I have read the **CONTRIBUTING.md** file
- [x] I will abide by the code of conduct



Patch:
diff --git a/changes/878.misc.rst b/changes/878.misc.rst
new file mode 100644
index 00000000..b3a2e2a5
--- /dev/null
+++ b/changes/878.misc.rst
@@ -0,0 +1,1 @@
+When packaging AppImages, the Docker image will now be built if necessary instead of logging an error.
diff --git a/src/briefcase/commands/package.py b/src/briefcase/commands/package.py
index 15db0fe6..641b06d5 100644
--- a/src/briefcase/commands/package.py
+++ b/src/briefcase/commands/package.py
@@ -48,6 +48,8 @@ class PackageCommand(BaseCommand):
         else:
             state = None
 
+        self.verify_app_tools(app)
+
         state = self.package_app(
             app, packaging_format=packaging_format, **full_options(state, options)
         )
@@ -103,7 +105,6 @@ class PackageCommand(BaseCommand):
         else:
             state = None
             for app_name, app in sorted(self.apps.items()):
-                self.verify_app_tools(app)
                 state = self._package_app(
                     app, update=update, **full_options(state, options)
                 )
diff --git a/src/briefcase/commands/publish.py b/src/briefcase/commands/publish.py
index b00c2d42..16469627 100644
--- a/src/briefcase/commands/publish.py
+++ b/src/briefcase/commands/publish.py
@@ -35,6 +35,22 @@ class PublishCommand(BaseCommand):
         """
         self.logger.info(f"TODO: Publish {app.app_name} to {channel}")
 
+    def _publish_app(self, app: BaseConfig, channel: str, **options):
+        """Internal method to publish a single app. Ensures the app exists, and
+        has been packaged before attempting to issue the actual publish
+        command.
+
+        :param app: The application to publish
+        :param channel: The publication channel to use
+        """
+        # TODO: Verify the app has been packaged
+        state = None
+        self.verify_app_tools(app)
+
+        state = self.publish_app(app, channel=channel, **full_options(state, options))
+
+        return state
+
     def __call__(self, channel=None, **options):
         # Confirm all required tools are available
         self.verify_tools()
@@ -51,8 +67,7 @@ class PublishCommand(BaseCommand):
         # Then publish them all to the selected channel.
         state = None
         for app_name, app in sorted(self.apps.items()):
-            self.verify_app_tools(app)
-            state = self.publish_app(
+            state = self._publish_app(
                 app, channel=channel, **full_options(state, options)
             )
 


Test patch:
diff --git a/tests/commands/package/test_call.py b/tests/commands/package/test_call.py
index 9b1b6ab5..83a74200 100644
--- a/tests/commands/package/test_call.py
+++ b/tests/commands/package/test_call.py
@@ -384,8 +384,6 @@ def test_update_package_one_app(package_command, first_app):
     assert package_command.actions == [
         # Tools are verified
         ("verify",),
-        # App tools are verified for app
-        ("verify-app-tools", "first"),
         # Update (and then build) the first app
         (
             "update",
@@ -406,6 +404,8 @@ def test_update_package_one_app(package_command, first_app):
                 "update_state": "first",
             },
         ),
+        # App tools are verified for app
+        ("verify-app-tools", "first"),
         # Package the first app
         (
             "package",
@@ -440,8 +440,6 @@ def test_update_package_two_app(package_command, first_app, second_app):
     assert package_command.actions == [
         # Tools are verified
         ("verify",),
-        # App tools are verified for first app
-        ("verify-app-tools", "first"),
         # Update (and then build) the first app
         (
             "update",
@@ -462,6 +460,8 @@ def test_update_package_two_app(package_command, first_app, second_app):
                 "update_state": "first",
             },
         ),
+        # App tools are verified for first app
+        ("verify-app-tools", "first"),
         # Package the first app
         (
             "package",
@@ -475,8 +475,6 @@ def test_update_package_two_app(package_command, first_app, second_app):
                 "build_state": "first",
             },
         ),
-        # App tools are verified for second app
-        ("verify-app-tools", "second"),
         # Update (and then build) the second app
         (
             "update",
@@ -504,6 +502,8 @@ def test_update_package_two_app(package_command, first_app, second_app):
                 "package_state": "first",
             },
         ),
+        # App tools are verified for second app
+        ("verify-app-tools", "second"),
         # package the second app
         (
             "package",