Skip to content

Commit

Permalink
Resolve Keycloak JS from NPM package metadata
Browse files Browse the repository at this point in the history
Closes #492

Signed-off-by: Jon Koops <[email protected]>
  • Loading branch information
jonkoops committed Oct 1, 2024
1 parent d377498 commit 56e604a
Show file tree
Hide file tree
Showing 11 changed files with 150 additions and 63 deletions.
14 changes: 4 additions & 10 deletions src/main/java/org/keycloak/webbuilder/Context.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,8 @@ public class Context {

private FreeMarker freeMarker;
private AsciiDoctor asciiDoctor;
private JsonParser jsonParser;

public Context(File rootDir) throws Exception {
jsonParser = new JsonParser();
freeMarker = new FreeMarker(rootDir);
asciiDoctor = new AsciiDoctor(rootDir);

Expand All @@ -62,12 +60,12 @@ public void init() throws Exception {
config = loadConfig();
links = new Links(config);

versions = new Versions(versionsDir, jsonParser);
extensions = new Extensions(extensionsDir, jsonParser);
versions = new Versions(versionsDir);
extensions = new Extensions(extensionsDir);
blogs = new Blogs(blogDir, versions, config, freeMarker, asciiDoctor);
guidesMetadata = new YamlParser().read(new File(getWebSrcDir(),"/guides.yaml"), GuidesMetadata.class);
guides = new Guides(guidesMetadata, tmpDir, getWebSrcDir(), asciiDoctor);
news = new News(newsDir, blogs, jsonParser, config);
news = new News(newsDir, blogs, config);

freeMarker.init(this);
asciiDoctor.init(this);
Expand All @@ -78,7 +76,7 @@ public void close() {
}

private Config loadConfig() {
Config config = jsonParser.read(new File(getWebSrcDir(),"/config.json"), Config.class);
Config config = JsonParser.read(new File(getWebSrcDir(),"/config.json"), Config.class);
config.setPublish(System.getProperties().containsKey("publish"));

if (System.getenv().containsKey("KC_URL")) {
Expand Down Expand Up @@ -113,10 +111,6 @@ public News news() {
return news;
}

public JsonParser json() {
return jsonParser;
}

public FreeMarker freeMarker() {
return freeMarker;
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/keycloak/webbuilder/Extensions.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@

public class Extensions extends LinkedList<Extensions.Extension> {

public Extensions(File extensionsDir, JsonParser json) {
public Extensions(File extensionsDir) {
for (File extensionFile : extensionsDir.listFiles((dir, name) -> name.endsWith(".json"))) {
add(json.read(extensionFile, Extension.class));
add(JsonParser.read(extensionFile, Extension.class));
}
Collections.sort(this);
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/keycloak/webbuilder/News.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@

public class News extends LinkedList<News.NewsItem> {

public News(File newsDir, Blogs blogs, JsonParser json, Config config) throws ParseException {
public News(File newsDir, Blogs blogs, Config config) throws ParseException {
File[] newsFiles = newsDir.listFiles((dir, name) -> name.endsWith(".json"));
if (newsFiles != null) {
for (int i = 0; i < newsFiles.length && i < config.getMaxNews(); i++) {
NewsItem news = json.read(newsFiles[i], NewsItem.class);
NewsItem news = JsonParser.read(newsFiles[i], NewsItem.class);
news.setDate(Constants.DATE_IN.parse(newsFiles[i].getName()));
add(news);
}
Expand Down
5 changes: 2 additions & 3 deletions src/main/java/org/keycloak/webbuilder/Versions.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import org.keycloak.webbuilder.utils.JsonParser;

import java.io.File;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
Expand All @@ -15,9 +14,9 @@

public class Versions extends LinkedList<Versions.Version> {

public Versions(File versionsDir, JsonParser json) {
public Versions(File versionsDir) {
for (File versionFile : versionsDir.listFiles((dir, name) -> name.endsWith(".json"))) {
add(json.read(versionFile, Version.class));
add(JsonParser.read(versionFile, Version.class));
}
Collections.sort(this);

Expand Down
45 changes: 27 additions & 18 deletions src/main/java/org/keycloak/webbuilder/builders/AppBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,43 @@

import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.ArchiveInputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.io.IOUtils;
import org.keycloak.webbuilder.misc.NpmPackageInfo;
import org.keycloak.webbuilder.npm.Package;
import org.keycloak.webbuilder.npm.Registry;
import org.keycloak.webbuilder.npm.Version;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.net.URL;
import java.nio.file.Path;

public class AppBuilder extends AbstractBuilder {

@Override
protected void build() throws Exception {
NpmPackageInfo npmPackageInfo = context.json().read(new URL("https://registry.npmjs.org/keycloak-js/"), NpmPackageInfo.class);

File f = new File(context.getTargetDir(), "app/keycloak.js");
if (!f.isFile()) {
URL u = new URL("https://registry.npmjs.org/keycloak-js/-/keycloak-js-" + npmPackageInfo.getDistTags().getLatest() + ".tgz");
try (ArchiveInputStream i = new TarArchiveInputStream(new GzipCompressorInputStream(new BufferedInputStream(u.openStream())))) {
for (ArchiveEntry e = i.getNextEntry(); e != null; e = i.getNextEntry()) {
if (e.getName().equals("package/dist/keycloak.js")) {
try (OutputStream o = new FileOutputStream(f)) {
IOUtils.copy(i, o);
}
}
}
Package packageInfo = Registry.getPackage("keycloak-js");
Version latestVersion = packageInfo.getVersionByTag("latest");
File targetFile = new File(context.getTargetDir(), "app/keycloak.js");

// Skip if target file already exists.
if (targetFile.isFile()) {
return;
}

String entryPoint = latestVersion.resolveEntryPoint();
String sourcePath = Path.of("package", entryPoint).toString();
ArchiveInputStream<TarArchiveEntry> tarball = latestVersion.getDist().getTarballStream();

for (ArchiveEntry entry = tarball.getNextEntry(); entry != null; entry = tarball.getNextEntry()) {
// Loop trough until we find a file that matches the package entrypoint.
if (!entry.getName().equals(sourcePath)) {
continue;
}

// Copy the file over when found.
try (OutputStream outputStream = new FileOutputStream(targetFile)) {
IOUtils.copy(tarball, outputStream);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import org.keycloak.webbuilder.Versions;
import org.keycloak.webbuilder.misc.ChangeLogEntry;
import org.keycloak.webbuilder.utils.JsonParser;
import org.kohsuke.github.GHIssue;
import org.kohsuke.github.GitHub;
import org.kohsuke.github.GitHubBuilder;
Expand Down Expand Up @@ -49,7 +50,7 @@ protected void build() throws Exception {
File changeLogFile = new File(releaseCacheDir, "changelog.json");

if (changeLogFile.exists()) {
Versions.ChangeLog changeLog = new Versions.ChangeLog(Arrays.asList(context.json().read(changeLogFile, ChangeLogEntry[].class)));
Versions.ChangeLog changeLog = new Versions.ChangeLog(Arrays.asList(JsonParser.read(changeLogFile, ChangeLogEntry[].class)));

if (v.getBlogTemplate() >= 3) {
for (ChangeLogEntry e : changeLog.getAll()) {
Expand Down
24 changes: 0 additions & 24 deletions src/main/java/org/keycloak/webbuilder/misc/NpmPackageInfo.java

This file was deleted.

20 changes: 20 additions & 0 deletions src/main/java/org/keycloak/webbuilder/npm/Package.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.keycloak.webbuilder.npm;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.Map;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Package {
@JsonProperty("dist-tags")
private Map<String, String> distTags;

@JsonProperty("versions")
private Map<String, Version> versions;

public Version getVersionByTag(String tag) {
String versionName = distTags.get(tag);
return versions.get(versionName);
}
}
24 changes: 24 additions & 0 deletions src/main/java/org/keycloak/webbuilder/npm/Registry.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.keycloak.webbuilder.npm;

import org.keycloak.webbuilder.utils.JsonParser;

import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;

public class Registry {
public static URI REGISTRY_URI;

static {
try {
REGISTRY_URI = new URI("https://registry.npmjs.org");
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}

public static Package getPackage(String name) throws MalformedURLException {
return JsonParser.read(REGISTRY_URI.resolve("./" + name).toURL(), Package.class);
}
}
64 changes: 64 additions & 0 deletions src/main/java/org/keycloak/webbuilder/npm/Version.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package org.keycloak.webbuilder.npm;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.apache.commons.compress.archivers.ArchiveInputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.URL;
import java.util.Map;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Version {
@JsonProperty("dist")
private Dist dist;

@JsonProperty("module")
private String module;

@JsonProperty
private Map<String, Export> exports;

public Dist getDist() {
return dist;
}

public String resolveEntryPoint() {
if (module != null) {
return module;
}

Export defaultExport = exports.get(".");
return defaultExport != null ? defaultExport.getDefaultPath() : null;
}

@JsonIgnoreProperties(ignoreUnknown = true)
public static class Dist {
@JsonProperty("tarball")
private String tarball;

public ArchiveInputStream<TarArchiveEntry> getTarballStream() throws IOException {
URL url = new URL(tarball);

return new TarArchiveInputStream(
new GzipCompressorInputStream(
new BufferedInputStream(url.openStream())
)
);
}
}

@JsonIgnoreProperties(ignoreUnknown = true)
public static class Export {
@JsonProperty("default")
private String defaultPath;

public String getDefaultPath() {
return defaultPath;
}
}
}
6 changes: 3 additions & 3 deletions src/main/java/org/keycloak/webbuilder/utils/JsonParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@

public class JsonParser {

private final ObjectMapper mapper = new ObjectMapper();
private static final ObjectMapper mapper = new ObjectMapper();

public <T> T read(File f, Class<T> t) {
public static <T> T read(File f, Class<T> t) {
try {
return mapper.readValue(f, t);
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public <T> T read(URL url, Class<T> t) {
public static <T> T read(URL url, Class<T> t) {
try {
return mapper.readValue(url, t);
} catch (Exception e) {
Expand Down

0 comments on commit 56e604a

Please sign in to comment.