Switch sdkman api to Feign

This commit is contained in:
Andres Almiray
2021-03-10 18:41:46 +01:00
parent 1c94fe0557
commit c0fc499b2b
26 changed files with 587 additions and 986 deletions

View File

@@ -16,5 +16,5 @@
* limitations under the License.
*/
dependencies {
api('kr.motd.maven:os-maven-plugin:1.6.2') { transitive = false }
api('kr.motd.maven:os-maven-plugin:1.7.0') { transitive = false }
}

View File

@@ -24,11 +24,12 @@ targetCompatibility = 1.8
kordampPluginVersion = 0.43.0
kordampBuildVersion = 2.2.0
gitPluginVersion = 3.0.0
checksumPluginVersion = 1.1.0
checksumPluginVersion = 1.2.0
shadowPluginVersion = 6.1.0
asmVersion = 8.0.1
jacksonVersion = 2.11.3
feignVersion = 10.12
jacksonVersion = 2.12.2
jgitVersion = 5.10.0.202012080955-r
jipsyVersion = 1.1.0
junitVersion = 5.7.0
@@ -36,9 +37,9 @@ hamcrestVersion = 2.2
mavenVersion = 3.6.0
mustacheVersion = 0.9.7
okhttpVersion = 3.14.9
picocliVersion = 4.5.2
picocliVersion = 4.6.1
plexusVersion = 3.1.0
tikaVersion = 1.24.1
tikaVersion = 1.25
wiremockVersion = 2.27.2
slf4jVersion = 1.7.30
snakeYamlVersion = 1.27

View File

@@ -1,19 +0,0 @@
#
# 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.
#
project_description = Java SDK for Gitlab

View File

@@ -1,93 +0,0 @@
/*
* 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.sdk.gitlab;
import org.apache.tika.Tika;
import org.apache.tika.mime.MediaType;
import org.gitlab4j.api.GitLabApi;
import org.gitlab4j.api.GitLabApiException;
import org.gitlab4j.api.models.FileUpload;
import org.gitlab4j.api.models.Release;
import org.gitlab4j.api.models.ReleaseParams;
import org.jreleaser.model.releaser.ReleaseException;
import org.jreleaser.util.Logger;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.List;
/**
* @author Andres Almiray
* @since 0.1.0
*/
public class Gitlab {
static final String ENDPOINT = "https://gitlab.com/";
private final Tika tika = new Tika();
private final Logger logger;
private final GitLabApi gitlab;
Gitlab(Logger logger, String authorization) throws ReleaseException {
this(logger, ENDPOINT, authorization);
}
Gitlab(Logger logger, String endpoint, String authorization) throws ReleaseException {
this.logger = logger;
gitlab = new GitLabApi(endpoint, authorization);
}
Release findReleaseByTag(String repo, String tagName) throws GitLabApiException, IOException {
logger.debug("Fetching release on {} with tag {}", repo, tagName);
return gitlab.getReleasesApi().getRelease(encode(repo), tagName);
}
void deleteRelease(String repo, String tagName) throws GitLabApiException, IOException {
logger.debug("Deleting release on {} with tag {}", repo, tagName);
gitlab.getReleasesApi().deleteRelease(encode(repo), tagName);
}
Release createRelease(String repo, ReleaseParams params) throws GitLabApiException, IOException {
logger.debug("Creating release on {} with tag {}", repo, params.getTagName());
return gitlab.getReleasesApi().createRelease(encode(repo), params);
}
void uploadAssets(String repo, Release release, List<Path> assets) throws GitLabApiException, IOException {
for (Path asset : assets) {
if (0 == asset.toFile().length()) {
// do not upload empty files
continue;
}
logger.debug("Uploading asset {}", asset.getFileName().toString());
try {
FileUpload upload = gitlab.getProjectApi()
.uploadFile(encode(repo), asset.toFile(), MediaType.parse(tika.detect(asset)).toString());
// gitlab.getReleaseLinksApi().link(...)
} catch (Exception e) {
logger.warn("Failed to upload " + asset.getFileName(), e);
}
}
}
private Object encode(String repo) throws IOException {
return URLEncoder.encode(repo, StandardCharsets.UTF_8.displayName());
}
}

View File

@@ -1,221 +0,0 @@
/*
* 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.sdk.gitlab;
import org.gitlab4j.api.GitLabApiException;
import org.gitlab4j.api.models.Release;
import org.gitlab4j.api.models.ReleaseParams;
import org.jreleaser.model.Changelog;
import org.jreleaser.model.JReleaserModel;
import org.jreleaser.model.releaser.ReleaseException;
import org.jreleaser.model.releaser.Releaser;
import org.jreleaser.model.releaser.ReleaserBuilder;
import org.jreleaser.util.Logger;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import static java.util.Objects.requireNonNull;
import static org.jreleaser.util.StringUtils.isNotBlank;
import static org.jreleaser.util.StringUtils.requireNonBlank;
/**
* @author Andres Almiray
* @since 0.1.0
*/
public class GitlabReleaser implements Releaser {
private final Path basedir;
private final Logger logger;
private final String repo;
private final String authorization;
private final String tagName;
private final String ref;
private final Changelog changelog;
private final String releaseName;
private final boolean overwrite;
private final boolean allowUploadToExisting;
private final String apiEndpoint;
private final List<Path> assets = new ArrayList<>();
public GitlabReleaser(Path basedir, Logger logger, String repo, String authorization,
String tagName, String ref, String releaseName,
Changelog changelog, boolean overwrite,
boolean allowUploadToExisting, String apiEndpoint, List<Path> assets) {
this.basedir = basedir;
this.logger = logger;
this.repo = repo;
this.authorization = authorization;
this.tagName = tagName;
this.ref = ref;
this.releaseName = releaseName;
this.changelog = changelog;
this.overwrite = overwrite;
this.allowUploadToExisting = allowUploadToExisting;
this.apiEndpoint = apiEndpoint;
this.assets.addAll(assets);
}
public void release() throws ReleaseException {
Gitlab api = new Gitlab(logger, apiEndpoint, authorization);
try {
Release release = api.findReleaseByTag(repo, tagName);
if (null != release) {
if (overwrite) {
api.deleteRelease(repo, tagName);
createRelease(api);
} else if (allowUploadToExisting) {
api.uploadAssets(repo, release, assets);
} else {
throw new IllegalStateException("Gitlab release failed because release " +
tagName + " already exists");
}
} else {
createRelease(api);
}
} catch (GitLabApiException | IOException | IllegalStateException e) {
throw new ReleaseException(e);
}
}
private void createRelease(Gitlab api) throws GitLabApiException, IOException {
ReleaseParams params = new ReleaseParams();
params.setName(releaseName);
params.setTagName(tagName);
params.setRef(ref);
Release release = api.createRelease(repo, params);
api.uploadAssets(repo, release, assets);
}
public static Builder builder() {
return new Builder();
}
public static class Builder implements ReleaserBuilder<GitlabReleaser> {
private final List<Path> assets = new ArrayList<>();
private Path basedir;
private Logger logger;
private String repo;
private String authorization;
private String tagName;
private String ref = "main";
private String releaseName;
private Changelog changelog;
private boolean overwrite;
private boolean allowUploadToExisting;
private String apiEndpoint = Gitlab.ENDPOINT;
public Builder basedir(Path basedir) {
this.basedir = requireNonNull(basedir, "'basedir' must not be null");
return this;
}
public Builder logger(Logger logger) {
this.logger = requireNonNull(logger, "'logger' must not be null");
return this;
}
public Builder repo(String repo) {
this.repo = requireNonBlank(repo, "'repo' must not be blank");
return this;
}
public Builder authorization(String authorization) {
this.authorization = requireNonBlank(authorization, "'authorization' must not be blank");
return this;
}
public Builder tagName(String tagName) {
this.tagName = requireNonBlank(tagName, "'tagName' must not be blank");
return this;
}
public Builder ref(String ref) {
this.ref = requireNonBlank(ref, "'ref' must not be blank");
return this;
}
public Builder releaseName(String releaseName) {
this.releaseName = requireNonBlank(releaseName, "'releaseName' must not be blank");
return this;
}
public Builder changelog(Changelog changelog) {
this.changelog = changelog;
return this;
}
public Builder overwrite(boolean overwrite) {
this.overwrite = overwrite;
return this;
}
public Builder allowUploadToExisting(boolean allowUploadToExisting) {
this.allowUploadToExisting = allowUploadToExisting;
return this;
}
public Builder apiEndpoint(String apiEndpoint) {
this.apiEndpoint = isNotBlank(apiEndpoint) ? apiEndpoint : Gitlab.ENDPOINT;
return this;
}
public Builder setReleaseAssets(List<Path> assets) {
if (null != assets) {
this.assets.addAll(assets);
}
return this;
}
@Override
public GitlabReleaser build() {
requireNonNull(basedir, "'basedir' must not be null");
requireNonNull(logger, "'logger' must not be null");
requireNonBlank(repo, "'repo' must not be blank");
requireNonBlank(authorization, "'authorization' must not be blank");
requireNonBlank(tagName, "'tagName' must not be blank");
requireNonBlank(ref, "'ref' must not be blank");
requireNonBlank(releaseName, "'releaseName' must not be blank");
if (assets.isEmpty()) {
throw new IllegalArgumentException("'assets must not be empty");
}
return new GitlabReleaser(basedir, logger, repo, authorization,
tagName, ref, releaseName,
changelog, overwrite,
allowUploadToExisting, apiEndpoint, assets);
}
@Override
public GitlabReleaser buildFromModel(Path basedir, JReleaserModel model) {
basedir(basedir);
repo(model.getRelease().getGitlab().getRepoName());
authorization(model.getRelease().getGitlab().getAuthorization());
tagName(model.getRelease().getGitlab().getTagName());
ref(model.getRelease().getGitlab().getRef());
releaseName(model.getRelease().getGitlab().getRepoName());
overwrite(model.getRelease().getGitlab().isOverwrite());
allowUploadToExisting(model.getRelease().getGitlab().isAllowUploadToExisting());
apiEndpoint(model.getRelease().getGitlab().getApiEndpoint());
changelog(model.getRelease().getGitlab().getChangelog());
return build();
}
}
}

View File

@@ -18,9 +18,10 @@
dependencies {
api project(':jreleaser-utils')
api "io.github.openfeign:feign-core:$feignVersion"
api "io.github.openfeign:feign-jackson:$feignVersion"
api "com.fasterxml.jackson.core:jackson-core:$jacksonVersion"
api "com.fasterxml.jackson.core:jackson-databind:$jacksonVersion"
api "com.squareup.okhttp3:okhttp:$okhttpVersion"
testImplementation "com.github.tomakehurst:wiremock-jre8:$wiremockVersion"
}

View File

@@ -1,66 +0,0 @@
/*
* 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.sdk.sdkman;
import okhttp3.Response;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* @author Andres Almiray
* @since 0.1.0
*/
abstract class AbstractMultiSdkmanCommand extends AbstractSdkmanCommand {
protected AbstractMultiSdkmanCommand(String consumerKey,
String consumerToken,
String candidate,
String version,
String apiHost,
boolean https) {
super(consumerKey,
consumerToken,
candidate,
version,
apiHost,
https);
}
protected Map<String, String> getPayload() {
Map<String, String> payload = new HashMap<>();
payload.put("candidate", candidate);
payload.put("version", version);
return payload;
}
protected abstract Response executeRequests() throws IOException;
@Override
public void execute() throws SdkmanException {
try {
Response resp = executeRequests();
int statusCode = resp.code();
if (statusCode < 200 || statusCode >= 300) {
throw new IllegalStateException("Server returned error " + resp.message());
}
} catch (Exception e) {
throw new SdkmanException("Sdk vendor operation failed", e);
}
}
}

View File

@@ -17,21 +17,6 @@
*/
package org.jreleaser.sdk.sdkman;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import static org.jreleaser.util.StringUtils.requireNonBlank;
/**
@@ -39,82 +24,18 @@ import static org.jreleaser.util.StringUtils.requireNonBlank;
* @since 0.1.0
*/
abstract class AbstractSdkmanCommand implements SdkmanCommand {
protected static final MediaType JSON = MediaType.get("application/json; charset=UTF-8");
protected final String consumerKey;
protected final String consumerToken;
protected final String candidate;
protected final String version;
protected final String apiHost;
protected final boolean https;
protected final Sdkman sdkman;
protected AbstractSdkmanCommand(String consumerKey,
protected AbstractSdkmanCommand(String apiHost,
String consumerKey,
String consumerToken,
String candidate,
String version,
String apiHost,
boolean https) {
this.consumerKey = consumerKey;
this.consumerToken = consumerToken;
String version) {
this.sdkman = new Sdkman(apiHost, consumerKey, consumerToken);
this.candidate = candidate;
this.version = version;
this.apiHost = apiHost;
this.https = https;
}
protected Map<String, String> getPayload() {
Map<String, String> payload = new HashMap<>();
payload.put("candidate", candidate);
payload.put("version", version);
return payload;
}
protected String toJson(Map<String, String> payload) {
try {
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(payload);
} catch (JsonProcessingException e) {
throw new IllegalArgumentException("Invalid JSON", e);
}
}
protected Response execCall(Request req) throws IOException {
req = req.newBuilder()
.addHeader("Consumer-Key", consumerKey)
.addHeader("Consumer-Token", consumerToken)
.addHeader("Content-Type", "application/json")
.addHeader("Accept", "application/json")
.build();
OkHttpClient client = new OkHttpClient();
try (Response response = client.newCall(req).execute()) {
return response;
}
}
protected URL createURL(String endpoint) {
try {
return createURI(endpoint).toURL();
} catch (MalformedURLException | URISyntaxException e) {
throw new IllegalArgumentException("Invalid URL", e);
}
}
private URI createURI(String endpoint) throws URISyntaxException {
String host = apiHost;
int i = host.indexOf("://");
if (i > -1) {
host = host.substring(i + 3);
}
String[] parts = host.split(":");
if (parts.length == 1) {
return new URI(https ? "https" : "http", host, endpoint, null);
} else if (parts.length == 2) {
return new URI(https ? "https" : "http", null, parts[0], Integer.parseInt(parts[1]), endpoint, null, null);
} else {
throw new URISyntaxException(apiHost, "Invalid");
}
}
static class Builder<S extends Builder<S>> {
@@ -122,8 +43,7 @@ abstract class AbstractSdkmanCommand implements SdkmanCommand {
protected String consumerToken;
protected String candidate;
protected String version;
protected String apiHost = "vendors.sdkman.io";
protected boolean https = true;
protected String apiHost = "https://vendors.sdkman.io";
protected final S self() {
return (S) this;
@@ -168,13 +88,5 @@ abstract class AbstractSdkmanCommand implements SdkmanCommand {
this.apiHost = requireNonBlank(apiHost, "'apiHost' must not be blank").trim();
return self();
}
/**
* Use HTTPS
*/
public S https(boolean https) {
this.https = https;
return self();
}
}
}

View File

@@ -1,58 +0,0 @@
/*
* 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.sdk.sdkman;
import okhttp3.Request;
import okhttp3.Response;
import java.util.Map;
/**
* @author Andres Almiray
* @since 0.1.0
*/
abstract class AbstractSingleSdkmanCommand extends AbstractSdkmanCommand {
protected AbstractSingleSdkmanCommand(String consumerKey,
String consumerToken,
String candidate,
String version,
String apiHost,
boolean https) {
super(consumerKey,
consumerToken,
candidate,
version,
apiHost,
https);
}
protected abstract Request createRequest(Map<String, String> payload);
@Override
public void execute() throws SdkmanException {
try {
Response resp = execCall(createRequest(getPayload()));
int statusCode = resp.code();
if (statusCode < 200 || statusCode >= 300) {
throw new IllegalStateException("Server returned error " + resp.message());
}
} catch (Exception e) {
throw new SdkmanException("Sdk vendor operation failed", e);
}
}
}

View File

@@ -17,55 +17,31 @@
*/
package org.jreleaser.sdk.sdkman;
import okhttp3.Request;
import okhttp3.RequestBody;
import java.util.Map;
import static org.jreleaser.util.StringUtils.isNotBlank;
import static org.jreleaser.util.StringUtils.requireNonBlank;
/**
* @author Andres Almiray
* @since 0.1.0
*/
public class AnnounceSdkmanCommand extends AbstractSingleSdkmanCommand {
public class AnnounceSdkmanCommand extends AbstractSdkmanCommand {
private final String hashtag;
private final String releaseNotesUrl;
private AnnounceSdkmanCommand(String consumerKey,
private AnnounceSdkmanCommand(String apiHost,
String consumerKey,
String consumerToken,
String candidate,
String version,
String apiHost,
boolean https,
String hashtag,
String releaseNotesUrl) {
super(consumerKey,
consumerToken,
candidate,
version,
apiHost,
https);
super(apiHost, consumerKey, consumerToken, candidate, version);
this.hashtag = hashtag;
this.releaseNotesUrl = releaseNotesUrl;
}
@Override
protected Map<String, String> getPayload() {
Map<String, String> payload = super.getPayload();
if (isNotBlank(hashtag)) payload.put("hashtag", hashtag.trim());
if (isNotBlank(releaseNotesUrl)) payload.put("url", releaseNotesUrl.trim());
return payload;
}
@Override
protected Request createRequest(Map<String, String> payload) {
RequestBody body = RequestBody.create(JSON, toJson(payload));
return new Request.Builder()
.url(createURL(ApiEndpoints.ANNOUNCE_ENDPOINT))
.post(body)
.build();
public void execute() throws SdkmanException {
sdkman.announce(candidate, version, hashtag, releaseNotesUrl);
}
public static Builder builder() {
@@ -93,19 +69,18 @@ public class AnnounceSdkmanCommand extends AbstractSingleSdkmanCommand {
}
public AnnounceSdkmanCommand build() {
requireNonBlank(apiHost, "'apiHost' must not be blank");
requireNonBlank(consumerKey, "'consumerKey' must not be blank");
requireNonBlank(consumerToken, "'consumerToken' must not be blank");
requireNonBlank(candidate, "'candidate' must not be blank");
requireNonBlank(version, "'version' must not be blank");
requireNonBlank(apiHost, "'apiHost' must not be blank");
return new AnnounceSdkmanCommand(
apiHost,
consumerKey,
consumerToken,
candidate,
version,
apiHost,
https,
hashtag,
releaseNotesUrl);
}

View File

@@ -17,35 +17,24 @@
*/
package org.jreleaser.sdk.sdkman;
import okhttp3.Request;
import okhttp3.RequestBody;
import java.util.Map;
import static org.jreleaser.sdk.sdkman.ApiEndpoints.DEFAULT_ENDPOINT;
import static org.jreleaser.util.StringUtils.requireNonBlank;
/**
* @author Andres Almiray
* @since 0.1.0
*/
public class DefaultSdkmanCommand extends AbstractSingleSdkmanCommand {
private DefaultSdkmanCommand(String consumerKey,
public class DefaultSdkmanCommand extends AbstractSdkmanCommand {
private DefaultSdkmanCommand(String apiHost,
String consumerKey,
String consumerToken,
String candidate,
String version,
String apiHost,
boolean https) {
super(consumerKey, consumerToken, candidate, version, apiHost, https);
String version) {
super(apiHost, consumerKey, consumerToken, candidate, version);
}
@Override
protected Request createRequest(Map<String, String> payload) {
RequestBody body = RequestBody.create(JSON, toJson(payload));
return new Request.Builder()
.url(createURL(DEFAULT_ENDPOINT))
.put(body)
.build();
public void execute() throws SdkmanException {
sdkman.setDefault(candidate, version);
}
public static Builder builder() {
@@ -54,19 +43,18 @@ public class DefaultSdkmanCommand extends AbstractSingleSdkmanCommand {
public static class Builder extends AbstractSdkmanCommand.Builder<Builder> {
public DefaultSdkmanCommand build() {
requireNonBlank(apiHost, "'apiHost' must not be blank");
requireNonBlank(consumerKey, "'consumerKey' must not be blank");
requireNonBlank(consumerToken, "'consumerToken' must not be blank");
requireNonBlank(candidate, "'candidate' must not be blank");
requireNonBlank(version, "'version' must not be blank");
requireNonBlank(apiHost, "'apiHost' must not be blank");
return new DefaultSdkmanCommand(
apiHost,
consumerKey,
consumerToken,
candidate,
version,
apiHost,
https);
version);
}
}
}

View File

@@ -17,19 +17,9 @@
*/
package org.jreleaser.sdk.sdkman;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import static org.jreleaser.sdk.sdkman.ApiEndpoints.ANNOUNCE_ENDPOINT;
import static org.jreleaser.sdk.sdkman.ApiEndpoints.DEFAULT_ENDPOINT;
import static org.jreleaser.sdk.sdkman.ApiEndpoints.RELEASE_ENDPOINT;
import static org.jreleaser.util.StringUtils.isBlank;
import static org.jreleaser.util.StringUtils.isNotBlank;
import static org.jreleaser.util.StringUtils.requireNonBlank;
@@ -38,94 +28,28 @@ import static org.jreleaser.util.StringUtils.requireNonBlank;
* @author Andres Almiray
* @since 0.1.0
*/
public class MajorReleaseSdkmanCommand extends AbstractMultiSdkmanCommand {
public class MajorReleaseSdkmanCommand extends AbstractSdkmanCommand {
private final String hashtag;
private final String releaseNotesUrl;
private final String url;
private final Map<String, String> platforms = new LinkedHashMap<>();
private MajorReleaseSdkmanCommand(String consumerKey,
private MajorReleaseSdkmanCommand(String apiHost,
String consumerKey,
String consumerToken,
String candidate,
String version,
String apiHost,
boolean https,
String hashtag,
String releaseNotesUrl,
String url,
Map<String, String> platforms) {
super(consumerKey,
consumerToken,
candidate,
version,
apiHost,
https);
super(apiHost, consumerKey, consumerToken, candidate, version);
this.hashtag = hashtag;
this.releaseNotesUrl = releaseNotesUrl;
this.url = url;
this.platforms.putAll(platforms);
}
@Override
protected Response executeRequests() throws IOException {
List<Response> responses = new ArrayList<>();
if (platforms.isEmpty()) {
responses.add(execCall(createRequest(getReleasePayload())));
} else {
for (Map.Entry<String, String> platform : platforms.entrySet()) {
Map<String, String> payload = super.getPayload();
payload.put("platform", platform.getKey());
payload.put("url", platform.getValue());
responses.add(execCall(createRequest(payload)));
}
}
responses.add(execCall(createAnnounceRequest()));
responses.add(execCall(createDefaultRequest()));
return responses.stream()
.filter(resp -> {
int statusCode = resp.code();
return statusCode < 200 || statusCode >= 300;
})
.findFirst()
.orElse(responses.get(responses.size() - 1));
}
private Map<String, String> getReleasePayload() {
Map<String, String> payload = super.getPayload();
payload.put("platform", "UNIVERSAL");
payload.put("url", url);
return payload;
}
private Request createRequest(Map<String, String> payload) {
RequestBody body = RequestBody.create(JSON, toJson(payload));
return new Request.Builder()
.url(createURL(RELEASE_ENDPOINT))
.post(body)
.build();
}
private Request createAnnounceRequest() {
Map<String, String> payload = super.getPayload();
if (isNotBlank(hashtag)) payload.put("hashtag", hashtag.trim());
if (isNotBlank(releaseNotesUrl)) payload.put("url", releaseNotesUrl.trim());
RequestBody body = RequestBody.create(JSON, toJson(payload));
return new Request.Builder()
.url(createURL(ANNOUNCE_ENDPOINT))
.post(body)
.build();
}
private Request createDefaultRequest() {
RequestBody body = RequestBody.create(JSON, toJson(super.getPayload()));
return new Request.Builder()
.url(createURL(DEFAULT_ENDPOINT))
.put(body)
.build();
public void execute() throws SdkmanException {
sdkman.majorRelease(candidate, version, platforms, hashtag, releaseNotesUrl);
}
public static Builder builder() {
@@ -191,27 +115,28 @@ public class MajorReleaseSdkmanCommand extends AbstractMultiSdkmanCommand {
}
public MajorReleaseSdkmanCommand build() {
requireNonBlank(apiHost, "'apiHost' must not be blank");
requireNonBlank(consumerKey, "'consumerKey' must not be blank");
requireNonBlank(consumerToken, "'consumerToken' must not be blank");
requireNonBlank(candidate, "'candidate' must not be blank");
requireNonBlank(version, "'version' must not be blank");
requireNonBlank(apiHost, "'apiHost' must not be blank");
// url is required if platforms is empty
if ((platforms.isEmpty()) && isBlank(url)) {
throw new IllegalArgumentException("Missing url");
}
if (isNotBlank(url)) {
platforms.put("UNIVERSAL", url);
}
return new MajorReleaseSdkmanCommand(
apiHost,
consumerKey,
consumerToken,
candidate,
version,
apiHost,
https,
hashtag,
releaseNotesUrl,
url,
platforms);
}
}

View File

@@ -17,18 +17,9 @@
*/
package org.jreleaser.sdk.sdkman;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import static org.jreleaser.sdk.sdkman.ApiEndpoints.ANNOUNCE_ENDPOINT;
import static org.jreleaser.sdk.sdkman.ApiEndpoints.RELEASE_ENDPOINT;
import static org.jreleaser.util.StringUtils.isBlank;
import static org.jreleaser.util.StringUtils.isNotBlank;
import static org.jreleaser.util.StringUtils.requireNonBlank;
@@ -37,85 +28,28 @@ import static org.jreleaser.util.StringUtils.requireNonBlank;
* @author Andres Almiray
* @since 0.1.0
*/
public class MinorReleaseSdkmanCommand extends AbstractMultiSdkmanCommand {
public class MinorReleaseSdkmanCommand extends AbstractSdkmanCommand {
private final String hashtag;
private final String releaseNotesUrl;
private final String url;
private final Map<String, String> platforms = new LinkedHashMap<>();
private MinorReleaseSdkmanCommand(String consumerKey,
private MinorReleaseSdkmanCommand(String apiHost,
String consumerKey,
String consumerToken,
String candidate,
String version,
String apiHost,
boolean https,
String hashtag,
String releaseNotesUrl,
String url,
Map<String, String> platforms) {
super(consumerKey,
consumerToken,
candidate,
version,
apiHost,
https);
super(apiHost, consumerKey, consumerToken, candidate, version);
this.hashtag = hashtag;
this.releaseNotesUrl = releaseNotesUrl;
this.url = url;
this.platforms.putAll(platforms);
}
@Override
protected Response executeRequests() throws IOException {
List<Response> responses = new ArrayList<>();
if (platforms.isEmpty()) {
responses.add(execCall(createRequest(getReleasePayload())));
} else {
for (Map.Entry<String, String> platform : platforms.entrySet()) {
Map<String, String> payload = super.getPayload();
payload.put("platform", platform.getKey());
payload.put("url", platform.getValue());
responses.add(execCall(createRequest(payload)));
}
}
responses.add(execCall(createAnnounceRequest()));
return responses.stream()
.filter(resp -> {
int statusCode = resp.code();
return statusCode < 200 || statusCode >= 300;
})
.findFirst()
.orElse(responses.get(responses.size() - 1));
}
private Map<String, String> getReleasePayload() {
Map<String, String> payload = super.getPayload();
payload.put("platform", "UNIVERSAL");
payload.put("url", url);
return payload;
}
private Request createRequest(Map<String, String> payload) {
RequestBody body = RequestBody.create(JSON, toJson(payload));
return new Request.Builder()
.url(createURL(RELEASE_ENDPOINT))
.post(body)
.build();
}
private Request createAnnounceRequest() {
Map<String, String> payload = super.getPayload();
if (isNotBlank(hashtag)) payload.put("hashtag", hashtag.trim());
if (isNotBlank(releaseNotesUrl)) payload.put("url", releaseNotesUrl.trim());
RequestBody body = RequestBody.create(JSON, toJson(payload));
return new Request.Builder()
.url(createURL(ANNOUNCE_ENDPOINT))
.post(body)
.build();
public void execute() throws SdkmanException {
sdkman.minorRelease(candidate, version, platforms, hashtag, releaseNotesUrl);
}
public static Builder builder() {
@@ -181,27 +115,28 @@ public class MinorReleaseSdkmanCommand extends AbstractMultiSdkmanCommand {
}
public MinorReleaseSdkmanCommand build() {
requireNonBlank(apiHost, "'apiHost' must not be blank");
requireNonBlank(consumerKey, "'consumerKey' must not be blank");
requireNonBlank(consumerToken, "'consumerToken' must not be blank");
requireNonBlank(candidate, "'candidate' must not be blank");
requireNonBlank(version, "'version' must not be blank");
requireNonBlank(apiHost, "'apiHost' must not be blank");
// url is required if platforms is empty
if ((platforms.isEmpty()) && isBlank(url)) {
throw new IllegalArgumentException("Missing url");
}
if (isNotBlank(url)) {
platforms.put("UNIVERSAL", url);
}
return new MinorReleaseSdkmanCommand(
apiHost,
consumerKey,
consumerToken,
candidate,
version,
apiHost,
https,
hashtag,
releaseNotesUrl,
url,
platforms);
}
}

View File

@@ -17,83 +17,33 @@
*/
package org.jreleaser.sdk.sdkman;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import static org.jreleaser.sdk.sdkman.ApiEndpoints.RELEASE_ENDPOINT;
import static org.jreleaser.util.StringUtils.isBlank;
import static org.jreleaser.util.StringUtils.isNotBlank;
import static org.jreleaser.util.StringUtils.requireNonBlank;
/**
* @author Andres Almiray
* @since 0.1.0
*/
public class ReleaseSdkmanCommand extends AbstractMultiSdkmanCommand {
private final String url;
public class ReleaseSdkmanCommand extends AbstractSdkmanCommand {
private final Map<String, String> platforms = new LinkedHashMap<>();
private ReleaseSdkmanCommand(String consumerKey,
private ReleaseSdkmanCommand(String apiHost,
String consumerKey,
String consumerToken,
String candidate,
String version,
String apiHost,
boolean https,
String url,
Map<String, String> platforms) {
super(consumerKey,
consumerToken,
candidate,
version,
apiHost,
https);
this.url = url;
super(apiHost, consumerKey, consumerToken, candidate, version);
this.platforms.putAll(platforms);
}
@Override
protected Map<String, String> getPayload() {
Map<String, String> payload = super.getPayload();
payload.put("platform", "UNIVERSAL");
payload.put("url", url);
return payload;
}
@Override
protected Response executeRequests() throws IOException {
if (platforms.isEmpty()) {
return execCall(createRequest(getPayload()));
}
List<Response> responses = new ArrayList<>();
for (Map.Entry<String, String> platform : platforms.entrySet()) {
Map<String, String> payload = super.getPayload();
payload.put("platform", platform.getKey());
payload.put("url", platform.getValue());
responses.add(execCall(createRequest(payload)));
}
return responses.stream()
.filter(resp -> {
int statusCode = resp.code();
return statusCode < 200 || statusCode >= 300;
})
.findFirst()
.orElse(responses.get(responses.size() - 1));
}
private Request createRequest(Map<String, String> payload) {
RequestBody body = RequestBody.create(JSON, toJson(payload));
return new Request.Builder()
.url(createURL(RELEASE_ENDPOINT))
.post(body)
.build();
public void execute() throws SdkmanException {
sdkman.release(candidate, version, platforms);
}
public static Builder builder() {
@@ -141,25 +91,26 @@ public class ReleaseSdkmanCommand extends AbstractMultiSdkmanCommand {
}
public ReleaseSdkmanCommand build() {
requireNonBlank(apiHost, "'apiHost' must not be blank");
requireNonBlank(consumerKey, "'consumerKey' must not be blank");
requireNonBlank(consumerToken, "'consumerToken' must not be blank");
requireNonBlank(candidate, "'candidate' must not be blank");
requireNonBlank(version, "'version' must not be blank");
requireNonBlank(apiHost, "'apiHost' must not be blank");
// url is required if platforms is empty
if ((platforms.isEmpty()) && isBlank(url)) {
throw new IllegalArgumentException("Missing url");
}
if (isNotBlank(url)) {
platforms.put("UNIVERSAL", url);
}
return new ReleaseSdkmanCommand(
apiHost,
consumerKey,
consumerToken,
candidate,
version,
apiHost,
https,
url,
platforms);
}
}

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.sdk.sdkman;
import feign.Feign;
import feign.Request;
import feign.jackson.JacksonDecoder;
import feign.jackson.JacksonEncoder;
import org.jreleaser.sdk.sdkman.api.Announce;
import org.jreleaser.sdk.sdkman.api.Candidate;
import org.jreleaser.sdk.sdkman.api.Release;
import org.jreleaser.sdk.sdkman.api.SdkmanAPI;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static org.jreleaser.util.StringUtils.requireNonBlank;
/**
* @author Andres Almiray
* @since 0.1.0
*/
public class Sdkman {
private final SdkmanAPI api;
public Sdkman(String apiHost, String consumerKey, String consumerToken) {
requireNonBlank(apiHost, "'apiHost' must not be blank");
requireNonBlank(consumerKey, "'consumerKey' must not be blank");
requireNonBlank(consumerToken, "'consumerToken' must not be blank");
api = Feign.builder()
.encoder(new JacksonEncoder())
.decoder(new JacksonDecoder())
.requestInterceptor(template -> {
template.header("Consumer-Key", consumerKey);
template.header("Consumer-Token", consumerToken);
template.header("Content-Type", "application/json");
template.header("Accept", "application/json");
})
.errorDecoder((methodKey, response) -> new IllegalStateException("Server returned error " + response.reason()))
.options(new Request.Options(20, TimeUnit.SECONDS, 60, TimeUnit.SECONDS, true))
.target(SdkmanAPI.class, apiHost);
}
public void announce(String candidate,
String version) throws SdkmanException {
Announce payload = Announce.of(candidate, version, null, null);
wrap(() -> api.announce(payload));
}
public void announce(String candidate,
String version,
String hashtag,
String releaseNotesUrl) throws SdkmanException {
Announce payload = Announce.of(candidate, version, hashtag, releaseNotesUrl);
wrap(() -> api.announce(payload));
}
public void setDefault(String candidate,
String version) throws SdkmanException {
Candidate payload = Candidate.of(candidate, version);
wrap(() -> api.setDefault(payload));
}
public void release(String candidate,
String version,
String url) throws SdkmanException {
Map<String, String> platforms = new LinkedHashMap<>();
platforms.put("UNIVERSAL", url);
release(candidate, version, platforms);
}
public void release(String candidate,
String version,
String platform,
String url) throws SdkmanException {
Map<String, String> platforms = new LinkedHashMap<>();
platforms.put(platform, url);
release(candidate, version, platforms);
}
public void release(String candidate,
String version,
Map<String, String> platforms) throws SdkmanException {
for (Map.Entry<String, String> entry : platforms.entrySet()) {
Release payload = Release.of(candidate, version, entry.getKey(), entry.getValue());
System.out.println(payload);
wrap(() -> api.release(payload));
}
}
public void majorRelease(String candidate,
String version,
String url,
String hashtag,
String releaseNotesUrl) throws SdkmanException {
Map<String, String> platforms = new LinkedHashMap<>();
platforms.put("UNIVERSAL", url);
majorRelease(candidate, version, platforms, hashtag, releaseNotesUrl);
}
public void majorRelease(String candidate,
String version,
String platform,
String url,
String hashtag,
String releaseNotesUrl) throws SdkmanException {
Map<String, String> platforms = new LinkedHashMap<>();
platforms.put(platform, url);
majorRelease(candidate, version, platforms, hashtag, releaseNotesUrl);
}
public void majorRelease(String candidate,
String version,
Map<String, String> platforms,
String hashtag,
String releaseNotesUrl) throws SdkmanException {
release(candidate, version, platforms);
announce(candidate, version, hashtag, releaseNotesUrl);
setDefault(candidate, version);
}
public void minorRelease(String candidate,
String version,
String url,
String hashtag,
String releaseNotesUrl) throws SdkmanException {
Map<String, String> platforms = new LinkedHashMap<>();
platforms.put("UNIVERSAL", url);
minorRelease(candidate, version, platforms, hashtag, releaseNotesUrl);
}
public void minorRelease(String candidate,
String version,
String platform,
String url,
String hashtag,
String releaseNotesUrl) throws SdkmanException {
Map<String, String> platforms = new LinkedHashMap<>();
platforms.put(platform, url);
minorRelease(candidate, version, platforms, hashtag, releaseNotesUrl);
}
public void minorRelease(String candidate,
String version,
Map<String, String> platforms,
String hashtag,
String releaseNotesUrl) throws SdkmanException {
release(candidate, version, platforms);
announce(candidate, version, hashtag, releaseNotesUrl);
}
private void wrap(Runnable runnable) throws SdkmanException {
try {
runnable.run();
} catch (RuntimeException e) {
throw new SdkmanException("Sdk vendor operation failed", e);
}
}
}

View File

@@ -0,0 +1,68 @@
/*
* 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.sdk.sdkman.api;
import static org.jreleaser.util.StringUtils.isNotBlank;
import static org.jreleaser.util.StringUtils.requireNonBlank;
/**
* @author Andres Almiray
* @since 0.1.0
*/
public class Announce extends Candidate {
private String hashtag;
private String releaseNotesUrl;
public String getHashtag() {
return hashtag;
}
public void setHashtag(String hashtag) {
this.hashtag = hashtag;
}
public String getReleaseNotesUrl() {
return releaseNotesUrl;
}
public void setReleaseNotesUrl(String releaseNotesUrl) {
this.releaseNotesUrl = releaseNotesUrl;
}
@Override
public String toString() {
return "Announce{" +
"candidate='" + candidate + '\'' +
", version='" + version + '\'' +
", hashtag='" + hashtag + '\'' +
", releaseNotesUrl='" + releaseNotesUrl + '\'' +
'}';
}
public static Announce of(String candidate,
String version,
String hashtag,
String releaseNotesUrl) {
Announce o = new Announce();
o.candidate = requireNonBlank(candidate, "'candidate' must not be blank").trim();
o.version = requireNonBlank(version, "'version' must not be blank").trim();
o.hashtag = isNotBlank(hashtag) ? hashtag.trim() : null;
o.releaseNotesUrl = isNotBlank(releaseNotesUrl) ? releaseNotesUrl.trim() : null;
return o;
}
}

View File

@@ -0,0 +1,60 @@
/*
* 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.sdk.sdkman.api;
import static org.jreleaser.util.StringUtils.requireNonBlank;
/**
* @author Andres Almiray
* @since 0.1.0
*/
public class Candidate {
protected String candidate;
protected String version;
public String getCandidate() {
return candidate;
}
public void setCandidate(String candidate) {
this.candidate = candidate;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
@Override
public String toString() {
return "Candidate{" +
"candidate='" + candidate + '\'' +
", version='" + version + '\'' +
'}';
}
public static Candidate of(String candidate, String version) {
Candidate o = new Candidate();
o.candidate = requireNonBlank(candidate, "'candidate' must not be blank").trim();
o.version = requireNonBlank(version, "'version' must not be blank").trim();
return o;
}
}

View File

@@ -0,0 +1,68 @@
/*
* 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.sdk.sdkman.api;
import static org.jreleaser.util.StringUtils.isNotBlank;
import static org.jreleaser.util.StringUtils.requireNonBlank;
/**
* @author Andres Almiray
* @since 0.1.0
*/
public class Release extends Candidate {
private String platform = "UNIVERSAL";
private String url;
public String getPlatform() {
return platform;
}
public void setPlatform(String platform) {
this.platform = platform;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
@Override
public String toString() {
return "Release{" +
"candidate='" + candidate + '\'' +
", version='" + version + '\'' +
", platform='" + platform + '\'' +
", url='" + url + '\'' +
'}';
}
public static Release of(String candidate,
String version,
String platform,
String url) {
Release o = new Release();
o.candidate = requireNonBlank(candidate, "'candidate' must not be blank").trim();
o.version = requireNonBlank(version, "'version' must not be blank").trim();
o.platform = isNotBlank(platform) ? platform.trim() : "UNIVERSAL";
o.url = requireNonBlank(url, "'url' must not be blank").trim();
return o;
}
}

View File

@@ -15,11 +15,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
dependencies {
api project(':jreleaser-model')
api project(':git-sdk')
package org.jreleaser.sdk.sdkman.api;
api "org.apache.tika:tika-core:$tikaVersion"
import feign.RequestLine;
api 'org.gitlab4j:gitlab4j-api:4.15.7'
}
/**
* @author Andres Almiray
* @since 0.1.0
*/
public interface SdkmanAPI {
@RequestLine("POST /announce/struct")
void announce(Announce announce);
@RequestLine("PUT /default")
void setDefault(Candidate candidate);
@RequestLine("POST /release")
void release(Release release);
}

View File

@@ -50,7 +50,6 @@ public class AnnounceSdkmanCommandTest {
.consumerToken("CONSUMER_TOKEN")
.candidate("jreleaser")
.version("1.0.0")
.https(false)
.build();
// when:
@@ -75,7 +74,6 @@ public class AnnounceSdkmanCommandTest {
.consumerToken("CONSUMER_TOKEN")
.candidate("jreleaser")
.version("1.0.0")
.https(false)
.build();
// expected:

View File

@@ -41,41 +41,39 @@ public class DefaultSdkmanCommandTest {
public void testStructuredAnnouncement() throws SdkmanException {
// given:
stubFor(put(urlEqualTo(ApiEndpoints.DEFAULT_ENDPOINT))
.willReturn(okJson("{\"status\": 202, \"message\":\"success\"}")));
.willReturn(okJson("{\"status\": 202, \"message\":\"success\"}")));
DefaultSdkmanCommand command = DefaultSdkmanCommand.builder()
.apiHost(api.baseUrl())
.consumerKey("CONSUMER_KEY")
.consumerToken("CONSUMER_TOKEN")
.candidate("jreleaser")
.version("1.0.0")
.https(false)
.build();
.apiHost(api.baseUrl())
.consumerKey("CONSUMER_KEY")
.consumerToken("CONSUMER_TOKEN")
.candidate("jreleaser")
.version("1.0.0")
.build();
// when:
command.execute();
// then:
Stubs.verifyPut(ApiEndpoints.DEFAULT_ENDPOINT, "{\n" +
" \"candidate\": \"jreleaser\",\n" +
" \"version\": \"1.0.0\"\n" +
"}");
" \"candidate\": \"jreleaser\",\n" +
" \"version\": \"1.0.0\"\n" +
"}");
}
@Test
public void testError() {
// given:
stubFor(post(urlEqualTo(ApiEndpoints.DEFAULT_ENDPOINT))
.willReturn(aResponse().withStatus(400)));
.willReturn(aResponse().withStatus(400)));
DefaultSdkmanCommand command = DefaultSdkmanCommand.builder()
.apiHost(api.baseUrl())
.consumerKey("CONSUMER_KEY")
.consumerToken("CONSUMER_TOKEN")
.candidate("jreleaser")
.version("1.0.0")
.https(false)
.build();
.apiHost(api.baseUrl())
.consumerKey("CONSUMER_KEY")
.consumerToken("CONSUMER_TOKEN")
.candidate("jreleaser")
.version("1.0.0")
.build();
// expected:
assertThrows(SdkmanException.class, command::execute);

View File

@@ -27,12 +27,12 @@ import static com.github.tomakehurst.wiremock.client.WireMock.put;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.jreleaser.sdk.sdkman.ApiEndpoints.ANNOUNCE_ENDPOINT;
import static org.jreleaser.sdk.sdkman.ApiEndpoints.DEFAULT_ENDPOINT;
import static org.jreleaser.sdk.sdkman.ApiEndpoints.RELEASE_ENDPOINT;
import static org.jreleaser.sdk.sdkman.Stubs.verifyPost;
import static org.jreleaser.sdk.sdkman.Stubs.verifyPut;
import static org.junit.jupiter.api.Assertions.assertThrows;
/**
* @author Andres Almiray
@@ -46,57 +46,55 @@ public class MajorReleaseSdkmanCommandTest {
public void testMajorReleaseWithAnnouncement() throws SdkmanException {
// given:
stubFor(post(urlEqualTo(RELEASE_ENDPOINT))
.willReturn(okJson("{\"status\": 201, \"message\":\"success\"}")));
.willReturn(okJson("{\"status\": 201, \"message\":\"success\"}")));
stubFor(post(urlEqualTo(ANNOUNCE_ENDPOINT))
.willReturn(okJson("{\"status\": 201, \"message\":\"success\"}")));
.willReturn(okJson("{\"status\": 201, \"message\":\"success\"}")));
stubFor(put(urlEqualTo(DEFAULT_ENDPOINT))
.willReturn(okJson("{\"status\": 201, \"message\":\"success\"}")));
.willReturn(okJson("{\"status\": 201, \"message\":\"success\"}")));
MajorReleaseSdkmanCommand command = MajorReleaseSdkmanCommand.builder()
.apiHost(api.baseUrl())
.consumerKey("CONSUMER_KEY")
.consumerToken("CONSUMER_TOKEN")
.candidate("jreleaser")
.version("1.0.0")
.url("https://host/jreleaser-1.0.0.zip")
.https(false)
.build();
.apiHost(api.baseUrl())
.consumerKey("CONSUMER_KEY")
.consumerToken("CONSUMER_TOKEN")
.candidate("jreleaser")
.version("1.0.0")
.url("https://host/jreleaser-1.0.0.zip")
.build();
// when:
command.execute();
// then:
verifyPost(RELEASE_ENDPOINT, "{\n" +
" \"candidate\": \"jreleaser\",\n" +
" \"version\": \"1.0.0\",\n" +
" \"platform\": \"UNIVERSAL\",\n" +
" \"url\": \"https://host/jreleaser-1.0.0.zip\"\n" +
"}");
" \"candidate\": \"jreleaser\",\n" +
" \"version\": \"1.0.0\",\n" +
" \"platform\": \"UNIVERSAL\",\n" +
" \"url\": \"https://host/jreleaser-1.0.0.zip\"\n" +
"}");
verifyPost(ANNOUNCE_ENDPOINT, "{\n" +
" \"candidate\": \"jreleaser\",\n" +
" \"version\": \"1.0.0\"\n" +
"}");
" \"candidate\": \"jreleaser\",\n" +
" \"version\": \"1.0.0\"\n" +
"}");
verifyPut(DEFAULT_ENDPOINT, "{\n" +
" \"candidate\": \"jreleaser\",\n" +
" \"version\": \"1.0.0\"\n" +
"}");
" \"candidate\": \"jreleaser\",\n" +
" \"version\": \"1.0.0\"\n" +
"}");
}
@Test
public void testError() {
// given:
stubFor(post(urlEqualTo(RELEASE_ENDPOINT))
.willReturn(aResponse().withStatus(500)));
.willReturn(aResponse().withStatus(500)));
MajorReleaseSdkmanCommand command = MajorReleaseSdkmanCommand.builder()
.apiHost(api.baseUrl())
.consumerKey("CONSUMER_KEY")
.consumerToken("CONSUMER_TOKEN")
.candidate("jreleaser")
.version("1.0.0")
.url("https://host/jreleaser-1.0.0.zip")
.https(false)
.build();
.apiHost(api.baseUrl())
.consumerKey("CONSUMER_KEY")
.consumerToken("CONSUMER_TOKEN")
.candidate("jreleaser")
.version("1.0.0")
.url("https://host/jreleaser-1.0.0.zip")
.build();
// expected:
assertThrows(SdkmanException.class, command::execute);

View File

@@ -26,9 +26,9 @@ import static com.github.tomakehurst.wiremock.client.WireMock.post;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.jreleaser.sdk.sdkman.ApiEndpoints.ANNOUNCE_ENDPOINT;
import static org.jreleaser.sdk.sdkman.ApiEndpoints.RELEASE_ENDPOINT;
import static org.junit.jupiter.api.Assertions.assertThrows;
/**
* @author Andres Almiray
@@ -42,51 +42,49 @@ public class MinorReleaseSdkmanCommandTest {
public void testMinorReleaseWithAnnouncement() throws SdkmanException {
// given:
stubFor(post(urlEqualTo(RELEASE_ENDPOINT))
.willReturn(okJson("{\"status\": 201, \"message\":\"success\"}")));
.willReturn(okJson("{\"status\": 201, \"message\":\"success\"}")));
stubFor(post(urlEqualTo(ANNOUNCE_ENDPOINT))
.willReturn(okJson("{\"status\": 201, \"message\":\"success\"}")));
.willReturn(okJson("{\"status\": 201, \"message\":\"success\"}")));
MinorReleaseSdkmanCommand command = MinorReleaseSdkmanCommand.builder()
.apiHost(api.baseUrl())
.consumerKey("CONSUMER_KEY")
.consumerToken("CONSUMER_TOKEN")
.candidate("jreleaser")
.version("1.0.0")
.url("https://host/jreleaser-1.0.0.zip")
.https(false)
.build();
.apiHost(api.baseUrl())
.consumerKey("CONSUMER_KEY")
.consumerToken("CONSUMER_TOKEN")
.candidate("jreleaser")
.version("1.0.0")
.url("https://host/jreleaser-1.0.0.zip")
.build();
// when:
command.execute();
// then:
Stubs.verifyPost(RELEASE_ENDPOINT, "{\n" +
" \"candidate\": \"jreleaser\",\n" +
" \"version\": \"1.0.0\",\n" +
" \"platform\": \"UNIVERSAL\",\n" +
" \"url\": \"https://host/jreleaser-1.0.0.zip\"\n" +
"}");
" \"candidate\": \"jreleaser\",\n" +
" \"version\": \"1.0.0\",\n" +
" \"platform\": \"UNIVERSAL\",\n" +
" \"url\": \"https://host/jreleaser-1.0.0.zip\"\n" +
"}");
Stubs.verifyPost(ANNOUNCE_ENDPOINT, "{\n" +
" \"candidate\": \"jreleaser\",\n" +
" \"version\": \"1.0.0\"\n" +
"}");
" \"candidate\": \"jreleaser\",\n" +
" \"version\": \"1.0.0\"\n" +
"}");
}
@Test
public void testError() {
// given:
stubFor(post(urlEqualTo(RELEASE_ENDPOINT))
.willReturn(aResponse().withStatus(500)));
.willReturn(aResponse().withStatus(500)));
MinorReleaseSdkmanCommand command = MinorReleaseSdkmanCommand.builder()
.apiHost(api.baseUrl())
.consumerKey("CONSUMER_KEY")
.consumerToken("CONSUMER_TOKEN")
.candidate("jreleaser")
.version("1.0.0")
.url("https://host/jreleaser-1.0.0.zip")
.https(false)
.build();
.apiHost(api.baseUrl())
.consumerKey("CONSUMER_KEY")
.consumerToken("CONSUMER_TOKEN")
.candidate("jreleaser")
.version("1.0.0")
.url("https://host/jreleaser-1.0.0.zip")
.build();
// expected:
assertThrows(SdkmanException.class, command::execute);

View File

@@ -40,115 +40,111 @@ public class ReleaseSdkmanCommandTest {
public void testSingleUniversalRelease() throws SdkmanException {
// given:
stubFor(post(urlEqualTo(ApiEndpoints.RELEASE_ENDPOINT))
.willReturn(okJson("{\"status\": 201, \"message\":\"success\"}")));
.willReturn(okJson("{\"status\": 201, \"message\":\"success\"}")));
ReleaseSdkmanCommand command = ReleaseSdkmanCommand.builder()
.apiHost(api.baseUrl())
.consumerKey("CONSUMER_KEY")
.consumerToken("CONSUMER_TOKEN")
.candidate("jreleaser")
.version("1.0.0")
.url("https://host/jreleaser-1.0.0.zip")
.https(false)
.build();
.apiHost(api.baseUrl())
.consumerKey("CONSUMER_KEY")
.consumerToken("CONSUMER_TOKEN")
.candidate("jreleaser")
.version("1.0.0")
.url("https://host/jreleaser-1.0.0.zip")
.build();
// when:
command.execute();
// then:
Stubs.verifyPost(ApiEndpoints.RELEASE_ENDPOINT, "{\n" +
" \"candidate\": \"jreleaser\",\n" +
" \"version\": \"1.0.0\",\n" +
" \"platform\": \"UNIVERSAL\",\n" +
" \"url\": \"https://host/jreleaser-1.0.0.zip\"\n" +
"}");
" \"candidate\": \"jreleaser\",\n" +
" \"version\": \"1.0.0\",\n" +
" \"platform\": \"UNIVERSAL\",\n" +
" \"url\": \"https://host/jreleaser-1.0.0.zip\"\n" +
"}");
}
@Test
public void testSinglePlatformRelease() throws SdkmanException {
// given:
stubFor(post(urlEqualTo(ApiEndpoints.RELEASE_ENDPOINT))
.willReturn(okJson("{\"status\": 201, \"message\":\"success\"}")));
.willReturn(okJson("{\"status\": 201, \"message\":\"success\"}")));
ReleaseSdkmanCommand command = ReleaseSdkmanCommand.builder()
.apiHost(api.baseUrl())
.consumerKey("CONSUMER_KEY")
.consumerToken("CONSUMER_TOKEN")
.candidate("jreleaser")
.version("1.0.0")
.platform("MAC_OSX", "https://host/jreleaser-1.0.0.zip")
.https(false)
.build();
.apiHost(api.baseUrl())
.consumerKey("CONSUMER_KEY")
.consumerToken("CONSUMER_TOKEN")
.candidate("jreleaser")
.version("1.0.0")
.platform("MAC_OSX", "https://host/jreleaser-1.0.0.zip")
.build();
// when:
command.execute();
// then:
Stubs.verifyPost(ApiEndpoints.RELEASE_ENDPOINT, "{\n" +
" \"candidate\": \"jreleaser\",\n" +
" \"version\": \"1.0.0\",\n" +
" \"platform\": \"MAC_OSX\",\n" +
" \"url\": \"https://host/jreleaser-1.0.0.zip\"\n" +
"}");
" \"candidate\": \"jreleaser\",\n" +
" \"version\": \"1.0.0\",\n" +
" \"platform\": \"MAC_OSX\",\n" +
" \"url\": \"https://host/jreleaser-1.0.0.zip\"\n" +
"}");
}
@Test
public void testMultiPlatformRelease() throws SdkmanException {
// given:
stubFor(post(urlEqualTo(ApiEndpoints.RELEASE_ENDPOINT))
.willReturn(okJson("{\"status\": 201, \"message\":\"success\"}")));
.willReturn(okJson("{\"status\": 201, \"message\":\"success\"}")));
ReleaseSdkmanCommand command = ReleaseSdkmanCommand.builder()
.apiHost(api.baseUrl())
.consumerKey("CONSUMER_KEY")
.consumerToken("CONSUMER_TOKEN")
.candidate("jreleaser")
.version("1.0.0")
.platform("MAC_OSX", "https://host/jreleaser-1.0.0-mac.zip")
.platform("WINDOWS_64", "https://host/jreleaser-1.0.0-win.zip")
.platform("LINUX_64", "https://host/jreleaser-1.0.0-linux.zip")
.https(false)
.build();
.apiHost(api.baseUrl())
.consumerKey("CONSUMER_KEY")
.consumerToken("CONSUMER_TOKEN")
.candidate("jreleaser")
.version("1.0.0")
.platform("MAC_OSX", "https://host/jreleaser-1.0.0-mac.zip")
.platform("WINDOWS_64", "https://host/jreleaser-1.0.0-win.zip")
.platform("LINUX_64", "https://host/jreleaser-1.0.0-linux.zip")
.build();
// when:
command.execute();
// then:
Stubs.verifyPost(ApiEndpoints.RELEASE_ENDPOINT, "{\n" +
" \"candidate\": \"jreleaser\",\n" +
" \"version\": \"1.0.0\",\n" +
" \"platform\": \"MAC_OSX\",\n" +
" \"url\": \"https://host/jreleaser-1.0.0-mac.zip\"\n" +
"}");
" \"candidate\": \"jreleaser\",\n" +
" \"version\": \"1.0.0\",\n" +
" \"platform\": \"MAC_OSX\",\n" +
" \"url\": \"https://host/jreleaser-1.0.0-mac.zip\"\n" +
"}");
Stubs.verifyPost(ApiEndpoints.RELEASE_ENDPOINT, "{\n" +
" \"candidate\": \"jreleaser\",\n" +
" \"version\": \"1.0.0\",\n" +
" \"platform\": \"WINDOWS_64\",\n" +
" \"url\": \"https://host/jreleaser-1.0.0-win.zip\"\n" +
"}");
" \"candidate\": \"jreleaser\",\n" +
" \"version\": \"1.0.0\",\n" +
" \"platform\": \"WINDOWS_64\",\n" +
" \"url\": \"https://host/jreleaser-1.0.0-win.zip\"\n" +
"}");
Stubs.verifyPost(ApiEndpoints.RELEASE_ENDPOINT, "{\n" +
" \"candidate\": \"jreleaser\",\n" +
" \"version\": \"1.0.0\",\n" +
" \"platform\": \"LINUX_64\",\n" +
" \"url\": \"https://host/jreleaser-1.0.0-linux.zip\"\n" +
"}");
" \"candidate\": \"jreleaser\",\n" +
" \"version\": \"1.0.0\",\n" +
" \"platform\": \"LINUX_64\",\n" +
" \"url\": \"https://host/jreleaser-1.0.0-linux.zip\"\n" +
"}");
}
@Test
public void testError() {
// given:
stubFor(post(urlEqualTo(ApiEndpoints.RELEASE_ENDPOINT))
.willReturn(aResponse().withStatus(500)));
.willReturn(aResponse().withStatus(500)));
ReleaseSdkmanCommand command = ReleaseSdkmanCommand.builder()
.apiHost(api.baseUrl())
.consumerKey("CONSUMER_KEY")
.consumerToken("CONSUMER_TOKEN")
.candidate("jreleaser")
.version("1.0.0")
.url("https://host/jreleaser-1.0.0.zip")
.https(false)
.build();
.apiHost(api.baseUrl())
.consumerKey("CONSUMER_KEY")
.consumerToken("CONSUMER_TOKEN")
.candidate("jreleaser")
.version("1.0.0")
.url("https://host/jreleaser-1.0.0.zip")
.build();
// expected:
assertThrows(SdkmanException.class, command::execute);

View File

@@ -36,7 +36,7 @@ class Stubs {
}
private static void verifyRequest(RequestPatternBuilder builder, String json) {
verify(builder.withHeader("Content-Type", equalTo("application/json; charset=UTF-8"))
verify(builder.withHeader("Content-Type", equalTo("application/json"))
.withHeader("Accept", equalTo("application/json"))
.withHeader("Consumer-Key", equalTo("CONSUMER_KEY"))
.withHeader("Consumer-Token", equalTo("CONSUMER_TOKEN"))