-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
O3-3511: Added plugin to Validate and Assemble content package (#24)
- Loading branch information
Showing
5 changed files
with
452 additions
and
209 deletions.
There are no files selected for viewing
99 changes: 99 additions & 0 deletions
99
...c/test/java/org/openmrs/maven/plugins/packager/config/ValidateContentPackageMojoTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
|
||
package org.openmrs.maven.plugins.packager.config; | ||
|
||
import static org.junit.Assert.assertFalse; | ||
import static org.junit.Assert.assertTrue; | ||
|
||
import java.io.FileInputStream; | ||
import java.util.Properties; | ||
|
||
import org.apache.maven.plugin.MojoExecutionException; | ||
import org.junit.Before; | ||
import org.junit.Rule; | ||
import org.junit.Test; | ||
import org.junit.rules.ExpectedException; | ||
import org.mockito.InjectMocks; | ||
import org.mockito.Mock; | ||
import org.mockito.MockitoAnnotations; | ||
|
||
public class ValidateContentPackageMojoTest { | ||
|
||
@InjectMocks | ||
private ValidateContentPackageMojo mojo = new ValidateContentPackageMojo(); | ||
|
||
@Mock | ||
private FileInputStream mockFileInputStream; | ||
|
||
@Mock | ||
private Properties mockProperties; | ||
|
||
@Rule | ||
public ExpectedException exceptionRule = ExpectedException.none(); | ||
|
||
@Before | ||
public void setUp() { | ||
MockitoAnnotations.initMocks(this); | ||
} | ||
|
||
@Test | ||
public void executeValidContentPropertiesFileWithoutErrors() throws Exception { | ||
String validPropertiesFile = "src/test/resources/config-test-child/valid-content.properties"; | ||
mojo.sourceFile = validPropertiesFile; | ||
mojo.execute(); | ||
//no exception is thrown | ||
} | ||
|
||
@Test(expected = MojoExecutionException.class) | ||
public void executeInvalidContentPropertiesFormatWithException() throws Exception { | ||
String invalidPropertiesFile = "src/test/resources/config-test-child/invalid-content.properties"; | ||
mojo.sourceFile = invalidPropertiesFile; | ||
mojo.execute(); | ||
//exception is thrown | ||
} | ||
|
||
@Test | ||
public void testInValidVersions() { | ||
assertFalse(mojo.isValid("latest")); | ||
assertFalse(mojo.isValid("next")); | ||
|
||
} | ||
|
||
public void testValidVersionRanges() { | ||
assertTrue(mojo.isValid("1.0")); | ||
assertTrue(mojo.isValid("0.13.0")); | ||
assertTrue(mojo.isValid("0.13.0")); | ||
assertTrue(mojo.isValid("^2.13.0")); | ||
assertTrue(mojo.isValid("~0.13.0")); | ||
assertTrue(mojo.isValid(">0.13.0")); | ||
assertTrue(mojo.isValid("<3.0.0")); | ||
assertTrue(mojo.isValid(">=3.0.0")); | ||
assertTrue(mojo.isValid(">=1.2.3")); | ||
assertTrue(mojo.isValid(">=1.2")); | ||
assertTrue(mojo.isValid("<=3.0.0")); | ||
assertTrue(mojo.isValid("1.0.0 - 1.10.10")); | ||
assertTrue(mojo.isValid("<2.1.0 || >2.6.0")); | ||
assertTrue(mojo.isValid(">=1.0.0-SNAPSHOT")); | ||
assertTrue(mojo.isValid(">=1.0.0-pre.1")); | ||
//some edge cases | ||
assertFalse(mojo.isValid("1.0.0-1234-")); | ||
assertFalse(mojo.isValid("abc")); | ||
assertFalse(mojo.isValid("1..0")); | ||
} | ||
|
||
@Test | ||
public void validNPMVersion() { | ||
assertTrue(mojo.isValid("1.0.01")); | ||
assertTrue(mojo.isValid("1.0.0-alpha@")); | ||
assertTrue(mojo.isValid("1.0.0.0")); | ||
} | ||
|
||
@Test | ||
public void testComplexRanges() { | ||
assertTrue(mojo.isValid(">=1.0.0 <2.0.0")); | ||
assertTrue(mojo.isValid("1.1.1 || 1.2.3 - 2.0.0")); | ||
assertTrue(mojo.isValid(">=1.0.0 - <2.0.0")); | ||
assertTrue(mojo.isValid("~2.1.5 || ~2.4.2 || >= 2.5-SNAPSHOT")); | ||
assertTrue(mojo.isValid("1.1.1 || 1.2.3 ! 2.0.0")); | ||
} | ||
|
||
} |
18 changes: 18 additions & 0 deletions
18
integration-tests/src/test/resources/config-test-child/invalid-content.properties
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# content.properties - Metadata for the content package and its dependencies | ||
|
||
# The name of this content package | ||
name=openmrs-content-hiv | ||
|
||
# The version of this content package (must follow SemVer) | ||
version=latest | ||
|
||
# Dependencies (specified in a format similar to distro.properties) | ||
|
||
# OMOD modules with their SemVer range | ||
omod.fhir2=>=1.0.0-SNAPSHOT | ||
omod.reporting=^2.0.0 | ||
|
||
# SPA modules with their SemVer range | ||
spa.frontendModules.@openmrs/esm-login-app=^3.0.0 | ||
spa.frontendModules.@openmrs/esm-patient-chart=~1.0.0 | ||
|
18 changes: 18 additions & 0 deletions
18
integration-tests/src/test/resources/config-test-child/valid-content.properties
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# content.properties - Metadata for the content package and its dependencies | ||
|
||
# The name of this content package | ||
name=openmrs-content-hiv | ||
|
||
# The version of this content package (must follow SemVer) | ||
version=1.0.0-SNAPSHOT | ||
|
||
# Dependencies (specified in a format similar to distro.properties) | ||
|
||
# OMOD modules with their SemVer range | ||
|
||
omod.reporting=>=2.0.1 | ||
|
||
# SPA modules with their SemVer range | ||
spa.frontendModules.@openmrs/esm-login-app=1.20.2 - 12.3.0 | ||
spa.frontendModules.@openmrs/esm-patient-chart=^1.0.0 | ||
|
111 changes: 111 additions & 0 deletions
111
...n/src/main/java/org/openmrs/maven/plugins/packager/config/ValidateContentPackageMojo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
/** | ||
* This Source Code Form is subject to the terms of the Mozilla Public License, | ||
* v. 2.0. If a copy of the MPL was not distributed with this file, you can | ||
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under | ||
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license. | ||
* | ||
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark, and the OpenMRS | ||
* graphic logo is a trademark of OpenMRS Inc. | ||
*/ | ||
package org.openmrs.maven.plugins.packager.config; | ||
|
||
import java.io.FileInputStream; | ||
import java.io.InputStream; | ||
import java.util.Properties; | ||
|
||
import org.apache.maven.plugin.AbstractMojo; | ||
import org.apache.maven.plugin.MojoExecutionException; | ||
import org.apache.maven.plugins.annotations.Mojo; | ||
import org.apache.maven.plugins.annotations.Parameter; | ||
import org.semver4j.Semver; | ||
import org.semver4j.SemverException; | ||
|
||
/** | ||
* Mojo to validate content properties file - ensures the properties are only within allowed ranges. | ||
* Values like "latest" and "next" are not permitted. | ||
*/ | ||
@Mojo(name = "validate-content-package") | ||
public class ValidateContentPackageMojo extends AbstractMojo { | ||
|
||
// List of terms that are not valid versions | ||
private static final String[] INVALID_TERMS = { "latest", "next" }; | ||
|
||
/** | ||
* The full path to the content.properties file, including the filename. This file is similar to | ||
* distro.properties used in the validation process. For example: | ||
* "{project.basedir}/content.properties". | ||
*/ | ||
@Parameter(property = "sourceFile") | ||
protected String sourceFile; | ||
|
||
/** | ||
* Executes the property validation. | ||
* | ||
* @throws MojoExecutionException if an error occurs during validation | ||
*/ | ||
@Override | ||
public void execute() throws MojoExecutionException { | ||
validateProperties(); | ||
} | ||
|
||
/** | ||
* Validates the properties in the given file. | ||
* | ||
* @throws MojoExecutionException if an error occurs while reading the file | ||
*/ | ||
private void validateProperties() throws MojoExecutionException { | ||
if (sourceFile == null) { | ||
throw new MojoExecutionException( | ||
"sourceFile is missing. A valid path and file for content.properties are required for this plugin."); | ||
} | ||
try (InputStream inputStream = new FileInputStream(sourceFile)) { | ||
Properties properties = new Properties(); | ||
properties.load(inputStream); | ||
|
||
if (!properties.containsKey("name") || !properties.containsKey("version")) { | ||
throw new MojoExecutionException("The properties file must contain both 'name' and 'version' keys."); | ||
} | ||
|
||
for (String key : properties.stringPropertyNames()) { | ||
String value = properties.getProperty(key); | ||
|
||
if (key.startsWith("omod") || key.startsWith("owa") || key.startsWith("spa.frontend") | ||
|| "version".equalsIgnoreCase(key)) { | ||
if (!isValid(value)) { | ||
throw new MojoExecutionException("Invalid SemVer format for key: " + key + ", value: " + value); | ||
} | ||
} | ||
} | ||
} | ||
catch (Exception e) { | ||
throw new MojoExecutionException("Could not validate configuration file '" + sourceFile + "': " + e.getMessage(), | ||
e); | ||
} | ||
} | ||
|
||
/** | ||
* Validates whether a given value is a valid SemVer expression. If the range expression | ||
* satisfies(true or false), it is considered valid. If an exception occurs, the range | ||
* expression is invalid. | ||
* | ||
* @param versionOrRange the value to validate | ||
* @return true if the value is a valid SemVer expression or range, false otherwise | ||
*/ | ||
protected boolean isValid(String versionOrRange) { | ||
|
||
for (String term : INVALID_TERMS) { | ||
if (term.equalsIgnoreCase(versionOrRange)) { | ||
return false; | ||
} | ||
} | ||
|
||
try { | ||
Semver semver = new Semver("0.0.0"); | ||
semver.satisfies(versionOrRange); | ||
return true; | ||
} | ||
catch (SemverException e) { | ||
return false; | ||
} | ||
} | ||
} |
Oops, something went wrong.