Skip to content

Commit f7071eb

Browse files
Preparing first release (#14)
* Change all Gradle configuration options until I could make ./gradlew :app:lint work. * Write a README describing how to use the project. * Write a CONTRIBUTING file for people to contribute freely. * Include codecov configuration (with jacoco) now that the project is public.
1 parent bd3c0ec commit f7071eb

File tree

16 files changed

+175
-43
lines changed

16 files changed

+175
-43
lines changed

.github/CONTRIBUTING.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
Contributing
2+
============
3+
4+
:+1::tada: First off, thanks for taking the time to contribute! :tada::+1:
5+
6+
If you would like to contribute code to this repository you can do so through GitHub by
7+
forking the repository and sending a pull request or opening an issue.
8+
9+
When submitting code, please make every effort to follow existing conventions
10+
and style in order to keep the code as readable as possible. Please also make
11+
sure your code compiles, passes the tests and the checkstyle configured for this repository.
12+
13+
Some tips that will help you to contribute to this repository:
14+
15+
* Write clean code and test it.
16+
* Follow the repository code style.
17+
* Write descriptive commit messages.
18+
* No PR will be merged if automatic checks are not passing.
19+
* Review if your changes affects the repository documentation and update it.
20+
* Describe the PR content and don't hesitate to add comments to explain us why you've added or changed something.
21+
22+
Code of conduct
23+
---------------
24+
25+
As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
26+
27+
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
28+
29+
Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
30+
31+
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
32+
33+
This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.
34+
35+
Instances of abusive, harassing, or otherwise unacceptable behavior can be reported by sending me a message at [twitter](https://twitter.com/AtSerchinastico).
36+
37+
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org/version/1/3/0/), version 1.3.0, available at [http://contributor-covenant.org/version/1/3/0/](http://contributor-covenant.org/version/1/3/0/).

.travis.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,7 @@ android:
99
- extra
1010

1111
script:
12-
- ./gradlew check test
12+
- ./gradlew check test
13+
14+
after_success:
15+
- bash <(curl -s https://codecov.io/bash)

README.md

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,88 @@
1-
# Lin
2-
Lin is an Android Lint tool but simpler
1+
![LIN](./readme/logo.png)
2+
3+
---------------
4+
5+
[![Build Status](https://travis-ci.org/Serchinastico/Lin.svg?branch=master)](https://travis-ci.org/Serchinastico/Lin)
6+
[![codecov](https://codecov.io/gh/Serchinastico/Lin/branch/master/graph/badge.svg)](https://codecov.io/gh/Serchinastico/Lin)
7+
8+
Lin is an Android Lint tool made simpler. It has two different goals:
9+
10+
1. To create a set of highly opinionated rules to apply to your Android projects.
11+
2. To offer a Kotlin DSL to write your own rules in a much easier way.
12+
13+
## How to use
14+
15+
Add the JitPack repository to your build file:
16+
17+
```groovy
18+
allprojects {
19+
repositories {
20+
...
21+
maven { url 'https://jitpack.io' }
22+
}
23+
}
24+
```
25+
26+
### Lin-Rules
27+
28+
Add the rules module dependencies to your project and the dsl module as part of the lint classpath:
29+
30+
```groovy
31+
dependencies {
32+
lintChecks 'com.serchinastico.lin:rules:0.0.1'
33+
lintClassPath 'com.serchinastico.lin:dsl:0.0.1'
34+
}
35+
```
36+
37+
### Lin-DSL
38+
39+
If you want to write your own rules just add the dsl and annotations modules to your linting project:
40+
41+
```groovy
42+
dependencies {
43+
compileOnly 'com.serchinastico.lin:dsl:0.0.1'
44+
compileOnly 'com.serchinastico.lin:annotations:0.0.1'
45+
}
46+
```
47+
48+
## How to write your own rules
49+
50+
Lin offers a DSL (Domain Specific Language) to write your own rules easily. The API is focused on representing your rules as concisely as possible. Let's bisect an example of a rule to understand how it works:
51+
52+
```kotlin
53+
@Rule
54+
fun noElseInSwitchWithEnumOrSealed() = rule(
55+
// Define the issue:
56+
issue(
57+
// 1. What files should the rule check
58+
Scope.JAVA_FILE_SCOPE,
59+
// 2. A brief description of the issue
60+
"There should not be else/default branches on a switch statement checking for enum/sealed class values",
61+
// 3. A more in-detail explanation of why are we detecting the issue
62+
"Adding an else/default branch breaks extensibility because it won't let you know if there is a missing " +
63+
"implementation when adding new types to the enum/sealed class",
64+
// The category this issue falls into
65+
Category.CORRECTNESS
66+
)
67+
) {
68+
/* The rule definition using the DSL. Define the
69+
* AST node you want to look for and include a
70+
* suchThat definition returning true when you want
71+
* your rule to report an issue.
72+
* The best way to see what nodes you have
73+
* available is by using your IDE autocomplete
74+
* function
75+
*/
76+
switch {
77+
suchThat { node ->
78+
val classReferenceType = node.expression?.getExpressionType() ?: (return@suchThat false)
79+
80+
if (!classReferenceType.isEnum && !classReferenceType.isSealed) {
81+
return@suchThat false
82+
}
83+
84+
node.clauses.any { clause -> clause.isElseBranch }
85+
}
86+
}
87+
}
88+
```

app/build.gradle

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,14 @@ android {
2020
}
2121
}
2222

23+
configurations {
24+
lintChecks
25+
}
26+
2327
dependencies {
24-
implementation fileTree(dir: 'libs', include: ['*.jar'])
28+
lintChecks project(path: ":rules", configuration: 'lintChecks')
29+
lintClassPath project(":dsl")
30+
2531
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.10"
2632
implementation 'com.android.support:appcompat-v7:28.0.0'
2733
testImplementation 'junit:junit:4.12'
Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
11
package com.serchinastico.lin
22

3-
import android.view.View
4-
5-
class TestClass {
6-
public val view: View = View(null)
7-
}
3+
class TestClass

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ buildscript {
55
}
66
dependencies {
77
classpath 'com.android.tools.build:gradle:3.2.1'
8-
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.10"
8+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.11"
99
}
1010
}
1111

dsl/build.gradle

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
apply plugin: 'java-library'
21
apply plugin: 'kotlin'
3-
apply plugin: 'kotlin-kapt'
42

53
dependencies {
64
compileOnly 'com.android.tools.lint:lint:26.2.1'

dsl/src/main/kotlin/com/serchinastico/lin/dsl/LinDsl.kt

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -128,26 +128,6 @@ sealed class LNode<T : UElement> {
128128

129129
fun rule(issueBuilder: IssueBuilder, block: LinRule.() -> LinRule): LinRule = LinRule(issueBuilder).block()
130130

131-
fun main(args: Array<String>) {
132-
val detectorScope = Scope.JAVA_FILE_SCOPE
133-
134-
rule(
135-
issue(
136-
detectorScope,
137-
"Framework classes to get or store data should never be called from Activities, Fragments or any other" +
138-
" Android related view.",
139-
"Your Android classes should not be responsible for retrieving or storing information, that should be " +
140-
"responsibility of another classes.",
141-
Category.INTEROPERABILITY
142-
)
143-
) {
144-
file {
145-
import { suchThat { it.isFrameworkLibraryImport } }
146-
type { suchThat { node -> node.uastSuperTypes.any { it.isAndroidFrameworkType } } }
147-
}
148-
}
149-
}
150-
151131
fun issue(
152132
scope: EnumSet<Scope>,
153133
description: String,

processor/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ apply plugin: 'kotlin'
33
apply plugin: 'kotlin-kapt'
44

55
dependencies {
6-
implementation project(":annotations")
7-
implementation project(":dsl")
6+
compile project(":annotations")
7+
compile project(":dsl")
88
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.3.10"
99
implementation "com.squareup:kotlinpoet:1.0.0-RC3"
1010
implementation "com.google.auto.service:auto-service:1.0-rc4"

processor/src/main/kotlin/com/serchinastico/lin/processor/RuleProcessor.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class RuleProcessor : AbstractProcessor() {
5858

5959
val className = "${issueId}Detector"
6060
val ruleFile = FileSpec.builder(packageName, className)
61+
.addImport("com.serchinastico.lin.dsl", "report")
6162
.addType(
6263
TypeSpec.classBuilder(className)
6364
.superclass(DETECTOR_CLASS_NAME)

0 commit comments

Comments
 (0)