Skip to content

Commit

Permalink
Merge pull request mvnpm#5854 from phillip-kruger/sub-packages
Browse files Browse the repository at this point in the history
Support for peerDependencies and sub package.json (in importmap)
  • Loading branch information
phillip-kruger authored Apr 16, 2024
2 parents 5ef52d7 + 5628e7b commit 649782e
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 22 deletions.
2 changes: 1 addition & 1 deletion .locker/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>io.mvnpm</groupId>
<version>3.0.32-SNAPSHOT</version>
<version>3.0.33-SNAPSHOT</version>
<artifactId>mvnpm-locker</artifactId>
<packaging>pom</packaging>

Expand Down
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>io.mvnpm</groupId>
<artifactId>mvnpm</artifactId>
<version>3.0.32-SNAPSHOT</version>
<version>3.0.33-SNAPSHOT</version>
<name>mvnpm</name>
<description>Maven on NPM</description>
<url>https://mvnpm.org/</url>
Expand Down Expand Up @@ -53,7 +53,7 @@
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
<quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
<quarkus.platform.version>3.9.2</quarkus.platform.version>
<quarkus.platform.version>3.9.3</quarkus.platform.version>
<skipITs>true</skipITs>
<surefire-plugin.version>3.2.5</surefire-plugin.version>
<formatter.plugin.version>2.23.0</formatter.plugin.version>
Expand Down
73 changes: 67 additions & 6 deletions src/main/java/io/mvnpm/file/ImportMapUtil.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,81 @@
package io.mvnpm.file;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;

import com.fasterxml.jackson.databind.ObjectMapper;

import io.mvnpm.Constants;
import io.mvnpm.importmap.ImportsDataBinding;
import io.mvnpm.importmap.model.Imports;
import io.mvnpm.npm.model.Package;
import io.quarkus.logging.Log;

@ApplicationScoped
public class ImportMapUtil {

private ImportMapUtil() {
@Inject
ObjectMapper objectMapper;

private static final String PACKAGE_JSON = "package.json";

public byte[] createImportMap(Map<String, byte[]> packageJsonFiles) throws IOException {
Map<String, io.mvnpm.npm.model.Package> packageJsonObjects = new HashMap<>();

byte[] mainPackageJson = packageJsonFiles.remove(PACKAGE_JSON);
Package mainPackageObject = objectMapper.readValue(mainPackageJson, io.mvnpm.npm.model.Package.class);

for (Map.Entry<String, byte[]> packageJsonFile : packageJsonFiles.entrySet()) {
String path = packageJsonFile.getKey();
byte[] content = packageJsonFile.getValue();
try {
packageJsonObjects.put(path, objectMapper.readValue(content, io.mvnpm.npm.model.Package.class));
} catch (IOException ex) {
Log.error(ex);
}
}

return createImportMap(mainPackageObject, packageJsonObjects);
}

public static byte[] createImportMap(io.mvnpm.npm.model.Package p) {
public byte[] createImportMap(io.mvnpm.npm.model.Package mainPackage,
Map<String, io.mvnpm.npm.model.Package> otherPackages) {
String root = getImportMapRoot(mainPackage);

String module = getModule(mainPackage);
Map<String, String> v = new HashMap<>();

v.put(mainPackage.name().npmFullName, root + module);
v.put(mainPackage.name().npmFullName + Constants.SLASH, root + getModuleRoot(module));

if (otherPackages != null && !otherPackages.isEmpty()) {
for (Map.Entry<String, Package> otherPackage : otherPackages.entrySet()) {
String path = otherPackage.getKey();

path = path.replace("/" + PACKAGE_JSON, "");

io.mvnpm.npm.model.Package p = otherPackage.getValue();
String otherModule = getModule(p);
v.put(mainPackage.name().npmFullName + Constants.SLASH + path,
root + path + Constants.SLASH + otherModule);
v.put(mainPackage.name().npmFullName + Constants.SLASH + path + Constants.SLASH,
root + path + Constants.SLASH);
}
}

Imports imports = new Imports(v);

String importmapJson = ImportsDataBinding.toJson(imports);

return importmapJson.getBytes();

}

public byte[] createImportMap(io.mvnpm.npm.model.Package p) {
String root = getImportMapRoot(p);

String module = getModule(p);
Expand All @@ -30,7 +91,7 @@ public static byte[] createImportMap(io.mvnpm.npm.model.Package p) {
return importmapJson.getBytes();
}

public static String getImportMapRoot(io.mvnpm.npm.model.Package p) {
public String getImportMapRoot(io.mvnpm.npm.model.Package p) {
String root = STATIC_ROOT + p.name().npmName;
if (p.repository() != null && p.repository().directory() != null && !p.repository().directory().isEmpty()) {
String d = p.repository().directory();
Expand All @@ -49,7 +110,7 @@ public static String getImportMapRoot(io.mvnpm.npm.model.Package p) {
return root + p.version() + Constants.SLASH;
}

private static String getModule(io.mvnpm.npm.model.Package p) {
private String getModule(io.mvnpm.npm.model.Package p) {
if (p.module() != null && !p.module().isEmpty()) {
return cleanModule(p.module());
} else if (p.main() != null && !p.main().isBlank()) {
Expand All @@ -60,14 +121,14 @@ private static String getModule(io.mvnpm.npm.model.Package p) {
return INDEX_JS;
}

private static String cleanModule(String module) {
private String cleanModule(String module) {
if (module.startsWith(Constants.DOT + Constants.SLASH)) {
return module.substring(2);
}
return module;
}

private static String getModuleRoot(String module) {
private String getModuleRoot(String module) {
if (!module.startsWith(Constants.SLASH) && module.contains(Constants.SLASH)) {
return module.split(Constants.SLASH)[0] + Constants.SLASH;
} else {
Expand Down
25 changes: 19 additions & 6 deletions src/main/java/io/mvnpm/file/type/JarClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ public class JarClient {
@Inject
MavenRepositoryService mavenRepositoryService;

@Inject
ImportMapUtil importMapUtil;

public Path createEmptyJar(Path forJar, String replaceJarWith) {
Path emptyFile = Paths.get(forJar.toString().replace(Constants.DOT_JAR, replaceJarWith));
if (!Files.exists(emptyFile)) {
Expand Down Expand Up @@ -95,9 +98,6 @@ private void jarInput(io.mvnpm.npm.model.Package p, Path localFilePath, Path pom
// Pom properties entry
writeJarEntry(jarOutput, pomXmlDir + POM_DOT_PROPERTIES, createPomProperties(p));

// Import map
writeJarEntry(jarOutput, Location.IMPORTMAP_PATH, ImportMapUtil.createImportMap(p));

// Tar contents
tgzToJar(p, tgzPath, jarOutput);

Expand All @@ -116,21 +116,29 @@ private void tgzToJar(io.mvnpm.npm.model.Package p, Path tgzPath, JarArchiveOutp
GzipCompressorInputStream gzipInputStream = new GzipCompressorInputStream(tgzInputStream);
TarArchiveInputStream tarArchiveInputStream = new TarArchiveInputStream(gzipInputStream)) {
final Map<String, byte[]> toTgz = new LinkedHashMap<>();
final Map<String, byte[]> toImportMap = new LinkedHashMap<>();
for (TarArchiveEntry entry = tarArchiveInputStream.getNextEntry(); entry != null; entry = tarArchiveInputStream
.getNextEntry()) {
tgzEntryToJarEntry(p, entry, tarArchiveInputStream, toTgz, jarOutput);
tgzEntryToJarEntry(p, entry, tarArchiveInputStream, toTgz, toImportMap, jarOutput);
}
// More.tar.gz
if (!toTgz.isEmpty()) {
final byte[] bytes = tarGz(toTgz);
writeJarEntry(jarOutput, MVNPM_MORE_ARCHIVE, bytes);
}
// Import map
if (!toImportMap.isEmpty()) {
writeJarEntry(jarOutput, Location.IMPORTMAP_PATH, importMapUtil.createImportMap(toImportMap));
}

}
}

private void tgzEntryToJarEntry(io.mvnpm.npm.model.Package p, ArchiveEntry entry, TarArchiveInputStream tar,
Map<String, byte[]> toTgz,
Map<String, byte[]> toImportMap,
JarArchiveOutputStream jarOutput) throws IOException {
String importMapRoot = ImportMapUtil.getImportMapRoot(p);
String importMapRoot = importMapUtil.getImportMapRoot(p);
// Let's filter out files we do not need..
String name = entry.getName();
final boolean shouldAdd = !matches(FILES_TO_EXCLUDE, name);
Expand All @@ -149,7 +157,12 @@ private void tgzEntryToJarEntry(io.mvnpm.npm.model.Package p, ArchiveEntry entry
bos.flush();
baos.flush();
if (shouldAdd && !isRelativeLink) {
writeJarEntry(jarOutput, jarEntryPath, baos.toByteArray());
byte[] contents = baos.toByteArray();
writeJarEntry(jarOutput, jarEntryPath, contents);
// Also gather all package.json
if (jarEntryPath.endsWith("/package.json")) {
toImportMap.put(name, contents);
}
} else if (shouldTgz && !isRelativeLink) {
// We don't add the META-INF because the tgz is already in META-INF
toTgz.put("resources" + importMapRoot + name, baos.toByteArray());
Expand Down
15 changes: 9 additions & 6 deletions src/main/java/io/mvnpm/file/type/PomClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public void createAndSavePom(io.mvnpm.npm.model.Package p, Path localFilePath) {

private void writePomToFileSystem(io.mvnpm.npm.model.Package p, Path localFilePath) {

List<Dependency> deps = toDependencies(p.dependencies());
List<Dependency> deps = toDependencies(p);

Model model = new Model();

Expand Down Expand Up @@ -208,17 +208,20 @@ private List<Developer> toDevelopers(List<Maintainer> maintainers) {
return ds;
}

private List<Dependency> toDependencies(Map<Name, String> dependencies) {
private List<Dependency> toDependencies(io.mvnpm.npm.model.Package p) {
List<Dependency> deps = new ArrayList<>();
populateFromMap(deps, p.dependencies());
populateFromMap(deps, p.peerDependencies());
return deps;
}

private void populateFromMap(List<Dependency> listToPopulate, Map<Name, String> dependencies) {
if (dependencies != null && !dependencies.isEmpty()) {
for (Map.Entry<Name, String> e : dependencies.entrySet()) {
Name name = e.getKey();
String version = e.getValue();
deps.add(toDependency(name, version));
listToPopulate.add(toDependency(name, version));
}
return deps;
} else {
return List.of();
}
}

Expand Down
5 changes: 4 additions & 1 deletion src/main/java/io/mvnpm/maven/MavenRepositoryApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ public class MavenRepositoryApi {
@Inject
CompositeService compositeService;

@Inject
ImportMapUtil importMapUtil;

@GET
@Path("/org/mvnpm/{ga : (.+)?}/maven-metadata.xml")
@Produces(MediaType.APPLICATION_XML)
Expand Down Expand Up @@ -95,7 +98,7 @@ public Response getImportMap(@PathParam("gavt") String gavt) {
.build();
} else {
Package npmPackage = npmRegistryFacade.getPackage(nameVersionType.name().npmFullName, nameVersionType.version());
return Response.ok(ImportMapUtil.createImportMap(npmPackage)).build();
return Response.ok(importMapUtil.createImportMap(npmPackage)).build();
}
}

Expand Down
1 change: 1 addition & 0 deletions src/main/java/io/mvnpm/npm/model/Package.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ public record Package(
String type,
List<Maintainer> maintainers,
Map<Name, String> dependencies,
Map<Name, String> peerDependencies,
Dist dist) {
}

0 comments on commit 649782e

Please sign in to comment.