-
-
Notifications
You must be signed in to change notification settings - Fork 350
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
base: main
Are you sure you want to change the base?
Changes from all commits
43ed8c7
8bae57e
577375f
5cab0a8
92a165e
4e82c26
1d3805a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
= 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. | ||
|
||
|
||
== Linting with Android cmdline lint tool | ||
|
||
include::partial$example/javalib/android/2-linting.adoc[] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.helloworld.app"> | ||
<uses-sdk android:minSdkVersion="9"/> | ||
<uses-sdk android:targetSdkVersion="35"/> | ||
<application android:label="Hello World" 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> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package com.helloworld.app; | ||
|
||
import android.app.Activity; | ||
import android.os.Bundle; | ||
import android.view.View; | ||
import android.widget.TextView; | ||
import android.view.ViewGroup.LayoutParams; | ||
import android.view.Gravity; | ||
|
||
|
||
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 "Hello, World!" | ||
textView.setText("Hello, World!"); | ||
|
||
// Set text size | ||
textView.setTextSize(32); | ||
|
||
// Center the text within the view | ||
textView.setGravity(Gravity.CENTER); | ||
|
||
// Set layout parameters (width and height) | ||
textView.setLayoutParams(new LayoutParams( | ||
LayoutParams.MATCH_PARENT, | ||
LayoutParams.MATCH_PARENT)); | ||
|
||
// Set the content view to display the TextView | ||
setContentView(textView); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
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" | ||
} | ||
|
||
// Actual android application | ||
object app extends AndroidLintModule { | ||
def androidSdkModule = mill.define.ModuleRef(androidSdkModule0) | ||
} | ||
|
||
/** See Also: app/AndroidManifest.xml */ | ||
/** See Also: app/src/main/java/com/helloworld/app/MainActivity.java */ | ||
|
||
/** Usage | ||
|
||
> ./mill show app.androidLint # Display full path to the linting report in HTML | ||
".../out/app/androidLint.dest/report.html" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should use |
||
|
||
*/ | ||
|
||
// 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 `androidLint` task | ||
// produces a detailed HTML report identifying potential issues in the code, such as performance, | ||
// security, and usability warnings. This helps maintain the health and quality of the codebase. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -254,4 +254,5 @@ trait AndroidAppModule extends JavaModule { | |
|
||
PathRef(keystoreFile) | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package mill.javalib.android | ||
|
||
import mill._ | ||
import mill.api.PathRef | ||
import mill.scalalib.JavaModule | ||
import mill.javalib.android.AndroidSdkModule | ||
|
||
/** | ||
* 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 AndroidSdkModule with JavaModule { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are we inheriting from both |
||
|
||
/** | ||
* Path to the project for which lint should run. | ||
*/ | ||
def projectPath: T[PathRef] = Task.Source { millSourcePath } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need this? Or can we just use |
||
|
||
/** | ||
* Specifies the file format of lint report. | ||
*/ | ||
def lintReportFormat: T[String] = Task { "html" } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The comment should list the possible formats we are aware of |
||
|
||
/** | ||
* Specifies the lint configuration XML file path. This allows setting custom lint rules or modifying existing ones. | ||
*/ | ||
def lintConfigPath: T[Option[PathRef]] = Task { None } | ||
|
||
/** | ||
* Enable or disable warnings in the lint report. | ||
*/ | ||
def warningsAsErrors: T[Boolean] = Task { false } | ||
|
||
/** | ||
* Additional options for lint (e.g., enabling/disabling specific checks). | ||
*/ | ||
def lintOptions: T[Seq[String]] = Task { Seq("--check", "NewApi,InlinedApi") } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All tasks in this module should be prefixed by |
||
|
||
/** | ||
* 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 an HTML report with the analysis | ||
* results for review. | ||
* | ||
* 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 androidLint: T[PathRef] = Task { | ||
|
||
val format = lintReportFormat() | ||
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 _ => throw new Exception(s"Unsupported report format: $format") | ||
} | ||
|
||
os.call( | ||
Seq( | ||
cmdlineToolsPath().path.toString + "/lint", | ||
lintReportFlag, | ||
lintReport.toString, | ||
projectPath.toString | ||
) | ||
) | ||
|
||
PathRef(lintReport) | ||
} | ||
|
||
} |
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.
Let's include an example custom lint configuration here so people know what it looks like