Skip to content

Commit

Permalink
CreateExtensionMojo should optionally add the newly created modules to
Browse files Browse the repository at this point in the history
BOMs
  • Loading branch information
ppalaga committed Aug 2, 2019
1 parent 66f78a1 commit 3fd472a
Show file tree
Hide file tree
Showing 12 changed files with 305 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

/**
* A utility to transform {@code pom.xml} files on the DOM level while keeping the original comments and formatting also
Expand Down Expand Up @@ -105,7 +104,7 @@ static void transform(Collection<Transformation> edits, Path path, Supplier<Stri
}

final XPath xPath = XPathFactory.newInstance().newXPath();
final TransformationContext context = new TransformationContext(path, detectIndentation(document, xPath),
final TransformationContext context = new TransformationContext(path, document, detectIndentation(document, xPath),
xPath);
for (Transformation edit : edits) {
edit.perform(document, context);
Expand Down Expand Up @@ -186,12 +185,14 @@ static String anyNs(String... elements) {
*/
public static class TransformationContext {
private final Path pomXmlPath;
private final Document document;
private final XPath xPath;
private final String indentationString;

public TransformationContext(Path pomXmlPath, String indentationString, XPath xPath) {
public TransformationContext(Path pomXmlPath, Document document, String indentationString, XPath xPath) {
super();
this.pomXmlPath = pomXmlPath;
this.document = document;
this.indentationString = indentationString;
this.xPath = xPath;
}
Expand Down Expand Up @@ -219,6 +220,26 @@ public String getIndentationString() {
return indentationString;
}

/**
* @param indentCount
* @return a new indentation node containing a newline and {@code indentCount} times concatenated
* {@link #indentationString}
*/
public Node indent(int indentCount) {
final StringBuilder sb = new StringBuilder(1 + indentCount * indentationString.length());
sb.append('\n');
for (int i = 0; i < indentCount; i++) {
sb.append(indentationString);
}
return document.createTextNode(sb.toString());
}

public Node textElement(String elementName, String value) {
final Node result = document.createElement(elementName);
result.appendChild(document.createTextNode(value));
return result;
}

}

/**
Expand All @@ -231,18 +252,17 @@ public static Transformation addModule(String module) {
try {
Node modules = (Node) context.getXPath().evaluate(anyNs("project", "modules"), document,
XPathConstants.NODE);
final String indent1 = "\n" + context.getIndentationString();
if (modules == null) {
final Node modulesIndent = document.createTextNode(indent1);
final Node modulesIndent = context.indent(1);
modules = document.createElement("modules");
modules.appendChild(document.createTextNode(indent1));
modules.appendChild(context.indent(1));

final Node build = (Node) context.getXPath().evaluate(anyNs("project", "build"), document,
XPathConstants.NODE);
if (build != null) {
Node ws = build.getPreviousSibling();
if (ws == null || ws.getNodeType() != Node.TEXT_NODE) {
ws = document.createTextNode(indent1);
ws = context.indent(1);
build.getParentNode().insertBefore(ws, build);
}
build.getParentNode().insertBefore(modulesIndent, ws);
Expand All @@ -266,25 +286,61 @@ public static Transformation addModule(String module) {
}
}

final Text indent = document.createTextNode(indent1 + context.getIndentationString());
final Node moduleNode = document.createElement("module");
moduleNode.appendChild(document.createTextNode(module));

final NodeList modulesChildren = modules.getChildNodes();
final int len = modulesChildren.getLength();
Node ws;
if (len == 0 || (ws = modulesChildren.item(len - 1)).getNodeType() != Node.TEXT_NODE) {
ws = document.createTextNode(indent1);
ws = context.indent(1);
modules.appendChild(ws);
}
modules.insertBefore(indent, ws);
modules.insertBefore(context.indent(2), ws);
modules.insertBefore(moduleNode, ws);
} catch (XPathExpressionException | DOMException e) {
throw new RuntimeException(e);
}
};
}

public static Transformation addManagedDependency(String groupId, String artifactId, String version) {
return (Document document, TransformationContext context) -> {
try {
Node dependencyManagementDeps = (Node) context.getXPath().evaluate(
anyNs("project", "dependencyManagement", "dependencies"), document,
XPathConstants.NODE);
if (dependencyManagementDeps == null) {
throw new IllegalStateException(
String.format("//project/dependencyManagement/dependencies not found in [%s]",
context.getPomXmlPath()));
}
final NodeList dependencyManagementDepsChildren = dependencyManagementDeps.getChildNodes();
Node ws = null;
if (dependencyManagementDepsChildren.getLength() > 0) {
ws = dependencyManagementDepsChildren.item(dependencyManagementDepsChildren.getLength() - 1);
}
if (ws == null || ws.getNodeType() != Node.TEXT_NODE) {
ws = context.indent(3);
dependencyManagementDeps.appendChild(ws);
}

dependencyManagementDeps.insertBefore(context.indent(3), ws);
final Node dep = document.createElement("dependency");
dep.appendChild(context.indent(4));
dep.appendChild(context.textElement("groupId", groupId));
dep.appendChild(context.indent(4));
dep.appendChild(context.textElement("artifactId", artifactId));
dep.appendChild(context.indent(4));
dep.appendChild(context.textElement("version", version));
dep.appendChild(context.indent(3));
dependencyManagementDeps.insertBefore(dep, ws);
} catch (XPathExpressionException | DOMException e) {
throw new RuntimeException(e);
}
};
}

/**
* Perform this {@link Transformation} on the given {@code document}
*
Expand All @@ -294,4 +350,4 @@ public static Transformation addModule(String module) {
void perform(Document document, TransformationContext context);

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,44 @@ static void assertAddModule(String src, Collection<Transformation> transformatio
() -> src, xml -> Assertions.assertEquals(expected, xml));
}

@Test
void addManagedDependency() {
final String source = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" //
+ "<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://maven.apache.org/POM/4.0.0\"\n" //
+ " xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n" //
+ " <modelVersion>4.0.0</modelVersion>\n" //
+ " <groupId>org.acme</groupId>\n" //
+ " <artifactId>bom</artifactId>\n" //
+ " <version>0.1-SNAPSHOT</version>\n" //
+ " <packaging>pom</packaging>\n" //
+ " <dependencyManagement>\n" //
+ " <dependencies>\n" //
+ " </dependencies>\n" //
+ " </dependencyManagement>\n" //
+ "</project>\n";
final String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" //
+ "<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://maven.apache.org/POM/4.0.0\"\n" //
+ " xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n" //
+ " <modelVersion>4.0.0</modelVersion>\n" //
+ " <groupId>org.acme</groupId>\n" //
+ " <artifactId>bom</artifactId>\n" //
+ " <version>0.1-SNAPSHOT</version>\n" //
+ " <packaging>pom</packaging>\n" //
+ " <dependencyManagement>\n" //
+ " <dependencies>\n" //
+ " <dependency>\n" //
+ " <groupId>org.acme</groupId>\n" //
+ " <artifactId>my-ext</artifactId>\n" //
+ " <version>${project.version}</version>\n" //
+ " </dependency>\n" //
+ " </dependencies>\n" //
+ " </dependencyManagement>\n" //
+ "</project>\n";
assertAddModule(source,
Collections.singletonList(Transformation.addManagedDependency("org.acme", "my-ext", "${project.version}")),
expected);
}

@Test
void format() throws TransformerConfigurationException, TransformerException, TransformerFactoryConfigurationError {
assertFormat("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public class CreateExtensionMojo extends AbstractMojo {

/**
* Directory where the changes should be performed. Default is the current directory of the current Java process.
*
*
* @since 0.20.0
*/
@Parameter(property = "quarkus.basedir")
Expand Down Expand Up @@ -296,6 +296,28 @@ public class CreateExtensionMojo extends AbstractMojo {
@Parameter(defaultValue = DEFAULT_ENCODING, required = true, property = "quarkus.encoding")
String encoding;

/**
* Path relative to {@link #basedir} pointing at a {@code pom.xml} file containing the BOM (Bill of Materials) that
* manages runtime extension artifacts. If set, the newly created Runtime module will be added to
* {@code <deploymentManagement>} section of this bom; otherwise the newly created Runtime module will not be added
* to any BOM.
*
* @since 0.21.0
*/
@Parameter(property = "quarkus.runtimeBomPath")
Path runtimeBomPath;

/**
* Path relative to {@link #basedir} pointing at a {@code pom.xml} file containing the BOM (Bill of Materials) that
* manages deployment time extension artifacts. If set, the newly created Deployment module will be added to
* {@code <deploymentManagement>} section of this bom; otherwise the newly created Deployment module will not be
* added to any BOM.
*
* @since 0.21.0
*/
@Parameter(property = "quarkus.deploymentBomPath")
Path deploymentBomPath;

@Parameter(defaultValue = "${project}", readonly = true)
MavenProject project;

Expand Down Expand Up @@ -339,6 +361,19 @@ public void execute() throws MojoExecutionException, MojoFailureException {
}
}

if (runtimeBomPath != null) {
runtimeBomPath = basedir.resolve(runtimeBomPath);
if (!Files.exists(runtimeBomPath)) {
throw new MojoFailureException("runtimeBomPath does not exist: " + runtimeBomPath);
}
}
if (deploymentBomPath != null) {
deploymentBomPath = basedir.resolve(deploymentBomPath);
if (!Files.exists(deploymentBomPath)) {
throw new MojoFailureException("deploymentBomPath does not exist: " + deploymentBomPath);
}
}

final Charset charset = Charset.forName(encoding);

final Path basePomXml = basedir.resolve("pom.xml");
Expand Down Expand Up @@ -410,8 +445,20 @@ void addModules(Path basePomXml, Model basePom, Charset charset) throws IOExcept
evalTemplate(cfg, "Processor.java", processorPath, charset, model);

if (!basePom.getModules().contains(model.artifactIdBase)) {
getLog().info(String.format("Adding module [%s] to [%s]", model.artifactIdBase, basePomXml));
new PomTransformer(basePomXml, charset).transform(Transformation.addModule(model.artifactIdBase));
}
if (runtimeBomPath != null) {
getLog().info(String.format("Adding [%s] to dependencyManagement in [%s]", model.artifactId, runtimeBomPath));
new PomTransformer(runtimeBomPath, charset)
.transform(Transformation.addManagedDependency(model.groupId, model.artifactId, "${project.version}"));
}
if (deploymentBomPath != null) {
final String aId = model.artifactId + "-deployment";
getLog().info(String.format("Adding [%s] to dependencyManagement in [%s]", aId, deploymentBomPath));
new PomTransformer(deploymentBomPath, charset).transform(
Transformation.addManagedDependency(model.groupId, aId, "${project.version}"));
}

}

Expand Down Expand Up @@ -545,6 +592,14 @@ static String artifactIdBase(String artifactId) {
}
}

public void setRuntimeBomPath(String runtimeBomPath) {
this.runtimeBomPath = Paths.get(runtimeBomPath);
}

public void setDeploymentBomPath(String deploymentBomPath) {
this.deploymentBomPath = Paths.get(deploymentBomPath);
}

public static class TemplateParams {
String grandParentRelativePath;
String grandParentVersion;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ void createExtensionUnderExistingPomCustomGrandParent() throws MojoExecutionExce
mojo.grandParentArtifactId = "build-bom";
mojo.grandParentRelativePath = "../../build-bom/pom.xml";
mojo.templatesUriBase = "file:templates";

mojo.runtimeBomPath = Paths.get("boms/runtime/pom.xml");
mojo.deploymentBomPath = Paths.get("boms/deployment/pom.xml");
mojo.execute();

assertTreesMatch(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.acme</groupId>
<artifactId>grand-parent</artifactId>
<version>0.1-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>deployment-bom</artifactId>
<packaging>pom</packaging>

<dependencyManagement>
<dependencies>
</dependencies>
</dependencyManagement>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.acme</groupId>
<artifactId>grand-parent</artifactId>
<version>0.1-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>runtime-bom</artifactId>
<packaging>pom</packaging>

<dependencyManagement>
<dependencies>
</dependencies>
</dependencyManagement>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.acme</groupId>
<artifactId>grand-parent</artifactId>
<version>0.1-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>deployment-bom</artifactId>
<packaging>pom</packaging>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.acme</groupId>
<artifactId>myproject-with-grand-parent-deployment</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.acme</groupId>
<artifactId>grand-parent</artifactId>
<version>0.1-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>runtime-bom</artifactId>
<packaging>pom</packaging>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.acme</groupId>
<artifactId>myproject-with-grand-parent</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
Loading

0 comments on commit 3fd472a

Please sign in to comment.