jbundler 0.0.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Build.md +32 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +35 -0
- data/Gemfile.lock- +33 -0
- data/Readme.md +88 -0
- data/lib/jbundler.jar +0 -0
- data/lib/jbundler.rb +25 -20
- data/lib/jbundler.rb~ +2 -0
- data/lib/jbundler/aether.rb +44 -15
- data/lib/jbundler/aether.rb~ +68 -0
- data/lib/jbundler/classpath_file.rb +2 -4
- data/lib/jbundler/classpath_file.rb~ +207 -0
- data/lib/jbundler/gemfile_lock.rb +4 -4
- data/lib/jbundler/gemfile_lock.rb~ +17 -0
- data/lib/jbundler/maven.rb~ +252 -0
- data/lib/jbundler/maven_gemify3.rb~ +337 -0
- data/lib/jbundler/{maven_util.rb → maven_util.rb~} +4 -14
- data/lib/jbundler/maven_version.rb~ +4 -0
- data/lib/jbundler/mavenfile.rb~ +9 -0
- data/lib/jbundler/pom.rb +2 -2
- data/lib/jbundler/pom.rb~ +251 -0
- data/spec/aether_spec.rb +78 -0
- data/spec/{mavenfile_spec.rb → aether_spec.rb~} +12 -14
- data/spec/classpath_file_spec.rb +26 -24
- data/spec/classpath_file_spec.rb~ +81 -0
- data/spec/{maven_util_spec.rb → maven_util_spec.rb~} +1 -12
- data/spec/mavenfile_spec.rb~ +40 -0
- data/spec/pom_spec.rb +2 -0
- data/spec/pom_spec.rb~ +40 -0
- data/spec/setup.rb +3 -0
- data/spec/setup.rb~ +3 -0
- metadata +82 -54
- data/lib/jbundler/mavenfile.rb +0 -77
data/Build.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# build jbundler #
|
2
|
+
|
3
|
+
the build uses ruby-maven. **note** ruby-maven uses maven and maven is highly modular, i.e. it comes only with the core and the moment you need a plugin he first time its starts downloading it. with that in mind the first usage of (ruby-)maven involves a lot of downloading - so be prepared :)
|
4
|
+
|
5
|
+
first get all the development gems in place:
|
6
|
+
|
7
|
+
```jruby -S bundle install```
|
8
|
+
|
9
|
+
to build the (extension) jar for the lib directory (prepare the jar before packaging the gem)
|
10
|
+
|
11
|
+
```rmvn prepare-package```
|
12
|
+
|
13
|
+
this also runs all the test over a couple of jruy version each in 1.8 and 1.9 mode. so these tests take some time. in skip the tests when building the gem use:
|
14
|
+
|
15
|
+
```rmvn prepare-package --Dmaven.test.skip```
|
16
|
+
|
17
|
+
to build the gem in **target/jbundler-0.0.1.gem**
|
18
|
+
|
19
|
+
```rmvn package```
|
20
|
+
|
21
|
+
or once the jar file is in place then
|
22
|
+
|
23
|
+
```gem build jbundler.gemspec```
|
24
|
+
|
25
|
+
will do as well.
|
26
|
+
|
27
|
+
## proper maven and IDEs ##
|
28
|
+
|
29
|
+
once ```rmvn``` generated the **Gemfile.pom** you can use proper maven3 by setting a sybolic link from **pom.xml** to **Gemfile.pom**. in the end rmvn is just ruby wrapper around maven3. the **Gemfile.pom** is generated from the *jbundler.gemspec*, *Gemfile*, *Gemfile.lock* and *Mavenfile*.
|
30
|
+
|
31
|
+
your IDE might be able to use the pom.xml to manage the project and its java sources.
|
32
|
+
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
jbundler (0.2.0)
|
5
|
+
ruby-maven (= 3.0.4.0.29.0)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
specs:
|
10
|
+
builder (3.0.0)
|
11
|
+
cucumber (1.1.9)
|
12
|
+
builder (>= 2.1.2)
|
13
|
+
diff-lcs (>= 1.1.2)
|
14
|
+
gherkin (~> 2.9.0)
|
15
|
+
json (>= 1.4.6)
|
16
|
+
term-ansicolor (>= 1.0.6)
|
17
|
+
diff-lcs (1.1.3)
|
18
|
+
gherkin (2.9.3-java)
|
19
|
+
json (>= 1.4.6)
|
20
|
+
json (1.7.3-java)
|
21
|
+
maven-tools (0.29.0)
|
22
|
+
minitest (2.10.1)
|
23
|
+
ruby-maven (3.0.4.0.29.0)
|
24
|
+
maven-tools (= 0.29.0)
|
25
|
+
thor (~> 0.14.6)
|
26
|
+
term-ansicolor (1.0.7)
|
27
|
+
thor (0.14.6)
|
28
|
+
|
29
|
+
PLATFORMS
|
30
|
+
java
|
31
|
+
|
32
|
+
DEPENDENCIES
|
33
|
+
cucumber (~> 1.1.9)
|
34
|
+
jbundler!
|
35
|
+
minitest (~> 2.10.0)
|
data/Gemfile.lock-
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
jbundler (0.2.0)
|
5
|
+
ruby-maven (= 3.0.4.0.29.0)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
specs:
|
10
|
+
builder (3.0.0)
|
11
|
+
cucumber (1.1.9)
|
12
|
+
builder (>= 2.1.2)
|
13
|
+
diff-lcs (>= 1.1.2)
|
14
|
+
gherkin (~> 2.9.0)
|
15
|
+
json (>= 1.4.6)
|
16
|
+
term-ansicolor (>= 1.0.6)
|
17
|
+
diff-lcs (1.1.3)
|
18
|
+
gherkin (2.9.3-java)
|
19
|
+
json (>= 1.4.6)
|
20
|
+
json (1.7.3-java)
|
21
|
+
minitest (2.10.1)
|
22
|
+
ruby-maven (3.0.4.0.29.0)
|
23
|
+
thor (~> 0.14.6)
|
24
|
+
term-ansicolor (1.0.7)
|
25
|
+
thor (0.14.6)
|
26
|
+
|
27
|
+
PLATFORMS
|
28
|
+
java
|
29
|
+
|
30
|
+
DEPENDENCIES
|
31
|
+
cucumber (~> 1.1.9)
|
32
|
+
jbundler!
|
33
|
+
minitest (~> 2.10.0)
|
data/Readme.md
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
# jbundler #
|
2
|
+
|
3
|
+
* the DSL mimics the one from bundler
|
4
|
+
* you can use maven like version declaration or rubygems/bundler like version ranges
|
5
|
+
* it locks down the versions like bundler inside "Mvnfile.lock"
|
6
|
+
* you can declare jar dependency within a rubygems using the requirements directive of the gem specification. jbundler will include those jar dependencies into its classpath
|
7
|
+
* on the first run everything get resolved, any further run just the setup of classpath is done (without any maven involved)
|
8
|
+
* it integrates nicely with bundler when Bundler.require is used
|
9
|
+
|
10
|
+
## get started
|
11
|
+
|
12
|
+
just add it as **first** entry in your *Gemfile* (pending since no gem is released)
|
13
|
+
|
14
|
+
```gem 'jbundler'```
|
15
|
+
|
16
|
+
such bundler config will trigger the classpath resolution on the first call of ```Bundler.require```, any successive runs will reuse the classpath from *.jbundler/classpath.rb* without any more action with maven.
|
17
|
+
|
18
|
+
if you use only **rubygems** or **isolate** then following require will trigger the classpath setup
|
19
|
+
|
20
|
+
```require 'jbundler'```
|
21
|
+
|
22
|
+
## example ##
|
23
|
+
|
24
|
+
**please first build the jar file for the jbundler gem, see [Build.md](Build.md).**
|
25
|
+
|
26
|
+
*example/my_project* has a Gemfile which uses a gem which depends on jar dependency. see *example/gem_with_jar/gem_with_jar.gemspec* how the jar gets declared.
|
27
|
+
|
28
|
+
execute *example/my_project/info.rb* to see it in action:
|
29
|
+
|
30
|
+
cd example/my_project
|
31
|
+
jruby -S bundle install
|
32
|
+
jruby -S bundle exec info.rb
|
33
|
+
|
34
|
+
## limitations ##
|
35
|
+
|
36
|
+
update of single artifacts is not possible.
|
37
|
+
|
38
|
+
since the version resolution happens in two steps - first the gems then the jars/poms - it is possible in case of failure of the second one there could be another set of versions for the gems which would then succeed the jars/poms resolution. but there is plenty of possible ways to improve this (maven could resolve the gems as well, etc)
|
39
|
+
|
40
|
+
**Mvnfile** is **not** a DSL, i.e. it is not ruby though it could use a ruby DSL to read the data (any contribution welcome).
|
41
|
+
|
42
|
+
## jar/pom dependencies ##
|
43
|
+
|
44
|
+
a pom dependency is not associated with a jar file but has dependencies to other poms or jars.
|
45
|
+
|
46
|
+
dependencies can be declared either in **Mvnfile**
|
47
|
+
|
48
|
+
jar 'org.slf4j:slf4j-simple', '> 1.6.2', '< 1.7.0'
|
49
|
+
jar 'org.sonatype.aether:aether-api', '1.13'
|
50
|
+
|
51
|
+
or inside the gemspec through the requirements (see also the example directory of this project):
|
52
|
+
|
53
|
+
Gem::Specification.new do |s|
|
54
|
+
s.name = 'gem_with_jar'
|
55
|
+
s.version = '0.0.0'
|
56
|
+
s.requirements << "jar 'org.slf4j:slf4j-api', '1.5.10'"
|
57
|
+
end
|
58
|
+
|
59
|
+
### maven like version ###
|
60
|
+
|
61
|
+
```jar 'my.group.id:my-artifact-id', '1.2.3'```
|
62
|
+
|
63
|
+
this will add the jar dependency for the maven artifact **my.group.id:my-artifact-id** with version **1.2.3**. this version will be treated as **maven version**, i.e. in case of a version conflict the one which is closer to project root will be used (see also: TODO link)
|
64
|
+
|
65
|
+
### rubygem like version ###
|
66
|
+
|
67
|
+
some example (see also: TODO link)
|
68
|
+
|
69
|
+
jar 'my.group.id:my-artifact-id', '1.2.3'
|
70
|
+
pom 'my.group:my-artifact-id', '=1.2.3'
|
71
|
+
jar 'my.group.id:artifact-id', '>1.2.3'
|
72
|
+
jar 'my.group:artifact-id', '>1.2.3', '=<2.0.1'
|
73
|
+
|
74
|
+
the no version will default to **[0,)** (maven version range) which is **>=0** in the rubygems world.
|
75
|
+
|
76
|
+
jar 'group:artifact-id'
|
77
|
+
|
78
|
+
the *not* version **!3.4.5** can not be mapped properly to a maven version ranges. **>3.4.5** is used instead in these (rare) cases.
|
79
|
+
|
80
|
+
## update ##
|
81
|
+
|
82
|
+
update of a single artifact is not possible (yet). but to update the whole set of artifacts just delete the lockfile *Mvnfile.lock*
|
83
|
+
|
84
|
+
if jbundler sees that **Gemfile.lock** or **Mvnfile** is newer then the **.jbundler/classpath.rb** file then jbundler tries to gracefully upgrade towards the changes. the is a maven-like behaviour and once there are command line tools for jbundler they can behave like bundler.
|
85
|
+
|
86
|
+
## meta-fu ##
|
87
|
+
|
88
|
+
bug-reports and pull request are most welcome.
|
data/lib/jbundler.jar
CHANGED
Binary file
|
data/lib/jbundler.rb
CHANGED
@@ -1,34 +1,39 @@
|
|
1
|
-
require '
|
1
|
+
require 'maven/tools/jarfile'
|
2
2
|
require 'jbundler/classpath_file'
|
3
3
|
require 'jbundler/gemfile_lock'
|
4
4
|
require 'jbundler/aether'
|
5
5
|
|
6
6
|
config = JBundler::AetherConfig.new
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
jarfile = Maven::Tools::Jarfile.new(config.jarfile)
|
9
|
+
if config.skip
|
10
|
+
warn "skip jbundler setup"
|
11
|
+
else
|
12
|
+
classpath_file = JBundler::ClasspathFile.new('.jbundler/classpath.rb')
|
13
|
+
gemfile_lock = JBundler::GemfileLock.new(jarfile, config.gemfile + '.lock')
|
11
14
|
|
12
|
-
if classpath_file.needs_update?(
|
13
|
-
|
15
|
+
if classpath_file.needs_update?(jarfile, gemfile_lock)
|
16
|
+
aether = JBundler::AetherRuby.new(config)
|
14
17
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
+
jarfile.populate_unlocked(aether)
|
19
|
+
gemfile_lock.populate_dependencies(aether)
|
20
|
+
jarfile.populate_locked(aether)
|
18
21
|
|
19
|
-
|
22
|
+
aether.resolve
|
20
23
|
|
21
|
-
|
22
|
-
|
23
|
-
end
|
24
|
+
classpath_file.generate(aether.classpath)
|
25
|
+
jarfile.generate_lockfile(aether.resolved_coordinates)
|
26
|
+
end
|
24
27
|
|
25
|
-
if classpath_file.exists?
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
if classpath_file.exists?
|
29
|
+
require 'java'
|
30
|
+
classpath_file.require_classpath
|
31
|
+
if config.verbose
|
32
|
+
warn "jbundler classpath:"
|
33
|
+
JBUNDLER_CLASSPATH.each do |path|
|
34
|
+
warn "\t#{path}"
|
35
|
+
end
|
32
36
|
end
|
33
37
|
end
|
38
|
+
|
34
39
|
end
|
data/lib/jbundler.rb~
ADDED
data/lib/jbundler/aether.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'java'
|
2
1
|
require 'yaml'
|
3
2
|
|
4
3
|
module JBundler
|
@@ -6,34 +5,54 @@ module JBundler
|
|
6
5
|
# allow yaml config in $HOME/.jbundlerrc and $PWD/.jbundlerrc
|
7
6
|
class AetherConfig
|
8
7
|
|
9
|
-
attr_accessor :verbose, :local_repository, :
|
8
|
+
attr_accessor :verbose, :local_repository, :jarfile, :gemfile, :skip
|
10
9
|
|
11
10
|
def initialize
|
12
11
|
file = '.jbundlerrc'
|
13
12
|
homefile = File.join(ENV['HOME'], file)
|
14
|
-
|
15
|
-
|
16
|
-
@config = (
|
13
|
+
home_config = YAML.load_file(homefile) if File.exists?(homefile)
|
14
|
+
pwd_config = YAML.load_file(file) if File.exists?(file)
|
15
|
+
@config = (home_config || {}).merge(pwd_config || {})
|
16
|
+
end
|
17
|
+
|
18
|
+
if defined? JRUBY_VERSION
|
19
|
+
def jbundler_env(key)
|
20
|
+
ENV[key.upcase.gsub(/./, '_')] || java.lang.System.getProperty(key.downcase.gsub(/_/, '.')) || @config[key.downcase.sub(/^j?bundler/, '').sub(/./, '_')]
|
21
|
+
end
|
22
|
+
else
|
23
|
+
def jbundler_env(key)
|
24
|
+
ENV[key.upcase.gsub(/./, '_')] || @config[key.downcase.sub(/^j?bundler/, '').sub(/./, '_')]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
private :jbundler_env
|
28
|
+
|
29
|
+
def skip
|
30
|
+
skip = jbundler_env('JBUNDLE_SKIP')
|
31
|
+
# defaults to false
|
32
|
+
@skip ||= skip && skip != 'false'
|
17
33
|
end
|
18
34
|
|
19
35
|
def verbose
|
20
|
-
verbose =
|
36
|
+
verbose = jbundler_env('JBUNDLE_VERBOSE')
|
21
37
|
# defaults to false
|
22
38
|
@verbose ||= verbose && verbose != 'false'
|
23
39
|
end
|
24
40
|
|
25
|
-
def
|
26
|
-
|
41
|
+
def jarfile
|
42
|
+
if File.exists?('Mvnfile')
|
43
|
+
warn "'Mvnfile' name is deprecated, please use 'Jarfile' instead"
|
44
|
+
@jarfile = 'Mvnfile'
|
45
|
+
end
|
46
|
+
@jarfile ||= jbundler_env('JBUNDLE_JARFILE') || 'Jarfile'
|
27
47
|
end
|
28
48
|
|
29
49
|
def gemfile
|
30
|
-
@gemfile ||=
|
50
|
+
@gemfile ||= jbundler_env('BUNDLE_GEMFILE') || 'Gemfile'
|
31
51
|
end
|
32
52
|
|
33
53
|
def local_repository
|
34
54
|
# use maven default local repo as default
|
35
|
-
@local_maven_repository ||= (
|
36
|
-
@config['local_repository']||
|
55
|
+
@local_maven_repository ||= (jbundler_env('JBUNDLE_LOCAL_REPOSITORY') ||
|
37
56
|
File.join( ENV['HOME'], ".m2", "repository"))
|
38
57
|
end
|
39
58
|
end
|
@@ -41,6 +60,8 @@ module JBundler
|
|
41
60
|
class AetherRuby
|
42
61
|
|
43
62
|
def self.setup_classloader
|
63
|
+
require 'java'
|
64
|
+
|
44
65
|
maven_home = File.dirname(File.dirname(Gem.bin_path('ruby-maven',
|
45
66
|
'rmvn')))
|
46
67
|
# TODO reduce to the libs which are really needed
|
@@ -81,11 +102,15 @@ module JBundler
|
|
81
102
|
end
|
82
103
|
|
83
104
|
def resolve
|
84
|
-
@aether.resolve
|
105
|
+
@aether.resolve unless artifacts.empty?
|
85
106
|
end
|
86
107
|
|
87
|
-
def classpath
|
88
|
-
|
108
|
+
def classpath
|
109
|
+
if artifacts.empty?
|
110
|
+
''
|
111
|
+
else
|
112
|
+
@aether.classpath
|
113
|
+
end
|
89
114
|
end
|
90
115
|
|
91
116
|
def repositories
|
@@ -97,7 +122,11 @@ module JBundler
|
|
97
122
|
end
|
98
123
|
|
99
124
|
def resolved_coordinates
|
100
|
-
|
125
|
+
if artifacts.empty?
|
126
|
+
[]
|
127
|
+
else
|
128
|
+
@aether.resolved_coordinates
|
129
|
+
end
|
101
130
|
end
|
102
131
|
|
103
132
|
def install(coordinate, file)
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'java'
|
2
|
+
module JBundler
|
3
|
+
|
4
|
+
class AetherRuby
|
5
|
+
|
6
|
+
def self.setup_classloader
|
7
|
+
unless defined? Aether
|
8
|
+
@maven_home = File.dirname(File.dirname(Gem.bin_path('ruby-maven',
|
9
|
+
'rmvn')))
|
10
|
+
# TODO reduce to the libs which are really needed
|
11
|
+
Dir.glob(File.join(@maven_home, 'lib', "*jar")).each {|path| require path }
|
12
|
+
require 'jbundler.jar'
|
13
|
+
java_import 'jbundler.Aether'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(local_repo = File.join( ENV['HOME'],
|
18
|
+
".m2",
|
19
|
+
"repository"),
|
20
|
+
verbose = false)
|
21
|
+
self.class.setup_classloader
|
22
|
+
@aether = AetherRuby.new(local_repo, verbose)
|
23
|
+
end
|
24
|
+
|
25
|
+
def add_artifact(coordinate, extension = nil)
|
26
|
+
if extension
|
27
|
+
coord = coordinate.split(/:/)
|
28
|
+
coord.insert(2, extension)
|
29
|
+
@aether.add_artifact(coordinate.join(":"))
|
30
|
+
else
|
31
|
+
@aether.add_artifact(coordinate)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def add_repository(url, name = "repo_#{repos.size}")
|
36
|
+
@aether.add_repository(name, url)
|
37
|
+
end
|
38
|
+
|
39
|
+
def install(coordinate)
|
40
|
+
@aether.install(coordinate)
|
41
|
+
end
|
42
|
+
|
43
|
+
def resolve
|
44
|
+
@aether.resolve
|
45
|
+
end
|
46
|
+
|
47
|
+
def classpath
|
48
|
+
@aether.classpath
|
49
|
+
end
|
50
|
+
|
51
|
+
def dependency_map
|
52
|
+
@aether.dependency_map
|
53
|
+
end
|
54
|
+
|
55
|
+
def repositories
|
56
|
+
@aether.repositories
|
57
|
+
end
|
58
|
+
|
59
|
+
def dependency_coordinates
|
60
|
+
@aether.dependency_coordinates
|
61
|
+
end
|
62
|
+
|
63
|
+
def install(coordinate, file)
|
64
|
+
@aether.install(coordinate, file)
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|