Skip to content

Commit

Permalink
Install jruby-complete.jar, and set "jruby"
Browse files Browse the repository at this point in the history
When using JRuby, Embulk expects to have an Embulk System Property "jruby"
with a "file:" URI, such as "jruby=file:///path/to/jruby-complete.9.x.y.z.jar"

See EEP-6: JRuby as Optional
https://github.com/embulk/embulk/blob/master/docs/eeps/eep-0006.md

This change is to add a new "jruby" notation in "installEmbulkRunSet"
to download jruby-complete.jar, and set the "jruby" property.
  • Loading branch information
dmikurube committed Jun 3, 2024
1 parent e39f24d commit e722d15
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 4 deletions.
64 changes: 62 additions & 2 deletions src/main/java/org/embulk/gradle/runset/InstallEmbulkRunSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.gradle.api.Action;
import org.gradle.api.IllegalDependencyNotation;
import org.gradle.api.InvalidUserDataException;
Expand Down Expand Up @@ -64,8 +65,10 @@ public InstallEmbulkRunSet() {

this.project = this.getProject();
this.logger = this.project.getLogger();
this.embulkHome = null;
this.embulkSystemProperties = new Properties();
this.embulkSystemPropertiesSource = null;
this.jrubyRelative = null;
this.m2RepoRelative = DEFAULT_M2_REPO_RELATIVE;

final ObjectFactory objectFactory = this.project.getObjects();
Expand Down Expand Up @@ -117,6 +120,45 @@ public void artifact(final Object dependencyNotation) {
}
}

/**
* Adds a JRuby-complete Maven artifact to be installed.
*
* <p>It tries to simulate Gradle's dependency notations, but it is yet far from perfect.
*
* @see <a href="https://github.com/gradle/gradle/blob/v8.7.0/platforms/software/dependency-management/src/main/java/org/gradle/api/internal/notations/DependencyNotationParser.java#L49-L86">org.gradle.api.internal.notations.DependencyNotationParser#create</a>
*/
public InstallEmbulkRunSet jruby(final Object dependencyNotation) {
final Dependency dependency;
if (dependencyNotation instanceof CharSequence) {
dependency = this.dependencyFromCharSequence((CharSequence) dependencyNotation);
} else if (dependencyNotation instanceof Map) {
dependency = this.dependencyFromMap((Map) dependencyNotation);
} else {
throw new IllegalDependencyNotation("Supplied jruby module notation is invalid.");
}

// Constructing an independent (detached) Configuration so that its dependencies are not affected by other plugins.
final Configuration configuration = this.project.getConfigurations().detachedConfiguration(dependency);

final ResolvableDependencies resolvableDependencies = configuration.getIncoming();
final ArtifactCollection artifactCollection = resolvableDependencies.getArtifacts();

// Getting the JAR file.
final ArrayList<ComponentIdentifier> componentIds = new ArrayList<>();
final Set<ResolvedArtifactResult> resolvedArtifactResults = artifactCollection.getArtifacts();
if (resolvedArtifactResults.isEmpty()) {
throw new IllegalDependencyNotation("Supplied jruby module notation is unavailable.");
}
if (resolvedArtifactResults.size() > 1) {
throw new IllegalDependencyNotation("Supplied jruby module notation has dependencies. Specify jruby-complete instead.");
}

final ResolvedArtifactResult resolvedArtifactResult = resolvedArtifactResults.stream().findFirst().get();
this.jrubyRelative = this.fromArtifact(resolvedArtifactResult, "jar");

return this;
}

public InstallEmbulkRunSet embulkHome(final File dir) {
if (dir == null) {
throw new InvalidUserDataException("Supplied embulkHome is null.");
Expand All @@ -140,6 +182,8 @@ public InstallEmbulkRunSet embulkHome(final File dir) {
this.logger.lifecycle("Supplied embulkHome \"{}\" does not exist, then will be created.", dir);
}

this.embulkHome = dir.toPath();

super.into(dir);
return this;
}
Expand Down Expand Up @@ -185,18 +229,20 @@ public final Copy into(final Object destPath, final Action<? super CopySpec> cop
throw new InvalidUserDataException("\"into\" is not permitted in InstallEmbulkRunSet. Use \"embulkHome\" instead.");
}

private void fromArtifact(final ResolvedArtifactResult resolvedArtifactResult, final String artifactType) {
private Path fromArtifact(final ResolvedArtifactResult resolvedArtifactResult, final String artifactType) {
final ComponentIdentifier id = resolvedArtifactResult.getId().getComponentIdentifier();
final File file = resolvedArtifactResult.getFile();

if (id instanceof ModuleComponentIdentifier) {
final Path modulePath = moduleToPath((ModuleComponentIdentifier) id);
final Path modulePathFromHome = this.m2RepoRelative.resolve(modulePath);
this.logger.lifecycle("Setting to copy {}:{} into {}", id, artifactType, modulePath);
this.logger.info("Cached file: {}", file);
this.from(file, copy -> {
copy.into(this.m2RepoRelative.resolve(modulePath).toFile());
copy.into(modulePathFromHome.toFile());
copy.setDuplicatesStrategy(DuplicatesStrategy.EXCLUDE);
});
return modulePathFromHome.resolve(file.getName());
} else if (id instanceof ProjectComponentIdentifier) {
throw new IllegalDependencyNotation("Cannot install artifacts for a project component (" + id.getDisplayName() + ")");
} else {
Expand Down Expand Up @@ -273,6 +319,16 @@ private static Map<Object, Object> castMap(final Map map) {
@Override
@TaskAction
protected void copy() {
if (this.embulkHome == null) {
throw new InvalidUserDataException("embulkHome is not supplied.");
}

if (this.jrubyRelative != null) {
this.embulkSystemProperties.setProperty(
"jruby",
this.embulkHome.resolve(this.jrubyRelative).toUri().toString());
}

if (this.embulkSystemPropertiesSource != null) {
try (final OutputStream out = Files.newOutputStream(this.embulkSystemPropertiesSource)) {
this.embulkSystemProperties.store(
Expand Down Expand Up @@ -314,7 +370,11 @@ private synchronized void createPropertiesSourceAndSetToCopy() {

private final Properties embulkSystemProperties;

private Path embulkHome;

private Path embulkSystemPropertiesSource;

private Path jrubyRelative;

private Path m2RepoRelative;
}
21 changes: 19 additions & 2 deletions src/test/java/org/embulk/gradle/runset/TestEmbulkRunSetPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@
import static org.embulk.gradle.runset.Util.prepareProjectDir;
import static org.embulk.gradle.runset.Util.runGradle;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
Expand All @@ -34,7 +37,7 @@

public class TestEmbulkRunSetPlugin {
@Test
public void testSimple(@TempDir Path tempDir) throws IOException {
public void testSimple(@TempDir Path tempDir) throws IOException, URISyntaxException {
final Path projectDir = prepareProjectDir(tempDir, "simple");

runGradle(projectDir, "installEmbulkRunSet");
Expand All @@ -53,8 +56,22 @@ public FileVisitResult visitFile(final Path file, final BasicFileAttributes attr
try (final InputStream in = Files.newInputStream(propertiesPath)) {
properties.load(in);
}
assertEquals(2, properties.size());
assertEquals(3, properties.size());
assertEquals("value", properties.getProperty("key"));
assertEquals(Paths.get("lib").resolve("m2").resolve("repository").toString(), properties.getProperty("m2_repo"));
assertEquals("lib/m2/repository", properties.getProperty("m2_repo"));
final URI jrubyUri = new URI(properties.getProperty("jruby"));
assertEquals("file", jrubyUri.getScheme());
final Path jrubyAbsolutePath = Paths.get(jrubyUri.getPath());
assertTrue(jrubyAbsolutePath.isAbsolute());
assertTrue(jrubyAbsolutePath.endsWith(
Paths.get("lib")
.resolve("m2")
.resolve("repository")
.resolve("org")
.resolve("jruby")
.resolve("jruby-complete")
.resolve("9.1.15.0")
.resolve("jruby-complete-9.1.15.0.jar")));
}
}
1 change: 1 addition & 0 deletions src/test/resources/simple/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ repositories {

installEmbulkRunSet {
embulkHome file("${project.buildDir}/simple")
jruby "org.jruby:jruby-complete:9.1.15.0"
m2RepoRelative "lib/m2/repository"
embulkSystemProperty "key", "value"
artifact "org.embulk:embulk-input-postgresql:0.13.2"
Expand Down

0 comments on commit e722d15

Please sign in to comment.