Repository: beeware/briefcase

Issue:
`briefcase new` should show which repository and branch it's using
`briefcase create` logs the repository and branch it's using:
```
[tmp] Generating application template...
Assigning tmp an application GUID of 000e29b3-1909-5d18-a892-2515bd585f58
Using app template: https://github.com/beeware/briefcase-windows-app-template.git, branch v0.3.10
Using existing template (sha f0d27880768f39f22c639a9e1abd8c7864072f0a, updated Tue Sep 20 15:53:52 2022)
```

But `briefcase new` doesn't include this information, which makes it inconvenient to verify whether it's doing the right thing:
```
Generating a new application 'tmp'
Using existing template (sha 46a68c2daad0c3b1c53e4b04e105cefa2586c9af, updated Tue Sep 27 14:18:02 2022)
```

Maybe the log line that gives the repository and branch could be moved into the lower-level `generate_template` function. Not only would that fix this issue, it would also make it clear what's happening when briefcase falls back to the `main` branch.

Discussion:

Patch:
diff --git a/changes/931.misc.rst b/changes/931.misc.rst
new file mode 100644
index 00000000..a5614b95
--- /dev/null
+++ b/changes/931.misc.rst
@@ -0,0 +1,1 @@
+When generating a new template using `briefcase new`, the template & branch that created the project is logged.
diff --git a/src/briefcase/commands/new.py b/src/briefcase/commands/new.py
index 65a2f512..c84e7175 100644
--- a/src/briefcase/commands/new.py
+++ b/src/briefcase/commands/new.py
@@ -492,7 +492,13 @@ What GUI toolkit do you want to use for this project?""",
                 f"A directory named '{context['app_name']}' already exists."
             )
 
+        # This is to have briefcase template file
+        # mentioning extra context on which template/branch
+        # the project was generated from.
+        context.update({"template": template, "branch": branch})
+
         try:
+            self.logger.info(f"Using app template: {template}, branch {branch}")
             # Unroll the new app template
             self.generate_template(
                 template=template,


Test patch:
diff --git a/tests/commands/new/test_new_app.py b/tests/commands/new/test_new_app.py
index 64eb4cc6..093dfcbf 100644
--- a/tests/commands/new/test_new_app.py
+++ b/tests/commands/new/test_new_app.py
@@ -41,12 +41,13 @@ def test_new_app(
 ):
     """A new app can be created with the default template."""
     monkeypatch.setattr(briefcase, "__version__", briefcase_version)
-    app_context = {
-        "formal_name": "My Application",
-        "class_name": "MyApplication",
-        "app_name": "myapplication",
-    }
-    new_command.build_app_context = mock.MagicMock(return_value=app_context)
+    new_command.build_app_context = mock.MagicMock(
+        return_value={
+            "formal_name": "My Application",
+            "class_name": "MyApplication",
+            "app_name": "myapplication",
+        }
+    )
     new_command.update_cookiecutter_cache = mock.MagicMock(
         return_value="~/.cookiecutters/briefcase-template"
     )
@@ -68,19 +69,29 @@ def test_new_app(
         no_input=True,
         output_dir=os.fsdecode(tmp_path),
         checkout=expected_branch,
-        extra_context=app_context,
+        extra_context={
+            "formal_name": "My Application",
+            "class_name": "MyApplication",
+            "app_name": "myapplication",
+            # The expected app context
+            # should now also contain the
+            # default template and branch
+            "template": "https://github.com/beeware/briefcase-template",
+            "branch": expected_branch,
+        },
     )
 
 
 def test_new_app_missing_template(monkeypatch, new_command, tmp_path):
     """If a versioned branch doesn't exist, an error is raised."""
     monkeypatch.setattr(briefcase, "__version__", "37.42.7")
-    app_context = {
-        "formal_name": "My Application",
-        "class_name": "MyApplication",
-        "app_name": "myapplication",
-    }
-    new_command.build_app_context = mock.MagicMock(return_value=app_context)
+    new_command.build_app_context = mock.MagicMock(
+        return_value={
+            "formal_name": "My Application",
+            "class_name": "MyApplication",
+            "app_name": "myapplication",
+        }
+    )
     new_command.update_cookiecutter_cache = mock.MagicMock(
         return_value="~/.cookiecutters/briefcase-template"
     )
@@ -110,7 +121,16 @@ def test_new_app_missing_template(monkeypatch, new_command, tmp_path):
         no_input=True,
         output_dir=os.fsdecode(tmp_path),
         checkout="v37.42.7",
-        extra_context=app_context,
+        extra_context={
+            "formal_name": "My Application",
+            "class_name": "MyApplication",
+            "app_name": "myapplication",
+            # The expected app context
+            # should now also contain the
+            # default template and branch
+            "template": "https://github.com/beeware/briefcase-template",
+            "branch": "v37.42.7",
+        },
     )
 
 
@@ -122,12 +142,13 @@ def test_new_app_dev(monkeypatch, new_command, tmp_path, briefcase_version):
     """In a dev version, template will fall back to the 'main' branch if a
     versioned template doesn't exist."""
     monkeypatch.setattr(briefcase, "__version__", briefcase_version)
-    app_context = {
-        "formal_name": "My Application",
-        "class_name": "MyApplication",
-        "app_name": "myapplication",
-    }
-    new_command.build_app_context = mock.MagicMock(return_value=app_context)
+    new_command.build_app_context = mock.MagicMock(
+        return_value={
+            "formal_name": "My Application",
+            "class_name": "MyApplication",
+            "app_name": "myapplication",
+        }
+    )
     new_command.update_cookiecutter_cache = mock.MagicMock(
         return_value="~/.cookiecutters/briefcase-template"
     )
@@ -166,14 +187,32 @@ def test_new_app_dev(monkeypatch, new_command, tmp_path, briefcase_version):
                 no_input=True,
                 output_dir=os.fsdecode(tmp_path),
                 checkout="v37.42.7",
-                extra_context=app_context,
+                extra_context={
+                    "formal_name": "My Application",
+                    "class_name": "MyApplication",
+                    "app_name": "myapplication",
+                    # The expected app context
+                    # should now also contain the
+                    # default template and branch
+                    "template": "https://github.com/beeware/briefcase-template",
+                    "branch": "v37.42.7",
+                },
             ),
             mock.call(
                 "~/.cookiecutters/briefcase-template",
                 no_input=True,
                 output_dir=os.fsdecode(tmp_path),
                 checkout="main",
-                extra_context=app_context,
+                extra_context={
+                    "formal_name": "My Application",
+                    "class_name": "MyApplication",
+                    "app_name": "myapplication",
+                    # The expected app context
+                    # should now also contain the
+                    # default template and branch
+                    "template": "https://github.com/beeware/briefcase-template",
+                    "branch": "v37.42.7",
+                },
             ),
         ]
     )
@@ -183,12 +222,13 @@ def test_new_app_with_template(monkeypatch, new_command, tmp_path):
     """A specific template can be requested."""
     monkeypatch.setattr(briefcase, "__version__", "37.42.7")
 
-    app_context = {
-        "formal_name": "My Application",
-        "class_name": "MyApplication",
-        "app_name": "myapplication",
-    }
-    new_command.build_app_context = mock.MagicMock(return_value=app_context)
+    new_command.build_app_context = mock.MagicMock(
+        return_value={
+            "formal_name": "My Application",
+            "class_name": "MyApplication",
+            "app_name": "myapplication",
+        }
+    )
     new_command.update_cookiecutter_cache = mock.MagicMock(
         return_value="https://example.com/other.git"
     )
@@ -210,7 +250,16 @@ def test_new_app_with_template(monkeypatch, new_command, tmp_path):
         no_input=True,
         output_dir=os.fsdecode(tmp_path),
         checkout="v37.42.7",
-        extra_context=app_context,
+        extra_context={
+            "formal_name": "My Application",
+            "class_name": "MyApplication",
+            "app_name": "myapplication",
+            # The expected app context
+            # should now also contain the
+            # template and branch
+            "template": "https://example.com/other.git",
+            "branch": "v37.42.7",
+        },
     )
 
 
@@ -218,12 +267,13 @@ def test_new_app_with_invalid_template(monkeypatch, new_command, tmp_path):
     """If the custom template is invalid, an error is raised."""
     monkeypatch.setattr(briefcase, "__version__", "37.42.7")
 
-    app_context = {
-        "formal_name": "My Application",
-        "class_name": "MyApplication",
-        "app_name": "myapplication",
-    }
-    new_command.build_app_context = mock.MagicMock(return_value=app_context)
+    new_command.build_app_context = mock.MagicMock(
+        return_value={
+            "formal_name": "My Application",
+            "class_name": "MyApplication",
+            "app_name": "myapplication",
+        }
+    )
     new_command.update_cookiecutter_cache = mock.MagicMock(
         return_value="https://example.com/other.git"
     )
@@ -251,7 +301,16 @@ def test_new_app_with_invalid_template(monkeypatch, new_command, tmp_path):
         no_input=True,
         output_dir=os.fsdecode(tmp_path),
         checkout="v37.42.7",
-        extra_context=app_context,
+        extra_context={
+            "formal_name": "My Application",
+            "class_name": "MyApplication",
+            "app_name": "myapplication",
+            # The expected app context
+            # should now also contain the
+            # template and branch
+            "template": "https://example.com/other.git",
+            "branch": "v37.42.7",
+        },
     )
 
 
@@ -260,12 +319,13 @@ def test_new_app_with_invalid_template_branch(monkeypatch, new_command, tmp_path
     is raised."""
     monkeypatch.setattr(briefcase, "__version__", "37.42.7")
 
-    app_context = {
-        "formal_name": "My Application",
-        "class_name": "MyApplication",
-        "app_name": "myapplication",
-    }
-    new_command.build_app_context = mock.MagicMock(return_value=app_context)
+    new_command.build_app_context = mock.MagicMock(
+        return_value={
+            "formal_name": "My Application",
+            "class_name": "MyApplication",
+            "app_name": "myapplication",
+        }
+    )
     new_command.update_cookiecutter_cache = mock.MagicMock(
         return_value="https://example.com/other.git"
     )
@@ -295,7 +355,16 @@ def test_new_app_with_invalid_template_branch(monkeypatch, new_command, tmp_path
         no_input=True,
         output_dir=os.fsdecode(tmp_path),
         checkout="v37.42.7",
-        extra_context=app_context,
+        extra_context={
+            "formal_name": "My Application",
+            "class_name": "MyApplication",
+            "app_name": "myapplication",
+            # The expected app context
+            # should now also contain the
+            # template and branch
+            "template": "https://example.com/other.git",
+            "branch": "v37.42.7",
+        },
     )