mirror of
https://github.com/jlengrand/jreleaser.git
synced 2026-03-10 08:31:24 +00:00
Add GH workflow
This commit is contained in:
19
apps/jreleaser-tool-provider/gradle.properties
Normal file
19
apps/jreleaser-tool-provider/gradle.properties
Normal file
@@ -0,0 +1,19 @@
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Copyright 2020 Andres Almiray.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
project_description = JReleaser Tool Provider
|
||||
33
apps/jreleaser-tool-provider/jreleaser-tool-provider.gradle
Normal file
33
apps/jreleaser-tool-provider/jreleaser-tool-provider.gradle
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
dependencies {
|
||||
api project(':jreleaser')
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile) { JavaCompile c ->
|
||||
c.sourceCompatibility = JavaVersion.VERSION_1_9
|
||||
c.targetCompatibility = JavaVersion.VERSION_1_9
|
||||
}
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion = JavaLanguageVersion.of(9)
|
||||
}
|
||||
}
|
||||
|
||||
25
apps/jreleaser-tool-provider/src/main/java/module-info.java
Normal file
25
apps/jreleaser-tool-provider/src/main/java/module-info.java
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
module org.kordamp.jreleaser.tool {
|
||||
exports org.kordamp.jreleaser.tool;
|
||||
requires org.kordamp.jreleaser.app;
|
||||
|
||||
provides java.util.spi.ToolProvider with
|
||||
org.kordamp.jreleaser.tool.JReleaserToolProvider;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.tool;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.spi.ToolProvider;
|
||||
import org.kordamp.jreleaser.app.Main;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class JReleaserToolProvider implements ToolProvider {
|
||||
public String name() {
|
||||
return "jreleaser";
|
||||
}
|
||||
|
||||
public int run(PrintWriter out, PrintWriter err, String... args) {
|
||||
return Main.run(out, err, args);
|
||||
}
|
||||
}
|
||||
19
apps/jreleaser/gradle.properties
Normal file
19
apps/jreleaser/gradle.properties
Normal file
@@ -0,0 +1,19 @@
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Copyright 2020 Andres Almiray.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
project_description = JReleaser
|
||||
52
apps/jreleaser/jreleaser.gradle
Normal file
52
apps/jreleaser/jreleaser.gradle
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
id 'application'
|
||||
}
|
||||
|
||||
config {
|
||||
info {
|
||||
specification { enabled = true }
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api project(':jreleaser-tools')
|
||||
api project(':jreleaser-templates')
|
||||
api project(':jreleaser-config-yaml')
|
||||
api('com.google.guava:guava:30.0-jre') { transitive = false }
|
||||
|
||||
annotationProcessor "info.picocli:picocli-codegen:$picocliVersion"
|
||||
api "info.picocli:picocli:$picocliVersion"
|
||||
api "org.slf4j:slf4j-api:$slf4jVersion"
|
||||
runtimeOnly "org.slf4j:slf4j-simple:$slf4jVersion"
|
||||
}
|
||||
|
||||
mainClassName = 'org.kordamp.jreleaser.app.Main'
|
||||
|
||||
processResources {
|
||||
inputs.property('version', project.version)
|
||||
filesMatching(['**/*.properties']) {
|
||||
expand(
|
||||
'version': project.version,
|
||||
'id': 'jrleaser',
|
||||
'name': 'jrleaser'
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.app;
|
||||
|
||||
import org.kordamp.jreleaser.app.internal.Colorizer;
|
||||
import org.kordamp.jreleaser.app.internal.JReleaserLoggerAdapter;
|
||||
import org.kordamp.jreleaser.util.Logger;
|
||||
import picocli.CommandLine;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
@CommandLine.Command
|
||||
abstract class AbstractCommand implements Callable<Integer> {
|
||||
protected Logger logger;
|
||||
|
||||
@CommandLine.Option(names = {"-d", "--debug"},
|
||||
description = "Set log level to debug.")
|
||||
boolean debug;
|
||||
|
||||
@CommandLine.Option(names = {"-i", "--info"},
|
||||
description = "Set log level to info.")
|
||||
boolean info;
|
||||
|
||||
@CommandLine.Option(names = {"-w", "--warn"},
|
||||
description = "Set log level to warn.")
|
||||
boolean warn;
|
||||
|
||||
@CommandLine.Option(names = {"-q", "--quiet"},
|
||||
description = "Log errors only.")
|
||||
boolean quiet;
|
||||
|
||||
@CommandLine.Option(names = {"--basedir"},
|
||||
description = "Base directory")
|
||||
Path basedir;
|
||||
|
||||
@CommandLine.Spec
|
||||
CommandLine.Model.CommandSpec spec;
|
||||
|
||||
protected abstract Main parent();
|
||||
|
||||
public Integer call() {
|
||||
Banner.display();
|
||||
|
||||
JReleaserLoggerAdapter.Level level = JReleaserLoggerAdapter.Level.WARN;
|
||||
if (debug) {
|
||||
level = JReleaserLoggerAdapter.Level.DEBUG;
|
||||
System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "debug");
|
||||
} else if (info) {
|
||||
level = JReleaserLoggerAdapter.Level.INFO;
|
||||
System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "info");
|
||||
} else if (warn) {
|
||||
level = JReleaserLoggerAdapter.Level.WARN;
|
||||
System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "warn");
|
||||
} else if (quiet) {
|
||||
level = JReleaserLoggerAdapter.Level.ERROR;
|
||||
System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "error");
|
||||
}
|
||||
|
||||
logger = new JReleaserLoggerAdapter(parent().out, level);
|
||||
|
||||
try {
|
||||
execute();
|
||||
} catch (HaltExecutionException e) {
|
||||
return 1;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace(new Colorizer(parent().out));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected abstract void execute();
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.app;
|
||||
|
||||
import org.kordamp.jreleaser.app.internal.JReleaserLoggerAdapter;
|
||||
import org.kordamp.jreleaser.config.JReleaserConfigLoader;
|
||||
import org.kordamp.jreleaser.model.JReleaserModel;
|
||||
import org.kordamp.jreleaser.model.JReleaserModelValidator;
|
||||
import org.kordamp.jreleaser.util.Logger;
|
||||
import picocli.CommandLine;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
@CommandLine.Command
|
||||
public abstract class AbstractModelCommand extends AbstractCommand {
|
||||
@CommandLine.Option(names = {"--config-file"},
|
||||
description = "The config file")
|
||||
Path configFile;
|
||||
|
||||
@CommandLine.ParentCommand
|
||||
Main parent;
|
||||
|
||||
Path actualConfigFile;
|
||||
Path actualBasedir;
|
||||
|
||||
@Override
|
||||
protected Main parent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
protected void execute() {
|
||||
resolveConfigFile();
|
||||
resolveBasedir();
|
||||
consumeModel(resolveModel());
|
||||
}
|
||||
|
||||
protected void resolveConfigFile() {
|
||||
actualConfigFile = null != configFile ? configFile : Paths.get(".").normalize().resolve(".jreleaser.yml");
|
||||
if (!Files.exists(actualConfigFile)) {
|
||||
spec.commandLine().getErr()
|
||||
.println(spec.commandLine().getColorScheme().errorText("Missing required option: '--config-file=<configFile>'"));
|
||||
spec.commandLine().usage(parent.out);
|
||||
throw new HaltExecutionException();
|
||||
}
|
||||
}
|
||||
|
||||
private void resolveBasedir() {
|
||||
actualBasedir = null != basedir ? basedir : actualConfigFile.toAbsolutePath().getParent();
|
||||
if (!Files.exists(actualBasedir)) {
|
||||
spec.commandLine().getErr()
|
||||
.println(spec.commandLine().getColorScheme().errorText("Missing required option: '--basedir=<basedir>'"));
|
||||
spec.commandLine().usage(parent.out);
|
||||
throw new HaltExecutionException();
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void consumeModel(JReleaserModel jreleaserModel);
|
||||
|
||||
private JReleaserModel resolveModel() {
|
||||
try {
|
||||
JReleaserModel jreleaserModel = JReleaserConfigLoader.loadConfig(actualConfigFile);
|
||||
List<String> errors = JReleaserModelValidator.validate(logger, actualBasedir, jreleaserModel);
|
||||
if (!errors.isEmpty()) {
|
||||
Logger logger = new JReleaserLoggerAdapter(parent.out);
|
||||
logger.error("== JReleaser ==");
|
||||
errors.forEach(logger::error);
|
||||
throw new JReleaserException("JReleaser with " + actualConfigFile.toAbsolutePath() + " has not been properly configured.");
|
||||
}
|
||||
|
||||
return jreleaserModel;
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new JReleaserException("Unexpected error when parsing configuration from " + actualConfigFile.toAbsolutePath(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.app;
|
||||
|
||||
import org.kordamp.jreleaser.model.Distribution;
|
||||
import org.kordamp.jreleaser.model.JReleaserModel;
|
||||
import org.kordamp.jreleaser.tools.DistributionProcessor;
|
||||
import org.kordamp.jreleaser.tools.ToolProcessingException;
|
||||
import picocli.CommandLine;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
@CommandLine.Command
|
||||
public abstract class AbstractProcessorCommand extends AbstractModelCommand {
|
||||
@CommandLine.Option(names = {"--fail-fast"},
|
||||
description = "Fail fast")
|
||||
boolean failFast = true;
|
||||
|
||||
Path outputDirectory;
|
||||
|
||||
@Override
|
||||
protected void consumeModel(JReleaserModel jreleaserModel) {
|
||||
outputDirectory = actualBasedir.resolve("out");
|
||||
|
||||
Path checksumDirectory = computeChecksums(jreleaserModel, outputDirectory);
|
||||
|
||||
List<ToolProcessingException> exceptions = new ArrayList<>();
|
||||
for (Distribution distribution : jreleaserModel.getDistributions().values()) {
|
||||
for (String toolName : Distribution.supportedTools()) {
|
||||
try {
|
||||
DistributionProcessor processor = createDistributionProcessor(jreleaserModel,
|
||||
checksumDirectory,
|
||||
outputDirectory,
|
||||
distribution,
|
||||
toolName);
|
||||
|
||||
consumeProcessor(processor);
|
||||
} catch (ToolProcessingException e) {
|
||||
if (failFast) throw new IllegalStateException("Unexpected error", e);
|
||||
exceptions.add(e);
|
||||
logger.warn("Unexpected error", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!exceptions.isEmpty()) {
|
||||
throw new IllegalStateException("There were " + exceptions.size() + " failure(s)");
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void consumeProcessor(DistributionProcessor processor) throws ToolProcessingException;
|
||||
|
||||
private DistributionProcessor createDistributionProcessor(JReleaserModel jreleaserModel,
|
||||
Path checksumDirectory,
|
||||
Path outputDirectory,
|
||||
Distribution distribution,
|
||||
String toolName) {
|
||||
return DistributionProcessor.builder()
|
||||
.logger(logger)
|
||||
.model(jreleaserModel)
|
||||
.distributionName(distribution.getName())
|
||||
.toolName(toolName)
|
||||
.checksumDirectory(checksumDirectory)
|
||||
.outputDirectory(outputDirectory
|
||||
.resolve("jreleaser")
|
||||
.resolve(distribution.getName())
|
||||
.resolve(toolName))
|
||||
.build();
|
||||
}
|
||||
|
||||
protected Path computeChecksums(JReleaserModel jreleaserModel, Path outputDirectory) {
|
||||
return outputDirectory.resolve("jreleaser")
|
||||
.resolve("checksums");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.app;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Scanner;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
final class Banner {
|
||||
private static final Banner b = new Banner();
|
||||
private final ResourceBundle bundle = ResourceBundle.getBundle(Banner.class.getName());
|
||||
private final String productVersion = bundle.getString("product.version");
|
||||
private final String productId = bundle.getString("product.id");
|
||||
private final String productName = bundle.getString("product.name");
|
||||
private final String banner = MessageFormat.format(bundle.getString("product.banner"), productName, productVersion);
|
||||
|
||||
private Banner() {
|
||||
// nooop
|
||||
}
|
||||
|
||||
public static void display() {
|
||||
try {
|
||||
File parent = new File(System.getProperty("user.home"), "/.jreleaser/caches");
|
||||
File markerFile = getMarkerFile(parent, b);
|
||||
if (!markerFile.exists()) {
|
||||
System.out.println(b.banner);
|
||||
markerFile.getParentFile().mkdirs();
|
||||
PrintStream out = new PrintStream(new FileOutputStream(markerFile));
|
||||
out.println("1");
|
||||
out.close();
|
||||
writeQuietly(markerFile, "1");
|
||||
} else {
|
||||
try {
|
||||
int count = Integer.parseInt(readQuietly(markerFile));
|
||||
if (count < 3) {
|
||||
System.out.println(b.banner);
|
||||
}
|
||||
writeQuietly(markerFile, (count + 1) + "");
|
||||
} catch (NumberFormatException e) {
|
||||
writeQuietly(markerFile, "1");
|
||||
System.out.println(b.banner);
|
||||
}
|
||||
}
|
||||
} catch (IOException ignored) {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeQuietly(File file, String text) {
|
||||
try {
|
||||
PrintStream out = new PrintStream(new FileOutputStream(file));
|
||||
out.println(text);
|
||||
out.close();
|
||||
} catch (IOException ignored) {
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
private static String readQuietly(File file) {
|
||||
try {
|
||||
Scanner in = new Scanner(new FileInputStream(file));
|
||||
return in.next();
|
||||
} catch (Exception ignored) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private static File getMarkerFile(File parent, Banner b) {
|
||||
return new File(parent,
|
||||
"kordamp" +
|
||||
File.separator +
|
||||
b.productId +
|
||||
File.separator +
|
||||
b.productVersion +
|
||||
File.separator +
|
||||
"marker.txt");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.app;
|
||||
|
||||
import org.kordamp.jreleaser.app.internal.JReleaserModelPrinter;
|
||||
import org.kordamp.jreleaser.model.JReleaserModel;
|
||||
import picocli.CommandLine;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
@CommandLine.Command(name = "config",
|
||||
description = "Displays current configuration")
|
||||
public class Config extends AbstractModelCommand {
|
||||
@Override
|
||||
protected void consumeModel(JReleaserModel jreleaserModel) {
|
||||
new JReleaserModelPrinter(parent.out).print(jreleaserModel.asMap());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.app;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class HaltExecutionException extends RuntimeException {
|
||||
public HaltExecutionException() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.app;
|
||||
|
||||
import org.kordamp.jreleaser.templates.TemplateUtils;
|
||||
import picocli.CommandLine;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
import java.nio.file.FileAlreadyExistsException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Scanner;
|
||||
|
||||
import static java.nio.file.StandardOpenOption.CREATE;
|
||||
import static java.nio.file.StandardOpenOption.CREATE_NEW;
|
||||
import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
|
||||
import static java.nio.file.StandardOpenOption.WRITE;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
@CommandLine.Command(name = "init",
|
||||
description = "Creates a jrelaser config file")
|
||||
public class Init extends AbstractCommand {
|
||||
@CommandLine.Option(names = {"--overwrite"},
|
||||
description = "Overwrite existing files")
|
||||
boolean overwrite;
|
||||
|
||||
@CommandLine.ParentCommand
|
||||
Main parent;
|
||||
|
||||
@Override
|
||||
protected Main parent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
protected void execute() {
|
||||
try {
|
||||
Path outputDirectory = null != basedir ? basedir : Paths.get(".").normalize();
|
||||
Path outputFile = outputDirectory.resolve(".jreleaser.yml");
|
||||
|
||||
Reader template = TemplateUtils.resolveTemplate(logger, Init.class,
|
||||
"META-INF/jreleaser/templates/jreleaser.yml.tpl");
|
||||
|
||||
logger.info("Writing file " + outputFile.toAbsolutePath());
|
||||
try (Writer writer = Files.newBufferedWriter(outputFile, (overwrite ? CREATE : CREATE_NEW), WRITE, TRUNCATE_EXISTING);
|
||||
Scanner scanner = new Scanner(template)) {
|
||||
while (scanner.hasNextLine()) {
|
||||
writer.write(scanner.nextLine() + System.lineSeparator());
|
||||
}
|
||||
} catch (FileAlreadyExistsException e) {
|
||||
logger.error("File {} already exists and overwrite was set to false.", outputFile.toAbsolutePath());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!quiet) {
|
||||
parent.out.println("JReleaser initialized at " + outputDirectory.toAbsolutePath());
|
||||
}
|
||||
} catch (IllegalStateException | IOException e) {
|
||||
throw new JReleaserException("Unexpected error", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.app;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class JReleaserException extends RuntimeException {
|
||||
public JReleaserException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public JReleaserException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public JReleaserException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.app;
|
||||
|
||||
import picocli.CommandLine;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
@CommandLine.Command(name = "jreleaser",
|
||||
description = "jreleaser",
|
||||
mixinStandardHelpOptions = true,
|
||||
versionProvider = Versions.class,
|
||||
subcommands = {Init.class, Config.class, Template.class, Prepare.class, Package.class})
|
||||
public class Main implements Runnable {
|
||||
PrintWriter out;
|
||||
PrintWriter err;
|
||||
|
||||
@CommandLine.Spec
|
||||
CommandLine.Model.CommandSpec spec;
|
||||
|
||||
public void run() {
|
||||
Banner.display();
|
||||
|
||||
spec.commandLine().usage(out);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.exit(run(args));
|
||||
}
|
||||
|
||||
public static int run(String... args) {
|
||||
Main cmd = new Main();
|
||||
CommandLine commandLine = new CommandLine(cmd);
|
||||
cmd.out = commandLine.getOut();
|
||||
cmd.err = commandLine.getErr();
|
||||
return commandLine.execute(args);
|
||||
}
|
||||
|
||||
public static int run(PrintWriter out, PrintWriter err, String... args) {
|
||||
Main cmd = new Main();
|
||||
cmd.out = out;
|
||||
cmd.err = err;
|
||||
return new CommandLine(cmd).execute(args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.app;
|
||||
|
||||
import org.kordamp.jreleaser.tools.DistributionProcessor;
|
||||
import org.kordamp.jreleaser.tools.ToolProcessingException;
|
||||
import picocli.CommandLine;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
@CommandLine.Command(name = "package",
|
||||
description = "Packages all distributions")
|
||||
public class Package extends AbstractProcessorCommand {
|
||||
@Override
|
||||
protected void consumeProcessor(DistributionProcessor processor) throws ToolProcessingException {
|
||||
if (processor.packageDistribution() && !quiet) {
|
||||
parent.out.println("Packaged " + processor.getDistributionName() +
|
||||
" distribution with tool " + processor.getToolName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.app;
|
||||
|
||||
import com.google.common.hash.HashCode;
|
||||
import com.google.common.hash.Hashing;
|
||||
import com.google.common.io.Files;
|
||||
import org.kordamp.jreleaser.model.Artifact;
|
||||
import org.kordamp.jreleaser.model.Distribution;
|
||||
import org.kordamp.jreleaser.model.JReleaserModel;
|
||||
import org.kordamp.jreleaser.tools.DistributionProcessor;
|
||||
import org.kordamp.jreleaser.tools.ToolProcessingException;
|
||||
import picocli.CommandLine;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
@CommandLine.Command(name = "prepare",
|
||||
description = "Prepares all distributions")
|
||||
public class Prepare extends AbstractProcessorCommand {
|
||||
@Override
|
||||
protected void consumeProcessor(DistributionProcessor processor) throws ToolProcessingException {
|
||||
if (processor.prepareDistribution()) {
|
||||
parent.out.println("Prepared " + processor.getDistributionName() +
|
||||
" distribution with tool " + processor.getToolName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Path computeChecksums(JReleaserModel jreleaserModel, Path outputDirectory) {
|
||||
Path checksumDirectory = super.computeChecksums(jreleaserModel, outputDirectory);
|
||||
|
||||
try {
|
||||
java.nio.file.Files.createDirectories(checksumDirectory);
|
||||
} catch (IOException e) {
|
||||
throw new JReleaserException("Unexpected error creating checksum directory.", e);
|
||||
}
|
||||
|
||||
jreleaserModel.getDistributions().values()
|
||||
.stream().flatMap((Function<Distribution, Stream<Artifact>>) distribution -> distribution.getArtifacts()
|
||||
.stream()).forEach(artifact -> {
|
||||
Path inputFile = Paths.get(artifact.getPath()).toAbsolutePath();
|
||||
String fileName = inputFile.getFileName().toString();
|
||||
Path checksumFilePath = checksumDirectory.resolve(fileName + ".sha256");
|
||||
try {
|
||||
HashCode hashCode = Files.asByteSource(inputFile.toFile()).hash(Hashing.sha256());
|
||||
Files.write(hashCode.toString().getBytes(), checksumFilePath.toFile());
|
||||
} catch (IOException e) {
|
||||
throw new JReleaserException("Unexpected error creating checksum for " + inputFile, e);
|
||||
}
|
||||
});
|
||||
|
||||
return checksumDirectory;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.app;
|
||||
|
||||
import org.kordamp.jreleaser.model.Distribution;
|
||||
import org.kordamp.jreleaser.templates.TemplateGenerationException;
|
||||
import org.kordamp.jreleaser.templates.TemplateGenerator;
|
||||
import picocli.CommandLine;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
@CommandLine.Command(name = "template",
|
||||
description = "Generates a tool template")
|
||||
public class Template extends AbstractCommand {
|
||||
@CommandLine.Option(names = {"--distribution-name"},
|
||||
description = "The name of the distribution",
|
||||
required = true)
|
||||
String distributionName;
|
||||
|
||||
@CommandLine.Option(names = {"--tool-name"},
|
||||
description = "The name of the tool",
|
||||
required = true)
|
||||
String toolName;
|
||||
|
||||
@CommandLine.Option(names = {"--distribution-type"},
|
||||
description = "The type of the distribution",
|
||||
required = true,
|
||||
defaultValue = "BINARY")
|
||||
Distribution.DistributionType distributionType;
|
||||
|
||||
@CommandLine.Option(names = {"--overwrite"},
|
||||
description = "Overwrite existing files")
|
||||
boolean overwrite;
|
||||
|
||||
@CommandLine.ParentCommand
|
||||
Main parent;
|
||||
|
||||
@Override
|
||||
protected Main parent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
protected void execute() {
|
||||
try {
|
||||
if (null == basedir) {
|
||||
spec.commandLine().getErr()
|
||||
.println(spec.commandLine().getColorScheme().errorText("Missing required option: '--basedir=<basedir>'"));
|
||||
spec.commandLine().usage(parent.out);
|
||||
throw new HaltExecutionException();
|
||||
}
|
||||
|
||||
Path outputDirectory = basedir
|
||||
.resolve("src")
|
||||
.resolve("distributions");
|
||||
|
||||
boolean result = TemplateGenerator.builder()
|
||||
.logger(logger)
|
||||
.distributionName(distributionName)
|
||||
.distributionType(distributionType)
|
||||
.toolName(toolName)
|
||||
.outputDirectory(outputDirectory)
|
||||
.overwrite(overwrite)
|
||||
.build()
|
||||
.generate();
|
||||
|
||||
if (result && !quiet) {
|
||||
parent.out.println("Template generated at " +
|
||||
outputDirectory.resolve(distributionName).resolve(toolName)
|
||||
.normalize().toAbsolutePath());
|
||||
}
|
||||
} catch (TemplateGenerationException e) {
|
||||
throw new JReleaserException("Unexpected error", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.app;
|
||||
|
||||
import picocli.CommandLine;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.net.URL;
|
||||
import java.util.Enumeration;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.Manifest;
|
||||
|
||||
import static org.kordamp.jreleaser.util.StringUtils.isNotBlank;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class Versions implements CommandLine.IVersionProvider {
|
||||
private static final ResourceBundle bundle = ResourceBundle.getBundle(Versions.class.getName());
|
||||
private static final String JRELEASER_VERSION = bundle.getString("jreleaser_version");
|
||||
|
||||
@Override
|
||||
public String[] getVersion() throws Exception {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
banner(new PrintStream(baos));
|
||||
return baos.toString().split("\n");
|
||||
}
|
||||
|
||||
public static void banner(PrintStream out) {
|
||||
Manifest manifest = findMyManifest();
|
||||
if (null != manifest) {
|
||||
String version = manifest.getMainAttributes().getValue(Attributes.Name.SPECIFICATION_VERSION);
|
||||
String buildDate = manifest.getMainAttributes().getValue("Build-Date");
|
||||
String buildTime = manifest.getMainAttributes().getValue("Build-Time");
|
||||
String buildRevision = manifest.getMainAttributes().getValue("Build-Revision");
|
||||
boolean additionalInfo = isNotBlank(buildDate) || isNotBlank(buildTime) || isNotBlank(buildRevision);
|
||||
|
||||
out.println("------------------------------------------------------------");
|
||||
out.println("jreleaser " + version);
|
||||
out.println("------------------------------------------------------------");
|
||||
if (additionalInfo) {
|
||||
if (isNotBlank(buildDate) && isNotBlank(buildTime)) {
|
||||
out.println("Build time: " + buildDate + " " + buildTime);
|
||||
}
|
||||
if (isNotBlank(buildRevision)) out.println("Revision: " + buildRevision);
|
||||
out.println("------------------------------------------------------------");
|
||||
}
|
||||
} else {
|
||||
out.println("jreleaser " + JRELEASER_VERSION);
|
||||
}
|
||||
}
|
||||
|
||||
private static Manifest findMyManifest() {
|
||||
try {
|
||||
Enumeration<URL> urls = Versions.class.getClassLoader().getResources("META-INF/MANIFEST.MF");
|
||||
while (urls.hasMoreElements()) {
|
||||
URL url = urls.nextElement();
|
||||
Manifest manifest = new Manifest(url.openStream());
|
||||
if (manifest.getMainAttributes().containsKey(Attributes.Name.SPECIFICATION_TITLE)) {
|
||||
String specificationTitle = manifest.getMainAttributes().getValue(Attributes.Name.SPECIFICATION_TITLE);
|
||||
if ("jreleaser".equals(specificationTitle)) {
|
||||
return manifest;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// well, this sucks
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.app.internal;
|
||||
|
||||
import picocli.CommandLine;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class Colorizer extends PrintWriter {
|
||||
public Colorizer(PrintWriter delegate) {
|
||||
super(delegate, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void print(String s) {
|
||||
super.print(CommandLine.Help.Ansi.AUTO.text("@|red " + s + "|@"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.app.internal;
|
||||
|
||||
import org.kordamp.jreleaser.util.Logger;
|
||||
import org.slf4j.helpers.MessageFormatter;
|
||||
import picocli.CommandLine;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class JReleaserLoggerAdapter implements Logger {
|
||||
private final PrintWriter out;
|
||||
private final Level level;
|
||||
|
||||
public JReleaserLoggerAdapter(PrintWriter out) {
|
||||
this(out, Level.WARN);
|
||||
}
|
||||
|
||||
public JReleaserLoggerAdapter(PrintWriter out, Level level) {
|
||||
this.out = out;
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(String message) {
|
||||
if (isLevelEnabled(Level.DEBUG)) {
|
||||
out.println(Level.DEBUG + message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(String message) {
|
||||
if (isLevelEnabled(Level.INFO)) {
|
||||
out.println(Level.INFO + message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String message) {
|
||||
if (isLevelEnabled(Level.WARN)) {
|
||||
out.println(Level.WARN + message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(String message) {
|
||||
if (isLevelEnabled(Level.ERROR)) {
|
||||
out.println(Level.ERROR + message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(String message, Object... args) {
|
||||
if (isLevelEnabled(Level.DEBUG)) {
|
||||
out.println(Level.DEBUG + MessageFormatter.arrayFormat(message, args).getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(String message, Object... args) {
|
||||
if (isLevelEnabled(Level.INFO)) {
|
||||
out.println(Level.INFO + MessageFormatter.arrayFormat(message, args).getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String message, Object... args) {
|
||||
if (isLevelEnabled(Level.WARN)) {
|
||||
out.println(Level.WARN + MessageFormatter.arrayFormat(message, args).getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(String message, Object... args) {
|
||||
if (isLevelEnabled(Level.ERROR)) {
|
||||
out.println(Level.ERROR + MessageFormatter.arrayFormat(message, args).getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(String message, Throwable throwable) {
|
||||
if (isLevelEnabled(Level.DEBUG)) {
|
||||
out.println(Level.DEBUG + message);
|
||||
printThrowable(throwable);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(String message, Throwable throwable) {
|
||||
if (isLevelEnabled(Level.INFO)) {
|
||||
out.println(Level.INFO + message);
|
||||
printThrowable(throwable);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String message, Throwable throwable) {
|
||||
if (isLevelEnabled(Level.WARN)) {
|
||||
out.println(Level.WARN + message);
|
||||
printThrowable(throwable);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(String message, Throwable throwable) {
|
||||
if (isLevelEnabled(Level.ERROR)) {
|
||||
out.println(Level.ERROR + message);
|
||||
printThrowable(throwable);
|
||||
}
|
||||
}
|
||||
|
||||
private void printThrowable(Throwable throwable) {
|
||||
if (null != throwable) {
|
||||
throwable.printStackTrace(new Colorizer(out));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isLevelEnabled(Level requested) {
|
||||
return requested.ordinal() >= level.ordinal();
|
||||
}
|
||||
|
||||
public enum Level {
|
||||
DEBUG("cyan"),
|
||||
INFO("blue"),
|
||||
WARN("yellow"),
|
||||
ERROR("red");
|
||||
|
||||
private final String color;
|
||||
|
||||
Level(String color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[" + colorize(name()) + "] ";
|
||||
}
|
||||
|
||||
private String colorize(String input) {
|
||||
return CommandLine.Help.Ansi.AUTO.string("@|" + color + " " + input + "|@");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.app.internal;
|
||||
|
||||
import picocli.CommandLine;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class JReleaserModelPrinter extends org.kordamp.jreleaser.model.JReleaserModelPrinter {
|
||||
public JReleaserModelPrinter(PrintWriter out) {
|
||||
super(out);
|
||||
}
|
||||
|
||||
public JReleaserModelPrinter(PrintWriter out, boolean showSecrets) {
|
||||
super(out, showSecrets);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String color(String color, String input) {
|
||||
return CommandLine.Help.Ansi.AUTO.string("@|" + color + " " + input + "|@");
|
||||
}
|
||||
}
|
||||
31
apps/jreleaser/src/main/module/module-info.java
Normal file
31
apps/jreleaser/src/main/module/module-info.java
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
module org.kordamp.jreleaser.app {
|
||||
exports org.kordamp.jreleaser.app;
|
||||
requires org.kordamp.jreleaser.util;
|
||||
requires org.kordamp.jreleaser.model;
|
||||
requires org.kordamp.jreleaser.config;
|
||||
requires org.kordamp.jreleaser.tools;
|
||||
requires org.kordamp.jreleaser.templates;
|
||||
requires info.picocli;
|
||||
requires org.slf4j;
|
||||
requires org.slf4j.simple;
|
||||
|
||||
opens org.kordamp.jreleaser.app to info.picocli;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
project:
|
||||
name: awesomeApp
|
||||
version: 0.0.0-SNAPSHOT
|
||||
description: Awesome App
|
||||
longDescription: Awesome App
|
||||
website: https://acme.com/awesomeapp
|
||||
authors:
|
||||
- Joe Cool
|
||||
license: Apache-2
|
||||
javaVersion: 8
|
||||
|
||||
release:
|
||||
repoType: GITHUB
|
||||
repoOwner: acme
|
||||
|
||||
distributions:
|
||||
awesomeApp:
|
||||
artifacts:
|
||||
- path: /path/to/app/awesomeApp-0.0.0-SNAPSHOT.zip
|
||||
@@ -0,0 +1,22 @@
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Copyright 2020 Andres Almiray.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
product.version=$version
|
||||
product.id=$id
|
||||
product.name=$name
|
||||
product.banner={0} {1}. Consider becoming a patron at https://www.patreon.com/aalmiray
|
||||
@@ -0,0 +1,19 @@
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Copyright 2020 Andres Almiray.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
jreleaser_version = ${version}
|
||||
105
build.gradle
Normal file
105
build.gradle
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
config {
|
||||
info {
|
||||
description = 'jreleaser'
|
||||
inceptionYear = '2020'
|
||||
tags = ['release']
|
||||
|
||||
specification {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
implementation {
|
||||
enabled = true
|
||||
}
|
||||
}
|
||||
|
||||
docs {
|
||||
javadoc {
|
||||
autoLinks {
|
||||
enabled = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bintray {
|
||||
enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
jcenter()
|
||||
mavenLocal()
|
||||
}
|
||||
|
||||
tasks.withType(GenerateModuleMetadata) {
|
||||
enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
subprojects {
|
||||
if (project.name != 'guide') {
|
||||
config {
|
||||
info {
|
||||
description = project.project_description
|
||||
}
|
||||
|
||||
bintray {
|
||||
enabled = true
|
||||
name = project.name
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile) { JavaCompile c ->
|
||||
c.sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
c.targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
tasks.withType(GroovyCompile) { GroovyCompile c ->
|
||||
c.sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
c.targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
if (project.projectDir.parentFile.name != 'plugins' &&
|
||||
project.name != 'jreleaser-tool-provider') {
|
||||
jar {
|
||||
multiRelease = true
|
||||
moduleInfoPath = 'src/main/module/module-info.java'
|
||||
}
|
||||
}
|
||||
|
||||
license {
|
||||
exclude('build/**')
|
||||
exclude('**/*.tpl')
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation "org.junit.jupiter:junit-jupiter:$junitVersion"
|
||||
testImplementation "org.hamcrest:hamcrest-library:$hamcrestVersion"
|
||||
|
||||
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junitVersion"
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
}
|
||||
}
|
||||
19
core/jreleaser-config-yaml/gradle.properties
Normal file
19
core/jreleaser-config-yaml/gradle.properties
Normal file
@@ -0,0 +1,19 @@
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Copyright 2020 Andres Almiray.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
project_description = JReleaser YAML config support
|
||||
25
core/jreleaser-config-yaml/jreleaser-config-yaml.gradle
Normal file
25
core/jreleaser-config-yaml/jreleaser-config-yaml.gradle
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
dependencies {
|
||||
api project(':jreleaser-config')
|
||||
api "org.yaml:snakeyaml:$snakeYamlVersion"
|
||||
|
||||
compileOnly "org.kordamp.jipsy:jipsy:${jipsyVersion}"
|
||||
annotationProcessor "org.kordamp.jipsy:jipsy:${jipsyVersion}"
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.config.yaml;
|
||||
|
||||
import org.kordamp.jipsy.ServiceProviderFor;
|
||||
import org.kordamp.jreleaser.config.JReleaserConfigParser;
|
||||
import org.kordamp.jreleaser.model.Artifact;
|
||||
import org.kordamp.jreleaser.model.JReleaserModel;
|
||||
import org.kordamp.jreleaser.model.Plug;
|
||||
import org.kordamp.jreleaser.model.Slot;
|
||||
import org.yaml.snakeyaml.TypeDescription;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.constructor.Constructor;
|
||||
import org.yaml.snakeyaml.introspector.Property;
|
||||
import org.yaml.snakeyaml.introspector.PropertyUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
@ServiceProviderFor(JReleaserConfigParser.class)
|
||||
public class YamlJReleaserConfigParser implements JReleaserConfigParser {
|
||||
@Override
|
||||
public boolean supports(Path configFile) {
|
||||
String fileName = configFile.getFileName().toString();
|
||||
return fileName.endsWith(".yml") || fileName.endsWith(".yaml");
|
||||
}
|
||||
|
||||
@Override
|
||||
public JReleaserModel parse(InputStream inputStream) throws IOException {
|
||||
Constructor c = new Constructor(JReleaserModel.class);
|
||||
TypeDescription td = new TypeDescription(JReleaserModel.class);
|
||||
td.addPropertyParameters("artifacts", Artifact.class);
|
||||
td.addPropertyParameters("plugs", Plug.class);
|
||||
td.addPropertyParameters("slots", Slot.class);
|
||||
c.addTypeDescription(td);
|
||||
|
||||
c.setPropertyUtils(new PropertyUtils() {
|
||||
@Override
|
||||
public Property getProperty(Class<? extends Object> type, String name) {
|
||||
if (name.equals("class")) {
|
||||
name = "clazz";
|
||||
}
|
||||
return super.getProperty(type, name);
|
||||
}
|
||||
});
|
||||
|
||||
Yaml yaml = new Yaml(c);
|
||||
|
||||
return yaml.load(inputStream);
|
||||
}
|
||||
}
|
||||
29
core/jreleaser-config-yaml/src/main/module/module-info.java
Normal file
29
core/jreleaser-config-yaml/src/main/module/module-info.java
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
module org.kordamp.jreleaser.config.yaml {
|
||||
exports org.kordamp.jreleaser.config.yaml;
|
||||
requires org.kordamp.jreleaser.config;
|
||||
requires org.kordamp.jreleaser.model;
|
||||
requires org.yaml.snakeyaml;
|
||||
requires static org.kordamp.jipsy;
|
||||
requires static org.kordamp.jipsy.annotations;
|
||||
|
||||
provides org.kordamp.jreleaser.config.JReleaserConfigParser
|
||||
with org.kordamp.jreleaser.config.yaml.YamlJReleaserConfigParser;
|
||||
}
|
||||
19
core/jreleaser-config/gradle.properties
Normal file
19
core/jreleaser-config/gradle.properties
Normal file
@@ -0,0 +1,19 @@
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Copyright 2020 Andres Almiray.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
project_description = JReleaser config support
|
||||
21
core/jreleaser-config/jreleaser-config.gradle
Normal file
21
core/jreleaser-config/jreleaser-config.gradle
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
dependencies {
|
||||
api project(':jreleaser-model')
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.config;
|
||||
|
||||
import org.kordamp.jreleaser.model.JReleaserModel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class JReleaserConfigLoader {
|
||||
public static JReleaserModel loadConfig(Path configFile) {
|
||||
ServiceLoader<JReleaserConfigParser> parsers = ServiceLoader.load(JReleaserConfigParser.class, JReleaserConfigParser.class.getClassLoader());
|
||||
|
||||
for (JReleaserConfigParser parser : parsers) {
|
||||
if (parser.supports(configFile)) {
|
||||
try (InputStream inputStream = configFile.toUri().toURL().openStream()) {
|
||||
return parser.parse(inputStream);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalArgumentException("Unexpected error parsing config file. " + configFile, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Unsupported config format. " + configFile);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.config;
|
||||
|
||||
import org.kordamp.jreleaser.model.JReleaserModel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
* Allows external configuration to be parsed with a custom format.
|
||||
*
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public interface JReleaserConfigParser {
|
||||
/**
|
||||
* Whether the given config file format is supported or not.</p>
|
||||
* Implementors would typically look at the file extension.
|
||||
*
|
||||
* @param configFile the configuration file to inspect
|
||||
* @return {@code true} if the given format is supported, {@code false} otherwise.
|
||||
*/
|
||||
boolean supports(Path configFile);
|
||||
|
||||
/**
|
||||
* Reads and parses external configuration into a {@code JReleaserModel} instance.
|
||||
*
|
||||
* @param inputStream the configuration's input source
|
||||
* @return a configured {@code JReleaserModel} instance, should never return {@code null}.
|
||||
* @throws IOException if an error occurs while reading from the {@code InputStream}.
|
||||
*/
|
||||
JReleaserModel parse(InputStream inputStream) throws IOException;
|
||||
}
|
||||
24
core/jreleaser-config/src/main/module/module-info.java
Normal file
24
core/jreleaser-config/src/main/module/module-info.java
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
module org.kordamp.jreleaser.config {
|
||||
exports org.kordamp.jreleaser.config;
|
||||
requires org.kordamp.jreleaser.model;
|
||||
|
||||
uses org.kordamp.jreleaser.config.JReleaserConfigParser;
|
||||
}
|
||||
19
core/jreleaser-model/gradle.properties
Normal file
19
core/jreleaser-model/gradle.properties
Normal file
@@ -0,0 +1,19 @@
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Copyright 2020 Andres Almiray.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
project_description = JReleaser Model
|
||||
21
core/jreleaser-model/jreleaser-model.gradle
Normal file
21
core/jreleaser-model/jreleaser-model.gradle
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
dependencies {
|
||||
api project(':jreleaser-utils')
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
abstract class AbstractDomain implements Serializable {
|
||||
public abstract Map<String, Object> asMap();
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.model;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
abstract class AbstractTool extends AbstractDomain implements Tool {
|
||||
protected final String toolName;
|
||||
protected final Map<String, Object> extraProperties = new LinkedHashMap<>();
|
||||
protected Boolean enabled;
|
||||
protected boolean enabledSet;
|
||||
protected Path templateDirectory;
|
||||
|
||||
protected AbstractTool(String toolName) {
|
||||
this.toolName = toolName;
|
||||
}
|
||||
|
||||
void setAll(AbstractTool tool) {
|
||||
this.enabled = tool.enabled;
|
||||
this.enabledSet = tool.enabledSet;
|
||||
this.templateDirectory = tool.templateDirectory;
|
||||
setExtraProperties(tool.extraProperties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isEnabled() {
|
||||
return enabled != null && enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(Boolean enabled) {
|
||||
this.enabledSet = true;
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabledSet() {
|
||||
return enabledSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getToolName() {
|
||||
return toolName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getTemplateDirectory() {
|
||||
return templateDirectory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTemplateDirectory(Path templateDirectory) {
|
||||
this.templateDirectory = templateDirectory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getExtraProperties() {
|
||||
return extraProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExtraProperties(Map<String, Object> extraProperties) {
|
||||
this.extraProperties.clear();
|
||||
this.extraProperties.putAll(extraProperties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addExtraProperties(Map<String, Object> extraProperties) {
|
||||
this.extraProperties.putAll(extraProperties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Map<String, Object> asMap() {
|
||||
if (!isEnabled()) return Collections.emptyMap();
|
||||
|
||||
Map<String, Object> props = new LinkedHashMap<>();
|
||||
props.put("enabled", isEnabled());
|
||||
props.put("templateDirectory", templateDirectory);
|
||||
asMap(props);
|
||||
props.put("extraProperties", extraProperties);
|
||||
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
map.put(getToolName(), props);
|
||||
return map;
|
||||
}
|
||||
|
||||
protected abstract void asMap(Map<String, Object> props);
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.model;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class Artifact extends AbstractDomain {
|
||||
private String path;
|
||||
private String hash;
|
||||
private String osClassifier;
|
||||
private String javaVersion;
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public String getHash() {
|
||||
return hash;
|
||||
}
|
||||
|
||||
public void setHash(String hash) {
|
||||
this.hash = hash;
|
||||
}
|
||||
|
||||
public String getOsClassifier() {
|
||||
return osClassifier;
|
||||
}
|
||||
|
||||
public void setOsClassifier(String osClassifier) {
|
||||
this.osClassifier = osClassifier;
|
||||
}
|
||||
|
||||
public String getJavaVersion() {
|
||||
return javaVersion;
|
||||
}
|
||||
|
||||
public void setJavaVersion(String javaVersion) {
|
||||
this.javaVersion = javaVersion;
|
||||
}
|
||||
|
||||
public Map<String, Object> asMap() {
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
map.put("path", path);
|
||||
map.put("hash", hash);
|
||||
map.put("osClassifier", osClassifier);
|
||||
map.put("javaVersion", javaVersion);
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.model;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class Brew extends AbstractTool {
|
||||
public static final String TOOL_NAME = "brew";
|
||||
|
||||
private final Map<String, String> dependencies = new LinkedHashMap<>();
|
||||
|
||||
public Brew() {
|
||||
super(TOOL_NAME);
|
||||
}
|
||||
|
||||
void setAll(Brew brew) {
|
||||
super.setAll(brew);
|
||||
setDependencies(brew.dependencies);
|
||||
}
|
||||
|
||||
public Map<String, String> getDependencies() {
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
public void setDependencies(Map<String, String> dependencies) {
|
||||
this.dependencies.clear();
|
||||
this.dependencies.putAll(dependencies);
|
||||
}
|
||||
|
||||
public void addDependencies(Map<String, String> dependencies) {
|
||||
this.dependencies.putAll(dependencies);
|
||||
}
|
||||
|
||||
public void addDependency(String key, String value) {
|
||||
dependencies.put(key, value);
|
||||
}
|
||||
|
||||
public void addDependency(String key) {
|
||||
dependencies.put(key, "");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void asMap(Map<String, Object> props) {
|
||||
props.put("dependencies", dependencies);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.model;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class Chocolatey extends AbstractTool {
|
||||
public static final String TOOL_NAME = "chocolatey";
|
||||
|
||||
public Chocolatey() {
|
||||
super(TOOL_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void asMap(Map<String, Object> props) {
|
||||
// empty
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.kordamp.jreleaser.util.StringUtils.isBlank;
|
||||
import static org.kordamp.jreleaser.util.StringUtils.isNotBlank;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class Distribution extends Packagers implements ExtraProperties {
|
||||
private final List<String> tags = new ArrayList<>();
|
||||
private final Map<String, Object> extraProperties = new LinkedHashMap<>();
|
||||
private final List<Artifact> artifacts = new ArrayList<>();
|
||||
private String name;
|
||||
private DistributionType type = DistributionType.BINARY;
|
||||
private String executable;
|
||||
private String javaVersion;
|
||||
|
||||
void setAll(Distribution distribution) {
|
||||
super.setAll(distribution);
|
||||
this.name = distribution.name;
|
||||
this.type = distribution.type;
|
||||
this.executable = distribution.executable;
|
||||
this.javaVersion = distribution.javaVersion;
|
||||
setTags(distribution.tags);
|
||||
setExtraProperties(distribution.extraProperties);
|
||||
setArtifacts(distribution.artifacts);
|
||||
}
|
||||
|
||||
public DistributionType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(DistributionType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = DistributionType.valueOf(type.replaceAll(" ", "_")
|
||||
.replaceAll("-", "_")
|
||||
.toUpperCase());
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getExecutable() {
|
||||
return executable;
|
||||
}
|
||||
|
||||
public void setExecutable(String executable) {
|
||||
this.executable = executable;
|
||||
}
|
||||
|
||||
public String getJavaVersion() {
|
||||
return javaVersion;
|
||||
}
|
||||
|
||||
public void setJavaVersion(String javaVersion) {
|
||||
this.javaVersion = javaVersion;
|
||||
}
|
||||
|
||||
public List<Artifact> getArtifacts() {
|
||||
return artifacts;
|
||||
}
|
||||
|
||||
public void setArtifacts(List<Artifact> artifacts) {
|
||||
this.artifacts.clear();
|
||||
this.artifacts.addAll(artifacts);
|
||||
}
|
||||
|
||||
public void addArtifacts(List<Artifact> artifacts) {
|
||||
this.artifacts.addAll(artifacts);
|
||||
}
|
||||
|
||||
public void addArtifact(Artifact artifact) {
|
||||
if (null != artifact) {
|
||||
this.artifacts.add(artifact);
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
public void setTags(List<String> tags) {
|
||||
this.tags.clear();
|
||||
this.tags.addAll(tags);
|
||||
}
|
||||
|
||||
public void addTags(List<String> tags) {
|
||||
this.tags.addAll(tags);
|
||||
}
|
||||
|
||||
public void addTag(String tag) {
|
||||
if (isNotBlank(tag)) {
|
||||
this.tags.add(tag.trim());
|
||||
}
|
||||
}
|
||||
|
||||
public void removeTag(String tag) {
|
||||
if (isNotBlank(tag)) {
|
||||
this.tags.remove(tag.trim());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getExtraProperties() {
|
||||
return extraProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExtraProperties(Map<String, Object> extraProperties) {
|
||||
this.extraProperties.putAll(extraProperties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addExtraProperties(Map<String, Object> extraProperties) {
|
||||
this.extraProperties.putAll(extraProperties);
|
||||
}
|
||||
|
||||
// --== TOOLs ==--
|
||||
|
||||
public <T extends Tool> T findTool(String name) {
|
||||
if (isBlank(name)) {
|
||||
throw new IllegalArgumentException("Tool name must not be blank");
|
||||
}
|
||||
|
||||
return resolveTool(name);
|
||||
}
|
||||
|
||||
public <T extends Tool> T getTool(String name) {
|
||||
T tool = findTool(name);
|
||||
if (null != tool) {
|
||||
return tool;
|
||||
}
|
||||
throw new IllegalArgumentException("Tool '" + name + "' has not been configured");
|
||||
}
|
||||
|
||||
private <T extends Tool> T resolveTool(String name) {
|
||||
switch (name.toLowerCase().trim()) {
|
||||
case Brew.TOOL_NAME:
|
||||
return (T) getBrew();
|
||||
case Chocolatey.TOOL_NAME:
|
||||
return (T) getChocolatey();
|
||||
case Scoop.TOOL_NAME:
|
||||
return (T) getScoop();
|
||||
case Snap.TOOL_NAME:
|
||||
return (T) getSnap();
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported tool '" + name + "'");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> asMap() {
|
||||
Map<String, Object> props = new LinkedHashMap<>();
|
||||
props.put("type", type);
|
||||
props.put("executable", executable);
|
||||
props.put("javaVersion", javaVersion);
|
||||
props.put("artifacts", artifacts.stream()
|
||||
.map(Artifact::asMap)
|
||||
.collect(Collectors.toList()));
|
||||
props.put("tags", tags);
|
||||
props.put("extraProperties", extraProperties);
|
||||
props.putAll(super.asMap());
|
||||
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
map.put(name, props);
|
||||
return map;
|
||||
}
|
||||
|
||||
public static Set<String> supportedTools() {
|
||||
Set<String> set = new LinkedHashSet<>();
|
||||
set.add(Brew.TOOL_NAME);
|
||||
set.add(Chocolatey.TOOL_NAME);
|
||||
set.add(Scoop.TOOL_NAME);
|
||||
set.add(Snap.TOOL_NAME);
|
||||
return Collections.unmodifiableSet(set);
|
||||
}
|
||||
|
||||
public enum DistributionType {
|
||||
BINARY,
|
||||
SINGLE_JAR
|
||||
// NATIVE_IMAGE,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public interface ExtraProperties extends Serializable {
|
||||
Map<String, Object> getExtraProperties();
|
||||
|
||||
void setExtraProperties(Map<String, Object> properties);
|
||||
|
||||
void addExtraProperties(Map<String, Object> properties);
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.model;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.kordamp.jreleaser.util.StringUtils.isBlank;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class JReleaserModel extends AbstractDomain {
|
||||
private final Project project = new Project();
|
||||
private final Release release = new Release();
|
||||
private final Packagers packagers = new Packagers();
|
||||
private final Map<String, Distribution> distributions = new LinkedHashMap<>();
|
||||
|
||||
public Project getProject() {
|
||||
return project;
|
||||
}
|
||||
|
||||
public void setProject(Project project) {
|
||||
this.project.setAll(project);
|
||||
}
|
||||
|
||||
public Release getRelease() {
|
||||
return release;
|
||||
}
|
||||
|
||||
public void setRelease(Release release) {
|
||||
this.release.setAll(release);
|
||||
}
|
||||
|
||||
public Packagers getPackagers() {
|
||||
return packagers;
|
||||
}
|
||||
|
||||
public void setPackagers(Packagers packagers) {
|
||||
this.packagers.setAll(packagers);
|
||||
}
|
||||
|
||||
public Map<String, Distribution> getDistributions() {
|
||||
return distributions;
|
||||
}
|
||||
|
||||
public void setDistributions(Map<String, Distribution> distributions) {
|
||||
this.distributions.clear();
|
||||
this.distributions.putAll(distributions);
|
||||
}
|
||||
|
||||
public void addDistributions(Map<String, Distribution> distributions) {
|
||||
this.distributions.putAll(distributions);
|
||||
}
|
||||
|
||||
public void addDistribution(Distribution distribution) {
|
||||
this.distributions.put(distribution.getName(), distribution);
|
||||
}
|
||||
|
||||
public Distribution findDistribution(String name) {
|
||||
if (isBlank(name)) {
|
||||
throw new IllegalArgumentException("Distribution name must not be blank");
|
||||
}
|
||||
|
||||
if (distributions.isEmpty()) {
|
||||
throw new IllegalArgumentException("No distributions have been configured");
|
||||
}
|
||||
|
||||
if (distributions.containsKey(name)) {
|
||||
return distributions.get(name);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Distribution '" + name + "' not found");
|
||||
}
|
||||
|
||||
public Map<String, Object> asMap() {
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
map.put("project", project.asMap());
|
||||
map.put("release", release.asMap());
|
||||
map.put("packagers", packagers.asMap());
|
||||
map.put("distributions", distributions.values()
|
||||
.stream()
|
||||
.map(Distribution::asMap)
|
||||
.collect(Collectors.toList()));
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.model;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.kordamp.jreleaser.util.StringUtils.isNotBlank;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public abstract class JReleaserModelPrinter {
|
||||
private static final String SECRET_KEYWORDS = "password,secret,credential,token,apikey,login";
|
||||
private static final String KEY_SECRET_KEYWORDS = "kordamp.secret.keywords";
|
||||
private final boolean showSecrets;
|
||||
private final PrintWriter out;
|
||||
|
||||
public JReleaserModelPrinter(PrintWriter out) {
|
||||
this(out, false);
|
||||
}
|
||||
|
||||
public JReleaserModelPrinter(PrintWriter out, boolean showSecrets) {
|
||||
this.out = out;
|
||||
this.showSecrets = showSecrets;
|
||||
}
|
||||
|
||||
public void print(Object value) {
|
||||
print(value, 0);
|
||||
}
|
||||
|
||||
public void print(Object value, int offset) {
|
||||
if (value instanceof Map) {
|
||||
doPrintMap((Map<String, ?>) value, offset);
|
||||
} else if (value instanceof Collection) {
|
||||
doPrintCollection((Collection<?>) value, offset);
|
||||
} else if (null != value) {
|
||||
Class<?> clazz = value.getClass();
|
||||
if (clazz.isArray()) {
|
||||
doPrintArray((Object[]) value, offset);
|
||||
} else {
|
||||
doPrintElement(value, offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void print(String value, int offset) {
|
||||
doPrintElement(value, offset);
|
||||
}
|
||||
|
||||
private void doPrintMap(Map<String, ?> map, final int offset) {
|
||||
if (map != null) {
|
||||
map.forEach((key, value) -> {
|
||||
if (value instanceof Map) {
|
||||
if (!((Map) value).isEmpty()) {
|
||||
out.println(multiply(" ", offset) + key + ":");
|
||||
doPrintMap((Map) value, offset + 1);
|
||||
}
|
||||
} else if (value instanceof Collection) {
|
||||
if (!((Collection) value).isEmpty()) {
|
||||
out.println(multiply(" ", offset) + key + ":");
|
||||
doPrintCollection((Collection) value, offset + 1);
|
||||
}
|
||||
} else if (null != value && value.getClass().isArray()) {
|
||||
if (((Object[]) value).length > 0) {
|
||||
out.println(multiply(" ", offset) + key + ":");
|
||||
doPrintArray((Object[]) value, offset + 1);
|
||||
}
|
||||
} else if (isNotNullNorBlank(value)) {
|
||||
doPrintMapEntry(key, value, offset);
|
||||
}
|
||||
|
||||
if (offset == 0) {
|
||||
out.println(" ");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void doPrintMapEntry(String key, Object value, int offset) {
|
||||
if (value instanceof Map) {
|
||||
doPrintMap(key, (Map) value, offset);
|
||||
} else if (value instanceof Collection) {
|
||||
doPrintCollection(key, (Collection<?>) value, offset);
|
||||
} else if (null != value) {
|
||||
Class<?> clazz = value.getClass();
|
||||
if (clazz.isArray()) {
|
||||
doPrintArray(key, (Object[]) value, offset);
|
||||
} else {
|
||||
String result = formatValue(value, isSecret(key));
|
||||
if (isNotNullNorBlank(result)) {
|
||||
out.println(multiply(" ", offset) + key + ": " + result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void doPrintCollection(Collection<?> collection, final int offset) {
|
||||
if (collection != null) {
|
||||
collection.forEach(value -> {
|
||||
if (value instanceof Map) {
|
||||
if (!((Map) value).isEmpty()) {
|
||||
doPrintMap((Map) value, offset);
|
||||
}
|
||||
} else if (value instanceof Collection) {
|
||||
if (!((Collection) value).isEmpty()) {
|
||||
doPrintCollection((Collection) value, offset + 1);
|
||||
}
|
||||
} else if (null != value && value.getClass().isArray()) {
|
||||
if (((Object[]) value).length > 0) {
|
||||
doPrintArray((Object[]) value, offset + 1);
|
||||
}
|
||||
} else if (isNotNullNorBlank(value)) {
|
||||
doPrintElement(value, offset);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void doPrintArray(Object[] array, final int offset) {
|
||||
if (array != null) {
|
||||
Arrays.stream(array).forEach(value -> {
|
||||
if (value instanceof Map) {
|
||||
if (!((Map) value).isEmpty()) {
|
||||
doPrintMap((Map) value, offset);
|
||||
}
|
||||
} else if (value instanceof Collection) {
|
||||
if (!((Collection) value).isEmpty()) {
|
||||
doPrintCollection((Collection) value, offset + 1);
|
||||
}
|
||||
} else if (null != value && value.getClass().isArray()) {
|
||||
if (((Object[]) value).length > 0) {
|
||||
doPrintArray((Object[]) value, offset + 1);
|
||||
}
|
||||
} else if (isNotNullNorBlank(value)) {
|
||||
doPrintElement(value, offset);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void doPrintMap(String key, Map<String, ?> map, int offset) {
|
||||
if (map != null && !map.isEmpty()) {
|
||||
out.println(multiply(" ", offset) + key + ':');
|
||||
doPrintMap(map, offset + 1);
|
||||
}
|
||||
}
|
||||
|
||||
private void doPrintCollection(String key, Collection<?> collection, int offset) {
|
||||
if (collection != null && !collection.isEmpty()) {
|
||||
out.println(multiply(" ", offset) + key + ':');
|
||||
doPrintCollection(collection, offset + 1);
|
||||
}
|
||||
}
|
||||
|
||||
private void doPrintArray(String key, Object[] array, int offset) {
|
||||
if (array != null && array.length > 0) {
|
||||
out.println(multiply(" ", offset) + key + ':');
|
||||
doPrintArray(array, offset + 1);
|
||||
}
|
||||
}
|
||||
|
||||
private void doPrintElement(Object value, int offset) {
|
||||
String result = formatValue(value);
|
||||
if (isNotNullNorBlank(result)) {
|
||||
out.println(multiply(" ", offset) + result);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isNotNullNorBlank(Object value) {
|
||||
if (value instanceof CharSequence) {
|
||||
return isNotBlank(String.valueOf(value));
|
||||
}
|
||||
|
||||
return value != null;
|
||||
}
|
||||
|
||||
private String formatValue(Object value) {
|
||||
return formatValue(value, false);
|
||||
}
|
||||
|
||||
private String formatValue(Object value, boolean secret) {
|
||||
if (value instanceof Boolean) {
|
||||
Boolean b = (Boolean) value;
|
||||
return b ? green(String.valueOf(b)) : red(String.valueOf(b));
|
||||
} else if (value instanceof Number) {
|
||||
return cyan(String.valueOf(value));
|
||||
} else if (value != null) {
|
||||
String s = String.valueOf(value);
|
||||
s = secret && !showSecrets ? multiply("*", 12) : s;
|
||||
|
||||
String r = parseAsBoolean(s);
|
||||
if (r != null) return r;
|
||||
r = parseAsInteger(s);
|
||||
if (r != null) return r;
|
||||
r = parseAsDouble(s);
|
||||
if (r != null) return r;
|
||||
|
||||
return secret ? magenta(s) : yellow(s);
|
||||
}
|
||||
|
||||
return String.valueOf(value);
|
||||
}
|
||||
|
||||
private String parseAsBoolean(String s) {
|
||||
if ("true".equalsIgnoreCase(s) || "false".equalsIgnoreCase(s)) {
|
||||
boolean b = Boolean.valueOf(s);
|
||||
return b ? green(String.valueOf(b)) : red(String.valueOf(b));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private String parseAsInteger(String s) {
|
||||
try {
|
||||
Integer.parseInt(s);
|
||||
return cyan(s);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private String parseAsDouble(String s) {
|
||||
try {
|
||||
Double.parseDouble(s);
|
||||
return cyan(s);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isSecret(String key) {
|
||||
String lower = key.toLowerCase();
|
||||
|
||||
for (String keyword : System.getProperty(KEY_SECRET_KEYWORDS, SECRET_KEYWORDS).split(",")) {
|
||||
if (lower.contains(keyword.trim().toLowerCase())) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private String cyan(String s) {
|
||||
return color("cyan", s);
|
||||
}
|
||||
|
||||
private String red(String s) {
|
||||
return color("red", s);
|
||||
}
|
||||
|
||||
private String green(String s) {
|
||||
return color("green", s);
|
||||
}
|
||||
|
||||
private String magenta(String s) {
|
||||
return color("magenta", s);
|
||||
}
|
||||
|
||||
private String yellow(String s) {
|
||||
return color("yellow", s);
|
||||
}
|
||||
|
||||
protected abstract String color(String color, String input);
|
||||
|
||||
private static String multiply(CharSequence self, Number factor) {
|
||||
int size = factor.intValue();
|
||||
if (size == 0) {
|
||||
return "";
|
||||
} else if (size < 0) {
|
||||
throw new IllegalArgumentException("multiply() should be called with a number of 0 or greater not: " + size);
|
||||
} else {
|
||||
StringBuilder answer = new StringBuilder(self);
|
||||
|
||||
for (int i = 1; i < size; ++i) {
|
||||
answer.append(self);
|
||||
}
|
||||
|
||||
return answer.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,352 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.model;
|
||||
|
||||
import org.kordamp.jreleaser.util.Logger;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.stream.Collectors.groupingBy;
|
||||
import static org.kordamp.jreleaser.util.StringUtils.capitalize;
|
||||
import static org.kordamp.jreleaser.util.StringUtils.getFilenameExtension;
|
||||
import static org.kordamp.jreleaser.util.StringUtils.isBlank;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public final class JReleaserModelValidator {
|
||||
private JReleaserModelValidator() {
|
||||
// noop
|
||||
}
|
||||
|
||||
public static List<String> validate(Logger logger, Path basedir, JReleaserModel model) {
|
||||
List<String> errors = new ArrayList<>();
|
||||
validateModel(logger, basedir, model, errors);
|
||||
return Collections.unmodifiableList(errors);
|
||||
}
|
||||
|
||||
private static void validateModel(Logger logger, Path basedir, JReleaserModel model, List<String> errors) {
|
||||
validateProject(logger, basedir, model.getProject(), errors);
|
||||
validateRelease(logger, basedir, model.getProject(), model.getRelease(), errors);
|
||||
validateDistributions(logger, basedir, model, model.getDistributions(), errors);
|
||||
}
|
||||
|
||||
private static void validateProject(Logger logger, Path basedir, Project project, List<String> errors) {
|
||||
if (isBlank(project.getName())) {
|
||||
errors.add("project.name must not be blank");
|
||||
}
|
||||
if (isBlank(project.getVersion())) {
|
||||
errors.add("project.version must not be blank");
|
||||
}
|
||||
if (isBlank(project.getDescription())) {
|
||||
errors.add("project.description must not be blank");
|
||||
}
|
||||
if (isBlank(project.getWebsite())) {
|
||||
errors.add("project.website must not be blank");
|
||||
}
|
||||
if (isBlank(project.getLicense())) {
|
||||
errors.add("project.license must not be blank");
|
||||
}
|
||||
if (isBlank(project.getLongDescription())) {
|
||||
project.setLongDescription(project.getDescription());
|
||||
}
|
||||
if (project.getAuthors().isEmpty()) {
|
||||
errors.add("project.authors must not be empty");
|
||||
}
|
||||
|
||||
adjustExtraProperties(project, "project");
|
||||
}
|
||||
|
||||
private static void validateRelease(Logger logger, Path basedir, Project project, Release release, List<String> errors) {
|
||||
if (isBlank(release.getRepoOwner())) {
|
||||
errors.add("release.repoOwner must not be blank");
|
||||
}
|
||||
if (isBlank(release.getRepoName())) {
|
||||
release.setRepoName(project.getName());
|
||||
}
|
||||
if (null == release.getRepoType()) {
|
||||
release.setRepoType(Release.RepoType.GITHUB);
|
||||
}
|
||||
|
||||
if (isBlank(release.getRepoHost())) {
|
||||
release.setRepoHost(release.getRepoType().repoHost());
|
||||
}
|
||||
if (isBlank(release.getDownloadUrlFormat())) {
|
||||
release.setDownloadUrlFormat(release.getRepoType().downloadUrlFormat());
|
||||
}
|
||||
if (isBlank(release.getReleaseNotesUrlFormat())) {
|
||||
release.setReleaseNotesUrlFormat(release.getRepoType().releaseNotesUrlFormat());
|
||||
}
|
||||
if (isBlank(release.getLatestReleaseUrlFormat())) {
|
||||
release.setLatestReleaseUrlFormat(release.getRepoType().latestReleaseUrlFormat());
|
||||
}
|
||||
if (isBlank(release.getIssueTrackerUrlFormat())) {
|
||||
release.setIssueTrackerUrlFormat(release.getRepoType().issueTrackerUrlFormat());
|
||||
}
|
||||
|
||||
if (isBlank(release.getAuthorization())) {
|
||||
String tokenName = release.getRepoType().name() + "_TOKEN";
|
||||
logger.warn("release.auhorization is not explicitly defined. Checking environment for {}", tokenName);
|
||||
if (isBlank(System.getenv(tokenName))) {
|
||||
errors.add("release.authorization must not be blank. Alternatively define a " + tokenName + " environment variable.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (isBlank(release.getTagName())) {
|
||||
release.setTagName("v" + project.getVersion());
|
||||
}
|
||||
if (isBlank(release.getTargetCommitish())) {
|
||||
release.setTargetCommitish("main");
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateDistributions(Logger logger, Path basedir, JReleaserModel model, Map<String, Distribution> distributions, List<String> errors) {
|
||||
if (distributions.isEmpty()) {
|
||||
errors.add("Missing distributions configuration");
|
||||
return;
|
||||
}
|
||||
|
||||
if (distributions.size() == 1) {
|
||||
distributions.values().stream()
|
||||
.findFirst().ifPresent(distribution -> distribution.setName(model.getProject().getName()));
|
||||
}
|
||||
|
||||
for (Map.Entry<String, Distribution> e : distributions.entrySet()) {
|
||||
Distribution distribution = e.getValue();
|
||||
if (isBlank(distribution.getName())) {
|
||||
distribution.setName(e.getKey());
|
||||
}
|
||||
validateDistribution(logger, basedir, model, distribution, errors);
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateDistribution(Logger logger, Path basedir, JReleaserModel model, Distribution distribution, List<String> errors) {
|
||||
if (isBlank(distribution.getName())) {
|
||||
errors.add("distribution.name must not be blank");
|
||||
return;
|
||||
}
|
||||
if (null == distribution.getType()) {
|
||||
errors.add("distribution." + distribution.getName() + ".type must not be null");
|
||||
return;
|
||||
}
|
||||
if (isBlank(distribution.getExecutable())) {
|
||||
distribution.setExecutable(distribution.getName());
|
||||
}
|
||||
if (isBlank(distribution.getJavaVersion())) {
|
||||
distribution.setJavaVersion(model.getProject().getJavaVersion());
|
||||
}
|
||||
if (null == distribution.getArtifacts() || distribution.getArtifacts().isEmpty()) {
|
||||
errors.add("distribution." + distribution.getName() + ".artifacts is empty");
|
||||
return;
|
||||
}
|
||||
|
||||
List<String> tags = new ArrayList<>();
|
||||
tags.addAll(model.getProject().getTags());
|
||||
tags.addAll(distribution.getTags());
|
||||
distribution.setTags(tags);
|
||||
|
||||
for (int i = 0; i < distribution.getArtifacts().size(); i++) {
|
||||
validateArtifact(logger, basedir, model, distribution, distribution.getArtifacts().get(i), i, errors);
|
||||
}
|
||||
// validate artifact.osClassifier is unique
|
||||
Map<String, List<Artifact>> byClassifier = distribution.getArtifacts().stream()
|
||||
.collect(groupingBy(artifact -> isBlank(artifact.getOsClassifier()) ? "<nil>" : artifact.getOsClassifier()));
|
||||
// check classifiers by extension
|
||||
byClassifier.entrySet().forEach(c -> {
|
||||
String classifier = "<nil>".equals(c.getKey()) ? "no" : c.getKey();
|
||||
c.getValue().stream()
|
||||
.collect(groupingBy(artifact -> getFilenameExtension(artifact.getPath())))
|
||||
.entrySet().forEach(e -> {
|
||||
if (e.getValue().size() > 1) {
|
||||
errors.add("distribution." + distribution.getName() +
|
||||
" has more than one artifact with " + classifier +
|
||||
" classifier for extension " + e.getValue());
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
adjustExtraProperties(distribution, "distribution");
|
||||
|
||||
validateBrew(logger, basedir, model, distribution, distribution.getBrew(), errors);
|
||||
validateChocolatey(logger, basedir, model, distribution, distribution.getChocolatey(), errors);
|
||||
validateScoop(logger, basedir, model, distribution, distribution.getScoop(), errors);
|
||||
validateSnap(logger, basedir, model, distribution, distribution.getSnap(), errors);
|
||||
}
|
||||
|
||||
private static void validateArtifact(Logger logger, Path basedir, JReleaserModel model, Distribution distribution, Artifact artifact, int index, List<String> errors) {
|
||||
if (null == artifact) {
|
||||
errors.add("distribution." + distribution.getName() + ".artifact[" + index + "] is null");
|
||||
return;
|
||||
}
|
||||
if (isBlank(artifact.getPath())) {
|
||||
errors.add("distribution." + distribution.getName() + ".artifact[" + index + "].path must not be null");
|
||||
}
|
||||
if (isBlank(artifact.getJavaVersion())) {
|
||||
artifact.setJavaVersion(distribution.getJavaVersion());
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateBrew(Logger logger, Path basedir, JReleaserModel model, Distribution distribution, Brew tool, List<String> errors) {
|
||||
if (!tool.isEnabledSet() && model.getPackagers().getBrew().isEnabledSet()) {
|
||||
tool.setEnabled(model.getPackagers().getBrew().isEnabled());
|
||||
}
|
||||
validateTemplate(logger, model, distribution, tool, tool.getToolName(), errors);
|
||||
adjustExtraProperties(model.getPackagers().getBrew(), tool.getToolName());
|
||||
adjustExtraProperties(tool, tool.getToolName());
|
||||
mergeExtraProperties(tool, model.getPackagers().getBrew());
|
||||
|
||||
Map<String, String> dependencies = new LinkedHashMap<>(model.getPackagers().getBrew().getDependencies());
|
||||
dependencies.putAll(tool.getDependencies());
|
||||
|
||||
tool.setDependencies(dependencies);
|
||||
}
|
||||
|
||||
private static void validateChocolatey(Logger logger, Path basedir, JReleaserModel model, Distribution distribution, Chocolatey tool, List<String> errors) {
|
||||
if (!tool.isEnabledSet() && model.getPackagers().getChocolatey().isEnabledSet()) {
|
||||
tool.setEnabled(model.getPackagers().getChocolatey().isEnabled());
|
||||
}
|
||||
validateTemplate(logger, model, distribution, tool, tool.getToolName(), errors);
|
||||
adjustExtraProperties(model.getPackagers().getChocolatey(), tool.getToolName());
|
||||
adjustExtraProperties(tool, tool.getToolName());
|
||||
mergeExtraProperties(tool, model.getPackagers().getChocolatey());
|
||||
}
|
||||
|
||||
private static void validateScoop(Logger logger, Path basedir, JReleaserModel model, Distribution distribution, Scoop tool, List<String> errors) {
|
||||
if (!tool.isEnabledSet() && model.getPackagers().getScoop().isEnabledSet()) {
|
||||
tool.setEnabled(model.getPackagers().getScoop().isEnabled());
|
||||
}
|
||||
validateTemplate(logger, model, distribution, tool, tool.getToolName(), errors);
|
||||
Scoop commonScoop = model.getPackagers().getScoop();
|
||||
adjustExtraProperties(commonScoop, tool.getToolName());
|
||||
adjustExtraProperties(tool, tool.getToolName());
|
||||
mergeExtraProperties(tool, model.getPackagers().getScoop());
|
||||
|
||||
if (isBlank(tool.getCheckverUrl())) {
|
||||
tool.setCheckverUrl(commonScoop.getCheckverUrl());
|
||||
if (isBlank(tool.getCheckverUrl())) {
|
||||
tool.setCheckverUrl(model.getRelease().getLatestReleaseUrlFormat());
|
||||
}
|
||||
}
|
||||
if (isBlank(tool.getAutoupdateUrl())) {
|
||||
tool.setAutoupdateUrl(commonScoop.getAutoupdateUrl());
|
||||
if (isBlank(tool.getAutoupdateUrl())) {
|
||||
tool.setAutoupdateUrl(model.getRelease().getDownloadUrlFormat());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateSnap(Logger logger, Path basedir, JReleaserModel model, Distribution distribution, Snap tool, List<String> errors) {
|
||||
if (!tool.isEnabledSet() && model.getPackagers().getSnap().isEnabledSet()) {
|
||||
tool.setEnabled(model.getPackagers().getSnap().isEnabled());
|
||||
}
|
||||
validateTemplate(logger, model, distribution, tool, tool.getToolName(), errors);
|
||||
Snap commonSnap = model.getPackagers().getSnap();
|
||||
adjustExtraProperties(commonSnap, tool.getToolName());
|
||||
adjustExtraProperties(tool, tool.getToolName());
|
||||
mergeExtraProperties(tool, model.getPackagers().getSnap());
|
||||
mergeSnapPlugs(tool, model.getPackagers().getSnap());
|
||||
mergeSnapSlots(tool, model.getPackagers().getSnap());
|
||||
|
||||
if (isBlank(tool.getBase())) {
|
||||
tool.setBase(commonSnap.getBase());
|
||||
if (isBlank(tool.getBase())) {
|
||||
errors.add("distribution." + distribution.getName() + ".snap.base must not be blank");
|
||||
}
|
||||
}
|
||||
if (isBlank(tool.getGrade())) {
|
||||
tool.setGrade(commonSnap.getGrade());
|
||||
if (isBlank(tool.getGrade())) {
|
||||
errors.add("distribution." + distribution.getName() + ".snap.grade must not be blank");
|
||||
}
|
||||
}
|
||||
if (isBlank(tool.getConfinement())) {
|
||||
tool.setConfinement(commonSnap.getConfinement());
|
||||
if (isBlank(tool.getConfinement())) {
|
||||
errors.add("distribution." + distribution.getName() + ".snap.confinement must not be blank");
|
||||
}
|
||||
}
|
||||
if (isBlank(tool.getExportedLogin())) {
|
||||
tool.setExportedLogin(commonSnap.getExportedLogin());
|
||||
if (isBlank(tool.getExportedLogin())) {
|
||||
errors.add("distribution." + distribution.getName() + ".snap.exportedLogin must not be empty");
|
||||
} else if (!basedir.resolve(tool.getExportedLogin()).toFile().exists()) {
|
||||
errors.add("distribution." + distribution.getName() + ".snap.exportedLogin does not exist. " + basedir.resolve(tool.getExportedLogin()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void mergeExtraProperties(Tool tool, Tool common) {
|
||||
Map<String, Object> extraProperties = new LinkedHashMap<>(common.getExtraProperties());
|
||||
extraProperties.putAll(tool.getExtraProperties());
|
||||
tool.setExtraProperties(extraProperties);
|
||||
}
|
||||
|
||||
private static void mergeSnapPlugs(Snap tool, Snap common) {
|
||||
Map<String, Plug> commonPlugs = common.getPlugs().stream()
|
||||
.collect(Collectors.toMap(Plug::getName, Plug::copyOf));
|
||||
Map<String, Plug> toolPlugs = tool.getPlugs().stream()
|
||||
.collect(Collectors.toMap(Plug::getName, Plug::copyOf));
|
||||
commonPlugs.forEach((name, cp) -> {
|
||||
Plug tp = toolPlugs.remove(name);
|
||||
if (null != tp) {
|
||||
cp.getAttributes().putAll(tp.getAttributes());
|
||||
}
|
||||
});
|
||||
commonPlugs.putAll(toolPlugs);
|
||||
tool.setPlugs(new ArrayList<>(commonPlugs.values()));
|
||||
}
|
||||
|
||||
private static void mergeSnapSlots(Snap tool, Snap common) {
|
||||
Map<String, Slot> commonSlots = common.getSlots().stream()
|
||||
.collect(Collectors.toMap(Slot::getName, Slot::copyOf));
|
||||
Map<String, Slot> toolSlots = tool.getSlots().stream()
|
||||
.collect(Collectors.toMap(Slot::getName, Slot::copyOf));
|
||||
commonSlots.forEach((name, cp) -> {
|
||||
Slot tp = toolSlots.remove(name);
|
||||
if (null != tp) {
|
||||
cp.getAttributes().putAll(tp.getAttributes());
|
||||
}
|
||||
});
|
||||
commonSlots.putAll(toolSlots);
|
||||
tool.setSlots(new ArrayList<>(commonSlots.values()));
|
||||
}
|
||||
|
||||
private static void validateTemplate(Logger logger, JReleaserModel model, Distribution distribution, Tool tool, String toolName, List<String> errors) {
|
||||
if (null != tool.getTemplateDirectory() && !tool.getTemplateDirectory().toFile().exists()) {
|
||||
errors.add("distribution." + distribution.getName() + "." + toolName + ".template does not exist. " + tool.getTemplateDirectory());
|
||||
}
|
||||
}
|
||||
|
||||
private static void adjustExtraProperties(ExtraProperties extra, String prefix) {
|
||||
if (extra.getExtraProperties().size() > 0) {
|
||||
Map<String, Object> props = extra.getExtraProperties()
|
||||
.entrySet().stream()
|
||||
.collect(Collectors.toMap(
|
||||
e -> prefix + capitalize(e.getKey()),
|
||||
Map.Entry::getValue));
|
||||
extra.setExtraProperties(props);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.model;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class Packagers extends AbstractDomain {
|
||||
private final Brew brew = new Brew();
|
||||
private final Chocolatey chocolatey = new Chocolatey();
|
||||
private final Scoop scoop = new Scoop();
|
||||
private final Snap snap = new Snap();
|
||||
|
||||
void setAll(Packagers packagers) {
|
||||
setBrew(packagers.brew);
|
||||
setChocolatey(packagers.chocolatey);
|
||||
setScoop(packagers.scoop);
|
||||
setSnap(packagers.snap);
|
||||
}
|
||||
|
||||
public Brew getBrew() {
|
||||
return brew;
|
||||
}
|
||||
|
||||
public void setBrew(Brew brew) {
|
||||
this.brew.setAll(brew);
|
||||
}
|
||||
|
||||
public Chocolatey getChocolatey() {
|
||||
return chocolatey;
|
||||
}
|
||||
|
||||
public void setChocolatey(Chocolatey chocolatey) {
|
||||
this.chocolatey.setAll(chocolatey);
|
||||
}
|
||||
|
||||
public Scoop getScoop() {
|
||||
return scoop;
|
||||
}
|
||||
|
||||
public void setScoop(Scoop scoop) {
|
||||
this.scoop.setAll(scoop);
|
||||
}
|
||||
|
||||
public Snap getSnap() {
|
||||
return snap;
|
||||
}
|
||||
|
||||
public void setSnap(Snap snap) {
|
||||
this.snap.setAll(snap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> asMap() {
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
map.putAll(brew.asMap());
|
||||
map.putAll(chocolatey.asMap());
|
||||
map.putAll(scoop.asMap());
|
||||
map.putAll(snap.asMap());
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.model;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class Plug extends AbstractDomain {
|
||||
private final Map<String, String> attributes = new LinkedHashMap<>();
|
||||
private String name;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Map<String, String> getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public void setAttributes(Map<String, String> attributes) {
|
||||
this.attributes.clear();
|
||||
this.attributes.putAll(attributes);
|
||||
}
|
||||
|
||||
public void addAttributes(Map<String, String> attributes) {
|
||||
this.attributes.putAll(attributes);
|
||||
}
|
||||
|
||||
public void addAttribute(String key, String value) {
|
||||
attributes.put(key, value);
|
||||
}
|
||||
|
||||
public Map<String, Object> asMap() {
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
map.put(name, attributes);
|
||||
return map;
|
||||
}
|
||||
|
||||
public static Plug copyOf(Plug other) {
|
||||
Plug copy = new Plug();
|
||||
copy.setName(other.getName());
|
||||
copy.setAttributes(other.getAttributes());
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.kordamp.jreleaser.util.StringUtils.isNotBlank;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class Project extends AbstractDomain implements ExtraProperties {
|
||||
private final List<String> authors = new ArrayList<>();
|
||||
private final List<String> tags = new ArrayList<>();
|
||||
private final Map<String, Object> extraProperties = new LinkedHashMap<>();
|
||||
private String name;
|
||||
private String version;
|
||||
private String description;
|
||||
private String longDescription;
|
||||
private String website;
|
||||
private String license;
|
||||
private String javaVersion;
|
||||
|
||||
void setAll(Project project) {
|
||||
this.name = project.name;
|
||||
this.version = project.version;
|
||||
this.description = project.description;
|
||||
this.longDescription = project.longDescription;
|
||||
this.website = project.website;
|
||||
this.license = project.license;
|
||||
this.javaVersion = project.javaVersion;
|
||||
setAuthors(project.authors);
|
||||
setTags(project.tags);
|
||||
setExtraProperties(project.extraProperties);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getLongDescription() {
|
||||
return longDescription;
|
||||
}
|
||||
|
||||
public void setLongDescription(String longDescription) {
|
||||
this.longDescription = longDescription;
|
||||
}
|
||||
|
||||
public String getWebsite() {
|
||||
return website;
|
||||
}
|
||||
|
||||
public void setWebsite(String website) {
|
||||
this.website = website;
|
||||
}
|
||||
|
||||
public String getLicense() {
|
||||
return license;
|
||||
}
|
||||
|
||||
public void setLicense(String license) {
|
||||
this.license = license;
|
||||
}
|
||||
|
||||
public String getJavaVersion() {
|
||||
return javaVersion;
|
||||
}
|
||||
|
||||
public void setJavaVersion(String javaVersion) {
|
||||
this.javaVersion = javaVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getExtraProperties() {
|
||||
return extraProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExtraProperties(Map<String, Object> extraProperties) {
|
||||
this.extraProperties.putAll(extraProperties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addExtraProperties(Map<String, Object> extraProperties) {
|
||||
this.extraProperties.putAll(extraProperties);
|
||||
}
|
||||
|
||||
public List<String> getAuthors() {
|
||||
return authors;
|
||||
}
|
||||
|
||||
public void setAuthors(List<String> authors) {
|
||||
this.authors.clear();
|
||||
this.authors.addAll(authors);
|
||||
}
|
||||
|
||||
public void addAuthors(List<String> authors) {
|
||||
this.authors.addAll(authors);
|
||||
}
|
||||
|
||||
public void addAuthor(String author) {
|
||||
if (isNotBlank(author)) {
|
||||
this.authors.add(author.trim());
|
||||
}
|
||||
}
|
||||
|
||||
public void removeAuthor(String author) {
|
||||
if (isNotBlank(author)) {
|
||||
this.authors.remove(author.trim());
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
public void setTags(List<String> tags) {
|
||||
this.tags.clear();
|
||||
this.tags.addAll(tags);
|
||||
}
|
||||
|
||||
public void addTags(List<String> tags) {
|
||||
this.tags.addAll(tags);
|
||||
}
|
||||
|
||||
public void addTag(String tag) {
|
||||
if (isNotBlank(tag)) {
|
||||
this.tags.add(tag.trim());
|
||||
}
|
||||
}
|
||||
|
||||
public void removeTag(String tag) {
|
||||
if (isNotBlank(tag)) {
|
||||
this.tags.remove(tag.trim());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> asMap() {
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
map.put("name", name);
|
||||
map.put("version", version);
|
||||
map.put("description", description);
|
||||
map.put("longDescription", longDescription);
|
||||
map.put("website", website);
|
||||
map.put("license", license);
|
||||
if (isNotBlank(javaVersion)) map.put("javaVersion", javaVersion);
|
||||
map.put("authors", authors);
|
||||
map.put("tags", tags);
|
||||
map.put("extraProperties", extraProperties);
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,296 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.model;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.kordamp.jreleaser.util.StringUtils.isNotBlank;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class Release extends AbstractDomain {
|
||||
private RepoType repoType;
|
||||
private String repoHost;
|
||||
private String repoOwner;
|
||||
private String repoName;
|
||||
private String downloadUrlFormat;
|
||||
private String releaseNotesUrlFormat;
|
||||
private String latestReleaseUrlFormat;
|
||||
private String issueTrackerUrlFormat;
|
||||
private String authorization;
|
||||
private String tagName;
|
||||
private String targetCommitish = "main";
|
||||
private String releaseName;
|
||||
private String body = "";
|
||||
private boolean draft;
|
||||
private boolean prerelease;
|
||||
private boolean overwrite;
|
||||
private boolean allowUploadToExisting;
|
||||
private String apiEndpoint;
|
||||
|
||||
void setAll(Release release) {
|
||||
this.repoType = release.repoType;
|
||||
this.repoHost = release.repoHost;
|
||||
this.repoOwner = release.repoOwner;
|
||||
this.repoName = release.repoName;
|
||||
this.downloadUrlFormat = release.downloadUrlFormat;
|
||||
this.releaseNotesUrlFormat = release.releaseNotesUrlFormat;
|
||||
this.latestReleaseUrlFormat = release.latestReleaseUrlFormat;
|
||||
this.issueTrackerUrlFormat = release.issueTrackerUrlFormat;
|
||||
this.authorization = release.authorization;
|
||||
this.tagName = release.tagName;
|
||||
this.targetCommitish = release.targetCommitish;
|
||||
this.releaseName = release.releaseName;
|
||||
this.body = release.body;
|
||||
this.draft = release.draft;
|
||||
this.prerelease = release.prerelease;
|
||||
this.overwrite = release.overwrite;
|
||||
this.allowUploadToExisting = release.allowUploadToExisting;
|
||||
this.apiEndpoint = release.apiEndpoint;
|
||||
}
|
||||
|
||||
public RepoType getRepoType() {
|
||||
return repoType;
|
||||
}
|
||||
|
||||
public void setRepoType(RepoType repoType) {
|
||||
this.repoType = repoType;
|
||||
}
|
||||
|
||||
public void setRepoType(String repoType) {
|
||||
if (isNotBlank(repoType)) {
|
||||
this.repoType = RepoType.valueOf(repoType.toUpperCase());
|
||||
}
|
||||
}
|
||||
|
||||
public String getRepoHost() {
|
||||
return repoHost;
|
||||
}
|
||||
|
||||
public void setRepoHost(String repoHost) {
|
||||
this.repoHost = repoHost;
|
||||
}
|
||||
|
||||
public String getRepoOwner() {
|
||||
return repoOwner;
|
||||
}
|
||||
|
||||
public void setRepoOwner(String repoOwner) {
|
||||
this.repoOwner = repoOwner;
|
||||
}
|
||||
|
||||
public String getRepoName() {
|
||||
return repoName;
|
||||
}
|
||||
|
||||
public void setRepoName(String repoName) {
|
||||
this.repoName = repoName;
|
||||
}
|
||||
|
||||
public String getDownloadUrlFormat() {
|
||||
return downloadUrlFormat;
|
||||
}
|
||||
|
||||
public void setDownloadUrlFormat(String downloadUrlFormat) {
|
||||
this.downloadUrlFormat = downloadUrlFormat;
|
||||
}
|
||||
|
||||
public String getReleaseNotesUrlFormat() {
|
||||
return releaseNotesUrlFormat;
|
||||
}
|
||||
|
||||
public void setReleaseNotesUrlFormat(String releaseNotesUrlFormat) {
|
||||
this.releaseNotesUrlFormat = releaseNotesUrlFormat;
|
||||
}
|
||||
|
||||
public String getLatestReleaseUrlFormat() {
|
||||
return latestReleaseUrlFormat;
|
||||
}
|
||||
|
||||
public void setLatestReleaseUrlFormat(String latestReleaseUrlFormat) {
|
||||
this.latestReleaseUrlFormat = latestReleaseUrlFormat;
|
||||
}
|
||||
|
||||
public String getIssueTrackerUrlFormat() {
|
||||
return issueTrackerUrlFormat;
|
||||
}
|
||||
|
||||
public void setIssueTrackerUrlFormat(String issueTrackerUrlFormat) {
|
||||
this.issueTrackerUrlFormat = issueTrackerUrlFormat;
|
||||
}
|
||||
|
||||
public String getAuthorization() {
|
||||
return authorization;
|
||||
}
|
||||
|
||||
public void setAuthorization(String authorization) {
|
||||
this.authorization = authorization;
|
||||
}
|
||||
|
||||
public String getTagName() {
|
||||
return tagName;
|
||||
}
|
||||
|
||||
public void setTagName(String tagName) {
|
||||
this.tagName = tagName;
|
||||
}
|
||||
|
||||
public String getTargetCommitish() {
|
||||
return targetCommitish;
|
||||
}
|
||||
|
||||
public void setTargetCommitish(String targetCommitish) {
|
||||
this.targetCommitish = targetCommitish;
|
||||
}
|
||||
|
||||
public String getReleaseName() {
|
||||
return releaseName;
|
||||
}
|
||||
|
||||
public void setReleaseName(String releaseName) {
|
||||
this.releaseName = releaseName;
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
public void setBody(String body) {
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public boolean isDraft() {
|
||||
return draft;
|
||||
}
|
||||
|
||||
public void setDraft(boolean draft) {
|
||||
this.draft = draft;
|
||||
}
|
||||
|
||||
public boolean isPrerelease() {
|
||||
return prerelease;
|
||||
}
|
||||
|
||||
public void setPrerelease(boolean prerelease) {
|
||||
this.prerelease = prerelease;
|
||||
}
|
||||
|
||||
public boolean isOverwrite() {
|
||||
return overwrite;
|
||||
}
|
||||
|
||||
public void setOverwrite(boolean overwrite) {
|
||||
this.overwrite = overwrite;
|
||||
}
|
||||
|
||||
public boolean isAllowUploadToExisting() {
|
||||
return allowUploadToExisting;
|
||||
}
|
||||
|
||||
public void setAllowUploadToExisting(boolean allowUploadToExisting) {
|
||||
this.allowUploadToExisting = allowUploadToExisting;
|
||||
}
|
||||
|
||||
public String getApiEndpoint() {
|
||||
return apiEndpoint;
|
||||
}
|
||||
|
||||
public void setApiEndpoint(String apiEndpoint) {
|
||||
this.apiEndpoint = apiEndpoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> asMap() {
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
map.put("repoHost", repoHost);
|
||||
map.put("repoType", repoType);
|
||||
map.put("repoOwner", repoOwner);
|
||||
map.put("repoName", repoName);
|
||||
map.put("downloadUrlFormat", downloadUrlFormat);
|
||||
map.put("releaseNotesUrlFormat", releaseNotesUrlFormat);
|
||||
map.put("latestReleaseUrlFormat", latestReleaseUrlFormat);
|
||||
map.put("issueTrackerUrlFormat", issueTrackerUrlFormat);
|
||||
map.put("authorization", authorization);
|
||||
map.put("tagName", tagName);
|
||||
map.put("targetCommitish", targetCommitish);
|
||||
map.put("releaseName", releaseName);
|
||||
map.put("body ", isNotBlank(body));
|
||||
map.put("draft", draft);
|
||||
map.put("prerelease", prerelease);
|
||||
map.put("overwrite", overwrite);
|
||||
map.put("allowUploadToExisting", allowUploadToExisting);
|
||||
map.put("apiEndpoint", apiEndpoint);
|
||||
return map;
|
||||
}
|
||||
|
||||
public enum RepoType {
|
||||
GITHUB("github.com",
|
||||
"https://{{repoHost}}/{{repoOwner}}/{{repoName}}/releases/download/v{{projectVersion}}/{{artifactFileName}}",
|
||||
"https://{{repoHost}}/{{repoOwner}}/{{repoName}}/releases/tag/v{{projectVersion}}",
|
||||
"https://{{repoHost}}/{{repoOwner}}/{{repoName}}/releases/latest",
|
||||
"https://{{repoHost}}/{{repoOwner}}/{{repoName}}/issues");
|
||||
/*
|
||||
GITLAB("gitlab.com",
|
||||
"https://{{repoHost}}/{{repoOwner}}/{{repoName}}/-/archive/v{{projectVersion}}/{{artifactFileName}}",
|
||||
"https://{{repoHost}}/{{repoOwner}}/{{repoName}}/-/releases/v{{projectVersion}}",
|
||||
"https://{{repoHost}}/{{repoOwner}}/{{repoName}}/-/releases/v{{projectVersion}}",
|
||||
"https://{{repoHost}}/{{repoOwner}}/{{repoName}}/-/issues");
|
||||
*/
|
||||
|
||||
private final String repoHost;
|
||||
private final String downloadUrlFormat;
|
||||
private final String releaseNotesUrlFormat;
|
||||
private final String latestReleaseUrlFormat;
|
||||
private final String issueTrackerUrlFormat;
|
||||
|
||||
RepoType(String repoHost,
|
||||
String downloadUrlFormat,
|
||||
String releaseNotesUrlFormat,
|
||||
String latestReleaseUrlFormat,
|
||||
String issueTrackerUrlFormat) {
|
||||
this.repoHost = repoHost;
|
||||
this.downloadUrlFormat = downloadUrlFormat;
|
||||
this.releaseNotesUrlFormat = releaseNotesUrlFormat;
|
||||
this.latestReleaseUrlFormat = latestReleaseUrlFormat;
|
||||
this.issueTrackerUrlFormat = issueTrackerUrlFormat;
|
||||
}
|
||||
|
||||
String repoHost() {
|
||||
return this.repoHost;
|
||||
}
|
||||
|
||||
String downloadUrlFormat() {
|
||||
return this.downloadUrlFormat;
|
||||
}
|
||||
|
||||
String releaseNotesUrlFormat() {
|
||||
return this.releaseNotesUrlFormat;
|
||||
}
|
||||
|
||||
String latestReleaseUrlFormat() {
|
||||
return this.latestReleaseUrlFormat;
|
||||
}
|
||||
|
||||
String issueTrackerUrlFormat() {
|
||||
return this.issueTrackerUrlFormat;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.model;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class Scoop extends AbstractTool {
|
||||
public static final String TOOL_NAME = "scoop";
|
||||
|
||||
private String checkverUrl;
|
||||
private String autoupdateUrl;
|
||||
|
||||
public Scoop() {
|
||||
super(TOOL_NAME);
|
||||
}
|
||||
|
||||
void setAll(Scoop scoop) {
|
||||
super.setAll(scoop);
|
||||
this.checkverUrl = scoop.checkverUrl;
|
||||
this.autoupdateUrl = scoop.autoupdateUrl;
|
||||
}
|
||||
|
||||
public String getCheckverUrl() {
|
||||
return checkverUrl;
|
||||
}
|
||||
|
||||
public void setCheckverUrl(String checkverUrl) {
|
||||
this.checkverUrl = checkverUrl;
|
||||
}
|
||||
|
||||
public String getAutoupdateUrl() {
|
||||
return autoupdateUrl;
|
||||
}
|
||||
|
||||
public void setAutoupdateUrl(String autoupdateUrl) {
|
||||
this.autoupdateUrl = autoupdateUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void asMap(Map<String, Object> props) {
|
||||
props.put("checkverUrl", checkverUrl);
|
||||
props.put("autoupdateUrl", autoupdateUrl);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.kordamp.jreleaser.util.StringUtils.isNotBlank;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class Slot extends AbstractDomain {
|
||||
private final Map<String, String> attributes = new LinkedHashMap<>();
|
||||
private final List<String> reads = new ArrayList<>();
|
||||
private final List<String> writes = new ArrayList<>();
|
||||
private String name;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Map<String, String> getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public void setAttributes(Map<String, String> attributes) {
|
||||
this.attributes.clear();
|
||||
this.attributes.putAll(attributes);
|
||||
}
|
||||
|
||||
public void addAttributes(Map<String, String> attributes) {
|
||||
this.attributes.putAll(attributes);
|
||||
}
|
||||
|
||||
public void addAttribute(String key, String value) {
|
||||
attributes.put(key, value);
|
||||
}
|
||||
|
||||
public List<String> getReads() {
|
||||
return reads;
|
||||
}
|
||||
|
||||
public void setReads(List<String> reads) {
|
||||
this.reads.clear();
|
||||
this.reads.addAll(reads);
|
||||
}
|
||||
|
||||
public void addReads(List<String> read) {
|
||||
this.reads.addAll(read);
|
||||
}
|
||||
|
||||
public void addRead(String read) {
|
||||
if (isNotBlank(read)) {
|
||||
this.reads.add(read.trim());
|
||||
}
|
||||
}
|
||||
|
||||
public void removeRead(String read) {
|
||||
if (isNotBlank(read)) {
|
||||
this.reads.remove(read.trim());
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getWrites() {
|
||||
return writes;
|
||||
}
|
||||
|
||||
public void setWrites(List<String> writes) {
|
||||
this.writes.clear();
|
||||
this.writes.addAll(writes);
|
||||
}
|
||||
|
||||
public void addWrites(List<String> write) {
|
||||
this.writes.addAll(write);
|
||||
}
|
||||
|
||||
public void addWrite(String write) {
|
||||
if (isNotBlank(write)) {
|
||||
this.writes.add(write.trim());
|
||||
}
|
||||
}
|
||||
|
||||
public void removeWrite(String write) {
|
||||
if (isNotBlank(write)) {
|
||||
this.writes.remove(write.trim());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getHasReads() {
|
||||
return !reads.isEmpty();
|
||||
}
|
||||
|
||||
public boolean getHasWrites() {
|
||||
return !writes.isEmpty();
|
||||
}
|
||||
|
||||
public Map<String, Object> asMap() {
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
map.put(name, attributes);
|
||||
map.put("read", reads);
|
||||
map.put("write", writes);
|
||||
return map;
|
||||
}
|
||||
|
||||
public static Slot copyOf(Slot other) {
|
||||
Slot copy = new Slot();
|
||||
copy.setName(other.getName());
|
||||
copy.setAttributes(other.getAttributes());
|
||||
copy.setReads(other.getReads());
|
||||
copy.setWrites(other.getWrites());
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.kordamp.jreleaser.util.StringUtils.isNotBlank;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class Snap extends AbstractTool {
|
||||
public static final String TOOL_NAME = "snap";
|
||||
|
||||
private final List<String> localPlugs = new ArrayList<>();
|
||||
private final List<Plug> plugs = new ArrayList<>();
|
||||
private final List<Slot> slots = new ArrayList<>();
|
||||
private String base = "core18";
|
||||
private String grade = "stable";
|
||||
private String confinement = "strict";
|
||||
private String exportedLogin;
|
||||
|
||||
public Snap() {
|
||||
super(TOOL_NAME);
|
||||
}
|
||||
|
||||
void setAll(Snap snap) {
|
||||
super.setAll(snap);
|
||||
this.base = snap.base;
|
||||
this.grade = snap.grade;
|
||||
this.confinement = snap.confinement;
|
||||
this.exportedLogin = snap.exportedLogin;
|
||||
setLocalPlugs(localPlugs);
|
||||
setPlugs(plugs);
|
||||
setSlots(slots);
|
||||
}
|
||||
|
||||
public String getBase() {
|
||||
return base;
|
||||
}
|
||||
|
||||
public void setBase(String base) {
|
||||
this.base = base;
|
||||
}
|
||||
|
||||
public String getGrade() {
|
||||
return grade;
|
||||
}
|
||||
|
||||
public void setGrade(String grade) {
|
||||
this.grade = grade;
|
||||
}
|
||||
|
||||
public String getConfinement() {
|
||||
return confinement;
|
||||
}
|
||||
|
||||
public void setConfinement(String confinement) {
|
||||
this.confinement = confinement;
|
||||
}
|
||||
|
||||
public List<String> getLocalPlugs() {
|
||||
return localPlugs;
|
||||
}
|
||||
|
||||
public void setLocalPlugs(List<String> localPlugs) {
|
||||
this.localPlugs.clear();
|
||||
this.localPlugs.addAll(localPlugs);
|
||||
}
|
||||
|
||||
public void addLocalPlugs(List<String> localPlugs) {
|
||||
this.localPlugs.addAll(localPlugs);
|
||||
}
|
||||
|
||||
public void addLocalPlug(String localPlug) {
|
||||
if (isNotBlank(localPlug)) {
|
||||
this.localPlugs.add(localPlug.trim());
|
||||
}
|
||||
}
|
||||
|
||||
public void removeLocalPlug(String localPlug) {
|
||||
if (isNotBlank(localPlug)) {
|
||||
this.localPlugs.remove(localPlug.trim());
|
||||
}
|
||||
}
|
||||
|
||||
public List<Plug> getPlugs() {
|
||||
return plugs;
|
||||
}
|
||||
|
||||
public void setPlugs(List<Plug> plugs) {
|
||||
this.plugs.clear();
|
||||
this.plugs.addAll(plugs);
|
||||
}
|
||||
|
||||
public void addPlugs(List<Plug> plugs) {
|
||||
this.plugs.addAll(plugs);
|
||||
}
|
||||
|
||||
public void addPlug(Plug plug) {
|
||||
if (null != plug) {
|
||||
this.plugs.add(plug);
|
||||
}
|
||||
}
|
||||
|
||||
public void removePlug(Plug plug) {
|
||||
if (null != plug) {
|
||||
this.plugs.remove(plug);
|
||||
}
|
||||
}
|
||||
|
||||
public List<Slot> getSlots() {
|
||||
return slots;
|
||||
}
|
||||
|
||||
public void setSlots(List<Slot> slots) {
|
||||
this.slots.clear();
|
||||
this.slots.addAll(slots);
|
||||
}
|
||||
|
||||
public void addSlots(List<Slot> slots) {
|
||||
this.slots.addAll(slots);
|
||||
}
|
||||
|
||||
public void addSlot(Slot slot) {
|
||||
if (null != slot) {
|
||||
this.slots.add(slot);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeSlot(Slot slot) {
|
||||
if (null != slot) {
|
||||
this.slots.remove(slot);
|
||||
}
|
||||
}
|
||||
public String getExportedLogin() {
|
||||
return exportedLogin;
|
||||
}
|
||||
|
||||
public void setExportedLogin(String exportedLogin) {
|
||||
this.exportedLogin = exportedLogin;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void asMap(Map<String, Object> props) {
|
||||
props.put("base", base);
|
||||
props.put("grade", grade);
|
||||
props.put("confinement", confinement);
|
||||
props.put("exportedLogin", exportedLogin);
|
||||
props.put("localPlugs", localPlugs);
|
||||
props.put("plugs", plugs);
|
||||
props.put("slots", slots);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public interface Tool extends Serializable, ExtraProperties {
|
||||
boolean isEnabledSet();
|
||||
|
||||
Boolean isEnabled();
|
||||
|
||||
void setEnabled(Boolean enabled);
|
||||
|
||||
String getToolName();
|
||||
|
||||
Path getTemplateDirectory();
|
||||
|
||||
void setTemplateDirectory(Path templateDirectory);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.model.releaser;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class ReleaseException extends Exception {
|
||||
public ReleaseException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ReleaseException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public ReleaseException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.model.releaser;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public interface Releaser {
|
||||
void release() throws ReleaseException;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.model.releaser;
|
||||
|
||||
import org.kordamp.jreleaser.model.JReleaserModel;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public interface ReleaserBuilder<R extends Releaser> {
|
||||
R build();
|
||||
|
||||
R buildFromModel(JReleaserModel model);
|
||||
}
|
||||
22
core/jreleaser-model/src/main/module/module-info.java
Normal file
22
core/jreleaser-model/src/main/module/module-info.java
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
module org.kordamp.jreleaser.model {
|
||||
exports org.kordamp.jreleaser.model;
|
||||
requires org.kordamp.jreleaser.util;
|
||||
}
|
||||
19
core/jreleaser-releaser/gradle.properties
Normal file
19
core/jreleaser-releaser/gradle.properties
Normal file
@@ -0,0 +1,19 @@
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Copyright 2020 Andres Almiray.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
project_description = JReleaser Releaser
|
||||
23
core/jreleaser-releaser/jreleaser-releaser.gradle
Normal file
23
core/jreleaser-releaser/jreleaser-releaser.gradle
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
dependencies {
|
||||
api project(':jreleaser-model')
|
||||
api project(':jreleaser-templates')
|
||||
api project(':github-java-sdk')
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.releaser;
|
||||
|
||||
import org.kordamp.jreleaser.model.JReleaserModel;
|
||||
import org.kordamp.jreleaser.model.releaser.ReleaserBuilder;
|
||||
import org.kordamp.jreleaser.sdk.github.GithubReleaser;
|
||||
import org.kordamp.jreleaser.util.Logger;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class Releasers {
|
||||
public static <RB extends ReleaserBuilder> RB findReleaser(Logger logger, JReleaserModel model) {
|
||||
switch (model.getRelease().getRepoType()) {
|
||||
case GITHUB:
|
||||
return (RB) GithubReleaser.builder();
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported releaser " + model.getRelease().getRepoType());
|
||||
}
|
||||
}
|
||||
}
|
||||
23
core/jreleaser-releaser/src/main/module/module-info.java
Normal file
23
core/jreleaser-releaser/src/main/module/module-info.java
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
module org.kordamp.jreleaser.releaser {
|
||||
exports org.kordamp.jreleaser.releaser;
|
||||
requires org.kordamp.jreleaser.model;
|
||||
requires org.kordamp.jreleaser.util;
|
||||
}
|
||||
19
core/jreleaser-templates/gradle.properties
Normal file
19
core/jreleaser-templates/gradle.properties
Normal file
@@ -0,0 +1,19 @@
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Copyright 2020 Andres Almiray.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
project_description = JReleaser tool templates
|
||||
22
core/jreleaser-templates/jreleaser-templates.gradle
Normal file
22
core/jreleaser-templates/jreleaser-templates.gradle
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
dependencies {
|
||||
api project(':jreleaser-model')
|
||||
api "com.github.spullara.mustache.java:compiler:$mustacheVersion"
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.templates;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class TemplateGenerationException extends Exception {
|
||||
public TemplateGenerationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public TemplateGenerationException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public TemplateGenerationException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.templates;
|
||||
|
||||
import org.kordamp.jreleaser.model.Distribution;
|
||||
import org.kordamp.jreleaser.util.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
import java.nio.file.FileAlreadyExistsException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
|
||||
import static java.nio.file.StandardOpenOption.CREATE;
|
||||
import static java.nio.file.StandardOpenOption.CREATE_NEW;
|
||||
import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
|
||||
import static java.nio.file.StandardOpenOption.WRITE;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static org.kordamp.jreleaser.util.StringUtils.requireNonBlank;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class TemplateGenerator {
|
||||
private final Logger logger;
|
||||
private final String distributionName;
|
||||
private final Distribution.DistributionType distributionType;
|
||||
private final String toolName;
|
||||
private final Path outputDirectory;
|
||||
private final boolean overwrite;
|
||||
|
||||
private TemplateGenerator(Logger logger,
|
||||
String distributionName,
|
||||
Distribution.DistributionType distributionType,
|
||||
String toolName,
|
||||
Path outputDirectory,
|
||||
boolean overwrite) {
|
||||
this.logger = logger;
|
||||
this.distributionName = distributionName;
|
||||
this.distributionType = distributionType;
|
||||
this.toolName = toolName;
|
||||
this.outputDirectory = outputDirectory;
|
||||
this.overwrite = overwrite;
|
||||
}
|
||||
|
||||
public String getDistributionName() {
|
||||
return distributionName;
|
||||
}
|
||||
|
||||
public Distribution.DistributionType getDistributionType() {
|
||||
return distributionType;
|
||||
}
|
||||
|
||||
public String getToolName() {
|
||||
return toolName;
|
||||
}
|
||||
|
||||
public Path getOutputDirectory() {
|
||||
return outputDirectory;
|
||||
}
|
||||
|
||||
public boolean isOverwrite() {
|
||||
return overwrite;
|
||||
}
|
||||
|
||||
public boolean generate() throws TemplateGenerationException {
|
||||
if (!Distribution.supportedTools().contains(toolName)) {
|
||||
logger.error("Tool {} is not supported", toolName);
|
||||
return false;
|
||||
}
|
||||
|
||||
Path output = outputDirectory.resolve(distributionName)
|
||||
.resolve(toolName);
|
||||
|
||||
logger.info("Creating output directory {}", output.toAbsolutePath());
|
||||
try {
|
||||
Files.createDirectories(output);
|
||||
} catch (IOException e) {
|
||||
throw fail(e);
|
||||
}
|
||||
|
||||
Map<String, Reader> templates = TemplateUtils.resolveTemplates(logger, distributionType, toolName);
|
||||
for (Map.Entry<String, Reader> template : templates.entrySet()) {
|
||||
Path outputFile = output.resolve(template.getKey());
|
||||
logger.info("Writing file " + outputFile.toAbsolutePath());
|
||||
try (Writer writer = Files.newBufferedWriter(outputFile, (overwrite ? CREATE : CREATE_NEW), WRITE, TRUNCATE_EXISTING);
|
||||
Scanner scanner = new Scanner(template.getValue())) {
|
||||
while (scanner.hasNextLine()) {
|
||||
writer.write(scanner.nextLine() + System.lineSeparator());
|
||||
}
|
||||
} catch (FileAlreadyExistsException e) {
|
||||
logger.error("File {} already exists and overwrite was set to false.", outputFile.toAbsolutePath());
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
throw fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private TemplateGenerationException fail(Exception e) throws TemplateGenerationException {
|
||||
throw new TemplateGenerationException("Unexpected error when generating template. " +
|
||||
"distributionType=" + distributionType +
|
||||
", distributionName=" + distributionName +
|
||||
", toolName=" + toolName, e);
|
||||
}
|
||||
|
||||
public static TemplateGeneratorBuilder builder() {
|
||||
return new TemplateGeneratorBuilder();
|
||||
}
|
||||
|
||||
public static class TemplateGeneratorBuilder {
|
||||
private Logger logger;
|
||||
private String distributionName;
|
||||
private Distribution.DistributionType distributionType = Distribution.DistributionType.BINARY;
|
||||
private String toolName;
|
||||
private Path outputDirectory;
|
||||
private boolean overwrite;
|
||||
|
||||
public TemplateGeneratorBuilder logger(Logger logger) {
|
||||
this.logger = requireNonNull(logger, "'logger' must not be null");
|
||||
return this;
|
||||
}
|
||||
|
||||
public TemplateGeneratorBuilder distributionName(String distributionName) {
|
||||
this.distributionName = requireNonBlank(distributionName, "'distributionName' must not be blank");
|
||||
return this;
|
||||
}
|
||||
|
||||
public TemplateGeneratorBuilder distributionType(Distribution.DistributionType distributionType) {
|
||||
this.distributionType = requireNonNull(distributionType, "'distributionType' must not be null");
|
||||
return this;
|
||||
}
|
||||
|
||||
public TemplateGeneratorBuilder toolName(String toolName) {
|
||||
this.toolName = requireNonBlank(toolName, "'toolName' must not be blank");
|
||||
return this;
|
||||
}
|
||||
|
||||
public TemplateGeneratorBuilder outputDirectory(Path outputDirectory) {
|
||||
this.outputDirectory = requireNonNull(outputDirectory, "'outputDirectory' must not be null");
|
||||
return this;
|
||||
}
|
||||
|
||||
public TemplateGeneratorBuilder overwrite(boolean overwrite) {
|
||||
this.overwrite = overwrite;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TemplateGenerator build() {
|
||||
requireNonNull(logger, "'logger' must not be null");
|
||||
requireNonBlank(distributionName, "'distributionName' must not be blank");
|
||||
requireNonNull(distributionType, "'distributionType' must not be null");
|
||||
requireNonBlank(toolName, "'toolName' must not be blank");
|
||||
requireNonNull(outputDirectory, "'outputDirectory' must not be null");
|
||||
return new TemplateGenerator(logger, distributionName, distributionType, toolName, outputDirectory, overwrite);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.templates;
|
||||
|
||||
import org.kordamp.jreleaser.model.Distribution;
|
||||
import org.kordamp.jreleaser.util.Logger;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.Enumeration;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public final class TemplateUtils {
|
||||
private TemplateUtils() {
|
||||
// noop
|
||||
}
|
||||
|
||||
public static String trimTplExtension(String str) {
|
||||
if (str.endsWith(".tpl")) {
|
||||
return str.substring(0, str.length() - 4);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
public static Map<String, Reader> resolveAndMergeTemplates(Logger logger, Distribution.DistributionType distributionType, String toolName, Path templateDirectory) {
|
||||
Map<String, Reader> templates = resolveTemplates(logger, distributionType, toolName);
|
||||
if (null != templateDirectory && templateDirectory.toFile().exists()) {
|
||||
templates.putAll(resolveTemplates(logger, distributionType, toolName, templateDirectory));
|
||||
}
|
||||
return templates;
|
||||
}
|
||||
|
||||
public static Map<String, Reader> resolveTemplates(Logger logger, Distribution.DistributionType distributionType, String toolName, Path templateDirectory) {
|
||||
Map<String, Reader> templates = new LinkedHashMap<>();
|
||||
|
||||
try {
|
||||
Files.walkFileTree(templateDirectory, new SimpleFileVisitor<Path>() {
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||
templates.put(templateDirectory.relativize(file).toString(),
|
||||
Files.newBufferedReader(file));
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
String distributionTypeName = distributionType.name().toLowerCase().replace('_', '-');
|
||||
throw new IllegalStateException("Unexpected error reading templates for distribution " +
|
||||
distributionTypeName + "/" + toolName + " from " + templateDirectory.toAbsolutePath());
|
||||
}
|
||||
|
||||
return templates;
|
||||
}
|
||||
|
||||
public static Map<String, Reader> resolveTemplates(Logger logger, Distribution.DistributionType distributionType, String toolName) {
|
||||
String distributionTypeName = distributionType.name().toLowerCase().replace('_', '-');
|
||||
String templatePrefix = "META-INF/jreleaser/templates/" +
|
||||
distributionTypeName + "/" + toolName.toLowerCase();
|
||||
|
||||
Map<String, Reader> templates = new LinkedHashMap<>();
|
||||
|
||||
logger.debug("Resolving templates from classpath");
|
||||
URL location = resolveLocation(TemplateUtils.class);
|
||||
if (null == location) {
|
||||
throw new IllegalStateException("Could not find location of classpath templates");
|
||||
}
|
||||
|
||||
try {
|
||||
if ("file".equals(location.getProtocol())) {
|
||||
boolean templateFound = false;
|
||||
JarFile jarFile = new JarFile(new File(location.toURI()));
|
||||
logger.debug("Searching for templates matching {}/*", templatePrefix);
|
||||
for (Enumeration<JarEntry> e = jarFile.entries(); e.hasMoreElements(); ) {
|
||||
JarEntry entry = e.nextElement();
|
||||
if (entry.isDirectory() || !entry.getName().startsWith(templatePrefix)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String templateName = entry.getName().substring(templatePrefix.length() + 1);
|
||||
templates.put(templateName, new InputStreamReader(jarFile.getInputStream(entry)));
|
||||
logger.debug("Found template {}", templateName);
|
||||
templateFound = true;
|
||||
}
|
||||
|
||||
if (!templateFound) {
|
||||
logger.error("Templates for {}/{} were not found", distributionTypeName, toolName);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException("Could not find location of classpath templates");
|
||||
}
|
||||
} catch (URISyntaxException | IOException e) {
|
||||
throw new IllegalStateException("Unexpected error reading templates for distribution " +
|
||||
distributionTypeName + "/" + toolName + " from classpath.");
|
||||
}
|
||||
|
||||
return templates;
|
||||
}
|
||||
|
||||
public static Reader resolveTemplate(Logger logger, Class<?> anchor, String templateKey) {
|
||||
logger.debug("Resolving template from classpath for {}@{}", anchor.getName(), templateKey);
|
||||
URL location = resolveLocation(anchor);
|
||||
if (null == location) {
|
||||
throw new IllegalStateException("Could not find location of classpath templates");
|
||||
}
|
||||
|
||||
try {
|
||||
if ("file".equals(location.getProtocol())) {
|
||||
JarFile jarFile = new JarFile(new File(location.toURI()));
|
||||
logger.debug("Searching for template matching {}", templateKey);
|
||||
for (Enumeration<JarEntry> e = jarFile.entries(); e.hasMoreElements(); ) {
|
||||
JarEntry entry = e.nextElement();
|
||||
if (entry.isDirectory() || !entry.getName().equals(templateKey)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
logger.debug("Found template {}", templateKey);
|
||||
return new InputStreamReader(jarFile.getInputStream(entry));
|
||||
}
|
||||
throw new IllegalStateException("Template for " +
|
||||
anchor.getName() + "@" + templateKey + " were not found");
|
||||
} else {
|
||||
throw new IllegalStateException("Could not find location of classpath templates");
|
||||
}
|
||||
} catch (URISyntaxException | IOException e) {
|
||||
throw new IllegalStateException("Unexpected error reading template for " +
|
||||
anchor.getName() + "@" + templateKey + " from classpath.");
|
||||
}
|
||||
}
|
||||
|
||||
private static URL resolveLocation(Class<?> klass) {
|
||||
if (klass == null) return null;
|
||||
|
||||
try {
|
||||
URL codeSourceLocation = klass.getProtectionDomain()
|
||||
.getCodeSource()
|
||||
.getLocation();
|
||||
if (codeSourceLocation != null) return codeSourceLocation;
|
||||
} catch (SecurityException | NullPointerException ignored) {
|
||||
// noop
|
||||
}
|
||||
|
||||
URL classResource = klass.getResource(klass.getSimpleName() + ".class");
|
||||
if (classResource == null) return null;
|
||||
|
||||
String url = classResource.toString();
|
||||
String suffix = klass.getCanonicalName().replace('.', '/') + ".class";
|
||||
if (!url.endsWith(suffix)) return null;
|
||||
String path = url.substring(0, url.length() - suffix.length());
|
||||
|
||||
if (path.startsWith("jar:")) path = path.substring(4, path.length() - 2);
|
||||
|
||||
try {
|
||||
return new URL(path);
|
||||
} catch (MalformedURLException ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
24
core/jreleaser-templates/src/main/module/module-info.java
Normal file
24
core/jreleaser-templates/src/main/module/module-info.java
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
module org.kordamp.jreleaser.templates {
|
||||
exports org.kordamp.jreleaser.templates;
|
||||
requires org.kordamp.jreleaser.model;
|
||||
requires org.kordamp.jreleaser.util;
|
||||
requires com.github.mustachejava;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
class {{projectNameCapitalized}} < Formula
|
||||
desc "{{projectDescription}}"
|
||||
homepage "{{projectWebsite}}"
|
||||
url "{{distributionUrl}}"
|
||||
sha256 "{{distributionSha256}}"
|
||||
license "{{projectLicense}}"
|
||||
|
||||
bottle :unneeded
|
||||
|
||||
{{#brewDependencies}}
|
||||
depends_on {{formattedDependency}}
|
||||
{{/brewDependencies}}
|
||||
|
||||
def install
|
||||
libexec.install Dir["*"]
|
||||
bin.install_symlink "#{libexec}/bin/{{distributionExecutable}}"
|
||||
end
|
||||
|
||||
test do
|
||||
output = shell_output("#{bin}/{{distributionExecutable}} --version")
|
||||
assert_match "{{projectVersion}}", output
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Do not remove this test for UTF-8: if “Ω” doesn’t appear as greek uppercase omega letter enclosed in quotation marks, you should use an editor that supports UTF-8, not this one. -->
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd">
|
||||
<metadata>
|
||||
<!-- required -->
|
||||
<id>{{distributionName}}</id>
|
||||
<version>{{projectVersion}}</version>
|
||||
<authors>{{projectAuthorsByComma}}</authors>
|
||||
<description>{{projectLongDescription}}</description>
|
||||
<!-- optional -->
|
||||
<title>{{projectName}}</title>
|
||||
<projectUrl>{{projectWebsite}}</projectUrl>
|
||||
<license type="expression">{{projectLicense}}</license>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<tags>{{distributionTagsBySpace}}</tags>
|
||||
<summary>{{projectDescription}}</summary>
|
||||
<releaseNotes>{{distributionReleaseNotes}}</releaseNotes>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="tools\**" target="tools" />
|
||||
</files>
|
||||
</package>
|
||||
@@ -0,0 +1,13 @@
|
||||
$tools = Split-Path $MyInvocation.MyCommand.Definition
|
||||
$package = Split-Path $tools
|
||||
$app_home = Join-Path $package '{{projectName}}-{{projectVersion}}'
|
||||
$app_bat = Join-Path $app_home 'bin/{{distributionExecutable}}.cmd'
|
||||
|
||||
Install-ChocolateyZipPackage `
|
||||
-PackageName '{{distributionName}}' `
|
||||
-Url '{{distributionUrl}}' `
|
||||
-Checksum '{{distributionSha256}}' `
|
||||
-ChecksumType 'sha256' `
|
||||
-UnzipLocation $package
|
||||
|
||||
Install-BinFile -Name '{{distributionExecutable}}' -Path $app_bat
|
||||
@@ -0,0 +1,6 @@
|
||||
$tools = Split-Path $MyInvocation.MyCommand.Definition
|
||||
$package = Split-Path $tools
|
||||
$app_home = Join-Path $package '{{projectName}}-{{projectVersion}}'
|
||||
$app_bat = Join-Path $app_home 'bin/{{distributionExecutable}}.cmd'
|
||||
|
||||
Uninstall-BinFile -Name '{{distributionExecutable}}' -Path $app_bat
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"homepage": "{{projectWebsite}}",
|
||||
"description": "{{projectDescription}}",
|
||||
"version": "{{projectVersion}}",
|
||||
"license": "{{projectLicense}}",
|
||||
"url": "{{distributionUrl}}",
|
||||
"hash": "sha256:{{distributionSha256}}",
|
||||
"extract_dir": "{{projectName}}-{{projectVersion}}",
|
||||
"env_add_path": "bin",
|
||||
"suggest": {
|
||||
"JDK": [
|
||||
"java/oraclejdk",
|
||||
"java/openjdk"
|
||||
]
|
||||
},
|
||||
"checkver": {
|
||||
"url": "{{scoopCheckverUrl}}",
|
||||
"re": "v([\\d.]+).zip"
|
||||
},
|
||||
"autoupdate": {
|
||||
"url": "{{scoopAutoupdateUrl}}",
|
||||
"extract_dir": "{{projectName}}-$version",
|
||||
"hash": {
|
||||
"url": "$url.sha256"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
name: {{distributionName}}
|
||||
base: {{snapBase}}
|
||||
version: {{projectVersion}}
|
||||
license: {{projectLicense}}
|
||||
grade: {{snapGrade}}
|
||||
type: app
|
||||
confinement: {{snapConfinement}}
|
||||
summary: {{projectDescription}}
|
||||
description: {{projectLongDescription}}
|
||||
|
||||
apps:
|
||||
{{distributionExecutable}}:
|
||||
command: bin/{{distributionExecutable}}
|
||||
environment:
|
||||
JAVA_HOME: $SNAP/usr/lib/jvm/java
|
||||
|
||||
{{#snapHasPlugs}}
|
||||
plugs:
|
||||
{{#snapPlugs}}
|
||||
{{name}}:
|
||||
{{#attributes}}
|
||||
{{key}}: {{value}}
|
||||
{{/attributes}}
|
||||
{{/snapPlugs}}
|
||||
{{/snapHasPlugs}}
|
||||
{{#snapHasSlots}}
|
||||
slots:
|
||||
{{#snapSlots}}
|
||||
{{name}}:
|
||||
{{#attributes}}
|
||||
{{key}}: {{value}}
|
||||
{{/attributes}}
|
||||
{{#hasReads}}
|
||||
reads:
|
||||
{{#reads}}
|
||||
- {{.}}
|
||||
{{/reads}}
|
||||
{{/hasReads}}
|
||||
{{#hasWrites}}
|
||||
writes:
|
||||
{{#writes}}
|
||||
- {{.}}
|
||||
{{/writes}}
|
||||
{{/hasWrites}}
|
||||
{{/snapSlots }}
|
||||
{{/snapHasSlots}}
|
||||
parts:
|
||||
{{distributionExecutable}}:
|
||||
plugin: dump
|
||||
source: {{distributionUrl}}
|
||||
source-checksum: sha256/{{distributionSha256}}
|
||||
stage-packages:
|
||||
- openjdk-{{javaVersion}}-jdk
|
||||
organize:
|
||||
usr/lib/jvm/java-{{javaVersion}}-openjdk*: usr/lib/jvm/java
|
||||
{{#snapHasLocalPlugs}}
|
||||
plugs:
|
||||
{{#snapLocalPlugs}}
|
||||
- {{.}}
|
||||
{{/snapLocalPlugs}}
|
||||
{{/snapHasLocalPlugs}}
|
||||
@@ -0,0 +1,103 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem {{distributionExecutable}} startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%..
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-jar {{artifactFileName}}"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=
|
||||
|
||||
@rem Execute {{distributionExecutable}}
|
||||
"%JAVA_EXE%" %JAVA_OPTS% %DEFAULT_JVM_OPTS% %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable APP_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%APP_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@@ -0,0 +1,183 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## {{distributionExecutable}} start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/.." >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="{{distributionExecutable}}"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-jar {{artifactFileName}}"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $JAVA_OPTS $DEFAULT_JVM_OPTS "$APP_ARGS"
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
@@ -0,0 +1,62 @@
|
||||
name: {{distributionName}}
|
||||
base: {{snapBase}}
|
||||
version: {{projectVersion}}
|
||||
license: {{projectLicense}}
|
||||
grade: {{snapGrade}}
|
||||
type: app
|
||||
confinement: {{snapConfinement}}
|
||||
summary: {{projectDescription}}
|
||||
description: {{projectLongDescription}}
|
||||
|
||||
apps:
|
||||
{{distributionExecutable}}:
|
||||
command: ${JAVA_HOME}/bin/java -jar $SNAP/{{distributionFileName}}
|
||||
environment:
|
||||
JAVA_HOME: $SNAP/usr/lib/jvm/java
|
||||
|
||||
{{#snapHasPlugs}}
|
||||
plugs:
|
||||
{{#snapPlugs}}
|
||||
{{name}}:
|
||||
{{#attributes}}
|
||||
{{key}}: {{value}}
|
||||
{{/attributes}}
|
||||
{{/snapPlugs}}
|
||||
{{/snapHasPlugs}}
|
||||
{{#snapHasSlots}}
|
||||
slots:
|
||||
{{#snapSlots}}
|
||||
{{name}}:
|
||||
{{#attributes}}
|
||||
{{key}}: {{value}}
|
||||
{{/attributes}}
|
||||
{{#hasReads}}
|
||||
reads:
|
||||
{{#reads}}
|
||||
- {{.}}
|
||||
{{/reads}}
|
||||
{{/hasReads}}
|
||||
{{#hasWrites}}
|
||||
writes:
|
||||
{{#writes}}
|
||||
- {{.}}
|
||||
{{/writes}}
|
||||
{{/hasWrites}}
|
||||
{{/snapSlots }}
|
||||
{{/snapHasSlots}}
|
||||
|
||||
parts:
|
||||
{{distributionExecutable}}:
|
||||
plugin: nil
|
||||
source: {{distributionUrl}}
|
||||
source-checksum: sha256/{{distributionSha256}}
|
||||
stage-packages:
|
||||
- openjdk-{{javaVersion}}-jdk
|
||||
organize:
|
||||
usr/lib/jvm/java-{{javaVersion}}-openjdk*: usr/lib/jvm/java
|
||||
{{#snapHasLocalPlugs}}
|
||||
plugs:
|
||||
{{#snapLocalPlugs}}
|
||||
- {{.}}
|
||||
{{/snapLocalPlugs}}
|
||||
{{/snapHasLocalPlugs}}
|
||||
19
core/jreleaser-tools/gradle.properties
Normal file
19
core/jreleaser-tools/gradle.properties
Normal file
@@ -0,0 +1,19 @@
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Copyright 2020 Andres Almiray.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
project_description = JReleaser Execution
|
||||
24
core/jreleaser-tools/jreleaser-tools.gradle
Normal file
24
core/jreleaser-tools/jreleaser-tools.gradle
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
dependencies {
|
||||
api project(':jreleaser-model')
|
||||
api project(':jreleaser-templates')
|
||||
api "com.github.spullara.mustache.java:compiler:$mustacheVersion"
|
||||
api "org.zeroturnaround:zt-exec:$ztexecVersion"
|
||||
}
|
||||
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.tools;
|
||||
|
||||
import org.kordamp.jreleaser.model.Artifact;
|
||||
import org.kordamp.jreleaser.model.Distribution;
|
||||
import org.kordamp.jreleaser.model.JReleaserModel;
|
||||
import org.kordamp.jreleaser.model.Project;
|
||||
import org.kordamp.jreleaser.model.Release;
|
||||
import org.kordamp.jreleaser.model.Tool;
|
||||
import org.kordamp.jreleaser.util.Logger;
|
||||
import org.zeroturnaround.exec.ProcessExecutor;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.nio.file.StandardOpenOption.CREATE;
|
||||
import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
|
||||
import static java.nio.file.StandardOpenOption.WRITE;
|
||||
import static org.kordamp.jreleaser.templates.TemplateUtils.resolveAndMergeTemplates;
|
||||
import static org.kordamp.jreleaser.tools.ProcessorUtils.applyTemplate;
|
||||
import static org.kordamp.jreleaser.util.FileUtils.createDirectoriesWithFullAccess;
|
||||
import static org.kordamp.jreleaser.util.FileUtils.grantFullAccess;
|
||||
import static org.kordamp.jreleaser.util.StringUtils.capitalize;
|
||||
import static org.kordamp.jreleaser.util.StringUtils.getClassNameForLowerCaseHyphenSeparatedName;
|
||||
import static org.kordamp.jreleaser.util.StringUtils.isBlank;
|
||||
import static org.kordamp.jreleaser.util.StringUtils.isNotBlank;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
abstract class AbstractToolProcessor<T extends Tool> implements ToolProcessor<T> {
|
||||
private final Logger logger;
|
||||
private final JReleaserModel model;
|
||||
private final T tool;
|
||||
|
||||
protected AbstractToolProcessor(Logger logger, JReleaserModel model, T tool) {
|
||||
this.logger = logger;
|
||||
this.model = model;
|
||||
this.tool = tool;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getTool() {
|
||||
return tool;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getToolName() {
|
||||
return tool.getToolName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Logger getLogger() {
|
||||
return logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JReleaserModel getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean prepareDistribution(Distribution distribution, Map<String, Object> context) throws ToolProcessingException {
|
||||
Tool tool = distribution.getTool(getToolName());
|
||||
|
||||
try {
|
||||
String distributionName = distribution.getName();
|
||||
getLogger().debug("Creating context for {}/{}", distributionName, getToolName());
|
||||
Map<String, Object> newContext = fillContext(distribution, context);
|
||||
if (newContext.isEmpty()) {
|
||||
logger.warn("Skipping {} tool for {} distribution", getToolName(), distributionName);
|
||||
return false;
|
||||
}
|
||||
getLogger().debug("Resolving templates for {}/{}", distributionName, getToolName());
|
||||
Map<String, Reader> templates = resolveAndMergeTemplates(logger, distribution.getType(), getToolName(), tool.getTemplateDirectory());
|
||||
for (Map.Entry<String, Reader> entry : templates.entrySet()) {
|
||||
getLogger().debug("Evaluating template {} for {}/{}", entry.getKey(), distributionName, getToolName());
|
||||
String content = applyTemplate(entry.getValue(), newContext);
|
||||
getLogger().debug("Writing template {} for {}/{}", entry.getKey(), distributionName, getToolName());
|
||||
writeFile(model.getProject(), distribution, content, context, entry.getKey());
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new ToolProcessingException(e);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean packageDistribution(Distribution distribution, Map<String, Object> context) throws ToolProcessingException {
|
||||
try {
|
||||
String distributionName = distribution.getName();
|
||||
getLogger().debug("Creating context for {}/{}", distributionName, getToolName());
|
||||
Map<String, Object> newContext = fillContext(distribution, context);
|
||||
if (newContext.isEmpty()) {
|
||||
logger.warn("Skipping {} tool for {} distribution", getToolName(), distributionName);
|
||||
return false;
|
||||
}
|
||||
return doPackageDistribution(distribution, newContext);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new ToolProcessingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract boolean doPackageDistribution(Distribution distribution, Map<String, Object> context) throws ToolProcessingException;
|
||||
|
||||
protected abstract void writeFile(Project project, Distribution distribution, String content, Map<String, Object> context, String fileName) throws ToolProcessingException;
|
||||
|
||||
protected void writeFile(String content, Path outputFile) throws ToolProcessingException {
|
||||
try {
|
||||
createDirectoriesWithFullAccess(outputFile.getParent());
|
||||
Files.write(outputFile, content.getBytes(), CREATE, WRITE, TRUNCATE_EXISTING);
|
||||
grantFullAccess(outputFile);
|
||||
} catch (IOException e) {
|
||||
throw new ToolProcessingException("Unexpected error when writing to " + outputFile.toAbsolutePath(), e);
|
||||
}
|
||||
}
|
||||
|
||||
protected Map<String, Object> fillContext(Distribution distribution, Map<String, Object> context) throws ToolProcessingException {
|
||||
Map<String, Object> newContext = new LinkedHashMap<>(context);
|
||||
getLogger().debug("Filling project properties into context");
|
||||
fillProjectProperties(newContext, model.getProject());
|
||||
getLogger().debug("Filling release properties into context");
|
||||
fillReleaseProperties(newContext, model.getRelease());
|
||||
getLogger().debug("Filling distribution properties into context");
|
||||
fillDistributionProperties(newContext, distribution, model.getRelease());
|
||||
getLogger().debug("Filling artifact properties into context");
|
||||
if (!verifyAndAddArtifacts(newContext, distribution)) {
|
||||
// we can't continue with this tool
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
getLogger().debug("Filling tool properties into context");
|
||||
fillToolProperties(newContext, distribution);
|
||||
newContext.putAll(tool.getExtraProperties());
|
||||
return newContext;
|
||||
}
|
||||
|
||||
protected void fillProjectProperties(Map<String, Object> context, Project project) {
|
||||
context.put(Constants.KEY_PROJECT_NAME, project.getName());
|
||||
context.put(Constants.KEY_PROJECT_NAME_CAPITALIZED, getClassNameForLowerCaseHyphenSeparatedName(project.getName()));
|
||||
context.put(Constants.KEY_PROJECT_VERSION, project.getVersion());
|
||||
context.put(Constants.KEY_PROJECT_DESCRIPTION, project.getDescription());
|
||||
context.put(Constants.KEY_PROJECT_LONG_DESCRIPTION, project.getLongDescription());
|
||||
context.put(Constants.KEY_PROJECT_WEBSITE, project.getWebsite());
|
||||
context.put(Constants.KEY_PROJECT_LICENSE, project.getLicense());
|
||||
context.put(Constants.KEY_JAVA_VERSION, project.getJavaVersion());
|
||||
context.put(Constants.KEY_PROJECT_AUTHORS_BY_SPACE, String.join(" ", project.getAuthors()));
|
||||
context.put(Constants.KEY_PROJECT_AUTHORS_BY_COMMA, String.join(",", project.getAuthors()));
|
||||
context.put(Constants.KEY_PROJECT_TAGS_BY_SPACE, String.join(" ", project.getTags()));
|
||||
context.put(Constants.KEY_PROJECT_TAGS_BY_COMMA, String.join(",", project.getTags()));
|
||||
context.putAll(project.getExtraProperties());
|
||||
}
|
||||
|
||||
protected void fillReleaseProperties(Map<String, Object> context, Release release) {
|
||||
context.put(Constants.KEY_REPO_HOST, release.getRepoHost());
|
||||
context.put(Constants.KEY_REPO_OWNER, release.getRepoOwner());
|
||||
context.put(Constants.KEY_REPO_NAME, release.getRepoName());
|
||||
}
|
||||
|
||||
protected void fillDistributionProperties(Map<String, Object> context, Distribution distribution, Release release) {
|
||||
context.put(Constants.KEY_DISTRIBUTION_NAME, distribution.getName());
|
||||
context.put(Constants.KEY_DISTRIBUTION_EXECUTABLE, distribution.getExecutable());
|
||||
context.put(Constants.KEY_DISTRIBUTION_TAGS_BY_SPACE, String.join(" ", distribution.getTags()));
|
||||
context.put(Constants.KEY_DISTRIBUTION_TAGS_BY_COMMA, String.join(",", distribution.getTags()));
|
||||
context.put(Constants.KEY_DISTRIBUTION_RELEASE_NOTES, applyTemplate(new StringReader(release.getReleaseNotesUrlFormat()), context));
|
||||
context.put(Constants.KEY_DISTRIBUTION_ISSUE_TRACKER, applyTemplate(new StringReader(release.getIssueTrackerUrlFormat()), context));
|
||||
context.put(Constants.KEY_DISTRIBUTION_LATEST_RELEASE, applyTemplate(new StringReader(release.getLatestReleaseUrlFormat()), context));
|
||||
context.putAll(distribution.getExtraProperties());
|
||||
}
|
||||
|
||||
protected abstract void fillToolProperties(Map<String, Object> context, Distribution distribution) throws ToolProcessingException;
|
||||
|
||||
protected boolean executeCommand(List<String> cmd) throws ToolProcessingException {
|
||||
try {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
ByteArrayOutputStream err = new ByteArrayOutputStream();
|
||||
|
||||
int exitValue = new ProcessExecutor(cmd)
|
||||
.redirectOutput(out)
|
||||
.redirectError(err)
|
||||
.execute()
|
||||
.getExitValue();
|
||||
|
||||
info(out);
|
||||
error(err);
|
||||
|
||||
if (exitValue == 0) return true;
|
||||
throw new ToolProcessingException("Command execution error. exitValue = " + exitValue);
|
||||
} catch (Exception e) {
|
||||
if (e instanceof ToolProcessingException) {
|
||||
throw (ToolProcessingException) e;
|
||||
}
|
||||
throw new ToolProcessingException("Unexpected error", e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean verifyAndAddArtifacts(Map<String, Object> context,
|
||||
Distribution distribution) throws ToolProcessingException {
|
||||
Set<String> fileExtensions = resolveByExtensionsFor(distribution.getType());
|
||||
List<Artifact> artifacts = distribution.getArtifacts().stream()
|
||||
.filter(artifact -> fileExtensions.stream().anyMatch(ext -> artifact.getPath().endsWith(ext)))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (artifacts.size() == 0) {
|
||||
// we can't proceed
|
||||
logger.warn("No suitable artifacts found in distribution {} to be packaged with {}",
|
||||
distribution.getName(), capitalize(tool.getToolName()));
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < artifacts.size(); i++) {
|
||||
Artifact artifact = artifacts.get(i);
|
||||
String classifier = isNotBlank(artifact.getOsClassifier()) ? capitalize(artifact.getOsClassifier()) : "";
|
||||
String artifactFileName = Paths.get(artifact.getPath()).getFileName().toString();
|
||||
context.put("artifact" + classifier + "JavaVersion", artifact.getJavaVersion());
|
||||
context.put("artifact" + classifier + "FileName", artifactFileName);
|
||||
context.put("artifact" + classifier + "Hash", artifact.getHash());
|
||||
Map<String, Object> newContext = new LinkedHashMap<>(context);
|
||||
newContext.put("artifactFileName", artifactFileName);
|
||||
String artifactUrl = applyTemplate(new StringReader(model.getRelease().getDownloadUrlFormat()), newContext, "downloadUrl");
|
||||
context.put("artifact" + classifier + "Url", artifactUrl);
|
||||
|
||||
if (0 == i) {
|
||||
context.put(Constants.KEY_DISTRIBUTION_URL, artifactUrl);
|
||||
context.put(Constants.KEY_DISTRIBUTION_SHA_256, artifact.getHash());
|
||||
context.put(Constants.KEY_DISTRIBUTION_JAVA_VERSION, artifact.getJavaVersion());
|
||||
context.put(Constants.KEY_DISTRIBUTION_FILE_NAME, artifactFileName);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected abstract Set<String> resolveByExtensionsFor(Distribution.DistributionType type);
|
||||
|
||||
protected void info(ByteArrayOutputStream out) {
|
||||
log(out, logger::info);
|
||||
}
|
||||
|
||||
protected void error(ByteArrayOutputStream err) {
|
||||
log(err, logger::error);
|
||||
}
|
||||
|
||||
private void log(ByteArrayOutputStream stream, Consumer<? super String> consumer) {
|
||||
String str = stream.toString();
|
||||
if (isBlank(str)) return;
|
||||
|
||||
Arrays.stream(str.split(System.lineSeparator()))
|
||||
.forEach(consumer);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.tools;
|
||||
|
||||
import org.kordamp.jreleaser.model.Brew;
|
||||
import org.kordamp.jreleaser.model.Distribution;
|
||||
import org.kordamp.jreleaser.model.JReleaserModel;
|
||||
import org.kordamp.jreleaser.model.Project;
|
||||
import org.kordamp.jreleaser.util.Logger;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.kordamp.jreleaser.templates.TemplateUtils.trimTplExtension;
|
||||
import static org.kordamp.jreleaser.util.StringUtils.isNotBlank;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class BrewToolProcessor extends AbstractToolProcessor<Brew> {
|
||||
public BrewToolProcessor(Logger logger, JReleaserModel model, Brew brew) {
|
||||
super(logger, model, brew);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doPackageDistribution(Distribution distribution, Map<String, Object> context) throws ToolProcessingException {
|
||||
getLogger().debug("Tool {} does not require additional packaging", getToolName());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<String> resolveByExtensionsFor(Distribution.DistributionType type) {
|
||||
Set<String> set = new LinkedHashSet<>();
|
||||
set.add(".zip");
|
||||
return set;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillToolProperties(Map<String, Object> context, Distribution distribution) throws ToolProcessingException {
|
||||
if (!getTool().getDependencies().containsKey(Constants.KEY_JAVA_VERSION)) {
|
||||
getTool().getDependencies().put(":java", (String) context.get(Constants.KEY_DISTRIBUTION_JAVA_VERSION));
|
||||
}
|
||||
|
||||
context.put(Constants.KEY_BREW_DEPENDENCIES, getTool().getDependencies()
|
||||
.entrySet().stream()
|
||||
.map(entry -> new Dependency(entry.getKey(), entry.getValue()))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeFile(Project project, Distribution distribution, String content, Map<String, Object> context, String fileName)
|
||||
throws ToolProcessingException {
|
||||
fileName = trimTplExtension(fileName);
|
||||
|
||||
Path outputDirectory = (Path) context.get(Constants.KEY_PREPARE_DIRECTORY);
|
||||
Path outputFile = "formula.rb".equals(fileName) ?
|
||||
outputDirectory.resolve("Formula").resolve(distribution.getExecutable().concat(".rb")) :
|
||||
outputDirectory.resolve(fileName);
|
||||
|
||||
writeFile(content, outputFile);
|
||||
}
|
||||
|
||||
public static class Dependency {
|
||||
private final String key;
|
||||
private final String value;
|
||||
|
||||
public Dependency(String key, String value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getFormattedDependency() {
|
||||
StringBuilder formatted = new StringBuilder();
|
||||
if (key.startsWith(":")) {
|
||||
formatted.append(key);
|
||||
} else {
|
||||
formatted.append("\"")
|
||||
.append(key)
|
||||
.append("\"");
|
||||
}
|
||||
if (isNotBlank(value)) {
|
||||
formatted.append(" => \"")
|
||||
.append(value)
|
||||
.append("\"");
|
||||
}
|
||||
return "!!" + formatted.toString() + "!!";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.tools;
|
||||
|
||||
import org.kordamp.jreleaser.model.Chocolatey;
|
||||
import org.kordamp.jreleaser.model.Distribution;
|
||||
import org.kordamp.jreleaser.model.JReleaserModel;
|
||||
import org.kordamp.jreleaser.model.Project;
|
||||
import org.kordamp.jreleaser.util.Logger;
|
||||
import org.kordamp.jreleaser.util.OsUtils;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.kordamp.jreleaser.templates.TemplateUtils.trimTplExtension;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class ChocolateyToolProcessor extends AbstractToolProcessor<Chocolatey> {
|
||||
public ChocolateyToolProcessor(Logger logger, JReleaserModel model, Chocolatey tool) {
|
||||
super(logger, model, tool);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doPackageDistribution(Distribution distribution, Map<String, Object> context) throws ToolProcessingException {
|
||||
if (!OsUtils.isWindows()) {
|
||||
getLogger().debug("Tool {} must run on Windows", getToolName());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<String> resolveByExtensionsFor(Distribution.DistributionType type) {
|
||||
Set<String> set = new LinkedHashSet<>();
|
||||
set.add(".zip");
|
||||
return set;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillToolProperties(Map<String, Object> context, Distribution distribution) throws ToolProcessingException {
|
||||
// noop
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeFile(Project project, Distribution distribution, String content, Map<String, Object> context, String fileName)
|
||||
throws ToolProcessingException {
|
||||
fileName = trimTplExtension(fileName);
|
||||
|
||||
Path outputDirectory = (Path) context.get(Constants.KEY_PREPARE_DIRECTORY);
|
||||
Path outputFile = "binary.nuspec".equals(fileName) ?
|
||||
outputDirectory.resolve(distribution.getExecutable().concat(".nuspec")) :
|
||||
outputDirectory.resolve(fileName);
|
||||
|
||||
writeFile(content, outputFile);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.tools;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public interface Constants {
|
||||
// General
|
||||
String KEY_JAVA_VERSION = "javaVersion";
|
||||
|
||||
// Project
|
||||
String KEY_PROJECT_NAME = "projectName";
|
||||
String KEY_PROJECT_NAME_CAPITALIZED = "projectNameCapitalized";
|
||||
String KEY_PROJECT_VERSION = "projectVersion";
|
||||
String KEY_PROJECT_DESCRIPTION = "projectDescription";
|
||||
String KEY_PROJECT_LONG_DESCRIPTION = "projectLongDescription";
|
||||
String KEY_PROJECT_WEBSITE = "projectWebsite";
|
||||
String KEY_PROJECT_LICENSE = "projectLicense";
|
||||
String KEY_PROJECT_AUTHORS_BY_SPACE = "projectAuthorsBySpace";
|
||||
String KEY_PROJECT_AUTHORS_BY_COMMA = "projectAuthorsByComma";
|
||||
String KEY_PROJECT_TAGS_BY_SPACE = "projectTagsBySpace";
|
||||
String KEY_PROJECT_TAGS_BY_COMMA = "projectTagsByComma";
|
||||
|
||||
// Release
|
||||
String KEY_REPO_HOST = "repoHost";
|
||||
String KEY_REPO_OWNER = "repoOwner";
|
||||
String KEY_REPO_NAME = "repoName";
|
||||
|
||||
// Distribution
|
||||
String KEY_DISTRIBUTION_NAME = "distributionName";
|
||||
String KEY_DISTRIBUTION_EXECUTABLE = "distributionExecutable";
|
||||
String KEY_DISTRIBUTION_TAGS_BY_SPACE = "distributionTagsBySpace";
|
||||
String KEY_DISTRIBUTION_TAGS_BY_COMMA = "distributionTagsByComma";
|
||||
String KEY_DISTRIBUTION_RELEASE_NOTES = "distributionReleaseNotes";
|
||||
String KEY_DISTRIBUTION_ISSUE_TRACKER = "distributionIssueTracker";
|
||||
String KEY_DISTRIBUTION_LATEST_RELEASE = "distributionLatestRelease";
|
||||
String KEY_DISTRIBUTION_JAVA_VERSION = "distributionJavaVersion";
|
||||
String KEY_DISTRIBUTION_URL = "distributionUrl";
|
||||
String KEY_DISTRIBUTION_SHA_256 = "distributionSha256";
|
||||
String KEY_DISTRIBUTION_FILE_NAME = "distributionFileName";
|
||||
|
||||
// Artifact
|
||||
String KEY_ARTIFACT_FILE_NAME = "artifactFileName";
|
||||
|
||||
// Brew
|
||||
String KEY_BREW_DEPENDENCIES = "brewDependencies";
|
||||
|
||||
// Scoop
|
||||
String KEY_SCOOP_CHECKVER_URL = "scoopCheckverUrl";
|
||||
String KEY_SCOOP_AUTOUPDATE_URL = "scoopAutoupdateUrl";
|
||||
|
||||
// Snap
|
||||
String KEY_SNAP_BASE = "snapBase";
|
||||
String KEY_SNAP_GRADE = "snapGrade";
|
||||
String KEY_SNAP_CONFINEMENT = "snapConfinement";
|
||||
String KEY_SNAP_HAS_PLUGS = "snapHasPlugs";
|
||||
String KEY_SNAP_PLUGS = "snapPlugs";
|
||||
String KEY_SNAP_HAS_SLOTS = "snapHasSlots";
|
||||
String KEY_SNAP_SLOTS = "snapSlots";
|
||||
String KEY_SNAP_HAS_LOCAL_PLUGS = "snapHasLocalPlugs";
|
||||
String KEY_SNAP_LOCAL_PLUGS = "snapLocalPlugs";
|
||||
|
||||
// ToolProcessor
|
||||
String KEY_CHECKSUM_DIRECTORY = "__CHECKSUM_DIRECTORY__";
|
||||
String KEY_OUTPUT_DIRECTORY = "__OUTPUT_DIRECTORY__";
|
||||
String KEY_PREPARE_DIRECTORY = "__PREPARE_DIRECTORY__";
|
||||
String KEY_PACKAGE_DIRECTORY = "__PACKAGE_DIRECTORY__";
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.tools;
|
||||
|
||||
import org.kordamp.jreleaser.model.Artifact;
|
||||
import org.kordamp.jreleaser.model.Distribution;
|
||||
import org.kordamp.jreleaser.model.JReleaserModel;
|
||||
import org.kordamp.jreleaser.model.Tool;
|
||||
import org.kordamp.jreleaser.util.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static org.kordamp.jreleaser.util.StringUtils.requireNonBlank;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class DistributionProcessor {
|
||||
private final Logger logger;
|
||||
private final JReleaserModel model;
|
||||
private final String distributionName;
|
||||
private final String toolName;
|
||||
private final Path checksumDirectory;
|
||||
private final Path outputDirectory;
|
||||
|
||||
private DistributionProcessor(Logger logger,
|
||||
JReleaserModel model,
|
||||
String distributionName,
|
||||
String toolName,
|
||||
Path checksumDirectory,
|
||||
Path outputDirectory) {
|
||||
this.logger = logger;
|
||||
this.model = model;
|
||||
this.distributionName = distributionName;
|
||||
this.toolName = toolName;
|
||||
this.checksumDirectory = checksumDirectory;
|
||||
this.outputDirectory = outputDirectory;
|
||||
}
|
||||
|
||||
public JReleaserModel getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
public String getDistributionName() {
|
||||
return distributionName;
|
||||
}
|
||||
|
||||
public String getToolName() {
|
||||
return toolName;
|
||||
}
|
||||
|
||||
public Path getChecksumDirectory() {
|
||||
return checksumDirectory;
|
||||
}
|
||||
|
||||
public Path getOutputDirectory() {
|
||||
return outputDirectory;
|
||||
}
|
||||
|
||||
public boolean prepareDistribution() throws ToolProcessingException {
|
||||
Distribution distribution = model.findDistribution(distributionName);
|
||||
Tool tool = distribution.getTool(toolName);
|
||||
if (!tool.isEnabled()) {
|
||||
logger.warn("Skipping {} tool for {} distribution", toolName, distributionName);
|
||||
return false;
|
||||
}
|
||||
|
||||
logger.info("Preparing {} distribution with tool {}", distributionName, toolName);
|
||||
|
||||
Map<String, Object> context = new LinkedHashMap<>();
|
||||
context.put(Constants.KEY_CHECKSUM_DIRECTORY, checksumDirectory);
|
||||
context.put(Constants.KEY_OUTPUT_DIRECTORY, outputDirectory);
|
||||
context.put(Constants.KEY_PREPARE_DIRECTORY, outputDirectory.resolve("prepare"));
|
||||
|
||||
logger.debug("Reading checksums for {} distribution", distributionName);
|
||||
for (int i = 0; i < distribution.getArtifacts().size(); i++) {
|
||||
Artifact artifact = distribution.getArtifacts().get(i);
|
||||
readHash(artifact, checksumDirectory);
|
||||
}
|
||||
|
||||
ToolProcessor<?> toolProcessor = ToolProcessors.findProcessor(logger, model, tool);
|
||||
return toolProcessor.prepareDistribution(distribution, context);
|
||||
}
|
||||
|
||||
public boolean packageDistribution() throws ToolProcessingException {
|
||||
Distribution distribution = model.findDistribution(distributionName);
|
||||
Tool tool = distribution.getTool(toolName);
|
||||
if (!tool.isEnabled()) {
|
||||
logger.warn("Skipping {} tool for {} distribution", toolName, distributionName);
|
||||
return false;
|
||||
}
|
||||
|
||||
logger.info("Packaging {} distribution with tool {}", distributionName, toolName);
|
||||
|
||||
Map<String, Object> context = new LinkedHashMap<>();
|
||||
context.put(Constants.KEY_OUTPUT_DIRECTORY, outputDirectory);
|
||||
context.put(Constants.KEY_PREPARE_DIRECTORY, outputDirectory.resolve("prepare"));
|
||||
context.put(Constants.KEY_PACKAGE_DIRECTORY, outputDirectory.resolve("package"));
|
||||
|
||||
ToolProcessor<?> toolProcessor = ToolProcessors.findProcessor(logger, model, tool);
|
||||
return toolProcessor.packageDistribution(distribution, context);
|
||||
}
|
||||
|
||||
private void readHash(Artifact artifact, Path checksumDirectory) throws ToolProcessingException {
|
||||
Path artifactPath = Paths.get(artifact.getPath());
|
||||
Path checksumPath = checksumDirectory.resolve(artifactPath.getFileName() + ".sha256");
|
||||
|
||||
if (!artifactPath.toFile().exists()) {
|
||||
throw new ToolProcessingException("Artifact does not exist. " + artifactPath.toAbsolutePath());
|
||||
}
|
||||
|
||||
if (!checksumPath.toFile().exists()) {
|
||||
throw new ToolProcessingException("Artifact checksum does not exist. " + checksumPath.toAbsolutePath());
|
||||
}
|
||||
|
||||
try {
|
||||
logger.debug("Reading checksum for {} from {}", artifactPath.toAbsolutePath(), checksumPath.toAbsolutePath());
|
||||
artifact.setHash(new String(Files.readAllBytes(checksumPath)));
|
||||
} catch (IOException e) {
|
||||
throw new ToolProcessingException("Unexpected error when reading hash from " + checksumPath.toAbsolutePath(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public static DistributionProcessorBuilder builder() {
|
||||
return new DistributionProcessorBuilder();
|
||||
}
|
||||
|
||||
public static class DistributionProcessorBuilder {
|
||||
private Logger logger;
|
||||
private JReleaserModel model;
|
||||
private String distributionName;
|
||||
private String toolName;
|
||||
private Path checksumDirectory;
|
||||
private Path outputDirectory;
|
||||
|
||||
public DistributionProcessorBuilder logger(Logger logger) {
|
||||
this.logger = requireNonNull(logger, "'logger' must not be null");
|
||||
return this;
|
||||
}
|
||||
|
||||
public DistributionProcessorBuilder model(JReleaserModel model) {
|
||||
this.model = requireNonNull(model, "'model' must not be null");
|
||||
return this;
|
||||
}
|
||||
|
||||
public DistributionProcessorBuilder distributionName(String distributionName) {
|
||||
this.distributionName = requireNonBlank(distributionName, "'distributionName' must not be blank");
|
||||
return this;
|
||||
}
|
||||
|
||||
public DistributionProcessorBuilder toolName(String toolName) {
|
||||
this.toolName = requireNonBlank(toolName, "'toolName' must not be blank");
|
||||
return this;
|
||||
}
|
||||
|
||||
public DistributionProcessorBuilder checksumDirectory(Path checksumDirectory) {
|
||||
this.checksumDirectory = requireNonNull(checksumDirectory, "'checksumDirectory' must not be null");
|
||||
return this;
|
||||
}
|
||||
|
||||
public DistributionProcessorBuilder outputDirectory(Path outputDirectory) {
|
||||
this.outputDirectory = requireNonNull(outputDirectory, "'outputDirectory' must not be null");
|
||||
return this;
|
||||
}
|
||||
|
||||
public DistributionProcessor build() {
|
||||
requireNonNull(logger, "'logger' must not be null");
|
||||
requireNonNull(model, "'model' must not be null");
|
||||
requireNonBlank(distributionName, "'distributionName' must not be blank");
|
||||
requireNonBlank(toolName, "'toolName' must not be blank");
|
||||
requireNonNull(checksumDirectory, "'checksumDirectory' must not be null");
|
||||
requireNonNull(outputDirectory, "'outputDirectory' must not be null");
|
||||
return new DistributionProcessor(logger, model, distributionName, toolName, checksumDirectory, outputDirectory);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.tools;
|
||||
|
||||
import com.github.mustachejava.DefaultMustacheFactory;
|
||||
import com.github.mustachejava.Mustache;
|
||||
import com.github.mustachejava.MustacheException;
|
||||
import com.github.mustachejava.MustacheFactory;
|
||||
import org.kordamp.jreleaser.model.Artifact;
|
||||
import org.kordamp.jreleaser.model.Distribution;
|
||||
import org.kordamp.jreleaser.model.JReleaserModel;
|
||||
import org.kordamp.jreleaser.model.Tool;
|
||||
import org.kordamp.jreleaser.util.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.kordamp.jreleaser.util.StringUtils.capitalize;
|
||||
import static org.kordamp.jreleaser.util.StringUtils.isNotBlank;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
final class ProcessorUtils {
|
||||
private ProcessorUtils() {
|
||||
//noop
|
||||
}
|
||||
|
||||
static <T extends Tool> boolean verifyAndAddArtifacts(Logger logger,
|
||||
Map<String, Object> context,
|
||||
JReleaserModel model,
|
||||
Distribution distribution,
|
||||
String artifactExtension,
|
||||
T tool) throws ToolProcessingException {
|
||||
List<Artifact> artifacts = distribution.getArtifacts().stream()
|
||||
.filter(artifact -> artifact.getPath().endsWith(artifactExtension))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (artifacts.size() == 0) {
|
||||
// we can't proceed
|
||||
logger.warn("No suitable {} artifacts found in distribution {} to be packaged with ",
|
||||
artifactExtension, distribution.getName(), capitalize(tool.getToolName()));
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < artifacts.size(); i++) {
|
||||
Artifact artifact = artifacts.get(i);
|
||||
String classifier = isNotBlank(artifact.getOsClassifier()) ? capitalize(artifact.getOsClassifier()) : "";
|
||||
String artifactFileName = Paths.get(artifact.getPath()).getFileName().toString();
|
||||
context.put("artifact" + classifier + "JavaVersion", artifact.getJavaVersion());
|
||||
context.put("artifact" + classifier + "FileName", artifactFileName);
|
||||
context.put("artifact" + classifier + "Hash", artifact.getHash());
|
||||
Map<String, Object> newContext = new LinkedHashMap<>(context);
|
||||
newContext.put("artifactFileName", artifactFileName);
|
||||
String artifactUrl = applyTemplate(new StringReader(model.getRelease().getDownloadUrlFormat()), newContext, "downloadUrl");
|
||||
context.put("artifact" + classifier + "Url", artifactUrl);
|
||||
|
||||
if (0 == i) {
|
||||
context.put("distributionUrl", artifactUrl);
|
||||
context.put("distributionSha256", artifact.getHash());
|
||||
context.put("distributionJavaVersion", artifact.getJavaVersion());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static String applyTemplate(Reader reader, Map<String, Object> context, String toolName) {
|
||||
StringWriter input = new StringWriter();
|
||||
MustacheFactory mf = new MyMustacheFactory();
|
||||
Mustache mustache = mf.compile(reader, toolName);
|
||||
mustache.execute(input, context);
|
||||
input.flush();
|
||||
return input.toString();
|
||||
}
|
||||
|
||||
static String applyTemplate(Reader reader, Map<String, Object> context) {
|
||||
return applyTemplate(reader, context, UUID.randomUUID().toString());
|
||||
}
|
||||
|
||||
private static class MyMustacheFactory extends DefaultMustacheFactory {
|
||||
@Override
|
||||
public void encode(String value, Writer writer) {
|
||||
if (value.startsWith("!!") && value.endsWith("!!")) {
|
||||
try {
|
||||
writer.write(value.substring(2, value.length() - 2));
|
||||
} catch (IOException e) {
|
||||
throw new MustacheException("Failed to write value: " + value, e);
|
||||
}
|
||||
} else {
|
||||
super.encode(value, writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.tools;
|
||||
|
||||
import org.kordamp.jreleaser.model.Distribution;
|
||||
import org.kordamp.jreleaser.model.JReleaserModel;
|
||||
import org.kordamp.jreleaser.model.Project;
|
||||
import org.kordamp.jreleaser.model.Scoop;
|
||||
import org.kordamp.jreleaser.util.Logger;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.nio.file.Path;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.kordamp.jreleaser.templates.TemplateUtils.trimTplExtension;
|
||||
import static org.kordamp.jreleaser.tools.ProcessorUtils.applyTemplate;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class ScoopToolProcessor extends AbstractToolProcessor<Scoop> {
|
||||
public ScoopToolProcessor(Logger logger, JReleaserModel model, Scoop scoop) {
|
||||
super(logger, model, scoop);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doPackageDistribution(Distribution distribution, Map<String, Object> context) throws ToolProcessingException {
|
||||
getLogger().debug("Tool {} does not require additional packaging", getToolName());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<String> resolveByExtensionsFor(Distribution.DistributionType type) {
|
||||
Set<String> set = new LinkedHashSet<>();
|
||||
set.add(".zip");
|
||||
return set;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillToolProperties(Map<String, Object> context, Distribution distribution) throws ToolProcessingException {
|
||||
context.put(Constants.KEY_SCOOP_CHECKVER_URL, resolveCheckverUrl(context));
|
||||
context.put(Constants.KEY_SCOOP_AUTOUPDATE_URL, resolveAutoupdateUrl(context));
|
||||
}
|
||||
|
||||
private Object resolveCheckverUrl(Map<String, Object> context) {
|
||||
if (!getTool().getCheckverUrl().contains("{{")) {
|
||||
return getTool().getCheckverUrl();
|
||||
}
|
||||
return applyTemplate(new StringReader(getTool().getCheckverUrl()), context);
|
||||
}
|
||||
|
||||
private Object resolveAutoupdateUrl(Map<String, Object> context) {
|
||||
if (!getTool().getAutoupdateUrl().contains("{{")) {
|
||||
return getTool().getAutoupdateUrl();
|
||||
}
|
||||
|
||||
Map<String, Object> copy = new LinkedHashMap<>(context);
|
||||
copy.put(Constants.KEY_PROJECT_VERSION, "$version");
|
||||
copy.put(Constants.KEY_ARTIFACT_FILE_NAME, copy.get("projectName") + "-$version.zip");
|
||||
return applyTemplate(new StringReader(getTool().getAutoupdateUrl()), copy);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeFile(Project project, Distribution distribution, String content, Map<String, Object> context, String fileName)
|
||||
throws ToolProcessingException {
|
||||
Path outputDirectory = (Path) context.get(Constants.KEY_PREPARE_DIRECTORY);
|
||||
Path outputFile = outputDirectory.resolve(trimTplExtension(fileName));
|
||||
|
||||
writeFile(content, outputFile);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.tools;
|
||||
|
||||
import org.kordamp.jreleaser.model.Distribution;
|
||||
import org.kordamp.jreleaser.model.JReleaserModel;
|
||||
import org.kordamp.jreleaser.model.Project;
|
||||
import org.kordamp.jreleaser.model.Snap;
|
||||
import org.kordamp.jreleaser.util.FileUtils;
|
||||
import org.kordamp.jreleaser.util.Logger;
|
||||
import org.kordamp.jreleaser.util.OsUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
|
||||
import static org.kordamp.jreleaser.templates.TemplateUtils.trimTplExtension;
|
||||
import static org.kordamp.jreleaser.util.FileUtils.createDirectoriesWithFullAccess;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class SnapToolProcessor extends AbstractToolProcessor<Snap> {
|
||||
public SnapToolProcessor(Logger logger, JReleaserModel model, Snap snap) {
|
||||
super(logger, model, snap);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doPackageDistribution(Distribution distribution, Map<String, Object> context) throws ToolProcessingException {
|
||||
if (OsUtils.isWindows()) {
|
||||
getLogger().debug("Tool {} must not run on Windows", getToolName());
|
||||
return false;
|
||||
}
|
||||
|
||||
Path primeDirectory = createPackage(context);
|
||||
|
||||
if (!login(distribution, context)) {
|
||||
getLogger().error("Could not log into snapcraft store");
|
||||
return false;
|
||||
}
|
||||
|
||||
return createSnap(distribution, context, primeDirectory);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<String> resolveByExtensionsFor(Distribution.DistributionType type) {
|
||||
Set<String> set = new LinkedHashSet<>();
|
||||
if (type == Distribution.DistributionType.BINARY) {
|
||||
set.add(".tar.gz");
|
||||
set.add(".tar");
|
||||
} else if (type == Distribution.DistributionType.SINGLE_JAR) {
|
||||
set.add(".jar");
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillToolProperties(Map<String, Object> context, Distribution distribution) throws ToolProcessingException {
|
||||
context.put(Constants.KEY_SNAP_BASE, getTool().getBase());
|
||||
context.put(Constants.KEY_SNAP_GRADE, getTool().getGrade());
|
||||
context.put(Constants.KEY_SNAP_CONFINEMENT, getTool().getConfinement());
|
||||
context.put(Constants.KEY_SNAP_HAS_PLUGS, !getTool().getPlugs().isEmpty());
|
||||
context.put(Constants.KEY_SNAP_PLUGS, getTool().getPlugs());
|
||||
context.put(Constants.KEY_SNAP_HAS_SLOTS, !getTool().getSlots().isEmpty());
|
||||
context.put(Constants.KEY_SNAP_SLOTS, getTool().getSlots());
|
||||
context.put(Constants.KEY_SNAP_HAS_LOCAL_PLUGS, !getTool().getLocalPlugs().isEmpty());
|
||||
context.put(Constants.KEY_SNAP_LOCAL_PLUGS, getTool().getLocalPlugs());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeFile(Project project, Distribution distribution, String content, Map<String, Object> context, String fileName)
|
||||
throws ToolProcessingException {
|
||||
fileName = trimTplExtension(fileName);
|
||||
|
||||
Path outputDirectory = (Path) context.get(Constants.KEY_PREPARE_DIRECTORY);
|
||||
Path outputFile = outputDirectory.resolve(fileName);
|
||||
|
||||
writeFile(content, outputFile);
|
||||
}
|
||||
|
||||
private Path createPackage(Map<String, Object> context) throws ToolProcessingException {
|
||||
try {
|
||||
Path prepareDirectory = (Path) context.get(Constants.KEY_PREPARE_DIRECTORY);
|
||||
Path snapDirectory = prepareDirectory.resolve("snap");
|
||||
Path packageDirectory = (Path) context.get(Constants.KEY_PACKAGE_DIRECTORY);
|
||||
Path primeDirectory = packageDirectory.resolve("prime");
|
||||
Path metaDirectory = primeDirectory.resolve("meta");
|
||||
createDirectoriesWithFullAccess(metaDirectory);
|
||||
if (FileUtils.copyFiles(getLogger(), snapDirectory, metaDirectory)) {
|
||||
Files.move(metaDirectory.resolve("snapcraft.yaml"),
|
||||
metaDirectory.resolve("snap.yaml"),
|
||||
REPLACE_EXISTING);
|
||||
return primeDirectory;
|
||||
} else {
|
||||
throw new ToolProcessingException("Could not copy files from " +
|
||||
prepareDirectory.toAbsolutePath().toString() + " to " +
|
||||
metaDirectory.toAbsolutePath().toString());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new ToolProcessingException("Unexpected error when creating package", e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean login(Distribution distribution, Map<String, Object> context) throws ToolProcessingException {
|
||||
List<String> cmd = new ArrayList<>();
|
||||
cmd.add("snapcraft");
|
||||
cmd.add("login");
|
||||
cmd.add("--with");
|
||||
cmd.add(distribution.getSnap().getExportedLogin());
|
||||
return executeCommand(cmd);
|
||||
}
|
||||
|
||||
private boolean createSnap(Distribution distribution, Map<String, Object> context, Path primeDirectory) throws ToolProcessingException {
|
||||
Path packageDirectory = (Path) context.get(Constants.KEY_PACKAGE_DIRECTORY);
|
||||
String version = (String) context.get(Constants.KEY_PROJECT_VERSION);
|
||||
String snapName = distribution.getName() + "-" + version + ".snap";
|
||||
|
||||
List<String> cmd = new ArrayList<>();
|
||||
cmd.add("snapcraft");
|
||||
cmd.add("snap");
|
||||
cmd.add(primeDirectory.toAbsolutePath().toString());
|
||||
cmd.add("--output");
|
||||
cmd.add(packageDirectory.resolve(snapName).toAbsolutePath().toString());
|
||||
return executeCommand(cmd);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.tools;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class ToolProcessingException extends Exception {
|
||||
public ToolProcessingException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ToolProcessingException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public ToolProcessingException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.tools;
|
||||
|
||||
import org.kordamp.jreleaser.model.Distribution;
|
||||
import org.kordamp.jreleaser.model.JReleaserModel;
|
||||
import org.kordamp.jreleaser.model.Tool;
|
||||
import org.kordamp.jreleaser.util.Logger;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public interface ToolProcessor<T extends Tool> {
|
||||
T getTool();
|
||||
|
||||
String getToolName();
|
||||
|
||||
Logger getLogger();
|
||||
|
||||
JReleaserModel getModel();
|
||||
|
||||
boolean prepareDistribution(Distribution distribution, Map<String, Object> context) throws ToolProcessingException;
|
||||
|
||||
boolean packageDistribution(Distribution distribution, Map<String, Object> context) throws ToolProcessingException;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.tools;
|
||||
|
||||
import org.kordamp.jreleaser.model.Brew;
|
||||
import org.kordamp.jreleaser.model.Chocolatey;
|
||||
import org.kordamp.jreleaser.model.JReleaserModel;
|
||||
import org.kordamp.jreleaser.model.Scoop;
|
||||
import org.kordamp.jreleaser.model.Snap;
|
||||
import org.kordamp.jreleaser.model.Tool;
|
||||
import org.kordamp.jreleaser.util.Logger;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class ToolProcessors {
|
||||
public static <T extends Tool> ToolProcessor<T> findProcessor(Logger logger, JReleaserModel model, T tool) {
|
||||
if (tool instanceof Brew) {
|
||||
return (ToolProcessor<T>) new BrewToolProcessor(logger, model, (Brew) tool);
|
||||
} else if (tool instanceof Chocolatey) {
|
||||
return (ToolProcessor<T>) new ChocolateyToolProcessor(logger, model, (Chocolatey) tool);
|
||||
} else if (tool instanceof Scoop) {
|
||||
return (ToolProcessor<T>) new ScoopToolProcessor(logger, model, (Scoop) tool);
|
||||
} else if (tool instanceof Snap) {
|
||||
return (ToolProcessor<T>) new SnapToolProcessor(logger, model, (Snap) tool);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unsupported tool " + tool);
|
||||
}
|
||||
}
|
||||
26
core/jreleaser-tools/src/main/module/module-info.java
Normal file
26
core/jreleaser-tools/src/main/module/module-info.java
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
module org.kordamp.jreleaser.tools {
|
||||
exports org.kordamp.jreleaser.tools;
|
||||
requires org.kordamp.jreleaser.model;
|
||||
requires org.kordamp.jreleaser.util;
|
||||
requires org.kordamp.jreleaser.templates;
|
||||
requires com.github.mustachejava;
|
||||
requires zt.exec;
|
||||
}
|
||||
19
core/jreleaser-utils/gradle.properties
Normal file
19
core/jreleaser-utils/gradle.properties
Normal file
@@ -0,0 +1,19 @@
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Copyright 2020 Andres Almiray.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
project_description = JReleaser utility classes
|
||||
21
core/jreleaser-utils/jreleaser-utils.gradle
Normal file
21
core/jreleaser-utils/jreleaser-utils.gradle
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
dependencies {
|
||||
api('kr.motd.maven:os-maven-plugin:1.6.2') { transitive = false }
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileAlreadyExistsException;
|
||||
import java.nio.file.FileSystemLoopException;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.FileVisitor;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.nio.file.attribute.FileAttribute;
|
||||
import java.nio.file.attribute.FileTime;
|
||||
import java.nio.file.attribute.PosixFilePermission;
|
||||
import java.nio.file.attribute.PosixFilePermissions;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.nio.file.FileVisitResult.CONTINUE;
|
||||
import static java.nio.file.FileVisitResult.SKIP_SUBTREE;
|
||||
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public final class FileUtils {
|
||||
private FileUtils() {
|
||||
//noop
|
||||
}
|
||||
|
||||
public static void createDirectoriesWithFullAccess(Path path) throws IOException {
|
||||
createDirectories(path, "rwxrwxrwx");
|
||||
}
|
||||
|
||||
public static void createDirectories(Path path, String accessRights) throws IOException {
|
||||
Set<PosixFilePermission> perms = PosixFilePermissions.fromString(accessRights);
|
||||
FileAttribute<Set<PosixFilePermission>> attr = PosixFilePermissions.asFileAttribute(perms);
|
||||
Files.createDirectories(path, attr);
|
||||
}
|
||||
|
||||
public static void grantFullAccess(Path path) throws IOException {
|
||||
grantAccess(path, "rwxrwxrwx");
|
||||
}
|
||||
|
||||
public static void grantAccess(Path path, String accessRights) throws IOException {
|
||||
Set<PosixFilePermission> perms = PosixFilePermissions.fromString(accessRights);
|
||||
Files.setPosixFilePermissions(path, perms);
|
||||
}
|
||||
|
||||
public static boolean copyFiles(Logger logger, Path source, Path target) throws IOException {
|
||||
FileTreeCopy copier = new FileTreeCopy(logger, source, target);
|
||||
Files.walkFileTree(source, copier);
|
||||
return copier.isSuccessful();
|
||||
}
|
||||
|
||||
private static class FileTreeCopy implements FileVisitor<Path> {
|
||||
private final Logger logger;
|
||||
private final Path source;
|
||||
private final Path target;
|
||||
private boolean success = true;
|
||||
|
||||
FileTreeCopy(Logger logger, Path source, Path target) {
|
||||
this.logger = logger;
|
||||
this.source = source;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public boolean isSuccessful() {
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
|
||||
Path newdir = target.resolve(source.relativize(dir));
|
||||
try {
|
||||
Files.copy(dir, newdir);
|
||||
FileUtils.grantFullAccess(newdir);
|
||||
} catch (FileAlreadyExistsException ignored) {
|
||||
// noop
|
||||
} catch (IOException e) {
|
||||
logger.error("Unable to create: {}", newdir, e);
|
||||
success = false;
|
||||
return SKIP_SUBTREE;
|
||||
}
|
||||
return CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
|
||||
try {
|
||||
Path newfile = target.resolve(source.relativize(file));
|
||||
Files.copy(file, newfile, REPLACE_EXISTING);
|
||||
FileUtils.grantFullAccess(newfile);
|
||||
} catch (IOException e) {
|
||||
logger.error("Unable to copy: {}", source, e);
|
||||
success = false;
|
||||
}
|
||||
return CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
|
||||
if (exc == null) {
|
||||
Path newdir = target.resolve(source.relativize(dir));
|
||||
try {
|
||||
FileTime time = Files.getLastModifiedTime(dir);
|
||||
Files.setLastModifiedTime(newdir, time);
|
||||
} catch (IOException e) {
|
||||
logger.warn("Unable to copy all attributes to: {}", newdir, e);
|
||||
}
|
||||
}
|
||||
return CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult visitFileFailed(Path file, IOException e) {
|
||||
if (e instanceof FileSystemLoopException) {
|
||||
logger.error("cycle detected: {}", file);
|
||||
} else {
|
||||
logger.error("Unable to copy: {}", file, e);
|
||||
}
|
||||
success = false;
|
||||
return CONTINUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.util;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public interface Logger {
|
||||
void debug(String message);
|
||||
|
||||
void info(String message);
|
||||
|
||||
void warn(String message);
|
||||
|
||||
void error(String message);
|
||||
|
||||
void debug(String message, Object... args);
|
||||
|
||||
void info(String message, Object... args);
|
||||
|
||||
void warn(String message, Object... args);
|
||||
|
||||
void error(String message, Object... args);
|
||||
|
||||
void debug(String message, Throwable throwable);
|
||||
|
||||
void info(String message, Throwable throwable);
|
||||
|
||||
void warn(String message, Throwable throwable);
|
||||
|
||||
void error(String message, Throwable throwable);
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.util;
|
||||
|
||||
import kr.motd.maven.os.Detector;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public final class OsUtils {
|
||||
private static final OsDetector OS_DETECTOR = new OsDetector();
|
||||
|
||||
private OsUtils() {
|
||||
//noop
|
||||
}
|
||||
|
||||
public static boolean isWindows() {
|
||||
return "windows".equals(OS_DETECTOR.get("os.detected.name"));
|
||||
}
|
||||
|
||||
public static boolean isMac() {
|
||||
return "osx".equals(OS_DETECTOR.get("os.detected.name"));
|
||||
}
|
||||
|
||||
public static String getValue(String key) {
|
||||
return OS_DETECTOR.get(key);
|
||||
}
|
||||
|
||||
public static Set<String> keySet() {
|
||||
return OS_DETECTOR.getProperties().keySet();
|
||||
}
|
||||
|
||||
public static Collection<String> values() {
|
||||
return OS_DETECTOR.getProperties().values();
|
||||
}
|
||||
|
||||
public static Set<Map.Entry<String, String>> entrySet() {
|
||||
return OS_DETECTOR.getProperties().entrySet();
|
||||
}
|
||||
|
||||
private static final class OsDetector extends Detector {
|
||||
private final Map<String, String> props = new LinkedHashMap<>();
|
||||
|
||||
private OsDetector() {
|
||||
Properties p = new Properties();
|
||||
p.put("failOnUnknownOS", "false");
|
||||
detect(p, Collections.emptyList());
|
||||
p.stringPropertyNames().forEach(k -> props.put(k, p.getProperty(k)));
|
||||
}
|
||||
|
||||
private Map<String, String> getProperties() {
|
||||
return Collections.unmodifiableMap(props);
|
||||
}
|
||||
|
||||
private String get(String key) {
|
||||
return props.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void log(String message) {
|
||||
// quiet
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void logProperty(String name, String value) {
|
||||
// quiet
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,514 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.kordamp.jreleaser.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class StringUtils {
|
||||
private static final String PROPERTY_SET_PREFIX = "set";
|
||||
private static final String PROPERTY_GET_PREFIX = "get";
|
||||
private static final Pattern GETTER_PATTERN_1 = Pattern.compile("^get[A-Z][\\w]*$");
|
||||
private static final Pattern GETTER_PATTERN_2 = Pattern.compile("^is[A-Z][\\w]*$");
|
||||
private static final Pattern SETTER_PATTERN = Pattern.compile("^set[A-Z][\\w]*$");
|
||||
private static final String ERROR_METHOD_NULL = "Argument 'method' must not be null";
|
||||
|
||||
/**
|
||||
* Capitalizes a String (makes the first char uppercase) taking care
|
||||
* of blank strings and single character strings.
|
||||
*
|
||||
* @param str The String to be capitalized
|
||||
* @return Capitalized version of the target string if it is not blank
|
||||
*/
|
||||
public static String capitalize(String str) {
|
||||
if (isBlank(str)) {
|
||||
return str;
|
||||
}
|
||||
|
||||
if (str.length() == 1) {
|
||||
return str.toUpperCase();
|
||||
}
|
||||
|
||||
return ((String) (str.substring(0, 1).toUpperCase(Locale.ENGLISH) + str.substring(1)));
|
||||
}
|
||||
|
||||
public static String getFilenameExtension(String path) {
|
||||
if (path == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int extIndex = path.lastIndexOf(".");
|
||||
if (extIndex == -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int folderIndex = path.lastIndexOf(File.separator);
|
||||
if (folderIndex > extIndex) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return path.substring(extIndex + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the name of a setter for the specified property name
|
||||
*
|
||||
* @param propertyName The property name
|
||||
* @return The setter equivalent
|
||||
*/
|
||||
public static String getSetterName(String propertyName) {
|
||||
return ((String) (PROPERTY_SET_PREFIX + capitalize(propertyName)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the name for a getter method to retrieve the specified property
|
||||
*
|
||||
* @param propertyName The property name
|
||||
* @return The name for the getter method for this property, if it were to exist, i.e. getConstraints
|
||||
*/
|
||||
public static String getGetterName(String propertyName) {
|
||||
return ((String) (PROPERTY_GET_PREFIX + capitalize(propertyName)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the class name for the given logical name and trailing name. For example "person" and "Controller" would evaluate to "PersonController"
|
||||
*
|
||||
* @param logicalName The logical name
|
||||
* @param trailingName The trailing name
|
||||
* @return The class name
|
||||
*/
|
||||
public static String getClassName(String logicalName, String trailingName) {
|
||||
if (isBlank(logicalName)) {
|
||||
throw new IllegalArgumentException("Argument [logicalName] must not be null or blank");
|
||||
}
|
||||
|
||||
|
||||
String className = capitalize(logicalName);
|
||||
if (trailingName != null) {
|
||||
className = ((String) (className + trailingName));
|
||||
}
|
||||
|
||||
return className;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the class name representation of the given name
|
||||
*
|
||||
* @param name The name to convert
|
||||
* @return The property name representation
|
||||
*/
|
||||
public static String getClassNameRepresentation(String name) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
if (name != null && name.length() > 0) {
|
||||
String[] tokens = name.split("[^\\w\\d]");
|
||||
for (String token1 : tokens) {
|
||||
String token = token1.trim();
|
||||
buf.append(capitalize(token));
|
||||
}
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts foo-bar into FooBar. Empty and null strings are returned
|
||||
* as-is.
|
||||
*
|
||||
* @param name The lower case hyphen separated name
|
||||
* @return The class name equivalent.
|
||||
*/
|
||||
public static String getClassNameForLowerCaseHyphenSeparatedName(String name) {
|
||||
// Handle null and empty strings.
|
||||
if (isBlank(name)) {
|
||||
return name;
|
||||
}
|
||||
|
||||
if (name.contains("-")) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
String[] tokens = name.split("-");
|
||||
for (String token : tokens) {
|
||||
if (token == null || token.length() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
buf.append(capitalize(token));
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
return capitalize(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the logical class name of a Griffon artifact given the Griffon class
|
||||
* and a specified trailing name
|
||||
*
|
||||
* @param clazz The class
|
||||
* @param trailingName The trailing name such as "Controller" or "TagLib"
|
||||
* @return The logical class name
|
||||
*/
|
||||
public static String getLogicalName(Class<?> clazz, String trailingName) {
|
||||
return getLogicalName(clazz.getName(), trailingName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the logical name of the class without the trailing name
|
||||
*
|
||||
* @param name The name of the class
|
||||
* @param trailingName The trailing name
|
||||
* @return The logical name
|
||||
*/
|
||||
public static String getLogicalName(String name, String trailingName) {
|
||||
if (isNotBlank(name) && isNotBlank(trailingName)) {
|
||||
String shortName = getShortName(name);
|
||||
if (shortName.endsWith(trailingName)) {
|
||||
return shortName.substring(0, shortName.length() - trailingName.length());
|
||||
}
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
public static String getLogicalPropertyName(String className, String trailingName) {
|
||||
if (isNotBlank(className) && isNotBlank(trailingName) && className.length() == trailingName.length() + 1 && className.endsWith(trailingName)) {
|
||||
return className.substring(0, 1).toLowerCase();
|
||||
}
|
||||
|
||||
return getLogicalName(getPropertyName(className), trailingName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shorter version of getPropertyNameRepresentation
|
||||
*
|
||||
* @param name The name to convert
|
||||
* @return The property name version
|
||||
*/
|
||||
public static String getPropertyName(String name) {
|
||||
return getPropertyNameRepresentation(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shorter version of getPropertyNameRepresentation
|
||||
*
|
||||
* @param clazz The clazz to convert
|
||||
* @return The property name version
|
||||
*/
|
||||
public static String getPropertyName(Class<?> clazz) {
|
||||
return getPropertyNameRepresentation(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the property name representation of the given {@code Method}
|
||||
*
|
||||
* @param method The method to inspect
|
||||
* @return The property name representation
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public static String getPropertyName(Method method) {
|
||||
Objects.requireNonNull(method, ERROR_METHOD_NULL);
|
||||
String name = method.getName();
|
||||
if (GETTER_PATTERN_1.matcher(name).matches() || SETTER_PATTERN.matcher(name).matches()) {
|
||||
return uncapitalize(name.substring(3));
|
||||
} else if (GETTER_PATTERN_2.matcher(name).matches()) {
|
||||
return uncapitalize(name.substring(2));
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the property name equivalent for the specified class
|
||||
*
|
||||
* @param targetClass The class to get the property name for
|
||||
* @return A property name representation of the class name (eg. MyClass becomes myClass)
|
||||
*/
|
||||
public static String getPropertyNameRepresentation(Class<?> targetClass) {
|
||||
String shortName = getShortName(targetClass);
|
||||
return getPropertyNameRepresentation(shortName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the property name representation of the given name
|
||||
*
|
||||
* @param name The name to convert
|
||||
* @return The property name representation
|
||||
*/
|
||||
public static String getPropertyNameRepresentation(String name) {
|
||||
if (isBlank(name)) {
|
||||
return name;
|
||||
}
|
||||
|
||||
// Strip any package from the name.
|
||||
int pos = name.lastIndexOf(".");
|
||||
if (pos != -1) {
|
||||
name = name.substring(pos + 1);
|
||||
}
|
||||
|
||||
// Check whether the name begins with two upper case letters.
|
||||
if (name.length() > 1 && Character.isUpperCase(name.charAt(0)) && Character.isUpperCase(name.charAt(1))) {
|
||||
return name;
|
||||
}
|
||||
|
||||
String propertyName = name.substring(0, 1).toLowerCase(Locale.ENGLISH) + name.substring(1);
|
||||
if (propertyName.contains(" ")) {
|
||||
propertyName = propertyName.replaceAll("\\s", "");
|
||||
}
|
||||
|
||||
return propertyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts foo-bar into fooBar
|
||||
*
|
||||
* @param name The lower case hyphen separated name
|
||||
* @return The property name equivalent
|
||||
*/
|
||||
public static String getPropertyNameForLowerCaseHyphenSeparatedName(String name) {
|
||||
return getPropertyName(getClassNameForLowerCaseHyphenSeparatedName(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the class name without the package prefix
|
||||
*
|
||||
* @param targetClass The class to get a short name for
|
||||
* @return The short name of the class
|
||||
*/
|
||||
public static String getShortName(Class<?> targetClass) {
|
||||
String className = targetClass.getName();
|
||||
return getShortName(className);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the class name without the package prefix
|
||||
*
|
||||
* @param className The class name to get a short name for
|
||||
* @return The short name of the class
|
||||
*/
|
||||
public static String getShortName(String className) {
|
||||
if (isBlank(className)) {
|
||||
return className;
|
||||
}
|
||||
|
||||
int i = className.lastIndexOf(".");
|
||||
if (i > -1) {
|
||||
className = className.substring(i + 1, className.length());
|
||||
}
|
||||
|
||||
return className;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a property name into its natural language equivalent eg ('firstName' becomes 'First Name')
|
||||
*
|
||||
* @param name The property name to convert
|
||||
* @return The converted property name
|
||||
*/
|
||||
public static String getNaturalName(String name) {
|
||||
name = getShortName(name);
|
||||
if (isBlank(name)) {
|
||||
return name;
|
||||
}
|
||||
|
||||
List<String> words = new ArrayList<String>();
|
||||
int i = 0;
|
||||
char[] chars = name.toCharArray();
|
||||
for (char c : chars) {
|
||||
String w;
|
||||
if (i >= words.size()) {
|
||||
w = "";
|
||||
words.add(i, w);
|
||||
} else {
|
||||
w = words.get(i);
|
||||
}
|
||||
|
||||
if (Character.isLowerCase(c) || Character.isDigit(c)) {
|
||||
if (Character.isLowerCase(c) && w.length() == 0) {
|
||||
c = Character.toUpperCase(c);
|
||||
} else if (w.length() > 1 && Character.isUpperCase(w.charAt(w.length() - 1))) {
|
||||
w = "";
|
||||
words.add(++i, w);
|
||||
}
|
||||
|
||||
words.set(i, w + c);
|
||||
} else if (Character.isUpperCase(c)) {
|
||||
if ((i == 0 && w.length() == 0) || Character.isUpperCase(w.charAt(w.length() - 1))) {
|
||||
words.set(i, w + c);
|
||||
} else {
|
||||
words.add(++i, String.valueOf(c));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder buf = new StringBuilder();
|
||||
for (Iterator<String> j = words.iterator(); j.hasNext(); ) {
|
||||
String word = j.next();
|
||||
buf.append(word);
|
||||
if (j.hasNext()) {
|
||||
buf.append(" ");
|
||||
}
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Determines whether a given string is <code>null</code>, empty,
|
||||
* or only contains whitespace. If it contains anything other than
|
||||
* whitespace then the string is not considered to be blank and the
|
||||
* method returns <code>false</code>.</p>
|
||||
*
|
||||
* @param str The string to test.
|
||||
* @return <code> true</code> if the string is <code>null</code>, or
|
||||
* blank.
|
||||
*/
|
||||
public static boolean isBlank(String str) {
|
||||
if (str == null || str.length() == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (char c : str.toCharArray()) {
|
||||
if (!Character.isWhitespace(c)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Determines whether a given string is not <code>null</code>, empty,
|
||||
* or only contains whitespace. If it contains anything other than
|
||||
* whitespace then the string is not considered to be blank and the
|
||||
* method returns <code>true</code>.</p>
|
||||
*
|
||||
* @param str The string to test.
|
||||
* @return <code> true</code> if the string is not <code>null</code>, nor
|
||||
* blank.
|
||||
*/
|
||||
public static boolean isNotBlank(String str) {
|
||||
return ((boolean) (!isBlank(str)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the specified String is not {@code blank}. This
|
||||
* method is designed primarily for doing parameter validation in methods
|
||||
* and constructors, as demonstrated below:
|
||||
* <blockquote><pre>
|
||||
* Foo(String str) {* this.str = GriffonNameUtils.requireNonBlank(str)
|
||||
* }* </pre></blockquote>
|
||||
*
|
||||
* @param str the String to check for blank
|
||||
* @return {@code str} if not {@code blank}
|
||||
* @throws IllegalArgumentException if {@code str} is {@code blank}
|
||||
*/
|
||||
public static String requireNonBlank(String str) {
|
||||
if (isBlank(str)) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the specified String is not {@code blank} and
|
||||
* throws a customized {@link IllegalArgumentException} if it is. This method
|
||||
* is designed primarily for doing parameter validation in methods and
|
||||
* constructors with multiple parameters, as demonstrated below:
|
||||
* <blockquote><pre>
|
||||
* Foo(String str) {* this.str = GriffonNameUtils.requireNonBlank(str, "str must not be null")
|
||||
* }* </pre></blockquote>
|
||||
*
|
||||
* @param str the String to check for blank
|
||||
* @param message detail message to be used in the event that a {@code
|
||||
* IllegalArgumentException} is thrown
|
||||
* @return {@code str} if not {@code blank}
|
||||
* @throws IllegalArgumentException if {@code str} is {@code blank}
|
||||
*/
|
||||
public static String requireNonBlank(String str, String message) {
|
||||
if (isBlank(str)) {
|
||||
throw new IllegalArgumentException(message);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the hyphenated name representation of the supplied class. For example
|
||||
* MyFunkyGriffonThingy would be my-funky-griffon-thingy.
|
||||
*
|
||||
* @param clazz The class to convert
|
||||
* @return The hyphenated name representation
|
||||
*/
|
||||
public static String getHyphenatedName(Class<?> clazz) {
|
||||
if (clazz == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return getHyphenatedName(clazz.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the hyphenated name representation of the given class name.
|
||||
* For example MyFunkyGriffonThingy would be my-funky-griffon-thingy.
|
||||
*
|
||||
* @param name The class name to convert.
|
||||
* @return The hyphenated name representation.
|
||||
*/
|
||||
public static String getHyphenatedName(String name) {
|
||||
if (isBlank(name)) {
|
||||
return name;
|
||||
}
|
||||
|
||||
if (name.endsWith(".groovy")) {
|
||||
name = name.substring(0, name.length() - 7);
|
||||
}
|
||||
|
||||
String naturalName = getNaturalName(getShortName(name));
|
||||
return naturalName.replaceAll("\\s", "-").toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Uncapitalizes a String (makes the first char lowercase) taking care
|
||||
* of blank strings and single character strings.
|
||||
*
|
||||
* @param str The String to be uncapitalized
|
||||
* @return Uncapitalized version of the target string if it is not blank
|
||||
*/
|
||||
public static String uncapitalize(String str) {
|
||||
if (isBlank(str)) {
|
||||
return str;
|
||||
}
|
||||
|
||||
if (str.length() == 1) {
|
||||
return String.valueOf(Character.toLowerCase(str.charAt(0)));
|
||||
}
|
||||
|
||||
return Character.toLowerCase(str.charAt(0)) + str.substring(1);
|
||||
}
|
||||
}
|
||||
22
core/jreleaser-utils/src/main/module/module-info.java
Normal file
22
core/jreleaser-utils/src/main/module/module-info.java
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
module org.kordamp.jreleaser.util {
|
||||
exports org.kordamp.jreleaser.util;
|
||||
requires os.maven.plugin;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user