Skip to content

Commit

Permalink
refactor: convert NoticeTask to java
Browse files Browse the repository at this point in the history
Relates to elastic#34459
  • Loading branch information
baptistemesta committed Oct 23, 2018
1 parent ed817fb commit c37ecf0
Show file tree
Hide file tree
Showing 3 changed files with 227 additions and 99 deletions.

This file was deleted.

128 changes: 128 additions & 0 deletions buildSrc/src/main/java/org/elasticsearch/gradle/NoticeTask.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you 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
*
* http://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 org.elasticsearch.gradle;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.gradle.api.DefaultTask;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.TaskAction;


/**
* A task to create a notice file which includes dependencies' notices.
*/
public class NoticeTask extends DefaultTask {

private static final Charset UTF8 = Charset.forName("UTF-8");
@InputFile
private File inputFile = getProject().getRootProject().file("NOTICE.txt");

@OutputFile
private File outputFile = new File(getProject().getBuildDir(), "notices/" + getName() + "/NOTICE.txt");

/**
* Directories to include notices from
*/
private List<File> licensesDirs = new ArrayList<>();

public NoticeTask() {
setDescription("Create a notice file from dependencies");
// Default licenses directory is ${projectDir}/licenses (if it exists)
File licensesDir = new File(getProject().getProjectDir(), "licenses");
if (licensesDir.exists()) {
licensesDirs.add(licensesDir);
}
}

/**
* Add notices from the specified directory.
*/
public void setLicensesDir(File licensesDir) {
licensesDirs.add(licensesDir);
}

public void setInputFile(File inputFile) {
this.inputFile = inputFile;
}

@TaskAction
public void generateNotice() throws IOException {
StringBuilder output = new StringBuilder();
output.append(read(inputFile));
output.append("\n\n");
// This is a map rather than a set so that the sort order is the 3rd
// party component names, unaffected by the full path to the various files
Map<String, File> seen = new TreeMap<>();
for (File licensesDir : licensesDirs) {
File[] files = licensesDir.listFiles((file) -> file.getName().matches(".*-NOTICE\\.txt"));
if (files == null) {
continue;
}
for (File file : files) {
String name = file.getName().substring(0, file.getName().length() - "-NOTICE.txt".length());
if (seen.containsKey(name)) {
File prevFile = seen.get(name);
if (!read(prevFile).equals(read(file))) {
throw new RuntimeException("Two different notices exist for dependency '" +
name + "': " + prevFile + " and " + file);
}
} else {
seen.put(name, file);
}
}
}
for (Map.Entry<String, File> entry : seen.entrySet()) {
String name = entry.getKey();
File file = entry.getValue();
appendFile(file, name, "NOTICE", output);
appendFile(new File(file.getParent(), name + "-LICENSE.txt"), name, "LICENSE", output);
}
outputFile.getParentFile().mkdirs();
outputFile.createNewFile();
write(outputFile, output.toString());
}

private String read(File file) throws IOException {
return new String(Files.readAllBytes(file.toPath()), UTF8);
}

private void write(File file, String content) throws IOException {
Files.write(file.toPath(), content.getBytes(UTF8));
}

private void appendFile(File file, String name, String type, StringBuilder output) throws IOException {
String text = read(file);
if (text.trim().isEmpty()) {
return;
}
output.append("================================================================================\n");
output.append(name).append(" ").append(type).append("\n");
output.append("================================================================================\n");
output.append(text).append("\n\n");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package org.elasticsearch.gradle;

import static java.nio.file.Files.readAllBytes;
import static java.nio.file.Files.write;
import static java.util.Collections.singletonMap;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Path;

import org.elasticsearch.gradle.test.GradleUnitTestCase;
import org.gradle.api.Project;
import org.gradle.internal.impldep.org.junit.rules.ExpectedException;
import org.gradle.internal.impldep.org.junit.rules.TemporaryFolder;
import org.gradle.testfixtures.ProjectBuilder;
import org.junit.Rule;

public class NoticeTaskTests extends GradleUnitTestCase {

private static final Charset UTF8 = Charset.forName("UTF-8");

@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
@Rule
public ExpectedException expectedException = ExpectedException.none();

private Project project;
private NoticeTask task;

private NoticeTask createTask(Project project) {
return (NoticeTask) project.task(singletonMap("type", NoticeTask.class), "noticeTask");
}

private Project createProject() throws IOException {
temporaryFolder.create();
File projectDir = temporaryFolder.newFolder();
return ProjectBuilder.builder().withProjectDir(projectDir).build();
}


public void testGenerateAllNotices() throws Exception {
project = createProject();
task = createTask(project);
Path projectDir = project.getProjectDir().toPath();
createFileIn(projectDir, "NOTICE.txt", "This is\nthe root notice\n");
Path licenseDir = projectDir.resolve("licenseDir");
createFileIn(licenseDir, "myNotice-NOTICE.txt", "This is\nmy notice\n");
createFileIn(licenseDir, "myNotice-LICENSE.txt", "This is\nmy license\n");
task.setLicensesDir(licenseDir.toFile());

task.generateNotice();

Path notice = project.getBuildDir().toPath().resolve("notices").resolve(task.getName()).resolve("NOTICE.txt");
String generatedContent = new String(readAllBytes(notice), UTF8);
String expected = "This is\n" +
"the root notice\n" +
"\n" +
"\n" +
"================================================================================\n" +
"myNotice NOTICE\n" +
"================================================================================\n" +
"This is\n" +
"my notice\n" +
"\n" +
"\n" +
"================================================================================\n" +
"myNotice LICENSE\n" +
"================================================================================\n" +
"This is\n" +
"my license";
assertEquals(expected, generatedContent.trim());
}

public void testShouldFailWhenMultipleNoticeIsPresent() throws Exception {
project = createProject();
task = createTask(project);
Path projectDir = project.getProjectDir().toPath();
createFileIn(projectDir, "NOTICE.txt", "This is\nthe root notice\n");
Path licenseDir = projectDir.resolve("licenseDir");
createFileIn(licenseDir, "myNotice1-NOTICE.txt", "This is\nmy notice\n");
createFileIn(licenseDir, "myNotice1-LICENSE.txt", "This is\nmy notice\n");
createFileIn(licenseDir, "myNotice2-NOTICE.txt", "This is\nmy notice\n");
createFileIn(licenseDir, "myNotice2-LICENSE.txt", "This is\nmy notice\n");
task.setLicensesDir(licenseDir.toFile());

expectedException.expect(RuntimeException.class);
expectedException.expectMessage("Two different notices exist");

task.generateNotice();
}

private void createFileIn(Path parent, String name, String content) throws IOException {
parent.toFile().mkdir();
Path file = parent.resolve(name);
file.toFile().createNewFile();
write(file, content.getBytes(UTF8));
}
}

0 comments on commit c37ecf0

Please sign in to comment.