Skip to content

Commit

Permalink
Allow custom separator for years in license header
Browse files Browse the repository at this point in the history
  • Loading branch information
eyalkaspi-delphix committed Feb 7, 2018
1 parent 115aa61 commit 7927e7e
Show file tree
Hide file tree
Showing 12 changed files with 230 additions and 38 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ You might be looking for:

### Version 1.10.0-SNAPSHOT - TBD (javadoc [lib](https://diffplug.github.io/spotless/javadoc/spotless-lib/snapshot/) [lib-extra](https://diffplug.github.io/spotless/javadoc/spotless-lib-extra/snapshot/), [snapshot repo](https://oss.sonatype.org/content/repositories/snapshots/com/diffplug/spotless/))

* LicenseHeaderStep now supports customizing the year range separator in copyright notices. ([#199](https://github.com/diffplug/spotless/pull/199))

### Version 1.9.0 - February 5th 2018 (javadoc [lib](https://diffplug.github.io/spotless/javadoc/spotless-lib/1.9.0/) [lib-extra](https://diffplug.github.io/spotless/javadoc/spotless-lib-extra/1.9.0/), artifact [lib]([jcenter](https://bintray.com/diffplug/opensource/spotless-lib), [lib-extra]([jcenter](https://bintray.com/diffplug/opensource/spotless-lib-extra)))

* Updated default ktlint from 0.6.1 to 0.14.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,24 +43,28 @@ public final class LicenseHeaderStep implements Serializable {
private String licenseHeaderWithYearTokenReplaced;

/** Creates a FormatterStep which forces the start of each file to match a license header. */
public static FormatterStep createFromHeader(String licenseHeader, String delimiter) {
public static FormatterStep createFromHeader(String licenseHeader, String delimiter,
String yearSeparator) {
Objects.requireNonNull(licenseHeader, "licenseHeader");
Objects.requireNonNull(delimiter, "delimiter");
Objects.requireNonNull(yearSeparator, "yearSeparator");
return FormatterStep.create(LicenseHeaderStep.NAME,
new LicenseHeaderStep(licenseHeader, delimiter),
new LicenseHeaderStep(licenseHeader, delimiter, yearSeparator),
step -> step::format);
}

/**
* Creates a FormatterStep which forces the start of each file to match the license header
* contained in the given file.
*/
public static FormatterStep createFromFile(File licenseHeaderFile, Charset encoding, String delimiter) {
public static FormatterStep createFromFile(File licenseHeaderFile, Charset encoding, String delimiter,
String yearSeparator) {
Objects.requireNonNull(licenseHeaderFile, "licenseHeaderFile");
Objects.requireNonNull(encoding, "encoding");
Objects.requireNonNull(delimiter, "delimiter");
Objects.requireNonNull(yearSeparator, "yearSeparator");
return FormatterStep.createLazy(LicenseHeaderStep.NAME,
() -> new LicenseHeaderStep(licenseHeaderFile, encoding, delimiter),
() -> new LicenseHeaderStep(licenseHeaderFile, encoding, delimiter, yearSeparator),
step -> step::format);
}

Expand All @@ -69,7 +73,7 @@ public static String name() {
}

/** The license that we'd like enforced. */
private LicenseHeaderStep(String licenseHeader, String delimiter) {
private LicenseHeaderStep(String licenseHeader, String delimiter, String yearSeparator) {
if (delimiter.contains("\n")) {
throw new IllegalArgumentException("The delimiter must not contain any newlines.");
}
Expand All @@ -86,13 +90,13 @@ private LicenseHeaderStep(String licenseHeader, String delimiter) {
this.licenseHeaderBeforeYearToken = licenseHeader.substring(0, yearTokenIndex);
this.licenseHeaderAfterYearToken = licenseHeader.substring(yearTokenIndex + 5, licenseHeader.length());
this.licenseHeaderWithYearTokenReplaced = licenseHeader.replace("$YEAR", String.valueOf(YearMonth.now().getYear()));
this.yearMatcherPattern = Pattern.compile("[0-9]{4}(-[0-9]{4})?");
this.yearMatcherPattern = Pattern.compile("[0-9]{4}(" + Pattern.quote(yearSeparator) + "[0-9]{4})?");
}
}

/** Reads the license file from the given file. */
private LicenseHeaderStep(File licenseFile, Charset encoding, String delimiter) throws IOException {
this(new String(Files.readAllBytes(licenseFile.toPath()), encoding), delimiter);
private LicenseHeaderStep(File licenseFile, Charset encoding, String delimiter, String yearSeparator) throws IOException {
this(new String(Files.readAllBytes(licenseFile.toPath()), encoding), delimiter, yearSeparator);
}

/** Formats the given string. */
Expand Down
2 changes: 2 additions & 0 deletions plugin-gradle/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

### Version 3.10.0-SNAPSHOT - TBD ([javadoc](https://diffplug.github.io/spotless/javadoc/snapshot/), [snapshot](https://oss.sonatype.org/content/repositories/snapshots/com/diffplug/spotless/spotless-plugin-gradle/))

* LicenseHeaderStep now supports customizing the year range separator in copyright notices. ([#199](https://github.com/diffplug/spotless/pull/199)

### Version 3.9.0 - February 5th 2018 ([javadoc](https://diffplug.github.io/spotless/javadoc/spotless-plugin-gradle/3.9.0/), [jcenter](https://bintray.com/diffplug/opensource/spotless-plugin-gradle/3.9.0))

* Updated default ktlint from 0.6.1 to 0.14.0
Expand Down
14 changes: 13 additions & 1 deletion plugin-gradle/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -307,10 +307,22 @@ The `licenseHeader` and `licenseHeaderFile` steps will generate license headers
* A generated license header will _not_ be updated when
* a single year is already present, e.g.
`/* Licensed under Apache-2.0 1990. */`
* a hyphen-separated year range is already present, e.g.
* a year range is already present, e.g.
`/* Licensed under Apache-2.0 1990-2003. */`
* the `$YEAR` token is otherwise missing

The separator for the year range defaults to the hyphen character, e.g `1990-2003`, but can be customized with the `yearSeparator` property.

For instance, the following configuration treats `1990, 2003` as a valid year range.

```gradle
spotless {
format java {
licenseHeader(''Licensed under Apache-2.0 $YEAR').yearSeparator(', ')
}
}
```


<a name="custom"></a>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -345,26 +345,92 @@ public void indentWithTabs() {
indentWithTabs(4);
}

abstract class LicenseHeaderConfig {

String delimiter;

static final String DEFAULT_LICENSE_YEAR_DELIMITER = "-";
String yearSeparator = DEFAULT_LICENSE_YEAR_DELIMITER;

public LicenseHeaderConfig(String delimiter) {
this.delimiter = Objects.requireNonNull(delimiter, "delimiter");
}

/**
* @param delimiter
* Spotless will look for a line that starts with this to know what the "top" is.
*/
public LicenseHeaderConfig delimiter(String delimiter) {
this.delimiter = Objects.requireNonNull(delimiter, "delimiter");
replaceStep(createStep());
return this;
}

/**
* @param yearSeparator
* The characters used to separate the first and last years in multi years patterns.
*/
public LicenseHeaderConfig yearSeparator(String yearSeparator) {
this.yearSeparator = Objects.requireNonNull(yearSeparator, "yearSeparator");
replaceStep(createStep());
return this;
}

abstract FormatterStep createStep();
}

class LicenseStringHeaderConfig extends LicenseHeaderConfig {

private String header;

LicenseStringHeaderConfig(String delimiter, String header) {
super(delimiter);
this.header = Objects.requireNonNull(header, "header");
}

FormatterStep createStep() {
return LicenseHeaderStep.createFromHeader(header, delimiter, yearSeparator);
}
}

class LicenseFileHeaderConfig extends LicenseHeaderConfig {

private Object headerFile;

LicenseFileHeaderConfig(String delimiter, Object headerFile) {
super(delimiter);
this.headerFile = Objects.requireNonNull(headerFile, "headerFile");
}

FormatterStep createStep() {
return LicenseHeaderStep
.createFromFile(getProject().file(headerFile), getEncoding(), delimiter,
yearSeparator);
}
}

/**
* @param licenseHeader
* Content that should be at the top of every file
* Content that should be at the top of every file.
* @param delimiter
* Spotless will look for a line that starts with this to know what the "top" is.
*/
public void licenseHeader(String licenseHeader, String delimiter) {
addStep(LicenseHeaderStep.createFromHeader(licenseHeader, delimiter));
public LicenseHeaderConfig licenseHeader(String licenseHeader, String delimiter) {
LicenseHeaderConfig config = new LicenseStringHeaderConfig(delimiter, licenseHeader);
addStep(config.createStep());
return config;
}

/**
* @param licenseHeaderFile
* Content that should be at the top of every file
* Content that should be at the top of every file.
* @param delimiter
* Spotless will look for a line that starts with this to know what the "top" is.
*/
public void licenseHeaderFile(Object licenseHeaderFile, String delimiter) {
Objects.requireNonNull(licenseHeaderFile, "licenseHeaderFile");
Objects.requireNonNull(delimiter, "delimiter");
addStep(LicenseHeaderStep.createFromFile(getProject().file(licenseHeaderFile), getEncoding(), delimiter));
public LicenseHeaderConfig licenseHeaderFile(Object licenseHeaderFile, String delimiter) {
LicenseHeaderConfig config = new LicenseFileHeaderConfig(delimiter, licenseHeaderFile);
addStep(config.createStep());
return config;
}

/** Sets up a format task according to the values in this extension. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ public void excludeJava(boolean excludeJava) {
this.excludeJava = excludeJava;
}

public void licenseHeader(String licenseHeader) {
licenseHeader(licenseHeader, JavaExtension.LICENSE_HEADER_DELIMITER);
public LicenseHeaderConfig licenseHeader(String licenseHeader) {
return licenseHeader(licenseHeader, JavaExtension.LICENSE_HEADER_DELIMITER);
}

public void licenseHeaderFile(Object licenseHeaderFile) {
licenseHeaderFile(licenseHeaderFile, JavaExtension.LICENSE_HEADER_DELIMITER);
public LicenseHeaderConfig licenseHeaderFile(Object licenseHeaderFile) {
return licenseHeaderFile(licenseHeaderFile, JavaExtension.LICENSE_HEADER_DELIMITER);
}

/** Method interface has been changed to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ public JavaExtension(SpotlessExtension rootExtension) {
// testlib/src/test/java/com/diffplug/spotless/generic/LicenseHeaderStepTest.java as well
static final String LICENSE_HEADER_DELIMITER = "package ";

public void licenseHeader(String licenseHeader) {
licenseHeader(licenseHeader, LICENSE_HEADER_DELIMITER);
public LicenseHeaderConfig licenseHeader(String licenseHeader) {
return licenseHeader(licenseHeader, LICENSE_HEADER_DELIMITER);
}

public void licenseHeaderFile(Object licenseHeaderFile) {
licenseHeaderFile(licenseHeaderFile, LICENSE_HEADER_DELIMITER);
public LicenseHeaderConfig licenseHeaderFile(Object licenseHeaderFile) {
return licenseHeaderFile(licenseHeaderFile, LICENSE_HEADER_DELIMITER);
}

/** Method interface has been changed to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ public KotlinExtension(SpotlessExtension rootExtension) {
super(rootExtension);
}

public void licenseHeader(String licenseHeader) {
licenseHeader(licenseHeader, LICENSE_HEADER_DELIMITER);
public LicenseHeaderConfig licenseHeader(String licenseHeader) {
return licenseHeader(licenseHeader, LICENSE_HEADER_DELIMITER);
}

public void licenseHeaderFile(Object licenseHeaderFile) {
licenseHeaderFile(licenseHeaderFile, LICENSE_HEADER_DELIMITER);
public LicenseHeaderConfig licenseHeaderFile(Object licenseHeaderFile) {
return licenseHeaderFile(licenseHeaderFile, LICENSE_HEADER_DELIMITER);
}

/** Adds the specified version of [ktlint](https://github.com/shyiko/ktlint). */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@

import java.io.File;
import java.io.IOException;
import java.time.YearMonth;

import org.assertj.core.api.Assertions;
import org.junit.Assert;
import org.junit.Test;

public class KotlinExtensionTest extends GradleIntegrationTest {
private static final String HEADER = "// License Header";
private static final String HEADER_WITH_YEAR = "// License Header $YEAR";

@Test
public void integration() throws IOException {
Expand Down Expand Up @@ -72,4 +74,66 @@ public void testWithHeader() throws IOException {
// Make sure that no additional stuff got added to the file.
.contains(HEADER + '\n' + original);
}

@Test
public void testWithCustomHeaderSeparator() throws IOException {
write("build.gradle",
"plugins {",
" id 'nebula.kotlin' version '1.0.6'",
" id 'com.diffplug.gradle.spotless'",
"}",
"repositories { mavenCentral() }",
"spotless {",
" kotlin {",
" licenseHeader ('" + HEADER + "', '@file')",
" ktlint()",
" }",
"}");
final File testFile = write("src/main/kotlin/test.kt", getTestResource("kotlin/licenseheader/KotlinCodeWithoutHeader.test"));
final String original = read(testFile.toPath());
gradleRunner().withArguments("spotlessApply").build();
final String result = read(testFile.toPath());
Assertions
.assertThat(result)
// Make sure the header gets added.
.startsWith(HEADER)
// Make sure that the rest of the file is still there with nothing removed.
.endsWith(original)
// Make sure that no additional stuff got added to the file.
.contains(HEADER + '\n' + original);
}

@Test
public void testWithNonStandardYearSeparator() throws IOException {
write("build.gradle",
"plugins {",
" id 'nebula.kotlin' version '1.0.6'",
" id 'com.diffplug.gradle.spotless'",
"}",
"repositories { mavenCentral() }",
"spotless {",
" kotlin {",
" licenseHeader('" + HEADER_WITH_YEAR + "').yearSeparator(', ')",
" ktlint()",
" }",
"}");

final File testFile = write("src/main/kotlin/test.kt", getTestResource("kotlin/licenseheader/KotlinCodeWithMultiYearHeader.test"));
final String original = read(testFile.toPath());
final File testFile2 = write("src/main/kotlin/test2.kt", getTestResource("kotlin/licenseheader/KotlinCodeWithMultiYearHeader2.test"));
final String original2 = read(testFile.toPath());
gradleRunner().withArguments("spotlessApply").build();
final String result = read(testFile.toPath());
final String result2 = read(testFile2.toPath());

Assertions
.assertThat(result)
// Make sure the a "valid" header isn't changed
.contains("// License Header 2012, 2014");

Assertions
.assertThat(result2)
// Make sure that an "invalid" header is rewritten
.startsWith(HEADER_WITH_YEAR.replace("$YEAR", String.valueOf(YearMonth.now().getYear())));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// License Header 2012, 2014
@file:JvmName("SomeFileName")
package my.test

object AnObject
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// License Header 2012-2014
@file:JvmName("SomeFileName")
package my.test

object AnObject
Loading

0 comments on commit 7927e7e

Please sign in to comment.