Skip to content

Commit

Permalink
feat: added --available to jdk list
Browse files Browse the repository at this point in the history
It's now possible to list the JDK versions available for installation.
  • Loading branch information
quintesse committed May 26, 2022
1 parent 95adbfd commit cd6a7eb
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 36 deletions.
25 changes: 17 additions & 8 deletions src/main/java/dev/jbang/cli/Jdk.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,22 +39,31 @@ public Integer install(
}

@CommandLine.Command(name = "list", description = "Lists installed JDKs.")
public Integer list() {
int v = JdkManager.getDefaultJdk();
public Integer list(
@CommandLine.Option(names = {
"--available" }, description = "Shows versions available for installation") boolean available) {
int defaultJdk = JdkManager.getDefaultJdk();
PrintStream out = System.out;
final Set<Integer> installedJdks = JdkManager.listInstalledJdks();
if (!installedJdks.isEmpty()) {
out.println("Available installed JDKs:");
installedJdks.forEach(jdk -> {
if (jdk == v) {
final Set<Integer> jdks = available ? JdkManager.listAvailableJdks() : installedJdks;
if (!jdks.isEmpty()) {
if (available) {
out.println("Available JDKs (*=installed, <=default):");
} else {
out.println("Installed JDKs (<=default):");
}
jdks.forEach(jdk -> {
out.print(" " + jdk);
if (jdk == defaultJdk) {
out.print(" <");
} else if (available && installedJdks.contains(jdk)) {
out.print(" *");
}
out.print(" " + jdk);

out.println();
});
} else {
out.println("No JDKs installed");
out.println(String.format("No JDKs %s", available ? "available" : "installed"));
}
return EXIT_OK;
}
Expand Down
68 changes: 49 additions & 19 deletions src/main/java/dev/jbang/net/JdkManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;
import java.util.*;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
Expand All @@ -28,10 +23,11 @@

public class JdkManager {
private static final String FOOJAY_JDK_DOWNLOAD_URL = "https://api.foojay.io/disco/v2.0/directuris?";
private static final String FOOJAY_JDK_VERSIONS_URL = "https://api.foojay.io/disco/v3.0/distributions/%s?";

private static String getDownloadUrl(int version, Util.OS os, Util.Arch arch, String distro) {
Map<String, String> param = new HashMap<>();
param.put("version", String.valueOf(version));
Map<String, String> params = new HashMap<>();
params.put("version", String.valueOf(version));

if (distro == null) {
if (version == 8 || version == 11 || version >= 17) {
Expand All @@ -40,32 +36,38 @@ private static String getDownloadUrl(int version, Util.OS os, Util.Arch arch, St
distro = "aoj";
}
}
param.put("distro", distro);
params.put("distro", distro);

String archiveType;
if (os == Util.OS.windows) {
archiveType = "zip";
} else {
archiveType = "tar.gz";
}
param.put("archive_type", archiveType);
params.put("archive_type", archiveType);

param.put("architecture", arch.name());
param.put("package_type", "jdk");
param.put("operating_system", os.name());
params.put("architecture", arch.name());
params.put("package_type", "jdk");
params.put("operating_system", os.name());

if (os == Util.OS.windows) {
param.put("libc_type", "c_std_lib");
params.put("libc_type", "c_std_lib");
} else if (os == Util.OS.mac) {
param.put("libc_type", "libc");
params.put("libc_type", "libc");
} else {
param.put("libc_type", "glibc");
params.put("libc_type", "glibc");
}

param.put("javafx_bundled", "false");
param.put("latest", "available");
params.put("javafx_bundled", "false");
params.put("latest", "available");

return FOOJAY_JDK_DOWNLOAD_URL + urlEncodeUTF8(param);
return FOOJAY_JDK_DOWNLOAD_URL + urlEncodeUTF8(params);
}

private static String getVersionsUrl(String distro) {
Map<String, String> params = new HashMap<>();
params.put("latest_per_update", "true");
return String.format(FOOJAY_JDK_VERSIONS_URL, distro) + urlEncodeUTF8(params);
}

static String urlEncodeUTF8(String s) {
Expand Down Expand Up @@ -304,6 +306,34 @@ public static void removeDefaultJdk() {
}
}

private static class VersionsResult {
List<String> versions;
}

private static class VersionsResponse {
List<VersionsResult> result;
}

public static Set<Integer> listAvailableJdks() {
try {
Set<Integer> result = new TreeSet<>();
String distro = Util.getVendor();
if (distro == null) {
VersionsResponse res = Util.readJsonFromURL(getVersionsUrl("aoj"), null, VersionsResponse.class);
res.result.get(0).versions.stream().map(v -> JavaUtil.parseJavaVersion(v)).forEach(v -> result.add(v));
res = Util.readJsonFromURL(getVersionsUrl("temurin"), null, VersionsResponse.class);
res.result.get(0).versions.stream().map(v -> JavaUtil.parseJavaVersion(v)).forEach(v -> result.add(v));
} else {
VersionsResponse res = Util.readJsonFromURL(getVersionsUrl(distro), null, VersionsResponse.class);
res.result.get(0).versions.stream().map(v -> JavaUtil.parseJavaVersion(v)).forEach(v -> result.add(v));
}
return Collections.unmodifiableSet(result);
} catch (IOException e) {
Util.verboseMsg("Couldn't list available JDKs", e);
}
return Collections.emptySet();
}

public static boolean isCurrentJdkManaged() {
Path home = JavaUtil.getJdkHome();
return (home != null && home.startsWith(getJdksPath()));
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/dev/jbang/util/JavaUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public static int parseJavaOutput(String output) {
public static int parseJavaVersion(String version) {
if (version != null) {
try {
String[] nums = version.split("[.-]");
String[] nums = version.split("[-.+]");
String num = nums.length > 1 && nums[0].equals("1") ? nums[1] : nums[0];
return Integer.parseInt(num);
} catch (NumberFormatException ex) {
Expand Down
18 changes: 13 additions & 5 deletions src/main/java/dev/jbang/util/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -943,17 +943,14 @@ private static String extractFileFromGist(String url) {
"https://api.github.com/gists/${gistid}");

Util.verboseMsg("Gist url api: " + gistapi);
String strdata = null;
Gist gist = null;
try {
strdata = readStringFromURL(gistapi, getGitHubHeaders());
gist = readJsonFromURL(gistapi, getGitHubHeaders(), Gist.class);
} catch (IOException e) {
Util.verboseMsg("Error when extracting file from gist url.");
throw new IllegalStateException(e);
}

Gson parser = new Gson();
Gist gist = parser.fromJson(strdata, Gist.class);

for (Entry<String, Map<String, String>> entry : gist.files.entrySet()) {
String key = entry.getKey();
String lowerCaseKey = key.toLowerCase();
Expand Down Expand Up @@ -1017,6 +1014,17 @@ public static String readStringFromURL(String requestURL, Map<String, String> he
}
}

public static <T> T readJsonFromURL(String requestURL, Map<String, String> headers, Class<T> type)
throws IOException {
verboseMsg("Reading JSON from: " + requestURL);
URLConnection connection = new URL(requestURL).openConnection();
if (headers != null) {
headers.forEach(connection::setRequestProperty);
}
Gson parser = new Gson();
return parser.fromJson(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8), type);
}

public static String repeat(String s, int times) {
// If Java 11 becomes the default we can change this to String::repeat
return String.join("", Collections.nCopies(times, s));
Expand Down
6 changes: 3 additions & 3 deletions src/test/java/dev/jbang/cli/TestJdk.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class TestJdk extends BaseTest {

@Test
void testNoJdksInstalled() throws IOException {
ExecutionResult result = checkedRun(Jdk::list);
ExecutionResult result = checkedRun(jdk -> jdk.list(false));

assertThat(result.exitCode, equalTo(SUCCESS_EXIT));
assertThat(result.normalizedOut(),
Expand All @@ -40,11 +40,11 @@ void testHasJdksInstalled() throws IOException {
Arrays .asList("11", "12", "13")
.forEach(jdkId -> new File(jdkPath.toFile(), jdkId).mkdirs());

ExecutionResult result = checkedRun(Jdk::list);
ExecutionResult result = checkedRun(jdk -> jdk.list(false));

assertThat(result.exitCode, equalTo(SUCCESS_EXIT));
assertThat(result.normalizedOut(),
equalTo("Available installed JDKs:\n 11\n 12\n 13\n"));
equalTo("Installed JDKs (<=default):\n 11\n 12\n 13\n"));
}

@Test
Expand Down

0 comments on commit cd6a7eb

Please sign in to comment.