mirror of
https://github.com/oxen-io/session-android.git
synced 2025-06-08 07:18:33 +00:00
Add custom lint rule project.
This commit is contained in:
parent
7f17b66a6c
commit
456857bbbd
@ -255,6 +255,8 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
lintChecks project(':lintchecks')
|
||||||
|
|
||||||
implementation 'androidx.appcompat:appcompat:1.1.0'
|
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||||
implementation 'androidx.recyclerview:recyclerview:1.0.0'
|
implementation 'androidx.recyclerview:recyclerview:1.0.0'
|
||||||
implementation 'com.google.android.material:material:1.1.0'
|
implementation 'com.google.android.material:material:1.1.0'
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
<issue id="ButtonOrder" severity="error" />
|
<issue id="ButtonOrder" severity="error" />
|
||||||
<issue id="ExtraTranslation" severity="warning" />
|
<issue id="ExtraTranslation" severity="warning" />
|
||||||
|
|
||||||
|
<!-- Custom lints -->
|
||||||
|
<issue id="LogNotSignal" severity="warning" />
|
||||||
|
|
||||||
<issue id="RestrictedApi" severity="error">
|
<issue id="RestrictedApi" severity="error">
|
||||||
<ignore path="*/org/thoughtcrime/securesms/mediasend/camerax/VideoCapture.java" />
|
<ignore path="*/org/thoughtcrime/securesms/mediasend/camerax/VideoCapture.java" />
|
||||||
<ignore path="*/org/thoughtcrime/securesms/mediasend/camerax/CameraXModule.java" />
|
<ignore path="*/org/thoughtcrime/securesms/mediasend/camerax/CameraXModule.java" />
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package org.thoughtcrime.securesms.logging;
|
package org.thoughtcrime.securesms.logging;
|
||||||
|
|
||||||
public class AndroidLogger extends Log.Logger {
|
import android.annotation.SuppressLint;
|
||||||
|
|
||||||
|
@SuppressLint("LogNotSignal")
|
||||||
|
public final class AndroidLogger extends Log.Logger {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void v(String tag, String message, Throwable t) {
|
public void v(String tag, String message, Throwable t) {
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
package org.thoughtcrime.securesms.logging;
|
package org.thoughtcrime.securesms.logging;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
|
||||||
import androidx.annotation.MainThread;
|
import androidx.annotation.MainThread;
|
||||||
|
|
||||||
public class Log {
|
@SuppressLint("LogNotSignal")
|
||||||
|
public final class Log {
|
||||||
|
|
||||||
private static Logger[] loggers;
|
private static Logger[] loggers;
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package org.thoughtcrime.securesms.logging;
|
package org.thoughtcrime.securesms.logging;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import androidx.annotation.AnyThread;
|
import androidx.annotation.AnyThread;
|
||||||
import androidx.annotation.WorkerThread;
|
import androidx.annotation.WorkerThread;
|
||||||
@ -21,7 +22,8 @@ import java.util.concurrent.CountDownLatch;
|
|||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
public class PersistentLogger extends Log.Logger {
|
@SuppressLint("LogNotSignal")
|
||||||
|
public final class PersistentLogger extends Log.Logger {
|
||||||
|
|
||||||
private static final String TAG = PersistentLogger.class.getSimpleName();
|
private static final String TAG = PersistentLogger.class.getSimpleName();
|
||||||
|
|
||||||
|
20
lintchecks/build.gradle
Normal file
20
lintchecks/build.gradle
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
apply plugin: 'java-library'
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
google()
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compileOnly 'com.android.tools.lint:lint-api:26.6.3'
|
||||||
|
compileOnly 'com.android.tools.lint:lint-checks:26.6.3'
|
||||||
|
|
||||||
|
testImplementation 'com.android.tools.lint:lint-tests:26.6.3'
|
||||||
|
testImplementation 'junit:junit:4.12'
|
||||||
|
}
|
||||||
|
|
||||||
|
jar {
|
||||||
|
manifest {
|
||||||
|
attributes('Lint-Registry-v2': 'org.signal.lint.Registry')
|
||||||
|
}
|
||||||
|
}
|
22
lintchecks/src/main/java/org/signal/lint/Registry.java
Normal file
22
lintchecks/src/main/java/org/signal/lint/Registry.java
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package org.signal.lint;
|
||||||
|
|
||||||
|
import com.android.tools.lint.client.api.IssueRegistry;
|
||||||
|
import com.android.tools.lint.detector.api.ApiKt;
|
||||||
|
import com.android.tools.lint.detector.api.Issue;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@SuppressWarnings("UnstableApiUsage")
|
||||||
|
public final class Registry extends IssueRegistry {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Issue> getIssues() {
|
||||||
|
return Collections.singletonList(SignalLogDetector.LOG_NOT_SIGNAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getApi() {
|
||||||
|
return ApiKt.CURRENT_API;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
package org.signal.lint;
|
||||||
|
|
||||||
|
import com.android.tools.lint.client.api.JavaEvaluator;
|
||||||
|
import com.android.tools.lint.detector.api.Category;
|
||||||
|
import com.android.tools.lint.detector.api.Detector;
|
||||||
|
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.LintFix;
|
||||||
|
import com.android.tools.lint.detector.api.Scope;
|
||||||
|
import com.android.tools.lint.detector.api.Severity;
|
||||||
|
import com.intellij.psi.PsiMethod;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.uast.UCallExpression;
|
||||||
|
import org.jetbrains.uast.UExpression;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@SuppressWarnings("UnstableApiUsage")
|
||||||
|
public final class SignalLogDetector extends Detector implements Detector.UastScanner {
|
||||||
|
|
||||||
|
static final Issue LOG_NOT_SIGNAL = Issue.create("LogNotSignal",
|
||||||
|
"Logging call to Android Log instead of Signal's Logger",
|
||||||
|
"Signal has its own logger which must be used.",
|
||||||
|
Category.MESSAGES,
|
||||||
|
5,
|
||||||
|
Severity.ERROR,
|
||||||
|
new Implementation(SignalLogDetector.class, Scope.JAVA_FILE_SCOPE));
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getApplicableMethodNames() {
|
||||||
|
return Arrays.asList("v", "d", "i", "w", "e", "wtf");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitMethodCall(JavaContext context, @NotNull UCallExpression call, @NotNull PsiMethod method) {
|
||||||
|
JavaEvaluator evaluator = context.getEvaluator();
|
||||||
|
|
||||||
|
if (evaluator.isMemberInClass(method, "android.util.Log")) {
|
||||||
|
LintFix fix = quickFixIssueLog(call);
|
||||||
|
context.report(LOG_NOT_SIGNAL, call, context.getLocation(call), "Using 'android.util.Log' instead of a Signal Logger", fix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private LintFix quickFixIssueLog(@NotNull UCallExpression logCall) {
|
||||||
|
List<UExpression> arguments = logCall.getValueArguments();
|
||||||
|
String methodName = logCall.getMethodName();
|
||||||
|
UExpression tag = arguments.get(0);
|
||||||
|
|
||||||
|
String fixSource = "org.thoughtcrime.securesms.logging.Log.";
|
||||||
|
|
||||||
|
switch (arguments.size()) {
|
||||||
|
case 2:
|
||||||
|
UExpression msgOrThrowable = arguments.get(1);
|
||||||
|
fixSource += String.format("%s(%s, %s)", methodName, tag, msgOrThrowable.asSourceString());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
UExpression msg = arguments.get(1);
|
||||||
|
UExpression throwable = arguments.get(2);
|
||||||
|
fixSource += String.format("%s(%s, %s, %s)", methodName, tag, msg.asSourceString(), throwable.asSourceString());
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException("android.util.Log overloads should have 2 or 3 arguments");
|
||||||
|
}
|
||||||
|
|
||||||
|
String logCallSource = logCall.asSourceString();
|
||||||
|
LintFix.GroupBuilder fixGrouper = fix().group();
|
||||||
|
fixGrouper.add(fix().replace().text(logCallSource).shortenNames().reformat(true).with(fixSource).build());
|
||||||
|
return fixGrouper.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
package org.signal.lint;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static com.android.tools.lint.checks.infrastructure.TestFiles.java;
|
||||||
|
import static com.android.tools.lint.checks.infrastructure.TestLintTask.lint;
|
||||||
|
|
||||||
|
public final class LogDetectorTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void androidLogUsed_LogNotSignal_2_args() {
|
||||||
|
lint()
|
||||||
|
.files(
|
||||||
|
java("package foo;\n" +
|
||||||
|
"import android.util.Log;\n" +
|
||||||
|
"public class Example {\n" +
|
||||||
|
" public void log() {\n" +
|
||||||
|
" Log.d(\"TAG\", \"msg\");\n" +
|
||||||
|
" }\n" +
|
||||||
|
"}")
|
||||||
|
)
|
||||||
|
.issues(SignalLogDetector.LOG_NOT_SIGNAL)
|
||||||
|
.run()
|
||||||
|
.expect("src/foo/Example.java:5: Error: Using 'android.util.Log' instead of a Signal Logger [LogNotSignal]\n" +
|
||||||
|
" Log.d(\"TAG\", \"msg\");\n" +
|
||||||
|
" ~~~~~~~~~~~~~~~~~~~\n" +
|
||||||
|
"1 errors, 0 warnings")
|
||||||
|
.expectFixDiffs("Fix for src/foo/Example.java line 5: Replace with org.thoughtcrime.securesms.logging.Log.d(\"TAG\", \"msg\"):\n" +
|
||||||
|
"@@ -5 +5\n" +
|
||||||
|
"- Log.d(\"TAG\", \"msg\");\n" +
|
||||||
|
"+ org.thoughtcrime.securesms.logging.Log.d(\"TAG\", \"msg\");");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void androidLogUsed_LogNotSignal_3_args() {
|
||||||
|
lint()
|
||||||
|
.files(
|
||||||
|
java("package foo;\n" +
|
||||||
|
"import android.util.Log;\n" +
|
||||||
|
"public class Example {\n" +
|
||||||
|
" public void log() {\n" +
|
||||||
|
" Log.w(\"TAG\", \"msg\", new Exception());\n" +
|
||||||
|
" }\n" +
|
||||||
|
"}")
|
||||||
|
)
|
||||||
|
.issues(SignalLogDetector.LOG_NOT_SIGNAL)
|
||||||
|
.run()
|
||||||
|
.expect("src/foo/Example.java:5: Error: Using 'android.util.Log' instead of a Signal Logger [LogNotSignal]\n" +
|
||||||
|
" Log.w(\"TAG\", \"msg\", new Exception());\n" +
|
||||||
|
" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" +
|
||||||
|
"1 errors, 0 warnings")
|
||||||
|
.expectFixDiffs("Fix for src/foo/Example.java line 5: Replace with org.thoughtcrime.securesms.logging.Log.w(\"TAG\", \"msg\", new Exception()):\n" +
|
||||||
|
"@@ -5 +5\n" +
|
||||||
|
"- Log.w(\"TAG\", \"msg\", new Exception());\n" +
|
||||||
|
"+ org.thoughtcrime.securesms.logging.Log.w(\"TAG\", \"msg\", new Exception());");
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,6 @@
|
|||||||
include ':app', ':libsignal-service'
|
include ':app'
|
||||||
|
include ':libsignal-service'
|
||||||
|
include ':lintchecks'
|
||||||
|
|
||||||
project(':app').name = 'Signal-Android'
|
project(':app').name = 'Signal-Android'
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user