Skip to content

Commit

Permalink
Replace getProject() references with injected services in task implem…
Browse files Browse the repository at this point in the history
…entations where possible (#81681)

- Rework task implementations to avoid project usage at execution time
- In general usages of getProject() within a task should be avoided as it is not compatible
with gradle configuration cache. Related to #57918
  • Loading branch information
breskeby committed Feb 23, 2022
1 parent 76691bc commit c468612
Show file tree
Hide file tree
Showing 23 changed files with 445 additions and 248 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import org.gradle.api.DefaultTask;
import org.gradle.api.GradleException;
import org.gradle.api.file.FileCollection;
import org.gradle.api.file.ProjectLayout;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.provider.ListProperty;
import org.gradle.api.tasks.CacheableTask;
import org.gradle.api.tasks.IgnoreEmptyDirectories;
Expand Down Expand Up @@ -55,12 +57,42 @@
import javax.inject.Inject;
import java.io.Serializable;

import javax.inject.Inject;

/**
* Checks files for license headers..
*/
@CacheableTask
public abstract class LicenseHeadersTask extends DefaultTask {
public LicenseHeadersTask() {

private final RegularFileProperty reportFile;

private static List<License> conventionalLicenses = Arrays.asList(
// Dual SSPLv1 and Elastic
new License("DUAL", "SSPL+Elastic License", "the Elastic License 2.0 or the Server")
);

/**
* Allowed license families for this project.
*/
@Input
private List<String> approvedLicenses = new ArrayList<String>(Arrays.asList("SSPL+Elastic License", "Generated", "Vendored", "Apache LZ4-Java"));
/**
* Files that should be excluded from the license header check. Use with extreme care, only in situations where the license on the
* source file is compatible with the codebase but we do not want to add the license to the list of approved headers (to avoid the
* possibility of inadvertently using the license on our own source files).
*/
@Input
private List<String> excludes = new ArrayList<String>();

private ListProperty<License> additionalLicenses;

@Inject
public LicenseHeadersTask(ObjectFactory objectFactory, ProjectLayout projectLayout) {
additionalLicenses = objectFactory.listProperty(License.class).convention(conventionalLicenses);
reportFile = objectFactory.fileProperty().convention(
projectLayout.getBuildDirectory().file("reports/licenseHeaders/rat.xml")
);
setDescription("Checks sources for missing, incorrect, or unacceptable license headers");
}

Expand All @@ -79,14 +111,11 @@ public List<FileCollection> getJavaFiles() {
@Internal
public abstract ListProperty<FileCollection> getSourceFolders();

public File getReportFile() {
@OutputFile
public RegularFileProperty getReportFile() {
return reportFile;
}

public void setReportFile(File reportFile) {
this.reportFile = reportFile;
}

public List<String> getApprovedLicenses() {
return approvedLicenses;
}
Expand All @@ -103,29 +132,6 @@ public void setExcludes(List<String> excludes) {
this.excludes = excludes;
}

@OutputFile
private File reportFile = new File(getProject().getBuildDir(), "reports/licenseHeaders/rat.xml");

private static List<License> conventionalLicenses = Arrays.asList(
// Dual SSPLv1 and Elastic
new License("DUAL", "SSPL+Elastic License", "the Elastic License 2.0 or the Server")
);

/**
* Allowed license families for this project.
*/
@Input
private List<String> approvedLicenses = new ArrayList<String>(Arrays.asList("SSPL+Elastic License", "Generated", "Vendored", "Apache LZ4-Java"));
/**
* Files that should be excluded from the license header check. Use with extreme care, only in situations where the license on the
* source file is compatible with the codebase but we do not want to add the license to the list of approved headers (to avoid the
* possibility of inadvertently using the license on our own source files).
*/
@Input
private List<String> excludes = new ArrayList<String>();

private ListProperty<License> additionalLicenses;

/**
* Additional license families that may be found. The key is the license category name (5 characters),
* followed by the family name and the value list of patterns to search for.
Expand All @@ -151,11 +157,6 @@ public void additionalLicense(final String categoryName, String familyName, Stri
additionalLicenses.add(new License(categoryName, familyName, pattern));
}

@Inject
public LicenseHeadersTask(ObjectFactory objectFactory) {
additionalLicenses = objectFactory.listProperty(License.class).convention(conventionalLicenses);
}

@TaskAction
public void runRat() {
ReportConfiguration reportConfiguration = new ReportConfiguration();
Expand Down Expand Up @@ -186,13 +187,15 @@ public void runRat() {
return simpleLicenseFamily;
}).toArray(SimpleLicenseFamily[]::new));

ClaimStatistic stats = generateReport(reportConfiguration, getReportFile());
File repFile = getReportFile().getAsFile().get();
ClaimStatistic stats = generateReport(reportConfiguration, repFile);
boolean unknownLicenses = stats.getNumUnknown() > 0;
boolean unApprovedLicenses = stats.getNumUnApproved() > 0;
if (unknownLicenses || unApprovedLicenses) {
getLogger().error("The following files contain unapproved license headers:");
unapprovedFiles(getReportFile()).stream().forEachOrdered(unapprovedFile -> getLogger().error(unapprovedFile));
throw new GradleException("Check failed. License header problems were found. Full details: " + reportFile.getAbsolutePath());
unapprovedFiles(repFile).stream().forEachOrdered(unapprovedFile -> getLogger().error(unapprovedFile));
throw new GradleException("Check failed. License header problems were found. Full details: " +
repFile.getAbsolutePath());
}
}

Expand All @@ -208,7 +211,7 @@ private IHeaderMatcher subStringMatcher(String licenseFamilyCategory, String lic

private ClaimStatistic generateReport(ReportConfiguration config, File xmlReportFile) {
try {
Files.deleteIfExists(reportFile.toPath());
Files.deleteIfExists(reportFile.get().getAsFile().toPath());
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(xmlReportFile));
return toXmlReportFile(config, bufferedWriter);
} catch (IOException | RatException exception) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.elasticsearch.gradle.internal.conventions.precommit.PrecommitTask;
import org.gradle.api.GradleException;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.TaskAction;

Expand All @@ -21,12 +22,19 @@
import java.util.function.Consumer;
import java.util.function.Predicate;

import javax.inject.Inject;

public class PomValidationTask extends PrecommitTask {

private final RegularFileProperty pomFile = getProject().getObjects().fileProperty();
private final RegularFileProperty pomFile;

private boolean foundError;

@Inject
public PomValidationTask(ObjectFactory objects) {
pomFile = objects.fileProperty();
}

@InputFile
public RegularFileProperty getPomFile() {
return pomFile;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.gradle.StartParameter;
import org.gradle.api.DefaultTask;
import org.gradle.api.GradleException;
import org.gradle.api.artifacts.Configuration;
Expand All @@ -27,6 +28,10 @@
import java.util.HashSet;
import java.util.Set;

import javax.inject.Inject;

import static org.elasticsearch.gradle.util.GradleUtils.projectPath;

/**
* A task to generate a dependency graph of our runtime dependencies and push that via
* an API call to a given endpoint of a SCA tool/service.
Expand All @@ -43,6 +48,7 @@ public class DependenciesGraphTask extends DefaultTask {
private Configuration runtimeConfiguration;
private String token;
private String url;
private StartParameter startParameter;

@Input
public String getUrl() {
Expand Down Expand Up @@ -71,10 +77,14 @@ public void setRuntimeConfiguration(Configuration runtimeConfiguration) {
this.runtimeConfiguration = runtimeConfiguration;
}

@Inject
public DependenciesGraphTask(StartParameter startParameter) {
this.startParameter = startParameter;
}

@TaskAction
void generateDependenciesGraph() {

if (getProject().getGradle().getStartParameter().isOffline()) {
if (startParameter.isOffline()) {
throw new GradleException("Must run in online mode in order to submit the dependency graph to the SCA service");
}

Expand Down Expand Up @@ -102,7 +112,7 @@ void generateDependenciesGraph() {
}
// We add one package and one node for each dependency, it suffices to check packages.
if (packages.size() > 0) {
final String projectName = "elastic/elasticsearch" + getProject().getPath();
final String projectName = "elastic/elasticsearch" + projectPath(getPath());
final String output = """
{
"depGraph": {
Expand Down Expand Up @@ -138,4 +148,5 @@ void generateDependenciesGraph() {
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
import org.gradle.api.artifacts.DependencySet;
import org.gradle.api.artifacts.ModuleVersionIdentifier;
import org.gradle.api.artifacts.ProjectDependency;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.file.ProjectLayout;
import org.gradle.api.internal.ConventionTask;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputDirectory;
import org.gradle.api.tasks.InputFiles;
Expand All @@ -33,6 +36,8 @@
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import javax.inject.Inject;

/**
* A task to gather information about the dependencies and export them into a csv file.
* <p>
Expand All @@ -45,17 +50,12 @@
* </ul>
*/
public class DependenciesInfoTask extends ConventionTask {
/**
* Directory to read license files
*/
@Optional
@InputDirectory
private File licensesDir = new File(getProject().getProjectDir(), "licenses").exists()
? new File(getProject().getProjectDir(), "licenses")
: null;

private final DirectoryProperty licensesDir;

@OutputFile
private File outputFile = new File(getProject().getBuildDir(), "reports/dependencies/dependencies.csv");
private File outputFile;

private LinkedHashMap<String, String> mappings;

public Configuration getRuntimeConfiguration() {
Expand All @@ -74,12 +74,17 @@ public void setCompileOnlyConfiguration(Configuration compileOnlyConfiguration)
this.compileOnlyConfiguration = compileOnlyConfiguration;
}

public File getLicensesDir() {
/**
* Directory to read license files
*/
@Optional
@InputDirectory
public DirectoryProperty getLicensesDir() {
return licensesDir;
}

public void setLicensesDir(File licensesDir) {
this.licensesDir = licensesDir;
this.licensesDir.set(licensesDir);
}

public File getOutputFile() {
Expand All @@ -101,13 +106,16 @@ public void setOutputFile(File outputFile) {
@InputFiles
private Configuration compileOnlyConfiguration;

public DependenciesInfoTask() {
@Inject
public DependenciesInfoTask(ProjectLayout projectLayout, ObjectFactory objectFactory) {
this.licensesDir = objectFactory.directoryProperty();
this.licensesDir.set(projectLayout.getProjectDirectory().dir("licenses"));
this.outputFile = projectLayout.getBuildDirectory().dir("reports/dependencies").get().file("dependencies.csv").getAsFile();
setDescription("Create a CSV file with dependencies information.");
}

@TaskAction
public void generateDependenciesInfo() throws IOException {

final DependencySet runtimeDependencies = runtimeConfiguration.getAllDependencies();
// we have to resolve the transitive dependencies and create a group:artifactId:version map

Expand Down Expand Up @@ -203,8 +211,9 @@ protected String getLicenseType(final String group, final String name) throws IO
}

protected File getDependencyInfoFile(final String group, final String name, final String infoFileSuffix) {
java.util.Optional<File> license = licensesDir != null
? Arrays.stream(licensesDir.listFiles((dir, fileName) -> Pattern.matches(".*-" + infoFileSuffix + ".*", fileName)))
File licenseDirFile = licensesDir.getAsFile().get();
java.util.Optional<File> license = licenseDirFile.exists()
? Arrays.stream(licenseDirFile.listFiles((dir, fileName) -> Pattern.matches(".*-" + infoFileSuffix + ".*", fileName)))
.filter(file -> {
String prefix = file.getName().split("-" + infoFileSuffix + ".*")[0];
return group.contains(prefix) || name.contains(prefix);
Expand All @@ -221,7 +230,7 @@ protected File getDependencyInfoFile(final String group, final String name, fina
+ ":"
+ name
+ " in "
+ getLicensesDir().getAbsolutePath()
+ licenseDirFile.getAbsolutePath()
)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,6 @@ public void setDir(File dir) {
this.dir = dir;
}

/**
* @param dir The path of the directory to create. Takes a String and coerces it to a file.
*/
public void setDir(String dir) {
this.dir = getProject().file(dir);
}

@Input
public int getDirMode() {
return dirMode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.logging.Logger;
import org.gradle.api.logging.Logging;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.tasks.Classpath;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.OutputDirectory;
Expand All @@ -28,6 +29,8 @@
import java.util.HashSet;
import java.util.Set;

import javax.inject.Inject;

/**
* Export Elasticsearch build resources to configurable paths
* <p>
Expand All @@ -43,8 +46,9 @@ public class ExportElasticsearchBuildResourcesTask extends DefaultTask {

private DirectoryProperty outputDir;

public ExportElasticsearchBuildResourcesTask() {
outputDir = getProject().getObjects().directoryProperty();
@Inject
public ExportElasticsearchBuildResourcesTask(ObjectFactory objects) {
outputDir = objects.directoryProperty();
}

@OutputDirectory
Expand Down

0 comments on commit c468612

Please sign in to comment.