Bug 2050591 - Remove ktlint and replace with ktfmt where possible r=geckoview-reviewers,android-reviewers,owlish,taskgraph-reviewers,ahal,ahochheiden,jonalmeida

Differential Revision: https://phabricator.services.mozilla.com/D314387
This commit is contained in:
Aaditya Dhingra
2026-08-15 16:46:29 +00:00
committed by adhingra@mozilla.com
parent 6619d8a7fe
commit 20167d0508
64 changed files with 84 additions and 442 deletions
+2
View File
@@ -44,6 +44,8 @@ max_line_length = 100
indent_style = space
indent_size = 4
max_line_length = 120
ij_kotlin_allow_trailing_comma = true
ij_kotlin_allow_trailing_comma_on_call_site = true
[*.{html,xhtml,htm,xml,xul,svg}]
indent_style = space
+6 -13
View File
@@ -325,13 +325,6 @@ subprojects { project ->
}
googleJavaFormat(libs.versions.google.java.format.get())
}
kotlin {
target project.fileTree(project.projectDir) {
include '**/*.kt'
exclude '**/thirdparty/**'
}
ktlint("${libs.versions.ktlint.get()}").setEditorConfigPath("${topsrcdir}/mobile/android/geckoview/.editorconfig")
}
}
// Work around https://github.com/diffplug/spotless/issues/1958 by
@@ -390,15 +383,15 @@ tasks.register("lint") {
description = "Runs lint on all mobile projects."
mobileProjects.each { dependsOn "${it}:lint" }
}
tasks.named("ktlint").configure {
tasks.named("ktfmtCheck").configure {
group = "verification"
description = "Runs ktlint on all mobile projects."
mobileProjects.each { dependsOn "${it}:ktlint" }
description = "Runs ktfmtCheck on all mobile projects."
mobileProjects.each { dependsOn "${it}:ktfmtCheck" }
}
tasks.named("ktlintFormat").configure {
tasks.named("ktfmtFormat").configure {
group = "formatting"
description = "Runs ktlintFormat on all mobile projects."
mobileProjects.each { dependsOn "${it}:ktlintFormat" }
description = "Runs ktfmtFormat on all mobile projects."
mobileProjects.each { dependsOn "${it}:ktfmtFormat" }
}
tasks.named("detekt").configure {
group = "verification"
@@ -6,7 +6,7 @@ for Gradle and Android.
In our current configuration, Spotless includes the
[Google Java Format plug-in](https://github.com/google/google-java-format)
which formats all our Java code using the Google Java coding style guidelines,
and [ktlint](https://ktlint.github.io/) which formats all
and [ktfmt](https://github.com/Kotlin/ktfmt) which formats all
our Kotlin code using the official Kotlin coding convention and Android Kotlin
Style Guide.
-2
View File
@@ -83,7 +83,6 @@ androidx-lint = "1.0.0"
detekt = "1.23.8"
google-java-format = "1.28.0"
ktfmt = "0.64"
ktlint = "1.8.0"
spotless = "8.9.0"
# Mozilla
@@ -264,7 +263,6 @@ detekt-cli = { module = "io.gitlab.arturbosch.detekt:detekt-cli", version.ref =
detekt-test = { module = "io.gitlab.arturbosch.detekt:detekt-test", version.ref = "detekt" }
google-java-format = { module = "com.google.googlejavaformat:google-java-format", version.ref = "google-java-format" }
ktfmt = { module = "com.facebook:ktfmt", version.ref = "ktfmt" }
ktlint = { module = "com.pinterest.ktlint:ktlint-cli", version.ref = "ktlint" }
spotless-plugin = { module = "com.diffplug.spotless:spotless-plugin-gradle", version.ref = "spotless" }
# Mozilla
@@ -1,40 +0,0 @@
# This is an .editorconfig that ktlint will "stop" at.
# If an .editorconfig file exists in any parent directory of the checkout
# directory, ktlint will fail because it uses those settings to determine what
# the indentation should be.
root = True
[*.{kt,kts}]
ij_kotlin_allow_trailing_comma_on_call_site=true
ij_kotlin_allow_trailing_comma=true
indent_size = 4
indent_style = space
insert_final_newline = true
ktlint_argument_list_wrapping_ignore_when_parameter_count_greater_or_equal_than = 13
ktlint_function_naming_ignore_when_annotated_with=Composable
# disabled rules we should decide whether to enable or not
ktlint_standard_annotation = disabled
ktlint_standard_blank-line-before-declaration = disabled
ktlint_standard_blank-line-between-when-conditions = disabled
ktlint_standard_chain-method-continuation = disabled
ktlint_standard_class-signature = disabled
ktlint_standard_enum-wrapping = disabled
ktlint_standard_function-expression-body = disabled
ktlint_standard_function-signature = disabled
ktlint_standard_if-else-wrapping = disabled
ktlint_standard_indent = disabled
ktlint_standard_multiline-expression-wrapping = disabled
ktlint_standard_no-empty-first-line-in-class-body = disabled
ktlint_standard_statement-wrapping = disabled
ktlint_standard_string-template-indent = disabled
ktlint_standard_when-entry-bracing = disabled
# rules that enforce style we don't want
ktlint_standard_backing-property-naming = disabled # it would force making backed properties public.
ktlint_standard_expression-operand-wrapping = disabled # noisy and doesn't improve readability much
ktlint_standard_max-line-length = disabled # already enabled in detekt
ktlint_standard_no-consecutive-comments = disabled # it would limit one line comments to one per line
+2 -2
View File
@@ -292,12 +292,12 @@ If your build fails, you may find you get more instructive error messages by att
# Coding Standards #
## Style ##
We follow the style enforced by [ktlint](https://ktlint.github.io/) and [detekt](https://github.com/detekt/detekt). See [how to configure Android Studio appropriately](https://pinterest.github.io/ktlint/latest/install/setup/).
We follow the style enforced by [ktfmt](https://github.com/Kotlin/ktfmt) and [detekt](https://github.com/detekt/detekt). See [how to configure Android Studio appropriately](https://github.com/Kotlin/ktfmt#intellij-android-studio-and-other-jetbrains-ides).
To check your style, run:
```
./gradlew ktlint
./gradlew ktfmtCheck
./gradlew detekt
```
@@ -18,7 +18,6 @@ plugins {
}
mozilla {
ktlintSourcePaths = ["components/**/*.kt", "samples/**/*.kt", "buildSrc/**/*.kt", "!**/build/**/*.kt"]
ktfmtSourcePaths = ["components/**/*.kt", "samples/**/*.kt", "buildSrc/**/*.kt", "!**/build/**/*.kt"]
detektSourcePaths = [
"**/components/**/*.kt", "**/buildSrc/**/*.kt", "**/samples/**/*.kt",
@@ -2,10 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// We allow wildcard imports as a convenience for the many json extension
// methods used.
@file:Suppress("ktlint:standard:no-wildcard-imports")
package mozilla.components.lib.crash.service
import android.content.Context
@@ -15,7 +15,6 @@ import org.jetbrains.uast.UFile
class LicenseCommentChecker(private val context: JavaContext) : UElementHandler() {
companion object {
@Suppress("ktlint:standard:wrapping")
val ValidLicenseForKotlinFiles = """
|/* This Source Code Form is subject to the terms of the Mozilla Public
| * License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -1,2 +1,2 @@
./gradlew detekt ktlint
./gradlew detekt ktfmtCheck
@@ -56,7 +56,7 @@ The *Android components* team evaluates, integrates and maintains tools that run
Currently we are using:
* [Android Lint](https://developer.android.com/studio/write/lint) - *"Android Lint is a tool which scans Android project sources for potential bugs."*
* [ktlint](https://github.com/shyiko/ktlint) - *"An anti-bikeshedding Kotlin linter with built-in formatter"*
* [ktfmt](https://github.com/Kotlin/ktfmt) - *"A pretty printer for the Kotlin programming language"*
* [detekt](https://github.com/arturbosch/detekt) - *"A static code analysis tool for the Kotlin programming language"*
In addition to that the *Android components* team started to write [custom lint rules](https://github.com/mozilla-mobile/firefox-android/tree/main/android-components/components/tooling/lint) that enforce component related rules (e.g. "Use the provided logging class in components instead of android.util.Log").
@@ -15,6 +15,6 @@
# output of `./gradlew tasks`.
./gradlew -q \
ktlint \
ktfmtCheck \
detekt \
testToolsDir
+1 -1
View File
@@ -139,7 +139,7 @@ native code. [Bug
making Android Studio and Gradle do this automatically.
If you want set up code formatting for Kotlin, please reference
[IntelliJ IDEA configuration](https://pinterest.github.io/ktlint/rules/configuration-intellij-idea/).
[IntelliJ IDEA configuration](https://github.com/Kotlin/ktfmt#intellij-android-studio-and-other-jetbrains-ides).
## Mobile Devices and Emulators
@@ -46,7 +46,7 @@ For Kotlin only projects, run these tools:
* Android lint
* [detekt](https://github.com/arturbosch/detekt)
* [ktlint](https://github.com/shyiko/ktlint)
* [ktfmt](https://github.com/Kotlin/ktfmt)
For projects that also include Java, add these tools:
@@ -9,7 +9,6 @@ If you get into trouble, _ask for help!_ These APIs can be confusing to get star
We have a few common lint systems for Mozilla Android apps:
- **detekt:** (probably) the go-to for analyzing Kotlin code
- **ktlint:** similar to detekt but use it instead if you don't want your lint rule to be suppressed, ever
- **android lint:** most useful when analyzing more than Kotlin code: Android-specific concerns (e.g. resource XML files), Gradle files, ProGuard files, etc. It is slow because it needs to compile the project and does multiple passes over the code; however, if your new lint check needs multiple passes, it can be useful.
- **Gradle tasks + hand-rolled check:** less performant but probably more familiar for devs to write. Use if you can't figure out how to use one of the other tools or if you're short on time
@@ -46,11 +45,6 @@ Execution failed for task ':detekt'.
detekt is lacking good documentation for writing custom rules: to understand how to write lint rules, look at our custom rules and the source of the rules built into detekt. You can also use `println` to output values inside `visit*` methods to understand what is available (ideally we can figure out how to launch a debugger to analyze it at runtime but we haven't yet).
## ktlint
TODO: fill this out!
We haven't written any ktlint rules so we're lacking knowledge here.
## Android Lint
-30
View File
@@ -1,30 +0,0 @@
[*.{kt,kts}]
ij_kotlin_allow_trailing_comma_on_call_site=true
ij_kotlin_allow_trailing_comma=true
insert_final_newline = true
ktlint_argument_list_wrapping_ignore_when_parameter_count_greater_or_equal_than = 13
ktlint_function_naming_ignore_when_annotated_with=Composable
# disabled rules we should decide whether to enable or not
ktlint_standard_annotation = disabled
ktlint_standard_blank-line-before-declaration = disabled
ktlint_standard_blank-line-between-when-conditions = disabled
ktlint_standard_chain-method-continuation = disabled
ktlint_standard_class-signature = disabled
ktlint_standard_enum-wrapping = disabled
ktlint_standard_function-expression-body = disabled
ktlint_standard_function-signature = disabled
ktlint_standard_if-else-wrapping = disabled
ktlint_standard_indent = disabled
ktlint_standard_multiline-expression-wrapping = disabled
ktlint_standard_no-empty-first-line-in-class-body = disabled
ktlint_standard_statement-wrapping = disabled
ktlint_standard_string-template-indent = disabled
ktlint_standard_when-entry-bracing = disabled
# rules that enforce style we don't want
ktlint_standard_backing-property-naming = disabled # it would force making backed properties public.
ktlint_standard_expression-operand-wrapping = disabled # noisy and doesn't improve readability much
ktlint_standard_max-line-length = disabled # already enabled in detekt
ktlint_standard_no-consecutive-comments = disabled # it would limit one line comments to one per line
-1
View File
@@ -782,7 +782,6 @@ def getSupportedLocales() {
}
mozilla {
ktlintSourcePaths = ["src/**/*.kt", "!**/build/**/*.kt"]
ktfmtSourcePaths = ["src/**/*.kt", "!**/build/**/*.kt"]
detektSourcePaths = [
"**/src/**/*.kt",
@@ -29,7 +29,7 @@ object AddToHomeScreenSelectors {
groups = listOf("systemPromptItem"),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun HOME_SCREEN_SHORTCUT(shortcutTitle: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR2_BY_TEXT,
value = shortcutTitle,
@@ -145,7 +145,7 @@ object BookmarksSelectors {
groups = listOf(),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun MULTI_SELECTION_COUNTER(count: Int = 0) = Selector(
strategy = SelectorStrategy.COMPOSE_BY_TEXT,
value = "$count selected",
@@ -153,7 +153,7 @@ object BookmarksSelectors {
groups = listOf(),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun ITEM_MENU(title: String = "") = Selector(
strategy = SelectorStrategy.COMPOSE_BY_CONTENT_DESCRIPTION,
value = "Item Menu for $title",
@@ -161,7 +161,7 @@ object BookmarksSelectors {
groups = listOf(),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun BOOKMARK_ITEM(title: String = "") = Selector(
strategy = SelectorStrategy.COMPOSE_BY_TEXT_MERGED,
value = title,
@@ -169,7 +169,7 @@ object BookmarksSelectors {
groups = listOf(),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun EXPAND_FOLDER_BUTTON(folderTitle: String = "") = Selector(
strategy = SelectorStrategy.COMPOSE_BY_CONTENT_DESCRIPTION,
value = getStringResource(R.string.bookmark_select_folder_expand_folder_content_description, folderTitle),
@@ -101,7 +101,7 @@ object BrowserPageSelectors {
groups = listOf("tabCrashReporter"),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun PAGE_CONTENT(text: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR_WITH_TEXT_CONTAINS,
value = text,
@@ -112,7 +112,7 @@ object BrowserPageSelectors {
// An item on the GeckoView text-selection floating action bar (and the app's paste popup),
// matched by exact visible text. Mirrors the legacy clickContextMenuItem, which located items
// with By.text(item) — covers "Select all", "Copy", "Search", "Private Search", "Paste".
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun TEXT_SELECTION_CONTEXT_MENU_ITEM(item: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR2_BY_TEXT,
value = item,
@@ -207,7 +207,7 @@ object BrowserPageSelectors {
groups = listOf(),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun PREFILLED_USERNAME(text: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR_WITH_WEB_ID_AND_TEXT,
value = "username",
@@ -216,7 +216,7 @@ object BrowserPageSelectors {
groups = listOf(),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun PREFILLED_PASSWORD(text: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR_WITH_WEB_ID_AND_TEXT,
value = "password",
@@ -232,7 +232,7 @@ object BrowserPageSelectors {
groups = listOf(),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun SUGGESTED_LOGIN(username: String = "") = Selector(
strategy = SelectorStrategy.COMPOSE_BY_TEXT,
value = username,
@@ -294,7 +294,7 @@ object BrowserPageSelectors {
// A saved-address suggestion row in the autofill prompt, keyed by the substring shown in its
// name/title (e.g. the street address). App View: package-prefixed res-id + textContains.
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun ADDRESS_SUGGESTION(text: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR_WITH_RES_ID_CONTAINING_TEXT,
value = "address_name",
@@ -305,7 +305,7 @@ object BrowserPageSelectors {
// Assertion helper: the web street-address field is populated with the expected value.
// Raw web DOM id + exact text.
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun AUTOFILLED_STREET_ADDRESS(text: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR_WITH_WEB_ID_AND_TEXT,
value = "streetAddress",
@@ -336,7 +336,7 @@ object BrowserPageSelectors {
// A saved-card suggestion row in the autofill prompt, keyed by the last digits shown in its masked
// number. App View: package-prefixed res-id + textContains.
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun CREDIT_CARD_SUGGESTION(lastDigits: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR_WITH_RES_ID_CONTAINING_TEXT,
value = "credit_card_number",
@@ -347,7 +347,7 @@ object BrowserPageSelectors {
// Assertion helper: the web card-number field is populated with the expected value. Raw web DOM id
// + exact text.
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun AUTOFILLED_CREDIT_CARD(number: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR_WITH_WEB_ID_AND_TEXT,
value = "cardNumber",
@@ -383,7 +383,7 @@ object BrowserPageSelectors {
)
// Title of the "open link in another app" prompt, parameterized by the target app name.
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun OPEN_IN_APP_PROMPT(appName: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR_WITH_TEXT_CONTAINS,
value = getStringResource(
@@ -18,7 +18,7 @@ object CollectionsSelectors {
groups = listOf("tabsTrayCollectionsSection"),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun EXISTING_COLLECTION_WITH_TITLE(collectionTitle: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR_WITH_TEXT,
value = collectionTitle,
@@ -33,7 +33,7 @@ object CollectionsSelectors {
groups = listOf(),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun COLLECTION_WITH_TITLE(collectionTitle: String = "") = Selector(
strategy = SelectorStrategy.COMPOSE_BY_TEXT,
value = collectionTitle,
@@ -41,7 +41,7 @@ object CollectionsSelectors {
groups = listOf("collectionItem"),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun COLLECTION_TAB_WITH_TITLE(tabTitle: String = "") = Selector(
strategy = SelectorStrategy.COMPOSE_BY_TEXT,
value = tabTitle,
@@ -49,7 +49,7 @@ object CollectionsSelectors {
groups = listOf("collectionTabItem"),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun COLLECTION_TAB_WITH_URL(url: String = "") = Selector(
strategy = SelectorStrategy.COMPOSE_BY_TEXT_SUBSTRING,
value = url,
@@ -106,7 +106,7 @@ object CustomTabsSelectors {
groups = listOf(),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun MENU_CUSTOM_ITEM(label: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR_WITH_TEXT_CONTAINS,
value = label,
@@ -105,7 +105,7 @@ object DownloadsSelectors {
* within ~5.5s, so a slow-but-landed click looks identical to a miss. A dump at one such "failure"
* showed the link holding input focus the tap had worked. Waiting is the caller's job here.
*/
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun DOWNLOAD_LINK(fileName: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR2_BY_DESCRIPTION_CONTAINS,
value = fileName,
@@ -116,7 +116,7 @@ object DownloadsSelectors {
// --- Downloads list rows (Compose; keyed off DownloadsListTestTag in main source) ---
/** The Downloads-list row for [fileName]; the screen tags each row with the file name. */
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun DOWNLOADED_FILE_LIST_ITEM(fileName: String = "") = Selector(
strategy = SelectorStrategy.COMPOSE_BY_TAG,
value = "${DownloadsListTestTag.DOWNLOADS_LIST_ITEM}.$fileName",
@@ -129,7 +129,7 @@ object DownloadsSelectors {
* outside the Downloads list: the download link on the test page and the completion snackbar.
* Device-level because the snackbar's file-name node is not reliably in the Compose tree.
*/
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun FILE_NAME_TEXT(fileName: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR_WITH_TEXT_CONTAINS,
value = fileName,
@@ -45,7 +45,7 @@ object FindInPageSelectors {
groups = listOf("requiredForPage"),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun RESULT_COUNTER(text: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR_WITH_TEXT_CONTAINS,
value = text,
@@ -109,7 +109,7 @@ object HomeSelectors {
groups = listOf("privateBrowsingHomeScreen"),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun TOP_SITE_ITEM(topSiteTitle: String = "") = Selector(
strategy = SelectorStrategy.COMPOSE_ON_ALL_NODES_BY_TAG_WITH_CHILD_TEXT_ON_FIRST,
value = "top_sites_list.top_site_item",
@@ -212,7 +212,7 @@ object MainMenuSelectors {
// The "Add <addon>" install icon on a recommended addon row in the expanded Extensions submenu.
// Keyed on the addon name because there is no test tag on the install icon (see AddonMenuItem);
// matched at the device level like the legacy installRecommendedAddon (itemWithDescription).
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun RECOMMENDED_ADDON_INSTALL_BUTTON(addonTitle: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR_WITH_DESCRIPTION_CONTAINS,
value = getStringResource(R.string.browser_menu_extension_plus_icon_content_description_2, addonTitle),
@@ -234,7 +234,7 @@ object MainMenuSelectors {
// The collapsed Extensions main-menu row once an extension is installed: it advertises the addon
// name in its content description. Mirrors the legacy verifyExtensionsButtonWithInstalledExtension
// (itemWithResIdAndDescription("mainMenu.extensions", <addon>)).
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun EXTENSIONS_BUTTON_WITH_INSTALLED_EXTENSION(addonTitle: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR_WITH_RES_ID_AND_DESCRIPTION_CONTAINS,
value = MenuDialogTestTag.EXTENSIONS,
@@ -245,7 +245,7 @@ object MainMenuSelectors {
// The installed extension row in the expanded Extensions submenu. Mirrors the legacy
// verifyInstalledExtension (hasTestTag(WEB_EXTENSION_ITEM) + content description contains <addon>).
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun INSTALLED_EXTENSION_ITEM(addonTitle: String = "") = Selector(
strategy = SelectorStrategy.COMPOSE_BY_TAG_AND_CONTENT_DESCRIPTION_SUBSTRING,
value = MenuDialogTestTag.WEB_EXTENSION_ITEM,
@@ -370,7 +370,7 @@ object MainMenuSelectors {
groups = listOf("browserViewMainMenuMoreItems", "moreMainMenuSubList"),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun OPEN_IN_APP_NAME_BUTTON(appName: String = "") = Selector(
strategy = SelectorStrategy.COMPOSE_BY_CONTENT_DESCRIPTION,
value = getStringResource(R.string.browser_menu_open_in_fenix, appName),
@@ -64,7 +64,7 @@ object NotificationSelectors {
)
// Matched by text anywhere in the shade — a notification's title or body.
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun SYSTEM_NOTIFICATION(text: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR_WITH_TEXT_CONTAINS,
value = text,
@@ -73,7 +73,7 @@ object NotificationSelectors {
)
// The collapsed notification's top line, used as the swipe handle to expand it.
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun NOTIFICATION_TOP_LINE(text: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR_WITH_RAW_RES_ID_CONTAINING_TEXT,
value = "android:id/notification_top_line",
@@ -92,7 +92,7 @@ object NotificationSelectors {
// clicks via clickAndSync and reports failure when no window update lands inside its ~5.5s budget --
// a slow-but-successful pause would then throw. UiObject2.click() just injects the gesture (see the
// strategy note in Selector.kt); the resulting state is asserted separately.
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun MEDIA_NOTIFICATION_CONTROL_BUTTON(action: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR2_BY_DESCRIPTION_CONTAINS,
value = action,
@@ -27,7 +27,7 @@ object RecentlyClosedTabsSelectors {
groups = listOf("emptyRecentlyClosedTabsList"),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun RECENTLY_CLOSED_ITEM(title: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR_WITH_RES_ID_AND_TEXT,
value = "title",
@@ -36,7 +36,7 @@ object RecentlyClosedTabsSelectors {
groups = listOf(),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun RECENTLY_CLOSED_ITEM_URL(url: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR_WITH_TEXT_CONTAINS,
value = url,
@@ -37,7 +37,7 @@ object SearchBarSelectors {
// An engine row inside the search-selector popup menu. Each row exposes the plain engine name as
// its content-description (mirrors the legacy verifySearchShortcutList / selectTemporarySearchMethod
// which matched hasContentDescription(engineName)).
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun SEARCH_SELECTOR_MENU_ENGINE(engineName: String = "") = Selector(
strategy = SelectorStrategy.COMPOSE_BY_CONTENT_DESCRIPTION,
value = engineName,
@@ -46,7 +46,7 @@ object SettingsAddonsManagerSelectors {
// the addon name via its content description. requiresScroll so the framework scrolls the row into
// view before clicking (mirrors the legacy addonsList().scrollIntoView) — needed for add-ons below
// the fold. Mirrors the legacy installButtonForAddon (withContentDescription("Install <addon>")).
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun INSTALL_ADDON_BUTTON(addonTitle: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR_WITH_DESCRIPTION_CONTAINS,
value = "Install $addonTitle",
@@ -74,7 +74,7 @@ object SettingsAddonsManagerSelectors {
// Title of the add-on install permission dialog ("Add <addon>"). Keyed on the addon name via a
// text-contains match on the shared dialog "title" id, mirroring the legacy verifyAddonPermissionPrompt.
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun ADDON_PERMISSION_PROMPT_TITLE(addonTitle: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR_WITH_RES_ID_CONTAINING_TEXT,
value = "title",
@@ -86,7 +86,7 @@ object SettingsAddonsManagerSelectors {
// Title of the install-completed dialog ("<addon> was added"). The addon's display name may be
// longer than the recommended-list name (e.g. "Bitwarden" -> "Bitwarden Password Manager"), so a
// text-contains match on the short name matches both. Mirrors legacy verifyAddonInstallCompletedPrompt.
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun ADDON_INSTALL_COMPLETED_TITLE(addonTitle: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR_WITH_RES_ID_CONTAINING_TEXT,
value = "title",
@@ -106,7 +106,7 @@ object SettingsAddonsManagerSelectors {
// An installed add-on row in the add-ons manager list, keyed on its name label. A text-contains
// match on the short name tolerates the longer display name shown in the list.
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun INSTALLED_ADDON_ITEM(addonTitle: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR_WITH_RES_ID_CONTAINING_TEXT,
value = "add_on_name",
@@ -129,7 +129,7 @@ object SettingsAutofillSelectors {
groups = listOf("deleteAddress"),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun SAVED_ADDRESS(name: String = "") = Selector(
strategy = SelectorStrategy.COMPOSE_BY_TEXT,
value = name,
@@ -74,7 +74,7 @@ object SettingsDeleteBrowsingDataSelectors {
groups = listOf(),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun OPEN_TABS_DETAILS(count: String = "0") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR_WITH_TEXT,
value = "$count tabs",
@@ -82,7 +82,7 @@ object SettingsDeleteBrowsingDataSelectors {
groups = listOf(),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun BROWSING_HISTORY_DETAILS(addresses: String = "0") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR_WITH_TEXT_CONTAINS,
value = "$addresses addresses",
@@ -59,7 +59,7 @@ object SettingsHomepageSelectors {
groups = listOf("homepageSettings"),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun OPENING_SCREEN_OPTION(openingScreenOption: String = "") = Selector(
strategy = SelectorStrategy.ESPRESSO_BY_ID_WITH_SIBLING_TEXT,
value = "radio_button",
@@ -61,7 +61,7 @@ object SettingsSavedPasswordsSelectors {
groups = listOf("loginDetails"),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun SAVED_LOGIN_ENTRY(username: String = "") = Selector(
strategy = SelectorStrategy.COMPOSE_BY_TEXT,
value = username,
@@ -69,7 +69,7 @@ object SettingsSavedPasswordsSelectors {
groups = listOf(),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun LOGIN_DETAILS_PASSWORD(password: String = "") = Selector(
strategy = SelectorStrategy.COMPOSE_BY_TAG_AND_TEXT,
value = LOGIN_DETAILS_PASSWORD_TEXT_FIELD,
@@ -14,7 +14,6 @@ object SettingsSearchDefaultSearchEngineSelectors {
groups = listOf("requiredForPage"),
)
@Suppress("ktlint:standard:function-naming")
fun DEFAULT_SEARCH_ENGINE_OPTION(engineName: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR_WITH_RES_ID_AND_TEXT,
value = "engine_text",
@@ -21,7 +21,7 @@ object SettingsSearchManageShortcutsSelectors {
)
// A single engine row in the shortcuts list, keyed by the engine name (the row's Text node).
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun SEARCH_ENGINE_SHORTCUT(engineName: String = "") = Selector(
strategy = SelectorStrategy.COMPOSE_BY_TEXT,
value = engineName,
@@ -299,7 +299,7 @@ object SettingsSelectors {
groups = listOf(),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun SETTING_OPTION_SUMMARY(settingName: String = "", settingSummary: String = "") = Selector(
strategy = SelectorStrategy.ESPRESSO_BY_TEXT_WITH_SIBLING_TEXT,
value = settingName,
@@ -163,7 +163,6 @@ object TabDrawerSelectors {
groups = listOf("createTabGroupView"),
)
@Suppress("ktlint:standard:function-naming")
fun CREATE_TAB_GROUP_COLOR_BUTTON(color: String = "") = Selector(
strategy = SelectorStrategy.COMPOSE_BY_CONTENT_DESCRIPTION,
value = color,
@@ -185,7 +184,6 @@ object TabDrawerSelectors {
groups = listOf("addToTabGroupView"),
)
@Suppress("ktlint:standard:function-naming")
fun ADD_TO_EXISTING_TAB_GROUP_BUTTON(title: String = "") = Selector(
strategy = SelectorStrategy.COMPOSE_BY_TEXT,
value = title,
@@ -193,7 +191,6 @@ object TabDrawerSelectors {
groups = listOf("addToTabGroupView"),
)
@Suppress("ktlint:standard:function-naming")
fun TAB_GROUP_ITEM(
tabGroupTitle: String = "",
numberOfTabs: Int = 1,
@@ -306,7 +303,6 @@ object TabDrawerSelectors {
groups = listOf("tabItem"),
)
@Suppress("ktlint:standard:function-naming")
fun TAB_ITEM_WITH_TITLE(tabTitle: String = "") = Selector(
strategy = SelectorStrategy.COMPOSE_ON_ALL_NODES_BY_TAG_WITH_CHILD_TEXT_ON_FIRST,
value = TabsTrayTestTag.TAB_ITEM_ROOT,
@@ -324,7 +320,6 @@ object TabDrawerSelectors {
groups = listOf("tabSelectionThreeDotMainMenu"),
)
@Suppress("ktlint:standard:function-naming")
fun SELECTION_COUNTER(numberOfTabs: Int = 0) = Selector(
strategy = SelectorStrategy.COMPOSE_BY_TEXT,
value = getStringResource(R.string.tab_tray_multi_select_title, numberOfTabs),
@@ -372,7 +367,6 @@ object TabDrawerSelectors {
// Tab search results render via FaviconListItem (title passed as a merged `label`), so the
// tag+child-text TAB_ITEM_WITH_TITLE can't locate them the way it does grid tab items; match the
// title text directly, as the legacy robot did with onNodeWithText.
@Suppress("ktlint:standard:function-naming")
fun TAB_SEARCH_RESULT(tabTitle: String = "") = Selector(
strategy = SelectorStrategy.COMPOSE_BY_TEXT,
value = tabTitle,
@@ -27,7 +27,6 @@ object TabHistorySelectors {
groups = listOf(),
)
@Suppress("ktlint:standard:function-naming")
fun TAB_HISTORY_ITEM(url: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR_WITH_TEXT,
value = url,
@@ -131,7 +131,7 @@ object ToolbarSelectors {
// An item in the context menu shown after long-pressing the display-mode (browser) URL box, e.g.
// "Copy", "Paste", "Paste & Go". Mirrors the legacy clickDisplayModeToolbarContextMenuItem, which
// matched these by content description on the Compose toolbar.
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun DISPLAY_MODE_TOOLBAR_MENU_ITEM(contentDescription: String = "") = Selector(
strategy = SelectorStrategy.COMPOSE_BY_CONTENT_DESCRIPTION,
value = contentDescription,
@@ -139,7 +139,7 @@ object ToolbarSelectors {
groups = listOf(),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun SEARCH_ENGINE_SELECTOR_ICON(searchEngineName: String = "") = Selector(
strategy = SelectorStrategy.COMPOSE_BY_CONTENT_DESCRIPTION,
value = getStringResource(R.string.search_engine_selector_content_description, searchEngineName),
@@ -163,7 +163,7 @@ object ToolbarSelectors {
// UIAutomator rather than Compose: this is asserted on BrowserPage with GeckoView active, where
// Compose sync can hang (same reason TAB_COUNTER_UIAUTOMATOR exists).
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun TAB_COUNTER_WITH_COUNT(openTabs: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR_WITH_DESCRIPTION_CONTAINS,
value = "Non-private Tabs Open: $openTabs",
@@ -174,7 +174,7 @@ object ToolbarSelectors {
// UIAutomator rather than Compose: asserted on BrowserPage with GeckoView active (see
// TAB_COUNTER_WITH_COUNT). The capitalized "Private Tabs Open:" is distinct from the normal
// counter's "Non-private Tabs Open:" fragment, so a description-contains match won't cross over.
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun PRIVATE_TAB_COUNTER_WITH_COUNT(openTabs: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR_WITH_DESCRIPTION_CONTAINS,
value = "Private Tabs Open: $openTabs",
@@ -182,7 +182,7 @@ object ToolbarSelectors {
groups = listOf(),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun TAB_STRIP_TAB_COUNTER_WITH_COUNT(openTabs: String = "") = Selector(
strategy = SelectorStrategy.COMPOSE_BY_CONTENT_DESCRIPTION,
value = "Non-private Tabs Open: $openTabs. Tap to switch tabs.",
@@ -196,7 +196,7 @@ object ToolbarSelectors {
// accessibility tree lags the Compose tree by seconds for the counter, so a UIAutomator check can
// still read the old count while Compose already shows the new one. Mirrors the legacy
// BrowserRobot.verifyTabCounter, which read the counter via composeTestRule.onNodeWithContentDescription.
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun TAB_COUNTER_COMPOSE_WITH_COUNT(openTabs: String = "") = Selector(
strategy = SelectorStrategy.COMPOSE_BY_CONTENT_DESCRIPTION,
value = "Non-private Tabs Open: $openTabs. Tap to switch tabs.",
@@ -204,7 +204,7 @@ object ToolbarSelectors {
groups = listOf(),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun PRIVATE_TAB_COUNTER_COMPOSE_WITH_COUNT(openTabs: String = "") = Selector(
strategy = SelectorStrategy.COMPOSE_BY_CONTENT_DESCRIPTION,
value = "Private Tabs Open: $openTabs. Tap to switch tabs.",
@@ -212,7 +212,7 @@ object ToolbarSelectors {
groups = listOf(),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun TAB_STRIP_TAB(tabTitle: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR_WITH_TEXT,
value = tabTitle,
@@ -220,7 +220,7 @@ object ToolbarSelectors {
groups = listOf(),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun TAB_STRIP_CLOSE_TAB_BUTTON(tabTitle: String = "") = Selector(
strategy = SelectorStrategy.UIAUTOMATOR_WITH_DESCRIPTION_CONTAINS,
value = "Close tab $tabTitle",
@@ -28,7 +28,7 @@ object UnifiedTrustPanelSelectors {
groups = listOf("clearCookiesAndSiteDataDialog"),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun CLEAR_COOKIES_AND_SITE_DATA_DIALOG_DESCRIPTION(webSite: String = "") = Selector(
strategy = SelectorStrategy.COMPOSE_BY_TEXT,
value = HtmlCompat.fromHtml(
@@ -56,7 +56,7 @@ object UnifiedTrustPanelSelectors {
// ── Site identity ───────────────────────────────────────────────────────
// Match the unique testTag AND the text. Text alone is ambiguous — the host also renders in the
// address bar (gotcha A7) — but tag alone would stop asserting which site the panel is describing.
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun WEBSITE_TITLE(webSite: String = "") = Selector(
strategy = SelectorStrategy.COMPOSE_BY_TAG_AND_TEXT,
value = "unified.trust.panel.website",
@@ -65,7 +65,7 @@ object UnifiedTrustPanelSelectors {
groups = listOf(),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun WEBSITE_URL(webSiteURL: String = "") = Selector(
strategy = SelectorStrategy.COMPOSE_BY_TAG_AND_TEXT,
value = "unified.trust.panel.website.url",
@@ -41,7 +41,7 @@ object WebCompatReporterSelectors {
groups = listOf("reporterViewItems"),
)
@Suppress("ktlint:standard:function-naming", "FunctionName")
@Suppress("FunctionName")
fun REPORTED_SITE_URL(url: String = "") = Selector(
strategy = SelectorStrategy.COMPOSE_BY_TEXT,
value = url,
-1
View File
@@ -26,7 +26,6 @@ plugins {
}
mozilla {
ktlintSourcePaths = ["app/src/**/*.kt", "!**/build/**/*.kt"]
ktfmtSourcePaths = ["app/src/**/*.kt", "!**/build/**/*.kt"]
}
@@ -27,7 +27,7 @@ fi
# - UI tests
# - android lint (takes a long time to run)
./gradlew -q \
ktlint \
ktfmtCheck \
detekt \
assembleDebug \
assembleDebugAndroidTest \
@@ -1,30 +0,0 @@
[*.{kt,kts}]
ij_kotlin_allow_trailing_comma_on_call_site=true
ij_kotlin_allow_trailing_comma=true
insert_final_newline = true
ktlint_argument_list_wrapping_ignore_when_parameter_count_greater_or_equal_than = 13
ktlint_function_naming_ignore_when_annotated_with=Composable
# disabled rules we should decide whether to enable or not
ktlint_standard_annotation = disabled
ktlint_standard_blank-line-before-declaration = disabled
ktlint_standard_blank-line-between-when-conditions = disabled
ktlint_standard_chain-method-continuation = disabled
ktlint_standard_class-signature = disabled
ktlint_standard_enum-wrapping = disabled
ktlint_standard_function-expression-body = disabled
ktlint_standard_function-signature = disabled
ktlint_standard_if-else-wrapping = disabled
ktlint_standard_indent = disabled
ktlint_standard_multiline-expression-wrapping = disabled
ktlint_standard_no-empty-first-line-in-class-body = disabled
ktlint_standard_statement-wrapping = disabled
ktlint_standard_string-template-indent = disabled
ktlint_standard_when-entry-bracing = disabled
# rules that enforce style we don't want
ktlint_standard_backing-property-naming = disabled # it would force making backed properties public.
ktlint_standard_expression-operand-wrapping = disabled # noisy and doesn't improve readability much
ktlint_standard_max-line-length = disabled # already enabled in detekt
ktlint_standard_no-consecutive-comments = disabled # it would limit one line comments to one per line
@@ -630,7 +630,6 @@ if (project.hasProperty("coverage")) {
}
mozilla {
ktlintSourcePaths = ["src/**/*.kt", "!**/build/**/*.kt"]
ktfmtSourcePaths = ["src/**/*.kt", "!**/build/**/*.kt"]
detektSourcePaths = [
"**/src/**/*.kt",
@@ -24,7 +24,6 @@ plugins {
}
mozilla {
ktlintSourcePaths = ["app/**/*.kt", "buildSrc/**/*.kt", "!**/build/**/*.kt"]
ktfmtSourcePaths = ["app/**/*.kt", "buildSrc/**/*.kt", "!**/build/**/*.kt"]
}
@@ -10,7 +10,7 @@ forever to dig through the logs):
./gradlew -q \
checkstyle \
ktlint \
ktfmtCheck \
pmd \
detektCheck \
app:assembleFocusArmDebug
@@ -14,7 +14,7 @@
# Descriptions for each gradle task below can be found in the
# output of `./gradlew tasks`.
./gradlew -q \
ktlint \
ktfmtCheck \
detekt \
assembleFocusDebugAndroidTest \
testFocusDebugUnitTest
-31
View File
@@ -1,31 +0,0 @@
root = True
[*.{kt,kts}]
ij_kotlin_allow_trailing_comma_on_call_site=true
ij_kotlin_allow_trailing_comma=true
insert_final_newline = true
ktlint_argument_list_wrapping_ignore_when_parameter_count_greater_or_equal_than = 13
# disabled rules we should decide whether to enable or not
ktlint_standard_annotation = disabled
ktlint_standard_blank-line-before-declaration = disabled
ktlint_standard_blank-line-between-when-conditions = disabled
ktlint_standard_chain-method-continuation = disabled
ktlint_standard_class-signature = disabled
ktlint_standard_enum-wrapping = disabled
ktlint_standard_function-expression-body = disabled
ktlint_standard_function-signature = disabled
ktlint_standard_if-else-wrapping = disabled
ktlint_standard_indent = disabled
ktlint_standard_multiline-expression-wrapping = disabled
ktlint_standard_no-empty-first-line-in-class-body = disabled
ktlint_standard_statement-wrapping = disabled
ktlint_standard_string-template-indent = disabled
ktlint_standard_when-entry-bracing = disabled
# rules that enforce style we don't want
ktlint_standard_backing-property-naming = disabled # it would force making backed properties public.
ktlint_standard_expression-operand-wrapping = disabled # noisy and doesn't improve readability much
ktlint_standard_max-line-length = disabled # already enabled in detekt
ktlint_standard_no-consecutive-comments = disabled # it would limit one line comments to one per line
@@ -1,7 +1,6 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
@file:Suppress("ktlint:standard:no-wildcard-imports")
package org.mozilla.geckoview.test
@@ -1981,7 +1981,6 @@ class GeckoSessionTestRuleTest : BaseSessionTest(noErrorCollector = true) {
sessionRule.performTestEndCheck()
}
@Suppress("ktlint:standard:annotation")
@Test fun addExternalDelegateDuringNextWait() {
mainSession.loadTestPath(HELLO_HTML_PATH)
sessionRule.waitForPageStop()
@@ -1,4 +1,3 @@
@file:Suppress("ktlint:standard:no-wildcard-imports")
package org.mozilla.geckoview.test
@@ -1,7 +1,6 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
@file:Suppress("ktlint:standard:no-wildcard-imports")
package org.mozilla.geckoview.test
@@ -8,7 +8,6 @@ plugins {
}
val mozconfig = gradle.extra["mozconfig"] as Map<*, *>
val topsrcdir = mozconfig["topsrcdir"] as String
val topobjdir = mozconfig["topobjdir"] as String
layout.buildDirectory.set(file("$topobjdir/gradle/build/mobile/android/gradle/plugins/apilint/apilint"))
@@ -16,8 +15,9 @@ layout.buildDirectory.set(file("$topobjdir/gradle/build/mobile/android/gradle/pl
spotless {
lineEndings = com.diffplug.spotless.LineEnding.UNIX
kotlin {
ktlint(libs.versions.ktlint.get())
.setEditorConfigPath("$topsrcdir/mobile/android/geckoview/.editorconfig")
ktfmt(libs.versions.ktfmt.get()).kotlinlangStyle().configure {
it.setMaxWidth(120)
}
}
}
@@ -10,7 +10,6 @@ import org.gradle.api.provider.Property
interface ProjectExtension {
val androidComponentsProject: Property<Boolean>
val ktlintSourcePaths: ListProperty<String>
val ktfmtSourcePaths: ListProperty<String>
val detektSourcePaths: ListProperty<String>
val detektConfig: Property<String>
@@ -9,10 +9,8 @@ import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.DependencySubstitution
import org.gradle.api.artifacts.ExternalModuleDependency
import org.gradle.api.artifacts.VersionCatalogsExtension
import org.gradle.api.artifacts.component.ModuleComponentIdentifier
import org.gradle.api.attributes.Bundling
import org.gradle.api.artifacts.component.ModuleComponentSelector
import org.gradle.api.logging.Logger
import org.gradle.api.logging.StandardOutputListener
@@ -33,7 +31,7 @@ class ProjectPlugin : Plugin<Project> {
override fun apply(project: Project) {
val mozilla = project.extensions.create("mozilla", ProjectExtension::class.java)
mozilla.androidComponentsProject.convention(false)
mozilla.ktlintSourcePaths.convention(emptyList())
mozilla.ktfmtSourcePaths.convention(emptyList())
mozilla.detektSourcePaths.convention(emptyList())
mozilla.detektAutoCorrect.convention(true)
mozilla.detektReports.convention(emptyMap())
@@ -59,7 +57,6 @@ class ProjectPlugin : Plugin<Project> {
configureAppServicesSubstitution(project, extraProperties, substs)
configureGleanSubstitution(project, extraProperties)
configureGleanVersionResolution(project)
configureKtlint(project, mozilla)
configureKtfmt(project, mozilla)
configureDetekt(project, mozilla)
configureAndroidComponentsLint(project, mozilla, topsrcdir)
@@ -323,75 +320,6 @@ class ProjectPlugin : Plugin<Project> {
private val GLEAN_GROUPS = setOf("org.mozilla.telemetry")
}
private fun configureKtlint(project: Project, mozilla: ProjectExtension) {
val sourcePaths = mozilla.ktlintSourcePaths
val ktlintConfig = project.configurations.register("ktlint")
val ktlintDep = project.provider {
val versionCatalogs = project.extensions.getByType(VersionCatalogsExtension::class.java)
val libs = versionCatalogs.named("libs")
val dep = project.dependencies.create(libs.findLibrary("ktlint").get().get())
if (dep is ExternalModuleDependency) {
dep.attributes {
attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling::class.java, Bundling.EXTERNAL))
}
}
dep
}
ktlintConfig.configure { dependencies.addLater(ktlintDep) }
val ktlintClasspath = project.files(ktlintConfig)
// Resolve the include/exclude globs (with leading "!" meaning exclude)
// into a FileTree rooted at projectDir, so Gradle can use the actual
// Kotlin source set to compute UP-TO-DATE / build cache keys.
fun ktlintSourceTree() = project.fileTree(project.projectDir).matching {
sourcePaths.get().forEach { pattern ->
if (pattern.startsWith("!")) {
exclude(pattern.removePrefix("!"))
} else {
include(pattern)
}
}
}
project.tasks.register("ktlint", JavaExec::class.java) {
group = "verification"
description = "Check Kotlin code style."
classpath = ktlintClasspath
mainClass.set("com.pinterest.ktlint.Main")
onlyIf { sourcePaths.get().isNotEmpty() }
sourcePaths.get().forEach { args(it) }
args("--reporter=json,output=build/reports/ktlint/ktlint.json")
args("--reporter=plain")
inputs.files(ktlintSourceTree())
.withPropertyName("ktlintSources")
.withPathSensitivity(org.gradle.api.tasks.PathSensitivity.RELATIVE)
.skipWhenEmpty()
outputs.file(project.file("build/reports/ktlint/ktlint.json"))
.withPropertyName("ktlintReport")
outputs.cacheIf { true }
}
project.tasks.register("ktlintFormat", JavaExec::class.java) {
group = "formatting"
description = "Fix Kotlin code style deviations."
classpath = ktlintClasspath
mainClass.set("com.pinterest.ktlint.Main")
onlyIf { sourcePaths.get().isNotEmpty() }
args("-F")
sourcePaths.get().forEach { args(it) }
args("--reporter=json,output=build/reports/ktlint/ktlintFormat.json")
args("--reporter=plain")
jvmArgs("--add-opens", "java.base/java.lang=ALL-UNNAMED")
inputs.files(ktlintSourceTree())
.withPropertyName("ktlintFormatSources")
.withPathSensitivity(org.gradle.api.tasks.PathSensitivity.RELATIVE)
.skipWhenEmpty()
outputs.file(project.file("build/reports/ktlint/ktlintFormat.json"))
.withPropertyName("ktlintFormatReport")
}
}
private fun configureDetekt(project: Project, mozilla: ProjectExtension) {
val sourcePaths = mozilla.detektSourcePaths
-1
View File
@@ -239,7 +239,6 @@ treeherder:
'buildconfig': 'Make sure the content of .buildconfig.yml matches what gradle knows about its projects'
'compare-locales': 'Validate strings.xml with compare-locales'
'detekt': 'detekt linter'
'ktlint': 'ktlint linter'
'lint': 'gradle lint linter'
'focus': 'Focus general tasks no matter the variant'
-1
View File
@@ -30,7 +30,6 @@ tasks-from:
- doc.yml
- file-metadata.yml
- jsshell.yml
- ktlint.yml
- mozlint.yml
- mozlint-android.yml
- node.yml
-76
View File
@@ -1,76 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
---
task-defaults:
description: 'Run ktlint over all modules'
run:
clone-with: hg
using: gradlew
gradlew: ['ktlint']
attributes:
code-review: true
always-target: true
fetches:
toolchain:
- android-sdk-linux
- linux64-embedded-uniffi-bindgen
- linux64-nimbus-fml
- android-gradle-dependencies
- linux64-jdk-repack
platform: 'lint/opt'
treeherder:
kind: test
tier: 1
worker-type: b-linux
worker:
docker-image: {in-tree: lint}
max-run-time: 1200
when:
files-changed:
- "mobile/android/android-components/**"
android-components:
run:
clone-with: hg
pre-gradlew:
- ["cd", "mobile/android/android-components"]
treeherder:
symbol: ktlint(AC)
worker:
artifacts:
- name: public/reports
path: /builds/worker/checkouts/gecko/mobile/android/android-components/build/reports
type: directory
focus:
when:
files-changed:
- "mobile/android/focus-android/**"
run:
clone-with: hg
pre-gradlew:
- ["cd", "mobile/android/focus-android"]
treeherder:
symbol: ktlint(focus)
worker:
artifacts:
- name: public/reports
path: /builds/worker/checkouts/gecko/mobile/android/focus-android/build/reports
type: directory
fenix:
when:
files-changed:
- "mobile/android/fenix/**"
run:
clone-with: hg
pre-gradlew:
- ["cd", "mobile/android/fenix"]
treeherder:
symbol: ktlint(fenix)
worker:
artifacts:
- name: public/reports
path: /builds/worker/checkouts/gecko/mobile/android/fenix/build/reports
type: directory
@@ -660,9 +660,6 @@ existing_tasks:
source-test-jsshell-bench-sunspider-sm: I8ekQvy3SEqT7SwE4IlAaA
source-test-jsshell-bench-web-tooling-sm: CHckq_RDQGmTzWvzBLryVA
source-test-jsshell-bench-web-tooling-v8: bOgj9JU0S4iRNcn1bywXQg
source-test-ktlint-android-components: LXpySOcCQ8yLVRj9H0FoWA
source-test-ktlint-fenix: UjawibIsRFyRFW3CoJcXrw
source-test-ktlint-focus: G1Ez50KYQpKrJD7lNradbg
source-test-mozlint-android-android-components: Bvk_7U5ZTd6JP_xnsGcvPg
source-test-mozlint-android-fenix: OOt3WrqfS1So2sSKteCQ3g
source-test-mozlint-android-focus: XUjvrKsPSM6hRmlBq-zWFw
@@ -764,9 +764,6 @@ existing_tasks:
source-test-jsshell-bench-sunspider-sm: HxAlqr5PQtOtzLukfCHO4Q
source-test-jsshell-bench-web-tooling-sm: G0I2H8XbTaeskioopdvm1w
source-test-jsshell-bench-web-tooling-v8: fKcLQRSsT9eQTcDoOhdHSQ
source-test-ktlint-android-components: LPGpNy6mS1yguxA8Zruikg
source-test-ktlint-fenix: fwiMAbkITh6RIsB61BwZzA
source-test-ktlint-focus: eIeqyyRQSlmJgL8uzyh9XA
source-test-mozlint-android-android-components: NliWkhZuQqasIx-BavjXtA
source-test-mozlint-android-fenix: GROiXRwWRj-HLlwOKEKcSw
source-test-mozlint-android-focus: AY8otzFuR0Gqe-6N02tA4g
@@ -804,9 +804,6 @@ existing_tasks:
source-test-jsshell-bench-web-tooling-linux1804-64-shippable/opt-v8: LUaomoakT1iM5rslcYHcRg
source-test-jsshell-bench-web-tooling-linux2404-64-shippable/opt-sm: di5ltgFeTref76bwOskWMA
source-test-jsshell-bench-web-tooling-linux2404-64-shippable/opt-v8: cQsISoG4Rnq9yG86_I22aQ
source-test-ktlint-android-components: Z9q3kDAYSFanUWYJwnqHlA
source-test-ktlint-fenix: KpX_eCBBSiOdNVxTWkdwWA
source-test-ktlint-focus: Wv6YB1spSrOnAQ5RU1lFkg
source-test-mozlint-android-android-components: Duw5qBfoTzyZHzZe383JJA
source-test-mozlint-android-expired-strings: b8NI4WRbQ9GYh1Zr1u2RkQ
source-test-mozlint-android-fenix: RMYd0gc1Q0OgoKDniWGHGA
+1 -33
View File
@@ -197,12 +197,10 @@ def report_gradlew(
topobjdir = lintargs["topobjdir"]
if fix:
ktlint_task = f":{project_name}:ktlintFormat"
ktfmt_task = f":{project_name}:ktfmtFormat"
else:
ktlint_task = f":{project_name}:ktlint"
ktfmt_task = f":{project_name}:ktfmtCheck"
tasks = [ktlint_task, ktfmt_task, f":{project_name}:detekt"] + list(lint_tasks)
tasks = [ktfmt_task, f":{project_name}:detekt"] + list(lint_tasks)
extra_args = lintargs.get("extra_args") or []
if disable_android_components_tasks:
@@ -263,36 +261,6 @@ def report_gradlew(
print(f"Could not read detekt report: '{detekt_report}'")
pass
ktlint_file = "ktlint.json"
if fix:
ktlint_file = "ktlintFormat.json"
ktlint_report = os.path.join(reports, "ktlint", ktlint_file)
if not os.path.exists(ktlint_report):
ktlint_report = os.path.join(
topsrcdir, subdir, "app", "build", "reports", "ktlint", ktlint_file
)
try:
issues = json.load(open(ktlint_report))
for issue in issues:
name = issue["file"]
if is_excluded_file(topsrcdir, excludes, name):
continue
for error in issue["errors"]:
err = {
"rule": error["rule"],
"path": name,
"lineno": error["line"],
"column": error["column"],
"message": error["message"],
"level": "error",
}
results.append(result.from_config(config, **err))
except FileNotFoundError:
print(f"Could not read ktlint report: `{ktlint_report}`")
pass
if not fix:
results.extend(
parse_ktfmt_results(