Add glob support in model.files

This commit is contained in:
Andres Almiray
2021-03-28 20:16:56 +02:00
parent 046762ea64
commit d02b9025eb
26 changed files with 902 additions and 170 deletions

75
CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,75 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and
orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
- The use of sexualized language or imagery and unwelcome sexual attention or
advances
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or electronic
address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at info@kordamp.org. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

View File

@@ -23,11 +23,11 @@ import org.jreleaser.model.Artifact;
import org.jreleaser.model.Distribution;
import org.jreleaser.model.JReleaserContext;
import org.jreleaser.model.JReleaserException;
import org.jreleaser.model.util.Artifacts;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
@@ -43,16 +43,16 @@ public class Checksum {
List<String> checksums = new ArrayList<>();
for (Artifact artifact : context.getModel().getFiles()) {
for (Artifact artifact : Artifacts.resolveFiles(context)) {
readHash(context, artifact);
checksums.add(artifact.getHash() + " " + Paths.get(artifact.getPath()).getFileName());
checksums.add(artifact.getHash() + " " + artifact.getFilePath().getFileName());
}
for (Distribution distribution : context.getModel().getDistributions().values()) {
for (Artifact artifact : distribution.getArtifacts()) {
readHash(context, distribution.getName(), artifact);
readHash(context, distribution, artifact);
checksums.add(artifact.getHash() + " " + distribution.getName() + "/" +
Paths.get(artifact.getPath()).getFileName());
artifact.getFilePath().getFileName());
}
}
@@ -70,22 +70,22 @@ public class Checksum {
}
}
public static void readHash(JReleaserContext context, String distributionName, Artifact artifact) throws JReleaserException {
Path artifactPath = context.getBasedir().resolve(Paths.get(artifact.getPath()));
Path checksumPath = context.getChecksumsDirectory().resolve(distributionName).resolve(artifactPath.getFileName() + ".sha256");
public static void readHash(JReleaserContext context, Distribution distribution, Artifact artifact) throws JReleaserException {
Path artifactPath = artifact.getResolvedPath(context, distribution);
Path checksumPath = context.getChecksumsDirectory().resolve(distribution.getName()).resolve(artifactPath.getFileName() + ".sha256");
readHash(context, artifact, artifactPath, checksumPath);
}
public static void readHash(JReleaserContext context, Artifact artifact) throws JReleaserException {
Path artifactPath = context.getBasedir().resolve(Paths.get(artifact.getPath()));
Path artifactPath = artifact.getResolvedPath(context);
Path checksumPath = context.getChecksumsDirectory().resolve(artifactPath.getFileName() + ".sha256");
readHash(context, artifact, artifactPath, checksumPath);
}
private static void readHash(JReleaserContext context, Artifact artifact, Path artifactPath, Path checksumPath) throws JReleaserException {
if (!artifactPath.toFile().exists()) {
if (!Files.exists(artifactPath)) {
throw new JReleaserException("Artifact does not exist. " + context.getBasedir().relativize(artifactPath));
}

View File

@@ -37,6 +37,7 @@ import org.jreleaser.model.Artifact;
import org.jreleaser.model.Distribution;
import org.jreleaser.model.JReleaserContext;
import org.jreleaser.model.Signing;
import org.jreleaser.model.util.Artifacts;
import org.jreleaser.util.signing.InMemoryKeyring;
import org.jreleaser.util.signing.SigningException;
@@ -50,7 +51,6 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.Security;
import java.util.ArrayList;
import java.util.List;
@@ -77,7 +77,7 @@ public class Signer {
return;
}
List<Path> paths = collectArtifactsForSigning(context);
List<Path> paths = collectArtifacts(context);
if (paths.isEmpty()) {
context.getLogger().info("No files configured for signing. Skipping");
return;
@@ -235,16 +235,16 @@ public class Signer {
}
}
private static List<Path> collectArtifactsForSigning(JReleaserContext context) {
private static List<Path> collectArtifacts(JReleaserContext context) {
List<Path> paths = new ArrayList<>();
for (Artifact artifact : context.getModel().getFiles()) {
paths.add(context.getBasedir().resolve(Paths.get(artifact.getPath())).normalize());
for (Artifact artifact : Artifacts.resolveFiles(context)) {
paths.add(artifact.getResolvedPath(context));
}
for (Distribution distribution : context.getModel().getDistributions().values()) {
for (Artifact artifact : distribution.getArtifacts()) {
paths.add(context.getBasedir().resolve(Paths.get(artifact.getPath())).normalize());
paths.add(artifact.getResolvedPath(context, distribution));
}
}

View File

@@ -350,7 +350,7 @@ abstract class AbstractToolProcessor<T extends Tool> implements ToolProcessor<T>
for (int i = 0; i < artifacts.size(); i++) {
Artifact artifact = artifacts.get(i);
String platform = isNotBlank(artifact.getPlatform()) ? capitalize(artifact.getPlatform()) : "";
String artifactFileName = Paths.get(artifact.getPath()).getFileName().toString();
String artifactFileName = artifact.getResolvedPath(context).getFileName().toString();
props.put("artifact" + platform + "FileName", artifactFileName);
props.put("artifact" + platform + "Hash", artifact.getHash());
Map<String, Object> newProps = new LinkedHashMap<>(props);

View File

@@ -73,7 +73,7 @@ public class DistributionProcessor {
context.getLogger().debug("Reading checksums for {} distribution", distributionName);
for (int i = 0; i < distribution.getArtifacts().size(); i++) {
Artifact artifact = distribution.getArtifacts().get(i);
Checksum.readHash(context, distributionName, artifact);
Checksum.readHash(context, distribution, artifact);
}
return ToolProcessors.findProcessor(context, tool)

View File

@@ -17,9 +17,17 @@
*/
package org.jreleaser.model;
import org.jreleaser.util.Constants;
import java.io.StringReader;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.LinkedHashMap;
import java.util.Map;
import static java.nio.file.Files.exists;
import static org.jreleaser.util.MustacheUtils.applyTemplate;
/**
* @author Andres Almiray
* @since 0.1.0
@@ -28,6 +36,44 @@ public class Artifact implements Domain {
private String path;
private String hash;
private String platform;
private Path filePath;
public Path getResolvedPath(JReleaserContext context) {
if (null == filePath) {
if (path.contains("{{")) {
path = applyTemplate(new StringReader(path), context.getModel().props());
}
filePath = context.getBasedir().resolve(Paths.get(path)).normalize();
if (!exists(filePath)) {
throw new JReleaserException("Path does not exist. " + context.getBasedir().relativize(filePath));
}
}
return filePath;
}
public Path getResolvedPath(JReleaserContext context, Distribution distribution) {
if (null == filePath) {
if (path.contains("{{")) {
Map<String, Object> props = context.getModel().props();
props.put(Constants.KEY_DISTRIBUTION_NAME, distribution.getName());
props.put(Constants.KEY_DISTRIBUTION_EXECUTABLE, distribution.getExecutable());
props.put(Constants.KEY_DISTRIBUTION_JAVA_GROUP_ID, distribution.getJava().getGroupId());
props.put(Constants.KEY_DISTRIBUTION_JAVA_ARTIFACT_ID, distribution.getJava().getArtifactId());
props.put(Constants.KEY_DISTRIBUTION_JAVA_VERSION, distribution.getJava().getVersion());
props.putAll(distribution.getResolvedExtraProperties());
path = applyTemplate(new StringReader(path), props);
}
filePath = context.getBasedir().resolve(Paths.get(path)).normalize();
if (!exists(filePath)) {
throw new JReleaserException("Artifact does not exist. " + context.getBasedir().relativize(filePath));
}
}
return filePath;
}
public Path getFilePath() {
return filePath;
}
public String getPath() {
return path;
@@ -60,4 +106,11 @@ public class Artifact implements Domain {
map.put("platform", platform);
return map;
}
public static Artifact of(Path filePath) {
Artifact artifact = new Artifact();
artifact.path = filePath.toAbsolutePath().toString();
artifact.filePath = filePath;
return artifact;
}
}

View File

@@ -219,9 +219,13 @@ public class Distribution extends Packagers implements ExtraProperties, EnabledP
props.put("enabled", isEnabled());
props.put("type", type);
props.put("executable", executable);
props.put("artifacts", artifacts.stream()
.map(Artifact::asMap)
.collect(Collectors.toList()));
Map<String, Map<String, Object>> mappedArtifacts = new LinkedHashMap<>();
for (int i = 0; i < artifacts.size(); i++) {
mappedArtifacts.put("artifact " + i, artifacts.get(i).asMap());
}
props.put("artifacts", mappedArtifacts);
props.put("tags", tags);
props.put("extraProperties", getResolvedExtraProperties());
if (java.isEnabled()) {

View File

@@ -28,6 +28,7 @@ import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;
import static org.jreleaser.util.StringUtils.isBlank;
import static org.jreleaser.util.StringUtils.isNotBlank;
/**
@@ -38,6 +39,10 @@ public class Environment implements Domain {
private String variables;
private Properties props;
public boolean isEmpty() {
return isBlank(variables);
}
void setAll(Environment environment) {
this.variables = environment.variables;
}

View File

@@ -0,0 +1,117 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright 2020-2021 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.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;
/**
* @author Andres Almiray
* @since 0.1.0
*/
public class Files implements Domain {
private final List<Artifact> artifacts = new ArrayList<>();
private final List<Glob> globs = new ArrayList<>();
private final Set<Artifact> paths = new LinkedHashSet<>();
private boolean resolved;
public boolean isEmpty() {
return artifacts.isEmpty() && globs.isEmpty();
}
public boolean arePathsResolved() {
return resolved;
}
public Set<Artifact> getPaths() {
return Collections.unmodifiableSet(paths);
}
public void setPaths(Set<Artifact> paths) {
this.paths.clear();
this.paths.addAll(paths);
this.resolved = true;
}
void setAll(Files files) {
setArtifacts(files.artifacts);
setGlobs(files.globs);
}
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<Glob> getGlobs() {
return globs;
}
public void setGlobs(List<Glob> globs) {
this.globs.clear();
this.globs.addAll(globs);
}
public void addGlobs(List<Glob> globs) {
this.globs.addAll(globs);
}
public void addGlob(Glob glob) {
if (null != glob) {
this.globs.add(glob);
}
}
@Override
public Map<String, Object> asMap() {
Map<String, Object> map = new LinkedHashMap<>();
Map<String, Map<String, Object>> mappedArtifacts = new LinkedHashMap<>();
for (int i = 0; i < artifacts.size(); i++) {
mappedArtifacts.put("artifact " + i, artifacts.get(i).asMap());
}
map.put("artifacts", mappedArtifacts);
Map<String, Map<String, Object>> mappedGlobs = new LinkedHashMap<>();
for (int i = 0; i < globs.size(); i++) {
mappedGlobs.put("glob " + i, globs.get(i).asMap());
}
map.put("globs", mappedGlobs);
return map;
}
}

View File

@@ -0,0 +1,176 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright 2020-2021 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.jreleaser.model;
import java.io.IOException;
import java.io.StringReader;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import static java.nio.file.FileVisitResult.CONTINUE;
import static java.nio.file.FileVisitResult.SKIP_SUBTREE;
import static java.nio.file.Files.exists;
import static org.jreleaser.util.MustacheUtils.applyTemplate;
import static org.jreleaser.util.StringUtils.isNotBlank;
/**
* @author Andres Almiray
* @since 0.1.0
*/
public class Glob implements Domain {
private String directory;
private String pattern;
private Boolean recursive;
private Set<Path> paths;
public Set<Path> getResolvedPaths(JReleaserContext context) {
if (null == paths) {
// resolve directory
Path path = context.getBasedir();
if (isNotBlank(directory)) {
if (directory.contains("{{")) {
directory = applyTemplate(new StringReader(directory), context.getModel().props());
}
path = context.getBasedir().resolve(Paths.get(directory)).normalize();
if (!exists(path)) {
throw new JReleaserException("Path does not exist. " + context.getBasedir().relativize(path));
}
}
FileCollector fileCollector = new FileCollector(context, pattern, path, isRecursive());
try {
java.nio.file.Files.walkFileTree(path, fileCollector);
} catch (IOException e) {
throw new JReleaserException("Unnexpected error resolving glob " + pattern);
}
if (fileCollector.failed) {
throw new JReleaserException("Could not resolve glob " + pattern);
}
paths = fileCollector.getFiles();
}
return paths;
}
public String getDirectory() {
return directory;
}
public void setDirectory(String directory) {
this.directory = directory;
}
public String getPattern() {
return pattern;
}
public void setPattern(String pattern) {
this.pattern = pattern;
}
public Boolean isRecursive() {
return recursive != null && recursive;
}
public void setRecursive(Boolean recursive) {
this.recursive = recursive;
}
public boolean isRecursiveSet() {
return recursive != null;
}
public Map<String, Object> asMap() {
Map<String, Object> map = new LinkedHashMap<>();
map.put("directory", directory);
map.put("pattern", pattern);
map.put("recursive", isRecursive());
return map;
}
public static class FileCollector extends SimpleFileVisitor<Path> {
private final PathMatcher matcher;
private final Set<Path> files = new LinkedHashSet<>();
private final JReleaserContext context;
private final boolean recursive;
private final Path start;
private boolean failed;
FileCollector(JReleaserContext context, String pattern, Path start, boolean recursive) {
this.context = context;
this.start = start;
this.recursive = recursive;
if (pattern.startsWith("regex:") || pattern.startsWith("glob:")) {
matcher = FileSystems.getDefault()
.getPathMatcher(pattern);
} else {
matcher = FileSystems.getDefault()
.getPathMatcher("glob:" + pattern);
}
}
private void match(Path file) {
Path name = file.getFileName();
if (name != null && matcher.matches(name)) {
files.add(file);
}
}
public Set<Path> getFiles() {
return Collections.unmodifiableSet(files);
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
match(file);
return CONTINUE;
}
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
if (recursive) {
match(dir);
return CONTINUE;
} else if (dir.equals(start)) {
match(dir);
return CONTINUE;
}
return SKIP_SUBTREE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException e) {
failed = true;
context.getLogger().error("Unnexpected error visiting path " +
context.getBasedir().relativize(file), e);
return CONTINUE;
}
}
}

View File

@@ -23,14 +23,12 @@ import org.jreleaser.util.Constants;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
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.jreleaser.util.StringUtils.getClassNameForLowerCaseHyphenSeparatedName;
import static org.jreleaser.util.StringUtils.isBlank;
import static org.jreleaser.util.StringUtils.isNotBlank;
/**
* @author Andres Almiray
@@ -43,7 +41,7 @@ public class JReleaserModel implements Domain {
private final Packagers packagers = new Packagers();
private final Announce announce = new Announce();
private final Signing signing = new Signing();
private final Set<Artifact> files = new LinkedHashSet<>();
private final Files files = new Files();
private final Map<String, Distribution> distributions = new LinkedHashMap<>();
private final String timestamp;
@@ -113,23 +111,12 @@ public class JReleaserModel implements Domain {
this.signing.setAll(signing);
}
public Set<Artifact> getFiles() {
public Files getFiles() {
return files;
}
public void setFiles(Set<Artifact> files) {
this.files.clear();
this.files.addAll(files);
}
public void addFiles(Set<Artifact> files) {
this.files.addAll(files);
}
public void addFiles(Artifact artifact) {
if (null != artifact) {
this.files.add(artifact);
}
public void setFiles(Files files) {
this.files.setAll(files);
}
public Map<String, Distribution> getDistributions() {
@@ -167,21 +154,19 @@ public class JReleaserModel implements Domain {
public Map<String, Object> asMap() {
Map<String, Object> map = new LinkedHashMap<>();
if (isNotBlank(environment.getVariables())) map.put("environment", environment.asMap());
if (!environment.isEmpty()) map.put("environment", environment.asMap());
map.put("project", project.asMap());
map.put("release", release.asMap());
map.put("packagers", packagers.asMap());
if (announce.isEnabled()) map.put("announce", announce.asMap());
if (signing.isEnabled()) map.put("signing", signing.asMap());
if (files.size() > 0) {
map.put("files", files.stream()
.map(Artifact::asMap)
.collect(Collectors.toList()));
}
map.put("distributions", distributions.values()
if (announce.isEnabled()) map.put("announce", announce.asMap());
if (!files.isEmpty()) map.put("files", files.asMap());
if (packagers.hasEnabledPackagers()) map.put("packagers", packagers.asMap());
List<Map<String, Object>> distributions = this.distributions.values()
.stream()
.map(Distribution::asMap)
.collect(Collectors.toList()));
.collect(Collectors.toList());
if (!distributions.isEmpty()) map.put("distributions", distributions);
return map;
}

View File

@@ -17,13 +17,10 @@
*/
package org.jreleaser.model;
import org.jreleaser.util.Constants;
import org.jreleaser.util.Env;
import org.jreleaser.util.JReleaserLogger;
import org.jreleaser.util.PlatformUtils;
import org.jreleaser.util.StringUtils;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
@@ -47,7 +44,6 @@ import static org.jreleaser.model.Twitter.TWITTER_CONSUMER_KEY;
import static org.jreleaser.model.Twitter.TWITTER_CONSUMER_SECRET;
import static org.jreleaser.model.Zulip.ZULIP_API_KEY;
import static org.jreleaser.util.Constants.KEY_REVERSE_REPO_HOST;
import static org.jreleaser.util.MustacheUtils.applyTemplate;
import static org.jreleaser.util.StringUtils.getFilenameExtension;
import static org.jreleaser.util.StringUtils.isBlank;
import static org.jreleaser.util.StringUtils.isNotBlank;
@@ -64,7 +60,6 @@ public final class JReleaserModelValidator {
public static List<String> validate(JReleaserContext context) {
List<String> errors = new ArrayList<>();
validateModel(context, errors);
resolveArtifactPaths(context);
return Collections.unmodifiableList(errors);
}
@@ -74,6 +69,7 @@ public final class JReleaserModelValidator {
validateRelease(context, errors);
validatePackagers(context, errors);
validateAnnouncers(context, errors);
validateFiles(context, errors);
validateDistributions(context, errors);
}
@@ -408,6 +404,15 @@ public final class JReleaserModelValidator {
return gitea.isEnabled();
}
private static void validateFiles(JReleaserContext context, List<String> errors) {
int i = 0;
for (Glob glob : context.getModel().getFiles().getGlobs()) {
if (isBlank(glob.getPattern())) {
errors.add("files.glob[" + i + "] must define a pattern");
}
}
}
private static void validateDistributions(JReleaserContext context, List<String> errors) {
Map<String, Distribution> distributions = context.getModel().getDistributions();
@@ -827,39 +832,4 @@ public final class JReleaserModelValidator {
if (isBlank(author.getEmail())) author.setEmail(other.getCommitAuthor().getEmail());
self.setCommitAuthor(author);
}
private static void resolveArtifactPaths(JReleaserContext context) {
JReleaserLogger logger = context.getLogger();
JReleaserModel model = context.getModel();
for (Distribution distribution : model.getDistributions().values()) {
Map<String, Object> props = model.props();
props.put(Constants.KEY_DISTRIBUTION_NAME, distribution.getName());
props.put(Constants.KEY_DISTRIBUTION_EXECUTABLE, distribution.getExecutable());
props.putAll(distribution.getResolvedExtraProperties());
for (int i = 0; i < distribution.getArtifacts().size(); i++) {
Artifact artifact = distribution.getArtifacts().get(i);
String path = artifact.getPath();
if (path.contains("{{")) {
String newpath = applyTemplate(new StringReader(path), props);
logger.debug("Adjusting distribution.artifact[{}].path{} from {}{} to {}",
i, System.lineSeparator(), path, System.lineSeparator(), newpath);
artifact.setPath(newpath);
}
}
}
Map<String, Object> props = model.props();
int i = 0;
for (Artifact artifact : model.getFiles()) {
String path = artifact.getPath();
if (path.contains("{{")) {
String newpath = applyTemplate(new StringReader(path), props);
logger.debug("Adjusting files[{i}].path{} from {}{} to {}",
i++, System.lineSeparator(), path, System.lineSeparator(), newpath);
artifact.setPath(newpath);
}
}
}
}

View File

@@ -31,6 +31,14 @@ public class Packagers implements Domain {
private final Scoop scoop = new Scoop();
private final Snap snap = new Snap();
public boolean hasEnabledPackagers() {
return brew.isEnabled() ||
chocolatey.isEnabled() ||
jbang.isEnabled() ||
scoop.isEnabled() ||
snap.isEnabled();
}
void setAll(Packagers packagers) {
setBrew(packagers.brew);
setChocolatey(packagers.chocolatey);

View File

@@ -20,10 +20,10 @@ package org.jreleaser.model.releaser.spi;
import org.jreleaser.model.Artifact;
import org.jreleaser.model.Distribution;
import org.jreleaser.model.JReleaserContext;
import org.jreleaser.model.util.Artifacts;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
@@ -76,13 +76,13 @@ public abstract class AbstractReleaserBuilder<R extends Releaser, B extends Rele
public B configureWith(JReleaserContext context) {
this.context = context;
for (Artifact artifact : context.getModel().getFiles()) {
addReleaseAsset(context.getBasedir().resolve(Paths.get(artifact.getPath())));
for (Artifact artifact : Artifacts.resolveFiles(context)) {
addReleaseAsset(artifact.getResolvedPath(context));
}
for (Distribution distribution : context.getModel().getDistributions().values()) {
for (Artifact artifact : distribution.getArtifacts()) {
addReleaseAsset(context.getBasedir().resolve(Paths.get(artifact.getPath())));
addReleaseAsset(artifact.getResolvedPath(context, distribution));
}
}

View File

@@ -0,0 +1,61 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright 2020-2021 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.jreleaser.model.util;
import org.jreleaser.model.Artifact;
import org.jreleaser.model.Files;
import org.jreleaser.model.Glob;
import org.jreleaser.model.JReleaserContext;
import org.jreleaser.model.JReleaserException;
import java.nio.file.Path;
import java.util.LinkedHashSet;
import java.util.Set;
/**
* @author Andres Almiray
* @since 0.1.0
*/
public class Artifacts {
public static Set<Artifact> resolveFiles(JReleaserContext context) throws JReleaserException {
Files files = context.getModel().getFiles();
if (files.arePathsResolved()) {
return files.getPaths();
}
Set<Artifact> paths = new LinkedHashSet<>();
// resolve artifacts
for (Artifact artifact : files.getArtifacts()) {
artifact.getResolvedPath(context);
paths.add(artifact);
}
// resolve globs
for (Glob glob : files.getGlobs()) {
for (Path path : glob.getResolvedPaths(context)) {
paths.add(Artifact.of(path));
}
}
files.setPaths(paths);
return files.getPaths();
}
}

View File

@@ -15,11 +15,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jreleaser.maven.plugin;
package org.jreleaser.gradle.plugin.dsl
import groovy.transform.CompileStatic
import org.gradle.api.Action
/**
*
* @author Andres Almiray
* @since 0.1.0
*/
public class File extends Artifact {
}
@CompileStatic
interface Files {
void artifact(Action<? super Artifact> action)
void glob(Action<? super Glob> action)
}

View File

@@ -0,0 +1,36 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright 2020-2021 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.jreleaser.gradle.plugin.dsl
import groovy.transform.CompileStatic
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.Property
/**
*
* @author Andres Almiray
* @since 0.1.0
*/
@CompileStatic
interface Glob {
DirectoryProperty getDirectory()
Property<String> getPattern()
Property<Boolean> getRecursive()
}

View File

@@ -43,13 +43,13 @@ class ArtifactImpl implements Artifact {
platform = objects.property(String).convention(Providers.notDefined())
}
void setPath(String path){
void setPath(String path) {
this.path.set(new File(path))
}
org.jreleaser.model.Artifact toModel() {
org.jreleaser.model.Artifact artifact = new org.jreleaser.model.Artifact()
if(path.present) {
if (path.present) {
artifact.path = path.asFile.get().absolutePath
} else {
throw new IllegalArgumentException("Artifact ${name} requires a value for 'path'")

View File

@@ -64,7 +64,7 @@ class DistributionImpl implements Distribution {
final SnapImpl snap
final JavaImpl java
final NamedDomainObjectContainer<ArtifactImpl> artifacts
private final NamedDomainObjectContainer<ArtifactImpl> artifacts
private final Property<String> myName
private final PackagersImpl packagers

View File

@@ -0,0 +1,84 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright 2020-2021 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.jreleaser.gradle.plugin.internal.dsl
import groovy.transform.CompileStatic
import org.gradle.api.Action
import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.NamedDomainObjectFactory
import org.gradle.api.model.ObjectFactory
import org.jreleaser.gradle.plugin.dsl.Artifact
import org.jreleaser.gradle.plugin.dsl.Files
import org.jreleaser.gradle.plugin.dsl.Glob
import javax.inject.Inject
/**
*
* @author Andres Almiray
* @since 0.1.0
*/
@CompileStatic
class FilesImpl implements Files {
private final NamedDomainObjectContainer<ArtifactImpl> artifacts
private final NamedDomainObjectContainer<GlobImpl> globs
@Inject
FilesImpl(ObjectFactory objects) {
artifacts = objects.domainObjectContainer(ArtifactImpl, new NamedDomainObjectFactory<ArtifactImpl>() {
@Override
ArtifactImpl create(String name) {
ArtifactImpl artifact = objects.newInstance(ArtifactImpl, objects)
artifact.name = name
artifact
}
})
globs = objects.domainObjectContainer(GlobImpl, new NamedDomainObjectFactory<GlobImpl>() {
@Override
GlobImpl create(String name) {
GlobImpl glob = objects.newInstance(GlobImpl, objects)
glob.name = name
glob
}
})
}
@Override
void artifact(Action<? super Artifact> action) {
ArtifactImpl artifact = artifacts.maybeCreate("artifact-${artifacts.size()}".toString())
action.execute(artifact)
}
@Override
void glob(Action<? super Glob> action) {
GlobImpl glob = globs.maybeCreate("glob-${globs.size()}".toString())
action.execute(glob)
}
org.jreleaser.model.Files toModel() {
org.jreleaser.model.Files files = new org.jreleaser.model.Files()
for (ArtifactImpl artifact : artifacts) {
files.artifacts.add(artifact.toModel())
}
for (GlobImpl glob : globs) {
files.globs.add(glob.toModel())
}
files
}
}

View File

@@ -0,0 +1,61 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright 2020-2021 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.jreleaser.gradle.plugin.internal.dsl
import groovy.transform.CompileStatic
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.internal.provider.Providers
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Property
import org.jreleaser.gradle.plugin.dsl.Glob
import javax.inject.Inject
/**
*
* @author Andres Almiray
* @since 0.1.0
*/
@CompileStatic
class GlobImpl implements Glob {
String name
final DirectoryProperty directory
final Property<String> pattern
final Property<Boolean> recursive
@Inject
GlobImpl(ObjectFactory objects) {
directory = objects.directoryProperty().convention(Providers.notDefined())
pattern = objects.property(String).convention(Providers.notDefined())
recursive = objects.property(Boolean).convention(Providers.notDefined())
}
void setDirectory(String path) {
this.directory.set(new File(path))
}
org.jreleaser.model.Glob toModel() {
org.jreleaser.model.Glob glob = new org.jreleaser.model.Glob()
if (directory.present) {
glob.directory = directory.asFile.get().absolutePath
}
if (pattern.present) glob.pattern = pattern.get()
if (recursive.present) glob.recursive = recursive.get()
glob
}
}

View File

@@ -0,0 +1,73 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright 2020-2021 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.jreleaser.maven.plugin;
import java.util.ArrayList;
import java.util.List;
/**
* @author Andres Almiray
* @since 0.1.0
*/
public class Files {
private final List<Artifact> artifacts = new ArrayList<>();
private final List<Glob> globs = new ArrayList<>();
void setAll(Files files) {
setArtifacts(files.artifacts);
setGlobs(files.globs);
}
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<Glob> getGlobs() {
return globs;
}
public void setGlobs(List<Glob> globs) {
this.globs.clear();
this.globs.addAll(globs);
}
public void addGlobs(List<Glob> globs) {
this.globs.addAll(globs);
}
public void addGlob(Glob glob) {
if (null != glob) {
this.globs.add(glob);
}
}
}

View File

@@ -0,0 +1,56 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright 2020-2021 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.jreleaser.maven.plugin;
/**
* @author Andres Almiray
* @since 0.1.0
*/
public class Glob {
private String directory;
private String pattern;
private Boolean recursive;
public String getDirectory() {
return directory;
}
public void setDirectory(String directory) {
this.directory = directory;
}
public String getPattern() {
return pattern;
}
public void setPattern(String pattern) {
this.pattern = pattern;
}
public Boolean isRecursive() {
return recursive != null && recursive;
}
public void setRecursive(Boolean recursive) {
this.recursive = recursive;
}
public boolean isRecursiveSet() {
return recursive != null;
}
}

View File

@@ -19,12 +19,7 @@ package org.jreleaser.maven.plugin;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Supplier;
import static org.jreleaser.util.StringUtils.isBlank;
/**
* @author Andres Almiray
@@ -37,7 +32,7 @@ public class Jreleaser {
private final Packagers packagers = new Packagers();
private final Announce announce = new Announce();
private final Signing signing = new Signing();
private final Set<File> files = new LinkedHashSet<>();
private final Files files = new Files();
private final List<Distribution> distributions = new ArrayList<>();
public Environment getEnvironment() {
@@ -88,23 +83,12 @@ public class Jreleaser {
this.signing.setAll(signing);
}
public Set<File> getFiles() {
public Files getFiles() {
return files;
}
public void setFiles(Set<File> files) {
this.files.clear();
this.files.addAll(files);
}
public void addFiles(Set<File> files) {
this.files.addAll(files);
}
public void addFiles(File artifact) {
if (null != artifact) {
this.files.add(artifact);
}
public void setFiles(Files files) {
this.files.setAll(files);
}
public List<Distribution> getDistributions() {
@@ -115,25 +99,4 @@ public class Jreleaser {
this.distributions.clear();
this.distributions.addAll(distributions);
}
public void addDistributions(Collection<Distribution> distributions) {
this.distributions.addAll(distributions);
}
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");
}
return distributions.stream()
.filter(d -> name.equals(d.getName()))
.findFirst()
.orElseThrow((Supplier<IllegalArgumentException>) () -> {
throw new IllegalArgumentException("Distribution '" + name + "' not found");
});
}
}

View File

@@ -27,11 +27,12 @@ import org.jreleaser.maven.plugin.Chocolatey;
import org.jreleaser.maven.plugin.CommitAuthor;
import org.jreleaser.maven.plugin.Distribution;
import org.jreleaser.maven.plugin.Environment;
import org.jreleaser.maven.plugin.File;
import org.jreleaser.maven.plugin.Files;
import org.jreleaser.maven.plugin.GitService;
import org.jreleaser.maven.plugin.Gitea;
import org.jreleaser.maven.plugin.Github;
import org.jreleaser.maven.plugin.Gitlab;
import org.jreleaser.maven.plugin.Glob;
import org.jreleaser.maven.plugin.Java;
import org.jreleaser.maven.plugin.Jbang;
import org.jreleaser.maven.plugin.Jreleaser;
@@ -56,10 +57,8 @@ import org.jreleaser.model.SnapTap;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.jreleaser.util.StringUtils.isNotBlank;
@@ -280,20 +279,11 @@ public final class JReleaserModelConverter {
return d;
}
private static List<org.jreleaser.model.Artifact> convertFiles(List<File> files) {
List<org.jreleaser.model.Artifact> as = new ArrayList<>();
for (File file : files) {
as.add(convertArtifact(file));
}
return as;
}
private static Set<org.jreleaser.model.Artifact> convertFiles(Set<File> files) {
Set<org.jreleaser.model.Artifact> as = new LinkedHashSet<>();
for (File file : files) {
as.add(convertArtifact(file));
}
return as;
private static org.jreleaser.model.Files convertFiles(Files files) {
org.jreleaser.model.Files fs = new org.jreleaser.model.Files();
fs.setArtifacts(convertArtifacts(files.getArtifacts()));
fs.setGlobs(convertGlobs(files.getGlobs()));
return fs;
}
private static List<org.jreleaser.model.Artifact> convertArtifacts(List<Artifact> artifacts) {
@@ -304,14 +294,6 @@ public final class JReleaserModelConverter {
return as;
}
private static Set<org.jreleaser.model.Artifact> convertArtifacts(Set<Artifact> artifacts) {
Set<org.jreleaser.model.Artifact> as = new LinkedHashSet<>();
for (Artifact artifact : artifacts) {
as.add(convertArtifact(artifact));
}
return as;
}
private static org.jreleaser.model.Artifact convertArtifact(Artifact artifact) {
org.jreleaser.model.Artifact a = new org.jreleaser.model.Artifact();
a.setPath(artifact.getPath());
@@ -320,6 +302,22 @@ public final class JReleaserModelConverter {
return a;
}
private static List<org.jreleaser.model.Glob> convertGlobs(List<Glob> globs) {
List<org.jreleaser.model.Glob> gs = new ArrayList<>();
for (Glob glob : globs) {
gs.add(convertGlob(glob));
}
return gs;
}
private static org.jreleaser.model.Glob convertGlob(Glob glob) {
org.jreleaser.model.Glob g = new org.jreleaser.model.Glob();
g.setDirectory(glob.getDirectory());
g.setPattern(glob.getPattern());
if (glob.isRecursiveSet()) g.setRecursive(glob.isRecursive());
return g;
}
private static org.jreleaser.model.Brew convertBrew(Brew brew) {
org.jreleaser.model.Brew t = new org.jreleaser.model.Brew();
if (brew.isEnabledSet()) t.setEnabled(brew.isEnabled());

View File

@@ -26,7 +26,6 @@ import org.jreleaser.model.announcer.spi.AnnounceException;
import org.jreleaser.model.announcer.spi.Announcer;
import java.io.StringReader;
import java.nio.file.Paths;
import java.util.LinkedHashMap;
import java.util.Map;
@@ -72,12 +71,12 @@ public class SdkmanAnnouncer implements Announcer {
// only zips are supported
if (!artifact.getPath().endsWith(".zip")) {
context.getLogger().debug("Artifact {} is not suitable for Sdkman publication. Skipping.",
Paths.get(artifact.getPath()).getFileName());
artifact.getResolvedPath(context, distribution).getFileName());
continue;
}
String platform = mapPlatform(artifact.getPlatform());
String url = artifactUrl(artifact);
String url = artifactUrl(distribution, artifact);
if (platforms.containsKey(platform)) {
context.getLogger().warn("Platform {}: {} will replace {}", platform, url, platforms.get(platform));
}
@@ -159,9 +158,9 @@ public class SdkmanAnnouncer implements Announcer {
return null;
}
private String artifactUrl(Artifact artifact) {
private String artifactUrl(Distribution distribution, Artifact artifact) {
Map<String, Object> newProps = context.getModel().props();
newProps.put("artifactFileName", Paths.get(artifact.getPath()).getFileName().toString());
newProps.put("artifactFileName", artifact.getResolvedPath(context, distribution).getFileName().toString());
return applyTemplate(new StringReader(context.getModel().getRelease().getGitService().getDownloadUrlFormat()), newProps, "downloadUrl");
}