779 lines
23 KiB
Java
779 lines
23 KiB
Java
/*
|
|
* Copyright 2023-2024 the original author or authors.
|
|
*
|
|
* 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
|
|
*
|
|
* https://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 rife.bld.extension;
|
|
|
|
import rife.bld.BaseProject;
|
|
import rife.bld.extension.detekt.Report;
|
|
import rife.bld.extension.detekt.ReportId;
|
|
import rife.bld.operations.AbstractProcessOperation;
|
|
import rife.bld.operations.exceptions.ExitStatusException;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Collection;
|
|
import java.util.List;
|
|
import java.util.logging.Level;
|
|
import java.util.logging.Logger;
|
|
|
|
/**
|
|
* Performs static code analysis with <a href="https://detekt.dev/">Detekt</a>.
|
|
*
|
|
* @author <a href="https://erik.thauvin.net/">Erik C. Thauvin</a>
|
|
* @since 1.0
|
|
*/
|
|
public class DetektOperation extends AbstractProcessOperation<DetektOperation> {
|
|
private static final List<String> DETEKT_JARS = List.of(
|
|
"annotations-",
|
|
"contester-breakpoint-",
|
|
"detekt-",
|
|
"jcommander-",
|
|
"kotlin-compiler-embeddable-",
|
|
"kotlin-daemon-embeddable-",
|
|
"kotlin-reflect-",
|
|
"kotlin-script-runtime-",
|
|
"kotlin-stdlib-",
|
|
"kotlin-stdlib-jdk7-",
|
|
"kotlin-stdlib-jdk8-",
|
|
"kotlinx-html-jvm-",
|
|
"kotlinx-serialization-",
|
|
"sarif4k-jvm-",
|
|
"snakeyaml-engine-",
|
|
"trove4j-");
|
|
private static final Logger LOGGER = Logger.getLogger(Report.class.getName());
|
|
private final Collection<File> classpath_ = new ArrayList<>();
|
|
private final Collection<File> config_ = new ArrayList<>();
|
|
private final Collection<String> excludes_ = new ArrayList<>();
|
|
private final Collection<String> includes_ = new ArrayList<>();
|
|
private final Collection<File> input_ = new ArrayList<>();
|
|
private final Collection<File> plugins_ = new ArrayList<>();
|
|
private final Collection<Report> report_ = new ArrayList<>();
|
|
private boolean allRules_;
|
|
private boolean autoCorrect_;
|
|
private String basePath_;
|
|
private String baseline_;
|
|
private boolean buildUponDefaultConfig_;
|
|
private String configResource_;
|
|
private boolean createBaseline_;
|
|
private boolean debug_;
|
|
private boolean disableDefaultRuleSets_;
|
|
private boolean generateConfig_;
|
|
private String jdkHome_;
|
|
private String jvmTarget_;
|
|
private String languageVersion_;
|
|
private int maxIssues_;
|
|
private boolean parallel_;
|
|
private BaseProject project_;
|
|
|
|
/**
|
|
* Activates all available (even unstable) rules.
|
|
*
|
|
* @param allRules {@code true} or {@code false}
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation allRules(boolean allRules) {
|
|
allRules_ = allRules;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Allow rules to autocorrect code if they support it. The default rule
|
|
* sets do NOT support autocorrecting and won't change any line in the
|
|
* users code base. However, custom rules can be written to support
|
|
* autocorrecting. The additional 'formatting' rule set, added with
|
|
* {@link #plugins(String...) Plugins}, does support it and needs this flag.
|
|
*
|
|
* @param autoCorrect {@code true} or {@code false}
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation autoCorrect(boolean autoCorrect) {
|
|
autoCorrect_ = autoCorrect;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Specifies a directory as the base path. Currently, it impacts all file
|
|
* paths in the formatted reports. File paths in console output and txt
|
|
* report are not affected and remain as absolute paths.
|
|
*
|
|
* @param path the directory path
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation basePath(String path) {
|
|
basePath_ = path;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Specifies a directory as the base path. Currently, it impacts all file
|
|
* paths in the formatted reports. File paths in console output and txt
|
|
* report are not affected and remain as absolute paths.
|
|
*
|
|
* @param path the directory path
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation basePath(File path) {
|
|
basePath_ = path.getAbsolutePath();
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* If a baseline xml file is passed in, only new code smells not in the
|
|
* baseline are printed in the console.
|
|
*
|
|
* @param baseline the baseline xml file
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation baseline(String baseline) {
|
|
baseline_ = baseline;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* If a baseline xml file is passed in, only new code smells not in the
|
|
* baseline are printed in the console.
|
|
*
|
|
* @param baseline the baseline xml file
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation baseline(File baseline) {
|
|
baseline_ = baseline.getAbsolutePath();
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Preconfigures detekt with a bunch of rules and some opinionated defaults
|
|
* for you. Allows additional provided configurations to override the
|
|
* defaults.
|
|
*
|
|
* @param buildUponDefaultConfig {@code true} or {@code false}
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation buildUponDefaultConfig(boolean buildUponDefaultConfig) {
|
|
buildUponDefaultConfig_ = buildUponDefaultConfig;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* EXPERIMENTAL: Paths where to find user class files and jar dependencies.
|
|
* Used for type resolution.
|
|
*
|
|
* @param paths one or more files
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation classPath(File... paths) {
|
|
classpath_.addAll(List.of(paths));
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* EXPERIMENTAL: Paths where to find user class files and jar dependencies.
|
|
* Used for type resolution.
|
|
*
|
|
* @param paths one or more files
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation classPath(String... paths) {
|
|
classpath_.addAll(Arrays.stream(paths).map(File::new).toList());
|
|
return this;
|
|
}
|
|
|
|
|
|
/**
|
|
* EXPERIMENTAL: Paths where to find user class files and jar dependencies.
|
|
* Used for type resolution.
|
|
*
|
|
* @param paths the paths
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation classPath(Collection<File> paths) {
|
|
classpath_.addAll(paths);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Paths where to find user class files and jar dependencies.
|
|
*
|
|
* @return the paths
|
|
*/
|
|
public Collection<File> classPath() {
|
|
return classpath_;
|
|
}
|
|
|
|
/**
|
|
* Paths to the config files ({@code path/to/config.yml}).
|
|
*
|
|
* @param configs one or more config files
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation config(File... configs) {
|
|
config_.addAll(List.of(configs));
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Paths to the config files ({@code path/to/config.yml}).
|
|
*
|
|
* @param configs one or more config files
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation config(String... configs) {
|
|
config_.addAll(Arrays.stream(configs).map(File::new).toList());
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Paths to the config files ({@code path/to/config.yml}).
|
|
*
|
|
* @param configs the config files
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation config(Collection<File> configs) {
|
|
config_.addAll(configs);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Paths to config files.
|
|
*
|
|
* @return the config files paths.
|
|
*/
|
|
public Collection<File> config() {
|
|
return config_;
|
|
}
|
|
|
|
/**
|
|
* Path to the config resource on detekt's classpath ({@code path/to/config.yml}).
|
|
*
|
|
* @param resource the config resource path
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation configResource(String resource) {
|
|
configResource_ = resource;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Path to the config resource on detekt's classpath ({@code path/to/config.yml}).
|
|
*
|
|
* @param resource the config resource path
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation configResource(File resource) {
|
|
configResource_ = resource.getAbsolutePath();
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Treats current analysis findings as a smell baseline for future detekt
|
|
* runs.
|
|
*
|
|
* @param createBaseline {@code true} or {@code false}
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation createBaseline(boolean createBaseline) {
|
|
createBaseline_ = createBaseline;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Prints extra information about configurations and extensions.
|
|
*
|
|
* @param debug {@code true} or {@code false}
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation debug(boolean debug) {
|
|
debug_ = debug;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Disables default rule sets.
|
|
*
|
|
* @param disable {@code true} or {@code false}
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation disableDefaultRuleSets(boolean disable) {
|
|
disableDefaultRuleSets_ = disable;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Globbing patterns describing paths to exclude from the analysis.
|
|
*
|
|
* @param patterns one or more pattern
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation excludes(String... patterns) {
|
|
excludes_.addAll(List.of(patterns));
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Globbing patterns describing paths to exclude from the analysis.
|
|
*
|
|
* @param patterns a collection of patterns
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation excludes(Collection<String> patterns) {
|
|
excludes_.addAll(patterns);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Returns the globbing patterns describing paths to exclude from the analysis.
|
|
*
|
|
* @return the globbing patterns
|
|
*/
|
|
public Collection<String> excludes() {
|
|
return excludes_;
|
|
}
|
|
|
|
/**
|
|
* Performs the operation.
|
|
*
|
|
* @throws InterruptedException when the operation was interrupted
|
|
* @throws IOException when an exception occurred during the execution of the process
|
|
* @throws ExitStatusException when the exit status was changed during the operation
|
|
*/
|
|
@Override
|
|
public void execute() throws IOException, InterruptedException, ExitStatusException {
|
|
if (project_ == null) {
|
|
if (LOGGER.isLoggable(Level.SEVERE) && !silent()) {
|
|
LOGGER.severe("A project must be specified.");
|
|
}
|
|
throw new ExitStatusException(ExitStatusException.EXIT_FAILURE);
|
|
} else {
|
|
super.execute();
|
|
if (successful_ && LOGGER.isLoggable(Level.INFO) && !silent()){
|
|
if (createBaseline_) {
|
|
LOGGER.info("Detekt baseline generated successfully: "
|
|
+ "file://" + new File(baseline_).toURI().getPath());
|
|
} else {
|
|
LOGGER.info("Detekt operation finished successfully.");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Part of the {@link #execute} operation, constructs the command list
|
|
* to use for building the process.
|
|
*/
|
|
@Override
|
|
protected List<String> executeConstructProcessCommandList() {
|
|
final List<String> args = new ArrayList<>();
|
|
if (project_ != null) {
|
|
args.add(javaTool());
|
|
args.add("-cp");
|
|
args.add(getDetektJarList(project_.libBldDirectory()));
|
|
args.add("io.gitlab.arturbosch.detekt.cli.Main");
|
|
|
|
// all-rules
|
|
if (allRules_) {
|
|
args.add("--all-rules");
|
|
}
|
|
|
|
// auto-correct
|
|
if (autoCorrect_) {
|
|
args.add("--auto-correct");
|
|
}
|
|
|
|
// base-path
|
|
if (isNotBlank(basePath_)) {
|
|
args.add("--base-path");
|
|
args.add(basePath_);
|
|
}
|
|
|
|
// baseline
|
|
if (isNotBlank(baseline_)) {
|
|
args.add("--baseline");
|
|
args.add(baseline_);
|
|
}
|
|
|
|
// build-upon-default-config
|
|
if (buildUponDefaultConfig_) {
|
|
args.add("--build-upon-default-config");
|
|
}
|
|
|
|
// classpath
|
|
if (!classpath_.isEmpty()) {
|
|
args.add("--classpath");
|
|
args.add(String.join(File.pathSeparator, classpath_.stream().map(File::getAbsolutePath).toList()));
|
|
}
|
|
|
|
// config
|
|
if (!config_.isEmpty()) {
|
|
args.add("-config");
|
|
args.add(String.join(";", config_.stream().map(File::getAbsolutePath).toList()));
|
|
}
|
|
|
|
// config-resource
|
|
if (isNotBlank(configResource_)) {
|
|
args.add("--config-resource");
|
|
args.add(configResource_);
|
|
}
|
|
|
|
// create-baseline
|
|
if (createBaseline_) {
|
|
args.add("--create-baseline");
|
|
}
|
|
|
|
// debug
|
|
if (debug_) {
|
|
args.add("--debug");
|
|
}
|
|
|
|
// disable-default-rulesets
|
|
if (disableDefaultRuleSets_) {
|
|
args.add("--disable-default-rulesets");
|
|
}
|
|
|
|
// excludes
|
|
if (!excludes_.isEmpty()) {
|
|
args.add("--excludes");
|
|
args.add(String.join(",", excludes_));
|
|
}
|
|
|
|
// generate-config
|
|
if (generateConfig_) {
|
|
args.add("--generate-config");
|
|
}
|
|
|
|
// includes
|
|
if (!includes_.isEmpty()) {
|
|
args.add("--includes");
|
|
args.add(String.join(",", includes_));
|
|
}
|
|
|
|
// input
|
|
if (!input_.isEmpty()) {
|
|
args.add("--input");
|
|
args.add(String.join(",", input_.stream().map(File::getAbsolutePath).toList()));
|
|
}
|
|
|
|
// jdk-home
|
|
if (isNotBlank(jdkHome_)) {
|
|
args.add("--jdk-home");
|
|
args.add(jdkHome_);
|
|
}
|
|
|
|
// jvm-target
|
|
if (isNotBlank(jvmTarget_)) {
|
|
args.add("--jvm-target");
|
|
args.add(jvmTarget_);
|
|
}
|
|
|
|
// language-version
|
|
if (isNotBlank(languageVersion_)) {
|
|
args.add("--language-version");
|
|
args.add(languageVersion_);
|
|
}
|
|
|
|
// max-issues
|
|
if (maxIssues_ > 0) {
|
|
args.add("--max-issues");
|
|
args.add(String.valueOf(maxIssues_));
|
|
}
|
|
|
|
// parallel
|
|
if (parallel_) {
|
|
args.add("--parallel");
|
|
}
|
|
|
|
// plugins
|
|
if (!plugins_.isEmpty()) {
|
|
args.add("--plugins");
|
|
args.add(String.join(",", plugins_.stream().map(File::getAbsolutePath).toList()));
|
|
}
|
|
|
|
// report
|
|
if (!report_.isEmpty()) {
|
|
report_.forEach(it -> {
|
|
args.add("--report");
|
|
args.add(it.id().name().toLowerCase() + ":" + it.path());
|
|
});
|
|
}
|
|
|
|
if (LOGGER.isLoggable(Level.FINE) && !silent()) {
|
|
LOGGER.fine(String.join(" ", args.stream().filter(this::isNotBlank).toList()));
|
|
}
|
|
}
|
|
|
|
return args;
|
|
}
|
|
|
|
/**
|
|
* Configures the operation from a {@link BaseProject}.
|
|
* <p>
|
|
* Sets the following:
|
|
* <ul>
|
|
* <li>{@link #baseline baseline} to {@code detekt-baseline.xml}, if it exists</li>
|
|
* <li>{@link #excludes excludes} to exclude {@code build} and {@code resources} directories</li>
|
|
* </ul>
|
|
*
|
|
* @param project the project to configure the operation from
|
|
* @return this operation instance
|
|
*/
|
|
@Override
|
|
public DetektOperation fromProject(BaseProject project) {
|
|
project_ = project;
|
|
var baseline = new File(project.workDirectory(), "detekt-baseline.xml");
|
|
if (baseline.exists()) {
|
|
baseline_ = baseline.getAbsolutePath();
|
|
}
|
|
excludes(".*/build/.*", ".*/resources/.*");
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Export default config. Path can be specified with {@link #config config} option.
|
|
* <p>
|
|
* Default path: {@code default-detekt-config.yml}
|
|
*
|
|
* @param generate {@code true} or {@code false}
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation generateConfig(boolean generate) {
|
|
generateConfig_ = generate;
|
|
return this;
|
|
}
|
|
|
|
// Retrieves the matching JARs files from the given directory.
|
|
private String getDetektJarList(File directory) {
|
|
var jars = new ArrayList<String>();
|
|
|
|
if (directory.isDirectory()) {
|
|
var files = directory.listFiles();
|
|
if (files != null) {
|
|
for (var f : files) {
|
|
if (!f.getName().endsWith("-sources.jar") && !f.getName().endsWith("-javadoc.jar")) {
|
|
for (var m : DETEKT_JARS) {
|
|
if (f.getName().startsWith(m)) {
|
|
jars.add(f.getAbsolutePath());
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return String.join(":", jars);
|
|
}
|
|
|
|
/**
|
|
* Globbing patterns describing paths to include in the analysis. Useful in
|
|
* combination with {@link #excludes() excludes} patterns.
|
|
*
|
|
* @param patterns one or more patterns
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation includes(String... patterns) {
|
|
includes_.addAll(List.of(patterns));
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Globbing patterns describing paths to include in the analysis. Useful in
|
|
* combination with {@link #excludes() excludes} patterns.
|
|
*
|
|
* @param patterns a collection of patterns
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation includes(Collection<String> patterns) {
|
|
includes_.addAll(patterns);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Returns the globbing patterns describing paths to include in the analysis.
|
|
*
|
|
* @return the globbing patterns
|
|
*/
|
|
public Collection<String> includes() {
|
|
return includes_;
|
|
}
|
|
|
|
/**
|
|
* Input paths to analyze. If not specified the current working directory is used.
|
|
*
|
|
* @param paths the paths
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation input(Collection<File> paths) {
|
|
input_.addAll(paths);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Input paths to analyze. If not specified the current working directory is used.
|
|
*
|
|
* @param paths one or more paths
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation input(String... paths) {
|
|
input_.addAll(Arrays.stream(paths).map(File::new).toList());
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Input paths to analyze. If not specified the current working directory is used.
|
|
*
|
|
* @param paths one or more paths
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation input(File... paths) {
|
|
input_.addAll(List.of(paths));
|
|
return this;
|
|
}
|
|
|
|
|
|
/**
|
|
* Returns the input paths to analyze.
|
|
*
|
|
* @return the input paths
|
|
*/
|
|
public Collection<File> input() {
|
|
return input_;
|
|
}
|
|
|
|
/*
|
|
* Determines if a string is not blank.
|
|
*/
|
|
private boolean isNotBlank(String s) {
|
|
return s != null && !s.isBlank();
|
|
}
|
|
|
|
/**
|
|
* EXPERIMENTAL: Use a custom JDK home directory to include into the
|
|
* classpath.
|
|
*
|
|
* @param path the JDK home directory path
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation jdkHome(String path) {
|
|
jdkHome_ = path;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* EXPERIMENTAL: Target version of the generated JVM bytecode that was
|
|
* generated during compilation and is now being used for type resolution
|
|
* <p>
|
|
* Default: 1.8
|
|
*
|
|
* @param target the target version
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation jvmTarget(String target) {
|
|
jvmTarget_ = target;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* EXPERIMENTAL: Compatibility mode for Kotlin language version X.Y,
|
|
* reports errors for all language features that came out later.
|
|
* <p>
|
|
* Possible Values: [1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1]
|
|
*
|
|
* @param version the version
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation languageVersion(String version) {
|
|
languageVersion_ = version;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Return exit code 0 only when found issues count does not exceed
|
|
* specified issues count.
|
|
*
|
|
* @param max the issues code
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation maxIssues(int max) {
|
|
maxIssues_ = max;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Enables parallel compilation and analysis of source files. Do some
|
|
* benchmarks first before enabling this flag. Heuristics show performance
|
|
* benefits starting from 2000 lines of Kotlin code.
|
|
*
|
|
* @param parallel {@code true} or {@code false}
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation parallel(boolean parallel) {
|
|
parallel_ = parallel;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Extra paths to plugin jars.
|
|
*
|
|
* @param jars one or more jars
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation plugins(String... jars) {
|
|
plugins_.addAll(Arrays.stream(jars).map(File::new).toList());
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Extra paths to plugin jars.
|
|
*
|
|
* @param jars one or more jars
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation plugins(File... jars) {
|
|
plugins_.addAll(List.of(jars));
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Extra paths to plugin jars.
|
|
*
|
|
* @param jars the jars paths
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation plugins(Collection<File> jars) {
|
|
plugins_.addAll(jars);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Extra path to plugins jars.
|
|
*
|
|
* @return the jars paths
|
|
*/
|
|
public Collection<File> plugins() {
|
|
return plugins_;
|
|
}
|
|
|
|
/**
|
|
* Generates a report for given {@link ReportId report-id} and stores it on given 'path'.
|
|
*
|
|
* @param reports one or more reports
|
|
* @return this operation instance
|
|
*/
|
|
public DetektOperation report(Report... reports) {
|
|
report_.addAll(List.of(reports));
|
|
return this;
|
|
}
|
|
}
|