Skip to content

Fail on SSPL licensed x-pack sources #79348

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
Oct 19, 2021
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
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import org.gradle.api.model.ObjectFactory;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.BufferedWriter;
Expand All @@ -51,6 +51,8 @@
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.inject.Inject;
import java.io.Serializable;

/**
* Checks files for license headers..
Expand Down Expand Up @@ -95,17 +97,18 @@ public List<String> getExcludes() {
return excludes;
}

public Map<String, String> getAdditionalLicenses() {
return additionalLicenses;
}

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.
*/
Expand All @@ -118,13 +121,17 @@ public void setExcludes(List<String> excludes) {
*/
@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.
*/
@Input
protected Map<String, String> additionalLicenses = new HashMap<String, String>();

public ListProperty<License> getAdditionalLicenses() {
return additionalLicenses;
}
/**
* Add a new license type.
* <p>
Expand All @@ -139,7 +146,12 @@ public void additionalLicense(final String categoryName, String familyName, Stri
throw new IllegalArgumentException("License category name must be exactly 5 characters, got " + categoryName);
}

additionalLicenses.put(categoryName + familyName, pattern);
additionalLicenses.add(new License(categoryName, familyName, pattern));
}

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

@TaskAction
Expand All @@ -160,14 +172,10 @@ public void runRat() {
matchers.add(subStringMatcher("GEN ", "Generated", "ANTLR GENERATED CODE"));
// Vendored Code
matchers.add(subStringMatcher("VEN ", "Vendored", "@notice"));
// Dual SSPLv1 and Elastic
matchers.add(subStringMatcher("DUAL", "SSPL+Elastic License", "the Elastic License 2.0 or the Server"));

for (Map.Entry<String, String> additional : additionalLicenses.entrySet()) {
String category = additional.getKey().substring(0, 5);
String family = additional.getKey().substring(5);
matchers.add(subStringMatcher(category, family, additional.getValue()));
}
additionalLicenses.get().forEach(l ->
matchers.add(subStringMatcher(l.licenseFamilyCategory, l.licenseFamilyName, l.substringPattern))
);

reportConfiguration.setHeaderMatcher(new HeaderMatcherMultiplexer(matchers.toArray(IHeaderMatcher[]::new)));
reportConfiguration.setApprovedLicenseNames(approvedLicenses.stream().map(license -> {
Expand All @@ -190,7 +198,6 @@ private IHeaderMatcher subStringMatcher(String licenseFamilyCategory, String lic
SubstringLicenseMatcher substringLicenseMatcher = new SubstringLicenseMatcher();
substringLicenseMatcher.setLicenseFamilyCategory(licenseFamilyCategory);
substringLicenseMatcher.setLicenseFamilyName(licenseFamilyName);

SubstringLicenseMatcher.Pattern pattern = new SubstringLicenseMatcher.Pattern();
pattern.setSubstring(substringPattern);
substringLicenseMatcher.addConfiguredPattern(pattern);
Expand Down Expand Up @@ -249,4 +256,16 @@ private static List<Element> elementList(NodeList resourcesNodes) {
}
return nodeList;
}

static class License implements Serializable {
private String licenseFamilyCategory;
private String licenseFamilyName;
private String substringPattern;

public License(String licenseFamilyCategory, String licenseFamilyName, String substringPattern) {
this.licenseFamilyCategory = licenseFamilyCategory;
this.licenseFamilyName = licenseFamilyName;
this.substringPattern = substringPattern;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,45 @@ class LicenseHeadersPrecommitPluginFuncTest extends AbstractGradleFuncTest {
result.task(":licenseHeaders").outcome == TaskOutcome.SUCCESS
}

def "supports sspl by convention"() {
given:
buildFile << """
plugins {
id 'java'
id 'elasticsearch.internal-licenseheaders'
}
"""
dualLicensedFile()

when:
def result = gradleRunner("licenseHeaders").build()

then:
result.task(":licenseHeaders").outcome == TaskOutcome.SUCCESS
}

def "sspl default additional license can be overridden"() {
given:
buildFile << """
plugins {
id 'java'
id 'elasticsearch.internal-licenseheaders'
}

tasks.named("licenseHeaders").configure {
additionalLicense 'ELAST', 'Elastic License 2.0', '2.0; you may not use this file except in compliance with the Elastic License'
}
"""
elasticLicensed()
dualLicensedFile()

when:
def result = gradleRunner("licenseHeaders").buildAndFail()

then:
result.task(":licenseHeaders").outcome == TaskOutcome.FAILED
}

private File unapprovedSourceFile(String filePath = "src/main/java/org/acme/UnapprovedLicensed.java") {
File sourceFile = file(filePath);
sourceFile << """
Expand Down Expand Up @@ -115,6 +154,21 @@ class LicenseHeadersPrecommitPluginFuncTest extends AbstractGradleFuncTest {
"""
}

private File elasticLicensed() {
file("src/main/java/org/acme/ElasticLicensed.java") << """
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

package org.acme;
public class ElasticLicensed {
}
"""
}

private String packageString(File sourceFile) {
String normalizedPath = normalized(sourceFile.getPath())
(normalizedPath.substring(normalizedPath.indexOf("src/main/java")) - "src/main/java/" - ("/" + sourceFile.getName())).replaceAll("/", ".")
Expand Down