[brew] support the binary stanza in cask template. Resolves #300

This commit is contained in:
Andres Almiray
2021-07-21 23:14:34 +02:00
parent 36374b97cc
commit 77cd5819ff
9 changed files with 295 additions and 34 deletions

View File

@@ -27,6 +27,7 @@ import org.jreleaser.model.JReleaserContext;
import org.jreleaser.model.JReleaserModel;
import org.jreleaser.util.Env;
import org.jreleaser.util.Errors;
import org.jreleaser.util.PlatformUtils;
import java.util.ArrayList;
import java.util.List;
@@ -108,36 +109,51 @@ public abstract class BrewValidator extends Validator {
}
private static void validateCask(JReleaserContext context, Distribution distribution, Brew tool, Errors errors) {
if (distribution.getType() == Distribution.DistributionType.SINGLE_JAR) {
tool.getCask().disable();
return;
}
context.getLogger().debug("distribution.{}.brew.cask", distribution.getName());
// look for a .dmg o .pkg
// look for a .dmg, .pkg. or .zip
int dmgFound = 0;
int pkgFound = 0;
int zipFound = 0;
String pkgName = "";
for (Artifact artifact : distribution.getArtifacts()) {
if (!artifact.isActive()) continue;
if (artifact.getPath().endsWith(".dmg") && !isTrue(artifact.getExtraProperties().get("skipBrew")))
if (!artifact.isActive() || !PlatformUtils.isMac(artifact.getPlatform())) continue;
if (artifact.getPath().endsWith(".dmg") && !isTrue(artifact.getExtraProperties().get("skipBrew"))) {
dmgFound++;
if (artifact.getPath().endsWith(".pkg") && !isTrue(artifact.getExtraProperties().get("skipBrew"))) {
} else if (artifact.getPath().endsWith(".pkg") && !isTrue(artifact.getExtraProperties().get("skipBrew"))) {
pkgFound++;
pkgName = artifact.getEffectivePath(context).getFileName().toString();
} else if (artifact.getPath().endsWith(".zip") && !isTrue(artifact.getExtraProperties().get("skipBrew"))) {
zipFound++;
}
}
Cask cask = tool.getCask();
if (dmgFound == 0 && pkgFound == 0) {
if (dmgFound == 0 && pkgFound == 0 && zipFound == 0) {
// no artifacts found, disable cask
cask.disable();
return;
} else if (dmgFound > 0 && pkgFound > 0) {
errors.configuration("distribution." + distribution.getName() + ".brew can only have a single .dmg or .pkg artifact");
return;
} else if (dmgFound > 1) {
errors.configuration("distribution." + distribution.getName() + ".brew has more than one .dmg artifact");
cask.disable();
return;
} else if (pkgFound > 1) {
errors.configuration("distribution." + distribution.getName() + ".brew has more than one .pkg artifact");
cask.disable();
return;
} else if (zipFound > 1) {
errors.configuration("distribution." + distribution.getName() + ".brew has more than one .zip artifact");
cask.disable();
return;
} else if (dmgFound + pkgFound + zipFound > 1) {
errors.configuration("distribution." + distribution.getName() + ".brew can only have a single matching .dmg, .pkg, or .zip artifact");
cask.disable();
return;
}
@@ -156,6 +172,10 @@ public abstract class BrewValidator extends Validator {
} else if (!cask.getAppName().endsWith(".app")) {
cask.setAppName(cask.getAppName() + ".app");
}
if (zipFound > 0) {
cask.setAppName("");
cask.setPkgName("");
}
if (isBlank(cask.getName())) {
cask.setName(tool.getResolvedFormulaName(context).toLowerCase());

View File

@@ -0,0 +1,53 @@
cask "{{brewCaskName}}" do
version "{{projectVersion}}"
sha256 "{{distributionChecksumSha256}}"
url "{{distributionUrl}}",
verified: "{{repoHost}}"
name "{{brewCaskDisplayName}}"
desc "{{projectDescription}}"
homepage "{{projectWebsite}}"
{{#brewCaskHasAppcast}}
appcast {{brewCaskAppcast}}
{{/brewCaskHasAppcast}}
auto_updates true
{{#brewHasLivecheck}}
livecheck do
{{#brewLivecheck}}
{{.}}
{{/brewLivecheck}}
end
{{/brewHasLivecheck}}
{{#brewDependencies}}
depends_on {{.}}
{{/brewDependencies}}
{{#brewCaskHasPkg}}
pkg "{{brewCaskPkg}}"
{{/brewCaskHasPkg}}
{{#brewCaskHasApp}}
app "{{brewCaskApp}}"
{{/brewCaskHasApp}}
{{#brewCaskHasBinary}}
binary "{{distributionArtifactName}}/bin/{{distributionExecutable}}"
{{/brewCaskHasBinary}}
{{#brewCaskHasUninstall}}
{{#brewCaskUninstall}}
uninstall {{name}}: [
{{#items}}
"{{.}}",
{{/items}}
]
{{/brewCaskUninstall}}
{{/brewCaskHasUninstall}}
{{#brewCaskHasZap}}
{{#brewCaskZap}}
zap {{name}}: [
{{#items}}
"{{.}}",
{{/items}}
]
{{/brewCaskZap}}
{{/brewCaskHasZap}}
end

View File

@@ -0,0 +1,53 @@
cask "{{brewCaskName}}" do
version "{{projectVersion}}"
sha256 "{{distributionChecksumSha256}}"
url "{{distributionUrl}}",
verified: "{{repoHost}}"
name "{{brewCaskDisplayName}}"
desc "{{projectDescription}}"
homepage "{{projectWebsite}}"
{{#brewCaskHasAppcast}}
appcast {{brewCaskAppcast}}
{{/brewCaskHasAppcast}}
auto_updates true
{{#brewHasLivecheck}}
livecheck do
{{#brewLivecheck}}
{{.}}
{{/brewLivecheck}}
end
{{/brewHasLivecheck}}
{{#brewDependencies}}
depends_on {{.}}
{{/brewDependencies}}
{{#brewCaskHasPkg}}
pkg "{{brewCaskPkg}}"
{{/brewCaskHasPkg}}
{{#brewCaskHasApp}}
app "{{brewCaskApp}}"
{{/brewCaskHasApp}}
{{#brewCaskHasBinary}}
binary "{{distributionArtifactName}}/bin/{{distributionExecutable}}"
{{/brewCaskHasBinary}}
{{#brewCaskHasUninstall}}
{{#brewCaskUninstall}}
uninstall {{name}}: [
{{#items}}
"{{.}}",
{{/items}}
]
{{/brewCaskUninstall}}
{{/brewCaskHasUninstall}}
{{#brewCaskHasZap}}
{{#brewCaskZap}}
zap {{name}}: [
{{#items}}
"{{.}}",
{{/items}}
]
{{/brewCaskZap}}
{{/brewCaskHasZap}}
end

View File

@@ -0,0 +1,53 @@
cask "{{brewCaskName}}" do
version "{{projectVersion}}"
sha256 "{{distributionChecksumSha256}}"
url "{{distributionUrl}}",
verified: "{{repoHost}}"
name "{{brewCaskDisplayName}}"
desc "{{projectDescription}}"
homepage "{{projectWebsite}}"
{{#brewCaskHasAppcast}}
appcast {{brewCaskAppcast}}
{{/brewCaskHasAppcast}}
auto_updates true
{{#brewHasLivecheck}}
livecheck do
{{#brewLivecheck}}
{{.}}
{{/brewLivecheck}}
end
{{/brewHasLivecheck}}
{{#brewDependencies}}
depends_on {{.}}
{{/brewDependencies}}
{{#brewCaskHasPkg}}
pkg "{{brewCaskPkg}}"
{{/brewCaskHasPkg}}
{{#brewCaskHasApp}}
app "{{brewCaskApp}}"
{{/brewCaskHasApp}}
{{#brewCaskHasBinary}}
binary "{{distributionArtifactName}}/bin/{{distributionExecutable}}"
{{/brewCaskHasBinary}}
{{#brewCaskHasUninstall}}
{{#brewCaskUninstall}}
uninstall {{name}}: [
{{#items}}
"{{.}}",
{{/items}}
]
{{/brewCaskUninstall}}
{{/brewCaskHasUninstall}}
{{#brewCaskHasZap}}
{{#brewCaskZap}}
zap {{name}}: [
{{#items}}
"{{.}}",
{{/items}}
]
{{/brewCaskZap}}
{{/brewCaskHasZap}}
end

View File

@@ -0,0 +1,53 @@
cask "{{brewCaskName}}" do
version "{{projectVersion}}"
sha256 "{{distributionChecksumSha256}}"
url "{{distributionUrl}}",
verified: "{{repoHost}}"
name "{{brewCaskDisplayName}}"
desc "{{projectDescription}}"
homepage "{{projectWebsite}}"
{{#brewCaskHasAppcast}}
appcast {{brewCaskAppcast}}
{{/brewCaskHasAppcast}}
auto_updates true
{{#brewHasLivecheck}}
livecheck do
{{#brewLivecheck}}
{{.}}
{{/brewLivecheck}}
end
{{/brewHasLivecheck}}
{{#brewDependencies}}
depends_on {{.}}
{{/brewDependencies}}
{{#brewCaskHasPkg}}
pkg "{{brewCaskPkg}}"
{{/brewCaskHasPkg}}
{{#brewCaskHasApp}}
app "{{brewCaskApp}}"
{{/brewCaskHasApp}}
{{#brewCaskHasBinary}}
binary "{{distributionArtifactName}}/bin/{{distributionExecutable}}"
{{/brewCaskHasBinary}}
{{#brewCaskHasUninstall}}
{{#brewCaskUninstall}}
uninstall {{name}}: [
{{#items}}
"{{.}}",
{{/items}}
]
{{/brewCaskUninstall}}
{{/brewCaskHasUninstall}}
{{#brewCaskHasZap}}
{{#brewCaskZap}}
zap {{name}}: [
{{#items}}
"{{.}}",
{{/items}}
]
{{/brewCaskZap}}
{{/brewCaskHasZap}}
end

View File

@@ -29,6 +29,9 @@ cask "{{brewCaskName}}" do
{{#brewCaskHasApp}}
app "{{brewCaskApp}}"
{{/brewCaskHasApp}}
{{#brewCaskHasBinary}}
binary "{{distributionArtifactName}}/bin/{{distributionExecutable}}"
{{/brewCaskHasBinary}}
{{#brewCaskHasUninstall}}
{{#brewCaskUninstall}}
uninstall {{name}}: [

View File

@@ -323,7 +323,7 @@ abstract class AbstractToolProcessor<T extends Tool> implements ToolProcessor<T>
}
Map<String, Object> newProps = new LinkedHashMap<>(props);
newProps.put(Constants.KEY_ARTIFACT_FILE_NAME, artifactFileName);
String artifactUrl = applyTemplate(context.getModel().getRelease().getGitService().getDownloadUrl(), newProps, "downloadUrl");
String artifactUrl = applyTemplate(context.getModel().getRelease().getGitService().getDownloadUrl(), newProps);
props.put("artifact" + platform + "Url", artifactUrl);
props.putAll(context.getModel().getUpload()
.resolveDownloadUrls(context, distribution, artifact, "artifact" + platform));

View File

@@ -17,7 +17,9 @@
*/
package org.jreleaser.tools;
import org.jreleaser.model.Artifact;
import org.jreleaser.model.Brew;
import org.jreleaser.model.Cask;
import org.jreleaser.model.Distribution;
import org.jreleaser.model.GitService;
import org.jreleaser.model.JReleaserContext;
@@ -27,12 +29,14 @@ import org.jreleaser.util.Constants;
import org.jreleaser.util.MustacheUtils;
import java.nio.file.Path;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
import static org.jreleaser.templates.TemplateUtils.trimTplExtension;
import static org.jreleaser.util.MustacheUtils.applyTemplate;
import static org.jreleaser.util.MustacheUtils.passThrough;
import static org.jreleaser.util.StringUtils.getFilename;
import static org.jreleaser.util.StringUtils.isNotBlank;
import static org.jreleaser.util.StringUtils.isTrue;
@@ -71,29 +75,44 @@ public class BrewToolProcessor extends AbstractRepositoryToolProcessor<Brew> {
.collect(Collectors.toList()));
}
if ((distribution.getType() == Distribution.DistributionType.JAVA_BINARY ||
Cask cask = tool.getCask();
if (cask.isEnabled()) {
props.put(Constants.KEY_BREW_CASK_NAME, cask.getResolvedCaskName(props));
props.put(Constants.KEY_BREW_CASK_DISPLAY_NAME, cask.getResolvedDisplayName(props));
props.put(Constants.KEY_BREW_CASK_HAS_UNINSTALL, !cask.getUninstallItems().isEmpty());
props.put(Constants.KEY_BREW_CASK_HAS_PKG, isNotBlank(cask.getPkgName()));
if (isNotBlank(cask.getPkgName())) {
props.put(Constants.KEY_BREW_CASK_PKG, cask.getResolvedPkgName(props));
}
props.put(Constants.KEY_BREW_CASK_HAS_APP, isNotBlank(cask.getAppName()));
if (isNotBlank(cask.getAppName())) {
props.put(Constants.KEY_BREW_CASK_APP, cask.getResolvedAppName(props));
}
props.put(Constants.KEY_BREW_CASK_UNINSTALL, cask.getUninstallItems());
props.put(Constants.KEY_BREW_CASK_HAS_ZAP, !cask.getZapItems().isEmpty());
props.put(Constants.KEY_BREW_CASK_ZAP, cask.getZapItems());
String appcast = cask.getResolvedAppcast(props);
props.put(Constants.KEY_BREW_CASK_HAS_APPCAST, isNotBlank(appcast));
props.put(Constants.KEY_BREW_CASK_APPCAST, appcast);
for (Artifact artifact : distribution.getArtifacts()) {
if (!artifact.isActive()) continue;
if (artifact.getPath().endsWith(".zip") && !isTrue(artifact.getExtraProperties().get("skipBrew"))) {
String artifactFileName = artifact.getEffectivePath(context).getFileName().toString();
Map<String, Object> newProps = new LinkedHashMap<>(props);
newProps.put(Constants.KEY_ARTIFACT_FILE_NAME, artifactFileName);
props.put(Constants.KEY_DISTRIBUTION_ARTIFACT_NAME, getFilename(artifactFileName));
String artifactUrl = applyTemplate(context.getModel().getRelease().getGitService().getDownloadUrl(), newProps);
props.put(Constants.KEY_DISTRIBUTION_URL, artifactUrl);
props.put(Constants.KEY_BREW_CASK_HAS_BINARY, true);
break;
}
}
} else if ((distribution.getType() == Distribution.DistributionType.JAVA_BINARY ||
distribution.getType() == Distribution.DistributionType.SINGLE_JAR) &&
!isTrue(tool.getExtraProperties().get("javaSkip")) &&
!isTrue(tool.getExtraProperties().get("skipJava"))) {
tool.addDependency("openjdk@" + props.get(Constants.KEY_DISTRIBUTION_JAVA_VERSION));
} else if (distribution.getType() == Distribution.DistributionType.NATIVE_PACKAGE) {
props.put(Constants.KEY_BREW_CASK_NAME, tool.getCask().getResolvedCaskName(props));
props.put(Constants.KEY_BREW_CASK_DISPLAY_NAME, tool.getCask().getResolvedDisplayName(props));
props.put(Constants.KEY_BREW_CASK_HAS_UNINSTALL, !tool.getCask().getUninstallItems().isEmpty());
props.put(Constants.KEY_BREW_CASK_HAS_PKG, isNotBlank(tool.getCask().getPkgName()));
if (isNotBlank(tool.getCask().getPkgName())) {
props.put(Constants.KEY_BREW_CASK_PKG, tool.getCask().getResolvedPkgName(props));
}
props.put(Constants.KEY_BREW_CASK_HAS_APP, isNotBlank(tool.getCask().getAppName()));
if (isNotBlank(tool.getCask().getAppName())) {
props.put(Constants.KEY_BREW_CASK_APP, tool.getCask().getResolvedAppName(props));
}
props.put(Constants.KEY_BREW_CASK_UNINSTALL, tool.getCask().getUninstallItems());
props.put(Constants.KEY_BREW_CASK_HAS_ZAP, !tool.getCask().getZapItems().isEmpty());
props.put(Constants.KEY_BREW_CASK_ZAP, tool.getCask().getZapItems());
String appcast = tool.getCask().getResolvedAppcast(props);
props.put(Constants.KEY_BREW_CASK_HAS_APPCAST, isNotBlank(appcast));
props.put(Constants.KEY_BREW_CASK_APPCAST, appcast);
}
props.put(Constants.KEY_BREW_DEPENDENCIES, tool.getDependenciesAsList()
@@ -113,12 +132,18 @@ public class BrewToolProcessor extends AbstractRepositoryToolProcessor<Brew> {
throws ToolProcessingException {
fileName = trimTplExtension(fileName);
Path outputFile = "formula.rb".equals(fileName) ?
outputDirectory.resolve("Formula").resolve(distribution.getExecutable().concat(".rb")) :
("cask.rb".equals(fileName) ?
if (tool.getCask().isEnabled()) {
if ("formula.rb".equals(fileName)) return;
Path outputFile = "cask.rb".equals(fileName) ?
outputDirectory.resolve("Casks").resolve(tool.getCask().getResolvedCaskName(props).concat(".rb")) :
outputDirectory.resolve(fileName));
writeFile(content, outputFile);
outputDirectory.resolve(fileName);
writeFile(content, outputFile);
} else {
if ("cask.rb".equals(fileName)) return;
Path outputFile = "formula.rb".equals(fileName) ?
outputDirectory.resolve("Formula").resolve(distribution.getExecutable().concat(".rb")) :
outputDirectory.resolve(fileName);
writeFile(content, outputFile);
}
}
}

View File

@@ -136,6 +136,7 @@ public interface Constants {
String KEY_BREW_CASK_ZAP = "brewCaskZap";
String KEY_BREW_CASK_HAS_APPCAST = "brewCaskHasAppcast";
String KEY_BREW_CASK_APPCAST = "brewCaskAppcast";
String KEY_BREW_CASK_HAS_BINARY = "brewCaskHasBinary";
// Docker
String KEY_DOCKER_SPEC_NAME = "dockerSpecName";