-
-
Notifications
You must be signed in to change notification settings - Fork 361
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
Add Android Linting Example #3931
Open
c0d33ngr
wants to merge
40
commits into
com-lihaoyi:main
Choose a base branch
from
c0d33ngr:add-android-linting-example
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 28 commits
Commits
Show all changes
40 commits
Select commit
Hold shift + click to select a range
43ed8c7
add draft androoid linting
c0d33ngr 8bae57e
add android linting example
c0d33ngr 577375f
fix linting error in scala files
c0d33ngr 5cab0a8
Merge branch 'main' into add-android-linting-example
c0d33ngr 92a165e
Update AndroidAppModule.scala
c0d33ngr 4e82c26
update code
c0d33ngr 1d3805a
fix build error
c0d33ngr bd67ec5
add some changes
c0d33ngr 6588076
Merge branch 'main' into add-android-linting-example
c0d33ngr c8f33f1
udpate code structure
c0d33ngr 2c78931
udpate code
c0d33ngr 1429e01
udpate code
c0d33ngr d0c7f11
Merge branch 'main' into add-android-linting-example
c0d33ngr 9e21cee
Update build.mill
c0d33ngr 60b1cbb
Update build.mill
c0d33ngr f6420eb
Update AndroidLintModule.scala
c0d33ngr 0994b1a
fix format errors
c0d33ngr 67deba8
fix formatting
c0d33ngr 03c0381
restructure code
c0d33ngr bea5080
fix doc test errors
c0d33ngr 8c32d89
Update build.mill
c0d33ngr 1be883b
update cdoe
c0d33ngr 2cae0ea
update cdoe
c0d33ngr 428e7c0
update cdoe to add some defaults
c0d33ngr 24d91e0
update doc to clean sepcific module
c0d33ngr 3d01603
Update build.mill via GitHub web
c0d33ngr 9585600
Update AndroidLintModule.scala via GitHub web
c0d33ngr df95eb3
Update AndroidLintModule.scala via GitHub web
c0d33ngr 49d4717
update code
c0d33ngr 54ded22
fix lint and test-doc errors
c0d33ngr b910ada
add abortOnError and baseline
c0d33ngr a6e2fc5
update code
c0d33ngr 195a51e
remove old codes
c0d33ngr e7de9dc
update code
c0d33ngr 20b4107
update code
c0d33ngr b4801fe
update code
c0d33ngr 7e24224
fix error
c0d33ngr 4133561
fix incrorect java suppress lint test
c0d33ngr 44cbf19
update code
c0d33ngr 7f99fdd
update code
c0d33ngr File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
= Linting Android Projects | ||
:page-aliases: Linting_Android_Projects.adoc | ||
|
||
include::partial$gtag-config.adoc[] | ||
|
||
This page covers essential practices for maintaining and enforcing code quality | ||
in Android projects using the Mill build tool. Proper linting helps detect | ||
and resolve potential issues early, promoting better performance, security, | ||
and user experience. | ||
|
||
|
||
include::partial$example/android/javalib/3-linting.adoc[] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.helloworld.app" android:versionCode="1" android:versionName="1.0"> | ||
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="35"/> | ||
<application android:label="@string/app_name" android:theme="@android:style/Theme.Light.NoTitleBar" android:debuggable="true"> | ||
<activity android:name=".MainActivity" | ||
android:exported="true"> | ||
<intent-filter> | ||
<action android:name="android.intent.action.MAIN"/> | ||
<category android:name="android.intent.category.LAUNCHER"/> | ||
</intent-filter> | ||
</activity> | ||
</application> | ||
</manifest> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<lint> | ||
<issue id="MissingApplicationIcon" severity="ignore" /> | ||
</lint> |
4 changes: 4 additions & 0 deletions
4
example/android/javalib/3-linting/app/resources/values/colors.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<resources> | ||
<color name="white">#FFFFFF</color> | ||
<color name="text_green">#34A853</color> | ||
</resources> |
4 changes: 4 additions & 0 deletions
4
example/android/javalib/3-linting/app/resources/values/strings.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<resources> | ||
<string name="app_name">HelloWorldApp</string> | ||
<string name="hello_world">Hello, World Java!</string> | ||
</resources> |
39 changes: 39 additions & 0 deletions
39
example/android/javalib/3-linting/app/src/main/java/com/helloworld/app/MainActivity.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package com.helloworld.app; | ||
|
||
import android.app.Activity; | ||
import android.os.Bundle; | ||
import android.view.Gravity; | ||
import android.view.ViewGroup.LayoutParams; | ||
import android.widget.TextView; | ||
|
||
public class MainActivity extends Activity { | ||
@Override | ||
protected void onCreate(Bundle savedInstanceState) { | ||
super.onCreate(savedInstanceState); | ||
|
||
// Create a new TextView | ||
TextView textView = new TextView(this); | ||
|
||
// Set the text to the string resource | ||
textView.setText(getString(R.string.hello_world)); | ||
|
||
// Set text size | ||
textView.setTextSize(32); | ||
|
||
// Center the text within the view | ||
textView.setGravity(Gravity.CENTER); | ||
|
||
// Set the layout parameters (width and height) | ||
textView.setLayoutParams( | ||
new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); | ||
|
||
// Set the text color using a resource | ||
textView.setTextColor(getResources().getColor(R.color.text_green)); | ||
|
||
// Set the background color using a resource | ||
textView.setBackgroundColor(getResources().getColor(R.color.white)); | ||
|
||
// Set the content view to display the TextView | ||
setContentView(textView); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
// == Linting with Basic Config | ||
|
||
// This Mill build configuration includes a linting step, which is essential for ensuring code | ||
// quality and adhering to best practices in Android development projects. Running the `androidLintRun` task | ||
// produces a detailed HTML report by default, identifying potential issues in the code, such as performance, | ||
// security, and usability warnings. This helps maintain the health and quality of the codebase. | ||
|
||
// In this example, we set a custom config to generate the report file in txt format and not HTML. | ||
c0d33ngr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
//// SNIPPET:BUILD | ||
package build | ||
|
||
import mill._ | ||
import mill.javalib.android.{AndroidSdkModule, AndroidLintModule} | ||
|
||
// Create and configure an Android SDK module to manage Android SDK paths and tools. | ||
object androidSdkModule0 extends AndroidSdkModule { | ||
def buildToolsVersion = "35.0.0" | ||
def bundleToolVersion = "1.17.2" | ||
} | ||
|
||
// Actual android application with linting config | ||
object app extends AndroidLintModule { | ||
def androidSdkModule = mill.define.ModuleRef(androidSdkModule0) | ||
|
||
// Set path to the custom `lint.xml` config file. It is usually at the root of the project | ||
def androidLintConfigPath = Task { Some(PathRef(millSourcePath / "lint.xml")) } | ||
|
||
// Set the linting report to be generated as a text file | ||
def androidLintReportFmt = Task { "txt" } | ||
c0d33ngr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// Set path to generated `.jar` files in this case (or `.class` files) | ||
def classPath = Task.Source { androidJar() } | ||
c0d33ngr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// Set path to the location of the project source codes | ||
def sourcesPath = Task.Source { (millSourcePath / "src" / "main" / "java") } | ||
c0d33ngr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// Specify additional flag options for Android Lint not defined in `AndroidLintModule` | ||
def androidLintArgs: T[Seq[String]] = Task { | ||
Seq( | ||
"--classpath", | ||
classPath().path.toString, | ||
"--sources", | ||
sourcesPath().path.toString | ||
) | ||
} | ||
|
||
} | ||
|
||
/** See Also: app/AndroidManifest.xml */ | ||
|
||
// The `AndroidManifest.xml` file shown above is flawed with hardcoded string linting problem so it can be spoted by running the `androidLintRun` task. | ||
|
||
/** See Also: app/resources/values/colors.xml */ | ||
/** See Also: app/resources/values/strings.xml */ | ||
/** See Also: app/src/main/java/com/helloworld/app/MainActivity.java */ | ||
/** See Also: app/lint.xml */ | ||
|
||
// The `lint.xml` file shown above ignores the `MissingApplicationIcon` error in the code as | ||
// the project is for demostration. There are no icons for the demo project. | ||
|
||
////SNIPPET:END | ||
|
||
/** Usage | ||
|
||
> ./mill show app.androidLintRun # Display full path to the linting report in text file | ||
".../out/app/androidLintRun.dest/report.txt" | ||
|
||
> cat out/app/androidLintRun.dest/report.txt # Display content of the linting report | ||
AndroidManifest.xml:3: Error: Avoid hardcoding the debug mode; leaving it out allows debug and release builds to automatically assign one [HardcodedDebugMode] | ||
|
||
> sed -i.bak 's/ android:debuggable="true"//g' app/AndroidManifest.xml # Fix the HardcodedDebugMode warning issue from `AndroidManifest.xml` | ||
|
||
> ./mill app.androidLintRun # Rerun it for new changes to reflect | ||
|
||
> cat out/app/androidLintRun.dest/report.txt # Check the content of report again | ||
No issues found. | ||
|
||
*/ | ||
|
||
// == Linting with Custom Configurations | ||
|
||
// The commands below set the serverity level of `MissingApplicationIcon` to `warning` in the `lint.xml` file that was shown above | ||
// and run the `androidLintRun` task. Some output of the changes is shown below. | ||
|
||
/** Usage | ||
|
||
> sed -i.bak 's/severity="ignore"/severity="warning"/g' app/lint.xml # Set `MissingApplicationIcon` severity level to warning | ||
c0d33ngr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
> ./mill app.androidLintRun # Rerun it for new changes to reflect | ||
|
||
> cat out/app/androidLintRun.dest/report.txt # Output the changes in the report | ||
AndroidManifest.xml:3: Warning: Should explicitly set android:icon, there is no default [MissingApplicationIcon] | ||
|
||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -339,4 +339,5 @@ trait AndroidAppModule extends JavaModule { | |
|
||
PathRef(keystoreFile) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package mill.javalib.android | ||
|
||
import mill._ | ||
import mill.api.PathRef | ||
import mill.javalib.android.AndroidAppModule | ||
|
||
/** | ||
* Android Lint Module for integrating the Android Lint tool in a Mill build. | ||
* | ||
* This module provides configuration options for executing Android Lint, including setting paths, | ||
* specifying lint rules, managing reports, and more. | ||
*/ | ||
@mill.api.experimental | ||
trait AndroidLintModule extends AndroidAppModule { | ||
c0d33ngr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/** | ||
* Specifies the file format of lint report. Available file formats are "html", "xml", "txt" and "sarif". | ||
* Specifies additional arguments for the Android Lint tool. | ||
* Allows for complete customization of the lint command. | ||
*/ | ||
def androidLintReportFmt: T[String] = Task { "html" } | ||
|
||
/** | ||
* Specifies the lint configuration XML file path. This allows setting custom lint rules or modifying existing ones. | ||
*/ | ||
def androidLintConfigPath: T[Option[PathRef]] = Task { None } | ||
c0d33ngr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/** | ||
* Specifies additional arguments for the Android Lint tool. | ||
* Allows for complete customization of the lint command. | ||
*/ | ||
def androidLintArgs: T[Seq[String]] = Task { Seq.empty[String] } | ||
|
||
/** | ||
* Runs the Android Lint tool to generate a report on code quality issues. | ||
* | ||
* This method utilizes Android Lint, a tool provided by the Android SDK, | ||
* to analyze the source code for potential bugs, performance issues, and | ||
* best practices compliance. It generates a report in the specified format. | ||
* | ||
* The lint tool requires the Android SDK's command-line tools to be installed. | ||
* The report is saved in the task's destination directory as "report.html". | ||
* | ||
* For more details on the Android Lint tool, refer to: | ||
* [[https://developer.android.com/studio/write/lint]] | ||
*/ | ||
def androidLintRun: T[PathRef] = Task.Command { | ||
|
||
val format = androidLintReportFmt() | ||
val lintReport: os.Path = T.dest / s"report.$format" | ||
|
||
// Map the report format to the corresponding lint command flag | ||
val lintReportFlag = format match { | ||
case "html" => "--html" | ||
case "txt" => "--text" | ||
case "xml" => "--xml" | ||
case "sarif" => "--sarif" | ||
case _ => throw new Exception(s"Unsupported report format: $format") | ||
} | ||
|
||
// Prepare the lint configuration argument if the config path is set | ||
val configArg = androidLintConfigPath().map(config => | ||
Seq("--config", config.path.toString) | ||
).getOrElse(Seq.empty) | ||
|
||
os.call( | ||
Seq( | ||
androidSdkModule().cmdlineToolsPath().path.toString + "/lint", | ||
millSourcePath.toString, | ||
lintReportFlag.toString, | ||
lintReport.toString | ||
) ++ configArg ++ androidLintArgs() | ||
) | ||
|
||
PathRef(lintReport) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
probably a change to rollback? seems like this was a separator
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.
please I do not fully understand what you meant here