Skip to content

Commit

Permalink
[Dependencies] Move away from Ivy
Browse files Browse the repository at this point in the history
Ivy didn't work when building a native image, so went with a simpler implementation that
tries to fetch a dependency from a Maven repository. Doesn't handle any transitive dependency
fetching, but maybe would add some of that later or figure out how to make something Ivy-like
work with the native-image stuff.
  • Loading branch information
ttiimm committed May 18, 2024
1 parent 54ac8d3 commit c516f14
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 109 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@ jobs:
with:
distribution: 'temurin'
java-version: '22'
- name: Dependencies
run: mkdir lib && wget -U "Cult-Baby" https://repo1.maven.org/maven2/org/apache/ivy/ivy/2.5.2/ivy-2.5.2.jar -O lib/ivy-2.5.2.jar
- name: Compile
run: java -cp lib/ivy-2.5.2.jar --enable-preview --source 22 src/Main.java build --fat
run: java --enable-preview --source 22 src/Main.java build --fat
- name: Get the version
id: get_version
run: echo ::set-output name=VERSION::${GITHUB_REF#refs/tags/v} | sed 's/-alpha//g'
Expand Down
3 changes: 1 addition & 2 deletions Cult.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
[package]
name = "cult"
version = "0.2.0"
version = "0.3.0"

[dependencies]
org.apache.ivy_ivy = "2.5.2"
131 changes: 27 additions & 104 deletions src/Main.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
import org.apache.ivy.Ivy;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.report.DownloadStatus;
import org.apache.ivy.core.report.ResolveReport;
import org.apache.ivy.core.resolve.ResolveOptions;
import org.apache.ivy.util.AbstractMessageLogger;
import org.apache.ivy.util.Message;

import java.io.*;
import java.net.URI;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.text.ParseException;
import java.util.*;
import java.util.jar.JarEntry;
Expand Down Expand Up @@ -222,78 +217,34 @@ Result extractDependencies() {
}

Result fetch(Dependencies dependencies) {
// // XXX: need to programmatically set the Ivy Settings since trying to load resources fails during native execution
// var ivySettings = new IvySettings();
// ivySettings.setDefaultIvyUserDir(new File(STR."\{System.getProperty("user.home")}/.ivy2"));
// ivySettings.setDefaultCache(new File(STR."\{System.getProperty("user.home")}/.ivy2/cache"));
//
// // Add a resolver for Maven Central
// IBiblioResolver resolver = new IBiblioResolver();
// resolver.setM2compatible(true);
// resolver.setName("central");
// resolver.setRoot("https://repo1.maven.org/maven2/");
// ivySettings.addResolver(resolver);
// ivySettings.setDefaultResolver(resolver.getName());
//
// // Add a public resolver
// URLResolver publicResolver = new URLResolver();
// publicResolver.setName("public");
// publicResolver.addIvyPattern("http://repo1.maven.org/maven2/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]");
// publicResolver.addArtifactPattern("http://repo1.maven.org/maven2/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]");
// ivySettings.addResolver(publicResolver);
//
// // Add a main resolver
// URLResolver mainResolver = new URLResolver();
// mainResolver.setName("main");
// mainResolver.addIvyPattern("http://repo1.maven.org/maven2/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]");
// mainResolver.addArtifactPattern("http://repo1.maven.org/maven2/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]");
// ivySettings.addResolver(mainResolver);
//
// Ivy ivy = Ivy.newInstance(ivySettings);
// Message.setDefaultLogger(new QuietLogger());

Ivy ivy = Ivy.newInstance();
try {
ivy.configureDefault();
Message.setDefaultLogger(new QuietLogger());
} catch (ParseException | IOException e) {
System.err.println("error: could not configure Ivy");
System.err.println(e.getMessage());
return new Result(null);
}

var dirResult = createDir(Paths.get("target","lib"));
if (!dirResult.isOk()) {
return dirResult;
var paths = new ArrayList<LibInfo>();
Path libDir = Paths.get("target", "lib");
var result = createDir(libDir);
if (!result.isOk()) {
return result;
}

var paths = new ArrayList<LibInfo>();
for (var entry : dependencies.get().entrySet()) {
try {
ModuleId module = entry.getKey();
Version version = entry.getValue();
ModuleRevisionId mrid = ModuleRevisionId.newInstance(module.organization, module.name, version.semver());
ResolveOptions resolveOptions = new ResolveOptions().setConfs(new String[]{"default"});
ResolveReport resolveReport = ivy.resolve(mrid, resolveOptions, true);
for (var report : resolveReport.getAllArtifactsReports()) {
if (report.getDownloadStatus() != DownloadStatus.NO) {
System.out.println(STR." \{report}");
}
// XXX: maybe need to filter based on the extension or some such?
var source = report.getLocalFile().getAbsoluteFile().toPath();
var target = Paths.get("target", "lib", source.getFileName().toString());
if (!target.toFile().exists()) {
Files.copy(source, target);
paths.add(new LibInfo(target, true));
} else {
paths.add(new LibInfo(target, false));
}

// XXX: maybe move this stuff into ModuleId
var module = entry.getKey();
var orgPath = String.join("/", module.organization.split("\\."));
var version = entry.getValue();
var semver = version.semver();
var jarName = STR."\{ module.name }-\{ semver }.jar";

var libJar = libDir.resolve(jarName);
if (libJar.toFile().exists()) {
paths.add(new LibInfo(libJar, false));
} else {
String url = STR."https://repo1.maven.org/maven2/\{ orgPath }/\{ module.name }/\{ semver }/\{ jarName }";
try (InputStream in = URI.create(url).toURL().openStream()) {
Files.copy(in, libJar);
paths.add(new LibInfo(libJar, false));
} catch (IOException e) {
System.err.println(STR."error: could not fetch library: \{url}");
System.err.println(e.getMessage());
return new Result(null);
}
} catch (ParseException | IOException e) {
System.err.println(STR."error: failed fetching dependency `\{entry}`");
System.err.println(e.getMessage());
return new Result(null);
}
}
return new Result(new Jars(paths));
Expand Down Expand Up @@ -564,31 +515,3 @@ public void run() {
}
}
}

// Custom Logger for Ivy, maybe there's an easier way to configure this behavior?
static class QuietLogger extends AbstractMessageLogger {

@Override
public void doProgress() {
// Do nothing
}

@Override
public void doEndProgress(String msg) {
// Do nothing
}

@Override
public void rawlog(String msg, int level) {
if (level <= Message.MSG_ERR) {
System.err.println(msg);
}
}

@Override
public void log(String msg, int level) {
if (level <= Message.MSG_ERR) {
System.err.println(msg);
}
}
}

0 comments on commit c516f14

Please sign in to comment.