Skip to content

Commit

Permalink
Merge pull request #551 from freefair/feature/plantuml
Browse files Browse the repository at this point in the history
Add PlantUml Plugin
  • Loading branch information
Frisch12 committed Jun 18, 2022
2 parents 216e7b7 + 4a5ac9d commit b04ff31
Show file tree
Hide file tree
Showing 16 changed files with 298 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -209,3 +209,6 @@ gradle-app.setting
**/build/

# End of https://www.gitignore.io/api/IntelliJ,macOS,osx,linux,windows,Gradle,java,gradle,lombok

lombok.config
**/gen/
1 change: 1 addition & 0 deletions build.gradle
Expand Up @@ -60,6 +60,7 @@ allprojects {
testImplementation 'org.assertj:assertj-core:3.23.1'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.8.2'
testImplementation 'org.mockito:mockito-core:4.6.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
}
}
Expand Down
17 changes: 17 additions & 0 deletions examples/plantuml/build.gradle
@@ -0,0 +1,17 @@
import io.freefair.gradle.plugins.plantuml.PlantumlTask

plugins {
id "io.freefair.plantuml"
}

plantUml {
fileFormat = "PNG"
outputDirectory = layout.buildDirectory.dir("dist")
}

tasks.register("plantUml2", PlantumlTask) {
source("src/plantuml2")
includePattern = "**/*.tuml"
fileFormat = "SVG"
outputDirectory = layout.buildDirectory.dir("dist2")
}
3 changes: 3 additions & 0 deletions examples/plantuml/src/plantuml/include/test-i.iuml
@@ -0,0 +1,3 @@
@startuml

@enduml
9 changes: 9 additions & 0 deletions examples/plantuml/src/plantuml/test.puml
@@ -0,0 +1,9 @@
@startuml
!include include/test-i.iuml

Alice -> Bob: Authentication Request
Bob --> Alice: Authentication Response

Alice -> Bob: Another authentication Request
Alice <-- Bob: another authentication Response
@enduml
7 changes: 7 additions & 0 deletions examples/plantuml/src/plantuml2/test2.tuml
@@ -0,0 +1,7 @@
@startuml
Alice -> Bob: Authentication Request
Bob --> Alice: Authentication Response

Alice -> Bob: Another authentication Request
Alice <-- Bob: another authentication Response
@enduml
1 change: 1 addition & 0 deletions examples/settings.gradle
Expand Up @@ -42,3 +42,4 @@ include ":code-generator:generator"
include ":test-maven-plugin"

include 'quicktype'
include 'plantuml'
Empty file added plantuml-plugin/README.md
Empty file.
27 changes: 27 additions & 0 deletions plantuml-plugin/build.gradle
@@ -0,0 +1,27 @@
apply plugin: "maven-publish"
apply plugin: "java-gradle-plugin"
apply plugin: "com.gradle.plugin-publish"

description = "Gradle Plugin for PlantUML"

dependencies {
//noinspection GradlePackageUpdate
compileOnly 'net.sourceforge.plantuml:plantuml:1.2022.5'

testRuntimeOnly 'net.sourceforge.plantuml:plantuml:1.2022.5'
}

gradlePlugin {
plugins {
plantuml {
id = "io.freefair.plantuml"
implementationClass = "io.freefair.gradle.plugins.plantuml.PlantumlPlugin"
displayName = "PlantUML Plugin"
description = "PlantUML Plugin"
}
}
}

pluginBundle {
tags = ["plantuml"]
}
@@ -0,0 +1,36 @@
package io.freefair.gradle.plugins.plantuml;

import lombok.SneakyThrows;
import net.sourceforge.plantuml.FileFormat;
import net.sourceforge.plantuml.FileFormatOption;
import net.sourceforge.plantuml.SourceFileReader;
import org.gradle.workers.WorkAction;

/**
* Gradle {@link WorkAction} for PlantUML {@link SourceFileReader}.
*
* @author Lars Grefer
* @see SourceFileReader
*/
public abstract class PlantumlAction implements WorkAction<PlantumlParameters> {

@SneakyThrows
@Override
public void execute() {

FileFormat fileFormat = getParameters().getFileFormat()
.map(String::toUpperCase)
.map(FileFormat::valueOf)
.getOrElse(FileFormat.PNG);

FileFormatOption fileFormatOption = new FileFormatOption(fileFormat, getParameters().getWithMetadata().get());

SourceFileReader sourceFileReader = new SourceFileReader(
getParameters().getInputFile().getAsFile().get(),
getParameters().getOutputDirectory().getAsFile().get(),
fileFormatOption
);

sourceFileReader.getGeneratedImages();
}
}
@@ -0,0 +1,23 @@
package io.freefair.gradle.plugins.plantuml;

import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.provider.Property;
import org.gradle.workers.WorkParameters;

/**
* {@link WorkParameters} for {@link PlantumlAction}.
*
* @author Lars Grefer
* @see PlantumlPlugin
*/
public interface PlantumlParameters extends WorkParameters {

RegularFileProperty getInputFile();

DirectoryProperty getOutputDirectory();

Property<String> getFileFormat();

Property<Boolean> getWithMetadata();
}
@@ -0,0 +1,30 @@
package io.freefair.gradle.plugins.plantuml;


import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;

/**
* @author Lars Grefer
*/
public class PlantumlPlugin implements Plugin<Project> {

@Override
public void apply(Project project) {
Configuration plantuml = project.getConfigurations().create("plantuml");

plantuml.defaultDependencies(s -> {
s.add(project.getDependencies().create("net.sourceforge.plantuml:plantuml:1.2022.5"));
});

project.getTasks().withType(PlantumlTask.class).configureEach(plantumlTask -> {
plantumlTask.getPlantumlClasspath().from(plantuml);
plantumlTask.getOutputDirectory().convention(project.getLayout().getBuildDirectory().dir("plantuml"));
});

project.getTasks().register("plantUml", PlantumlTask.class, plantumlTask -> {
plantumlTask.source("src/plantuml");
});
}
}
@@ -0,0 +1,71 @@
package io.freefair.gradle.plugins.plantuml;

import lombok.Getter;
import org.gradle.api.file.ConfigurableFileCollection;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.file.FileSystemOperations;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.*;
import org.gradle.workers.WorkQueue;
import org.gradle.workers.WorkerExecutor;

import javax.inject.Inject;
import java.io.File;

/**
* @author Lars Grefer
*/
public class PlantumlTask extends SourceTask {

private final WorkerExecutor workerExecutor;

private final FileSystemOperations fileSystemOperations;

@Getter
@Classpath
private final ConfigurableFileCollection plantumlClasspath = getProject().files();

@Getter
@OutputDirectory
private final DirectoryProperty outputDirectory = getProject().getObjects().directoryProperty();

@Getter
@Input
@Optional
private final Property<String> fileFormat = getProject().getObjects().property(String.class);

@Getter
@Input
private final Property<Boolean> withMetadata = getProject().getObjects().property(Boolean.class).convention(true);

@Getter
@Input
private final Property<String> includePattern = getProject().getObjects().property(String.class).convention("**/*.puml");

@Inject
public PlantumlTask(WorkerExecutor workerExecutor, FileSystemOperations fileSystemOperations) {
this.fileSystemOperations = fileSystemOperations;
this.workerExecutor = workerExecutor;
this.setGroup("plantuml");
}

@TaskAction
public void execute() {

fileSystemOperations.delete(deleteSpec -> deleteSpec.delete(outputDirectory));

WorkQueue workQueue = workerExecutor.processIsolation(process -> {
process.getClasspath().from(plantumlClasspath);
process.getForkOptions().systemProperty("java.awt.headless", true);
});

for (File file : getSource().matching(p -> p.include(includePattern.get()))) {
workQueue.submit(PlantumlAction.class, params -> {
params.getInputFile().set(file);
params.getOutputDirectory().set(outputDirectory);
params.getFileFormat().set(fileFormat);
params.getWithMetadata().set(withMetadata);
});
}
}
}
@@ -0,0 +1,63 @@
package io.freefair.gradle.plugins.plantuml;

import org.gradle.api.Project;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.provider.Property;
import org.gradle.internal.impldep.org.junit.Before;
import org.gradle.testfixtures.ProjectBuilder;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

import java.io.File;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;

class PlantumlPluginTest {

private Project project;

@BeforeEach
void init() {
project = ProjectBuilder.builder().build();
}

@Test
void apply() {
project.getPlugins().apply(PlantumlPlugin.class);

assertThat(project.getTasks().getNames()).contains("plantUml");
}

@Test
void execute() {
project.getPlugins().apply(PlantumlPlugin.class);

PlantumlTask task = project.getTasks().withType(PlantumlTask.class).getByName("plantUml");

task.source(getClass().getClassLoader().getResource("puml-files").getPath());

assertThrows(UnsupportedOperationException.class, task::execute);
}

@Test
void taskExecution(@TempDir File tempDir) {
PlantumlParameters parameters = project.getObjects().newInstance(PlantumlParameters.class);

parameters.getInputFile().set(new File(getClass().getClassLoader().getResource("puml-files/test.puml").getPath()));
parameters.getOutputDirectory().set(tempDir);
parameters.getFileFormat().set("PNG");
parameters.getWithMetadata().set(false);

PlantumlAction action = new PlantumlAction() {
@Override
public PlantumlParameters getParameters() {
return parameters;
}
};

action.execute();
}
}
6 changes: 6 additions & 0 deletions plantuml-plugin/src/test/resources/puml-files/test.puml
@@ -0,0 +1,6 @@
@startuml

Bob -> Alice: Test
Alice --> Bob: return Test

@enduml
1 change: 1 addition & 0 deletions settings.gradle
Expand Up @@ -20,3 +20,4 @@ include "okhttp-plugin"
include "git-plugin"
include "mkdocs-plugin"
include "quicktype-plugin"
include "plantuml-plugin"

0 comments on commit b04ff31

Please sign in to comment.