Conversation
freakboy3742
left a comment
There was a problem hiding this comment.
The mechanics of this look good; a couple of minor comments, and obviously the testing issues still need to be addressed.
Co-authored-by: Russell Keith-Magee <russell@keith-magee.com>
…riefcase into file-associations
|
I have two code coverage issues of which I'm not sure how to proceed. The aforementioned exception if the plist file is not in the correct location works fine in manual testing, but is not a part of the tests since the location is hardcoded in the file. So no 100% coverage. Should I change the path to a global variable, alter that in testing to check for the exception? Or should I skip the coverage for that branch? Second issue is the if-statement in document validation where it checks the platform. If it is not macOS, it should not do the mime type to UTI conversion. I never test on macOS that it is not macOS, so coverage.py complains. |
There's a couple of possible approaches I can see - but your idea of putting the name of the file as a constant and then mocking/monkeypatching that constant for the purposes of the "file doesn't exist" test sounds good to me.
What we really need here is a conditional no-branch... but I don't think our conditional coverage handling can do that. The best fix I can see there is to put in a no-op |
|
There's currently one failed unit test because of a timeout which I don't really understand since it seems that the failing test mocks a download, so... should never time out? Not sure. Restarting the GitHub action will probably solve this for now. |
Hrm... I don't think it's doing a download, but it may be probing a live URL, which would make it sensitive to a temporary network outage. I haven't seen that failure before, though - I've kicked off the test again, and it looks like it's passed this time. |
Specifying multiple values in a LSItemContentTypes key is only valid when multiple document types are manually grouped together in the Info.plist file. For Briefcase apps, document types are always separately declared in the configuration file, so only a single value must be provided. Because the key name is plural and is an array in the Info.plist file, a list *is* accepted, but must have only one element.
Since the code to pass coverage was ugly and should be removed in any case, I'm now passing pre-commit. I'm really not sure why coverage.py keeps complaining the branch is never reached, when it clearly _is_.
|
A new issue has arisen: coverage. Coverage.py keeps complaining one branch of an if-statement is never reached in the tests, but I know for a fact that it is reached. If I include an |
|
The coverage error is |
I don't have much experience with coverage.py, so thanks for taking a look! The if-statement checks whether the supplied content type is a list, and the 'else' means 'no list'. I believe I test that here: . If I add an else: 1 / 0 statement that test crashes. So either I'm doing something wrong, I'm missing something obvious, or coverage.py is a bit confused. |
|
Are you sure you're adding the |
...but I don't like the fix.
src/briefcase/config.py
Outdated
| else: | ||
| True is True |
There was a problem hiding this comment.
These two lines seem to fix the coverage check, but obviously they don't do anything.
There was a problem hiding this comment.
@mhsmith, but this fails the ruff pre-commit check with https://docs.astral.sh/ruff/rules/useless-comparison/. Of course. I don't know what the best course of action is.
There was a problem hiding this comment.
We had a similar mysterious coverage failure in #2308, but I don't think we ever worked out the cause.
There was a problem hiding this comment.
Ah, I see the commit, thanks. I've now pushed a no-op which hopefully satisfies both the coverage checker and the pre-commit check and will leave that in for now. If it's a bug in coverage.py, this will hopefully be fixed in the future and this can go out. Not sure if I have enough time and inclination to create an MRE from this to file as an issue on coverage.py.
freakboy3742
left a comment
There was a problem hiding this comment.
This is getting pretty close; a couple of minor tweaks and suggestions inline.
| def test_mime_type_to_uti_with_nonexisting_coretypes_file(monkeypatch): | ||
| """Test that mime_type_to_UTI returns None if the coretypes file doesn't exist.""" | ||
| monkeypatch.setattr(utils, "CORETYPES_PATH", "/does/not/exist") | ||
| assert utils.mime_type_to_UTI("application/pdf") is None |
There was a problem hiding this comment.
For consistency, this should either (a) be test at the validate_document_type_config() level (i.e., a reproduction of the actual application/pdf case, but with the "couldn't find UTI data" response, or a separate test in the macOS module that does a couple of superficial direct checks of mime_type_to_UTI().
There was a problem hiding this comment.
I'm not sure I follow. Could you elaborate, please?
There was a problem hiding this comment.
All the other tests in this file are based on invoking validate_document_type_config(); but this test is invoking utils.mime_type_to_UTI. The test suite is broadly organised by test function; a test of mime_type_to_UTI should either be in a test file for that method; or the entry point for for this specific test should be modified to use validate_document_type_config() (i.e., testing the same thing, but doing so by setting up test conditions that will result in performing a mime type lookup).
To that end - this test file should also be called test_validate_document_type_config.
There was a problem hiding this comment.
I've reshuffled the tests. Renamed test_document_type_config.py to test_validate_document_type_config.py and split out test_is_uti_core_type.py and test_mime_type_to_uti.py, and the first test file no longer depends on the briefcase.platforms.macOS.utils module.
Co-authored-by: Russell Keith-Magee <russell@keith-magee.com>
|
(At least) one failing test needs a rerun:
|
|
Added some documentation to describe the document types, especially the new macOS-specific support. Probably a work in progress, but it is a first draft. |
|
FYI - I wanted to let you know that I'm not ignoring this PR; I'm currently buried in post-PyCon US backlog. I'm hoping to get to this in a day or two. |
|
Sure, no worries! |
freakboy3742
left a comment
There was a problem hiding this comment.
First off - apologies for the delay in reviewing this. "A couple of days" turned out to be overly optimistic.
But - this is awesome stuff. I've done an update pass on the documentation, and tweaked some tests (mostly as penance for being so slow on the review); but I think this is good to go. Thanks for all your work on this - Briefcase's doctype handling is a lot more robust as a result of your efforts.
docs/reference/configuration.rst
Outdated
| ``application/x-myapp-data``. This is not a valid MIME type, and should not be | ||
| used for production applications. It is only used for testing purposes, to allow |
There was a problem hiding this comment.
AFAIK, this is incorrect. The application/x- prefix is defined by RFC 2046 for "private and experimental" MIME types - it exists specifically for expansion by end users without needing to go through formal IANA registration - so it is valid.
| Background | ||
| ~~~~~~~~~~ | ||
|
|
||
| First, macOS document types are defined in the ``Info.plist`` file, and the |
There was a problem hiding this comment.
These docs are great from the perspective of macOS internals, but they're not as practical for a Briefcase user. Reading these docs, my immediate question was "ok... but what do I have to do?".
And - for most users, the answer is "nothing". I've pushed an update to these docs that changes the focus to more of a "how does Briefcase use these settings", rather than trying to explain Apple's Info.plist scheme.
src/briefcase/config.py
Outdated
| elif isinstance(content_types, str): | ||
| # If the content type is a string, convert it to a list | ||
| macOS["LSItemContentTypes"] = [content_types] | ||
| else: |
There was a problem hiding this comment.
These no-op branches can be cleaned up if the content type handling is performed before the UTI handling - I'll push an update to do this.
tests/config/test_AppConfig.py
Outdated
| "extension": "doc", | ||
| "description": "A document", | ||
| "url": "https://testurl.com", | ||
| "mime_type": "text/x.my-doc-type", |
There was a problem hiding this comment.
This isn't a valid doctype - we should be using application/x-my-doc-type.
|
|
||
|
|
||
| @pytest.mark.skipif(sys.platform != "darwin", reason="Test runs only on macOS") | ||
| def test_is_uti_core_type(): |
There was a problem hiding this comment.
This test can be parameterised.
|
|
||
|
|
||
| @pytest.mark.skipif(sys.platform != "darwin", reason="Test runs only on macOS") | ||
| def test_mime_type_to_uti(): |
There was a problem hiding this comment.
This test can be parameterized.
|
No need to apologise, I first started working on this back in March, 2024, but did not have time to finish this for many, many months. Thank you for your encouragement, guidance, and careful reviews throughout the process! I've looked through your latest changes; I like them. Thanks for merging! |
This PR adds file associations to macOS apps. The support in briefcase.toml is already there and the feature is documented. It wasn't yet generalised for non-package file types.
Refs #1706 (the issue)
Refs beeware/briefcase-macOS-app-template#72 (the PR for the macOS app template)
Refs beeware/briefcase-macOS-Xcode-template#82 (the PR for the macOS Xcode template)
This PR completes the work in the briefcase CLI tool.
I tested with https://github.com/davidfokkema/helloworld. This repository may be removed when the PR is merged.
PR Checklist: