Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;
import picocli.CommandLine.ParentCommand;

@Command(name = "download-latest-asset",
description = "From the latest release, downloads the first matching asset, and outputs the downloaded filename"
Expand All @@ -29,8 +30,8 @@ public class DownloadLatestAssetCommand implements Callable<Integer> {
@Option(names = "--output-directory", defaultValue = ".")
Path outputDirectory;

@Option(names = "--api-base-url", defaultValue = GithubClient.DEFAULT_API_BASE_URL)
String apiBaseUrl;
@ParentCommand
GithubCommands parent;

@Parameters(arity = "1", paramLabel = "org/repo")
public void setOrgRepo(String input) {
Expand All @@ -50,7 +51,7 @@ public Integer call() throws Exception {

try (SharedFetch sharedFetch = Fetch.sharedFetch("github download-latest-asset", sharedFetchArgs.options())) {

final GithubClient client = new GithubClient(sharedFetch, apiBaseUrl);
final GithubClient client = new GithubClient(sharedFetch, parent.getApiBaseUrl(), parent.getToken());
final Path result = client.downloadLatestAsset(organization, repo, namePattern, outputDirectory)
.block();

Expand Down
5 changes: 4 additions & 1 deletion src/main/java/me/itzg/helpers/github/GithubClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,20 @@ public class GithubClient {

private final SharedFetch sharedFetch;
private final UriBuilder uriBuilder;
private final String token;

public GithubClient(SharedFetch sharedFetch, String apiBaseUrl) {
public GithubClient(SharedFetch sharedFetch, String apiBaseUrl, @Nullable String token) {
this.sharedFetch = sharedFetch;
this.uriBuilder = UriBuilder.withBaseUrl(apiBaseUrl);
this.token = token;
}

public Mono<Path> downloadLatestAsset(String org, String repo, @Nullable Pattern namePattern, Path outputDirectory) {
return sharedFetch.fetch(
uriBuilder.resolve("/repos/{org}/{repo}/releases/latest", org, repo)
)
.acceptContentTypes(Collections.singletonList("application/vnd.github+json"))
.withAuthorization("Bearer", token)
.toObject(Release.class)
.assemble()
.onErrorResume(throwable -> {
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/me/itzg/helpers/github/GithubCommands.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
package me.itzg.helpers.github;

import lombok.Getter;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;

@Command(name = "github",
subcommands = {
DownloadLatestAssetCommand.class
}
)
@Getter
public class GithubCommands {

@Option(names = "--api-base-url", defaultValue = GithubClient.DEFAULT_API_BASE_URL)
String apiBaseUrl;

@Option(names = "--token", defaultValue = "${env:GH_TOKEN}",
description = "An access token for GitHub to elevate rate limit vs anonymous access"
)
String token;
}
10 changes: 10 additions & 0 deletions src/main/java/me/itzg/helpers/http/FetchBuilderBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import me.itzg.helpers.errors.GenericException;
import me.itzg.helpers.http.SharedFetch.Options;
import me.itzg.helpers.json.ObjectMappers;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import reactor.core.publisher.Mono;
import reactor.netty.ByteBufMono;
Expand Down Expand Up @@ -172,6 +173,15 @@ public SELF header(String name, String value) {
return self();
}

public SELF withAuthorization(String authorizationType, String credentials) {
if (StringUtils.isNotBlank(authorizationType) && StringUtils.isNotBlank(credentials)) {
return header(AUTHORIZATION.toString(), authorizationType + " " + credentials);
}
else {
return self();
}
}

/**
* Helps with fluent sub-type builder pattern
*/
Expand Down
6 changes: 0 additions & 6 deletions src/main/java/me/itzg/helpers/http/SharedFetch.java
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,6 @@ public FetchBuilderBase<?> fetch(URI uri) {
return new FetchBuilderBase<>(uri, this);
}

@SuppressWarnings("unused")
public SharedFetch addHeader(String name, String value) {
headers.put(name, value);
return this;
}

@Override
public void close() {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@ class DownloadLatestAssetCommandTest {
.configureStaticDsl(true)
.build();

private final RandomStringUtils randomStringUtils = RandomStringUtils.insecure();

@Test
void usingNamePattern(@TempDir Path tempDir, WireMockRuntimeInfo wmInfo) {
final String filename = RandomStringUtils.randomAlphabetic(10) + ".jar";
final String fileContent = RandomStringUtils.randomAlphabetic(20);
final String filename = randomStringUtils.nextAlphabetic(10) + ".jar";
final String fileContent = randomStringUtils.nextAlphabetic(20);

stubFor(get("/repos/org/repo/releases/latest")
.willReturn(ok()
Expand All @@ -58,9 +60,10 @@ void usingNamePattern(@TempDir Path tempDir, WireMockRuntimeInfo wmInfo) {
)
);

final int exitCode = new CommandLine(new DownloadLatestAssetCommand())
final int exitCode = new CommandLine(new GithubCommands())
.execute(
"--api-base-url", wmInfo.getHttpBaseUrl(),
"download-latest-asset",
"--name-pattern", "app-.+?(?<!-sources)\\.jar",
"--output-directory", tempDir.toString(),
"org/repo"
Expand Down Expand Up @@ -94,6 +97,7 @@ void rateLimitExceeded(@TempDir Path tempDir, WireMockRuntimeInfo wmInfo) {
final Instant expectedDelayUntil = Instant.now()
.plusSeconds(1);

//noinspection UastIncorrectHttpHeaderInspection custom declared by Github
stubFor(get(anyUrl())
.willReturn(forbidden()
.withHeader("x-ratelimit-reset", String.valueOf(expectedDelayUntil.getEpochSecond()))
Expand All @@ -102,10 +106,11 @@ void rateLimitExceeded(@TempDir Path tempDir, WireMockRuntimeInfo wmInfo) {

final LatchingExecutionExceptionHandler executionExceptionHandler = new LatchingExecutionExceptionHandler();

final int exitCode = new CommandLine(new DownloadLatestAssetCommand())
final int exitCode = new CommandLine(new GithubCommands())
.setExecutionExceptionHandler(executionExceptionHandler)
.execute(
"--api-base-url", wmInfo.getHttpBaseUrl(),
"download-latest-asset",
"--output-directory", tempDir.toString(),
"org/repo"
);
Expand Down