Skip to content

Commit

Permalink
Merge pull request e-gineering#133 from DEsoftware/set-properties-set…
Browse files Browse the repository at this point in the history
…s-git-info

New goal set-git-properties
  • Loading branch information
bvarner authored Apr 17, 2023
2 parents 04fb7c2 + c1a29a2 commit 7ac1213
Show file tree
Hide file tree
Showing 4 changed files with 351 additions and 0 deletions.
117 changes: 117 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,123 @@ from a property file during the build. Both property key names and property valu
Multiple executions can be configured, and each execution can target different scopes (system or project), and can load
properties from files with an assigned keyPrefix, letting you name-space properties from execution ids.

## Goal: `set-git-properties` (Stores branch type and name in Maven properties)

The goal `set-git-properties` sets in the Git branch type and name in Maven properties.
The following properties are set:

* `branchType`: The type of the branch
* `branchName`: The name of the branch

### Mapping Git branch name

In certain situations it is necessary to sanitize the branch name (e.g. when using the branch name as tag for a docker image).
For such purposes it is possible to the map the branch name and store the mapped value in an additional Maven property.

### Mapping branch name with a java class

The mapper can be implemented with a Java class that implements `java.util.function.BiFunction<String,String,String>`.
* The first argument of the function is the branch name, the second argument is the branch type.
* The result of the function is the mapped branch name.
* The class has to be provided via a maven artifact as dependency of the plugin.
* The `language` element has the value `java`.
* The `propertyName` defines the name of the Maven property where the mapped branch name is stored.

Example:
```xml
<build>
<plugins>
<plugin>
<groupId>com.e-gineering</groupId>
<artifactId>gitflow-helper-maven-plugin</artifactId>
<version>${gitflow.helper.plugin.version}</version>
<configuration>
<branchNamePropertyMappers>
<branchNamePropertyMapper>
<propertyName>branchNameLowerCase</propertyName>
<language>java</language>
<mapper>com.example.BranchMapperToLowerCase</mapper>
</branchNamePropertyMapper>
</branchNamePropertyMappers>
</configuration>
<executions>
<execution>
<goals>
<goal>set-git-properties</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupdId>com.example</groupdId>
<artifactId>branchNameMapper</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</plugin>
</plugins>
...
</build>
```
The mapper class:
```java
package com.example;

import java.util.function.BiFunction;

public class BranchMapperToLowerCase implements BiFunction<String,String,String>
{
public String apply(String branchName, String branchType)
{
return branchName.toLowerCase();
}
}
```

### Mapping the branch name with a JSR223 scripting language

The branch name mapping can also be implemented with a JSR232 scripting language.
For this case the

* `language` is the name of the JSR232 scripting language (per default only `javascript` is possible. For additional language can be provided by additional dependencies)
* `mapper` contains the script that implements a function with map `map`. The first parameter of the function is the branch name, the second parameter is the branch type.
* The return value of the script is the mapped branch name. It is stored in the property.
* The Git branch name is stored in the variable `branchName` and the branch type is accessible via `branchType`

**Example:** Mapper in javascript

```xml
<build>
<plugins>
<plugin>
<groupId>com.e-gineering</groupId>
<artifactId>gitflow-helper-maven-plugin</artifactId>
<version>${gitflow.helper.plugin.version}</version>
<configuration>
<branchNamePropertyMappers>
<branchNamePropertyMapper>
<propertyName>branchNameLowerCase</propertyName>
<language>javascript</language>
<mapper>
function map(branchName, branchType) {
return branchName.toLowerCase();
}
</mapper>
</branchNamePropertyMapper>
</branchNamePropertyMappers>
</configuration>
<executions>
<execution>
<goals>
<goal>set-git-properties</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
...
</build>
```

## Goal: `retarget-deploy` (Branch Specific Deploy Targets & Staging)

Expand Down
117 changes: 117 additions & 0 deletions src/main/java/com/e_gineering/maven/gitflowhelper/PropertyMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package com.e_gineering.maven.gitflowhelper;

import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.shared.utils.StringUtils;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.util.function.BiFunction;

/**
* Helper for mapping the GIT branch name
*/
public class PropertyMapper
{
private String propertyName;
private String language = "java";
private String mapper;

public String getLanguage()
{
return language;
}

public void setLanguage(final String language)
{
this.language = language;
}

public String getPropertyName()
{
return propertyName;
}

public void setPropertyName(final String propertyName)
{
this.propertyName = propertyName;
}

public String getMapper()
{
return mapper;
}

public void setMapper(final String mapper)
{
this.mapper = mapper;
}

/**
* Maps the Git branch name
* @param gitBranchInfo the Git Info
* @return the mapped branch name
* @throws MojoExecutionException on error
*/
String map(GitBranchInfo gitBranchInfo) throws MojoExecutionException
{
if(StringUtils.isBlank(getPropertyName())) {
throw new MojoExecutionException("Mapper has not propertyName");
}
if(StringUtils.isBlank(getLanguage())) {
throw new MojoExecutionException("Mapper for property [" + getPropertyName() + "] has no language");
}
if(StringUtils.isBlank(getMapper())) {
throw new MojoExecutionException("Mapper for property [" + getPropertyName() + "] has no mapper");
}
if("java".equalsIgnoreCase(language)) {

Class<?> mapperClass;
try
{
mapperClass = Class.forName(mapper.trim());
}
catch(ClassNotFoundException e)
{
throw new MojoExecutionException("Error in mapper for property [" + getPropertyName() + "]: class " + mapper + " not found", e);
}

if(!BiFunction.class.isAssignableFrom(mapperClass)) {
throw new MojoExecutionException("Error in mapper for property [" + getPropertyName() + "]: class " + mapper + " does not implement " + BiFunction.class.getName());
}

try
{
@SuppressWarnings("unchecked")
BiFunction<String,String,String> function = (BiFunction<String,String,String>)Class.forName(mapper).newInstance();
return function.apply(gitBranchInfo.getName(), gitBranchInfo.getType().name());
}
catch(Exception e)
{
throw new MojoExecutionException("Error in mapper for property [" + getPropertyName() + "]", e);
}
}
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName(language);
if(engine == null) {
throw new MojoExecutionException("Property mapper for property [" + getPropertyName() + "] has an unsupported language [" + language + "]");
}
try
{
engine.eval(mapper);

Invocable inv = (Invocable) engine;

Object ret = inv.invokeFunction("map", gitBranchInfo.getName(), gitBranchInfo.getType());
if(ret == null) {
return null;
}
return String.valueOf(ret);
}
catch(Exception e)
{
throw new MojoExecutionException("Error in property mapper for property [" + getPropertyName()+ "]", e);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.e_gineering.maven.gitflowhelper;

import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.codehaus.plexus.util.StringUtils;

/**
* Stores the branch type and the git branch in Maven properties
*/
@Mojo(name = "set-git-properties", defaultPhase = LifecyclePhase.VALIDATE, threadSafe = true)
public class SetGitPropertiesMojo extends AbstractGitflowBranchMojo
{
/**
* Defines the name of the property where the branch type is stored
*/
@Parameter(property = "branchTypeProperty", defaultValue = "branchType")
private String branchTypeProperty = "branchType";

/**
* Defines the name of the property where the Git branch name is stored.
*/
@Parameter(property = "branchNameProperty", defaultValue = "gitBranchName")
private String branchNameProperty = "branchName";

/**
* Der branchNamePropertyMapper allows to store the Git branch name
* into additional properties.<br>
* The branchName can be mapped by a java class, or an JSR223 scripting language
*/
@Parameter(property = "branchNamePropertyMappers")
private PropertyMapper[] branchNamePropertyMappers;

@Override
protected void execute(final GitBranchInfo gitBranchInfo) throws MojoExecutionException, MojoFailureException
{
if(!StringUtils.isBlank(branchTypeProperty)) {
project.getProperties().setProperty(branchTypeProperty, gitBranchInfo.getType().name());
}
if(!StringUtils.isBlank(branchNameProperty)) {
project.getProperties().setProperty(branchNameProperty, gitBranchInfo.getName());
}

if(branchNamePropertyMappers != null) {
for(PropertyMapper pm : branchNamePropertyMappers)
{
String mappedValue = pm.map(gitBranchInfo);
getLog().info("Mapper [" + pm.getPropertyName() + "] mapped Git branch name [" + gitBranchInfo.getName() + "] to [" + mappedValue + "]");
if(StringUtils.isBlank(mappedValue)) {
getLog().warn("Mapper for property [" + pm.getPropertyName() + "] did not provide a value, ignoring it");
continue;
}
project.getProperties().setProperty(pm.getPropertyName(), mappedValue);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.e_gineering.maven.gitflowhelper;

import org.apache.maven.plugin.MojoExecutionException;
import org.junit.Assert;
import org.junit.Test;

import java.util.function.BiFunction;

public class TestPropertyMapper
{
/**
* Test the methode {@link PropertyMapper#map(GitBranchInfo)} with a Java Mapper
* @throws MojoExecutionException on error
*/
@Test
public void testPropertyMapperWithJava() throws MojoExecutionException
{
PropertyMapper mapper = new PropertyMapper();
mapper.setPropertyName("prop");
mapper.setLanguage("java");
mapper.setMapper(ToLowerCaseMapper.class.getName());

GitBranchInfo info = new GitBranchInfo("FOO", GitBranchType.DEVELOPMENT, "bar");

Assert.assertEquals("foo", mapper.map(info));
}

/**
* Test the methode {@link PropertyMapper#map(GitBranchInfo)} with a Javascript Mapper
* @throws MojoExecutionException on error
*/
@Test
public void testPropertyMapperWithJavascript() throws MojoExecutionException
{
PropertyMapper mapper = new PropertyMapper();
mapper.setPropertyName("prop");
mapper.setLanguage("javascript");
mapper.setMapper(""
+ "function map(branchName, branchType) {\n"
+" return branchName.toLowerCase();\n"
+ "}"
);

GitBranchInfo info = new GitBranchInfo("FOO", GitBranchType.DEVELOPMENT, "bar");

Assert.assertEquals("foo", mapper.map(info));

}

public static class ToLowerCaseMapper implements BiFunction<String,String,String>
{
@Override
public String apply(String branchName, String branchType)
{
return branchName.toLowerCase();
}
}
}

0 comments on commit 7ac1213

Please sign in to comment.