[cli] allow properties to be set on the command line. Resolves #308

This commit is contained in:
Andres Almiray
2021-07-25 00:42:17 +02:00
parent 50abfa2a29
commit 73c202eb0e
8 changed files with 90 additions and 56 deletions

View File

@@ -19,7 +19,9 @@ package org.jreleaser.cli;
import org.jreleaser.config.JReleaserConfigParser;
import org.jreleaser.engine.context.ContextCreator;
import org.jreleaser.model.Environment;
import org.jreleaser.model.JReleaserContext;
import org.jreleaser.model.JReleaserModel;
import org.jreleaser.model.JReleaserVersion;
import org.jreleaser.util.StringUtils;
import picocli.CommandLine;
@@ -31,6 +33,7 @@ import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Optional;
import java.util.Properties;
import java.util.ServiceLoader;
import java.util.Set;
@@ -50,6 +53,11 @@ public abstract class AbstractModelCommand extends AbstractCommand {
description = "Searches for the Git root.")
boolean gitRootSearch;
@CommandLine.Option(names = {"-p", "--set-property"},
paramLabel = "<key=value>",
description = "Sets the value of a property. Repeatable.")
String[] properties;
@CommandLine.ParentCommand
Main parent;
@@ -125,11 +133,15 @@ public abstract class AbstractModelCommand extends AbstractCommand {
protected abstract void doExecute(JReleaserContext context);
protected JReleaserContext createContext() {
JReleaserModel model = ContextCreator.resolveModel(logger, actualConfigFile);
Environment.PropertiesSource propertiesSource = new Environment.PropertiesPropertiesSource(collectProperties());
model.getEnvironment().setPropertiesSource(propertiesSource);
return ContextCreator.create(
logger,
resolveConfigurer(actualConfigFile),
getMode(),
actualConfigFile,
model,
actualBasedir,
getOutputDirectory(),
dryrun(),
@@ -179,4 +191,25 @@ public abstract class AbstractModelCommand extends AbstractCommand {
protected List<String> collectSelectedPlatforms() {
return Collections.emptyList();
}
protected Properties collectProperties() {
Properties props = new Properties();
if (properties != null && properties.length > 0) {
for (String property : properties) {
if (property.contains("=")) {
int d = property.indexOf('=');
if (d == 0 || d == properties.length - 1) {
throw new IllegalArgumentException("Invalid property '" + property + "'");
}
props.put(property.substring(0, d),
property.substring(d + 1));
} else {
props.put(property, Boolean.TRUE);
}
}
}
return props;
}
}

View File

@@ -30,12 +30,13 @@ import java.util.List;
*/
@CommandLine.Command
public abstract class AbstractPlatformAwareModelCommand extends AbstractModelCommand {
@CommandLine.Option(names = {"--select-current-platform"},
@CommandLine.Option(names = {"-scp", "--select-current-platform"},
description = "Activates paths matching the current platform.")
boolean selectCurrentPlatform;
@CommandLine.Option(names = {"--select-platform"},
description = "Activates paths matching the given platform.")
@CommandLine.Option(names = {"-sp", "--select-platform"},
paramLabel = "<platform>",
description = "Activates paths matching the given platform. Repeatable.")
String[] selectPlatforms;
@Override

View File

@@ -96,7 +96,8 @@ public class Release extends AbstractPlatformAwareModelCommand {
boolean update;
@CommandLine.Option(names = {"--update-section"},
description = "Release section to be updated.")
paramLabel = "<section>",
description = "Release section to be updated. Repeatable.")
String[] updateSections;
@CommandLine.Option(names = {"--skip-tag"},
@@ -136,11 +137,13 @@ public class Release extends AbstractPlatformAwareModelCommand {
boolean armored;
@CommandLine.Option(names = {"--file"},
description = "Input file(s) to be uploaded.")
paramLabel = "<file>",
description = "Input file to be uploaded. Repeatable.")
String[] files;
@CommandLine.Option(names = {"--glob"},
description = "Input file(s) to be uploaded (as globs).")
paramLabel = "<file>",
description = "Input file to be uploaded (as glob). Repeatable.")
String[] globs;
protected void execute() {

View File

@@ -211,7 +211,7 @@ public class Artifact implements Domain, ExtraProperties {
return resolvedTransform;
}
private Map<String,Object> artifactProps(Map<String, Object> props) {
private Map<String, Object> artifactProps(Map<String, Object> props) {
props.putAll(getExtraProperties());
props.putAll(getResolvedExtraProperties());
props.put("platform", platform);

View File

@@ -32,6 +32,7 @@ import java.util.Optional;
import java.util.Properties;
import java.util.ServiceLoader;
import static org.jreleaser.util.StringUtils.getPropertyNameForLowerCaseHyphenSeparatedName;
import static org.jreleaser.util.StringUtils.isBlank;
import static org.jreleaser.util.StringUtils.isNotBlank;
@@ -41,19 +42,19 @@ import static org.jreleaser.util.StringUtils.isNotBlank;
*/
public class Environment implements Domain {
private final Map<String, Object> properties = new LinkedHashMap<>();
private VariablesSource variablesSource;
private PropertiesSource propertiesSource;
private String variables;
private Properties props;
private Properties vars;
private Path propertiesFile;
void setAll(Environment environment) {
this.variablesSource = environment.variablesSource;
this.variables = environment.variables;
setProperties(environment.properties);
setPropertiesSource(environment.propertiesSource);
}
public String getVariable(String key) {
return props.getProperty(Env.prefix(key));
return vars.getProperty(Env.prefix(key));
}
public boolean isSet() {
@@ -61,12 +62,15 @@ public class Environment implements Domain {
!properties.isEmpty();
}
public VariablesSource getVariablesSource() {
return variablesSource;
public PropertiesSource getPropertiesSource() {
return propertiesSource;
}
public void setVariablesSource(VariablesSource variablesSource) {
this.variablesSource = variablesSource;
public void setPropertiesSource(PropertiesSource propertiesSource) {
this.propertiesSource = propertiesSource;
if (null != this.propertiesSource) {
properties.putAll(propertiesSource.getProperties());
}
}
public String getVariables() {
@@ -99,13 +103,8 @@ public class Environment implements Domain {
}
public void initProps(JReleaserContext context) {
if (null == props) {
props = new Properties();
if (isNotBlank(variables)) {
loadProperties(context, context.getBasedir().resolve(variables.trim()));
return;
}
if (null == vars) {
vars = new Properties();
String home = System.getenv("JRELEASER_USER_HOME");
if (isBlank(home)) {
@@ -113,24 +112,28 @@ public class Environment implements Domain {
}
Path configDirectory = Paths.get(home).resolve(".jreleaser");
loadProperties(context, resolveConfigFileAt(configDirectory)
loadVariables(context, resolveConfigFileAt(configDirectory)
.orElse(configDirectory.resolve("config.properties")));
if (null != variablesSource) {
props.putAll(variablesSource.getVariables());
if (isNotBlank(variables)) {
loadVariables(context, context.getBasedir().resolve(variables.trim()));
}
if (null != propertiesSource) {
properties.putAll(propertiesSource.getProperties());
}
}
}
private void loadProperties(JReleaserContext context, Path file) {
private void loadVariables(JReleaserContext context, Path file) {
propertiesFile = file;
context.getLogger().info("Loading properties from {}", file.toAbsolutePath());
if (Files.exists(file)) {
try {
if (file.getFileName().toString().endsWith(".properties")) {
props.load(new FileInputStream(file.toFile()));
vars.load(new FileInputStream(file.toFile()));
} else {
props.putAll(JReleaserConfigLoader.loadProperties(file));
vars.putAll(JReleaserConfigLoader.loadProperties(file));
}
} catch (IOException e) {
context.getLogger().debug("Could not load properties from {}", file.toAbsolutePath(), e);
@@ -154,58 +157,53 @@ public class Environment implements Domain {
return Optional.empty();
}
public interface VariablesSource {
Map<String, String> getVariables();
public interface PropertiesSource {
Map<String, String> getProperties();
}
public static abstract class AbstractVariablesSource implements VariablesSource {
public static abstract class AbstractPropertiesSource implements PropertiesSource {
@Override
public Map<String, String> getVariables() {
Map<String, String> variables = doGetVariables();
public Map<String, String> getProperties() {
Map<String, String> props = doGetProperties();
Map<String, String> map = new LinkedHashMap<>();
variables.forEach((key, value) -> {
if (key.startsWith("jreleaser.")) {
map.put(key.replace(".", "_").toUpperCase(), value);
}
});
variables.forEach((key, value) -> {
if (key.startsWith("JRELEASER_")) {
map.put(key, value);
}
props.forEach((key, value) -> {
if (key.startsWith("JRELEASER_")) return;
String k = key.replace(".", "-");
k = getPropertyNameForLowerCaseHyphenSeparatedName(k);
map.put(k, value);
});
return map;
}
protected abstract Map<String, String> doGetVariables();
protected abstract Map<String, String> doGetProperties();
}
public static class PropertiesVariablesSource extends AbstractVariablesSource {
public static class PropertiesPropertiesSource extends AbstractPropertiesSource {
private final Properties properties;
public PropertiesVariablesSource(Properties properties) {
public PropertiesPropertiesSource(Properties properties) {
this.properties = properties;
}
@Override
protected Map<String, String> doGetVariables() {
protected Map<String, String> doGetProperties() {
Map<String, String> map = new LinkedHashMap<>();
properties.forEach((k, v) -> map.put(String.valueOf(k), String.valueOf(v)));
return map;
}
}
public static class MapVariablesSource extends AbstractVariablesSource {
public static class MapPropertiesSource extends AbstractPropertiesSource {
private final Map<String, ?> properties;
public MapVariablesSource(Map<String, ?> properties) {
public MapPropertiesSource(Map<String, ?> properties) {
this.properties = properties;
}
@Override
protected Map<String, String> doGetVariables() {
protected Map<String, String> doGetProperties() {
Map<String, String> map = new LinkedHashMap<>();
properties.forEach((k, v) -> map.put(k, String.valueOf(v)));
return map;

View File

@@ -225,7 +225,7 @@ class JReleaserExtensionImpl implements JReleaserExtension {
JReleaserModel toModel(org.gradle.api.Project gradleProject, JReleaserLogger logger) {
if (configFile.present) {
JReleaserModel jreleaser = ContextCreator.resolveModel(logger, configFile.asFile.get().toPath())
jreleaser.environment.variablesSource = new org.jreleaser.model.Environment.MapVariablesSource(project.properties)
jreleaser.environment.propertiesSource = new org.jreleaser.model.Environment.MapPropertiesSource(project.properties)
return jreleaser
}

View File

@@ -49,7 +49,7 @@ class EnvironmentImpl implements Environment {
org.jreleaser.model.Environment toModel(Project project) {
org.jreleaser.model.Environment environment = new org.jreleaser.model.Environment()
environment.variablesSource = new org.jreleaser.model.Environment.MapVariablesSource(project.properties)
environment.propertiesSource = new org.jreleaser.model.Environment.MapPropertiesSource(project.properties)
if (variables.present) environment.variables = variables.asFile.get().absolutePath
if (properties.present) environment.properties.putAll(properties.get())
environment

View File

@@ -44,11 +44,10 @@ public final class JReleaserModelConfigurer {
public static JReleaserModel configure(JReleaserModel model, MavenProject mavenProject, MavenSession session) {
Properties properties = new Properties();
properties.putAll(System.getProperties());
properties.putAll(mavenProject.getModel().getProperties());
Environment.VariablesSource variablesSource = new Environment.PropertiesVariablesSource(properties);
Environment.PropertiesSource propertiesSource = new Environment.PropertiesPropertiesSource(properties);
model.getEnvironment().setVariablesSource(variablesSource);
model.getEnvironment().setPropertiesSource(propertiesSource);
configureProject(model.getProject(), mavenProject, session);
return model;