diff --git a/build.gradle b/build.gradle index e0843ad..6516161 100644 --- a/build.gradle +++ b/build.gradle @@ -23,9 +23,9 @@ repositories { } dependencies { - compile 'org.slf4j:slf4j-api:1.7.12+' + compile 'org.slf4j:slf4j-api:1.7.12' /* using the simple logger at runtime, no need for it at compile time though */ - runtime 'org.slf4j:slf4j-simple:1.7.12+' + runtime 'org.slf4j:slf4j-simple:1.7.12' /* Used for processing yaml files inside of gems */ compile 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.5.4' @@ -33,8 +33,8 @@ dependencies { compile 'com.fasterxml.jackson.core:jackson-databind:2.5.4' /* shrinkwrap is used for digging into archives */ - compile "org.jboss.shrinkwrap:shrinkwrap-bom:1.2.2+" - compile "org.jboss.shrinkwrap:shrinkwrap-depchain:1.2.2+" + compile "org.jboss.shrinkwrap:shrinkwrap-bom:1.2.2" + compile "org.jboss.shrinkwrap:shrinkwrap-depchain:1.2.2" testCompile "org.spockframework:spock-core:1.0-groovy-2.4" testCompile 'org.apache.commons:commons-io:1.3.2+' diff --git a/gem/jems.gemspec b/gem/jems.gemspec new file mode 100644 index 0000000..8a7aa1e --- /dev/null +++ b/gem/jems.gemspec @@ -0,0 +1,14 @@ +#-*- mode: ruby -*- + +Gem::Specification.new do |s| + s.name = 'jems' + s.version = '0.1.5' + s.authors = ['Christian Meier'] + s.summary = 'JRuby Jems' + s.files = ['jems.gemspec', 'lib/jems.rb'] + s.platform = 'java' + s.requirements << "jar com.github.jrubygradle:jem, #{s.version}" + s.add_runtime_dependency 'jar-dependencies', '~> 0.1.15' +end + +# vim: syntax=Ruby diff --git a/gem/lib/jems.rb b/gem/lib/jems.rb new file mode 100644 index 0000000..f98fdde --- /dev/null +++ b/gem/lib/jems.rb @@ -0,0 +1,34 @@ +require 'jems_jars' +module Jems + + def self.jems_class_loader + @class_loader ||= com.github.jrubygradle.jem.JemsClassLoader.create + end + + def self.activate( gem ) + gemspec_raw = jems_class_loader.add_jem( gem ) + gemspec = eval( gemspec_raw.to_ruby ) + + return false if Gem.loaded_specs[ gemspec.name ] + + gem_name = 'gems/' + gemspec.full_name + '/.jrubydir' + url = jems_class_loader.get_resource( gem_name ) + base = "uri:#{url.to_s.sub(/.jrubydir$/, '')}" + + added = false + gemspec.require_paths.each do |path| + fullpath = File.join( base, path ) + if File.directory?(fullpath) and not $LOAD_PATH.member?(fullpath) + # TODO rubygems insert before 'site_ruby' entry of the LOAD_PATH + $LOAD_PATH.unshift fullpath + added = true + end + end + # TODO check if gemspec.activate does the job better + if added + Gem.loaded_specs[ gemspec.name ] = gemspec + end + added + end + +end diff --git a/src/main/java/groovy/com/github/jrubygradle/jem/Dependency.java b/src/main/java/com/github/jrubygradle/jem/Dependency.java similarity index 100% rename from src/main/java/groovy/com/github/jrubygradle/jem/Dependency.java rename to src/main/java/com/github/jrubygradle/jem/Dependency.java diff --git a/src/main/java/groovy/com/github/jrubygradle/jem/Gem.java b/src/main/java/com/github/jrubygradle/jem/Gem.java similarity index 99% rename from src/main/java/groovy/com/github/jrubygradle/jem/Gem.java rename to src/main/java/com/github/jrubygradle/jem/Gem.java index 45fb33b..d66b089 100644 --- a/src/main/java/groovy/com/github/jrubygradle/jem/Gem.java +++ b/src/main/java/com/github/jrubygradle/jem/Gem.java @@ -7,7 +7,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import java.io.File; -import java.io.IOError; import java.io.IOException; import java.io.InputStream; import java.util.List; diff --git a/src/main/java/groovy/com/github/jrubygradle/jem/GemInstaller.java b/src/main/java/com/github/jrubygradle/jem/GemInstaller.java similarity index 100% rename from src/main/java/groovy/com/github/jrubygradle/jem/GemInstaller.java rename to src/main/java/com/github/jrubygradle/jem/GemInstaller.java diff --git a/src/main/java/com/github/jrubygradle/jem/JemsClassLoader.java b/src/main/java/com/github/jrubygradle/jem/JemsClassLoader.java new file mode 100644 index 0000000..473f166 --- /dev/null +++ b/src/main/java/com/github/jrubygradle/jem/JemsClassLoader.java @@ -0,0 +1,50 @@ +package com.github.jrubygradle.jem; + +import com.github.jrubygradle.jem.internal.GemInstaller; +import com.github.jrubygradle.jem.GemInstaller.DuplicateBehavior; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Files; +import java.util.Collections; + +/** + * Created by cmeier on 8/15/15. + */ +public class JemsClassLoader extends URLClassLoader { + + private final File jemsDir; + + public static JemsClassLoader create() throws IOException { + return new JemsClassLoader(Files.createTempDirectory("jems").toFile()); + } + + public JemsClassLoader(File jemsDir) throws IOException { + super(new URL[] { jemsDir.toURI().toURL() }); + this.jemsDir = jemsDir; + } + + public Gem addJem(String jem) throws IOException { + return addJem(new File(jem)); + } + public Gem addJem(File jem) throws IOException { + GemInstaller installer = new GemInstaller(jemsDir.getAbsolutePath(), Collections.emptyList()); + installer.mkdirs(); + Gem gemspec = installer.installGem(jemsDir, jem, DuplicateBehavior.OVERWRITE); + String dir = "gems/" + installer.gemFullName(gemspec); + createDirInfoFile(dir); + for(String path: gemspec.requirePaths){ + createDirInfoFile(dir + "/" + path); + } + return gemspec; + } + + private void createDirInfoFile(String dir) throws IOException { + try (FileWriter out = new FileWriter(new File(jemsDir, dir + "/.jrubydir"))){ + out.append("."); + } + } +} diff --git a/src/main/java/groovy/com/github/jrubygradle/jem/Requirement.java b/src/main/java/com/github/jrubygradle/jem/Requirement.java similarity index 100% rename from src/main/java/groovy/com/github/jrubygradle/jem/Requirement.java rename to src/main/java/com/github/jrubygradle/jem/Requirement.java diff --git a/src/main/java/groovy/com/github/jrubygradle/jem/Version.java b/src/main/java/com/github/jrubygradle/jem/Version.java similarity index 100% rename from src/main/java/groovy/com/github/jrubygradle/jem/Version.java rename to src/main/java/com/github/jrubygradle/jem/Version.java diff --git a/src/main/java/groovy/com/github/jrubygradle/jem/internal/GemInstaller.java b/src/main/java/com/github/jrubygradle/jem/internal/GemInstaller.java similarity index 97% rename from src/main/java/groovy/com/github/jrubygradle/jem/internal/GemInstaller.java rename to src/main/java/com/github/jrubygradle/jem/internal/GemInstaller.java index 9782a32..df464c6 100644 --- a/src/main/java/groovy/com/github/jrubygradle/jem/internal/GemInstaller.java +++ b/src/main/java/com/github/jrubygradle/jem/internal/GemInstaller.java @@ -50,14 +50,14 @@ public class GemInstaller { } } - public boolean installGem(File installDir, File gem, DuplicateBehavior onDuplicate) { + public Gem installGem(File installDir, File gem, DuplicateBehavior onDuplicate) { /* TODO: isValidGem? */ try { cacheGemInInstallDir(installDir, gem); } catch (IOException ex) { logger.error("Failed to cache our gem in %s", installDir, ex); - return false; + return null; } Gem gemMetadata; @@ -73,7 +73,7 @@ public class GemInstaller { } catch (IOException ex) { logger.error("Failed to process the metadata", ex); - return false; + return null; } logger.info(String.format("We've processed metadata for %s at version %s", gemMetadata.name, gemMetadata.version.version)); @@ -96,7 +96,7 @@ public class GemInstaller { gemMetadata.name, installDir), ex); } - return true; + return gemMetadata; } /** diff --git a/src/test/groovy/com/github/jrubygradle/jem/internal/GemInstallerSpec.groovy b/src/test/groovy/com/github/jrubygradle/jem/internal/GemInstallerSpec.groovy index a30a107..b2ea2d2 100644 --- a/src/test/groovy/com/github/jrubygradle/jem/internal/GemInstallerSpec.groovy +++ b/src/test/groovy/com/github/jrubygradle/jem/internal/GemInstallerSpec.groovy @@ -6,7 +6,6 @@ import spock.lang.* import java.nio.file.Files import java.nio.file.Path -import org.apache.commons.io.FileUtils class GemInstallerSpec extends Specification { static final String FIXTURES_ROOT = new File(['src', 'test', 'resources'].join(File.separator)).absolutePath