Loading pkgs/development/compilers/openjdk/22.nix +36 −19 Original line number Diff line number Diff line Loading @@ -3,7 +3,6 @@ , fetchurl , fetchpatch , fetchFromGitHub , bash , pkg-config , autoconf , cpio Loading Loading @@ -44,27 +43,32 @@ , gnome_vfs , glib , GConf , writeShellScript }: let version = { feature = "22"; interim = ""; build = "36"; }; # Java version format: # $FEATURE.$INTERIM.$UPDATE.$PATCH # See # https://openjdk.org/jeps/223 # https://docs.oracle.com/en/java/javase/22/docs/api/java.base/java/lang/Runtime.Version.html featureVersion = "22"; info = builtins.getAttr featureVersion (lib.importJSON ./info.json); version = info.version; # when building a headless jdk, also bootstrap it with a headless jdk openjdk-bootstrap = openjdk22-bootstrap.override { gtkSupport = !headless; }; openjdk = stdenv.mkDerivation { openjdk = stdenv.mkDerivation (finalAttrs: { pname = "openjdk" + lib.optionalString headless "-headless"; version = "${version.feature}${version.interim}+${version.build}"; inherit version; src = fetchFromGitHub { owner = "openjdk"; repo = "jdk${version.feature}u"; rev = "jdk-${version.feature}${version.interim}+${version.build}"; hash = "sha256-itjvIedPwJl/l3a2gIVpNMs1zkbrjioVqbCj1Z1nCJE="; repo = info.repo; rev = "jdk-${version}"; hash = info.hash; }; nativeBuildInputs = [ pkg-config autoconf unzip ensureNewerSourcesForZipFilesHook ]; Loading Loading @@ -144,9 +148,8 @@ let # https://openjdk.org/groups/build/doc/building.html configureFlags = [ "--with-boot-jdk=${openjdk-bootstrap.home}" "--with-version-build=${version.build}" "--with-version-opt=nixos" "--with-version-pre=" "--with-version-string=${version}" "--with-vendor-version-string=(nix)" "--enable-unlimited-crypto" "--with-native-debug-symbols=internal" "--with-libjpeg=system" Loading Loading @@ -247,14 +250,28 @@ let disallowedReferences = [ openjdk-bootstrap ]; pos = builtins.unsafeGetAttrPos "feature" version; meta = import ./meta.nix lib version.feature; pos = __curPos; meta = import ./meta.nix lib featureVersion; passthru = { architecture = ""; home = "${openjdk}/lib/openjdk"; inherit gtk3; updateScript = let java-json = fetchurl { url = "https://search.maven.org/remotecontent?filepath=org/json/json/20240303/json-20240303.jar"; hash = "sha256-PPbNaJLjLitMHDng9S9SSKL1s3ZG/fu3mma0a2GEFO0="; }; in writeShellScript "update-java" '' ${finalAttrs.finalPackage}/bin/java \ -cp ${java-json} \ ${./JavaUpdater.java} \ 22 pkgs/development/compilers/openjdk/info.json ''; home = "${finalAttrs.finalPackage}/lib/openjdk"; inherit gtk3; }; }); in openjdk pkgs/development/compilers/openjdk/JavaUpdater.java 0 → 100644 +181 −0 Original line number Diff line number Diff line import org.json.JSONArray; import org.json.JSONObject; import java.io.IOException; import java.io.PrintWriter; import java.net.URI; import java.net.http.*; import java.nio.file.Files; import java.nio.file.Path; import java.util.*; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.stream.StreamSupport; public class JavaUpdater { record GitHubResult(Optional<String> latestVersion, Optional<String> next) { } record JsonInfo(String repo, String version, String hash) { public JsonInfo(JSONObject json) { this(json.getString("repo"), json.getString("version"), json.getString("hash")); } public String toJsonString(String featureVersion) { return """ \s "%s": { \s "version": "%s", \s "repo": "%s", \s "hash": "%s" \s }\ """.formatted(featureVersion, version, repo, hash); } } // Parses the GitHub Link header public static Optional<String> getNextLink(HttpHeaders headers) { var linkHeader = headers.map().get("Link"); if (linkHeader == null || linkHeader.isEmpty()) return null; var links = linkHeader.getFirst(); var linksRegex = Pattern.compile("<(.+)>;\\s*rel=\"next\""); return Pattern.compile(",") .splitAsStream(links) .map(x -> linksRegex.matcher(x).results() .map(g -> g.group(1)) .findFirst() ) .filter(Optional::isPresent) .map(Optional::orElseThrow) .findFirst(); } // HTTP request helper, sets GITHUB_TOKEN if present private static HttpRequest NewGithubRequest(String url) { var token = System.getenv().get("GITHUB_TOKEN"); var builder = HttpRequest.newBuilder() .uri(URI.create(url)); if (token != null) builder.setHeader("Authorization", "Bearer " + token); return builder.build(); } private static GitHubResult getLatestTag(String url) { var request = NewGithubRequest(url); var response = HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) .join(); var json = new JSONArray(response.body()); Optional<String> version = StreamSupport.stream(json.spliterator(), false) .map(JSONObject.class::cast) .map(x -> x.getString("name").replaceFirst("jdk-", "")) .filter(x -> x.contains("-ga")) .max(Comparator.comparing(Runtime.Version::parse)); return new GitHubResult(version, getNextLink(response.headers())); } public String findNewerVersion() { var url = Optional.of("https://api.github.com/repos/openjdk/" + getRepo() + "/tags?per_page=100"); String version = getCurrentVersion(); do { GitHubResult response = getLatestTag(url.orElseThrow()); if (response.latestVersion.isPresent() && response.latestVersion.orElseThrow().equals(version)) { return null; } String latestVersion = Stream.of(version, response.latestVersion.orElse(version)) .max(Comparator.comparing(Runtime.Version::parse)).orElseThrow(); if (latestVersion != version) return latestVersion; url = response.next; } while (url.isPresent()); return null; } private static String prettyPrint(JSONObject json) { Iterable<String> iterable = () -> json.keys(); return StreamSupport .stream(iterable.spliterator(), false) .sorted(Comparator.reverseOrder()) .map(majorVersion -> (new JsonInfo(json.getJSONObject(majorVersion))).toJsonString(majorVersion)) .collect( Collectors.joining(",\n", "{\n", "\n}") ); } public void updateJsonInfo(String newVersion) { try { JSONObject json = getJsonInfo(); var info = json.getJSONObject(featureNumber); info.put("version", newVersion); info.put("hash", nixHash(newVersion)); try (PrintWriter out = new PrintWriter(infoJsonPath)) { out.println(prettyPrint(json)); } } catch (Exception e) { throw new RuntimeException(e); } } private String nixHash(String version) { try { var process = new ProcessBuilder("nix", "flake", "prefetch", "--extra-experimental-features", "'nix-command flakes'", "--json", "github:openjdk/" + getRepo() + "/jdk-" + version).start(); var json = new JSONObject(new String(process.getInputStream().readAllBytes())); process.waitFor(); return json.getString("hash"); } catch (Exception e) { throw new RuntimeException(e); } } private final String featureNumber; private final String infoJsonPath; private final JSONObject jsonInfo; public String getCurrentVersion() { return this.jsonInfo.getJSONObject(this.featureNumber).getString("version"); } public String getRepo() { return this.jsonInfo.getJSONObject(this.featureNumber).getString("repo"); } public JSONObject getJsonInfo() { try { String infoStr = Files.readString(Path.of(this.infoJsonPath)); return new JSONObject(infoStr); } catch (IOException e) { throw new RuntimeException(e); } } public JavaUpdater(String featureNumber, String infoJsonPath) { this.featureNumber = featureNumber; this.infoJsonPath = infoJsonPath; this.jsonInfo = getJsonInfo(); } public static void main(String[] args) { var updater = new JavaUpdater(args[0], args[1]); String newerVersion = updater.findNewerVersion(); if (newerVersion != null) { updater.updateJsonInfo(newerVersion); } } } pkgs/development/compilers/openjdk/info.json 0 → 100644 +12 −0 Original line number Diff line number Diff line { "22": { "version": "22-ga", "repo": "jdk22u", "hash": "sha256-itjvIedPwJl/l3a2gIVpNMs1zkbrjioVqbCj1Z1nCJE=" }, "21": { "version": "21.0.3-ga", "repo": "jdk21u", "hash": "sha256-zRN16lrc5gtDlTVIQJRRx103w/VbRkatCLeEc9AXWPE=" } } Loading
pkgs/development/compilers/openjdk/22.nix +36 −19 Original line number Diff line number Diff line Loading @@ -3,7 +3,6 @@ , fetchurl , fetchpatch , fetchFromGitHub , bash , pkg-config , autoconf , cpio Loading Loading @@ -44,27 +43,32 @@ , gnome_vfs , glib , GConf , writeShellScript }: let version = { feature = "22"; interim = ""; build = "36"; }; # Java version format: # $FEATURE.$INTERIM.$UPDATE.$PATCH # See # https://openjdk.org/jeps/223 # https://docs.oracle.com/en/java/javase/22/docs/api/java.base/java/lang/Runtime.Version.html featureVersion = "22"; info = builtins.getAttr featureVersion (lib.importJSON ./info.json); version = info.version; # when building a headless jdk, also bootstrap it with a headless jdk openjdk-bootstrap = openjdk22-bootstrap.override { gtkSupport = !headless; }; openjdk = stdenv.mkDerivation { openjdk = stdenv.mkDerivation (finalAttrs: { pname = "openjdk" + lib.optionalString headless "-headless"; version = "${version.feature}${version.interim}+${version.build}"; inherit version; src = fetchFromGitHub { owner = "openjdk"; repo = "jdk${version.feature}u"; rev = "jdk-${version.feature}${version.interim}+${version.build}"; hash = "sha256-itjvIedPwJl/l3a2gIVpNMs1zkbrjioVqbCj1Z1nCJE="; repo = info.repo; rev = "jdk-${version}"; hash = info.hash; }; nativeBuildInputs = [ pkg-config autoconf unzip ensureNewerSourcesForZipFilesHook ]; Loading Loading @@ -144,9 +148,8 @@ let # https://openjdk.org/groups/build/doc/building.html configureFlags = [ "--with-boot-jdk=${openjdk-bootstrap.home}" "--with-version-build=${version.build}" "--with-version-opt=nixos" "--with-version-pre=" "--with-version-string=${version}" "--with-vendor-version-string=(nix)" "--enable-unlimited-crypto" "--with-native-debug-symbols=internal" "--with-libjpeg=system" Loading Loading @@ -247,14 +250,28 @@ let disallowedReferences = [ openjdk-bootstrap ]; pos = builtins.unsafeGetAttrPos "feature" version; meta = import ./meta.nix lib version.feature; pos = __curPos; meta = import ./meta.nix lib featureVersion; passthru = { architecture = ""; home = "${openjdk}/lib/openjdk"; inherit gtk3; updateScript = let java-json = fetchurl { url = "https://search.maven.org/remotecontent?filepath=org/json/json/20240303/json-20240303.jar"; hash = "sha256-PPbNaJLjLitMHDng9S9SSKL1s3ZG/fu3mma0a2GEFO0="; }; in writeShellScript "update-java" '' ${finalAttrs.finalPackage}/bin/java \ -cp ${java-json} \ ${./JavaUpdater.java} \ 22 pkgs/development/compilers/openjdk/info.json ''; home = "${finalAttrs.finalPackage}/lib/openjdk"; inherit gtk3; }; }); in openjdk
pkgs/development/compilers/openjdk/JavaUpdater.java 0 → 100644 +181 −0 Original line number Diff line number Diff line import org.json.JSONArray; import org.json.JSONObject; import java.io.IOException; import java.io.PrintWriter; import java.net.URI; import java.net.http.*; import java.nio.file.Files; import java.nio.file.Path; import java.util.*; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.stream.StreamSupport; public class JavaUpdater { record GitHubResult(Optional<String> latestVersion, Optional<String> next) { } record JsonInfo(String repo, String version, String hash) { public JsonInfo(JSONObject json) { this(json.getString("repo"), json.getString("version"), json.getString("hash")); } public String toJsonString(String featureVersion) { return """ \s "%s": { \s "version": "%s", \s "repo": "%s", \s "hash": "%s" \s }\ """.formatted(featureVersion, version, repo, hash); } } // Parses the GitHub Link header public static Optional<String> getNextLink(HttpHeaders headers) { var linkHeader = headers.map().get("Link"); if (linkHeader == null || linkHeader.isEmpty()) return null; var links = linkHeader.getFirst(); var linksRegex = Pattern.compile("<(.+)>;\\s*rel=\"next\""); return Pattern.compile(",") .splitAsStream(links) .map(x -> linksRegex.matcher(x).results() .map(g -> g.group(1)) .findFirst() ) .filter(Optional::isPresent) .map(Optional::orElseThrow) .findFirst(); } // HTTP request helper, sets GITHUB_TOKEN if present private static HttpRequest NewGithubRequest(String url) { var token = System.getenv().get("GITHUB_TOKEN"); var builder = HttpRequest.newBuilder() .uri(URI.create(url)); if (token != null) builder.setHeader("Authorization", "Bearer " + token); return builder.build(); } private static GitHubResult getLatestTag(String url) { var request = NewGithubRequest(url); var response = HttpClient.newHttpClient().sendAsync(request, HttpResponse.BodyHandlers.ofString()) .join(); var json = new JSONArray(response.body()); Optional<String> version = StreamSupport.stream(json.spliterator(), false) .map(JSONObject.class::cast) .map(x -> x.getString("name").replaceFirst("jdk-", "")) .filter(x -> x.contains("-ga")) .max(Comparator.comparing(Runtime.Version::parse)); return new GitHubResult(version, getNextLink(response.headers())); } public String findNewerVersion() { var url = Optional.of("https://api.github.com/repos/openjdk/" + getRepo() + "/tags?per_page=100"); String version = getCurrentVersion(); do { GitHubResult response = getLatestTag(url.orElseThrow()); if (response.latestVersion.isPresent() && response.latestVersion.orElseThrow().equals(version)) { return null; } String latestVersion = Stream.of(version, response.latestVersion.orElse(version)) .max(Comparator.comparing(Runtime.Version::parse)).orElseThrow(); if (latestVersion != version) return latestVersion; url = response.next; } while (url.isPresent()); return null; } private static String prettyPrint(JSONObject json) { Iterable<String> iterable = () -> json.keys(); return StreamSupport .stream(iterable.spliterator(), false) .sorted(Comparator.reverseOrder()) .map(majorVersion -> (new JsonInfo(json.getJSONObject(majorVersion))).toJsonString(majorVersion)) .collect( Collectors.joining(",\n", "{\n", "\n}") ); } public void updateJsonInfo(String newVersion) { try { JSONObject json = getJsonInfo(); var info = json.getJSONObject(featureNumber); info.put("version", newVersion); info.put("hash", nixHash(newVersion)); try (PrintWriter out = new PrintWriter(infoJsonPath)) { out.println(prettyPrint(json)); } } catch (Exception e) { throw new RuntimeException(e); } } private String nixHash(String version) { try { var process = new ProcessBuilder("nix", "flake", "prefetch", "--extra-experimental-features", "'nix-command flakes'", "--json", "github:openjdk/" + getRepo() + "/jdk-" + version).start(); var json = new JSONObject(new String(process.getInputStream().readAllBytes())); process.waitFor(); return json.getString("hash"); } catch (Exception e) { throw new RuntimeException(e); } } private final String featureNumber; private final String infoJsonPath; private final JSONObject jsonInfo; public String getCurrentVersion() { return this.jsonInfo.getJSONObject(this.featureNumber).getString("version"); } public String getRepo() { return this.jsonInfo.getJSONObject(this.featureNumber).getString("repo"); } public JSONObject getJsonInfo() { try { String infoStr = Files.readString(Path.of(this.infoJsonPath)); return new JSONObject(infoStr); } catch (IOException e) { throw new RuntimeException(e); } } public JavaUpdater(String featureNumber, String infoJsonPath) { this.featureNumber = featureNumber; this.infoJsonPath = infoJsonPath; this.jsonInfo = getJsonInfo(); } public static void main(String[] args) { var updater = new JavaUpdater(args[0], args[1]); String newerVersion = updater.findNewerVersion(); if (newerVersion != null) { updater.updateJsonInfo(newerVersion); } } }
pkgs/development/compilers/openjdk/info.json 0 → 100644 +12 −0 Original line number Diff line number Diff line { "22": { "version": "22-ga", "repo": "jdk22u", "hash": "sha256-itjvIedPwJl/l3a2gIVpNMs1zkbrjioVqbCj1Z1nCJE=" }, "21": { "version": "21.0.3-ga", "repo": "jdk21u", "hash": "sha256-zRN16lrc5gtDlTVIQJRRx103w/VbRkatCLeEc9AXWPE=" } }