You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2020/09/17 19:11:42 UTC
[isis] 01/02: ISIS-2433: automated gradle.settings creation
(provided as JUnit test)
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git
commit 4fe19db073d607ac395960debf82fa263f61c621
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Sep 17 21:02:46 2020 +0200
ISIS-2433: automated gradle.settings creation (provided as JUnit test)
---
.../tooling/projectmodel/gen/GradleSettings.java | 58 +++++++++
.../projectmodel/gen/GradleSettingsFactory.java | 69 ++++++++++
.../projectmodel/gen/GradleSettingsWriter.java | 80 ++++++++++++
.../projectmodel/test/GradleSettingsTest.java | 142 +++++++++++++++++++++
4 files changed, 349 insertions(+)
diff --git a/tooling/projectmodel/src/main/java/org/apache/isis/tooling/projectmodel/gen/GradleSettings.java b/tooling/projectmodel/src/main/java/org/apache/isis/tooling/projectmodel/gen/GradleSettings.java
new file mode 100644
index 0000000..e5d37b2
--- /dev/null
+++ b/tooling/projectmodel/src/main/java/org/apache/isis/tooling/projectmodel/gen/GradleSettings.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF 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.apache.isis.tooling.projectmodel.gen;
+
+import java.io.File;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Optional;
+
+import org.apache.isis.tooling.projectmodel.ArtifactKey;
+
+import lombok.Data;
+import lombok.Value;
+import lombok.val;
+
+@Data
+public class GradleSettings {
+
+ @Value(staticConstructor = "of")
+ public static class GradleBuildArtifact {
+ private final String name;
+ private final String realtivePath;
+ private final File projectDirectory;
+
+ public final boolean isRoot() {
+ return realtivePath.equals("/");
+ }
+
+ public final Optional<File> getDefaultBuildFile() {
+ val buildFile = new File(getProjectDirectory(), "build.gradle");
+ if(buildFile.exists()) {
+ return Optional.of(buildFile);
+ }
+ return Optional.empty();
+ }
+
+ }
+
+ private final String rootProjectName;
+ private final Map<ArtifactKey, GradleBuildArtifact> buildArtifactsByArtifactKey = new LinkedHashMap<>();
+
+}
diff --git a/tooling/projectmodel/src/main/java/org/apache/isis/tooling/projectmodel/gen/GradleSettingsFactory.java b/tooling/projectmodel/src/main/java/org/apache/isis/tooling/projectmodel/gen/GradleSettingsFactory.java
new file mode 100644
index 0000000..f6f89a0
--- /dev/null
+++ b/tooling/projectmodel/src/main/java/org/apache/isis/tooling/projectmodel/gen/GradleSettingsFactory.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF 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.apache.isis.tooling.projectmodel.gen;
+
+import java.io.File;
+
+import org.apache.isis.commons.internal.base._Files;
+import org.apache.isis.commons.internal.base._Strings;
+import org.apache.isis.tooling.projectmodel.ArtifactKey;
+import org.apache.isis.tooling.projectmodel.ProjectNode;
+import org.apache.isis.tooling.projectmodel.ProjectNodeFactory;
+import org.apache.isis.tooling.projectmodel.gen.GradleSettings.GradleBuildArtifact;
+
+import lombok.NonNull;
+import lombok.val;
+
+public class GradleSettingsFactory {
+
+ public static GradleSettings generateFromMaven(File projRootFolder, String rootProjectName) {
+
+ val projTree = ProjectNodeFactory.maven(projRootFolder);
+ val rootPath = _Files.canonicalPath(projRootFolder).get();
+
+ val gradleSettings = new GradleSettings(rootProjectName);
+ val folderByArtifactKey = gradleSettings.getBuildArtifactsByArtifactKey();
+
+ projTree.depthFirst(projModel -> {
+ folderByArtifactKey.put(projModel.getArtifactKey(), gradleBuildArtifactFor(projModel, rootPath));
+ });
+
+ return gradleSettings;
+ }
+
+ // -- HELPER
+
+ private static GradleBuildArtifact gradleBuildArtifactFor(ProjectNode projModel, String rootPath) {
+ val name = toCanonicalBuildName(projModel.getArtifactKey());
+ val realtivePath = toCanonicalRelativePath(projModel, rootPath);
+ return GradleBuildArtifact.of(name, realtivePath, projModel.getProjectDirectory());
+ }
+
+ private static String toCanonicalBuildName(final @NonNull ArtifactKey artifactKey) {
+ return String.format(":%s:%s", artifactKey.getGroupId(), artifactKey.getArtifactId());
+ }
+
+ private static String toCanonicalRelativePath(ProjectNode projModel, String rootPath) {
+ val canonicalProjDir = _Files.canonicalPath(projModel.getProjectDirectory()).get();
+ val relativePath = _Files.toRelativePath(rootPath, canonicalProjDir);
+ return _Strings.prefix(relativePath.replace('\\', '/'), "/");
+ }
+
+
+}
diff --git a/tooling/projectmodel/src/main/java/org/apache/isis/tooling/projectmodel/gen/GradleSettingsWriter.java b/tooling/projectmodel/src/main/java/org/apache/isis/tooling/projectmodel/gen/GradleSettingsWriter.java
new file mode 100644
index 0000000..e25d920
--- /dev/null
+++ b/tooling/projectmodel/src/main/java/org/apache/isis/tooling/projectmodel/gen/GradleSettingsWriter.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF 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.apache.isis.tooling.projectmodel.gen;
+
+import java.io.StringWriter;
+import java.io.Writer;
+
+import lombok.SneakyThrows;
+import lombok.val;
+
+public class GradleSettingsWriter {
+
+ public static String toString(GradleSettings gradleSettings) {
+ if(gradleSettings==null) {
+ return "";
+ }
+ val adocWriter = new GradleSettingsWriter();
+ val stringWriter = new StringWriter();
+ adocWriter.write(gradleSettings, stringWriter);
+ return stringWriter.toString();
+ }
+
+ public void write(GradleSettings gradleSettings, Writer writer) {
+ writeWithFormat(writer, "rootProject.name = '%s'\n", gradleSettings.getRootProjectName());
+
+ writeEmptyLine(writer);
+
+ gradleSettings.getBuildArtifactsByArtifactKey().forEach((artifactKey, buildArtifact)->{
+
+ if(buildArtifact.isRoot()) {
+ return; // don't write include statements for the project's root
+ }
+
+ writeWithFormat(writer, "include '%s'\n", buildArtifact.getName());
+ });
+
+ writeEmptyLine(writer);
+
+ gradleSettings.getBuildArtifactsByArtifactKey().forEach((artifactKey, buildArtifact)->{
+
+ if(buildArtifact.isRoot()) {
+ return; // don't write include statements for the project's root
+ }
+
+ writeWithFormat(writer,
+ "project('%s').projectDir = \"$rootDir%s\" as File\n",
+ buildArtifact.getName(),
+ buildArtifact.getRealtivePath());
+ });
+ }
+
+ // -- HELPER
+
+ @SneakyThrows
+ private static void writeWithFormat(Writer writer, String format, Object...args) {
+ writer.write(String.format(format, args));
+ }
+
+ @SneakyThrows
+ private static void writeEmptyLine(Writer writer) {
+ writer.write("\n");
+ }
+
+}
diff --git a/tooling/projectmodel/src/test/java/org/apache/isis/tooling/projectmodel/test/GradleSettingsTest.java b/tooling/projectmodel/src/test/java/org/apache/isis/tooling/projectmodel/test/GradleSettingsTest.java
new file mode 100644
index 0000000..04fe5aa
--- /dev/null
+++ b/tooling/projectmodel/src/test/java/org/apache/isis/tooling/projectmodel/test/GradleSettingsTest.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF 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.apache.isis.tooling.projectmodel.test;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.time.LocalDate;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+import org.apache.isis.commons.internal.base._Strings;
+import org.apache.isis.tooling.projectmodel.gen.GradleSettings;
+import org.apache.isis.tooling.projectmodel.gen.GradleSettingsFactory;
+import org.apache.isis.tooling.projectmodel.gen.GradleSettingsWriter;
+
+import lombok.SneakyThrows;
+import lombok.val;
+
+class GradleSettingsTest {
+
+ File projRootFolder;
+ boolean hasUnresolvableGradleBuildArtifacts;
+
+ @BeforeEach
+ void setUp() throws Exception {
+ projRootFolder = new File("./").getAbsoluteFile().getParentFile().getParentFile().getParentFile();
+ System.out.println("running GradleSettingsTest at " + projRootFolder.getAbsolutePath());
+ hasUnresolvableGradleBuildArtifacts = false;
+ }
+
+ @AfterEach
+ void tearDown() throws Exception {
+ }
+
+ @Test @Disabled("activate only if you want to see the settings.gradle written to stdout")
+ void writeGradleSettingsToStdout() throws IOException {
+ GradleSettings gradleSettings = GradleSettingsFactory.generateFromMaven(projRootFolder, "isis");
+ assertNotNull(gradleSettings);
+
+ System.out.println();
+ System.out.println();
+ System.out.println(String.format("// generated by %s", this.getClass().getName()));
+ System.out.println(String.format("// date %s", LocalDate.now().toString()));
+ System.out.println();
+ System.out.println(GradleSettingsWriter.toString(gradleSettings));
+ }
+
+ @Test
+ void testGradleSettingGenerator() throws IOException {
+ GradleSettings gradleSettings = GradleSettingsFactory.generateFromMaven(projRootFolder, "isis");
+
+ assertNotNull(gradleSettings);
+
+ val knownBuildArtifactNames = new HashSet<String>();
+
+ gradleSettings.getBuildArtifactsByArtifactKey().forEach((artifactKey, buildArtifact)->{
+ knownBuildArtifactNames.add(buildArtifact.getName());
+ });
+
+ gradleSettings.getBuildArtifactsByArtifactKey().forEach((artifactKey, buildArtifact)->{
+
+ if(buildArtifact.isRoot()) {
+ return; // skip project's root
+ }
+
+ buildArtifact.getDefaultBuildFile()
+ .ifPresent(buildFile->{
+ checkBuildFile(buildFile, knownBuildArtifactNames);
+ });
+
+ });
+
+ assertFalse(hasUnresolvableGradleBuildArtifacts);
+ }
+
+ // -- HELPER
+
+ @SneakyThrows
+ private void checkBuildFile(File buildFile, Set<String> knownBuildArtifactNames) {
+ //System.out.println(String.format("checking %s", buildFile.getAbsolutePath()));
+
+ val lines = _Strings.readAllLines(new FileInputStream(buildFile), StandardCharsets.UTF_8);
+
+ for(val line : lines) {
+ checkBuildFileLine(buildFile, line, knownBuildArtifactNames);
+ }
+
+ }
+
+ private void checkBuildFileLine(File buildFile, String line, Set<String> knownBuildArtifactNames) {
+ val buildArtifactName = parseBuildArtifactName(line);
+ if(buildArtifactName==null) {
+ return;
+ }
+ if(!knownBuildArtifactNames.contains(buildArtifactName)) {
+ hasUnresolvableGradleBuildArtifacts = true;
+ System.err.println(String.format("not found '%s' in file '%s'", buildArtifactName, buildFile));
+ }
+ }
+
+ // compile project(':isis-parent:isis-schema')
+ private String parseBuildArtifactName(String line) {
+ int p = line.indexOf("project('");
+ if(p<0) {
+ return null;
+ }
+ int start = p + 9;
+ int end = line.indexOf("')", start);
+ if(end<0) {
+ return null;
+ }
+ val buildArtifactName = line.substring(start, end);
+ return buildArtifactName;
+ }
+
+}