Skip to content

Commit

Permalink
Default values for configuration, especially VersionInfo (#205)
Browse files Browse the repository at this point in the history
* Fix: Escape angle brackets in Markdown documentation to be printed out.

GitHub uses one of many kinds of Markdown syntaxes. In this one it does not display plain text inside angle brackets (like <any text>) in the headers, so we need to escape them. For details, please see the issue: microsoft/vscode#12491

* `disableVersionInfoDefaults` docs note added

* Snapshot version bump according to default parameters changes

* New parameter for disabling VersionInfo defaults

* Filling out VersionInfo defaults

* Filling out VersionInfo defaults

* Unit tests for Copyright generator

* Copyright generator description

* JUnitParams lib added to POM.xml

* Unit tests for Launch4j fileVersion generator

* Additional Unit tests for Launch4j fileVersion generator

* Refactoring of Launch4j fileVersion generator

* "errTitle" default value provided

* "errTitle" default value in docs

* "versionInfo -> originalFilename" default value added

* release version notes Resolves #98

* Line added to MOJO doc

* trademarks & companyName also filled by defaults

* Mockito Core library added

* VersionInfo refactoring

* VersionInfo unit tests

* Adds missing VersionInfo unit tests

* Adds missing Mojo param to MojoTest

* Refactoring MojoTest

* Missing dependency added to POM

* Possibility of not filling out VersionInfo in XML at all

* Documentation for VersionInfo defaults added

* Throwing exception datailed descriptions

* Release version without snapshot

* Revert "Release version without snapshot"

This reverts commit d019663.

* default scope for filling out defaults inside VersionInfo

* Newline's at the end of the files

* Private constructors for utility classes added
  • Loading branch information
koksyn authored Jan 6, 2023
1 parent a18045e commit e3949fe
Show file tree
Hide file tree
Showing 13 changed files with 986 additions and 41 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ The full list of all the parameters is available [here](src/main/resources/MOJO.

# Version Notes

## Version notes 2.3.0 - 2022-12-30
- provides default values for plugin configuration, especially for `<VersionInfo>`, see Issue [#98](../../issues/98)
- adds a `disableVersionInfoDefaults` parameter to be able to disable provided defaults, see PR [#205](../../pull/205)
- adds documentation notes regarding a new defaults, see [VERSIONINFO.md](src/main/resources/VERSIONINFO.md)
- throwing exceptions with detailed description of default values formula, when cannot fulfill default values (no configuration data for formula), it helps plugin user with debugging what is wrong

## Version notes 2.2.0 - 2022-11-24
- upgrades Launch4j to version 3.50 and adopts config to the bew requirements, see Issue [#199](../../issues/199)
and PR [#200](../../pull/200) for more details what has to be changed
Expand Down
19 changes: 18 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<groupId>com.akathist.maven.plugins.launch4j</groupId>
<artifactId>launch4j-maven-plugin</artifactId>
<packaging>maven-plugin</packaging>
<version>2.2.1-SNAPSHOT</version>
<version>2.3.0-SNAPSHOT</version>

<name>Maven Launch4j Plugin</name>
<description>This plugin creates Windows executables from Java jar files using the Launch4j utility.</description>
Expand Down Expand Up @@ -119,12 +119,29 @@
<artifactId>maven-artifact-transfer</artifactId>
<version>0.13.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>pl.pragmatists</groupId>
<artifactId>JUnitParams</artifactId>
<version>1.1.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.11.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-testing</groupId>
<artifactId>maven-plugin-testing-harness</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ public class Launch4jMojo extends AbstractMojo {
* like if java can't be found. If this is a console app and not a gui, then this value
* is used to prefix any error messages, as in ${errTitle}: ${errorMessage}.
*/
@Parameter
@Parameter(defaultValue = "${project.name}")
private String errTitle;

/**
Expand Down Expand Up @@ -262,7 +262,7 @@ public class Launch4jMojo extends AbstractMojo {
* Details about the classpath your application should have.
* This is required if you are not wrapping a jar.
*/
@Parameter()
@Parameter
private ClassPath classPath;

/**
Expand All @@ -283,6 +283,12 @@ public class Launch4jMojo extends AbstractMojo {
@Parameter
private VersionInfo versionInfo;

/**
* If set to true, it will prevent filling out the VersionInfo params with default values.
*/
@Parameter(defaultValue = "false")
private boolean disableVersionInfoDefaults;

/**
* Various messages you can display.
*/
Expand Down Expand Up @@ -340,6 +346,17 @@ private void doExecute() throws MojoExecutionException {
return;
}

if (!disableVersionInfoDefaults) {
try {
if(versionInfo == null) {
versionInfo = new VersionInfo();
}
versionInfo.tryFillOutByDefaults(project, outfile);
} catch (RuntimeException exception) {
throw new MojoExecutionException("Cannot fill out VersionInfo by defaults", exception);
}
}

final File workDir = setupBuildEnvironment();
if (infile != null) {
if (infile.exists()) {
Expand Down Expand Up @@ -834,6 +851,7 @@ public String toString() {
", singleInstance=" + singleInstance +
", splash=" + splash +
", versionInfo=" + versionInfo +
", disableVersionInfoDefaults=" + disableVersionInfoDefaults +
", messages=" + messages +
", manifest=" + manifest +
", saveConfig=" + saveConfig +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,22 @@
*/
package com.akathist.maven.plugins.launch4j;

import com.akathist.maven.plugins.launch4j.generators.CopyrightGenerator;
import com.akathist.maven.plugins.launch4j.generators.Launch4jFileVersionGenerator;
import net.sf.launch4j.config.LanguageID;
import org.apache.commons.lang3.StringUtils;
import org.apache.maven.model.Organization;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

/**
* Information that appears in the Windows Explorer.
*/
public class VersionInfo {

private static final Map<String, LanguageID> LANGUAGE_TO_LANGUAGE_ID;

static {
Expand Down Expand Up @@ -110,6 +115,27 @@ public class VersionInfo {
@Parameter
String trademarks;

public VersionInfo() {
}

public VersionInfo(String fileVersion, String txtFileVersion, String fileDescription,
String copyright, String productVersion, String txtProductVersion,
String productName, String companyName, String internalName,
String originalFilename, String language, String trademarks) {
this.fileVersion = fileVersion;
this.txtFileVersion = txtFileVersion;
this.fileDescription = fileDescription;
this.copyright = copyright;
this.productVersion = productVersion;
this.txtProductVersion = txtProductVersion;
this.productName = productName;
this.companyName = companyName;
this.internalName = internalName;
this.originalFilename = originalFilename;
this.language = language;
this.trademarks = trademarks;
}

net.sf.launch4j.config.VersionInfo toL4j() {
net.sf.launch4j.config.VersionInfo ret = new net.sf.launch4j.config.VersionInfo();

Expand Down Expand Up @@ -137,6 +163,75 @@ private void setLanguage(net.sf.launch4j.config.VersionInfo ret) {
ret.setLanguage(languageID);
}

void tryFillOutByDefaults(MavenProject project, File outfile) {
if (project == null) {
throw new IllegalArgumentException("'project' is required, but it is null.");
}
if (outfile == null) {
throw new IllegalArgumentException("'outfile' is required, but it is null.");
}

String version = project.getVersion();
Organization organization = project.getOrganization();

tryFillOutByDefaultVersionInL4jFormat(version);
tryFillOutCopyrightByDefaults(project.getInceptionYear(), organization);
tryFillOutOrganizationRelatedDefaults(organization);
tryFillOutSimpleValuesByDefaults(
version,
project.getName(),
project.getArtifactId(),
project.getDescription()
);

originalFilename = getDefaultWhenOriginalIsBlank(originalFilename, outfile.getName(), "originalFilename", "${project.version}");
}

private void tryFillOutByDefaultVersionInL4jFormat(String version) {
final String defaultFileVersion = Launch4jFileVersionGenerator.generate(version);
fileVersion = getDefaultWhenOriginalIsBlank(fileVersion, defaultFileVersion, "fileVersion", "${project.version}");
productVersion = getDefaultWhenOriginalIsBlank(productVersion, defaultFileVersion, "productVersion", "${project.version}");
}

private void tryFillOutCopyrightByDefaults(String inceptionYear, Organization organization) {
final String defaultCopyright = CopyrightGenerator.generate(inceptionYear, organization);
copyright = getDefaultWhenOriginalIsBlank(copyright, defaultCopyright, "copyright", "${project.inceptionYear},${project.organization.name}");
}

private void tryFillOutOrganizationRelatedDefaults(Organization organization) {
if (organization != null) {
companyName = getDefaultWhenOriginalIsBlank(companyName, organization.getName(), "companyName", "${project.organization.name}");
trademarks = getDefaultWhenOriginalIsBlank(trademarks, organization.getName(), "trademarks", "${project.organization.name}");
}
}

private void tryFillOutSimpleValuesByDefaults(String version,
String name,
String artifactId,
String description) {
txtFileVersion = getDefaultWhenOriginalIsBlank(txtFileVersion, version, "txtFileVersion", "${project.version}");
txtProductVersion = getDefaultWhenOriginalIsBlank(txtProductVersion, version, "txtProductVersion", "${project.version}");
productName = getDefaultWhenOriginalIsBlank(productName, name, "productName", "${project.name}");
internalName = getDefaultWhenOriginalIsBlank(internalName, artifactId, "internalName", "${project.artifactId}");
fileDescription = getDefaultWhenOriginalIsBlank(fileDescription, description, "fileDescription", "${project.description}");
}

private String getDefaultWhenOriginalIsBlank(final String originalValue,
final String defaultValue,
final String originalParameterName,
final String defaultValueFormulaParams) {
if (StringUtils.isBlank(originalValue)) {
if(StringUtils.isNotBlank(defaultValue)) {
return defaultValue;
}

throw new IllegalStateException("Please fill the missing configuration values. " +
"Error when trying to fulfill default value for VersionInfo parameter:'" + originalParameterName + "' with formula params:'" + defaultValueFormulaParams + "'.");
}

return originalValue;
}

@Override
public String toString() {
return "VersionInfo{" +
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.akathist.maven.plugins.launch4j.generators;

import org.apache.commons.lang3.StringUtils;
import org.apache.maven.model.Organization;

import java.time.LocalDate;

public class CopyrightGenerator {
private CopyrightGenerator() {
}

/**
* Parameters should be taken from MavenProject properties:
* @param projectInceptionYear as ${project.inceptionYear}
* @param projectOrganization as ${project.organization}
*/
public static String generate(String projectInceptionYear, Organization projectOrganization) {
String inceptionYear = generateInceptionYear(projectInceptionYear);
int buildYear = LocalDate.now().getYear();
String organizationName = generateOrganizationName(projectOrganization);

return String.format("Copyright © %s%d%s. All rights reserved.", inceptionYear, buildYear, organizationName);
}

private static String generateInceptionYear(String projectInceptionYear) {
if(StringUtils.isNotBlank(projectInceptionYear)) {
return projectInceptionYear + "-";
}

return "";
}

private static String generateOrganizationName(Organization projectOrganization) {
if(projectOrganization != null && StringUtils.isNotBlank(projectOrganization.getName())) {
return " " + projectOrganization.getName();
}

return "";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.akathist.maven.plugins.launch4j.generators;

import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;

public class Launch4jFileVersionGenerator {
private static final int REQUIRED_NESTED_VERSION_LEVELS = 4;
private static final String SIMPLE_PROJECT_VERSION_REGEX = "^((\\d(\\.)?)*\\d+)(-\\w+)?$";
private static final Pattern simpleProjectVersionPattern = Pattern.compile(
SIMPLE_PROJECT_VERSION_REGEX, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE
);

private Launch4jFileVersionGenerator() {
}

/**
* Converts projectVersion into a format "x.x.x.x" ('x' as a number), which is required by Launch4j.
*
* For shorter versions like "x.x.x" it will append zeros (to the 4th level) at the end like "x.x.x.0".
* Every text flag like "-SNAPSHOT" or "-alpha" will be cut off.
* Too many nested numbers (more than 4 levels) will be cut off as well: "1.2.3.4.5.6" -> "1.2.3.4".
*
* Param should be taken from MavenProject property:
* @param projectVersion as ${project.version}
*/
public static String generate(String projectVersion) {
if(projectVersion == null) {
return null;
}
if(!simpleProjectVersionPattern.matcher(projectVersion).matches()) {
throw new IllegalArgumentException("'project.version' is in invalid format. Regex pattern: " + SIMPLE_PROJECT_VERSION_REGEX);
}

String versionLevels = removeTextFlags(projectVersion);
String limitedVersionLevels = cutOffTooManyNestedLevels(versionLevels);

return appendMissingNestedLevelsByZeros(limitedVersionLevels);
}

private static String removeTextFlags(String version) {
if(version.contains("-")) {
String[] parts = version.split("-");
return parts[0];
}

return version;
}

private static String cutOffTooManyNestedLevels(String versionLevels) {
String[] levels = versionLevels.split("\\.");

if(levels.length > REQUIRED_NESTED_VERSION_LEVELS) {
List<String> limitedLevels = Arrays.asList(levels)
.subList(0, REQUIRED_NESTED_VERSION_LEVELS);
return String.join(".", limitedLevels);
}

return versionLevels;
}

private static String appendMissingNestedLevelsByZeros(String versionLevels) {
String[] levels = versionLevels.split("\\.");

StringBuilder filledLevels = new StringBuilder(versionLevels);
for (int i = levels.length; i < REQUIRED_NESTED_VERSION_LEVELS; i++) {
filledLevels.append(".0");
}

return filledLevels.toString();
}
}
Loading

0 comments on commit e3949fe

Please sign in to comment.