diff --git a/maven-plugin/pom.xml b/maven-plugin/pom.xml
index c9705fe7..2fabab6c 100644
--- a/maven-plugin/pom.xml
+++ b/maven-plugin/pom.xml
@@ -159,6 +159,12 @@
dom4j
+
+
+ org.projectlombok
+ lombok
+
+
net.lingala.zip4j
@@ -226,7 +232,35 @@
+
+
+ src/test/resources
+ true
+
+ integration-test/invokeIT/pom.xml
+
+
+
+ src/test/resources
+ false
+
+ integration-test/invokeIT/pom.xml
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 3.4.2
+
+
+
+ test-jar
+
+
+
+
org.apache.maven.plugins
maven-plugin-plugin
diff --git a/maven-plugin/src/main/java/org/openmrs/maven/plugins/AbstractTask.java b/maven-plugin/src/main/java/org/openmrs/maven/plugins/AbstractTask.java
index b7e19161..272849fe 100644
--- a/maven-plugin/src/main/java/org/openmrs/maven/plugins/AbstractTask.java
+++ b/maven-plugin/src/main/java/org/openmrs/maven/plugins/AbstractTask.java
@@ -1,5 +1,6 @@
package org.openmrs.maven.plugins;
+import lombok.Getter;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
@@ -12,14 +13,15 @@
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.settings.Settings;
+import org.openmrs.maven.plugins.git.DefaultGitHelper;
+import org.openmrs.maven.plugins.git.GitHelper;
import org.openmrs.maven.plugins.model.Server;
import org.openmrs.maven.plugins.utility.ConfigurationInstaller;
import org.openmrs.maven.plugins.utility.DefaultJira;
import org.openmrs.maven.plugins.utility.DistroHelper;
-import org.openmrs.maven.plugins.git.DefaultGitHelper;
-import org.openmrs.maven.plugins.git.GitHelper;
import org.openmrs.maven.plugins.utility.DockerHelper;
import org.openmrs.maven.plugins.utility.Jira;
+import org.openmrs.maven.plugins.utility.MavenEnvironment;
import org.openmrs.maven.plugins.utility.ModuleInstaller;
import org.openmrs.maven.plugins.utility.NodeHelper;
import org.openmrs.maven.plugins.utility.OwaHelper;
@@ -140,10 +142,17 @@ public abstract class AbstractTask extends AbstractMojo {
*/
DockerHelper dockerHelper;
+ /**
+ * provides access to the current Maven environment
+ */
+ @Getter
+ private MavenEnvironment mavenEnvironment;
+
public AbstractTask() {
}
public AbstractTask(AbstractTask other) {
+ this.mavenEnvironment = other.mavenEnvironment;
this.mavenProject = other.mavenProject;
this.mavenSession = other.mavenSession;
this.wizard = other.wizard;
@@ -155,6 +164,7 @@ public AbstractTask(AbstractTask other) {
this.distroHelper = other.distroHelper;
this.owaHelper = other.owaHelper;
this.spaInstaller = other.spaInstaller;
+ this.configurationInstaller = other.configurationInstaller;
this.gitHelper = other.gitHelper;
this.dockerHelper = other.dockerHelper;
this.settings = other.settings;
@@ -166,6 +176,16 @@ public AbstractTask(AbstractTask other) {
}
public void initTask() {
+ if (mavenEnvironment == null) {
+ mavenEnvironment = new MavenEnvironment();
+ mavenEnvironment.setMavenProject(mavenProject);
+ mavenEnvironment.setMavenSession(mavenSession);
+ mavenEnvironment.setSettings(settings);
+ mavenEnvironment.setArtifactMetadataSource(artifactMetadataSource);
+ mavenEnvironment.setArtifactFactory(artifactFactory);
+ mavenEnvironment.setPluginManager(pluginManager);
+ mavenEnvironment.setWizard(wizard);
+ }
if (jira == null) {
jira = new DefaultJira();
}
diff --git a/maven-plugin/src/main/java/org/openmrs/maven/plugins/InvokeMethod.java b/maven-plugin/src/main/java/org/openmrs/maven/plugins/InvokeMethod.java
new file mode 100644
index 00000000..bf21c5b9
--- /dev/null
+++ b/maven-plugin/src/main/java/org/openmrs/maven/plugins/InvokeMethod.java
@@ -0,0 +1,93 @@
+package org.openmrs.maven.plugins;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.apache.commons.lang.StringUtils;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.openmrs.maven.plugins.utility.MavenEnvironment;
+import org.openmrs.maven.plugins.utility.Wizard;
+
+import java.lang.reflect.Method;
+
+/**
+ * The purpose is this Mojo is to support testing of helper utilities that are used by the various goals. This will:
+ * instantiate a new object of type className
+ * if this class has a setter property for a MavenExecution, this will be set
+ * it will then invoke the given testMethod on the testClass
+ */
+@Mojo(name = InvokeMethod.NAME)
+@Getter @Setter
+public class InvokeMethod extends AbstractTask {
+
+ public static final String NAME = "invoke-method";
+
+ @Parameter(property = "className")
+ String className;
+
+ @Parameter(property = "methodName")
+ String methodName;
+
+ public void executeTask() throws MojoExecutionException {
+
+ if (StringUtils.isBlank(className) || StringUtils.isBlank(methodName)) {
+ throw new MojoExecutionException("You must supply both a className and methodName parameter");
+ }
+
+ Wizard wizard = getMavenEnvironment().getWizard();
+
+ wizard.showMessage("Invoking: " + className + ":" + methodName);
+
+ Class> clazz;
+ try {
+ clazz = getClass().getClassLoader().loadClass(className);
+ }
+ catch (ClassNotFoundException e) {
+ throw new MojoExecutionException("Unable to load class", e);
+ }
+ wizard.showMessage("Class " + clazz.getName() + " loaded successfully");
+
+ Object instance;
+ try {
+ instance = clazz.getConstructor().newInstance();
+ } catch (Exception e) {
+ throw new MojoExecutionException("Unable to instantiate class with " + getClass(), e);
+ }
+ wizard.showMessage("New instance of " + clazz.getName() + " instantiated");
+
+ Method setterMethod = null;
+ try {
+ setterMethod = clazz.getMethod("set" + MavenEnvironment.class.getSimpleName(), MavenEnvironment.class);
+ }
+ catch (NoSuchMethodException ignored) {
+ }
+
+ if (setterMethod != null) {
+ try {
+ setterMethod.invoke(instance, getMavenEnvironment());
+ wizard.showMessage("Instance populated with maven environment");
+ }
+ catch (Exception e) {
+ throw new MojoExecutionException("Error executing method: " + methodName, e);
+ }
+ }
+
+ Method method;
+ try {
+ method = clazz.getMethod(methodName);
+ }
+ catch (NoSuchMethodException e) {
+ throw new MojoExecutionException("Unable to find method: " + methodName, e);
+ }
+ wizard.showMessage("Got test method: " + method.getName());
+
+ try {
+ method.invoke(instance);
+ }
+ catch (Exception e) {
+ throw new MojoExecutionException("Error executing method: " + methodName, e);
+ }
+ wizard.showMessage("Method: " + method.getName() + " invoked successfully");
+ }
+}
diff --git a/maven-plugin/src/test/java/org/openmrs/maven/plugins/AbstractMavenIT.java b/maven-plugin/src/test/java/org/openmrs/maven/plugins/AbstractMavenIT.java
new file mode 100644
index 00000000..492edbce
--- /dev/null
+++ b/maven-plugin/src/test/java/org/openmrs/maven/plugins/AbstractMavenIT.java
@@ -0,0 +1,55 @@
+package org.openmrs.maven.plugins;
+
+
+import lombok.Getter;
+import lombok.Setter;
+import org.junit.Before;
+import org.openmrs.maven.plugins.utility.MavenEnvironment;
+
+import java.io.File;
+
+@Getter @Setter
+public abstract class AbstractMavenIT extends AbstractSdkIT {
+
+ MavenEnvironment mavenEnvironment = null;
+
+ @Override
+ @Before
+ public void setup() throws Exception {
+ super.setup();
+ mavenEnvironment = null;
+ }
+
+ @Override
+ void addTestResources() throws Exception {
+ includePomFile("invokeIT", "pom.xml");
+ }
+
+ protected void executeTest(MavenTestFunction testFunction) throws Exception {
+ StackTraceElement invoker = Thread.currentThread().getStackTrace()[2];
+ String className = invoker.getClassName();
+ String testMethod = invoker.getMethodName();
+ if (mavenEnvironment == null) {
+ addTaskParam("className", className);
+ addTaskParam("methodName", testMethod);
+ addTaskParam(BATCH_ANSWERS, getAnswers());
+ addTaskParam("testMode", "true");
+ String plugin = resolveSdkArtifact();
+ verifier.executeGoal(plugin + ":" + InvokeMethod.NAME);
+ }
+ else {
+ testFunction.executeTest();
+ }
+ }
+
+ protected File getMavenTestDirectory() {
+ return new File(mavenEnvironment.getMavenProject().getBuild().getDirectory());
+ }
+
+ /**
+ * Simple interface that encapsulates a test that should be evaluated by tests that use this Mojo
+ */
+ public interface MavenTestFunction {
+ void executeTest() throws Exception;
+ }
+}
diff --git a/maven-plugin/src/test/java/org/openmrs/maven/plugins/AbstractSdkIT.java b/maven-plugin/src/test/java/org/openmrs/maven/plugins/AbstractSdkIT.java
index a9f8bbea..36a2f397 100644
--- a/maven-plugin/src/test/java/org/openmrs/maven/plugins/AbstractSdkIT.java
+++ b/maven-plugin/src/test/java/org/openmrs/maven/plugins/AbstractSdkIT.java
@@ -83,25 +83,26 @@ public String resolveSdkArtifact() throws MojoExecutionException {
return sdk.get("groupId")+":"+sdk.get("artifactId")+":"+sdk.get("version");
}
- void includeTestResource(String fileName) throws Exception {
- File source = getTestFile(TEST_DIRECTORY, fileName);
- File target = new File(testDirectory, fileName);
- if (source.isDirectory()) {
- FileUtils.copyDirectory(source, testDirectory);
- }
- else {
- FileUtils.copyFile(source, target);
+ void includeDistroPropertiesFile(String... paths) throws Exception {
+ Path sourcePath = testDirectoryPath.resolve(TEST_DIRECTORY);
+ for (String path : paths) {
+ sourcePath = sourcePath.resolve(path);
}
+ Path targetPath = testDirectoryPath.resolve(DistroProperties.DISTRO_FILE_NAME);
+ FileUtils.copyFile(sourcePath.toFile(), targetPath.toFile());
}
- void includeDistroPropertiesFile(String fileName) throws Exception {
- File source = getTestFile(TEST_DIRECTORY, fileName);
- File target = new File(testDirectory, DistroProperties.DISTRO_FILE_NAME);
- FileUtils.copyFile(source, target);
+ void includePomFile(String... paths) throws Exception {
+ Path sourcePath = testDirectoryPath.resolve(TEST_DIRECTORY);
+ for (String path : paths) {
+ sourcePath = sourcePath.resolve(path);
+ }
+ Path targetPath = testDirectoryPath.resolve("pom.xml");
+ FileUtils.copyFile(sourcePath.toFile(), targetPath.toFile());
}
void addTestResources() throws Exception {
- includeTestResource("pom.xml");
+ includePomFile("pom.xml");
includeDistroPropertiesFile(DistroProperties.DISTRO_FILE_NAME);
}
diff --git a/maven-plugin/src/test/java/org/openmrs/maven/plugins/BuildIT.java b/maven-plugin/src/test/java/org/openmrs/maven/plugins/BuildIT.java
index aecce120..f6e79d7e 100644
--- a/maven-plugin/src/test/java/org/openmrs/maven/plugins/BuildIT.java
+++ b/maven-plugin/src/test/java/org/openmrs/maven/plugins/BuildIT.java
@@ -1,5 +1,6 @@
package org.openmrs.maven.plugins;
+import org.apache.commons.io.FileUtils;
import org.junit.Before;
import org.junit.Test;
import org.openmrs.maven.plugins.model.Project;
@@ -13,7 +14,7 @@ public class BuildIT extends AbstractSdkIT {
private String serverId;
void addTestResources() throws Exception {
- includeTestResource("buildIT");
+ FileUtils.copyDirectory(getTestFile(TEST_DIRECTORY, "buildIT"), testDirectory);
}
@Before
diff --git a/maven-plugin/src/test/java/org/openmrs/maven/plugins/utility/ArtifactHelperIT.java b/maven-plugin/src/test/java/org/openmrs/maven/plugins/utility/ArtifactHelperIT.java
new file mode 100644
index 00000000..854c3fbe
--- /dev/null
+++ b/maven-plugin/src/test/java/org/openmrs/maven/plugins/utility/ArtifactHelperIT.java
@@ -0,0 +1,48 @@
+package org.openmrs.maven.plugins.utility;
+
+
+import lombok.Getter;
+import lombok.Setter;
+import org.apache.maven.it.VerificationException;
+import org.junit.Test;
+import org.openmrs.maven.plugins.AbstractMavenIT;
+import org.openmrs.maven.plugins.model.Artifact;
+
+import java.io.File;
+
+import static org.junit.Assert.assertTrue;
+
+@Getter @Setter
+public class ArtifactHelperIT extends AbstractMavenIT {
+
+ @Test
+ public void test_downloadModuleWithDefaultName() throws Exception {
+ executeTest(() -> {
+ ArtifactHelper artifactHelper = new ArtifactHelper(getMavenEnvironment());
+ Artifact artifact = new Artifact("idgen-omod", "4.14.0", "org.openmrs.module", "jar");
+ artifactHelper.downloadArtifact(artifact, getMavenTestDirectory(), null);
+ File expectedFile = new File(getMavenTestDirectory(), "idgen-omod-4.14.0.jar");
+ assertTrue(expectedFile.exists());
+ });
+ }
+
+ @Test
+ public void downloadModuleWithSpecificName() throws Exception {
+ executeTest(() -> {
+ ArtifactHelper artifactHelper = new ArtifactHelper(getMavenEnvironment());
+ Artifact artifact = new Artifact("idgen-omod", "4.14.0", "org.openmrs.module", "jar");
+ artifactHelper.downloadArtifact(artifact, getMavenTestDirectory(), "idgen.omod");
+ File expectedFile = new File(getMavenTestDirectory(), "idgen.omod");
+ assertTrue(expectedFile.exists());
+ });
+ }
+
+ @Test(expected = VerificationException.class)
+ public void downloadModuleThatDoesNotExist() throws Exception {
+ executeTest(() -> {
+ ArtifactHelper artifactHelper = new ArtifactHelper(getMavenEnvironment());
+ Artifact artifact = new Artifact("idgen-omod", "4.0.0", "org.openmrs.module", "jar");
+ artifactHelper.downloadArtifact(artifact, getMavenTestDirectory(), "idgen.omod");
+ });
+ }
+}
diff --git a/maven-plugin/src/test/resources/integration-test/invokeIT/pom.xml b/maven-plugin/src/test/resources/integration-test/invokeIT/pom.xml
new file mode 100644
index 00000000..7e6f9327
--- /dev/null
+++ b/maven-plugin/src/test/resources/integration-test/invokeIT/pom.xml
@@ -0,0 +1,78 @@
+
+ 4.0.0
+
+ org.openmrs
+ openmrs-sdk-integration-test-project
+ 1.0
+ pom
+
+
+
+
+
+ ${project.groupId}
+ ${project.artifactId}
+ ${project.version}
+
+
+ ${project.groupId}
+ ${project.artifactId}
+ ${project.version}
+ tests
+ test-jar
+ compile
+
+
+ org.apache.maven.shared
+ maven-verifier
+ 1.7.2
+ compile
+
+
+ junit
+ junit
+ 4.12
+ jar
+ compile
+
+
+ org.hamcrest
+ hamcrest-core
+ 2.2
+ compile
+
+
+ org.hamcrest
+ hamcrest-library
+ 2.2
+ compile
+
+
+ org.mockito
+ mockito-core
+ 3.9.0
+ compile
+
+
+
+
+
+
+
+
+ openmrs-repo
+ OpenMRS repository
+ https://mavenrepo.openmrs.org/nexus/content/repositories/public
+
+
+
+
diff --git a/pom.xml b/pom.xml
index 075485a5..4e704731 100644
--- a/pom.xml
+++ b/pom.xml
@@ -77,6 +77,7 @@
UTF-8
3.20.0
2.13.4.2
+ 1.18.26
@@ -466,6 +467,13 @@
guava
32.1.2-jre
+
+
+
+ org.projectlombok
+ lombok
+ ${lombokVersion}
+
diff --git a/sdk-commons/pom.xml b/sdk-commons/pom.xml
index 6baf6266..60133553 100644
--- a/sdk-commons/pom.xml
+++ b/sdk-commons/pom.xml
@@ -86,6 +86,11 @@
mockito-core
test
+
+ org.projectlombok
+ lombok
+ provided
+
diff --git a/sdk-commons/src/main/java/org/openmrs/maven/plugins/utility/ArtifactHelper.java b/sdk-commons/src/main/java/org/openmrs/maven/plugins/utility/ArtifactHelper.java
new file mode 100644
index 00000000..039f2dc2
--- /dev/null
+++ b/sdk-commons/src/main/java/org/openmrs/maven/plugins/utility/ArtifactHelper.java
@@ -0,0 +1,76 @@
+package org.openmrs.maven.plugins.utility;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.openmrs.maven.plugins.model.Artifact;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.twdata.maven.mojoexecutor.MojoExecutor;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+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;
+
+/**
+ * The purpose of this class is to handle all interactions with Maven that require retrieving artifacts from the Maven repository
+ */
+public class ArtifactHelper {
+
+ private static final Logger log = LoggerFactory.getLogger(ArtifactHelper.class);
+
+ final MavenEnvironment mavenEnvironment;
+
+ public ArtifactHelper(MavenEnvironment mavenEnvironment) {
+ this.mavenEnvironment = mavenEnvironment;
+ }
+
+ public File downloadArtifact(Artifact artifact, File directory) throws MojoExecutionException {
+ return downloadArtifact(artifact, directory, null);
+ }
+
+ /**
+ * Downloads the given artifact to the given directory with the given fileName. If fileName is null, it will use the maven default.
+ * @param artifact the artifact to download
+ * @param directory the directory into which to download the artifact
+ * @param fileName the name of the file to save the artifact to (optional, if null will use the maven default)
+ * @return the downloaded File
+ * @throws MojoExecutionException
+ */
+ public File downloadArtifact(Artifact artifact, File directory, String fileName) throws MojoExecutionException {
+ if (StringUtils.isBlank(fileName)) {
+ fileName = artifact.getArtifactId() + "-" + artifact.getVersion() + "." + artifact.getType();
+ }
+ artifact.setDestFileName(fileName);
+ List artifactItems = new ArrayList<>();
+ MojoExecutor.Element element = artifact.toElement(directory.getAbsolutePath());
+ artifactItems.add(element);
+ executeMojo(
+ plugin(
+ groupId(SDKConstants.DEPENDENCY_PLUGIN_GROUP_ID),
+ artifactId(SDKConstants.DEPENDENCY_PLUGIN_ARTIFACT_ID),
+ version(SDKConstants.DEPENDENCY_PLUGIN_VERSION)
+ ),
+ goal("copy"),
+ configuration(
+ element(name("artifactItems"), artifactItems.toArray(new MojoExecutor.Element[0]))
+ ),
+ executionEnvironment(
+ mavenEnvironment.getMavenProject(),
+ mavenEnvironment.getMavenSession(),
+ mavenEnvironment.getPluginManager()
+ )
+ );
+ return new File(directory, artifact.getDestFileName());
+ }
+}
diff --git a/sdk-commons/src/main/java/org/openmrs/maven/plugins/utility/MavenEnvironment.java b/sdk-commons/src/main/java/org/openmrs/maven/plugins/utility/MavenEnvironment.java
new file mode 100644
index 00000000..9a06fbae
--- /dev/null
+++ b/sdk-commons/src/main/java/org/openmrs/maven/plugins/utility/MavenEnvironment.java
@@ -0,0 +1,23 @@
+package org.openmrs.maven.plugins.utility;
+
+import lombok.Data;
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.BuildPluginManager;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.settings.Settings;
+
+/**
+ * Component that allows access to the Maven components set within the current execution environment
+ */
+@Data
+public class MavenEnvironment {
+ private MavenProject mavenProject;
+ private MavenSession mavenSession;
+ private Settings settings;
+ private ArtifactMetadataSource artifactMetadataSource;
+ private ArtifactFactory artifactFactory;
+ private BuildPluginManager pluginManager;
+ private Wizard wizard;
+}