Skip to content

Add sample for Android Studio 3.x #10

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

Merged
merged 1 commit into from
Sep 12, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 5 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Custom Lint Rules
============
=================

The [Android `lint` tool](http://developer.android.com/tools/help/lint.html) is a static code
analysis tool that checks your Android project source files for potential bugs and optimization
Expand Down Expand Up @@ -31,31 +31,15 @@ git clone https://github.com/googlesamples/android-custom-lint-rules.git
cd android-custom-lint-rules
```

##### Build the validator
##### Build the code

`./gradlew build`

##### Copy to the lint directory

`cp ./build/libs/android-custom-lint-rules.jar ~/.android/lint/`

##### Verify whether the issues are registered with lint

`lint --show MainActivityDetector`

##### Run lint

`./gradlew lint`

> Note: If you can't run `lint` directly, you may want to include android tools `PATH` in your
`~/.bash_profile`.
> (i.e. `PATH=$PATH:~/Library/Android/sdk/tools`)
>
> Then run `source ~/.bash_profile`.
For Android Studio 3.x and above, use the sample in `android-studio-3`.
If you are targeting Android Studio 2.x and older, use the sample in `android-studio-2`.

Support
-------

- The "lint-dev" Google group: https://groups.google.com/forum/#!forum/lint-dev
- Google+ Community: https://plus.google.com/communities/105153134372062985968
- Stack Overflow: http://stackoverflow.com/questions/tagged/android

Expand Down
33 changes: 33 additions & 0 deletions android-studio-2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
See README.md in the parent directory for general information.

Getting Started
---------------

##### Fetch code

```
git clone https://github.com/googlesamples/android-custom-lint-rules.git
cd android-custom-lint-rules
```

##### Build the validator

`./gradlew build`

##### Copy to the lint directory

`cp ./build/libs/android-custom-lint-rules.jar ~/.android/lint/`

##### Verify whether the issues are registered with lint

`lint --show MainActivityDetector`

##### Run lint

`./gradlew lint`

> Note: If you can't run `lint` directly, you may want to include android tools `PATH` in your
`~/.bash_profile`.
> (i.e. `PATH=$PATH:~/Library/Android/sdk/tools`)
>
> Then run `source ~/.bash_profile`.
2 changes: 1 addition & 1 deletion build.gradle → android-studio-2/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ dependencies {

jar {
manifest {
attributes("Lint-Registry-v2": "com.example.google.lint.MyIssueRegistry")
attributes("Lint-Registry": "com.example.google.lint.MyIssueRegistry")
}
}

Expand Down
File renamed without changes.
File renamed without changes.
48 changes: 48 additions & 0 deletions android-studio-3/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Sample Lint Checks

This project shows how Android Studio 3 (beta 5 and later) handles packaging
of lint rules.

## Lint Check Jar Library

First, there's the lint check implementation itself. That's done in the
"checks" project, which just applies the Gradle "java" plugin, and
that project produces a jar. Note that the dependencies for the lint
check project (other than its testing dependencies) must all be "compileOnly":

dependencies {
compileOnly "com.android.tools.lint:lint-api:$lintVersion"
compileOnly "com.android.tools.lint:lint-checks:$lintVersion"
...

## Lint Check AAR Library

Next, there's a separate Android library project, called "library". This
library doesn't have any code on its own (though it could). However,
in its build.gradle, it specifies this:

dependencies {
lintChecks project(':checks')
}

This tells the Gradle plugin to take the output from the "checks" project
and package that as a "lint.jar" payload inside this library's AAR file.
When that's done, any other projects that depends on this library will
automatically be using the lint checks.

## App Modules

Note that you don't have to go through the extra "library indirection"
if you have a lint check that you only want to apply to one or more
app modules. You can simply include the `lintChecks` dependency as shown
above there as well, and then lint will include these rules when analyzing
the project.

## Lint Version

The lint version of the libraries (specified in this project as the
`lintVersion` variable in build.gradle) should be the same version
that is used by the Gradle plugin.

If the Gradle plugin version is *X*.*Y*.*Z*, then the Lint library
version is *X+23*.*Y*.*Z*.
30 changes: 30 additions & 0 deletions android-studio-3/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
ext {
gradlePluginVersion = '3.0.0-beta5'
lintVersion = '26.0.0-beta5'
}

repositories {
google()
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle:$gradlePluginVersion"

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}

allprojects {
repositories {
google()
jcenter()
}
}

task clean(type: Delete) {
delete rootProject.buildDir
}
1 change: 1 addition & 0 deletions android-studio-3/checks/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
21 changes: 21 additions & 0 deletions android-studio-3/checks/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
apply plugin: 'java-library'

dependencies {
compileOnly "com.android.tools.lint:lint-api:$lintVersion"
compileOnly "com.android.tools.lint:lint-checks:$lintVersion"
testCompile "junit:junit:4.12"
testCompile "com.android.tools.lint:lint:$lintVersion"
testCompile "com.android.tools.lint:lint-tests:$lintVersion"
testCompile "com.android.tools:testutils:$lintVersion"
}

sourceCompatibility = "1.8"
targetCompatibility = "1.8"

jar {
manifest {
// Only use the "-v2" key here if your checks have been updated to the
// new 3.0 APIs (including UAST)
attributes("Lint-Registry-v2": "com.example.lint.checks.SampleIssueRegistry")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.lint.checks;

import com.android.tools.lint.client.api.UElementHandler;
import com.android.tools.lint.detector.api.Category;
import com.android.tools.lint.detector.api.Detector;
import com.android.tools.lint.detector.api.Detector.UastScanner;
import com.android.tools.lint.detector.api.Implementation;
import com.android.tools.lint.detector.api.Issue;
import com.android.tools.lint.detector.api.JavaContext;
import com.android.tools.lint.detector.api.Scope;
import com.android.tools.lint.detector.api.Severity;

import org.jetbrains.uast.UElement;
import org.jetbrains.uast.ULiteralExpression;
import org.jetbrains.uast.UastLiteralUtils;

import java.util.Collections;
import java.util.List;

/**
* Sample detector showing how to analyze Kotlin/Java code.
* This example flags all string literals in the code that contain
* the word "lint".
*/
public class SampleCodeDetector extends Detector implements UastScanner {
/** Issue describing the problem and pointing to the detector implementation */
public static final Issue ISSUE = Issue.create(
// ID: used in @SuppressLint warnings etc
"ShortUniqueId",

// Title -- shown in the IDE's preference dialog, as category headers in the
// Analysis results window, etc
"Lint Mentions",

// Full explanation of the issue; you can use some markdown markup such as
// `monospace`, *italic*, and **bold**.
"This check highlights string literals in code which mentions " +
"the word `lint`. Blah blah blah.\n" +
"\n" +
"Another paragraph here.\n",
Category.CORRECTNESS,
6,
Severity.WARNING,
new Implementation(
SampleCodeDetector.class,
Scope.JAVA_FILE_SCOPE));

@Override
public List<Class<? extends UElement>> getApplicableUastTypes() {
return Collections.singletonList(ULiteralExpression.class);
}

@Override
public UElementHandler createUastHandler(JavaContext context) {
// Not: Visiting UAST nodes is a pretty general purpose mechanism;
// Lint has specialized support to do common things like "visit every class
// that extends a given super class or implements a given interface", and
// "visit every call site that calls a method by a given name" etc.
// Take a careful look at UastScanner and the various existing lint check
// implementations before doing things the "hard way".
// Also be aware of context.getJavaEvaluator() which provides a lot of
// utility functionality.
return new UElementHandler() {
@Override
public void visitLiteralExpression(ULiteralExpression expression) {
String string = UastLiteralUtils.getValueIfStringLiteral(expression);
if (string == null) {
return;
}

if (string.contains("lint") && string.matches(".*\\blint\\b.*")) {
context.report(ISSUE, expression, context.getLocation(expression),
"This code mentions `lint`: **Congratulations**");
}
}
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.lint.checks;

import com.android.tools.lint.client.api.IssueRegistry;
import com.android.tools.lint.detector.api.Issue;

import java.util.Collections;
import java.util.List;

/*
* The list of issues that will be checked when running <code>lint</code>.
*/
public class SampleIssueRegistry extends IssueRegistry {
@Override
public List<Issue> getIssues() {
return Collections.singletonList(SampleCodeDetector.ISSUE);
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.lint.checks;

import com.android.tools.lint.checks.infrastructure.LintDetectorTest;
import com.android.tools.lint.detector.api.Detector;
import com.android.tools.lint.detector.api.Issue;

import java.util.Collections;
import java.util.List;

public class SampleCodeDetectorTest extends LintDetectorTest {
public void testBasic() {
lint().files(
java("" +
"package test.pkg;\n" +
"public class TestClass1 {\n" +
" // In a comment, mentioning \"lint\" has no effect\n" +
" private static String s1 = \"Ignore non-word usages: linting\";\n" +
" private static String s2 = \"Let's say it: lint\";\n" +
"}"))
.run()
.expect("src/test/pkg/TestClass1.java:5: Warning: This code mentions lint: Congratulations [ShortUniqueId]\n" +
" private static String s2 = \"Let's say it: lint\";\n" +
" ~~~~~~~~~~~~~~~~~~~~\n" +
"0 errors, 1 warnings\n");
}

@Override
protected Detector getDetector() {
return new SampleCodeDetector();
}

@Override
protected List<Issue> getIssues() {
return Collections.singletonList(SampleCodeDetector.ISSUE);
}
}
17 changes: 17 additions & 0 deletions android-studio-3/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Project-wide Gradle settings.

# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.

# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html

# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m

# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
Binary file not shown.
6 changes: 6 additions & 0 deletions android-studio-3/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#Fri Sep 01 06:52:38 PDT 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
Loading