Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,13 @@ publishing {
}


// The de.rwth.se.cdgen plugin lives in the standalone ./cdgradle build. To also check and publish it, we have to add it here.
def cdgradleBuild = gradle.includedBuilds.find { it.name == 'cdgradle' }
if (cdgradleBuild != null) {
tasks.named('check') { dependsOn cdgradleBuild.task(':check') }
tasks.named('publish') { dependsOn cdgradleBuild.task(':publish') }
}

/*
TODO (ALu): Once all dependant projects are published,
we can properly use transitive dependencies:
Expand Down
52 changes: 52 additions & 0 deletions cdgradle-it/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/* (c) https://github.com/MontiCore/monticore */

def cdgradleBuild = gradle.includedBuilds.find { it.name == 'cdgradle' }

configurations {
cdgenPluginRuntime
}

dependencies {
cdgenPluginRuntime "de.se_rwth.commons:se-commons-gradle:$mc_version"
cdgenPluginRuntime "de.se_rwth.commons:se-commons-logging:$mc_version"

testImplementation project(':cdlang')

testImplementation gradleTestKit()
testImplementation "org.junit.jupiter:junit-jupiter-api:$junit_version"
testImplementation "org.junit.jupiter:junit-jupiter-params:$junit_version"
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junit_version"
testRuntimeOnly "org.junit.platform:junit-platform-launcher:$junit_version"
testImplementation "commons-io:commons-io:2.21.0"
}

tasks.named('test', Test) {
useJUnitPlatform()

def cd4aJar = project(':cdlang').tasks.named('jar').flatMap { it.archiveFile }
def cdRuntimeJar = project(':cd-runtime').tasks.named('jar').flatMap { it.archiveFile }
def pluginRuntime = configurations.cdgenPluginRuntime

dependsOn cd4aJar, cdRuntimeJar
inputs.files(cd4aJar, cdRuntimeJar, pluginRuntime)

File pluginJar = null
if (cdgradleBuild != null) {
pluginJar = new File(cdgradleBuild.projectDir, "target/libs/cdgradle-${version}.jar")
dependsOn cdgradleBuild.task(':jar')
inputs.file(pluginJar).withPropertyName('cdgradlePluginJar')
}
def resolvedPluginJar = pluginJar

doFirst {
def cp = ([resolvedPluginJar] + pluginRuntime.files.toList()).findAll { it != null }
systemProperty 'cdgen.pluginClasspath', cp*.absolutePath.join(File.pathSeparator)
systemProperty 'cdgen.cd4aJar', cd4aJar.get().asFile.absolutePath
systemProperty 'cdgen.runtimeJar', cdRuntimeJar.get().asFile.absolutePath
systemProperty 'cdgen.version', version.toString()

// MontiVerse passthrough
systemProperty 'maven.repo.local', System.getProperty('maven.repo.local') ?: ''
systemProperty 'useLocalRepo', findProperty('useLocalRepo') ?: ''
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/* (c) https://github.com/MontiCore/monticore */
package de.monticore.cdgen;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;

import de.monticore.cd4code.CD4CodeMill;
import de.monticore.symbols.basicsymbols.BasicSymbolsMill;
import de.se_rwth.commons.logging.LogStub;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.io.FileUtils;
import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.GradleRunner;
import org.gradle.testkit.runner.TaskOutcome;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.io.TempDir;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

public class CDGenGradlePluginTest {

private static final List<File> PLUGIN_CLASSPATH = parseClasspath("cdgen.pluginClasspath");

private static final String CD4A_JAR = requiredProperty("cdgen.cd4aJar");

private static final String RUNTIME_JAR = requiredProperty("cdgen.runtimeJar");

private static final String VERSION = requiredProperty("cdgen.version");

@TempDir
File testProjectDir;

@ParameterizedTest
@ValueSource(strings = { "8.5", "8.7", "8.14" })
public void testCDGen(String gradleVersion) throws IOException {
FileUtils.copyDirectory(new File("src/test/resources/testProject"), testProjectDir);

BuildResult result = runner(gradleVersion).withArguments(withProperties("build", "--info",
"--stacktrace")).build();
assertEquals(TaskOutcome.SUCCESS, result.task(":generateClassDiagrams").getOutcome());
assertEquals(TaskOutcome.SUCCESS, result.task(":compileJava").getOutcome());

String log = result.getOutput().replace('\\', '/');
assertTrue(log.contains("/cd-runtime/target/libs/") && log.contains("-cd-runtime.jar"),
"cdToolTargetRuntime was not the local :cd-runtime build");
assertFalse(log.matches("(?s).*modules-2/files-[^\\s\"]*/de\\.monticore\\.lang/cd4analysis/.*"),
"a Nexus de.monticore.lang:cd4analysis leaked onto the generator classpath");

File symbolsOut = new File(testProjectDir, "build/cdgensymbols/main/original/MyCD.cdsym");
assertTrue(symbolsOut.exists(), "Exported original symbols missing");

// The generated symbols must be resolvable
LogStub.initPlusLog();
CD4CodeMill.init();
BasicSymbolsMill.initializePrimitives();
BasicSymbolsMill.initializeString();
CD4CodeMill.globalScope().getSymbolPath().addEntry(symbolsOut.getParentFile().toPath());
CD4CodeMill.globalScope().loadDiagram("MyCD");

CD4CodeMill.globalScope().resolveMethod("MyCD.MyCD.CanBeObserved.getName");
// Check for a method within a class, which is TOPed
// We explicitly expect the method to be resolvable via IncompleteA
CD4CodeMill.globalScope().resolveMethod("MyCD.MyCD.IncompleteA.getName");
CD4CodeMill.globalScope().resolveType("MyCD.MyCD.BBuilder");

Assertions.assertEquals(0, LogStub.getFindingsCount());
CD4CodeMill.reset();
}

/** The plugin with a decorator in a custom source set and a custom config template. */
@ParameterizedTest
@ValueSource(strings = { "8.5", "8.7", "8.14" })
public void testCDGenOwnDecorator(String gradleVersion) throws IOException {
FileUtils.copyDirectory(new File("src/test/resources/testProject"), testProjectDir);

BuildResult result = runner(gradleVersion).withArguments(withProperties("build", "--info",
"--stacktrace", "-PwithCustomDec=true")).build();
assertEquals(TaskOutcome.SUCCESS, result.task(":generateClassDiagrams").getOutcome());
assertEquals(TaskOutcome.SUCCESS, result.task(":compileJava").getOutcome());

if (!result.getOutput().contains("I am decorating")) {
System.err.println(result.getOutput());
fail("Failed to find \"I am decorating\" in output");
}
}

private GradleRunner runner(String gradleVersion) {
return GradleRunner.create().withPluginClasspath(PLUGIN_CLASSPATH).withGradleVersion(
gradleVersion).withProjectDir(testProjectDir);
}

private List<String> withProperties(String... args) {
List<String> ret = new ArrayList<>(Arrays.asList(args));

String mavenRepo = System.getProperty("maven.repo.local");
if (mavenRepo != null && !mavenRepo.isEmpty()) {
ret.add("-Dmaven.repo.local=" + mavenRepo);
}
String useLocalRepo = System.getProperty("useLocalRepo");
if (useLocalRepo != null && !useLocalRepo.isEmpty()) {
ret.add("-PuseLocalRepo=" + useLocalRepo);
}

ret.add("-Pversion=" + VERSION);
ret.add("-Pcdgen_cd4aJarFile=" + CD4A_JAR);
ret.add("-Pcdgen_runtimeJarFile=" + RUNTIME_JAR);
return ret;
}

private static List<File> parseClasspath(String propertyKey) {
return Arrays.stream(requiredProperty(propertyKey).split(File.pathSeparator)).map(File::new)
.collect(Collectors.toList());
}

private static String requiredProperty(String key) {
String value = System.getProperty(key);
if (value == null || value.isEmpty()) {
throw new IllegalStateException("system property '" + key
+ "' is not set -- run this via the :cdgradle-it:test task");
}
return value;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
useLocalRepo=false
12 changes: 12 additions & 0 deletions cdgradle-it/src/test/resources/testProject/settings.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* (c) https://github.com/MontiCore/monticore */
pluginManagement {
repositories {
if (("true").equals(providers.gradleProperty('useLocalRepo').getOrElse('false'))) {
mavenLocal()
}
mavenCentral()
gradlePluginPortal()
maven { url = "https://nexus.se.rwth-aachen.de/content/groups/public" }
}
}
rootProject.name = 'testProject'
72 changes: 72 additions & 0 deletions cdgradle/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/* (c) https://github.com/MontiCore/monticore */
plugins {
id 'java-library'
id 'java-gradle-plugin'
id 'maven-publish'
id 'de.se_rwth.codestyle' version "$mc_version"
}

group = 'de.monticore.lang.cd4analysis'

layout.buildDirectory = layout.projectDirectory.dir('target')

repositories {
if (providers.gradleProperty('useLocalRepo').getOrElse('false') == 'true') {
mavenLocal()
}
maven {
url = providers.gradleProperty('repo')
.getOrElse('https://nexus.se.rwth-aachen.de/content/groups/public')
def u = providers.gradleProperty('mavenUser')
def p = providers.gradleProperty('mavenPassword')
if (u.present && p.present) {
credentials {
username = u.get()
password = p.get()
}
}
}
mavenCentral()
}

dependencies {
implementation "de.se_rwth.commons:se-commons-gradle:$mc_version"
implementation "de.se_rwth.commons:se-commons-logging:$mc_version"
}

gradlePlugin {
plugins {
cdplugin {
id = "de.rwth.se.cdgen"
implementationClass = "de.monticore.cdgen.gradleplugin.CDGenGradlePlugin"
}
}
}

publishing {
repositories.maven {
credentials.username = mavenUser
credentials.password = mavenPassword
def releasesRepoUrl = "https://nexus.se.rwth-aachen.de/content/repositories/monticore-releases/"
def snapshotsRepoUrl = "https://nexus.se.rwth-aachen.de/content/repositories/monticore-snapshots/"
url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
}
}

def buildInfoVersion = project.version.toString()

tasks.register('generateResources') {
ext {
propFile = layout.buildDirectory.file("generated/buildInfo.properties")
}
outputs.file propFile
doLast {
File f = propFile.get().asFile
f.parentFile.mkdirs()
f.text = "version=$buildInfoVersion"
}
}
processResources {
from files(generateResources)
dependsOn generateResources
}
11 changes: 11 additions & 0 deletions cdgradle/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# (c) https://github.com/MontiCore/monticore
mavenUser=${username}
mavenPassword=${password}

version=7.10.0-SNAPSHOT
mc_version=7.10.0-SNAPSHOT

repo=https://nexus.se.rwth-aachen.de/content/groups/public
useLocalRepo=false

org.gradle.jvmargs=-Xmx2048m
24 changes: 24 additions & 0 deletions cdgradle/settings.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/* (c) https://github.com/MontiCore/monticore */

pluginManagement {
repositories {
if (providers.gradleProperty('useLocalRepo').getOrElse('false') == 'true') {
mavenLocal()
}
maven {
url = providers.gradleProperty('repo')
.getOrElse('https://nexus.se.rwth-aachen.de/content/groups/public')
if (providers.gradleProperty('mavenUser').present
&& providers.gradleProperty('mavenPassword').present) {
credentials {
username = providers.gradleProperty('mavenUser').get()
password = providers.gradleProperty('mavenPassword').get()
}
}
}
mavenCentral()
gradlePluginPortal()
}
}

rootProject.name = 'cdgradle'
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import org.gradle.api.tasks.*;

/**
* Gradle Task of the {@link de.monticore.cdgen.CDGenTool} It is an all-files task, as -i A.cd -i
* Gradle Task of the {@code de.monticore.cdgen.CDGenTool} It is an all-files task, as -i A.cd -i
* B.cd is allowed
*/
@CacheableTask
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* (c) https://github.com/MontiCore/monticore */
package de.monticore.cdgen.gradleplugin;

import de.monticore.gradle.common.GradleLog;
import de.se_rwth.commons.logging.Log;

import java.util.Arrays;

public class CDGenToolInvoker {

protected static final String CDGEN_TOOL_CLASS = "de.monticore.cdgen.CDGenTool";

public static void run(String[] args) {
GradleLog.init();
Log.info("Starting CDGenTool: \n" + "\t java -jar CDGenTool.jar " + Arrays.toString(args),
CDGenToolInvoker.class.getName());
invokeGradleMain(args);
}

public static void invokeGradleMain(String[] args) {
try {
Class.forName(CDGEN_TOOL_CLASS).getMethod("gradleMain", String[].class).invoke(null,
(Object) args);
}
catch (ReflectiveOperationException e) {
throw new IllegalStateException("Could not invoke " + CDGEN_TOOL_CLASS
+ ".gradleMain(String[]); is the cd4analysis generator on the cdTool configuration?", e);
}
}

}
21 changes: 21 additions & 0 deletions cdlang-it/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/* (c) https://github.com/MontiCore/monticore */

plugins {
id 'de.rwth.se.cdgen'
}

dependencies {
cdTool project(':cdlang')
cdToolTargetRuntime project(':cd-runtime')

testImplementation "de.se_rwth.commons:se-commons-logging:$mc_version"
testImplementation "de.se_rwth.commons:se-commons-utilities:$mc_version"

testImplementation platform('org.junit:junit-bom:5.10.0')
testImplementation 'org.junit.jupiter:junit-jupiter'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

tasks.named('generateTestClassDiagrams') {
coCos = true
}
Loading