beeware / briefcase

Tools to support converting a Python project into a standalone native application.
https://briefcase.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
2.48k stars 353 forks source link

Validate app document types before passing to cookiecutter #1770

Open rmartin16 opened 2 months ago

rmartin16 commented 2 months ago

Describe the bug

When a [tool.briefcase.app.<app name>.document_type.<extension>] table is configured incorrectly, the error reporting is a little opaque.

❯ briefcase create -vv

Application 'helloworld' already exists; overwrite [y/N]? y

[helloworld] Removing old application bundle...

[helloworld] Generating application template...
Using app template: https://github.com/beeware/briefcase-macOS-app-template.git, branch v0.3.18
Template branch None not found; falling back to development template
Using existing template (sha 17b3f5fa170e7d3490e399350502633994d4316b, updated Thu May  2 01:58:29 2024)

Log saved to /Users/user/tmp/beeware/helloworld/logs/briefcase.2024_05_02-19_11_59.create.log

Traceback (most recent call last):
  File "/Users/user/.pyenv/versions/briefcase-3.12/lib/python3.12/site-packages/git/util.py", line 1209, in __getitem__
    return getattr(self, index)
           ^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/.pyenv/versions/briefcase-3.12/lib/python3.12/site-packages/git/util.py", line 1198, in __getattr__
    return list.__getattribute__(self, attr)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'IterableList' object has no attribute 'origin/v0.3.18'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/user/github/beeware/briefcase/src/briefcase/commands/base.py", line 919, in update_cookiecutter_cache
    head = remote.refs[branch]
           ~~~~~~~~~~~^^^^^^^^
  File "/Users/user/.pyenv/versions/briefcase-3.12/lib/python3.12/site-packages/git/util.py", line 1211, in __getitem__
    raise IndexError("No item found with id %r" % (self._prefix + index)) from e
IndexError: No item found with id 'origin/v0.3.18'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/user/github/beeware/briefcase/src/briefcase/commands/base.py", line 1017, in generate_template
    self._generate_template(
  File "/Users/user/github/beeware/briefcase/src/briefcase/commands/base.py", line 958, in _generate_template
    cached_template = self.update_cookiecutter_cache(
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/github/beeware/briefcase/src/briefcase/commands/base.py", line 928, in update_cookiecutter_cache
    raise TemplateUnsupportedVersion(branch) from e
briefcase.exceptions.TemplateUnsupportedVersion: Could not find a template branch for Briefcase v0.3.18.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/user/.pyenv/versions/briefcase-3.12/lib/python3.12/site-packages/cookiecutter/generate.py", line 409, in generate_files
    generate_file(
  File "/Users/user/.pyenv/versions/briefcase-3.12/lib/python3.12/site-packages/cookiecutter/generate.py", line 209, in generate_file
    rendered_file = tmpl.render(**context)
                    ^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/.pyenv/versions/briefcase-3.12/lib/python3.12/site-packages/jinja2/environment.py", line 1301, in render
    self.environment.handle_exception()
  File "/Users/user/.pyenv/versions/briefcase-3.12/lib/python3.12/site-packages/jinja2/environment.py", line 936, in handle_exception
    raise rewrite_traceback_stack(source=source)
  File "{{ cookiecutter.formal_name }}.app/Contents/Info.plist", line 75, in top-level template code
jinja2.exceptions.UndefinedError: 'dict object' has no attribute 'extension'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/user/.pyenv/versions/briefcase-3.12/bin/briefcase", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/Users/user/github/beeware/briefcase/src/briefcase/__main__.py", line 29, in main
    command(**options)
  File "/Users/user/github/beeware/briefcase/src/briefcase/commands/create.py", line 818, in __call__
    state = self.create_app(app, **full_options(state, options))
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/github/beeware/briefcase/src/briefcase/commands/create.py", line 765, in create_app
    self.generate_app_template(app=app)
  File "/Users/user/github/beeware/briefcase/src/briefcase/commands/create.py", line 237, in generate_app_template
    self.generate_template(
  File "/Users/user/github/beeware/briefcase/src/briefcase/commands/base.py", line 1035, in generate_template
    self._generate_template(
  File "/Users/user/github/beeware/briefcase/src/briefcase/commands/base.py", line 967, in _generate_template
    self.tools.cookiecutter(
  File "/Users/user/.pyenv/versions/briefcase-3.12/lib/python3.12/site-packages/cookiecutter/main.py", line 182, in cookiecutter
    result = generate_files(
             ^^^^^^^^^^^^^^^
  File "/Users/user/.pyenv/versions/briefcase-3.12/lib/python3.12/site-packages/cookiecutter/generate.py", line 416, in generate_files
    raise UndefinedVariableInTemplate(msg, err, context) from err
cookiecutter.exceptions.UndefinedVariableInTemplate: Unable to create file '{{ cookiecutter.formal_name }}.app/Contents/Info.plist'. Error message: 'dict object' has no attribute 'extension'. Context: OrderedDict({'cookiecutter': OrderedDict({'format': 'app', 'formal_name': 'Hello World', 'app_name': 'helloworld', 'module_name': 'helloworld', 'info': {}, 'entitlements': {'com.apple.security.cs.allow-unsigned-executable-memory': True, 'com.apple.security.cs.disable-library-validation': True}, 'document_types': {'png': {'icon': 'asdf', 'description': 'description', 'url': 'zxcv://xcvb'}}, 'version': '0.0.1', 'build': '1', 'bundle': 'com.example', 'python_version': '3.12.1', '_extensions': ['briefcase.integrations.cookiecutter.PythonVersionExtension', 'briefcase.integrations.cookiecutter.PListExtension'], '_template': '/Users/user/.cookiecutters/briefcase-macOS-app-template', '_output_dir': '/Users/user/tmp/beeware/helloworld/build/helloworld/macos', '_repo_dir': '/Users/user/.cookiecutters/briefcase-macOS-app-template', '_checkout': 'main'}), '_cookiecutter': {'format': 'app', 'formal_name': 'Hello World', 'app_name': 'helloworld', 'module_name': 'helloworld', 'info': {}, 'entitlements': {'com.apple.security.cs.allow-unsigned-executable-memory': True, 'com.apple.security.cs.disable-library-validation': True}, 'document_types': {'png': {'icon': 'asdf', 'description': 'description', 'url': 'zxcv://xcvb'}}, 'version': '0.0.1', 'build': '1', 'bundle': 'com.example', 'python_version': '3.12.1'}})

Steps to reproduce

Configure a [tool.briefcase.app.<app name>.document_type.<extension>] table without the extension field....or any of the other fields and run briefcase create (macOS only currently).

Expected behavior

Users are plainly informed of the document type misconfiguration.

Screenshots

No response

Environment

Logs

briefcase.2024_05_02-19_16_39.create.log

Additional context

No response

freakboy3742 commented 2 months ago

See also #1706 for the implementation changes need to make this work on Windows MSI; if there's anything buggy that needs to be addressed here, adding the feature to Windows would be a good opportunity to fix it.

oakal510 commented 1 month ago

I'm looking into this at PyCon '24.

oakal510 commented 1 month ago

I was able to reproduce this error and to find where to add a better error message can be triggered, but still trying to improve the message further.