mirror of
https://github.com/fork-maintainers/iceraven-browser
synced 2024-11-15 18:12:54 +00:00
[fenix] Closes https://github.com/mozilla-mobile/fenix/issues/8944 - Adds custom lint checks
This commit is contained in:
parent
058e6b3e9f
commit
ccee01a230
@ -581,6 +581,8 @@ dependencies {
|
|||||||
// For the initial release of Glean 19, we require consumer applications to
|
// For the initial release of Glean 19, we require consumer applications to
|
||||||
// depend on a separate library for unit tests. This will be removed in future releases.
|
// depend on a separate library for unit tests. This will be removed in future releases.
|
||||||
testImplementation "org.mozilla.telemetry:glean-forUnitTests:${project.ext.glean_version}"
|
testImplementation "org.mozilla.telemetry:glean-forUnitTests:${project.ext.glean_version}"
|
||||||
|
|
||||||
|
lintChecks project(":mozilla-lint-rules")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (project.hasProperty("raptor")) {
|
if (project.hasProperty("raptor")) {
|
||||||
|
1
mozilla-lint-rules/.gitignore
vendored
Normal file
1
mozilla-lint-rules/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/build
|
21
mozilla-lint-rules/build.gradle
Normal file
21
mozilla-lint-rules/build.gradle
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
apply plugin: 'java-library'
|
||||||
|
apply plugin: 'kotlin'
|
||||||
|
|
||||||
|
targetCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compileOnly "org.jetbrains.kotlin:kotlin-stdlib:1.3.61"
|
||||||
|
compileOnly "com.android.tools.lint:lint-api:26.6.1"
|
||||||
|
compileOnly "com.android.tools.lint:lint-checks:26.6.1"
|
||||||
|
}
|
||||||
|
|
||||||
|
jar {
|
||||||
|
manifest {
|
||||||
|
attributes('Lint-Registry-v2': 'org.mozilla.fenix.lintrules.LintIssueRegistry')
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
package org.mozilla.fenix.lintrules
|
||||||
|
|
||||||
|
import com.android.SdkConstants.ATTR_SRC
|
||||||
|
import com.android.SdkConstants.FQCN_IMAGE_BUTTON
|
||||||
|
import com.android.SdkConstants.FQCN_IMAGE_VIEW
|
||||||
|
import com.android.SdkConstants.IMAGE_BUTTON
|
||||||
|
import com.android.SdkConstants.IMAGE_VIEW
|
||||||
|
import com.android.resources.ResourceFolderType
|
||||||
|
import com.android.tools.lint.detector.api.Category
|
||||||
|
import com.android.tools.lint.detector.api.Implementation
|
||||||
|
import com.android.tools.lint.detector.api.Issue
|
||||||
|
import com.android.tools.lint.detector.api.ResourceXmlDetector
|
||||||
|
import com.android.tools.lint.detector.api.Scope
|
||||||
|
import com.android.tools.lint.detector.api.Severity
|
||||||
|
import com.android.tools.lint.detector.api.XmlContext
|
||||||
|
import org.w3c.dom.Element
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A custom lint check that prohibits not using the app:srcCompat for ImageViews
|
||||||
|
*/
|
||||||
|
class AndroidSrcXmlDetector : ResourceXmlDetector() {
|
||||||
|
companion object {
|
||||||
|
const val SCHEMA = "http://schemas.android.com/apk/res/android"
|
||||||
|
const val FULLY_QUALIFIED_APP_COMPAT_IMAGE_BUTTON =
|
||||||
|
"androidx.appcompat.widget.AppCompatImageButton"
|
||||||
|
const val FULLY_QUALIFIED_APP_COMPAT_VIEW_CLASS =
|
||||||
|
"androidx.appcompat.widget.AppCompatImageView"
|
||||||
|
const val APP_COMPAT_IMAGE_BUTTON = "AppCompatImageButton"
|
||||||
|
const val APP_COMPAT_IMAGE_VIEW = "AppCompatImageView"
|
||||||
|
|
||||||
|
const val ERROR_MESSAGE = "Using android:src to define resource instead of app:srcCompat"
|
||||||
|
|
||||||
|
val ISSUE_XML_SRC_USAGE = Issue.create(
|
||||||
|
id = "AndroidSrcXmlDetector",
|
||||||
|
briefDescription = "Prohibits using android:src in ImageViews and ImageButtons",
|
||||||
|
explanation = "ImageView (and descendants) images should be declared using app:srcCompat",
|
||||||
|
category = Category.CORRECTNESS,
|
||||||
|
severity = Severity.ERROR,
|
||||||
|
implementation = Implementation(
|
||||||
|
AndroidSrcXmlDetector::class.java,
|
||||||
|
Scope.RESOURCE_FILE_SCOPE
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun appliesTo(folderType: ResourceFolderType): Boolean {
|
||||||
|
// Return true if we want to analyze resource files in the specified resource
|
||||||
|
// folder type. In this case we only need to analyze layout resource files.
|
||||||
|
return folderType == ResourceFolderType.LAYOUT
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getApplicableElements(): Collection<String>? {
|
||||||
|
return setOf(
|
||||||
|
FQCN_IMAGE_VIEW,
|
||||||
|
IMAGE_VIEW,
|
||||||
|
FQCN_IMAGE_BUTTON,
|
||||||
|
IMAGE_BUTTON,
|
||||||
|
FULLY_QUALIFIED_APP_COMPAT_IMAGE_BUTTON,
|
||||||
|
FULLY_QUALIFIED_APP_COMPAT_VIEW_CLASS,
|
||||||
|
APP_COMPAT_IMAGE_BUTTON,
|
||||||
|
APP_COMPAT_IMAGE_VIEW
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitElement(context: XmlContext, element: Element) {
|
||||||
|
if (!element.hasAttributeNS(SCHEMA, ATTR_SRC)) return
|
||||||
|
val node = element.getAttributeNodeNS(SCHEMA, ATTR_SRC)
|
||||||
|
|
||||||
|
context.report(
|
||||||
|
issue = ISSUE_XML_SRC_USAGE,
|
||||||
|
scope = node,
|
||||||
|
location = context.getLocation(node),
|
||||||
|
message = ERROR_MESSAGE
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,81 @@
|
|||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
package org.mozilla.fenix.lintrules
|
||||||
|
|
||||||
|
import com.android.SdkConstants.ATTR_TINT
|
||||||
|
import com.android.SdkConstants.FQCN_IMAGE_BUTTON
|
||||||
|
import com.android.SdkConstants.FQCN_IMAGE_VIEW
|
||||||
|
import com.android.SdkConstants.IMAGE_BUTTON
|
||||||
|
import com.android.SdkConstants.IMAGE_VIEW
|
||||||
|
import com.android.resources.ResourceFolderType
|
||||||
|
import com.android.tools.lint.detector.api.Category
|
||||||
|
import com.android.tools.lint.detector.api.Implementation
|
||||||
|
import com.android.tools.lint.detector.api.Issue
|
||||||
|
import com.android.tools.lint.detector.api.ResourceXmlDetector
|
||||||
|
import com.android.tools.lint.detector.api.Scope
|
||||||
|
import com.android.tools.lint.detector.api.Severity
|
||||||
|
import com.android.tools.lint.detector.api.XmlContext
|
||||||
|
import org.w3c.dom.Element
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A custom lint check that prohibits not using the app:tint for ImageViews
|
||||||
|
*/
|
||||||
|
class ImageViewAndroidTintXmlDetector : ResourceXmlDetector() {
|
||||||
|
companion object {
|
||||||
|
const val SCHEMA = "http://schemas.android.com/apk/res/android"
|
||||||
|
const val FULLY_QUALIFIED_APP_COMPAT_IMAGE_BUTTON =
|
||||||
|
"androidx.appcompat.widget.AppCompatImageButton"
|
||||||
|
const val FULLY_QUALIFIED_APP_COMPAT_VIEW_CLASS =
|
||||||
|
"androidx.appcompat.widget.AppCompatImageView"
|
||||||
|
const val APP_COMPAT_IMAGE_BUTTON = "AppCompatImageButton"
|
||||||
|
const val APP_COMPAT_IMAGE_VIEW = "AppCompatImageView"
|
||||||
|
|
||||||
|
const val ERROR_MESSAGE =
|
||||||
|
"Using android:tint to tint ImageView instead of app:tint with AppCompatImageView"
|
||||||
|
|
||||||
|
val ISSUE_XML_SRC_USAGE = Issue.create(
|
||||||
|
id = "AndroidSrcXmlDetector",
|
||||||
|
briefDescription = "Prohibits using android:tint in ImageViews and ImageButtons",
|
||||||
|
explanation = "ImageView (and descendants) should be tinted using app:tint",
|
||||||
|
category = Category.CORRECTNESS,
|
||||||
|
severity = Severity.ERROR,
|
||||||
|
implementation = Implementation(
|
||||||
|
ImageViewAndroidTintXmlDetector::class.java,
|
||||||
|
Scope.RESOURCE_FILE_SCOPE
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun appliesTo(folderType: ResourceFolderType): Boolean {
|
||||||
|
// Return true if we want to analyze resource files in the specified resource
|
||||||
|
// folder type. In this case we only need to analyze layout resource files.
|
||||||
|
return folderType == ResourceFolderType.LAYOUT
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getApplicableElements(): Collection<String>? {
|
||||||
|
return setOf(
|
||||||
|
FQCN_IMAGE_VIEW,
|
||||||
|
IMAGE_VIEW,
|
||||||
|
FQCN_IMAGE_BUTTON,
|
||||||
|
IMAGE_BUTTON,
|
||||||
|
FULLY_QUALIFIED_APP_COMPAT_IMAGE_BUTTON,
|
||||||
|
FULLY_QUALIFIED_APP_COMPAT_VIEW_CLASS,
|
||||||
|
APP_COMPAT_IMAGE_BUTTON,
|
||||||
|
APP_COMPAT_IMAGE_VIEW
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitElement(context: XmlContext, element: Element) {
|
||||||
|
if (!element.hasAttributeNS(SCHEMA, ATTR_TINT)) return
|
||||||
|
val node = element.getAttributeNodeNS(SCHEMA, ATTR_TINT)
|
||||||
|
|
||||||
|
context.report(
|
||||||
|
issue = ISSUE_XML_SRC_USAGE,
|
||||||
|
scope = node,
|
||||||
|
location = context.getLocation(node),
|
||||||
|
message = ERROR_MESSAGE
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
package org.mozilla.fenix.lintrules
|
||||||
|
|
||||||
|
import com.android.tools.lint.client.api.IssueRegistry
|
||||||
|
import com.android.tools.lint.detector.api.Issue
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registry which provides a list of our custom lint checks to be performed on an Android project.
|
||||||
|
*/
|
||||||
|
@Suppress("unused")
|
||||||
|
class LintIssueRegistry : IssueRegistry() {
|
||||||
|
override val api: Int = com.android.tools.lint.detector.api.CURRENT_API
|
||||||
|
override val issues: List<Issue> = listOf(
|
||||||
|
AndroidSrcXmlDetector.ISSUE_XML_SRC_USAGE,
|
||||||
|
TextViewAndroidSrcXmlDetector.ISSUE_XML_SRC_USAGE,
|
||||||
|
ImageViewAndroidTintXmlDetector.ISSUE_XML_SRC_USAGE
|
||||||
|
)
|
||||||
|
}
|
@ -0,0 +1,97 @@
|
|||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
package org.mozilla.fenix.lintrules
|
||||||
|
|
||||||
|
import com.android.SdkConstants.ATTR_DRAWABLE_BOTTOM
|
||||||
|
import com.android.SdkConstants.ATTR_DRAWABLE_END
|
||||||
|
import com.android.SdkConstants.ATTR_DRAWABLE_LEFT
|
||||||
|
import com.android.SdkConstants.ATTR_DRAWABLE_RIGHT
|
||||||
|
import com.android.SdkConstants.ATTR_DRAWABLE_START
|
||||||
|
import com.android.SdkConstants.ATTR_DRAWABLE_TOP
|
||||||
|
import com.android.SdkConstants.FQCN_TEXT_VIEW
|
||||||
|
import com.android.SdkConstants.TEXT_VIEW
|
||||||
|
import com.android.resources.ResourceFolderType
|
||||||
|
import com.android.tools.lint.detector.api.Category
|
||||||
|
import com.android.tools.lint.detector.api.Implementation
|
||||||
|
import com.android.tools.lint.detector.api.Issue
|
||||||
|
import com.android.tools.lint.detector.api.ResourceXmlDetector
|
||||||
|
import com.android.tools.lint.detector.api.Scope
|
||||||
|
import com.android.tools.lint.detector.api.Severity
|
||||||
|
import com.android.tools.lint.detector.api.XmlContext
|
||||||
|
import org.w3c.dom.Element
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A custom lint check that prohibits not using the app:srcCompat for ImageViews
|
||||||
|
*/
|
||||||
|
class TextViewAndroidSrcXmlDetector : ResourceXmlDetector() {
|
||||||
|
companion object {
|
||||||
|
const val SCHEMA = "http://schemas.android.com/apk/res/android"
|
||||||
|
|
||||||
|
const val ERROR_MESSAGE =
|
||||||
|
"Using android:drawableX to define resource instead of app:drawableXCompat"
|
||||||
|
|
||||||
|
val ISSUE_XML_SRC_USAGE = Issue.create(
|
||||||
|
id = "TextViewAndroidSrcXmlDetector",
|
||||||
|
briefDescription = "Prohibits using android namespace to define drawables in TextViews",
|
||||||
|
explanation = "TextView drawables should be declared using app:drawableXCompat",
|
||||||
|
category = Category.CORRECTNESS,
|
||||||
|
severity = Severity.ERROR,
|
||||||
|
implementation = Implementation(
|
||||||
|
TextViewAndroidSrcXmlDetector::class.java,
|
||||||
|
Scope.RESOURCE_FILE_SCOPE
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun appliesTo(folderType: ResourceFolderType): Boolean {
|
||||||
|
// Return true if we want to analyze resource files in the specified resource
|
||||||
|
// folder type. In this case we only need to analyze layout resource files.
|
||||||
|
return folderType == ResourceFolderType.LAYOUT
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getApplicableElements(): Collection<String>? {
|
||||||
|
return setOf(
|
||||||
|
FQCN_TEXT_VIEW,
|
||||||
|
TEXT_VIEW
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitElement(context: XmlContext, element: Element) {
|
||||||
|
val node = when {
|
||||||
|
element.hasAttributeNS(SCHEMA, ATTR_DRAWABLE_BOTTOM) -> element.getAttributeNodeNS(
|
||||||
|
SCHEMA,
|
||||||
|
ATTR_DRAWABLE_BOTTOM
|
||||||
|
)
|
||||||
|
element.hasAttributeNS(SCHEMA, ATTR_DRAWABLE_END) -> element.getAttributeNodeNS(
|
||||||
|
SCHEMA,
|
||||||
|
ATTR_DRAWABLE_END
|
||||||
|
)
|
||||||
|
element.hasAttributeNS(SCHEMA, ATTR_DRAWABLE_LEFT) -> element.getAttributeNodeNS(
|
||||||
|
SCHEMA,
|
||||||
|
ATTR_DRAWABLE_LEFT
|
||||||
|
)
|
||||||
|
element.hasAttributeNS(
|
||||||
|
SCHEMA,
|
||||||
|
ATTR_DRAWABLE_RIGHT
|
||||||
|
) -> element.getAttributeNodeNS(SCHEMA, ATTR_DRAWABLE_RIGHT)
|
||||||
|
element.hasAttributeNS(
|
||||||
|
SCHEMA,
|
||||||
|
ATTR_DRAWABLE_START
|
||||||
|
) -> element.getAttributeNodeNS(SCHEMA, ATTR_DRAWABLE_START)
|
||||||
|
element.hasAttributeNS(SCHEMA, ATTR_DRAWABLE_TOP) -> element.getAttributeNodeNS(
|
||||||
|
SCHEMA,
|
||||||
|
ATTR_DRAWABLE_TOP
|
||||||
|
)
|
||||||
|
else -> null
|
||||||
|
} ?: return
|
||||||
|
|
||||||
|
context.report(
|
||||||
|
issue = ISSUE_XML_SRC_USAGE,
|
||||||
|
scope = node,
|
||||||
|
location = context.getLocation(node),
|
||||||
|
message = ERROR_MESSAGE
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
include ':app'
|
include ':app'
|
||||||
|
|
||||||
include ':mozilla-detekt-rules'
|
include ':mozilla-detekt-rules'
|
||||||
|
include ':mozilla-lint-rules'
|
||||||
def log(message) {
|
def log(message) {
|
||||||
logger.lifecycle("[settings] ${message}")
|
logger.lifecycle("[settings] ${message}")
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user