Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Features/156 embed live reload #188

Merged
merged 12 commits into from
Jun 15, 2022
87 changes: 52 additions & 35 deletions aadarchi-maven-plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<name>Agile Architecture Documentation System : Maven plugin</name>

<dependencies>
<!-- used to invoke asciidoctor-maven-plugin in a controlled way -->
<!-- used to invoke asciidoctor-maven-plugin in a controlled way -->
<dependency>
<groupId>org.twdata.maven</groupId>
<artifactId>mojo-executor</artifactId>
Expand All @@ -39,6 +39,11 @@
<artifactId>base</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>net.alchim31</groupId>
<artifactId>livereload-jvm</artifactId>
<version>0.2.0</version>
</dependency>
</dependencies>

<build>
Expand All @@ -51,40 +56,52 @@
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-invoker-plugin</artifactId>
<version>1.10</version>
<configuration>
<debug>true</debug>
<scriptVariables>
<pluginVersion>${project.version}</pluginVersion>
</scriptVariables>
<projectsDirectory>src/it</projectsDirectory>
<pomIncludes>
<pomInclude>**/pom.xml</pomInclude>
</pomIncludes>
<!-- Without this configuration, projects are run directly from src, which means no interpolation is done -->
<cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
<!-- Local repository used for tests -->
<localRepositoryPath>${project.build.directory}/local-repo</localRepositoryPath>
<!-- The settings file will fasten build download according to https://maven.apache.org/plugins/maven-invoker-plugin/examples/fast-use.html -->
<settingsFile>src/it/settings.xml</settingsFile>
<postBuildHookScript>verify.groovy</postBuildHookScript>
</configuration>
<executions>
<execution>
<goals>
<!-- Invoking install prior to running tests will make sure this artifact is correctly copied
(see https://maven.apache.org/plugins/maven-invoker-plugin/examples/install-artifacts.html) -->
<goal>install</goal>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>integration-tests</id>
<activation>
<property>
<name>!skip_integration</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-invoker-plugin</artifactId>
<version>1.10</version>
<configuration>
<debug>true</debug>
<scriptVariables>
<pluginVersion>${project.version}</pluginVersion>
</scriptVariables>
<projectsDirectory>src/it</projectsDirectory>
<pomIncludes>
<pomInclude>**/pom.xml</pomInclude>
</pomIncludes>
<!-- Without this configuration, projects are run directly from src, which means no interpolation is done -->
<cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
<!-- Local repository used for tests -->
<localRepositoryPath>${project.build.directory}/local-repo</localRepositoryPath>
<!-- The settings file will fasten build download according to https://maven.apache.org/plugins/maven-invoker-plugin/examples/fast-use.html -->
<settingsFile>src/it/settings.xml</settingsFile>
<postBuildHookScript>verify.groovy</postBuildHookScript>
</configuration>
<executions>
<execution>
<goals>
<!-- Invoking install prior to running tests will make sure this artifact is correctly copied
(see https://maven.apache.org/plugins/maven-invoker-plugin/examples/install-artifacts.html) -->
<goal>install</goal>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

</profile>
</profiles>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
package org.ndx.agile.architecture.documentation.system.maven.plugin;

import static org.twdata.maven.mojoexecutor.MojoExecutor.artifactId;
import static org.twdata.maven.mojoexecutor.MojoExecutor.configuration;
import static org.twdata.maven.mojoexecutor.MojoExecutor.element;
import static org.twdata.maven.mojoexecutor.MojoExecutor.executeMojo;
import static org.twdata.maven.mojoexecutor.MojoExecutor.executionEnvironment;
import static org.twdata.maven.mojoexecutor.MojoExecutor.goal;
import static org.twdata.maven.mojoexecutor.MojoExecutor.groupId;
import static org.twdata.maven.mojoexecutor.MojoExecutor.name;
import static org.twdata.maven.mojoexecutor.MojoExecutor.plugin;
import static org.twdata.maven.mojoexecutor.MojoExecutor.version;

import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Executors;

import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Resource;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.BuildPluginManager;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.ndx.agile.architecture.base.enhancers.ModelElementKeys.ConfigProperties.WorkspaceDsl;
import org.twdata.maven.mojoexecutor.MojoExecutor.Element;

import net_alchim31_livereload.LRServer; //#from net.alchim31:livereload-jvm:0.2.0

@Mojo(name = "livereload", defaultPhase = LifecyclePhase.PACKAGE)
public class LiveReload extends AbstractMojo {

@Component
private MavenProject mavenProject;

@Component
private MavenSession mavenSession;

@Component
private BuildPluginManager pluginManager;
/**
* Input folder where asciidoc files are stored.
*/
@Parameter(name="html-docs-source-dir", defaultValue="${project.basedir}/src/docs/asciidoc", property = "asciidoc.source.docs.directory")
private File htmlDocsSourceDir;
/**
* Input folder where asciidoc files for slides are stored
*/
@Parameter(name="html-slides-source-dir", defaultValue="${project.basedir}/src/slides/asciidoc", property = "asciidoc.source.slides.directory")
private File htmlSlidesSourceDir;
/**
* Input workspace.dsl file
*/
@Parameter(name="architecture-dsl", defaultValue=WorkspaceDsl.VALUE, property = WorkspaceDsl.NAME)
private File architectureDsl;
@Parameter(defaultValue="${project.build.sourceDirectory}", readonly = true, required = true)
private File javaSourcesDir;

/**
* Port used for livereload of generated documentation
*/
@Parameter(name="livereload-port", defaultValue="35729")
private int livereloadPort;

/**
* List of goals to execute after live-reload.
* As it is a list, the default value is not provided in a way compatible with maven annotation.
*
* The default value for that goal is
*
* <ul>
* <li>prepare-package</li>
* <li>"io.github.Riduidel.agile-architecture-documentation-system:aadarchi-maven-plugin@generate-html-docs"</li>
* <li>"io.github.Riduidel.agile-architecture-documentation-system:aadarchi-maven-plugin@generate-html-slides"</li>
* </ul>
*/
@Parameter(name="goals-to-execute")
private List<String> goalsToExecute = Arrays.asList("prepare-package",
"io.github.Riduidel.agile-architecture-documentation-system:aadarchi-maven-plugin@generate-html-docs",
"io.github.Riduidel.agile-architecture-documentation-system:aadarchi-maven-plugin@generate-html-slides"
);

@Override
public void execute() throws MojoExecutionException, MojoFailureException {
try (ServerSocket test = new ServerSocket(livereloadPort)){
getLog().debug(String.format("port %d can be used", livereloadPort));
} catch (IOException e) {
throw new MojoFailureException(String.format("port %d not available", livereloadPort));
}

Path docroot = FileSystems.getDefault().getPath(mavenProject.getBuild().getDirectory());
Executors.newSingleThreadExecutor().execute(() -> {
try {
new LRServer(livereloadPort, docroot).run(); // == start() + join()
} catch (Exception e) {
throw new RuntimeException(e);
}
});

executeMojo(
plugin(
groupId("com.fizzed"),
artifactId("fizzed-watcher-maven-plugin"),
version("1.0.6")
),
goal("run"),
configuration(
element(name("touchFile"), "target/watcher.touchfile"),
element(name("watches"),
watches()
),
element(name("goals"),
goals()
)
),
executionEnvironment(
mavenProject,
mavenSession,
pluginManager
)
);
}

private Element[] goals() {
// First, get our artifact name
return goalsToExecute.stream()
.map(text -> element(name("goal"), text))
.toArray(Element[]::new);
}

private Element[] watches() {
List<File> files = new ArrayList<File>(Arrays.asList(
javaSourcesDir,
htmlDocsSourceDir,
htmlSlidesSourceDir,
architectureDsl.getParentFile()
));

for(Resource r : mavenProject.getResources()) {
files.add(new File(r.getDirectory()));
}

return files.stream()
.filter(File::exists)
.map(File::getAbsolutePath)
.map(text -> element(name("watch"), element(name("directory"), text))).toArray(Element[]::new);
}
}
74 changes: 5 additions & 69 deletions architecture-documentation/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -324,80 +324,16 @@
<defaultGoal>package</defaultGoal>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<id>start-livereload-server in background</id>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<!-- Livereload is launched as an exec job to allow it to run in
background -->
<executable>java</executable>
<!-- See https://github.com/davidB/livereload-jvm/blob/0.2.0/src/main/java/net_alchim31_livereload/Main.java
for details -->
<arguments>
<argument>-classpath</argument>
<classpath>
<dependency>net.alchim31:livereload-jvm</dependency>
<dependency>org.eclipse.jetty:jetty-util</dependency>
<dependency>org.eclipse.jetty:jetty-io</dependency>
<dependency>org.eclipse.jetty.orbit:javax.servlet:jar</dependency>
<dependency>org.eclipse.jetty:jetty-continuation</dependency>
<dependency>org.eclipse.jetty:jetty-server</dependency>
<dependency>org.eclipse.jetty.orbit:javax.servlet</dependency>
<dependency>org.eclipse.jetty:jetty-http</dependency>
<dependency>com.googlecode.json-simple:json-simple</dependency>
<dependency>org.eclipse.jetty:jetty-websocket</dependency>
</classpath>
<argument>net_alchim31_livereload.Main</argument>
<argument>-d</argument>
<argument>${asciidoc.target.base.directory}</argument>
</arguments>
<async>true</async>
<asyncDestroyOnShutdown>true</asyncDestroyOnShutdown>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.fizzed</groupId>
<artifactId>fizzed-watcher-maven-plugin</artifactId>
<groupId>${project.groupId}</groupId>
<artifactId>aadarchi-maven-plugin</artifactId>
<version>${project.version}</version>
<executions>
<execution>
<id>watch source</id>
<id>generate-html-slides</id>
<phase>package</phase>
<goals>
<goal>run</goal>
<goal>livereload</goal>
</goals>
<configuration>
<touchFile>target/watcher.touchfile</touchFile>
<watches>
<watch>
<directory>${project.basedir}/src/main/java</directory>
</watch>
<watch>
<directory>${project.basedir}/src/architecture/resources</directory>
</watch>
<watch>
<directory>${project.basedir}/src/main/resources</directory>
</watch>
<watch>
<directory>${project.basedir}/src/docs/asciidoc</directory>
</watch>
<watch>
<directory>${project.basedir}/src/slides/asciidoc</directory>
</watch>
</watches>
<goals>
<goal>prepare-package</goal>
<goal>org.asciidoctor:asciidoctor-maven-plugin:process-asciidoc@generate-slides</goal>
<goal>org.asciidoctor:asciidoctor-maven-plugin:process-asciidoc@generate-html-doc</goal>
</goals>
</configuration>
</execution>
</executions>
</plugin>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ public interface ModelElementKeys {
*
*/
public static interface ConfigProperties {
public static interface WorkspaceDsl {
public String NAME = ModelElementKeys.PREFIX + "dsl";
public String VALUE = "${project.basedir}/src/architecture/resources/workspace.dsl";
}
public static interface AsciidocSourceDir {
public String NAME = "asciidoc.source.docs.directory";
public String VALUE = "${project.basedir}/src/docs/asciidoc";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import org.apache.deltaspike.core.api.config.ConfigProperty;
import org.ndx.agile.architecture.base.ArchitectureModelProvider;
import org.ndx.agile.architecture.base.enhancers.ModelElementKeys;
import org.ndx.agile.architecture.base.enhancers.ModelElementKeys.ConfigProperties.WorkspaceDsl;

import com.structurizr.Workspace;
import com.structurizr.dsl.StructurizrDslParser;
Expand All @@ -19,9 +19,8 @@
@Named("Using workspace.dsl")
public class FromDsl implements ArchitectureModelProvider {

private static final String WORKSPACE_DSL = ModelElementKeys.PREFIX + "dsl";
@Inject
@ConfigProperty(name = WORKSPACE_DSL, defaultValue = "${project.basedir}/src/architecture/resources/workspace.dsl") File workspace;
@ConfigProperty(name = WorkspaceDsl.NAME, defaultValue = WorkspaceDsl.VALUE) File workspace;

@Override
public Workspace describeArchitecture() {
Expand All @@ -31,7 +30,7 @@ public Workspace describeArchitecture() {
+ "We tried to read file %s but there was nothing.\n"
+ "Please either move that file into that location or set the property %s",
workspace.getAbsolutePath(),
WORKSPACE_DSL));
WorkspaceDsl.NAME));
}
StructurizrDslParser parser = new StructurizrDslParser();
try {
Expand Down