Skip to content
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

Enforce user-facing locale checks via lint; fixes #8917 #18096

Merged
merged 1 commit into from
Mar 23, 2025

Conversation

spoisseroux
Copy link
Contributor

Purpose / Description

User-facing text formatting sometimes uses Locale.ROOT or lacks explicit locale, leading to incorrect number/date formats

Fixes

Approach

  • Created LocaleRootDetector to flag Locale.ROOT in user-facing formatting methods (ie., String.format(), NumberFormat).
  • Activated DefaultLocale lint rule to enforce explicit Locale parameters.
  • Updated violations to use Locale.getDefault() where appropriate.

How Has This Been Tested?

./gradlew clean lint

Learning (optional, can help others)

Android custom lint rules
Used existing custom lint rules as a template

Checklist

  • You have a descriptive commit message with a short title (first line, max 50 chars).
  • You have commented your code, particularly in hard-to-understand areas
  • You have performed a self-review of your own code
  • [NA] UI changes: include screenshots of all affected screens (in particular showing any new or changed strings)
  • [NA] UI Changes: You have tested your change using the Google Accessibility Scanner

Copy link

welcome bot commented Mar 14, 2025

First PR! 🚀 We sincerely appreciate that you have taken the time to propose a change to AnkiDroid! Please have patience with us as we are all volunteers - we will get to this as soon as possible.

Copy link
Member

@Arthur-Milchior Arthur-Milchior left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi,

First, thanks so much for starting to contribute.
I'd really love some tests with that. You can look at DirectSystemTimeInstantiationTest to see how to test linters. Because, to be honest, I've a hard time reading Linter code, it's very specific and this is not something I read every day, while tests are very easy to verify.

Are you here for GSoC? If so, we also expect you to create a test, so that'd be nice too. If so, I'd like to add, as a mentor, that it'd be great if you also had a contribution that introduce a user facing change. It's always easier for me, as a mentor, to evaluate Android code; than code processing code


private fun isLocaleRootUsage(node: UCallExpression): Boolean =
node.methodName?.let { methodName ->
(methodName == "format" || methodName == "getInstance" || methodName == "newInstance") &&
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a fan to be honest. I'm far from certain that this is exactly all of the function where Locale.ROOT should not be used.

I think we should just forbid it everywhere, and then enable it in the case where we find out it's really needed, as Mike suggested in the issue.

I'd be fine however if you explicitly exclude some functions where we know we really don't care about the locale.
I'm fine if you just suppress the Lint error on all usages of Locale.ROOT currently used in the code. Ideally I'd love a comment with it, but I'd understand if you lack context to explain the choice in some of the places.

Copy link
Contributor Author

@spoisseroux spoisseroux Mar 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeap, I'm here from GSoC. I have a merged unit test here.

Could you recommend me a user-facing issue that would be good for a beginner? There weren't many not currently being worked on that have the Good First Issue label. I took this as I was recently learning about linters so thought it was a good fit, sorry about that.

I will update to forbid everywhere, and suppress of current uses of Locale.ROOT (most likely without the comments) and implement tests.

Thanks so much for the feedback!

Added lint rule to ensure proper locale usage in text formatting

- Implemented custom `LocaleRootDetector` to flag `Locale.ROOT` in user-facing
  formatting methods (e.g. String.format, NumberFormat)
- Enabled `DefaultLocale` check to require explicit Locale parameters
- Fixed violations in AxisValueDisplay and other components

Testing:
- Ran `./gradlew lint` to verify new checks flag violations
@Arthur-Milchior Arthur-Milchior force-pushed the fix-8917-locale-root-lint branch from 1090bf5 to 8dcb5cc Compare March 16, 2025 23:29
class LocaleRootDetectorTest {
@Language("JAVA")
private val invalidCode =
"""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove the empty spaces

@Arthur-Milchior Arthur-Milchior added the Needs Second Approval Has one approval, one more approval to merge label Mar 16, 2025
Copy link
Member

@mikehardy mikehardy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice one! Thank you

@mikehardy mikehardy added this pull request to the merge queue Mar 23, 2025
Merged via the queue into ankidroid:main with commit 13005d8 Mar 23, 2025
9 checks passed
@github-actions github-actions bot added this to the 2.21 release milestone Mar 23, 2025
@github-actions github-actions bot removed the Needs Second Approval Has one approval, one more approval to merge label Mar 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Lint: no Locale.ROOT in text user see
3 participants