Преглед на файлове

Add CheckAntoraVersionPlugin

Rob Winch преди 3 години
родител
ревизия
9b6c7af526

+ 10 - 1
buildSrc/build.gradle

@@ -26,6 +26,10 @@ sourceSets {
 
 gradlePlugin {
 	plugins {
+		checkAntoraVersion {
+			id = "org.springframework.antora.check-version"
+			implementationClass = "org.springframework.gradle.antora.CheckAntoraVersionPlugin"
+		}
 		trang {
 			id = "trang"
 			implementationClass = "trang.TrangPlugin"
@@ -75,6 +79,7 @@ dependencies {
 	implementation 'com.google.code.gson:gson:2.8.6'
 	implementation 'com.thaiopensource:trang:20091111'
 	implementation 'net.sourceforge.saxon:saxon:9.1.0.8'
+	implementation 'org.yaml:snakeyaml:1.30'
 	implementation localGroovy()
 
 	implementation 'io.github.gradle-nexus:publish-plugin:1.1.0'
@@ -102,7 +107,11 @@ dependencies {
 }
 
 
-test {
+tasks.named('test', Test).configure {
 	onlyIf { !project.hasProperty("buildSrc.skipTests") }
 	useJUnitPlatform()
+	jvmArgs(
+			'--add-opens', 'java.base/java.lang=ALL-UNNAMED',
+			'--add-opens', 'java.base/java.util=ALL-UNNAMED'
+	)
 }

+ 66 - 0
buildSrc/src/main/java/org/springframework/gradle/antora/CheckAntoraVersionPlugin.java

@@ -0,0 +1,66 @@
+package org.springframework.gradle.antora;
+
+import org.gradle.api.Action;
+import org.gradle.api.GradleException;
+import org.gradle.api.Plugin;
+import org.gradle.api.Project;
+import org.gradle.api.Task;
+import org.gradle.api.tasks.TaskProvider;
+import org.gradle.language.base.plugins.LifecycleBasePlugin;
+
+public class CheckAntoraVersionPlugin implements Plugin<Project> {
+	public static final String ANTORA_CHECK_VERSION_TASK_NAME = "antoraCheckVersion";
+
+	@Override
+	public void apply(Project project) {
+		TaskProvider<CheckAntoraVersionTask> antoraCheckVersion = project.getTasks().register(ANTORA_CHECK_VERSION_TASK_NAME, CheckAntoraVersionTask.class, new Action<CheckAntoraVersionTask>() {
+			@Override
+			public void execute(CheckAntoraVersionTask antoraCheckVersion) {
+				antoraCheckVersion.setGroup(LifecycleBasePlugin.VERIFICATION_GROUP);
+				antoraCheckVersion.setDescription("Checks the antora.yml version properties match the Gradle version");
+				antoraCheckVersion.getAntoraVersion().convention(project.provider(() -> getDefaultAntoraVersion(project)));
+				antoraCheckVersion.getAntoraPrerelease().convention(project.provider(() -> getDefaultAntoraPrerelease(project)));
+				antoraCheckVersion.getAntoraYmlFile().fileProvider(project.provider(() -> project.file("antora.yml")));
+			}
+		});
+		project.getPlugins().withType(LifecycleBasePlugin.class, new Action<LifecycleBasePlugin>() {
+			@Override
+			public void execute(LifecycleBasePlugin lifecycleBasePlugin) {
+				project.getTasks().named(LifecycleBasePlugin.CHECK_TASK_NAME).configure(new Action<Task>() {
+					@Override
+					public void execute(Task check) {
+						check.dependsOn(antoraCheckVersion);
+					}
+				});
+			}
+		});
+	}
+
+	private static String getDefaultAntoraVersion(Project project) {
+		String projectVersion = getProjectVersion(project);
+		int preReleaseIndex = getPreReleaseIndex(projectVersion);
+		return isPreRelease(projectVersion) ? projectVersion.substring(0, preReleaseIndex) : projectVersion;
+	}
+
+	private static String getDefaultAntoraPrerelease(Project project) {
+		String projectVersion = getProjectVersion(project);
+		int preReleaseIndex = getPreReleaseIndex(projectVersion);
+		return isPreRelease(projectVersion) ? projectVersion.substring(preReleaseIndex) : null;
+	}
+
+	private static String getProjectVersion(Project project) {
+		Object projectVersion = project.getVersion();
+		if (projectVersion == null) {
+			throw new GradleException("Please define antoraVersion and antoraPrerelease on " + ANTORA_CHECK_VERSION_TASK_NAME + " or provide a Project version so they can be defaulted");
+		}
+		return String.valueOf(projectVersion);
+	}
+
+	private static int getPreReleaseIndex(String projectVersion) {
+		return projectVersion.lastIndexOf("-");
+	}
+
+	private static boolean isPreRelease(String projectVersion) {
+		return getPreReleaseIndex(projectVersion) >= 0;
+	}
+}

+ 72 - 0
buildSrc/src/main/java/org/springframework/gradle/antora/CheckAntoraVersionTask.java

@@ -0,0 +1,72 @@
+package org.springframework.gradle.antora;
+
+import org.gradle.api.DefaultTask;
+import org.gradle.api.GradleException;
+import org.gradle.api.file.RegularFileProperty;
+import org.gradle.api.provider.Property;
+import org.gradle.api.tasks.Input;
+import org.gradle.api.tasks.InputFile;
+import org.gradle.api.tasks.TaskAction;
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.constructor.Constructor;
+import org.yaml.snakeyaml.representer.Representer;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+
+public abstract class CheckAntoraVersionTask extends DefaultTask {
+
+	@TaskAction
+	public void check() throws FileNotFoundException {
+		File antoraYmlFile = getAntoraYmlFile().getAsFile().get();
+		String expectedAntoraVersion = getAntoraVersion().get();
+		String expectedAntoraPrerelease = getAntoraPrerelease().getOrElse(null);
+
+		Representer representer = new Representer();
+		representer.getPropertyUtils().setSkipMissingProperties(true);
+
+		Yaml yaml = new Yaml(new Constructor(AntoraYml.class), representer);
+		AntoraYml antoraYml = yaml.load(new FileInputStream(antoraYmlFile));
+
+		String actualAntoraPrerelease = antoraYml.getPrerelease();
+		boolean preReleaseMatches = antoraYml.getPrerelease() == null && expectedAntoraPrerelease == null ||
+				(actualAntoraPrerelease != null && actualAntoraPrerelease.equals(expectedAntoraPrerelease));
+		String actualAntoraVersion = antoraYml.getVersion();
+		if (!preReleaseMatches ||
+				!expectedAntoraVersion.equals(actualAntoraVersion)) {
+			throw new GradleException("The Gradle version of '" + getProject().getVersion() + "' should have version: '" + expectedAntoraVersion + "' and prerelease: '" + expectedAntoraPrerelease + "' defined in " + antoraYmlFile + " but got version: '" + actualAntoraVersion+"' and prerelease: '" + actualAntoraPrerelease + "'");
+		}
+	}
+
+	@InputFile
+	public abstract RegularFileProperty getAntoraYmlFile();
+
+	@Input
+	public abstract Property<String> getAntoraVersion();
+
+	@Input
+	public abstract Property<String> getAntoraPrerelease();
+
+	public static class AntoraYml {
+		private String version;
+
+		private String prerelease;
+
+		public String getVersion() {
+			return version;
+		}
+
+		public void setVersion(String version) {
+			this.version = version;
+		}
+
+		public String getPrerelease() {
+			return prerelease;
+		}
+
+		public void setPrerelease(String prerelease) {
+			this.prerelease = prerelease;
+		}
+	}
+}

+ 265 - 0
buildSrc/src/test/java/org/springframework/gradle/antora/CheckAntoraVersionPluginTests.java

@@ -0,0 +1,265 @@
+package org.springframework.gradle.antora;
+
+import org.apache.commons.io.IOUtils;
+import org.gradle.api.GradleException;
+import org.gradle.api.Project;
+import org.gradle.api.Task;
+import org.gradle.testfixtures.ProjectBuilder;
+import org.junit.jupiter.api.Test;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.nio.charset.StandardCharsets;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+import static org.assertj.core.api.Assertions.assertThatIOException;
+
+class CheckAntoraVersionPluginTests {
+
+	@Test
+	void defaultsPropertiesWhenSnapshot() {
+		String expectedVersion = "1.0.0-SNAPSHOT";
+		Project project = ProjectBuilder.builder().build();
+		project.setVersion(expectedVersion);
+		project.getPluginManager().apply(CheckAntoraVersionPlugin.class);
+
+		Task task = project.getTasks().findByName(CheckAntoraVersionPlugin.ANTORA_CHECK_VERSION_TASK_NAME);
+
+		assertThat(task).isInstanceOf(CheckAntoraVersionTask.class);
+
+		CheckAntoraVersionTask checkAntoraVersionTask = (CheckAntoraVersionTask) task;
+		assertThat(checkAntoraVersionTask.getAntoraVersion().get()).isEqualTo("1.0.0");
+		assertThat(checkAntoraVersionTask.getAntoraPrerelease().get()).isEqualTo("-SNAPSHOT");
+		assertThat(checkAntoraVersionTask.getAntoraYmlFile().getAsFile().get()).isEqualTo(project.file("antora.yml"));
+	}
+
+	@Test
+	void defaultsPropertiesWhenMilestone() {
+		String expectedVersion = "1.0.0-M1";
+		Project project = ProjectBuilder.builder().build();
+		project.setVersion(expectedVersion);
+		project.getPluginManager().apply(CheckAntoraVersionPlugin.class);
+
+		Task task = project.getTasks().findByName(CheckAntoraVersionPlugin.ANTORA_CHECK_VERSION_TASK_NAME);
+
+		assertThat(task).isInstanceOf(CheckAntoraVersionTask.class);
+
+		CheckAntoraVersionTask checkAntoraVersionTask = (CheckAntoraVersionTask) task;
+		assertThat(checkAntoraVersionTask.getAntoraVersion().get()).isEqualTo("1.0.0");
+		assertThat(checkAntoraVersionTask.getAntoraPrerelease().get()).isEqualTo("-M1");
+		assertThat(checkAntoraVersionTask.getAntoraYmlFile().getAsFile().get()).isEqualTo(project.file("antora.yml"));
+	}
+
+	@Test
+	void defaultsPropertiesWhenRc() {
+		String expectedVersion = "1.0.0-RC1";
+		Project project = ProjectBuilder.builder().build();
+		project.setVersion(expectedVersion);
+		project.getPluginManager().apply(CheckAntoraVersionPlugin.class);
+
+		Task task = project.getTasks().findByName(CheckAntoraVersionPlugin.ANTORA_CHECK_VERSION_TASK_NAME);
+
+		assertThat(task).isInstanceOf(CheckAntoraVersionTask.class);
+
+		CheckAntoraVersionTask checkAntoraVersionTask = (CheckAntoraVersionTask) task;
+		assertThat(checkAntoraVersionTask.getAntoraVersion().get()).isEqualTo("1.0.0");
+		assertThat(checkAntoraVersionTask.getAntoraPrerelease().get()).isEqualTo("-RC1");
+		assertThat(checkAntoraVersionTask.getAntoraYmlFile().getAsFile().get()).isEqualTo(project.file("antora.yml"));
+	}
+
+	@Test
+	void defaultsPropertiesWhenRelease() {
+		String expectedVersion = "1.0.0";
+		Project project = ProjectBuilder.builder().build();
+		project.setVersion(expectedVersion);
+		project.getPluginManager().apply(CheckAntoraVersionPlugin.class);
+
+		Task task = project.getTasks().findByName(CheckAntoraVersionPlugin.ANTORA_CHECK_VERSION_TASK_NAME);
+
+		assertThat(task).isInstanceOf(CheckAntoraVersionTask.class);
+
+		CheckAntoraVersionTask checkAntoraVersionTask = (CheckAntoraVersionTask) task;
+		assertThat(checkAntoraVersionTask.getAntoraVersion().get()).isEqualTo("1.0.0");
+		assertThat(checkAntoraVersionTask.getAntoraPrerelease().isPresent()).isFalse();
+		assertThat(checkAntoraVersionTask.getAntoraYmlFile().getAsFile().get()).isEqualTo(project.file("antora.yml"));
+	}
+
+	@Test
+	void explicitProperties() {
+		Project project = ProjectBuilder.builder().build();
+		project.getPluginManager().apply(CheckAntoraVersionPlugin.class);
+
+		Task task = project.getTasks().findByName(CheckAntoraVersionPlugin.ANTORA_CHECK_VERSION_TASK_NAME);
+
+		CheckAntoraVersionTask checkAntoraVersionTask = (CheckAntoraVersionTask) task;
+		checkAntoraVersionTask.getAntoraVersion().set("1.0.0");
+		checkAntoraVersionTask.getAntoraPrerelease().set("-SNAPSHOT");
+		assertThat(checkAntoraVersionTask.getAntoraVersion().get()).isEqualTo("1.0.0");
+		assertThat(checkAntoraVersionTask.getAntoraPrerelease().get()).isEqualTo("-SNAPSHOT");
+		assertThat(checkAntoraVersionTask.getAntoraYmlFile().getAsFile().get()).isEqualTo(project.file("antora.yml"));
+	}
+
+	@Test
+	void versionNotDefined() throws Exception {
+		Project project = ProjectBuilder.builder().build();
+		File rootDir = project.getRootDir();
+		IOUtils.write("version: '1.0.0'", new FileOutputStream(new File(rootDir, "antora.yml")), StandardCharsets.UTF_8);
+		project.getPluginManager().apply(CheckAntoraVersionPlugin.class);
+
+		Task task = project.getTasks().findByName(CheckAntoraVersionPlugin.ANTORA_CHECK_VERSION_TASK_NAME);
+
+		assertThat(task).isInstanceOf(CheckAntoraVersionTask.class);
+
+		CheckAntoraVersionTask checkAntoraVersionTask = (CheckAntoraVersionTask) task;
+		assertThatExceptionOfType(GradleException.class).isThrownBy(() -> checkAntoraVersionTask.check());
+	}
+
+	@Test
+	void antoraFileNotFound() throws Exception {
+		String expectedVersion = "1.0.0-SNAPSHOT";
+		Project project = ProjectBuilder.builder().build();
+		project.setVersion(expectedVersion);
+		project.getPluginManager().apply(CheckAntoraVersionPlugin.class);
+
+		Task task = project.getTasks().findByName(CheckAntoraVersionPlugin.ANTORA_CHECK_VERSION_TASK_NAME);
+
+		assertThat(task).isInstanceOf(CheckAntoraVersionTask.class);
+
+		CheckAntoraVersionTask checkAntoraVersionTask = (CheckAntoraVersionTask) task;
+		assertThatIOException().isThrownBy(() -> checkAntoraVersionTask.check());
+	}
+
+	@Test
+	void actualAntoraPrereleaseNull() throws Exception {
+		String expectedVersion = "1.0.0-SNAPSHOT";
+		Project project = ProjectBuilder.builder().build();
+		File rootDir = project.getRootDir();
+		IOUtils.write("version: '1.0.0'", new FileOutputStream(new File(rootDir, "antora.yml")), StandardCharsets.UTF_8);
+		project.setVersion(expectedVersion);
+		project.getPluginManager().apply(CheckAntoraVersionPlugin.class);
+
+		Task task = project.getTasks().findByName(CheckAntoraVersionPlugin.ANTORA_CHECK_VERSION_TASK_NAME);
+
+		assertThat(task).isInstanceOf(CheckAntoraVersionTask.class);
+
+		CheckAntoraVersionTask checkAntoraVersionTask = (CheckAntoraVersionTask) task;
+		assertThatExceptionOfType(GradleException.class).isThrownBy(() -> checkAntoraVersionTask.check());
+
+	}
+
+	@Test
+	void matchesWhenSnapshot() throws Exception {
+		String expectedVersion = "1.0.0-SNAPSHOT";
+		Project project = ProjectBuilder.builder().build();
+		File rootDir = project.getRootDir();
+		IOUtils.write("version: '1.0.0'\nprerelease: '-SNAPSHOT'", new FileOutputStream(new File(rootDir, "antora.yml")), StandardCharsets.UTF_8);
+		project.setVersion(expectedVersion);
+		project.getPluginManager().apply(CheckAntoraVersionPlugin.class);
+
+		Task task = project.getTasks().findByName(CheckAntoraVersionPlugin.ANTORA_CHECK_VERSION_TASK_NAME);
+
+		assertThat(task).isInstanceOf(CheckAntoraVersionTask.class);
+
+		CheckAntoraVersionTask checkAntoraVersionTask = (CheckAntoraVersionTask) task;
+		checkAntoraVersionTask.check();
+	}
+
+	@Test
+	void matchesWhenMilestone() throws Exception {
+		String expectedVersion = "1.0.0-M1";
+		Project project = ProjectBuilder.builder().build();
+		File rootDir = project.getRootDir();
+		IOUtils.write("version: '1.0.0'\nprerelease: '-M1'", new FileOutputStream(new File(rootDir, "antora.yml")), StandardCharsets.UTF_8);
+		project.setVersion(expectedVersion);
+		project.getPluginManager().apply(CheckAntoraVersionPlugin.class);
+
+		Task task = project.getTasks().findByName(CheckAntoraVersionPlugin.ANTORA_CHECK_VERSION_TASK_NAME);
+
+		assertThat(task).isInstanceOf(CheckAntoraVersionTask.class);
+
+		CheckAntoraVersionTask checkAntoraVersionTask = (CheckAntoraVersionTask) task;
+		checkAntoraVersionTask.check();
+	}
+
+	@Test
+	void matchesWhenRc() throws Exception {
+		String expectedVersion = "1.0.0-RC1";
+		Project project = ProjectBuilder.builder().build();
+		File rootDir = project.getRootDir();
+		IOUtils.write("version: '1.0.0'\nprerelease: '-RC1'", new FileOutputStream(new File(rootDir, "antora.yml")), StandardCharsets.UTF_8);
+		project.setVersion(expectedVersion);
+		project.getPluginManager().apply(CheckAntoraVersionPlugin.class);
+
+		Task task = project.getTasks().findByName(CheckAntoraVersionPlugin.ANTORA_CHECK_VERSION_TASK_NAME);
+
+		assertThat(task).isInstanceOf(CheckAntoraVersionTask.class);
+
+		CheckAntoraVersionTask checkAntoraVersionTask = (CheckAntoraVersionTask) task;
+		checkAntoraVersionTask.check();
+	}
+
+	@Test
+	void matchesWhenReleaseAndPrereleaseUndefined() throws Exception {
+		String expectedVersion = "1.0.0";
+		Project project = ProjectBuilder.builder().build();
+		File rootDir = project.getRootDir();
+		IOUtils.write("version: '1.0.0'", new FileOutputStream(new File(rootDir, "antora.yml")), StandardCharsets.UTF_8);
+		project.setVersion(expectedVersion);
+		project.getPluginManager().apply(CheckAntoraVersionPlugin.class);
+
+		Task task = project.getTasks().findByName(CheckAntoraVersionPlugin.ANTORA_CHECK_VERSION_TASK_NAME);
+
+		assertThat(task).isInstanceOf(CheckAntoraVersionTask.class);
+
+		CheckAntoraVersionTask checkAntoraVersionTask = (CheckAntoraVersionTask) task;
+		checkAntoraVersionTask.check();
+	}
+
+	@Test
+	void matchesWhenExplicitRelease() throws Exception {
+		Project project = ProjectBuilder.builder().build();
+		File rootDir = project.getRootDir();
+		IOUtils.write("version: '1.0.0'", new FileOutputStream(new File(rootDir, "antora.yml")), StandardCharsets.UTF_8);
+		project.getPluginManager().apply(CheckAntoraVersionPlugin.class);
+
+		Task task = project.getTasks().findByName(CheckAntoraVersionPlugin.ANTORA_CHECK_VERSION_TASK_NAME);
+
+		assertThat(task).isInstanceOf(CheckAntoraVersionTask.class);
+		CheckAntoraVersionTask checkAntoraVersionTask = (CheckAntoraVersionTask) task;
+		((CheckAntoraVersionTask) task).getAntoraVersion().set("1.0.0");
+		checkAntoraVersionTask.check();
+	}
+
+	@Test
+	void matchesWhenExplicitPrerelease() throws Exception {
+		Project project = ProjectBuilder.builder().build();
+		File rootDir = project.getRootDir();
+		IOUtils.write("version: '1.0.0'\nprerelease: '-SNAPSHOT'", new FileOutputStream(new File(rootDir, "antora.yml")), StandardCharsets.UTF_8);
+		project.getPluginManager().apply(CheckAntoraVersionPlugin.class);
+
+		Task task = project.getTasks().findByName(CheckAntoraVersionPlugin.ANTORA_CHECK_VERSION_TASK_NAME);
+
+		assertThat(task).isInstanceOf(CheckAntoraVersionTask.class);
+		CheckAntoraVersionTask checkAntoraVersionTask = (CheckAntoraVersionTask) task;
+		((CheckAntoraVersionTask) task).getAntoraVersion().set("1.0.0");
+		((CheckAntoraVersionTask) task).getAntoraPrerelease().set("-SNAPSHOT");
+		checkAntoraVersionTask.check();
+	}
+
+	@Test
+	void matchesWhenMissingPropertyDefined() throws Exception {
+		Project project = ProjectBuilder.builder().build();
+		File rootDir = project.getRootDir();
+		IOUtils.write("name: 'ROOT'\nversion: '1.0.0'", new FileOutputStream(new File(rootDir, "antora.yml")), StandardCharsets.UTF_8);
+		project.getPluginManager().apply(CheckAntoraVersionPlugin.class);
+
+		Task task = project.getTasks().findByName(CheckAntoraVersionPlugin.ANTORA_CHECK_VERSION_TASK_NAME);
+
+		assertThat(task).isInstanceOf(CheckAntoraVersionTask.class);
+		CheckAntoraVersionTask checkAntoraVersionTask = (CheckAntoraVersionTask) task;
+		((CheckAntoraVersionTask) task).getAntoraVersion().set("1.0.0");
+		checkAntoraVersionTask.check();
+	}
+
+}

+ 1 - 0
docs/spring-security-docs.gradle

@@ -1,5 +1,6 @@
 plugins {
 	id "io.github.rwinch.antora" version "0.0.2"
+	id "org.springframework.antora.check-version"
 }
 
 apply plugin: 'io.spring.convention.docs'