-
-
Notifications
You must be signed in to change notification settings - Fork 469
Fix app name validation logic and improve error message #2405
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
Tests failed :-( i will be looking into those when I'm back home |
|
Hi @freakboy3742 ! I'm getting some errors that are unrelated to my changes. At least I suppose so. Could you check those out please? |
|
@egarciamendez Looks like you were bitten by some transient network problems - not sure if the problem was on Github's side, or Adoptium's - but either way, re-running the tests looks like it has succeeded. This indicates there are some tests that we should probably clean up - there's very limited situations where we should be dependent on external network availability to run the test suite, and from the look of these test failures, none of these would qualify. I've added #2409 to track this issue with the test suite. |
freakboy3742
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is definitely headed in the right direction - a couple of cleanups and suggestions inline.
Co-authored-by: Russell Keith-Magee <[email protected]>
…eck for valid module name
freakboy3742
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This revision has overcorrected a little too much - it's allowing names that shouldn't be allowed, and rejecting names that should be valid. To be fair - some of those rejected names were historically rejected as well - so this is at least partially a case of the existing test cases being misleading.
I think the core of the problem is that PEP 508 compliance in the app name is a red herring. Despite the historical code, we don't actually want PEP 508 compliance for app names - we want "is valid identifier after replacing - with _" and "is not a keyword".
The convert wizard then needs different handling, because project.name is governed solely by PEP 508 - but there are valid PEP508 names that aren't valid app names (e.g., foo.bar), and names that aren't valid PEP 508 names, but are validated app names (e.g., foo_). In the convert wizard, there's essentially 2 cases:
- The project name is a valid app name as written
- The project name can be canonicalised into a valid app name.
Case 1 is the simple case (e.g., project.name = "foobar") - in which case, the name is being used unmodified, so we can use it as the app name without any confirmation.
Case 2 is the slightly more complex case, where we are applying a transformation (e.g., project.name = "foo.bar", which canonicalises to foo_bar). In this case, that's likely a good candidate, but we need to get the user to confirm this.
If neither of these cases are true - 1foo.bar, for example - then we need to fall back to alternate suggestions (such as using the directory name).
Does that make sense?
| and is_valid_app_name(self.pep621_data["name"]) | ||
| and override_value is None | ||
| ): | ||
| if "name" in self.pep621_data and override_value is None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why you've dropped the validity check here - 1hello.world is a valid project.name by PEP 508, which canonicalizes to 1hello-world - but that's not a valid app name, so it can't be used as a candidate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's 3 cases here:
- The project name is useable as-is.
foobarandfoo-barare both valid project names, and are also valid app names as-is. They can be directly provided as the candidate app name, as there's no transformation being applied. - The project name could be a valid name, but requires some canonicalisation.
test.nameis a valid PEP 508 project name, and it canonicalizes totest-name; we don't want to provide that name as an automatic app name, but it's a reasonable candidate for an app name that the user could confirm as valid. - The project name isn't valid, even after canonicalisation.
42foobaris a valid project name - but it canonicalizes to exactly the same value, which isn't a valid app name. In this case, we need to fall back to other hinted options (such as the base path of the project).
The code has a branch for 1 and 3; but the logic that triggers 1 is incorrect and it merges in the canonicalisation required by case 2. There's no logic handling the case of "test.name" being coerced into a hint for the user to confirm.
Does that make more sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, thank you for the explanation (and your patience 😅)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok - but my the original point still stands: you've dropped the validation check on this branch. By this code, if user provides any value for name in the [project] data, the canonicalised version of that name will be used. You've added code for the three cases that I described - but this check comes before those cases are evaluated.
| and is_valid_app_name(self.pep621_data["name"]) | ||
| and override_value is None | ||
| ): | ||
| if "name" in self.pep621_data and override_value is None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's 3 cases here:
- The project name is useable as-is.
foobarandfoo-barare both valid project names, and are also valid app names as-is. They can be directly provided as the candidate app name, as there's no transformation being applied. - The project name could be a valid name, but requires some canonicalisation.
test.nameis a valid PEP 508 project name, and it canonicalizes totest-name; we don't want to provide that name as an automatic app name, but it's a reasonable candidate for an app name that the user could confirm as valid. - The project name isn't valid, even after canonicalisation.
42foobaris a valid project name - but it canonicalizes to exactly the same value, which isn't a valid app name. In this case, we need to fall back to other hinted options (such as the base path of the project).
The code has a branch for 1 and 3; but the logic that triggers 1 is incorrect and it merges in the canonicalisation required by case 2. There's no logic handling the case of "test.name" being coerced into a hint for the user to confirm.
Does that make more sense?
…r rules and exclude problematic Unicode characters
…ases for valid identifiers
…s file for permissions
freakboy3742
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the update; there's still some issues with the validation logic. I've tried to explain inline. Let me know if you need any further clarifications.
| and is_valid_app_name(self.pep621_data["name"]) | ||
| and override_value is None | ||
| ): | ||
| if "name" in self.pep621_data and override_value is None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok - but my the original point still stands: you've dropped the validation check on this branch. By this code, if user provides any value for name in the [project] data, the canonicalised version of that name will be used. You've added code for the three cases that I described - but this check comes before those cases are evaluated.
src/briefcase/config.py
Outdated
| # case, which has very slightly different semantics with non-ASCII characters. This | ||
| # definition is the one from | ||
| # https://github.com/pypa/packaging/blob/24.0/src/packaging/_tokenizer.py#L80 | ||
| PEP508_NAME_RE = re.compile(r"^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9])$") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This regex isn't being used any more, so it can be dropped.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually it is being used in some android sdk dependency. That's why I didn't delete it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah - I somehow missed that usage in my searching.
In this case, I think that's a case where the regex can be moved and renamed. It's being used to identify valid Android emulator names, which aren't bound by PEP 508 - they just happen to have very similar rules.
Interestingly, PEP 508 will allow bee.phone as a name, and that works with the emulator (I just checked), but period isn't included in the description of a valid emulator name.
So - I'd suggest moving it to the android module where it's being used, and rename it to ANDROID_EMULATOR_NAME_RE.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done :-)
| ) | ||
| # Case 2: Project name could be valid after canonicalization (e.g., "test.name" -> "test-name", "test-app_name" -> "test-app-name") | ||
| elif is_valid_app_name(canonicalized_name): | ||
| default = canonicalized_name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By this logic, case 1 and case 2 are functionally identical. The key difference between case 1 and case 2 is that we don't need to ask the user to confirm case 1 - we're using exactly the same name, so it's fine as is. Case 2 involves a transformation, so it needs to be confirmed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
Co-authored-by: Russell Keith-Magee <[email protected]>
|
Are you waiting on a review of this code? Aside from the CI pre-commit failure, it looks like some of my comments from my previous review are outstanding. When you're ready for another review, let me know and I'll take a look. |

This PR fixes a bug in the is_valid_app_name function and improves the error message for better user experience.
Changes Made
Problem Solved
The improved error message provides clear, actionable guidance to developers when their app name is rejected.
Fixes #2127
PR Checklist: