lock_jar 0.0.3 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -5,7 +5,7 @@ gem "naether", "~> 0.6.0"
5
5
  # Add dependencies to develop your gem here.
6
6
  # Include everything needed to run rake, tests, features, etc.
7
7
  group :development do
8
- gem "rspec", ">= 0"
8
+ gem "rspec", "~> 2.9.0"
9
9
  gem "bundler", "> 1.0.0"
10
10
  gem "jeweler", "~> 1.6.4"
11
11
  end
data/README.rdoc CHANGED
@@ -1,8 +1,9 @@
1
1
  = LockJar
2
2
 
3
- LockJar manages Java Jars for Ruby. A Jarfile ({example}[https://github.com/mguymon/lock_jar/blob/master/spec/Jarfile])
4
- is used to generate a Jarfile.lock that contains all the resolved jar dependencies for scopes runtime, compile, and test. The Jarfile.lock can be used to populate
5
- the classpath.
3
+ LockJar manages Java Jars for Ruby. Powered by {Naether}[https://github.com/mguymon/naether] to create a frankenstein of
4
+ Bundler and Maven. A Jarfile ({example}[https://github.com/mguymon/lock_jar/blob/master/spec/Jarfile]) is used to
5
+ generate a Jarfile.lock that contains all the resolved jar dependencies for scopes runtime, compile, and test.
6
+ The Jarfile.lock can be used to populate the classpath.
6
7
 
7
8
  https://github.com/mguymon/lock_jar
8
9
 
@@ -18,9 +19,10 @@ gem install lock_jar
18
19
  A Jarfile is a simple file using a Ruby DSL for defining a project's Jar dependencies using the following
19
20
  methods:
20
21
 
21
- * repository: url of additional Maven repository to use.
22
- * jar: artifact notation of Jar dependency
23
- * pom: local path to a Maven pom
22
+ * local: Set the local Maven repository
23
+ * repository: Add url of additional Maven repository to use.
24
+ * jar: Add Jar dependency in artifact notation
25
+ * pom: Add local path to a Maven pom
24
26
  * scope: set the scope for a jar or pom declaration. Default scope is compile
25
27
 
26
28
  Example Jarfile
@@ -43,10 +45,8 @@ Example Jarfile
43
45
 
44
46
  When the Jarfile is locked, the transitive dependencies for the Jars and Pom are resolved and saved to the Jarfile.lock file.
45
47
 
46
- Example of locking
48
+ Example of locking a Jarfile to a Jarfile.lock
47
49
 
48
- require 'lock_jar'
49
-
50
50
  LockJar.lock
51
51
 
52
52
 
@@ -58,6 +58,8 @@ the additional Maven repositories.
58
58
  The Jarfile.lock
59
59
 
60
60
  ---
61
+ repositories:
62
+ - http://repository.jboss.org/nexus/content/groups/public-jboss
61
63
  scopes:
62
64
  compile:
63
65
  dependencies:
@@ -85,26 +87,56 @@ The Jarfile.lock
85
87
  resolved_dependencies:
86
88
  - junit:junit:jar:4.10
87
89
  - org.hamcrest:hamcrest-core:jar:1.1
88
- repositories:
89
- - http://repository.jboss.org/nexus/content/groups/public-jboss
90
90
 
91
91
 
92
92
  ==== Accessing Jars
93
93
 
94
94
  Once a Jarfile.lock is generated, you can list all resolved jars by
95
-
96
- require 'lock_jars'
97
95
 
98
96
  jars = LockJar.list
99
97
 
100
98
  or directly load all Jars into the classpath
101
-
102
- require 'lock_jars'
103
99
 
104
100
  jars = LockJar.load
105
101
 
106
102
  Do not forget, if you change your Jarfile, you have to re-generate the Jarfile.lock.
107
103
 
104
+ === Skipping the Jarfile
105
+
106
+ You can skip the Jarfile and directly load dependencies by passing a block to LockJar.load
107
+
108
+ LockJar.load do
109
+ jar 'org.eclipse.jetty:example-jetty-embedded:jar:8.1.2.v20120308'
110
+ end
111
+
112
+ === Bundler Integration
113
+
114
+ LockJar integrates with {Bundler}[https://github.com/carlhuda/bundler/] by {modifying}[https://github.com/mguymon/lock_jar/blob/master/lib/lock_jar/bundler.rb] the Bundler
115
+ DSL to include LockJar's DSL, generating a Jarfile.lock when Bundler locks, and populating the classpath
116
+ when Bundler requires.
117
+
118
+ ==== Example
119
+
120
+ The following Gemfile with LockJar
121
+
122
+ require 'lock_jar/bundler'
123
+
124
+ gem "naether"
125
+
126
+ # lockjar dsl that is used to generate Jarfile.lock
127
+ lock_jar do
128
+ scope :test do
129
+ jar 'junit:junit:jar:4.10'
130
+ end
131
+
132
+ pom 'spec/pom.xml', :scope => :compile
133
+ end
134
+
135
+ Will produce a Gemfile.lock and Jarfile.lock for
136
+
137
+ bundle install
138
+
139
+ When Bundle.setup or Bundle.require is called, the jars from the Jarfile.lock are loaded into the classpath.
108
140
 
109
141
  === Buildr Integration
110
142
 
@@ -161,9 +193,6 @@ Generated the following lock files using lock_jar:lock
161
193
  * project1.lock - contains junit and mina jars.
162
194
  * project2.lock - contains junit and pom.xml jars.
163
195
 
164
- === About
165
-
166
- Power by {Naether}[https://github.com/mguymon/naether] to create a frankenstein of Bundler and Maven.
167
196
 
168
197
  == License
169
198
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.3
1
+ 0.1.0
@@ -0,0 +1,98 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with this
3
+ # work for additional information regarding copyright ownership. The ASF
4
+ # licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations under
14
+ # the License.
15
+
16
+ require 'rubygems'
17
+ require 'bundler/dsl'
18
+ require 'lock_jar'
19
+ require 'lock_jar/dsl'
20
+
21
+ module Bundler
22
+ class Dsl
23
+ def lock_jar(&blk)
24
+ @lock_jar_blk = blk
25
+ end
26
+
27
+ def to_definition(lockfile, unlock)
28
+ @sources << @rubygems_source unless @sources.include?(@rubygems_source)
29
+ definition = LockJarDefinition.new(lockfile, @dependencies, @sources, unlock)
30
+
31
+ if @lock_jar_blk
32
+ definition.lock_jar = LockJar::Dsl.evaluate( nil, &@lock_jar_blk )
33
+ end
34
+
35
+ definition
36
+ end
37
+ end
38
+
39
+ class Environment
40
+ def lock_jar
41
+ @definition.lock_jar
42
+ end
43
+ end
44
+
45
+ class LockJarDefinition < Bundler::Definition
46
+ alias :lockjar_replaced_lock :lock
47
+ attr_accessor :lock_jar
48
+
49
+ def lock( file )
50
+ LockJar.lock( lock_jar )
51
+
52
+ lockjar_replaced_lock( file )
53
+ end
54
+ end
55
+
56
+ class Runtime
57
+ alias :lockjar_replaced_setup :setup
58
+ alias :lockjar_replaced_require :require
59
+
60
+ def setup(*groups)
61
+ scopes = []
62
+ if groups && groups.size == 0
63
+ scopes = ["compile","runtime"]
64
+ else
65
+ groups.each do |group|
66
+ if "development" == group.to_s
67
+ scopes << "compile"
68
+ elsif "default" == group.to_s
69
+ scopes << "compile" << "runtime"
70
+ end
71
+ end
72
+ end
73
+
74
+ LockJar.load( scopes.uniq )
75
+
76
+ lockjar_replaced_setup( *groups )
77
+ end
78
+
79
+ def require(*groups)
80
+ scopes = []
81
+
82
+ if groups && groups.size == 0
83
+ scopes = ["compile","runtime"]
84
+ else
85
+ groups.each do |group|
86
+ if "development" == group.to_s
87
+ scopes << "compile"
88
+ elsif "default" == group.to_s
89
+ scopes << "compile" << "runtime"
90
+ end
91
+ end
92
+ end
93
+ LockJar.load( scopes.uniq )
94
+
95
+ lockjar_replaced_require( *groups )
96
+ end
97
+ end
98
+ end
data/lib/lock_jar/dsl.rb CHANGED
@@ -18,6 +18,7 @@ module LockJar
18
18
 
19
19
  attr_reader :notations
20
20
  attr_reader :repositories
21
+ attr_reader :local_repository
21
22
  attr_reader :scopes
22
23
 
23
24
  class << self
@@ -58,23 +59,37 @@ module LockJar
58
59
  end
59
60
 
60
61
  @present_scope = 'compile'
62
+
63
+ @local_repository = nil
64
+ end
65
+
66
+ def local( path )
67
+ @local_repository = path
61
68
  end
62
69
 
63
70
  def jar(notation, *args)
64
- if notation
65
- @notations[@present_scope] << notation
71
+ opts = {}
72
+ if args.last.is_a? Hash
73
+ opts.merge!( args.last )
66
74
  end
75
+
76
+ artifact( notation, opts )
67
77
  end
68
78
 
69
79
  # Pom default to all scopes, unless nested in a scope
70
80
  def pom(path, *args)
71
- if @scope_changed
72
- @notations[@present_scope] << path
73
- else
74
- LockJar::Dsl.scopes.each do |scope|
75
- @notations[scope] << path
76
- end
81
+ opts = { }
82
+
83
+ if args.last.is_a? Hash
84
+ opts.merge!( args.last )
85
+ end
86
+
87
+ # if not scope opts and default scope, set to all
88
+ unless opts[:scope] || opts[:scopes] || @scope_changed
89
+ opts[:scope] = Dsl.scopes
77
90
  end
91
+
92
+ artifact( path, opts )
78
93
  end
79
94
 
80
95
  def repository( url, opts = {} )
@@ -104,5 +119,37 @@ module LockJar
104
119
 
105
120
  self
106
121
  end
122
+
123
+ private
124
+ def artifact(artifact, opts)
125
+
126
+ scopes = opts[:scope] || opts[:scopes] || opts[:group]
127
+ if scopes
128
+
129
+ unless scopes.is_a? Array
130
+ scopes = [scopes]
131
+ end
132
+
133
+ # include present scope if within a scope block
134
+ if @scope_changed
135
+ scopes << @present_scope
136
+ end
137
+
138
+ else
139
+ scopes = [@present_scope]
140
+ end
141
+
142
+ if artifact
143
+ scopes.each do |scope|
144
+ scope = 'compile' if scope.to_s == 'development'
145
+
146
+ if @notations[scope.to_s]
147
+ @notations[scope.to_s] << artifact
148
+ end
149
+ end
150
+ end
151
+
152
+ end
153
+
107
154
  end
108
155
  end
@@ -1,27 +1,39 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with this
3
+ # work for additional information regarding copyright ownership. The ASF
4
+ # licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations under
14
+ # the License.
1
15
 
16
+ require 'lock_jar/runtime'
2
17
 
3
18
  module LockJar
4
19
  class Maven
5
20
 
6
21
  class << self
7
- def runtime( opts = {} )
8
- Runtime.new( opts )
9
- end
10
22
 
11
23
  def pom_version( pom_path, opts = {} )
12
- runtime(opts).resolver.naether.pom_version( pom_path )
24
+ Runtime.instance.resolver(opts).naether.pom_version( pom_path )
13
25
  end
14
26
 
15
27
  def write_pom( notation, file_path, opts = {} )
16
- runtime(opts).resolver.naether.write_pom( notation, file_path )
28
+ Runtime.instance.resolver(opts).naether.write_pom( notation, file_path )
17
29
  end
18
30
 
19
31
  def deploy_artifact( notation, file_path, url, deploy_opts = {}, lockjar_opts = {} )
20
- runtime(lockjar_opts).resolver.naether.deploy_artifact( notation, file_path, url, deploy_opts )
32
+ Runtime.instance.resolver(lockjar_opts).naether.deploy_artifact( notation, file_path, url, deploy_opts )
21
33
  end
22
34
 
23
35
  def install( notation, pom_path, jar_path, opts = {} )
24
- runtime(opts).resolver.naether.install( notation, pom_path, jar_path )
36
+ Runtime.instance.resolver(opts).naether.install( notation, pom_path, jar_path )
25
37
  end
26
38
  end
27
39
  end
@@ -20,9 +20,11 @@ require 'tmpdir'
20
20
  module LockJar
21
21
  class Resolver
22
22
 
23
+ attr_reader :opts
23
24
  attr_reader :naether
24
25
 
25
26
  def initialize( opts = {} )
27
+ @opts = opts
26
28
  local_repo = opts[:local_repo]
27
29
 
28
30
  # Bootstrap Naether
@@ -13,22 +13,28 @@
13
13
  # License for the specific language governing permissions and limitations under
14
14
  # the License.
15
15
 
16
- require "yaml"
17
16
  require 'rubygems'
17
+ require "yaml"
18
+ require 'singleton'
18
19
  require 'lock_jar/resolver'
19
20
  require 'lock_jar/dsl'
20
21
  require 'lock_jar/runtime'
21
22
 
22
23
  module LockJar
23
24
  class Runtime
25
+ include Singleton
24
26
 
25
- attr_reader :resolver
27
+ attr_reader :current_resolver
26
28
 
27
- def initialize( opts = {} )
28
- @resolver = LockJar::Resolver.new( opts )
29
+ def resolver( opts = {} )
30
+ if @current_resolver.nil? || opts != @current_resolver.opts
31
+ @current_resolver = LockJar::Resolver.new( opts )
32
+ end
33
+
34
+ @current_resolver
29
35
  end
30
36
 
31
- def lock( jarfile = "Jarfile", opts = {} )
37
+ def lock( jarfile, opts = {} )
32
38
  lock_jar_file = nil
33
39
 
34
40
  if jarfile.is_a? LockJar::Dsl
@@ -37,16 +43,27 @@ module LockJar
37
43
  lock_jar_file = LockJar::Dsl.evaluate( jarfile )
38
44
  end
39
45
 
46
+ # If not set in opts, and is set in dsl
47
+ if opts[:local_repo].nil? && lock_jar_file.local_repository
48
+ opts[:local_repo] = lock_jar_file.local_repository
49
+ end
50
+
40
51
  lock_jar_file.repositories.each do |repo|
41
- @resolver.add_remote_repository( repo )
52
+ resolver(opts).add_remote_repository( repo )
42
53
  end
43
-
44
- lock_data = { 'scopes' => {} }
45
-
54
+
55
+ lock_data = { }
56
+
57
+ unless lock_jar_file.local_repository.nil?
58
+ lock_data['local_repository'] = lock_jar_file.local_repository
59
+ end
60
+
46
61
  if lock_jar_file.repositories.size > 0
47
62
  lock_data['repositories'] = lock_jar_file.repositories
48
63
  end
49
64
 
65
+ lock_data['scopes'] = {}
66
+
50
67
  lock_jar_file.notations.each do |scope, notations|
51
68
 
52
69
  dependencies = []
@@ -54,10 +71,12 @@ module LockJar
54
71
  dependencies << {notation => scope}
55
72
  end
56
73
 
57
- resolved_notations = @resolver.resolve( dependencies )
58
- lock_data['scopes'][scope] = {
59
- 'dependencies' => notations,
60
- 'resolved_dependencies' => resolved_notations }
74
+ if dependencies.size > 0
75
+ resolved_notations = resolver(opts).resolve( dependencies )
76
+ lock_data['scopes'][scope] = {
77
+ 'dependencies' => notations,
78
+ 'resolved_dependencies' => resolved_notations }
79
+ end
61
80
  end
62
81
 
63
82
  File.open( opts[:lockfile] || "Jarfile.lock", "w") do |f|
@@ -65,57 +84,65 @@ module LockJar
65
84
  end
66
85
  end
67
86
 
68
- def list( jarfile_lock = "Jarfile.lock", scopes = ['compile', 'runtime'] )
69
- lock_data = YAML.load_file( jarfile_lock )
70
-
87
+ def list( jarfile_lock, scopes = ['compile', 'runtime'], opts = {}, &blk )
71
88
  dependencies = []
72
-
73
- scopes.each do |scope|
74
- if lock_data['scopes'][scope]
75
- dependencies += lock_data['scopes'][scope]['resolved_dependencies']
76
- end
89
+
90
+ if jarfile_lock
91
+ dependencies += lockfile_dependencies( read_lockfile( jarfile_lock), scopes )
77
92
  end
78
93
 
79
- dependencies
94
+ unless blk.nil?
95
+ dsl = LockJar::Dsl.evaluate(&blk)
96
+ dependencies += dsl_dependencies( dsl, scopes )
97
+ end
98
+
99
+ dependencies.uniq
80
100
  end
81
101
 
82
- def load( jarfile_lock = "Jarfile.lock", scopes = ['compile', 'runtime'], &blk )
83
- dependencies = []
84
-
102
+ def load( jarfile_lock, scopes = ['compile', 'runtime'], opts = {}, &blk )
85
103
  if jarfile_lock
86
- if File.exists?(jarfile_lock)
87
- dependencies += read_jarfile( jarfile_lock, scopes )
88
- else
89
- warn( "LockJar jarfile_lock not found: #{jarfile_lock}" )
104
+ lockfile = read_lockfile( jarfile_lock )
105
+
106
+ if opts[:local_repo].nil? && lockfile['local_repo']
107
+ opts[:local_repo] = lockfile['local_repo']
90
108
  end
91
109
  end
92
-
93
- if blk
110
+
111
+ unless blk.nil?
94
112
  dsl = LockJar::Dsl.evaluate(&blk)
95
- dependencies += read_dsl( dsl, scopes )
113
+
114
+ if opts[:local_repo].nil? && dsl.local_repository
115
+ opts[:local_repo] = dsl.local_repository
116
+ end
96
117
  end
97
118
 
98
- dependencies.uniq!
119
+ dependencies = list( jarfile_lock, scopes, &blk )
120
+
121
+ if opts[:resolve]
122
+ dependencies = resolver(opts).resolve( dependencies )
123
+ end
99
124
 
100
- @resolver.load_jars_to_classpath( dependencies )
125
+ resolver(opts).load_jars_to_classpath( dependencies )
101
126
  end
102
127
 
103
128
  private
104
- def read_jarfile( jarfile_lock, scopes )
105
- lock_data = YAML.load_file( jarfile_lock )
106
-
129
+ def read_lockfile( jarfile_lock )
130
+ YAML.load_file( jarfile_lock )
131
+ end
132
+
133
+ def lockfile_dependencies( lockfile, scopes)
107
134
  dependencies = []
108
135
 
109
136
  scopes.each do |scope|
110
- if lock_data['scopes'][scope]
111
- dependencies += lock_data['scopes'][scope]['resolved_dependencies']
137
+ if lockfile['scopes'][scope]
138
+ dependencies += lockfile['scopes'][scope]['resolved_dependencies']
112
139
  end
113
140
  end
114
141
 
115
142
  dependencies
116
143
  end
117
144
 
118
- def read_dsl( dsl, scopes )
145
+ def dsl_dependencies( dsl, scopes )
119
146
 
120
147
  dependencies = []
121
148
 
@@ -125,7 +152,7 @@ module LockJar
125
152
  end
126
153
  end
127
154
 
128
- @resolver.resolve( dependencies )
155
+ dependencies
129
156
  end
130
157
  end
131
158
  end
data/lib/lock_jar.rb CHANGED
@@ -25,21 +25,60 @@ module LockJar
25
25
  #
26
26
  # Accepts path to the jarfile and hash of options to configure LockJar
27
27
  def self.lock( jarfile = 'Jarfile', opts = {} )
28
- Runtime.new( opts ).lock( jarfile, opts )
28
+ Runtime.instance.lock( jarfile, opts )
29
29
  end
30
30
 
31
31
  # List jars for an array of scope in a lockfile
32
32
  #
33
33
  # Accepts path to the lockfile, array of scopes, and hash of options to configure LockJar
34
- def self.list( lockfile = 'Jarfile.lock', scopes = ['compile', 'runtime'], opts = {}, &blk )
35
- Runtime.new( opts ).list( lockfile, scopes )
34
+ def self.list( *args, &blk )
35
+ lockfile = nil
36
+ opts = {}
37
+ scopes = ['compile', 'runtime']
38
+
39
+ args.each do |arg|
40
+ if arg.is_a?(Hash)
41
+ opts.merge!( arg )
42
+ elsif arg.is_a?( String )
43
+ lockfile = arg
44
+ elsif arg.is_a?( Array )
45
+ scopes = arg
46
+ end
47
+ end
48
+
49
+ # default to Jarfile.lock
50
+ if blk.nil? && lockfile.nil?
51
+ lockfile = 'Jarfile.lock'
52
+ end
53
+
54
+ Runtime.instance.list( lockfile, scopes, opts, &blk )
36
55
  end
37
56
 
38
- # Load jars for an array of scopes in a lockfile
57
+ # Load jars for an array of scopes in a lockfile. Defaults lockfile to Jarfile.lock
39
58
  #
40
- # Accepts a path to the lockfile, array scopes, and hash of optiosn to configure LockJar
41
- def self.load( lockfile = 'Jarfile.lock', scopes = ['compile', 'runtime'], opts = {}, &blk )
42
- Runtime.new( opts ).load( lockfile, scopes, &blk )
59
+ # Accepts a path to the lockfile, array scopes, and hash of options to configure LockJar. A
60
+ # block of LockJar::Dsl can be set.
61
+ def self.load( *args, &blk )
62
+ lockfile = nil
63
+ opts = {}
64
+ scopes = ['compile', 'runtime']
65
+
66
+ args.each do |arg|
67
+ if arg.is_a?(Hash)
68
+ opts.merge!( arg )
69
+ elsif arg.is_a?( String )
70
+ lockfile = arg
71
+ elsif arg.is_a?( Array )
72
+ scopes = arg
73
+ end
74
+ end
75
+
76
+ # default to Jarfile.lock
77
+ if blk.nil? && lockfile.nil?
78
+ lockfile = 'Jarfile.lock'
79
+ end
80
+
81
+ Runtime.instance.load( lockfile, scopes, opts, &blk )
43
82
  end
44
83
 
45
84
  end
data/lock_jar.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "lock_jar"
8
- s.version = "0.0.3"
8
+ s.version = "0.1.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Michael Guymon"]
12
- s.date = "2012-04-16"
12
+ s.date = "2012-04-19"
13
13
  s.description = "Manage Jar files for Ruby. In the spirit of Bundler, a Jarfile\n is used to generate a Jarfile.lock that contains all the resolved jar dependencies for scopes runtime, compile, and test.\n The Jarfile.lock can be used to populate the classpath"
14
14
  s.email = "michael.guymon@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -24,17 +24,23 @@ Gem::Specification.new do |s|
24
24
  "VERSION",
25
25
  "lib/lock_jar.rb",
26
26
  "lib/lock_jar/buildr.rb",
27
+ "lib/lock_jar/bundler.rb",
27
28
  "lib/lock_jar/dsl.rb",
28
29
  "lib/lock_jar/maven.rb",
29
30
  "lib/lock_jar/resolver.rb",
30
31
  "lib/lock_jar/runtime.rb",
31
32
  "lock_jar.gemspec",
33
+ "spec/BundlerJarfile.lock",
32
34
  "spec/Jarfile",
35
+ "spec/helper/bundler_helper.rb",
36
+ "spec/lock_jar/bundler_spec.rb",
33
37
  "spec/lock_jar/dsl_spec.rb",
34
38
  "spec/lock_jar/maven_spec.rb",
35
39
  "spec/lock_jar/resolver_spec.rb",
40
+ "spec/lock_jar/runtime_spec.rb",
36
41
  "spec/lock_jar_spec.rb",
37
- "spec/pom.xml"
42
+ "spec/pom.xml",
43
+ "spec/spec_helper.rb"
38
44
  ]
39
45
  s.homepage = "http://github.com/mguymon/lock_jar"
40
46
  s.licenses = ["Apache"]
@@ -47,18 +53,18 @@ Gem::Specification.new do |s|
47
53
 
48
54
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
49
55
  s.add_runtime_dependency(%q<naether>, ["~> 0.6.0"])
50
- s.add_development_dependency(%q<rspec>, [">= 0"])
56
+ s.add_development_dependency(%q<rspec>, ["~> 2.9.0"])
51
57
  s.add_development_dependency(%q<bundler>, ["> 1.0.0"])
52
58
  s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
53
59
  else
54
60
  s.add_dependency(%q<naether>, ["~> 0.6.0"])
55
- s.add_dependency(%q<rspec>, [">= 0"])
61
+ s.add_dependency(%q<rspec>, ["~> 2.9.0"])
56
62
  s.add_dependency(%q<bundler>, ["> 1.0.0"])
57
63
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
58
64
  end
59
65
  else
60
66
  s.add_dependency(%q<naether>, ["~> 0.6.0"])
61
- s.add_dependency(%q<rspec>, [">= 0"])
67
+ s.add_dependency(%q<rspec>, ["~> 2.9.0"])
62
68
  s.add_dependency(%q<bundler>, ["> 1.0.0"])
63
69
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
64
70
  end
@@ -0,0 +1,22 @@
1
+ ---
2
+ scopes:
3
+ compile:
4
+ dependencies:
5
+ - /home/zinger/devel/projects/swx/lock_jar/spec/pom.xml
6
+ resolved_dependencies:
7
+ - com.slackworks:modelcitizen:jar:0.2.2
8
+ - commons-lang:commons-lang:jar:2.6
9
+ - commons-beanutils:commons-beanutils:jar:1.8.3
10
+ - commons-logging:commons-logging:jar:1.1.1
11
+ - ch.qos.logback:logback-classic:jar:0.9.24
12
+ - ch.qos.logback:logback-core:jar:0.9.24
13
+ - org.slf4j:slf4j-api:jar:1.6.1
14
+ - com.metapossum:metapossum-scanner:jar:1.0
15
+ - commons-io:commons-io:jar:1.4
16
+ - junit:junit:jar:4.7
17
+ test:
18
+ dependencies:
19
+ - junit:junit:jar:4.10
20
+ resolved_dependencies:
21
+ - junit:junit:jar:4.10
22
+ - org.hamcrest:hamcrest-core:jar:1.1
data/spec/Jarfile CHANGED
@@ -1,3 +1,4 @@
1
+ local '~/.m2'
1
2
  repository 'http://repository.jboss.org/nexus/content/groups/public-jboss'
2
3
 
3
4
  jar "org.apache.mina:mina-core:2.0.4"
@@ -0,0 +1,156 @@
1
+ # Require the correct version of popen for the current platform
2
+ if RbConfig::CONFIG['host_os'] =~ /mingw|mswin/
3
+ begin
4
+ require 'win32/open3'
5
+ rescue LoadError
6
+ abort "Run `gem install win32-open3` to be able to run specs"
7
+ end
8
+ else
9
+ require 'open3'
10
+ end
11
+
12
+
13
+ module BundlerHelper
14
+
15
+ # Taken from Bundler spec supprt
16
+ # https://github.com/carlhuda/bundler/tree/master/spec/support
17
+
18
+ attr_reader :out, :err, :exitstatus
19
+
20
+ def gemfile(*args)
21
+ path = bundled_app("Gemfile")
22
+ path = args.shift if Pathname === args.first
23
+ str = args.shift || ""
24
+ path.dirname.mkpath
25
+ File.open(path.to_s, 'w') do |f|
26
+ f.puts str
27
+ end
28
+ end
29
+
30
+ def lockfile(*args)
31
+ path = bundled_app("Gemfile.lock")
32
+ path = args.shift if Pathname === args.first
33
+ str = args.shift || ""
34
+
35
+ # Trim the leading spaces
36
+ spaces = str[/\A\s+/, 0] || ""
37
+ str.gsub!(/^#{spaces}/, '')
38
+
39
+ File.open(path.to_s, 'w') do |f|
40
+ f.puts str
41
+ end
42
+ end
43
+
44
+ def install_gemfile(*args)
45
+ gemfile(*args)
46
+ opts = args.last.is_a?(Hash) ? args.last : {}
47
+ bundle :install, opts
48
+ end
49
+
50
+ def bundle(cmd, options = {})
51
+ expect_err = options.delete(:expect_err)
52
+ exitstatus = options.delete(:exitstatus)
53
+ options["no-color"] = true unless options.key?("no-color") || %w(exec conf).include?(cmd.to_s[0..3])
54
+
55
+ #bundle_bin = File.expand_path('../../../bin/bundle', __FILE__)
56
+ bundle_bin = `which bundle`.strip
57
+
58
+ requires = options.delete(:requires) || []
59
+ requires << File.expand_path('../fakeweb/'+options.delete(:fakeweb)+'.rb', __FILE__) if options.key?(:fakeweb)
60
+ requires << File.expand_path('../artifice/'+options.delete(:artifice)+'.rb', __FILE__) if options.key?(:artifice)
61
+ requires_str = requires.map{|r| "-r#{r}"}.join(" ")
62
+
63
+ env = (options.delete(:env) || {}).map{|k,v| "#{k}='#{v}' "}.join
64
+ args = options.map do |k,v|
65
+ v == true ? " --#{k}" : " --#{k} #{v}" if v
66
+ end.join
67
+
68
+ cmd = "#{env}#{Gem.ruby} -I#{lib} #{requires_str} #{bundle_bin} #{cmd}#{args}"
69
+
70
+ #puts cmd
71
+
72
+ if exitstatus
73
+ sys_status(cmd)
74
+ else
75
+ sys_exec(cmd, expect_err){|i| yield i if block_given? }
76
+ end
77
+ end
78
+
79
+ def root
80
+ @root ||= Pathname.new(File.expand_path("../../..", __FILE__))
81
+ end
82
+
83
+ def bundled_app(*path)
84
+ root = tmp.join("bundled_app")
85
+ FileUtils.mkdir_p(root)
86
+ root.join(*path)
87
+ end
88
+
89
+ def tmp(*path)
90
+ root.join("tmp", *path)
91
+ end
92
+
93
+ def in_app_root(&blk)
94
+ Dir.chdir(bundled_app, &blk)
95
+ end
96
+
97
+ def lib
98
+ File.expand_path('../../../lib', __FILE__)
99
+ end
100
+
101
+ def sys_exec(cmd, expect_err = false)
102
+ Open3.popen3(cmd.to_s) do |stdin, stdout, stderr|
103
+ @in_p, @out_p, @err_p = stdin, stdout, stderr
104
+
105
+ yield @in_p if block_given?
106
+ @in_p.close
107
+
108
+ @out = @out_p.read_available_bytes.strip
109
+ @err = @err_p.read_available_bytes.strip
110
+ end
111
+
112
+ #puts @out
113
+ puts @err unless expect_err || @err.empty? || !$show_err
114
+ @out
115
+ end
116
+
117
+ def ruby(ruby, options = {})
118
+ expect_err = options.delete(:expect_err)
119
+ env = (options.delete(:env) || {}).map{|k,v| "#{k}='#{v}' "}.join
120
+ ruby.gsub!(/["`\$]/) {|m| "\\#{m}" }
121
+ lib_option = options[:no_lib] ? "" : " -I#{lib}"
122
+
123
+ #puts %{#{env}#{Gem.ruby}#{lib_option} -e "#{ruby}"}
124
+
125
+ sys_exec(%{#{env}#{Gem.ruby}#{lib_option} -e "#{ruby}"}, expect_err)
126
+ end
127
+
128
+ RSpec::Matchers.define :have_dep do |*args|
129
+ dep = Bundler::Dependency.new(*args)
130
+
131
+ match do |actual|
132
+ actual.length == 1 && actual.all? { |d| d == dep }
133
+ end
134
+ end
135
+ end
136
+
137
+ class IO
138
+ def read_available_bytes(chunk_size = 16384, select_timeout = 0.02)
139
+ buffer = []
140
+
141
+ return "" if closed? || eof?
142
+ # IO.select cannot be used here due to the fact that it
143
+ # just does not work on windows
144
+ while true
145
+ begin
146
+ IO.select([self], nil, nil, select_timeout)
147
+ break if eof? # stop raising :-(
148
+ buffer << self.readpartial(chunk_size)
149
+ rescue(EOFError)
150
+ break
151
+ end
152
+ end
153
+
154
+ return buffer.join
155
+ end
156
+ end
@@ -0,0 +1,82 @@
1
+ require 'spec_helper'
2
+ require 'rubygems'
3
+ require 'bundler'
4
+ require 'lib/lock_jar/bundler'
5
+ require 'helper/bundler_helper'
6
+
7
+ describe Bundler do
8
+ include BundlerHelper
9
+
10
+ before(:each) do
11
+ gemfile <<-G
12
+ require 'lock_jar/bundler'
13
+ source "file://#{tmp('bundler')}"
14
+ gem "naether"
15
+
16
+ lock_jar do
17
+ scope :test do
18
+ jar 'junit:junit:jar:4.10'
19
+ end
20
+
21
+ pom "#{File.join(root, 'spec', 'pom.xml')}", :scope => :development
22
+ end
23
+ G
24
+ in_app_root
25
+ end
26
+
27
+ after(:each) do
28
+ Dir.chdir(root)
29
+ end
30
+
31
+ it "provides a list of the env dependencies" do
32
+ Bundler.load.dependencies.should have_dep("naether", ">= 0")
33
+ end
34
+
35
+ it "provides a list of the jar and pom dependencies" do
36
+ Bundler.load.lock_jar.notations.should eql( {"compile"=>["/home/zinger/devel/projects/swx/lock_jar/spec/pom.xml"], "runtime"=>[], "test"=>["junit:junit:jar:4.10"]} )
37
+ end
38
+
39
+ it "should create Jarfile.lock with bundle install" do
40
+ File.delete( bundled_app("Jarfile.lock") ) if File.exists? bundled_app("Jarfile.lock")
41
+ install_gemfile <<-G
42
+ require 'lock_jar/bundler'
43
+ source "file://#{tmp('bundler')}"
44
+ gem "naether"
45
+
46
+ lock_jar do
47
+ scope :test do
48
+ jar 'junit:junit:jar:4.10'
49
+ end
50
+
51
+ pom "#{File.join(root, 'spec', 'pom.xml')}", :scope => :development
52
+ end
53
+
54
+ G
55
+
56
+ File.exists?( bundled_app("Jarfile.lock") ).should be_true
57
+
58
+ IO.read( File.join(root,'spec', 'BundlerJarfile.lock') ).should eql( IO.read( bundled_app("Jarfile.lock") ) )
59
+ end
60
+
61
+ it "should create Jarfile.lock with bundle update" do
62
+ File.delete( bundled_app("Jarfile.lock") ) if File.exists? bundled_app("Jarfile.lock")
63
+ bundle "update"
64
+ File.exists?( bundled_app("Jarfile.lock") ).should be_true
65
+
66
+ IO.read( File.join(root,'spec', 'BundlerJarfile.lock') ).should eql( IO.read( bundled_app("Jarfile.lock") ) )
67
+ end
68
+
69
+ it "should load Jarfile.lock with Bundle.setup" do
70
+ ruby <<-RUBY
71
+ require 'rubygems'
72
+ require 'bundler'
73
+ require 'lock_jar/bundler'
74
+ Bundler.setup
75
+
76
+ puts com.slackworks.modelcitizen.ModelFactory.to_s
77
+ RUBY
78
+ err.should eq("")
79
+ out.should match("Java::ComSlackworksModelcitizen::ModelFactory")
80
+ end
81
+
82
+ end
@@ -1,17 +1,18 @@
1
- require 'rubygems'
2
- require 'lib/lock_jar/dsl'
1
+ require 'spec_helper'
3
2
 
4
3
  describe LockJar::Dsl do
5
4
  context "Instance" do
6
5
  it "should load a Jarfile" do
7
6
  jarfile = LockJar::Dsl.evaluate( "spec/Jarfile" )
8
7
 
8
+ jarfile.local_repository.should eql '~/.m2'
9
9
  jarfile.notations.should eql( {"compile"=>["org.apache.mina:mina-core:2.0.4", "spec/pom.xml"], "runtime"=>["spec/pom.xml", "org.apache.tomcat:servlet-api:jar:6.0.35"], "test"=>["spec/pom.xml", "junit:junit:jar:4.10"]} )
10
10
  jarfile.repositories.should eql( ["http://repository.jboss.org/nexus/content/groups/public-jboss"] )
11
11
  end
12
12
 
13
13
  it "should load a block" do
14
14
  block = LockJar::Dsl.evaluate do
15
+ local '~/.m2'
15
16
  repository 'http://repository.jboss.org/nexus/content/groups/public-jboss'
16
17
 
17
18
  jar "org.apache.mina:mina-core:2.0.4"
@@ -26,6 +27,7 @@ describe LockJar::Dsl do
26
27
  end
27
28
  end
28
29
 
30
+ block.local_repository.should eql '~/.m2'
29
31
  block.notations.should eql( {"compile"=>["org.apache.mina:mina-core:2.0.4", "spec/pom.xml"], "runtime"=>["spec/pom.xml", "org.apache.tomcat:servlet-api:jar:6.0.35"], "test"=>["spec/pom.xml", "junit:junit:jar:4.10"]} )
30
32
  block.repositories.should eql( ["http://repository.jboss.org/nexus/content/groups/public-jboss"] )
31
33
 
@@ -0,0 +1,27 @@
1
+ require 'rubygems'
2
+ require 'lib/lock_jar/runtime'
3
+
4
+ describe LockJar::Runtime do
5
+ context "Singleton" do
6
+ it "should set local repo" do
7
+ LockJar::Runtime.instance.load( nil ) do
8
+ jar 'org.modeshape:modeshape-common:2.3.0.Final'
9
+ end
10
+
11
+ LockJar::Runtime.instance.current_resolver.naether.local_repo_path.should eql File.expand_path('~/.m2/repository')
12
+
13
+ LockJar::Runtime.instance.load( nil, [], :local_repo => 'tmp/param_config' ) do
14
+ local 'dsl_config'
15
+ end
16
+
17
+ LockJar::Runtime.instance.current_resolver.naether.local_repo_path.should eql 'tmp/param_config'
18
+
19
+ LockJar::Runtime.instance.load( nil ) do
20
+ local 'tmp/dsl_config'
21
+ end
22
+
23
+ LockJar::Runtime.instance.current_resolver.naether.local_repo_path.should eql 'tmp/dsl_config'
24
+
25
+ end
26
+ end
27
+ end
@@ -16,22 +16,44 @@ describe LockJar do
16
16
  jars = LockJar.list( 'tmp/Jarfile.lock', ['compile', 'runtime', 'bad scope'], :local_repo => 'tmp/test-repo' )
17
17
  jars.should eql( ["org.apache.mina:mina-core:jar:2.0.4", "org.slf4j:slf4j-api:jar:1.6.1", "com.slackworks:modelcitizen:jar:0.2.2", "commons-lang:commons-lang:jar:2.6", "commons-beanutils:commons-beanutils:jar:1.8.3", "commons-logging:commons-logging:jar:1.1.1", "ch.qos.logback:logback-classic:jar:0.9.24", "ch.qos.logback:logback-core:jar:0.9.24", "com.metapossum:metapossum-scanner:jar:1.0", "commons-io:commons-io:jar:1.4", "junit:junit:jar:4.7", "org.apache.tomcat:servlet-api:jar:6.0.35"] )
18
18
  end
19
+
20
+ context "load" do
21
+ it "by Jarfile.lock" do
22
+ if Naether.platform == 'java'
23
+ lambda { include_class 'org.apache.mina.core.IoUtil' }.should raise_error
24
+ else
25
+ lambda { Rjb::import('org.apache.mina.core.IoUtil') }.should raise_error
26
+ end
27
+
28
+ jars = LockJar.load( 'tmp/Jarfile.lock', ['compile', 'runtime'], :local_repo => 'tmp/test-repo' )
19
29
 
20
- it "should load jars" do
21
- if Naether.platform == 'java'
22
- lambda { include_class 'org.apache.mina.core.IoUtil' }.should raise_error
23
- else
24
- lambda { Rjb::import('org.apache.mina.core.IoUtil') }.should raise_error
30
+ jars.should eql( [File.expand_path("tmp/test-repo/org/apache/mina/mina-core/2.0.4/mina-core-2.0.4.jar"), File.expand_path("tmp/test-repo/org/slf4j/slf4j-api/1.6.1/slf4j-api-1.6.1.jar"), File.expand_path("tmp/test-repo/com/slackworks/modelcitizen/0.2.2/modelcitizen-0.2.2.jar"), File.expand_path("tmp/test-repo/commons-lang/commons-lang/2.6/commons-lang-2.6.jar"), File.expand_path("tmp/test-repo/commons-beanutils/commons-beanutils/1.8.3/commons-beanutils-1.8.3.jar"), File.expand_path("tmp/test-repo/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar"), File.expand_path("tmp/test-repo/ch/qos/logback/logback-classic/0.9.24/logback-classic-0.9.24.jar"), File.expand_path("tmp/test-repo/ch/qos/logback/logback-core/0.9.24/logback-core-0.9.24.jar"), File.expand_path("tmp/test-repo/com/metapossum/metapossum-scanner/1.0/metapossum-scanner-1.0.jar"), File.expand_path("tmp/test-repo/commons-io/commons-io/1.4/commons-io-1.4.jar"), File.expand_path("tmp/test-repo/junit/junit/4.7/junit-4.7.jar"), File.expand_path("tmp/test-repo/org/apache/tomcat/servlet-api/6.0.35/servlet-api-6.0.35.jar")] )
31
+
32
+ if Naether.platform == 'java'
33
+ lambda { include_class 'org.apache.mina.core.IoUtil' }.should_not raise_error
34
+ else
35
+ lambda { Rjb::import('org.apache.mina.core.IoUtil') }.should_not raise_error
36
+ end
25
37
  end
26
-
27
- jars = LockJar.load( 'tmp/Jarfile.lock', ['compile', 'runtime'], :local_repo => 'tmp/test-repo' )
28
-
29
- jars.should eql( [File.expand_path("tmp/test-repo/org/apache/mina/mina-core/2.0.4/mina-core-2.0.4.jar"), File.expand_path("tmp/test-repo/org/slf4j/slf4j-api/1.6.1/slf4j-api-1.6.1.jar"), File.expand_path("tmp/test-repo/com/slackworks/modelcitizen/0.2.2/modelcitizen-0.2.2.jar"), File.expand_path("tmp/test-repo/commons-lang/commons-lang/2.6/commons-lang-2.6.jar"), File.expand_path("tmp/test-repo/commons-beanutils/commons-beanutils/1.8.3/commons-beanutils-1.8.3.jar"), File.expand_path("tmp/test-repo/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar"), File.expand_path("tmp/test-repo/ch/qos/logback/logback-classic/0.9.24/logback-classic-0.9.24.jar"), File.expand_path("tmp/test-repo/ch/qos/logback/logback-core/0.9.24/logback-core-0.9.24.jar"), File.expand_path("tmp/test-repo/com/metapossum/metapossum-scanner/1.0/metapossum-scanner-1.0.jar"), File.expand_path("tmp/test-repo/commons-io/commons-io/1.4/commons-io-1.4.jar"), File.expand_path("tmp/test-repo/junit/junit/4.7/junit-4.7.jar"), File.expand_path("tmp/test-repo/org/apache/tomcat/servlet-api/6.0.35/servlet-api-6.0.35.jar")] )
38
+
39
+ it "by block with resolve option" do
40
+ if Naether.platform == 'java'
41
+ lambda { include_class 'org.modeshape.common.math.Duration' }.should raise_error
42
+ else
43
+ lambda { Rjb::import('org.modeshape.common.math.Duration') }.should raise_error
44
+ end
45
+
46
+ jars = LockJar.load( :resolve => true ) do
47
+ jar 'org.modeshape:modeshape-common:2.3.0.Final'
48
+ end
30
49
 
31
- if Naether.platform == 'java'
32
- lambda { include_class 'org.apache.mina.core.IoUtil' }.should_not raise_error
33
- else
34
- lambda { Rjb::import('org.apache.mina.core.IoUtil') }.should_not raise_error
50
+ jars.should eql( ["/home/zinger/.m2/repository/org/modeshape/modeshape-common/2.3.0.Final/modeshape-common-2.3.0.Final.jar", "/home/zinger/.m2/repository/org/slf4j/slf4j-api/1.5.11/slf4j-api-1.5.11.jar", "/home/zinger/.m2/repository/net/jcip/jcip-annotations/1.0/jcip-annotations-1.0.jar"] )
51
+
52
+ if Naether.platform == 'java'
53
+ lambda { include_class 'org.modeshape.common.math.Duration' }.should_not raise_error
54
+ else
55
+ lambda { Rjb::import('org.modeshape.common.math.Duration') }.should_not raise_error
56
+ end
35
57
  end
36
58
  end
37
59
  end
@@ -0,0 +1,6 @@
1
+ $:.unshift File.expand_path('..', __FILE__)
2
+ $:.unshift File.expand_path('../../lib', __FILE__)
3
+
4
+ RSpec.configure do |config|
5
+
6
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lock_jar
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
+ - 1
8
9
  - 0
9
- - 3
10
- version: 0.0.3
10
+ version: 0.1.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Michael Guymon
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-04-16 00:00:00 Z
18
+ date: 2012-04-19 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  prerelease: false
@@ -39,12 +39,14 @@ dependencies:
39
39
  requirement: &id002 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
- - - ">="
42
+ - - ~>
43
43
  - !ruby/object:Gem::Version
44
- hash: 3
44
+ hash: 43
45
45
  segments:
46
+ - 2
47
+ - 9
46
48
  - 0
47
- version: "0"
49
+ version: 2.9.0
48
50
  version_requirements: *id002
49
51
  name: rspec
50
52
  - !ruby/object:Gem::Dependency
@@ -99,17 +101,23 @@ files:
99
101
  - VERSION
100
102
  - lib/lock_jar.rb
101
103
  - lib/lock_jar/buildr.rb
104
+ - lib/lock_jar/bundler.rb
102
105
  - lib/lock_jar/dsl.rb
103
106
  - lib/lock_jar/maven.rb
104
107
  - lib/lock_jar/resolver.rb
105
108
  - lib/lock_jar/runtime.rb
106
109
  - lock_jar.gemspec
110
+ - spec/BundlerJarfile.lock
107
111
  - spec/Jarfile
112
+ - spec/helper/bundler_helper.rb
113
+ - spec/lock_jar/bundler_spec.rb
108
114
  - spec/lock_jar/dsl_spec.rb
109
115
  - spec/lock_jar/maven_spec.rb
110
116
  - spec/lock_jar/resolver_spec.rb
117
+ - spec/lock_jar/runtime_spec.rb
111
118
  - spec/lock_jar_spec.rb
112
119
  - spec/pom.xml
120
+ - spec/spec_helper.rb
113
121
  homepage: http://github.com/mguymon/lock_jar
114
122
  licenses:
115
123
  - Apache