From f4fcd7c3e6fd7dda00ae155aa59bb903e5532ec0 Mon Sep 17 00:00:00 2001 From: Igor Domagala <259741@student.pwr.edu.pl> Date: Mon, 21 Aug 2023 12:22:27 +0200 Subject: [PATCH 01/20] add test --- sample-gradle/build.gradle | 30 ++--- typescript-generator-gradle-plugin/pom.xml | 28 +++++ .../generator/gradle/GenerateTask.java | 19 +-- .../gradle/BuildLogicFunctionalTest.java | 112 ++++++++++++++++++ 4 files changed, 165 insertions(+), 24 deletions(-) create mode 100644 typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java diff --git a/sample-gradle/build.gradle b/sample-gradle/build.gradle index 0ecd1593e..6364f3f84 100644 --- a/sample-gradle/build.gradle +++ b/sample-gradle/build.gradle @@ -5,7 +5,7 @@ buildscript { // /*dev*/ } dependencies { classpath 'com.fasterxml.jackson.module:jackson-module-scala_2.13:2.14.2' - // /*dev*/ classpath 'cz.habarta.typescript-generator:typescript-generator-gradle-plugin:FILL_VERSION-SNAPSHOT' + classpath files('/Users/igor/typescript-generator/typescript-generator-gradle-plugin/target/typescript-generator-gradle-plugin-3.2-SNAPSHOT.jar') } } @@ -14,10 +14,10 @@ plugins { id 'groovy' id "org.jetbrains.kotlin.jvm" version "1.8.10" id 'scala' - /*prod*/ id 'cz.habarta.typescript-generator' version 'FILL_VERSION' + } -// /*dev*/ apply plugin: 'cz.habarta.typescript-generator' +apply plugin: cz.habarta.typescript.generator.gradle.TypeScriptGeneratorPlugin version = '3.0' sourceCompatibility = 11 @@ -43,24 +43,24 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) { generateTypeScript { classes = [ - 'cz.habarta.typescript.generator.sample.Person', - 'cz.habarta.typescript.generator.sample.PersonGroovy', - 'cz.habarta.typescript.generator.sample.PersonKt', - 'cz.habarta.typescript.generator.sample.PersonScala', + 'cz.habarta.typescript.generator.sample.Person', + 'cz.habarta.typescript.generator.sample.PersonGroovy', + 'cz.habarta.typescript.generator.sample.PersonKt', + 'cz.habarta.typescript.generator.sample.PersonScala', ] jsonLibrary = 'jackson2' outputKind = 'module' excludeClasses = [ - 'groovy.lang.GroovyObject', - 'groovy.lang.MetaClass', - 'java.io.Serializable', - 'scala.Equals', - 'scala.Product', - 'scala.Serializable', + 'groovy.lang.GroovyObject', + 'groovy.lang.MetaClass', + 'java.io.Serializable', + 'scala.Equals', + 'scala.Product', + 'scala.Serializable', ] jackson2Modules = [ - 'com.fasterxml.jackson.module.scala.DefaultScalaModule', - 'com.fasterxml.jackson.module.kotlin.KotlinModule', + 'com.fasterxml.jackson.module.scala.DefaultScalaModule', + 'com.fasterxml.jackson.module.kotlin.KotlinModule', ] } diff --git a/typescript-generator-gradle-plugin/pom.xml b/typescript-generator-gradle-plugin/pom.xml index 43742569d..a06c47781 100644 --- a/typescript-generator-gradle-plugin/pom.xml +++ b/typescript-generator-gradle-plugin/pom.xml @@ -63,6 +63,34 @@ typescript-generator-core 3.2-SNAPSHOT + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-api + test + + + + org.gradle + gradle-test-kit + 6.1.1 + test + + + commons-io + commons-io + 2.11.0 + + diff --git a/typescript-generator-gradle-plugin/src/main/java/cz/habarta/typescript/generator/gradle/GenerateTask.java b/typescript-generator-gradle-plugin/src/main/java/cz/habarta/typescript/generator/gradle/GenerateTask.java index 12b282619..0dbdf5785 100644 --- a/typescript-generator-gradle-plugin/src/main/java/cz/habarta/typescript/generator/gradle/GenerateTask.java +++ b/typescript-generator-gradle-plugin/src/main/java/cz/habarta/typescript/generator/gradle/GenerateTask.java @@ -34,10 +34,13 @@ import java.util.Set; import org.gradle.api.DefaultTask; import org.gradle.api.Task; +import org.gradle.api.file.ConfigurableFileCollection; +import org.gradle.api.tasks.CacheableTask; +import org.gradle.api.tasks.Classpath; import org.gradle.api.tasks.TaskAction; -public class GenerateTask extends DefaultTask { +public abstract class GenerateTask extends DefaultTask { public String outputFile; public TypeScriptFileType outputFileType; @@ -130,6 +133,9 @@ public class GenerateTask extends DefaultTask { public List jackson2Modules; public Logger.Level loggingLevel; + @Classpath + abstract ConfigurableFileCollection getClasspath(); + private Settings createSettings(URLClassLoader classLoader) { final Settings settings = new Settings(); if (outputFileType != null) { @@ -229,14 +235,9 @@ public void generate() throws Exception { // class loader final Set urls = new LinkedHashSet<>(); - for (Task task : getProject().getTasks()) { - if (task.getName().startsWith("compile") && !task.getName().startsWith("compileTest")) { - for (File file : task.getOutputs().getFiles()) { - urls.add(file.toURI().toURL()); - } - } + for (File file : getClasspath()) { + urls.add(file.toURI().toURL()); } - urls.addAll(getFilesFromConfiguration("compileClasspath")); try (URLClassLoader classLoader = Settings.createClassLoader(getProject().getName(), urls.toArray(new URL[0]), Thread.currentThread().getContextClassLoader())) { @@ -276,5 +277,5 @@ private List getFilesFromConfiguration(String configuration) { return Collections.emptyList(); } } - } + diff --git a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java new file mode 100644 index 000000000..b4d3c262a --- /dev/null +++ b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java @@ -0,0 +1,112 @@ +package cz.habarta.typescript.generator.gradle; + +import static org.gradle.testkit.runner.GradleRunner.create; +import static org.junit.jupiter.api.Assertions.*; + +import org.gradle.testkit.runner.BuildResult; +import org.gradle.testkit.runner.GradleRunner; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +import static org.gradle.testkit.runner.TaskOutcome.SUCCESS; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + + +public class BuildLogicFunctionalTest { + + @TempDir File testProjectDir; + private File settingsFile; + private File buildFile; + + @BeforeEach + public void setup() { + // settingsFile = new File(testProjectDir, "settings.gradle"); + buildFile = new File(testProjectDir, "build.gradle"); + } + + + + @Test + public void testConfigurationCache() throws IOException { + + String buildFileContent = "'prepareBuildGradleFile(\n" + + " plugins {\n" + + " id 'java'\n" + + " id 'groovy'\n" + + " id \"org.jetbrains.kotlin.jvm\" version \"1.8.10\"\n" + + " id 'scala'}\n" + + "\n" + + "\n" + + " apply plugin: cz.habarta.typescript.generator.gradle.TypeScriptGeneratorPlugin\n" + + "\n" + + " version = '3.0'\n" + + " sourceCompatibility = 11\n" + + " targetCompatibility = 11\n" + + "\n" + + " repositories {\n" + + " mavenCentral()\n" + + " }\n" + + "\n" + + " generateTypeScript {\n" + + " classes = [\n" + + " 'cz.habarta.typescript.generator.sample.Person',\n" + + " 'cz.habarta.typescript.generator.sample.PersonGroovy',\n" + + " 'cz.habarta.typescript.generator.sample.PersonKt',\n" + + " 'cz.habarta.typescript.generator.sample.PersonScala',\n" + + " ]\n" + + " jsonLibrary = 'jackson2'\n" + + " outputKind = 'module'\n" + + " excludeClasses = [\n" + + " 'groovy.lang.GroovyObject',\n" + + " 'groovy.lang.MetaClass',\n" + + " 'java.io.Serializable',\n" + + " 'scala.Equals',\n" + + " 'scala.Product',\n" + + " 'scala.Serializable',\n" + + " ]\n" + + " jackson2Modules = [\n" + + " 'com.fasterxml.jackson.module.scala.DefaultScalaModule',\n" + + " 'com.fasterxml.jackson.module.kotlin.KotlinModule',\n" + + " ]\n" + + " }\n" + + "\n" + + " build.dependsOn generateTypeScript"; + writeFile(buildFile, buildFileContent); + + BuildResult result = create() + .withProjectDir(testProjectDir) + .withGradleVersion("8.1") + .withPluginClasspath() + .withDebug(true) + .withArguments( + "--stacktrace", + "--info", + "--configuration-cache", + "generateJava", + "build" + ) + .build(); + + assertTrue(result.getOutput().contains("BUILD SUCCESSFUL")); + } + + private void writeFile(File destination, String content) throws IOException { + BufferedWriter output = null; + try { + output = new BufferedWriter(new FileWriter(destination)); + output.write(content); + } finally { + if (output != null) { + output.close(); + } + } + } +} + From 4c933e73f9ce1188fb774d3ac0c3f7b7d40a33f1 Mon Sep 17 00:00:00 2001 From: Igor Domagala <259741@student.pwr.edu.pl> Date: Mon, 28 Aug 2023 11:49:36 +0200 Subject: [PATCH 02/20] add test --- sample-gradle/build.gradle | 30 ++-- typescript-generator-gradle-plugin/pom.xml | 66 +++------ .../generator/gradle/GenerateTask.java | 125 ++++++++-------- .../gradle/TypeScriptGeneratorPlugin.java | 9 +- .../gradle/BuildLogicFunctionalTest.java | 139 ++++++++++-------- .../src/test/resources/build.gradle.template | 62 ++++++++ 6 files changed, 237 insertions(+), 194 deletions(-) create mode 100644 typescript-generator-gradle-plugin/src/test/resources/build.gradle.template diff --git a/sample-gradle/build.gradle b/sample-gradle/build.gradle index 6364f3f84..0205afa4e 100644 --- a/sample-gradle/build.gradle +++ b/sample-gradle/build.gradle @@ -5,7 +5,7 @@ buildscript { // /*dev*/ } dependencies { classpath 'com.fasterxml.jackson.module:jackson-module-scala_2.13:2.14.2' - classpath files('/Users/igor/typescript-generator/typescript-generator-gradle-plugin/target/typescript-generator-gradle-plugin-3.2-SNAPSHOT.jar') + // /*dev*/ classpath 'cz.habarta.typescript-generator:typescript-generator-gradle-plugin:FILL_VERSION-SNAPSHOT' } } @@ -14,10 +14,10 @@ plugins { id 'groovy' id "org.jetbrains.kotlin.jvm" version "1.8.10" id 'scala' - + /*prod*/ id 'cz.habarta.typescript-generator' version '3.2.1263' } -apply plugin: cz.habarta.typescript.generator.gradle.TypeScriptGeneratorPlugin +// /*dev*/ apply plugin: 'cz.habarta.typescript-generator' version = '3.0' sourceCompatibility = 11 @@ -43,24 +43,24 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) { generateTypeScript { classes = [ - 'cz.habarta.typescript.generator.sample.Person', - 'cz.habarta.typescript.generator.sample.PersonGroovy', - 'cz.habarta.typescript.generator.sample.PersonKt', - 'cz.habarta.typescript.generator.sample.PersonScala', + 'cz.habarta.typescript.generator.sample.Person', + 'cz.habarta.typescript.generator.sample.PersonGroovy', + 'cz.habarta.typescript.generator.sample.PersonKt', + 'cz.habarta.typescript.generator.sample.PersonScala', ] jsonLibrary = 'jackson2' outputKind = 'module' excludeClasses = [ - 'groovy.lang.GroovyObject', - 'groovy.lang.MetaClass', - 'java.io.Serializable', - 'scala.Equals', - 'scala.Product', - 'scala.Serializable', + 'groovy.lang.GroovyObject', + 'groovy.lang.MetaClass', + 'java.io.Serializable', + 'scala.Equals', + 'scala.Product', + 'scala.Serializable', ] jackson2Modules = [ - 'com.fasterxml.jackson.module.scala.DefaultScalaModule', - 'com.fasterxml.jackson.module.kotlin.KotlinModule', + 'com.fasterxml.jackson.module.scala.DefaultScalaModule', + 'com.fasterxml.jackson.module.kotlin.KotlinModule', ] } diff --git a/typescript-generator-gradle-plugin/pom.xml b/typescript-generator-gradle-plugin/pom.xml index a06c47781..4b3ada7d2 100644 --- a/typescript-generator-gradle-plugin/pom.xml +++ b/typescript-generator-gradle-plugin/pom.xml @@ -13,51 +13,10 @@ typescript-generator-gradle-plugin - 5.6 + 7.3 - - org.gradle - gradle-core - ${gradle.version} - provided - - - org.gradle - gradle-core-api - ${gradle.version} - provided - - - org.gradle - gradle-model-core - ${gradle.version} - provided - - - org.gradle - gradle-base-services - ${gradle.version} - provided - - - org.gradle - gradle-base-services-groovy - ${gradle.version} - provided - - - org.gradle - gradle-logging - ${gradle.version} - provided - - - org.codehaus.groovy - groovy-all - 2.4.21 - cz.habarta.typescript-generator typescript-generator-core @@ -74,17 +33,28 @@ test - org.junit.jupiter - junit-jupiter-api + dev.gradleplugins + gradle-test-kit + 8.2.1 + + + com.fasterxml.jackson.module + jackson-module-scala_2.13 + 2.14.2 test - - org.gradle - gradle-test-kit - 6.1.1 + com.fasterxml.jackson.module + jackson-module-kotlin + 2.14.2 test + + org.junit.jupiter + junit-jupiter-api + test + + commons-io commons-io diff --git a/typescript-generator-gradle-plugin/src/main/java/cz/habarta/typescript/generator/gradle/GenerateTask.java b/typescript-generator-gradle-plugin/src/main/java/cz/habarta/typescript/generator/gradle/GenerateTask.java index 0dbdf5785..3c1a1199d 100644 --- a/typescript-generator-gradle-plugin/src/main/java/cz/habarta/typescript/generator/gradle/GenerateTask.java +++ b/typescript-generator-gradle-plugin/src/main/java/cz/habarta/typescript/generator/gradle/GenerateTask.java @@ -1,48 +1,27 @@ package cz.habarta.typescript.generator.gradle; -import cz.habarta.typescript.generator.ClassMapping; -import cz.habarta.typescript.generator.DateMapping; -import cz.habarta.typescript.generator.EnumMapping; -import cz.habarta.typescript.generator.GsonConfiguration; -import cz.habarta.typescript.generator.IdentifierCasing; -import cz.habarta.typescript.generator.Input; -import cz.habarta.typescript.generator.Jackson2Configuration; -import cz.habarta.typescript.generator.JsonLibrary; -import cz.habarta.typescript.generator.JsonbConfiguration; -import cz.habarta.typescript.generator.Logger; -import cz.habarta.typescript.generator.MapMapping; -import cz.habarta.typescript.generator.ModuleDependency; -import cz.habarta.typescript.generator.NullabilityDefinition; -import cz.habarta.typescript.generator.OptionalProperties; -import cz.habarta.typescript.generator.OptionalPropertiesDeclaration; -import cz.habarta.typescript.generator.Output; -import cz.habarta.typescript.generator.RestNamespacing; -import cz.habarta.typescript.generator.Settings; -import cz.habarta.typescript.generator.StringQuotes; -import cz.habarta.typescript.generator.TypeScriptFileType; -import cz.habarta.typescript.generator.TypeScriptGenerator; -import cz.habarta.typescript.generator.TypeScriptOutputKind; +import cz.habarta.typescript.generator.*; import cz.habarta.typescript.generator.util.Utils; +import org.gradle.api.DefaultTask; +import org.gradle.api.file.ConfigurableFileCollection; +import org.gradle.api.file.ProjectLayout; +import org.gradle.api.tasks.Classpath; +import org.gradle.api.tasks.TaskAction; +import org.jetbrains.annotations.NotNull; + +import javax.inject.Inject; import java.io.File; +import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; -import org.gradle.api.DefaultTask; -import org.gradle.api.Task; -import org.gradle.api.file.ConfigurableFileCollection; -import org.gradle.api.tasks.CacheableTask; -import org.gradle.api.tasks.Classpath; -import org.gradle.api.tasks.TaskAction; public abstract class GenerateTask extends DefaultTask { - public String outputFile; public TypeScriptFileType outputFileType; public TypeScriptOutputKind outputKind; public String module; @@ -133,9 +112,20 @@ public abstract class GenerateTask extends DefaultTask { public List jackson2Modules; public Logger.Level loggingLevel; + public String projectName; + + private final ProjectLayout projectLayout; + @Classpath abstract ConfigurableFileCollection getClasspath(); + public String outputFile; + + @Inject + public GenerateTask(ProjectLayout projectLayout) { + this.projectLayout = projectLayout; + } + private Settings createSettings(URLClassLoader classLoader) { final Settings settings = new Settings(); if (outputFileType != null) { @@ -206,7 +196,7 @@ private Settings createSettings(URLClassLoader classLoader) { settings.primitivePropertiesRequired = primitivePropertiesRequired; settings.generateInfoJson = generateInfoJson; settings.generateNpmPackageJson = generateNpmPackageJson; - settings.npmName = npmName == null && generateNpmPackageJson ? getProject().getName() : npmName; + settings.npmName = npmName == null && generateNpmPackageJson ? projectName : npmName; settings.npmVersion = npmVersion == null && generateNpmPackageJson ? settings.getDefaultNpmVersion() : npmVersion; settings.npmTypescriptVersion = npmTypescriptVersion; settings.npmBuildScript = npmBuildScript; @@ -221,6 +211,7 @@ private Settings createSettings(URLClassLoader classLoader) { return settings; } + @TaskAction public void generate() throws Exception { if (outputKind == null) { @@ -232,50 +223,54 @@ public void generate() throws Exception { TypeScriptGenerator.setLogger(new Logger(loggingLevel)); TypeScriptGenerator.printVersion(); + try (URLClassLoader classLoader = createClassloader()) { + final Settings settings = createSettings(classLoader); + final Input.Parameters parameters = parameters(classLoader, settings); + File finalOutputFile = calculateOutputFile(settings); + settings.validateFileName(finalOutputFile); + new TypeScriptGenerator(settings).generateTypeScript(Input.from(parameters), Output.to(finalOutputFile)); + } + } + @NotNull + private URLClassLoader createClassloader() throws MalformedURLException { // class loader final Set urls = new LinkedHashSet<>(); for (File file : getClasspath()) { urls.add(file.toURI().toURL()); } + return Settings.createClassLoader(projectName, urls.toArray(new URL[0]), Thread.currentThread().getContextClassLoader()); + } - try (URLClassLoader classLoader = Settings.createClassLoader(getProject().getName(), urls.toArray(new URL[0]), Thread.currentThread().getContextClassLoader())) { - - final Settings settings = createSettings(classLoader); - - final Input.Parameters parameters = new Input.Parameters(); - parameters.classNames = classes; - parameters.classNamePatterns = classPatterns; - parameters.classesWithAnnotations = classesWithAnnotations; - parameters.classesImplementingInterfaces = classesImplementingInterfaces; - parameters.classesExtendingClasses = classesExtendingClasses; - parameters.jaxrsApplicationClassName = classesFromJaxrsApplication; - parameters.automaticJaxrsApplication = classesFromAutomaticJaxrsApplication; - parameters.isClassNameExcluded = settings.getExcludeFilter(); - parameters.classLoader = classLoader; - parameters.scanningAcceptedPackages = scanningAcceptedPackages; - parameters.debug = loggingLevel == Logger.Level.Debug; + @NotNull + private File calculateOutputFile(Settings settings) { + return new File(outputFile != null ? outputFile : defaultOutputFile(settings)); + } - final File output = outputFile != null - ? getProject().file(outputFile) - : new File(new File(getProject().getBuildDir(), "typescript-generator"), getProject().getName() + settings.getExtension()); - settings.validateFileName(output); + @NotNull + private String defaultOutputFile(Settings settings) { + return projectLayout.getBuildDirectory().dir("typescript-generator").get().file(projectName + ext(settings.outputFileType)).getAsFile().getAbsolutePath(); + } - new TypeScriptGenerator(settings).generateTypeScript(Input.from(parameters), Output.to(output)); - } + @NotNull + private Input.Parameters parameters(URLClassLoader classLoader, Settings settings) { + final Input.Parameters parameters = new Input.Parameters(); + parameters.classNames = classes; + parameters.classNamePatterns = classPatterns; + parameters.classesWithAnnotations = classesWithAnnotations; + parameters.classesImplementingInterfaces = classesImplementingInterfaces; + parameters.classesExtendingClasses = classesExtendingClasses; + parameters.jaxrsApplicationClassName = classesFromJaxrsApplication; + parameters.automaticJaxrsApplication = classesFromAutomaticJaxrsApplication; + parameters.isClassNameExcluded = settings.getExcludeFilter(); + parameters.classLoader = classLoader; + parameters.scanningAcceptedPackages = scanningAcceptedPackages; + parameters.debug = loggingLevel == Logger.Level.Debug; + return parameters; } - private List getFilesFromConfiguration(String configuration) { - try { - final List urls = new ArrayList<>(); - for (File file : getProject().getConfigurations().getAt(configuration).getFiles()) { - urls.add(file.toURI().toURL()); - } - return urls; - } catch (Exception e) { - TypeScriptGenerator.getLogger().warning(String.format("Cannot get file names from configuration '%s': %s", configuration, e.getMessage())); - return Collections.emptyList(); - } + private String ext(TypeScriptFileType outputFileType) { + return outputFileType.equals(TypeScriptFileType.implementationFile) ? ".ts" : ".d.ts"; } } diff --git a/typescript-generator-gradle-plugin/src/main/java/cz/habarta/typescript/generator/gradle/TypeScriptGeneratorPlugin.java b/typescript-generator-gradle-plugin/src/main/java/cz/habarta/typescript/generator/gradle/TypeScriptGeneratorPlugin.java index d9e0eb8c4..815a67883 100644 --- a/typescript-generator-gradle-plugin/src/main/java/cz/habarta/typescript/generator/gradle/TypeScriptGeneratorPlugin.java +++ b/typescript-generator-gradle-plugin/src/main/java/cz/habarta/typescript/generator/gradle/TypeScriptGeneratorPlugin.java @@ -1,7 +1,6 @@ package cz.habarta.typescript.generator.gradle; -import java.util.Collections; import org.gradle.api.Plugin; import org.gradle.api.Project; import org.gradle.api.Task; @@ -11,14 +10,14 @@ public class TypeScriptGeneratorPlugin implements Plugin { @Override public void apply(Project project) { - final Task generateTsTask = project.task(Collections.singletonMap(Task.TASK_TYPE, GenerateTask.class), "generateTypeScript"); - + GenerateTask generateTsTask = project.getTasks().create("generateTypeScript", GenerateTask.class); + project.getLogger().warn("Output type: " + generateTsTask.outputFileType); + generateTsTask.projectName = project.getName(); for (Task task : project.getTasks()) { if (task.getName().startsWith("compile") && !task.getName().startsWith("compileTest")) { generateTsTask.dependsOn(task.getName()); - generateTsTask.getInputs().files(task); } } - } + } } diff --git a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java index b4d3c262a..70c731450 100644 --- a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java +++ b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java @@ -1,100 +1,86 @@ package cz.habarta.typescript.generator.gradle; -import static org.gradle.testkit.runner.GradleRunner.create; -import static org.junit.jupiter.api.Assertions.*; - +import org.apache.commons.io.FileUtils; import org.gradle.testkit.runner.BuildResult; import org.gradle.testkit.runner.GradleRunner; +import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; +import sun.misc.Unsafe; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; +import java.lang.reflect.Field; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; -import static org.gradle.testkit.runner.TaskOutcome.SUCCESS; -import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; public class BuildLogicFunctionalTest { - @TempDir File testProjectDir; - private File settingsFile; + + String sampleGradle = "/Users/igor/typescript-generator/sample-gradle"; + File sourceDir = new File(sampleGradle + "/src"); + @TempDir + File testProjectDir; private File buildFile; + private File classpathFile; @BeforeEach - public void setup() { + public void setup() throws IOException { // settingsFile = new File(testProjectDir, "settings.gradle"); + buildFile = new File(testProjectDir, "build.gradle"); + classpathFile = new File(new File(BuildLogicFunctionalTest.class.getResource("/build.gradle.template").getPath()).getParent(), "plugin-under-test-metadata.properties"); } - @Test public void testConfigurationCache() throws IOException { + writeFile(classpathFile, "implementation-classpath=" + getClasspath(testProjectDir).stream().collect(Collectors.joining(File.pathSeparator))); + FileUtils.copyToFile(getClass().getResourceAsStream("/build.gradle.template"), buildFile); + FileUtils.copyDirectory(sourceDir, new File(testProjectDir, "src")); + assertTrue(runGradle("assemble").getOutput().contains("BUILD SUCCESSFUL")); + BuildResult generateTypeScript = runGradle("generateTypeScript"); + assertTrue(generateTypeScript.getOutput().contains("BUILD SUCCESSFUL")); + } - String buildFileContent = "'prepareBuildGradleFile(\n" + - " plugins {\n" + - " id 'java'\n" + - " id 'groovy'\n" + - " id \"org.jetbrains.kotlin.jvm\" version \"1.8.10\"\n" + - " id 'scala'}\n" + - "\n" + - "\n" + - " apply plugin: cz.habarta.typescript.generator.gradle.TypeScriptGeneratorPlugin\n" + - "\n" + - " version = '3.0'\n" + - " sourceCompatibility = 11\n" + - " targetCompatibility = 11\n" + - "\n" + - " repositories {\n" + - " mavenCentral()\n" + - " }\n" + - "\n" + - " generateTypeScript {\n" + - " classes = [\n" + - " 'cz.habarta.typescript.generator.sample.Person',\n" + - " 'cz.habarta.typescript.generator.sample.PersonGroovy',\n" + - " 'cz.habarta.typescript.generator.sample.PersonKt',\n" + - " 'cz.habarta.typescript.generator.sample.PersonScala',\n" + - " ]\n" + - " jsonLibrary = 'jackson2'\n" + - " outputKind = 'module'\n" + - " excludeClasses = [\n" + - " 'groovy.lang.GroovyObject',\n" + - " 'groovy.lang.MetaClass',\n" + - " 'java.io.Serializable',\n" + - " 'scala.Equals',\n" + - " 'scala.Product',\n" + - " 'scala.Serializable',\n" + - " ]\n" + - " jackson2Modules = [\n" + - " 'com.fasterxml.jackson.module.scala.DefaultScalaModule',\n" + - " 'com.fasterxml.jackson.module.kotlin.KotlinModule',\n" + - " ]\n" + - " }\n" + - "\n" + - " build.dependsOn generateTypeScript"; - writeFile(buildFile, buildFileContent); - - BuildResult result = create() + private BuildResult runGradle(String task) { + return GradleRunner.create() .withProjectDir(testProjectDir) - .withGradleVersion("8.1") + .withGradleVersion("8.2.1") .withPluginClasspath() - .withDebug(true) .withArguments( - "--stacktrace", - "--info", + "--stacktrace", + "--info", "--configuration-cache", - "generateJava", - "build" + task ) .build(); + } + + private static List getClasspath(File projectDir) { + List list = new ArrayList<>(Arrays.asList(getUrls(ClassLoader.getSystemClassLoader())).stream().map(URL::getFile).collect(Collectors.toList())); + list.addAll(buildDirs(projectDir.toString())); + return list; + } - assertTrue(result.getOutput().contains("BUILD SUCCESSFUL")); + @NotNull + private static List buildDirs(String sampleGradle) { + List projectBuildDirs = new ArrayList<>(); + projectBuildDirs.add(sampleGradle + "/build/classes/java/main/"); + projectBuildDirs.add(sampleGradle + "/build/classes/groovy/main/"); + projectBuildDirs.add(sampleGradle + "/build/classes/scala/main/"); + projectBuildDirs.add(sampleGradle + "/build/classes/kotlin/main/"); + return projectBuildDirs; } private void writeFile(File destination, String content) throws IOException { @@ -108,5 +94,36 @@ private void writeFile(File destination, String content) throws IOException { } } } + + public static URL[] getUrls(ClassLoader classLoader) { + if (classLoader instanceof URLClassLoader) { + return ((URLClassLoader) classLoader).getURLs(); + } + + // jdk9 + if (classLoader.getClass().getName().startsWith("jdk.internal.loader.ClassLoaders$")) { + try { + Field field = Unsafe.class.getDeclaredField("theUnsafe"); + field.setAccessible(true); + Unsafe unsafe = (Unsafe) field.get(null); + + // jdk.internal.loader.ClassLoaders.AppClassLoader.ucp + Field ucpField = classLoader.getClass().getSuperclass().getDeclaredField("ucp"); + long ucpFieldOffset = unsafe.objectFieldOffset(ucpField); + Object ucpObject = unsafe.getObject(classLoader, ucpFieldOffset); + + // jdk.internal.loader.URLClassPath.path + Field pathField = ucpField.getType().getDeclaredField("path"); + long pathFieldOffset = unsafe.objectFieldOffset(pathField); + ArrayList path = (ArrayList) unsafe.getObject(ucpObject, pathFieldOffset); + + return path.toArray(new URL[path.size()]); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + return null; + } } diff --git a/typescript-generator-gradle-plugin/src/test/resources/build.gradle.template b/typescript-generator-gradle-plugin/src/test/resources/build.gradle.template new file mode 100644 index 000000000..6ad97c0a6 --- /dev/null +++ b/typescript-generator-gradle-plugin/src/test/resources/build.gradle.template @@ -0,0 +1,62 @@ + +buildscript { + dependencies { + classpath 'com.fasterxml.jackson.module:jackson-module-scala_2.13:2.14.2' + } +} + +plugins { + id 'java' + id "org.jetbrains.kotlin.jvm" version "1.9.0" + id 'scala' + id 'groovy' + id 'cz.habarta.typescript-generator' + +} + +version = '3.0' +sourceCompatibility = 11 +targetCompatibility = 11 + +repositories { + mavenCentral() +} + +tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) { + kotlinOptions { + jvmTarget = '11' + } +} + +dependencies { + implementation 'com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:2.14.2' + implementation 'org.codehaus.groovy:groovy-all:3.0.16' + implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.8.10' + implementation 'org.scala-lang:scala-library:2.13.10' + implementation 'com.fasterxml.jackson.module:jackson-module-kotlin:2.14.2' +} + +generateTypeScript { + classes = [ + 'cz.habarta.typescript.generator.sample.Person', + 'cz.habarta.typescript.generator.sample.PersonGroovy', + 'cz.habarta.typescript.generator.sample.PersonKt', + 'cz.habarta.typescript.generator.sample.PersonScala', + ] + jsonLibrary = 'jackson2' + outputKind = 'module' + excludeClasses = [ + 'groovy.lang.GroovyObject', + 'groovy.lang.MetaClass', + 'java.io.Serializable', + 'scala.Equals', + 'scala.Product', + 'scala.Serializable', + ] + jackson2Modules = [ + 'com.fasterxml.jackson.module.scala.DefaultScalaModule', + 'com.fasterxml.jackson.module.kotlin.KotlinModule', + ] +} + +build.dependsOn generateTypeScript From 2b6586a841a770f822543ea3431467430c34340e Mon Sep 17 00:00:00 2001 From: igor Date: Thu, 31 Aug 2023 16:28:54 +0200 Subject: [PATCH 03/20] Add configuration cache compatibility and config cache test --- .../gradle/BuildLogicFunctionalTest.java | 102 ++++++------------ .../gradle/GradlePluginClasspathProvider.java | 70 ++++++++++++ 2 files changed, 103 insertions(+), 69 deletions(-) create mode 100644 typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java diff --git a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java index 70c731450..bed99d0fd 100644 --- a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java +++ b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java @@ -4,30 +4,28 @@ import org.gradle.testkit.runner.BuildResult; import org.gradle.testkit.runner.GradleRunner; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -import sun.misc.Unsafe; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; -import java.lang.reflect.Field; import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; +import java.nio.charset.StandardCharsets; +import static cz.habarta.typescript.generator.gradle.GradlePluginClasspathProvider.getClasspath; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.CoreMatchers.containsString; public class BuildLogicFunctionalTest { - - String sampleGradle = "/Users/igor/typescript-generator/sample-gradle"; + String sampleGradle = "../../typescript-generator/sample-gradle"; File sourceDir = new File(sampleGradle + "/src"); @TempDir File testProjectDir; @@ -35,22 +33,31 @@ public class BuildLogicFunctionalTest { private File classpathFile; @BeforeEach - public void setup() throws IOException { - // settingsFile = new File(testProjectDir, "settings.gradle"); - + public void setup() { buildFile = new File(testProjectDir, "build.gradle"); - classpathFile = new File(new File(BuildLogicFunctionalTest.class.getResource("/build.gradle.template").getPath()).getParent(), "plugin-under-test-metadata.properties"); + classpathFile = new File(buildGradleTemplate().getParent(), "plugin-under-test-metadata.properties"); } - @Test - public void testConfigurationCache() throws IOException { - writeFile(classpathFile, "implementation-classpath=" + getClasspath(testProjectDir).stream().collect(Collectors.joining(File.pathSeparator))); - FileUtils.copyToFile(getClass().getResourceAsStream("/build.gradle.template"), buildFile); + public void shouldWorkWithConfigurationCache() throws IOException, NoSuchFieldException, IllegalAccessException { + String classpath = "implementation-classpath=" + String.join(File.pathSeparator, getClasspath(testProjectDir)); + System.out.println("Classpath: " + classpath); + writeFile(classpathFile, classpath); + FileUtils.copyToFile(buildGradleTemplateUrl().openStream(), buildFile); FileUtils.copyDirectory(sourceDir, new File(testProjectDir, "src")); + assertTrue(runGradle("assemble").getOutput().contains("BUILD SUCCESSFUL")); BuildResult generateTypeScript = runGradle("generateTypeScript"); assertTrue(generateTypeScript.getOutput().contains("BUILD SUCCESSFUL")); + + String testFileName = testProjectDir.getName() + ".d.ts"; + String testFilePath = testProjectDir.toString() + "/build/typescript-generator/" + testFileName; + String schema = FileUtils.readFileToString(new File(testFilePath) , StandardCharsets.UTF_8); + assertThat(schema, containsString("export interface Person {\n")); + assertThat(schema, containsString("export interface PersonGroovy {\n")); + assertThat(schema, containsString("export interface PersonKt {\n")); + assertThat(schema, containsString("export interface PersonScala {\n")); + } private BuildResult runGradle(String task) { @@ -59,71 +66,28 @@ private BuildResult runGradle(String task) { .withGradleVersion("8.2.1") .withPluginClasspath() .withArguments( - "--stacktrace", - "--info", + "--stacktrace", + "--info", "--configuration-cache", task ) .build(); } - private static List getClasspath(File projectDir) { - List list = new ArrayList<>(Arrays.asList(getUrls(ClassLoader.getSystemClassLoader())).stream().map(URL::getFile).collect(Collectors.toList())); - list.addAll(buildDirs(projectDir.toString())); - return list; + @NotNull + private static File buildGradleTemplate() { + return new File(buildGradleTemplateUrl().getPath()); } - @NotNull - private static List buildDirs(String sampleGradle) { - List projectBuildDirs = new ArrayList<>(); - projectBuildDirs.add(sampleGradle + "/build/classes/java/main/"); - projectBuildDirs.add(sampleGradle + "/build/classes/groovy/main/"); - projectBuildDirs.add(sampleGradle + "/build/classes/scala/main/"); - projectBuildDirs.add(sampleGradle + "/build/classes/kotlin/main/"); - return projectBuildDirs; + @Nullable + private static URL buildGradleTemplateUrl() { + return BuildLogicFunctionalTest.class.getResource("/build.gradle.template"); } private void writeFile(File destination, String content) throws IOException { - BufferedWriter output = null; - try { - output = new BufferedWriter(new FileWriter(destination)); + try (BufferedWriter output = new BufferedWriter(new FileWriter(destination))) { output.write(content); - } finally { - if (output != null) { - output.close(); - } - } - } - - public static URL[] getUrls(ClassLoader classLoader) { - if (classLoader instanceof URLClassLoader) { - return ((URLClassLoader) classLoader).getURLs(); - } - - // jdk9 - if (classLoader.getClass().getName().startsWith("jdk.internal.loader.ClassLoaders$")) { - try { - Field field = Unsafe.class.getDeclaredField("theUnsafe"); - field.setAccessible(true); - Unsafe unsafe = (Unsafe) field.get(null); - - // jdk.internal.loader.ClassLoaders.AppClassLoader.ucp - Field ucpField = classLoader.getClass().getSuperclass().getDeclaredField("ucp"); - long ucpFieldOffset = unsafe.objectFieldOffset(ucpField); - Object ucpObject = unsafe.getObject(classLoader, ucpFieldOffset); - - // jdk.internal.loader.URLClassPath.path - Field pathField = ucpField.getType().getDeclaredField("path"); - long pathFieldOffset = unsafe.objectFieldOffset(pathField); - ArrayList path = (ArrayList) unsafe.getObject(ucpObject, pathFieldOffset); - - return path.toArray(new URL[path.size()]); - } catch (Exception e) { - e.printStackTrace(); - return null; - } } - return null; } } diff --git a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java new file mode 100644 index 000000000..d6787f5e0 --- /dev/null +++ b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java @@ -0,0 +1,70 @@ +package cz.habarta.typescript.generator.gradle; + +import org.jetbrains.annotations.NotNull; +import sun.misc.Unsafe; + +import java.io.File; +import java.lang.reflect.Field; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.*; +import java.util.stream.Collectors; + +public class GradlePluginClasspathProvider { + public static List getClasspath(File projectDir) throws NoSuchFieldException, IllegalAccessException { + List list = new ArrayList<>(Arrays.asList(GradlePluginClasspathProvider.getUrls(ClassLoader.getSystemClassLoader())).stream().map(URL::getFile).collect(Collectors.toList())); + list.addAll(buildDirs(projectDir.toString())); + return list; + } + + public static URL[] getUrls(ClassLoader classLoader) throws NoSuchFieldException, IllegalAccessException { + System.out.println(classLoader.getClass().getName()); + if (classLoader instanceof URLClassLoader) { + return ((URLClassLoader) classLoader).getURLs(); + } + + // jdk9 + if (classLoader.getClass().getName().startsWith("jdk.internal.loader.ClassLoaders$")) { + Field field = Unsafe.class.getDeclaredField("theUnsafe"); + field.setAccessible(true); + Unsafe unsafe = (Unsafe) field.get(null); + + // jdk.internal.loader.ClassLoaders.AppClassLoader.ucp + Field ucpField = classLoader.getClass().getSuperclass().getDeclaredField("ucp"); + long ucpFieldOffset = unsafe.objectFieldOffset(ucpField); + Object ucpObject = unsafe.getObject(classLoader, ucpFieldOffset); + + // jdk.internal.loader.URLClassPath.path + Field pathField = ucpField.getType().getDeclaredField("path"); + long pathFieldOffset = unsafe.objectFieldOffset(pathField); + ArrayList path = (ArrayList) unsafe.getObject(ucpObject, pathFieldOffset); + + Field mapField = ucpField.getType().getDeclaredField("lmap"); + long mapFieldOffset = unsafe.objectFieldOffset(mapField); + Map map = (Map) unsafe.getObject(ucpObject, mapFieldOffset); + List all = new ArrayList<>(); + all.addAll(path); + all.addAll(map.keySet().stream().map(url -> { + try { + return new URL(url); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + }).collect(Collectors.toSet())); + return all.toArray(new URL[0]); + } + return null; + } + + @NotNull + private static List buildDirs(String sampleGradleDir) { + List buildDirs = new ArrayList<>(); + buildDirs.add(sampleGradleDir + "/build/classes/java/main/"); + buildDirs.add(sampleGradleDir + "/build/classes/groovy/main/"); + buildDirs.add(sampleGradleDir + "/build/classes/scala/main/"); + buildDirs.add(sampleGradleDir + "/build/classes/kotlin/main/"); + return buildDirs; + } + +} From 89a17f689e5fd24123cf15619c0cc3cccd44c2f7 Mon Sep 17 00:00:00 2001 From: igor Date: Thu, 31 Aug 2023 16:36:07 +0200 Subject: [PATCH 04/20] Revert "Add configuration cache compatibility and config cache test" This reverts commit 2b6586a841a770f822543ea3431467430c34340e. --- .../gradle/BuildLogicFunctionalTest.java | 102 ++++++++++++------ .../gradle/GradlePluginClasspathProvider.java | 70 ------------ 2 files changed, 69 insertions(+), 103 deletions(-) delete mode 100644 typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java diff --git a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java index bed99d0fd..70c731450 100644 --- a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java +++ b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java @@ -4,28 +4,30 @@ import org.gradle.testkit.runner.BuildResult; import org.gradle.testkit.runner.GradleRunner; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; +import sun.misc.Unsafe; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; +import java.lang.reflect.Field; import java.net.URL; -import java.nio.charset.StandardCharsets; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; -import static cz.habarta.typescript.generator.gradle.GradlePluginClasspathProvider.getClasspath; -import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.CoreMatchers.containsString; public class BuildLogicFunctionalTest { - String sampleGradle = "../../typescript-generator/sample-gradle"; + + String sampleGradle = "/Users/igor/typescript-generator/sample-gradle"; File sourceDir = new File(sampleGradle + "/src"); @TempDir File testProjectDir; @@ -33,31 +35,22 @@ public class BuildLogicFunctionalTest { private File classpathFile; @BeforeEach - public void setup() { + public void setup() throws IOException { + // settingsFile = new File(testProjectDir, "settings.gradle"); + buildFile = new File(testProjectDir, "build.gradle"); - classpathFile = new File(buildGradleTemplate().getParent(), "plugin-under-test-metadata.properties"); + classpathFile = new File(new File(BuildLogicFunctionalTest.class.getResource("/build.gradle.template").getPath()).getParent(), "plugin-under-test-metadata.properties"); } + @Test - public void shouldWorkWithConfigurationCache() throws IOException, NoSuchFieldException, IllegalAccessException { - String classpath = "implementation-classpath=" + String.join(File.pathSeparator, getClasspath(testProjectDir)); - System.out.println("Classpath: " + classpath); - writeFile(classpathFile, classpath); - FileUtils.copyToFile(buildGradleTemplateUrl().openStream(), buildFile); + public void testConfigurationCache() throws IOException { + writeFile(classpathFile, "implementation-classpath=" + getClasspath(testProjectDir).stream().collect(Collectors.joining(File.pathSeparator))); + FileUtils.copyToFile(getClass().getResourceAsStream("/build.gradle.template"), buildFile); FileUtils.copyDirectory(sourceDir, new File(testProjectDir, "src")); - assertTrue(runGradle("assemble").getOutput().contains("BUILD SUCCESSFUL")); BuildResult generateTypeScript = runGradle("generateTypeScript"); assertTrue(generateTypeScript.getOutput().contains("BUILD SUCCESSFUL")); - - String testFileName = testProjectDir.getName() + ".d.ts"; - String testFilePath = testProjectDir.toString() + "/build/typescript-generator/" + testFileName; - String schema = FileUtils.readFileToString(new File(testFilePath) , StandardCharsets.UTF_8); - assertThat(schema, containsString("export interface Person {\n")); - assertThat(schema, containsString("export interface PersonGroovy {\n")); - assertThat(schema, containsString("export interface PersonKt {\n")); - assertThat(schema, containsString("export interface PersonScala {\n")); - } private BuildResult runGradle(String task) { @@ -66,28 +59,71 @@ private BuildResult runGradle(String task) { .withGradleVersion("8.2.1") .withPluginClasspath() .withArguments( - "--stacktrace", - "--info", + "--stacktrace", + "--info", "--configuration-cache", task ) .build(); } - @NotNull - private static File buildGradleTemplate() { - return new File(buildGradleTemplateUrl().getPath()); + private static List getClasspath(File projectDir) { + List list = new ArrayList<>(Arrays.asList(getUrls(ClassLoader.getSystemClassLoader())).stream().map(URL::getFile).collect(Collectors.toList())); + list.addAll(buildDirs(projectDir.toString())); + return list; } - @Nullable - private static URL buildGradleTemplateUrl() { - return BuildLogicFunctionalTest.class.getResource("/build.gradle.template"); + @NotNull + private static List buildDirs(String sampleGradle) { + List projectBuildDirs = new ArrayList<>(); + projectBuildDirs.add(sampleGradle + "/build/classes/java/main/"); + projectBuildDirs.add(sampleGradle + "/build/classes/groovy/main/"); + projectBuildDirs.add(sampleGradle + "/build/classes/scala/main/"); + projectBuildDirs.add(sampleGradle + "/build/classes/kotlin/main/"); + return projectBuildDirs; } private void writeFile(File destination, String content) throws IOException { - try (BufferedWriter output = new BufferedWriter(new FileWriter(destination))) { + BufferedWriter output = null; + try { + output = new BufferedWriter(new FileWriter(destination)); output.write(content); + } finally { + if (output != null) { + output.close(); + } + } + } + + public static URL[] getUrls(ClassLoader classLoader) { + if (classLoader instanceof URLClassLoader) { + return ((URLClassLoader) classLoader).getURLs(); + } + + // jdk9 + if (classLoader.getClass().getName().startsWith("jdk.internal.loader.ClassLoaders$")) { + try { + Field field = Unsafe.class.getDeclaredField("theUnsafe"); + field.setAccessible(true); + Unsafe unsafe = (Unsafe) field.get(null); + + // jdk.internal.loader.ClassLoaders.AppClassLoader.ucp + Field ucpField = classLoader.getClass().getSuperclass().getDeclaredField("ucp"); + long ucpFieldOffset = unsafe.objectFieldOffset(ucpField); + Object ucpObject = unsafe.getObject(classLoader, ucpFieldOffset); + + // jdk.internal.loader.URLClassPath.path + Field pathField = ucpField.getType().getDeclaredField("path"); + long pathFieldOffset = unsafe.objectFieldOffset(pathField); + ArrayList path = (ArrayList) unsafe.getObject(ucpObject, pathFieldOffset); + + return path.toArray(new URL[path.size()]); + } catch (Exception e) { + e.printStackTrace(); + return null; + } } + return null; } } diff --git a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java deleted file mode 100644 index d6787f5e0..000000000 --- a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java +++ /dev/null @@ -1,70 +0,0 @@ -package cz.habarta.typescript.generator.gradle; - -import org.jetbrains.annotations.NotNull; -import sun.misc.Unsafe; - -import java.io.File; -import java.lang.reflect.Field; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.*; -import java.util.stream.Collectors; - -public class GradlePluginClasspathProvider { - public static List getClasspath(File projectDir) throws NoSuchFieldException, IllegalAccessException { - List list = new ArrayList<>(Arrays.asList(GradlePluginClasspathProvider.getUrls(ClassLoader.getSystemClassLoader())).stream().map(URL::getFile).collect(Collectors.toList())); - list.addAll(buildDirs(projectDir.toString())); - return list; - } - - public static URL[] getUrls(ClassLoader classLoader) throws NoSuchFieldException, IllegalAccessException { - System.out.println(classLoader.getClass().getName()); - if (classLoader instanceof URLClassLoader) { - return ((URLClassLoader) classLoader).getURLs(); - } - - // jdk9 - if (classLoader.getClass().getName().startsWith("jdk.internal.loader.ClassLoaders$")) { - Field field = Unsafe.class.getDeclaredField("theUnsafe"); - field.setAccessible(true); - Unsafe unsafe = (Unsafe) field.get(null); - - // jdk.internal.loader.ClassLoaders.AppClassLoader.ucp - Field ucpField = classLoader.getClass().getSuperclass().getDeclaredField("ucp"); - long ucpFieldOffset = unsafe.objectFieldOffset(ucpField); - Object ucpObject = unsafe.getObject(classLoader, ucpFieldOffset); - - // jdk.internal.loader.URLClassPath.path - Field pathField = ucpField.getType().getDeclaredField("path"); - long pathFieldOffset = unsafe.objectFieldOffset(pathField); - ArrayList path = (ArrayList) unsafe.getObject(ucpObject, pathFieldOffset); - - Field mapField = ucpField.getType().getDeclaredField("lmap"); - long mapFieldOffset = unsafe.objectFieldOffset(mapField); - Map map = (Map) unsafe.getObject(ucpObject, mapFieldOffset); - List all = new ArrayList<>(); - all.addAll(path); - all.addAll(map.keySet().stream().map(url -> { - try { - return new URL(url); - } catch (MalformedURLException e) { - throw new RuntimeException(e); - } - }).collect(Collectors.toSet())); - return all.toArray(new URL[0]); - } - return null; - } - - @NotNull - private static List buildDirs(String sampleGradleDir) { - List buildDirs = new ArrayList<>(); - buildDirs.add(sampleGradleDir + "/build/classes/java/main/"); - buildDirs.add(sampleGradleDir + "/build/classes/groovy/main/"); - buildDirs.add(sampleGradleDir + "/build/classes/scala/main/"); - buildDirs.add(sampleGradleDir + "/build/classes/kotlin/main/"); - return buildDirs; - } - -} From 18d0b7fa37fb574bc03a21696be877aaf17bfe6c Mon Sep 17 00:00:00 2001 From: IgorDomagala <259741@student.pwr.edu.pl> Date: Thu, 31 Aug 2023 17:37:33 +0200 Subject: [PATCH 05/20] Add configuration cache compatibility and config cache test --- .../gradle/BuildLogicFunctionalTest.java | 102 ++++++++++++------ .../gradle/GradlePluginClasspathProvider.java | 70 ------------ 2 files changed, 69 insertions(+), 103 deletions(-) delete mode 100644 typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java diff --git a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java index bed99d0fd..70c731450 100644 --- a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java +++ b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java @@ -4,28 +4,30 @@ import org.gradle.testkit.runner.BuildResult; import org.gradle.testkit.runner.GradleRunner; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; +import sun.misc.Unsafe; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; +import java.lang.reflect.Field; import java.net.URL; -import java.nio.charset.StandardCharsets; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; -import static cz.habarta.typescript.generator.gradle.GradlePluginClasspathProvider.getClasspath; -import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.CoreMatchers.containsString; public class BuildLogicFunctionalTest { - String sampleGradle = "../../typescript-generator/sample-gradle"; + + String sampleGradle = "/Users/igor/typescript-generator/sample-gradle"; File sourceDir = new File(sampleGradle + "/src"); @TempDir File testProjectDir; @@ -33,31 +35,22 @@ public class BuildLogicFunctionalTest { private File classpathFile; @BeforeEach - public void setup() { + public void setup() throws IOException { + // settingsFile = new File(testProjectDir, "settings.gradle"); + buildFile = new File(testProjectDir, "build.gradle"); - classpathFile = new File(buildGradleTemplate().getParent(), "plugin-under-test-metadata.properties"); + classpathFile = new File(new File(BuildLogicFunctionalTest.class.getResource("/build.gradle.template").getPath()).getParent(), "plugin-under-test-metadata.properties"); } + @Test - public void shouldWorkWithConfigurationCache() throws IOException, NoSuchFieldException, IllegalAccessException { - String classpath = "implementation-classpath=" + String.join(File.pathSeparator, getClasspath(testProjectDir)); - System.out.println("Classpath: " + classpath); - writeFile(classpathFile, classpath); - FileUtils.copyToFile(buildGradleTemplateUrl().openStream(), buildFile); + public void testConfigurationCache() throws IOException { + writeFile(classpathFile, "implementation-classpath=" + getClasspath(testProjectDir).stream().collect(Collectors.joining(File.pathSeparator))); + FileUtils.copyToFile(getClass().getResourceAsStream("/build.gradle.template"), buildFile); FileUtils.copyDirectory(sourceDir, new File(testProjectDir, "src")); - assertTrue(runGradle("assemble").getOutput().contains("BUILD SUCCESSFUL")); BuildResult generateTypeScript = runGradle("generateTypeScript"); assertTrue(generateTypeScript.getOutput().contains("BUILD SUCCESSFUL")); - - String testFileName = testProjectDir.getName() + ".d.ts"; - String testFilePath = testProjectDir.toString() + "/build/typescript-generator/" + testFileName; - String schema = FileUtils.readFileToString(new File(testFilePath) , StandardCharsets.UTF_8); - assertThat(schema, containsString("export interface Person {\n")); - assertThat(schema, containsString("export interface PersonGroovy {\n")); - assertThat(schema, containsString("export interface PersonKt {\n")); - assertThat(schema, containsString("export interface PersonScala {\n")); - } private BuildResult runGradle(String task) { @@ -66,28 +59,71 @@ private BuildResult runGradle(String task) { .withGradleVersion("8.2.1") .withPluginClasspath() .withArguments( - "--stacktrace", - "--info", + "--stacktrace", + "--info", "--configuration-cache", task ) .build(); } - @NotNull - private static File buildGradleTemplate() { - return new File(buildGradleTemplateUrl().getPath()); + private static List getClasspath(File projectDir) { + List list = new ArrayList<>(Arrays.asList(getUrls(ClassLoader.getSystemClassLoader())).stream().map(URL::getFile).collect(Collectors.toList())); + list.addAll(buildDirs(projectDir.toString())); + return list; } - @Nullable - private static URL buildGradleTemplateUrl() { - return BuildLogicFunctionalTest.class.getResource("/build.gradle.template"); + @NotNull + private static List buildDirs(String sampleGradle) { + List projectBuildDirs = new ArrayList<>(); + projectBuildDirs.add(sampleGradle + "/build/classes/java/main/"); + projectBuildDirs.add(sampleGradle + "/build/classes/groovy/main/"); + projectBuildDirs.add(sampleGradle + "/build/classes/scala/main/"); + projectBuildDirs.add(sampleGradle + "/build/classes/kotlin/main/"); + return projectBuildDirs; } private void writeFile(File destination, String content) throws IOException { - try (BufferedWriter output = new BufferedWriter(new FileWriter(destination))) { + BufferedWriter output = null; + try { + output = new BufferedWriter(new FileWriter(destination)); output.write(content); + } finally { + if (output != null) { + output.close(); + } + } + } + + public static URL[] getUrls(ClassLoader classLoader) { + if (classLoader instanceof URLClassLoader) { + return ((URLClassLoader) classLoader).getURLs(); + } + + // jdk9 + if (classLoader.getClass().getName().startsWith("jdk.internal.loader.ClassLoaders$")) { + try { + Field field = Unsafe.class.getDeclaredField("theUnsafe"); + field.setAccessible(true); + Unsafe unsafe = (Unsafe) field.get(null); + + // jdk.internal.loader.ClassLoaders.AppClassLoader.ucp + Field ucpField = classLoader.getClass().getSuperclass().getDeclaredField("ucp"); + long ucpFieldOffset = unsafe.objectFieldOffset(ucpField); + Object ucpObject = unsafe.getObject(classLoader, ucpFieldOffset); + + // jdk.internal.loader.URLClassPath.path + Field pathField = ucpField.getType().getDeclaredField("path"); + long pathFieldOffset = unsafe.objectFieldOffset(pathField); + ArrayList path = (ArrayList) unsafe.getObject(ucpObject, pathFieldOffset); + + return path.toArray(new URL[path.size()]); + } catch (Exception e) { + e.printStackTrace(); + return null; + } } + return null; } } diff --git a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java deleted file mode 100644 index d6787f5e0..000000000 --- a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java +++ /dev/null @@ -1,70 +0,0 @@ -package cz.habarta.typescript.generator.gradle; - -import org.jetbrains.annotations.NotNull; -import sun.misc.Unsafe; - -import java.io.File; -import java.lang.reflect.Field; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.*; -import java.util.stream.Collectors; - -public class GradlePluginClasspathProvider { - public static List getClasspath(File projectDir) throws NoSuchFieldException, IllegalAccessException { - List list = new ArrayList<>(Arrays.asList(GradlePluginClasspathProvider.getUrls(ClassLoader.getSystemClassLoader())).stream().map(URL::getFile).collect(Collectors.toList())); - list.addAll(buildDirs(projectDir.toString())); - return list; - } - - public static URL[] getUrls(ClassLoader classLoader) throws NoSuchFieldException, IllegalAccessException { - System.out.println(classLoader.getClass().getName()); - if (classLoader instanceof URLClassLoader) { - return ((URLClassLoader) classLoader).getURLs(); - } - - // jdk9 - if (classLoader.getClass().getName().startsWith("jdk.internal.loader.ClassLoaders$")) { - Field field = Unsafe.class.getDeclaredField("theUnsafe"); - field.setAccessible(true); - Unsafe unsafe = (Unsafe) field.get(null); - - // jdk.internal.loader.ClassLoaders.AppClassLoader.ucp - Field ucpField = classLoader.getClass().getSuperclass().getDeclaredField("ucp"); - long ucpFieldOffset = unsafe.objectFieldOffset(ucpField); - Object ucpObject = unsafe.getObject(classLoader, ucpFieldOffset); - - // jdk.internal.loader.URLClassPath.path - Field pathField = ucpField.getType().getDeclaredField("path"); - long pathFieldOffset = unsafe.objectFieldOffset(pathField); - ArrayList path = (ArrayList) unsafe.getObject(ucpObject, pathFieldOffset); - - Field mapField = ucpField.getType().getDeclaredField("lmap"); - long mapFieldOffset = unsafe.objectFieldOffset(mapField); - Map map = (Map) unsafe.getObject(ucpObject, mapFieldOffset); - List all = new ArrayList<>(); - all.addAll(path); - all.addAll(map.keySet().stream().map(url -> { - try { - return new URL(url); - } catch (MalformedURLException e) { - throw new RuntimeException(e); - } - }).collect(Collectors.toSet())); - return all.toArray(new URL[0]); - } - return null; - } - - @NotNull - private static List buildDirs(String sampleGradleDir) { - List buildDirs = new ArrayList<>(); - buildDirs.add(sampleGradleDir + "/build/classes/java/main/"); - buildDirs.add(sampleGradleDir + "/build/classes/groovy/main/"); - buildDirs.add(sampleGradleDir + "/build/classes/scala/main/"); - buildDirs.add(sampleGradleDir + "/build/classes/kotlin/main/"); - return buildDirs; - } - -} From 9c0594229f426e2f198e9cbf42a868a22b598b8c Mon Sep 17 00:00:00 2001 From: IgorDomagala <259741@student.pwr.edu.pl> Date: Thu, 31 Aug 2023 17:39:48 +0200 Subject: [PATCH 06/20] Add configuration cache compatibility and config cache test --- .../gradle/BuildLogicFunctionalTest.java | 102 ++++++------------ .../gradle/GradlePluginClasspathProvider.java | 70 ++++++++++++ 2 files changed, 103 insertions(+), 69 deletions(-) create mode 100644 typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java diff --git a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java index 70c731450..bed99d0fd 100644 --- a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java +++ b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java @@ -4,30 +4,28 @@ import org.gradle.testkit.runner.BuildResult; import org.gradle.testkit.runner.GradleRunner; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -import sun.misc.Unsafe; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; -import java.lang.reflect.Field; import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; +import java.nio.charset.StandardCharsets; +import static cz.habarta.typescript.generator.gradle.GradlePluginClasspathProvider.getClasspath; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.CoreMatchers.containsString; public class BuildLogicFunctionalTest { - - String sampleGradle = "/Users/igor/typescript-generator/sample-gradle"; + String sampleGradle = "../../typescript-generator/sample-gradle"; File sourceDir = new File(sampleGradle + "/src"); @TempDir File testProjectDir; @@ -35,22 +33,31 @@ public class BuildLogicFunctionalTest { private File classpathFile; @BeforeEach - public void setup() throws IOException { - // settingsFile = new File(testProjectDir, "settings.gradle"); - + public void setup() { buildFile = new File(testProjectDir, "build.gradle"); - classpathFile = new File(new File(BuildLogicFunctionalTest.class.getResource("/build.gradle.template").getPath()).getParent(), "plugin-under-test-metadata.properties"); + classpathFile = new File(buildGradleTemplate().getParent(), "plugin-under-test-metadata.properties"); } - @Test - public void testConfigurationCache() throws IOException { - writeFile(classpathFile, "implementation-classpath=" + getClasspath(testProjectDir).stream().collect(Collectors.joining(File.pathSeparator))); - FileUtils.copyToFile(getClass().getResourceAsStream("/build.gradle.template"), buildFile); + public void shouldWorkWithConfigurationCache() throws IOException, NoSuchFieldException, IllegalAccessException { + String classpath = "implementation-classpath=" + String.join(File.pathSeparator, getClasspath(testProjectDir)); + System.out.println("Classpath: " + classpath); + writeFile(classpathFile, classpath); + FileUtils.copyToFile(buildGradleTemplateUrl().openStream(), buildFile); FileUtils.copyDirectory(sourceDir, new File(testProjectDir, "src")); + assertTrue(runGradle("assemble").getOutput().contains("BUILD SUCCESSFUL")); BuildResult generateTypeScript = runGradle("generateTypeScript"); assertTrue(generateTypeScript.getOutput().contains("BUILD SUCCESSFUL")); + + String testFileName = testProjectDir.getName() + ".d.ts"; + String testFilePath = testProjectDir.toString() + "/build/typescript-generator/" + testFileName; + String schema = FileUtils.readFileToString(new File(testFilePath) , StandardCharsets.UTF_8); + assertThat(schema, containsString("export interface Person {\n")); + assertThat(schema, containsString("export interface PersonGroovy {\n")); + assertThat(schema, containsString("export interface PersonKt {\n")); + assertThat(schema, containsString("export interface PersonScala {\n")); + } private BuildResult runGradle(String task) { @@ -59,71 +66,28 @@ private BuildResult runGradle(String task) { .withGradleVersion("8.2.1") .withPluginClasspath() .withArguments( - "--stacktrace", - "--info", + "--stacktrace", + "--info", "--configuration-cache", task ) .build(); } - private static List getClasspath(File projectDir) { - List list = new ArrayList<>(Arrays.asList(getUrls(ClassLoader.getSystemClassLoader())).stream().map(URL::getFile).collect(Collectors.toList())); - list.addAll(buildDirs(projectDir.toString())); - return list; + @NotNull + private static File buildGradleTemplate() { + return new File(buildGradleTemplateUrl().getPath()); } - @NotNull - private static List buildDirs(String sampleGradle) { - List projectBuildDirs = new ArrayList<>(); - projectBuildDirs.add(sampleGradle + "/build/classes/java/main/"); - projectBuildDirs.add(sampleGradle + "/build/classes/groovy/main/"); - projectBuildDirs.add(sampleGradle + "/build/classes/scala/main/"); - projectBuildDirs.add(sampleGradle + "/build/classes/kotlin/main/"); - return projectBuildDirs; + @Nullable + private static URL buildGradleTemplateUrl() { + return BuildLogicFunctionalTest.class.getResource("/build.gradle.template"); } private void writeFile(File destination, String content) throws IOException { - BufferedWriter output = null; - try { - output = new BufferedWriter(new FileWriter(destination)); + try (BufferedWriter output = new BufferedWriter(new FileWriter(destination))) { output.write(content); - } finally { - if (output != null) { - output.close(); - } - } - } - - public static URL[] getUrls(ClassLoader classLoader) { - if (classLoader instanceof URLClassLoader) { - return ((URLClassLoader) classLoader).getURLs(); - } - - // jdk9 - if (classLoader.getClass().getName().startsWith("jdk.internal.loader.ClassLoaders$")) { - try { - Field field = Unsafe.class.getDeclaredField("theUnsafe"); - field.setAccessible(true); - Unsafe unsafe = (Unsafe) field.get(null); - - // jdk.internal.loader.ClassLoaders.AppClassLoader.ucp - Field ucpField = classLoader.getClass().getSuperclass().getDeclaredField("ucp"); - long ucpFieldOffset = unsafe.objectFieldOffset(ucpField); - Object ucpObject = unsafe.getObject(classLoader, ucpFieldOffset); - - // jdk.internal.loader.URLClassPath.path - Field pathField = ucpField.getType().getDeclaredField("path"); - long pathFieldOffset = unsafe.objectFieldOffset(pathField); - ArrayList path = (ArrayList) unsafe.getObject(ucpObject, pathFieldOffset); - - return path.toArray(new URL[path.size()]); - } catch (Exception e) { - e.printStackTrace(); - return null; - } } - return null; } } diff --git a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java new file mode 100644 index 000000000..d6787f5e0 --- /dev/null +++ b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java @@ -0,0 +1,70 @@ +package cz.habarta.typescript.generator.gradle; + +import org.jetbrains.annotations.NotNull; +import sun.misc.Unsafe; + +import java.io.File; +import java.lang.reflect.Field; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.*; +import java.util.stream.Collectors; + +public class GradlePluginClasspathProvider { + public static List getClasspath(File projectDir) throws NoSuchFieldException, IllegalAccessException { + List list = new ArrayList<>(Arrays.asList(GradlePluginClasspathProvider.getUrls(ClassLoader.getSystemClassLoader())).stream().map(URL::getFile).collect(Collectors.toList())); + list.addAll(buildDirs(projectDir.toString())); + return list; + } + + public static URL[] getUrls(ClassLoader classLoader) throws NoSuchFieldException, IllegalAccessException { + System.out.println(classLoader.getClass().getName()); + if (classLoader instanceof URLClassLoader) { + return ((URLClassLoader) classLoader).getURLs(); + } + + // jdk9 + if (classLoader.getClass().getName().startsWith("jdk.internal.loader.ClassLoaders$")) { + Field field = Unsafe.class.getDeclaredField("theUnsafe"); + field.setAccessible(true); + Unsafe unsafe = (Unsafe) field.get(null); + + // jdk.internal.loader.ClassLoaders.AppClassLoader.ucp + Field ucpField = classLoader.getClass().getSuperclass().getDeclaredField("ucp"); + long ucpFieldOffset = unsafe.objectFieldOffset(ucpField); + Object ucpObject = unsafe.getObject(classLoader, ucpFieldOffset); + + // jdk.internal.loader.URLClassPath.path + Field pathField = ucpField.getType().getDeclaredField("path"); + long pathFieldOffset = unsafe.objectFieldOffset(pathField); + ArrayList path = (ArrayList) unsafe.getObject(ucpObject, pathFieldOffset); + + Field mapField = ucpField.getType().getDeclaredField("lmap"); + long mapFieldOffset = unsafe.objectFieldOffset(mapField); + Map map = (Map) unsafe.getObject(ucpObject, mapFieldOffset); + List all = new ArrayList<>(); + all.addAll(path); + all.addAll(map.keySet().stream().map(url -> { + try { + return new URL(url); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + }).collect(Collectors.toSet())); + return all.toArray(new URL[0]); + } + return null; + } + + @NotNull + private static List buildDirs(String sampleGradleDir) { + List buildDirs = new ArrayList<>(); + buildDirs.add(sampleGradleDir + "/build/classes/java/main/"); + buildDirs.add(sampleGradleDir + "/build/classes/groovy/main/"); + buildDirs.add(sampleGradleDir + "/build/classes/scala/main/"); + buildDirs.add(sampleGradleDir + "/build/classes/kotlin/main/"); + return buildDirs; + } + +} From 4c7118af6b2c21ce7a707121c1bf9f387a98741b Mon Sep 17 00:00:00 2001 From: IgorDomagala <259741@student.pwr.edu.pl> Date: Mon, 4 Sep 2023 10:56:14 +0200 Subject: [PATCH 07/20] minor fixes --- sample-gradle/build.gradle | 2 +- typescript-generator-gradle-plugin/pom.xml | 2 +- .../typescript/generator/gradle/BuildLogicFunctionalTest.java | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/sample-gradle/build.gradle b/sample-gradle/build.gradle index 0205afa4e..0ecd1593e 100644 --- a/sample-gradle/build.gradle +++ b/sample-gradle/build.gradle @@ -14,7 +14,7 @@ plugins { id 'groovy' id "org.jetbrains.kotlin.jvm" version "1.8.10" id 'scala' - /*prod*/ id 'cz.habarta.typescript-generator' version '3.2.1263' + /*prod*/ id 'cz.habarta.typescript-generator' version 'FILL_VERSION' } // /*dev*/ apply plugin: 'cz.habarta.typescript-generator' diff --git a/typescript-generator-gradle-plugin/pom.xml b/typescript-generator-gradle-plugin/pom.xml index 4b3ada7d2..148ab9900 100644 --- a/typescript-generator-gradle-plugin/pom.xml +++ b/typescript-generator-gradle-plugin/pom.xml @@ -13,7 +13,7 @@ typescript-generator-gradle-plugin - 7.3 + 5.6 diff --git a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java index bed99d0fd..b20bd997b 100644 --- a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java +++ b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java @@ -17,7 +17,6 @@ import java.nio.charset.StandardCharsets; import static cz.habarta.typescript.generator.gradle.GradlePluginClasspathProvider.getClasspath; -import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.CoreMatchers.containsString; From 7409a9b5be00f29762f1504d352ff37d8c7ed41e Mon Sep 17 00:00:00 2001 From: IgorDomagala <259741@student.pwr.edu.pl> Date: Mon, 4 Sep 2023 15:04:27 +0200 Subject: [PATCH 08/20] add configuration cache - minor fixes --- typescript-generator-gradle-plugin/pom.xml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/typescript-generator-gradle-plugin/pom.xml b/typescript-generator-gradle-plugin/pom.xml index 148ab9900..124ab7753 100644 --- a/typescript-generator-gradle-plugin/pom.xml +++ b/typescript-generator-gradle-plugin/pom.xml @@ -27,11 +27,6 @@ junit-jupiter-api test - - org.junit.jupiter - junit-jupiter-api - test - dev.gradleplugins gradle-test-kit @@ -49,11 +44,6 @@ 2.14.2 test - - org.junit.jupiter - junit-jupiter-api - test - commons-io From d9d16ee5fe606a7fb840fc6cbb126f27b2216f01 Mon Sep 17 00:00:00 2001 From: IgorDomagala <259741@student.pwr.edu.pl> Date: Mon, 4 Sep 2023 15:28:28 +0200 Subject: [PATCH 09/20] add configuration cache - minor fixes and windows support --- .../gradle/GradlePluginClasspathProvider.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java index d6787f5e0..ba6f8ed1d 100644 --- a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java +++ b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java @@ -60,11 +60,11 @@ public static URL[] getUrls(ClassLoader classLoader) throws NoSuchFieldException @NotNull private static List buildDirs(String sampleGradleDir) { List buildDirs = new ArrayList<>(); - buildDirs.add(sampleGradleDir + "/build/classes/java/main/"); - buildDirs.add(sampleGradleDir + "/build/classes/groovy/main/"); - buildDirs.add(sampleGradleDir + "/build/classes/scala/main/"); - buildDirs.add(sampleGradleDir + "/build/classes/kotlin/main/"); + buildDirs.add(sampleGradleDir + File.separator +"build" + File.separator + "classes" + File.separator + "java" + File.separator + "main" + File.separator); + buildDirs.add(sampleGradleDir + File.separator +"build"+ File.separator +"classes"+ File.separator +"groovy"+ File.separator +"main"+ File.separator); + buildDirs.add(sampleGradleDir + File.separator +"build"+ File.separator +"classes"+ File.separator +"scala"+ File.separator +"main"+ File.separator); + buildDirs.add(sampleGradleDir + File.separator +"build"+ File.separator +"classes"+ File.separator +"kotlin"+ File.separator +"main"+ File.separator);; return buildDirs; } -} +} \ No newline at end of file From 13b783f5cd5a2bea304a9cc607255c9fbf41c6a1 Mon Sep 17 00:00:00 2001 From: IgorDomagala <259741@student.pwr.edu.pl> Date: Tue, 5 Sep 2023 17:32:36 +0200 Subject: [PATCH 10/20] add configuration cache - minor fixes and windows support --- .../gradle/GradlePluginClasspathProvider.java | 58 +++++++++++++------ 1 file changed, 39 insertions(+), 19 deletions(-) diff --git a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java index ba6f8ed1d..b651f08e3 100644 --- a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java +++ b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java @@ -6,22 +6,27 @@ import java.io.File; import java.lang.reflect.Field; import java.net.MalformedURLException; +import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; import java.util.stream.Collectors; public class GradlePluginClasspathProvider { + public static List getClasspath(File projectDir) throws NoSuchFieldException, IllegalAccessException { - List list = new ArrayList<>(Arrays.asList(GradlePluginClasspathProvider.getUrls(ClassLoader.getSystemClassLoader())).stream().map(URL::getFile).collect(Collectors.toList())); + List list = GradlePluginClasspathProvider.getUrls(ClassLoader.getSystemClassLoader()).stream().map(file -> file.getAbsolutePath()).collect(Collectors.toList()); list.addAll(buildDirs(projectDir.toString())); return list; } - public static URL[] getUrls(ClassLoader classLoader) throws NoSuchFieldException, IllegalAccessException { + public static List getUrls(ClassLoader classLoader) throws NoSuchFieldException, IllegalAccessException { System.out.println(classLoader.getClass().getName()); if (classLoader instanceof URLClassLoader) { - return ((URLClassLoader) classLoader).getURLs(); + return (Arrays.asList(((URLClassLoader) classLoader).getURLs())).stream().map(URL -> toFile(URL)).collect(Collectors.toList()); } // jdk9 @@ -38,32 +43,47 @@ public static URL[] getUrls(ClassLoader classLoader) throws NoSuchFieldException // jdk.internal.loader.URLClassPath.path Field pathField = ucpField.getType().getDeclaredField("path"); long pathFieldOffset = unsafe.objectFieldOffset(pathField); - ArrayList path = (ArrayList) unsafe.getObject(ucpObject, pathFieldOffset); + List path = (ArrayList) unsafe.getObject(ucpObject, pathFieldOffset); Field mapField = ucpField.getType().getDeclaredField("lmap"); long mapFieldOffset = unsafe.objectFieldOffset(mapField); Map map = (Map) unsafe.getObject(ucpObject, mapFieldOffset); - List all = new ArrayList<>(); - all.addAll(path); - all.addAll(map.keySet().stream().map(url -> { - try { - return new URL(url); - } catch (MalformedURLException e) { - throw new RuntimeException(e); - } - }).collect(Collectors.toSet())); - return all.toArray(new URL[0]); + List all = new ArrayList<>(); + all.addAll(path.stream().map(URL -> toFile(URL)).collect(Collectors.toList())); + all.addAll(map.keySet().stream().map(url -> toFile(asUrl(url))).collect(Collectors.toSet())); + return all; } + return null; } + @NotNull + private static URL asUrl(String url) { + try { + return new URL(url); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + } + + @NotNull + private static File toFile(URL url) { + try { + return new File(url.toURI()); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + } + + @NotNull private static List buildDirs(String sampleGradleDir) { List buildDirs = new ArrayList<>(); - buildDirs.add(sampleGradleDir + File.separator +"build" + File.separator + "classes" + File.separator + "java" + File.separator + "main" + File.separator); - buildDirs.add(sampleGradleDir + File.separator +"build"+ File.separator +"classes"+ File.separator +"groovy"+ File.separator +"main"+ File.separator); - buildDirs.add(sampleGradleDir + File.separator +"build"+ File.separator +"classes"+ File.separator +"scala"+ File.separator +"main"+ File.separator); - buildDirs.add(sampleGradleDir + File.separator +"build"+ File.separator +"classes"+ File.separator +"kotlin"+ File.separator +"main"+ File.separator);; + buildDirs.add(String.join(File.separator, sampleGradleDir, "build", "classes", "java", "main")); + buildDirs.add(String.join(File.separator, sampleGradleDir, "build", "classes", "groovy", "main")); + buildDirs.add(String.join(File.separator, sampleGradleDir, "build", "classes", "scala", "main")); + buildDirs.add(String.join(File.separator, sampleGradleDir, "build", "classes", "kotlin", "main")); + return buildDirs; } From 60b8cb5a33152069739cdc45cc37c9eae5dfa084 Mon Sep 17 00:00:00 2001 From: IgorDomagala <259741@student.pwr.edu.pl> Date: Tue, 5 Sep 2023 17:47:27 +0200 Subject: [PATCH 11/20] add configuration cache - minor fixes and windows support --- .../typescript/generator/gradle/BuildLogicFunctionalTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java index b20bd997b..effb5fe4f 100644 --- a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java +++ b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java @@ -39,7 +39,7 @@ public void setup() { @Test public void shouldWorkWithConfigurationCache() throws IOException, NoSuchFieldException, IllegalAccessException { - String classpath = "implementation-classpath=" + String.join(File.pathSeparator, getClasspath(testProjectDir)); + String classpath = "implementation-classpath=" + String.join(":", getClasspath(testProjectDir)); System.out.println("Classpath: " + classpath); writeFile(classpathFile, classpath); FileUtils.copyToFile(buildGradleTemplateUrl().openStream(), buildFile); From 232695a7907c59404338cce8604e327327273e1e Mon Sep 17 00:00:00 2001 From: Igor <259741@student.pwr.edu.pl> Date: Thu, 7 Sep 2023 15:32:53 +0200 Subject: [PATCH 12/20] add windows support --- .../gradle/BuildLogicFunctionalTest.java | 13 ++++---- .../gradle/GradlePluginClasspathProvider.java | 32 +++++++++++-------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java index effb5fe4f..a686038c1 100644 --- a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java +++ b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java @@ -39,7 +39,7 @@ public void setup() { @Test public void shouldWorkWithConfigurationCache() throws IOException, NoSuchFieldException, IllegalAccessException { - String classpath = "implementation-classpath=" + String.join(":", getClasspath(testProjectDir)); + String classpath = "implementation-classpath=" + String.join(";", getClasspath(testProjectDir)); System.out.println("Classpath: " + classpath); writeFile(classpathFile, classpath); FileUtils.copyToFile(buildGradleTemplateUrl().openStream(), buildFile); @@ -50,12 +50,12 @@ public void shouldWorkWithConfigurationCache() throws IOException, NoSuchFieldEx assertTrue(generateTypeScript.getOutput().contains("BUILD SUCCESSFUL")); String testFileName = testProjectDir.getName() + ".d.ts"; - String testFilePath = testProjectDir.toString() + "/build/typescript-generator/" + testFileName; + String testFilePath = testProjectDir + File.separator + "build" + File.separator + "typescript-generator" + File.separator + testFileName; String schema = FileUtils.readFileToString(new File(testFilePath) , StandardCharsets.UTF_8); - assertThat(schema, containsString("export interface Person {\n")); - assertThat(schema, containsString("export interface PersonGroovy {\n")); - assertThat(schema, containsString("export interface PersonKt {\n")); - assertThat(schema, containsString("export interface PersonScala {\n")); + assertThat(schema, containsString("export interface Person {")); + assertThat(schema, containsString("export interface PersonGroovy {")); + assertThat(schema, containsString("export interface PersonKt {")); + assertThat(schema, containsString("export interface PersonScala {")); } @@ -65,6 +65,7 @@ private BuildResult runGradle(String task) { .withGradleVersion("8.2.1") .withPluginClasspath() .withArguments( + // "-Dorg.gradle.jvmargs='-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005'", "--stacktrace", "--info", "--configuration-cache", diff --git a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java index b651f08e3..4294f6e2a 100644 --- a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java +++ b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java @@ -1,26 +1,32 @@ package cz.habarta.typescript.generator.gradle; +import org.apache.commons.io.FileUtils; import org.jetbrains.annotations.NotNull; import sun.misc.Unsafe; import java.io.File; import java.lang.reflect.Field; -import java.net.MalformedURLException; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLClassLoader; +import java.net.*; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import static org.apache.commons.io.FileUtils.readFileToString; + public class GradlePluginClasspathProvider { public static List getClasspath(File projectDir) throws NoSuchFieldException, IllegalAccessException { - List list = GradlePluginClasspathProvider.getUrls(ClassLoader.getSystemClassLoader()).stream().map(file -> file.getAbsolutePath()).collect(Collectors.toList()); - list.addAll(buildDirs(projectDir.toString())); - return list; + List list = GradlePluginClasspathProvider.getUrls(ClassLoader.getSystemClassLoader()); + list.addAll(buildDirs(projectDir)); + return list.stream().map(file -> path(file)).collect(Collectors.toList()); + } + + @NotNull + private static String path(File file) { + String path = file.getAbsolutePath(); + return path.replace("\\", "\\\\"); } public static List getUrls(ClassLoader classLoader) throws NoSuchFieldException, IllegalAccessException { @@ -77,12 +83,12 @@ private static File toFile(URL url) { @NotNull - private static List buildDirs(String sampleGradleDir) { - List buildDirs = new ArrayList<>(); - buildDirs.add(String.join(File.separator, sampleGradleDir, "build", "classes", "java", "main")); - buildDirs.add(String.join(File.separator, sampleGradleDir, "build", "classes", "groovy", "main")); - buildDirs.add(String.join(File.separator, sampleGradleDir, "build", "classes", "scala", "main")); - buildDirs.add(String.join(File.separator, sampleGradleDir, "build", "classes", "kotlin", "main")); + private static List buildDirs(File sampleGradleDir) { + List buildDirs = new ArrayList<>(); + buildDirs.add(FileUtils.getFile( sampleGradleDir, "build", "classes", "java", "main")); + buildDirs.add(FileUtils.getFile( sampleGradleDir, "build", "classes", "groovy", "main")); + buildDirs.add(FileUtils.getFile( sampleGradleDir, "build", "classes", "scala", "main")); + buildDirs.add(FileUtils.getFile( sampleGradleDir, "build", "classes", "kotlin", "main")); return buildDirs; } From 8ca5a5826457fe22697eb8fe668d79b492dea75b Mon Sep 17 00:00:00 2001 From: IgorDomagala <259741@student.pwr.edu.pl> Date: Thu, 7 Sep 2023 16:47:57 +0200 Subject: [PATCH 13/20] add configuration cache - minor fixes and windows support --- .../generator/gradle/BuildLogicFunctionalTest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java index a686038c1..c0940903b 100644 --- a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java +++ b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java @@ -17,6 +17,8 @@ import java.nio.charset.StandardCharsets; import static cz.habarta.typescript.generator.gradle.GradlePluginClasspathProvider.getClasspath; +import static java.io.File.pathSeparator; +import static java.io.File.separator; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.CoreMatchers.containsString; @@ -39,7 +41,7 @@ public void setup() { @Test public void shouldWorkWithConfigurationCache() throws IOException, NoSuchFieldException, IllegalAccessException { - String classpath = "implementation-classpath=" + String.join(";", getClasspath(testProjectDir)); + String classpath = "implementation-classpath=" + String.join(pathSeparator, getClasspath(testProjectDir)); System.out.println("Classpath: " + classpath); writeFile(classpathFile, classpath); FileUtils.copyToFile(buildGradleTemplateUrl().openStream(), buildFile); @@ -50,7 +52,7 @@ public void shouldWorkWithConfigurationCache() throws IOException, NoSuchFieldEx assertTrue(generateTypeScript.getOutput().contains("BUILD SUCCESSFUL")); String testFileName = testProjectDir.getName() + ".d.ts"; - String testFilePath = testProjectDir + File.separator + "build" + File.separator + "typescript-generator" + File.separator + testFileName; + String testFilePath = testProjectDir + separator + "build" + separator + "typescript-generator" + separator + testFileName; String schema = FileUtils.readFileToString(new File(testFilePath) , StandardCharsets.UTF_8); assertThat(schema, containsString("export interface Person {")); assertThat(schema, containsString("export interface PersonGroovy {")); From c47a5e3707b3ac4d466ee3e81fc299843001f8d8 Mon Sep 17 00:00:00 2001 From: IgorDomagala <259741@student.pwr.edu.pl> Date: Tue, 12 Sep 2023 12:35:13 +0200 Subject: [PATCH 14/20] match with checkstyle requirements, change dependencies --- typescript-generator-gradle-plugin/pom.xml | 49 +++++++++++++++++-- .../generator/gradle/GenerateTask.java | 39 +++++++++++---- .../gradle/BuildLogicFunctionalTest.java | 27 +++++----- .../gradle/GradlePluginClasspathProvider.java | 14 +++--- 4 files changed, 95 insertions(+), 34 deletions(-) diff --git a/typescript-generator-gradle-plugin/pom.xml b/typescript-generator-gradle-plugin/pom.xml index 124ab7753..0638bb2b2 100644 --- a/typescript-generator-gradle-plugin/pom.xml +++ b/typescript-generator-gradle-plugin/pom.xml @@ -18,9 +18,40 @@ - cz.habarta.typescript-generator - typescript-generator-core - 3.2-SNAPSHOT + org.gradle + gradle-core + ${gradle.version} + provided + + + org.gradle + gradle-core-api + ${gradle.version} + provided + + + org.gradle + gradle-model-core + ${gradle.version} + provided + + + org.gradle + gradle-base-services + ${gradle.version} + provided + + + org.gradle + gradle-base-services-groovy + ${gradle.version} + provided + + + org.gradle + gradle-logging + ${gradle.version} + provided org.junit.jupiter @@ -31,6 +62,7 @@ dev.gradleplugins gradle-test-kit 8.2.1 + test com.fasterxml.jackson.module @@ -38,6 +70,11 @@ 2.14.2 test + + cz.habarta.typescript-generator + typescript-generator-core + 3.2-SNAPSHOT + com.fasterxml.jackson.module jackson-module-kotlin @@ -50,6 +87,12 @@ commons-io 2.11.0 + + org.sonatype.sisu + sisu-inject-bean + 2.3.0 + compile + diff --git a/typescript-generator-gradle-plugin/src/main/java/cz/habarta/typescript/generator/gradle/GenerateTask.java b/typescript-generator-gradle-plugin/src/main/java/cz/habarta/typescript/generator/gradle/GenerateTask.java index 3c1a1199d..6f69d4ef4 100644 --- a/typescript-generator-gradle-plugin/src/main/java/cz/habarta/typescript/generator/gradle/GenerateTask.java +++ b/typescript-generator-gradle-plugin/src/main/java/cz/habarta/typescript/generator/gradle/GenerateTask.java @@ -1,16 +1,29 @@ package cz.habarta.typescript.generator.gradle; -import cz.habarta.typescript.generator.*; +import cz.habarta.typescript.generator.ClassMapping; +import cz.habarta.typescript.generator.DateMapping; +import cz.habarta.typescript.generator.EnumMapping; +import cz.habarta.typescript.generator.GsonConfiguration; +import cz.habarta.typescript.generator.IdentifierCasing; +import cz.habarta.typescript.generator.Input; +import cz.habarta.typescript.generator.Jackson2Configuration; +import cz.habarta.typescript.generator.JsonLibrary; +import cz.habarta.typescript.generator.JsonbConfiguration; +import cz.habarta.typescript.generator.Logger; +import cz.habarta.typescript.generator.MapMapping; +import cz.habarta.typescript.generator.ModuleDependency; +import cz.habarta.typescript.generator.NullabilityDefinition; +import cz.habarta.typescript.generator.OptionalProperties; +import cz.habarta.typescript.generator.OptionalPropertiesDeclaration; +import cz.habarta.typescript.generator.Output; +import cz.habarta.typescript.generator.RestNamespacing; +import cz.habarta.typescript.generator.Settings; +import cz.habarta.typescript.generator.StringQuotes; +import cz.habarta.typescript.generator.TypeScriptFileType; +import cz.habarta.typescript.generator.TypeScriptGenerator; +import cz.habarta.typescript.generator.TypeScriptOutputKind; import cz.habarta.typescript.generator.util.Utils; -import org.gradle.api.DefaultTask; -import org.gradle.api.file.ConfigurableFileCollection; -import org.gradle.api.file.ProjectLayout; -import org.gradle.api.tasks.Classpath; -import org.gradle.api.tasks.TaskAction; -import org.jetbrains.annotations.NotNull; - -import javax.inject.Inject; import java.io.File; import java.net.MalformedURLException; import java.net.URL; @@ -18,6 +31,14 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Set; +import javax.inject.Inject; +import org.gradle.api.DefaultTask; +import org.gradle.api.file.ConfigurableFileCollection; +import org.gradle.api.file.ProjectLayout; +import org.gradle.api.tasks.Classpath; +import org.gradle.api.tasks.TaskAction; +import org.jetbrains.annotations.NotNull; + public abstract class GenerateTask extends DefaultTask { diff --git a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java index c0940903b..62ef5940d 100644 --- a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java +++ b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java @@ -1,29 +1,26 @@ package cz.habarta.typescript.generator.gradle; +import static cz.habarta.typescript.generator.gradle.GradlePluginClasspathProvider.getClasspath; +import java.io.BufferedWriter; +import java.io.File; +import static java.io.File.pathSeparator; +import static java.io.File.separator; +import java.io.FileWriter; +import java.io.IOException; +import java.net.URL; +import java.nio.charset.StandardCharsets; import org.apache.commons.io.FileUtils; import org.gradle.testkit.runner.BuildResult; import org.gradle.testkit.runner.GradleRunner; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.MatcherAssert.assertThat; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.net.URL; -import java.nio.charset.StandardCharsets; - -import static cz.habarta.typescript.generator.gradle.GradlePluginClasspathProvider.getClasspath; -import static java.io.File.pathSeparator; -import static java.io.File.separator; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.CoreMatchers.containsString; - - public class BuildLogicFunctionalTest { String sampleGradle = "../../typescript-generator/sample-gradle"; diff --git a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java index 4294f6e2a..a4993e046 100644 --- a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java +++ b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java @@ -1,19 +1,19 @@ package cz.habarta.typescript.generator.gradle; -import org.apache.commons.io.FileUtils; -import org.jetbrains.annotations.NotNull; -import sun.misc.Unsafe; - import java.io.File; import java.lang.reflect.Field; -import java.net.*; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.stream.Collectors; - -import static org.apache.commons.io.FileUtils.readFileToString; +import org.apache.commons.io.FileUtils; +import org.jetbrains.annotations.NotNull; +import sun.misc.Unsafe; public class GradlePluginClasspathProvider { From 68f5adf2719efbed1b4c384fe38257a72a211958 Mon Sep 17 00:00:00 2001 From: IgorDomagala <259741@student.pwr.edu.pl> Date: Tue, 12 Sep 2023 14:43:46 +0200 Subject: [PATCH 15/20] change dependencies, add compatibility with older gradle versions --- typescript-generator-gradle-plugin/pom.xml | 5 +++++ .../generator/gradle/TypeScriptGeneratorPlugin.java | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/typescript-generator-gradle-plugin/pom.xml b/typescript-generator-gradle-plugin/pom.xml index 0638bb2b2..b76a8c974 100644 --- a/typescript-generator-gradle-plugin/pom.xml +++ b/typescript-generator-gradle-plugin/pom.xml @@ -53,6 +53,11 @@ ${gradle.version} provided + + org.codehaus.groovy + groovy-all + 2.4.21 + org.junit.jupiter junit-jupiter-api diff --git a/typescript-generator-gradle-plugin/src/main/java/cz/habarta/typescript/generator/gradle/TypeScriptGeneratorPlugin.java b/typescript-generator-gradle-plugin/src/main/java/cz/habarta/typescript/generator/gradle/TypeScriptGeneratorPlugin.java index 815a67883..23a4f43b2 100644 --- a/typescript-generator-gradle-plugin/src/main/java/cz/habarta/typescript/generator/gradle/TypeScriptGeneratorPlugin.java +++ b/typescript-generator-gradle-plugin/src/main/java/cz/habarta/typescript/generator/gradle/TypeScriptGeneratorPlugin.java @@ -11,7 +11,6 @@ public class TypeScriptGeneratorPlugin implements Plugin { @Override public void apply(Project project) { GenerateTask generateTsTask = project.getTasks().create("generateTypeScript", GenerateTask.class); - project.getLogger().warn("Output type: " + generateTsTask.outputFileType); generateTsTask.projectName = project.getName(); for (Task task : project.getTasks()) { if (task.getName().startsWith("compile") && !task.getName().startsWith("compileTest")) { From 8420c8606b683111b4a805a49d26abbdaad5d221 Mon Sep 17 00:00:00 2001 From: IgorDomagala <259741@student.pwr.edu.pl> Date: Tue, 12 Sep 2023 17:47:04 +0200 Subject: [PATCH 16/20] change dependencies, add compatibility with older gradle versions --- typescript-generator-gradle-plugin/pom.xml | 13 +++++++------ .../gradle/BuildLogicFunctionalTest.java | 7 +++++-- .../gradle/GradlePluginClasspathProvider.java | 16 +++++++++++----- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/typescript-generator-gradle-plugin/pom.xml b/typescript-generator-gradle-plugin/pom.xml index b76a8c974..e055512b3 100644 --- a/typescript-generator-gradle-plugin/pom.xml +++ b/typescript-generator-gradle-plugin/pom.xml @@ -17,6 +17,12 @@ + + dev.gradleplugins + gradle-test-kit + 8.2.1 + test + org.gradle gradle-core @@ -63,12 +69,7 @@ junit-jupiter-api test - - dev.gradleplugins - gradle-test-kit - 8.2.1 - test - + com.fasterxml.jackson.module jackson-module-scala_2.13 diff --git a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java index 62ef5940d..4014c748a 100644 --- a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java +++ b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java @@ -25,6 +25,9 @@ public class BuildLogicFunctionalTest { String sampleGradle = "../../typescript-generator/sample-gradle"; File sourceDir = new File(sampleGradle + "/src"); + + @TempDir + File testKitDir; @TempDir File testProjectDir; private File buildFile; @@ -50,7 +53,7 @@ public void shouldWorkWithConfigurationCache() throws IOException, NoSuchFieldEx String testFileName = testProjectDir.getName() + ".d.ts"; String testFilePath = testProjectDir + separator + "build" + separator + "typescript-generator" + separator + testFileName; - String schema = FileUtils.readFileToString(new File(testFilePath) , StandardCharsets.UTF_8); + String schema = FileUtils.readFileToString(new File(testFilePath), StandardCharsets.UTF_8); assertThat(schema, containsString("export interface Person {")); assertThat(schema, containsString("export interface PersonGroovy {")); assertThat(schema, containsString("export interface PersonKt {")); @@ -59,12 +62,12 @@ public void shouldWorkWithConfigurationCache() throws IOException, NoSuchFieldEx } private BuildResult runGradle(String task) { + System.setProperty("org.gradle.testkit.dir", testKitDir.getAbsolutePath()); return GradleRunner.create() .withProjectDir(testProjectDir) .withGradleVersion("8.2.1") .withPluginClasspath() .withArguments( - // "-Dorg.gradle.jvmargs='-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005'", "--stacktrace", "--info", "--configuration-cache", diff --git a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java index a4993e046..d7fabf2bc 100644 --- a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java +++ b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/GradlePluginClasspathProvider.java @@ -18,11 +18,17 @@ public class GradlePluginClasspathProvider { public static List getClasspath(File projectDir) throws NoSuchFieldException, IllegalAccessException { - List list = GradlePluginClasspathProvider.getUrls(ClassLoader.getSystemClassLoader()); + List list = GradlePluginClasspathProvider.getUrls(ClassLoader.getSystemClassLoader()) + .stream().filter(file -> !gradleDependency(file)) + .collect(Collectors.toList()); list.addAll(buildDirs(projectDir)); return list.stream().map(file -> path(file)).collect(Collectors.toList()); } + private static boolean gradleDependency(File file) { + return file.getAbsolutePath().contains(String.format("%sorg%sgradle%s", File.separator, File.separator, File.separator)); + } + @NotNull private static String path(File file) { String path = file.getAbsolutePath(); @@ -85,10 +91,10 @@ private static File toFile(URL url) { @NotNull private static List buildDirs(File sampleGradleDir) { List buildDirs = new ArrayList<>(); - buildDirs.add(FileUtils.getFile( sampleGradleDir, "build", "classes", "java", "main")); - buildDirs.add(FileUtils.getFile( sampleGradleDir, "build", "classes", "groovy", "main")); - buildDirs.add(FileUtils.getFile( sampleGradleDir, "build", "classes", "scala", "main")); - buildDirs.add(FileUtils.getFile( sampleGradleDir, "build", "classes", "kotlin", "main")); + buildDirs.add(FileUtils.getFile(sampleGradleDir, "build", "classes", "java", "main")); + buildDirs.add(FileUtils.getFile(sampleGradleDir, "build", "classes", "groovy", "main")); + buildDirs.add(FileUtils.getFile(sampleGradleDir, "build", "classes", "scala", "main")); + buildDirs.add(FileUtils.getFile(sampleGradleDir, "build", "classes", "kotlin", "main")); return buildDirs; } From ed0ba6e3f6eb7eb88944b785298c7b2bf113fadc Mon Sep 17 00:00:00 2001 From: IgorDomagala <259741@student.pwr.edu.pl> Date: Tue, 12 Sep 2023 18:17:22 +0200 Subject: [PATCH 17/20] change jackson-databind version --- typescript-generator-core/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/typescript-generator-core/pom.xml b/typescript-generator-core/pom.xml index 97d105a30..ea7effd92 100644 --- a/typescript-generator-core/pom.xml +++ b/typescript-generator-core/pom.xml @@ -22,6 +22,7 @@ com.fasterxml.jackson.core jackson-databind + 2.14.0 com.fasterxml.jackson.module From 114173dcd2d23548354c48068164d23732cd934a Mon Sep 17 00:00:00 2001 From: IgorDomagala <259741@student.pwr.edu.pl> Date: Thu, 14 Sep 2023 15:28:37 +0200 Subject: [PATCH 18/20] add BuildLogicFunctionalTest compatibility with windows --- .../gradle/BuildLogicFunctionalTest.java | 46 ++++++++++++------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java index 4014c748a..e5d0b4dbb 100644 --- a/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java +++ b/typescript-generator-gradle-plugin/src/test/java/cz/habarta/typescript/generator/gradle/BuildLogicFunctionalTest.java @@ -1,5 +1,6 @@ package cz.habarta.typescript.generator.gradle; +import com.google.common.io.Files; import static cz.habarta.typescript.generator.gradle.GradlePluginClasspathProvider.getClasspath; import java.io.BufferedWriter; import java.io.File; @@ -25,9 +26,8 @@ public class BuildLogicFunctionalTest { String sampleGradle = "../../typescript-generator/sample-gradle"; File sourceDir = new File(sampleGradle + "/src"); + private File testKitDir = Files.createTempDir(); - @TempDir - File testKitDir; @TempDir File testProjectDir; private File buildFile; @@ -41,24 +41,36 @@ public void setup() { @Test public void shouldWorkWithConfigurationCache() throws IOException, NoSuchFieldException, IllegalAccessException { - String classpath = "implementation-classpath=" + String.join(pathSeparator, getClasspath(testProjectDir)); - System.out.println("Classpath: " + classpath); - writeFile(classpathFile, classpath); - FileUtils.copyToFile(buildGradleTemplateUrl().openStream(), buildFile); - FileUtils.copyDirectory(sourceDir, new File(testProjectDir, "src")); + try { + String classpath = "implementation-classpath=" + String.join(pathSeparator, getClasspath(testProjectDir)); + System.out.println("Classpath: " + classpath); + writeFile(classpathFile, classpath); + FileUtils.copyToFile(buildGradleTemplateUrl().openStream(), buildFile); + FileUtils.copyDirectory(sourceDir, new File(testProjectDir, "src")); - assertTrue(runGradle("assemble").getOutput().contains("BUILD SUCCESSFUL")); - BuildResult generateTypeScript = runGradle("generateTypeScript"); - assertTrue(generateTypeScript.getOutput().contains("BUILD SUCCESSFUL")); + assertTrue(runGradle("assemble").getOutput().contains("BUILD SUCCESSFUL")); + BuildResult generateTypeScript = runGradle("generateTypeScript"); + assertTrue(generateTypeScript.getOutput().contains("BUILD SUCCESSFUL")); - String testFileName = testProjectDir.getName() + ".d.ts"; - String testFilePath = testProjectDir + separator + "build" + separator + "typescript-generator" + separator + testFileName; - String schema = FileUtils.readFileToString(new File(testFilePath), StandardCharsets.UTF_8); - assertThat(schema, containsString("export interface Person {")); - assertThat(schema, containsString("export interface PersonGroovy {")); - assertThat(schema, containsString("export interface PersonKt {")); - assertThat(schema, containsString("export interface PersonScala {")); + String testFileName = testProjectDir.getName() + ".d.ts"; + String testFilePath = testProjectDir + separator + "build" + separator + "typescript-generator" + separator + testFileName; + String schema = FileUtils.readFileToString(new File(testFilePath), StandardCharsets.UTF_8); + assertThat(schema, containsString("export interface Person {")); + assertThat(schema, containsString("export interface PersonGroovy {")); + assertThat(schema, containsString("export interface PersonKt {")); + assertThat(schema, containsString("export interface PersonScala {")); + } finally { + deleteGradleDir(testKitDir); + } + } + private static void deleteGradleDir(File testKitDir) { + try { + FileUtils.deleteDirectory(testKitDir); + }catch (IOException e) + { + //might happen on Windows but should be ignored + } } private BuildResult runGradle(String task) { From 4cd38ac8d2a65773b2fbf5b564e650e07b073a8c Mon Sep 17 00:00:00 2001 From: IgorDomagala <259741@student.pwr.edu.pl> Date: Thu, 14 Sep 2023 16:02:15 +0200 Subject: [PATCH 19/20] minor fixes --- typescript-generator-core/pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/typescript-generator-core/pom.xml b/typescript-generator-core/pom.xml index ea7effd92..97d105a30 100644 --- a/typescript-generator-core/pom.xml +++ b/typescript-generator-core/pom.xml @@ -22,7 +22,6 @@ com.fasterxml.jackson.core jackson-databind - 2.14.0 com.fasterxml.jackson.module From 577df0ff92a87f635033886b9997dcb03aad1647 Mon Sep 17 00:00:00 2001 From: IgorDomagala <259741@student.pwr.edu.pl> Date: Thu, 14 Sep 2023 16:16:40 +0200 Subject: [PATCH 20/20] minor fixes --- typescript-generator-gradle-plugin/pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/typescript-generator-gradle-plugin/pom.xml b/typescript-generator-gradle-plugin/pom.xml index e055512b3..67131d82b 100644 --- a/typescript-generator-gradle-plugin/pom.xml +++ b/typescript-generator-gradle-plugin/pom.xml @@ -23,6 +23,11 @@ 8.2.1 test + + com.fasterxml.jackson.core + jackson-databind + 2.14.2 + org.gradle gradle-core