doubleshot 0.2.0-java → 0.3.0-java

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.
Files changed (47) hide show
  1. data/Doubleshot +16 -6
  2. data/README-OLD.textile +216 -0
  3. data/README.textile +38 -182
  4. data/lib/doubleshot.rb +100 -39
  5. data/lib/doubleshot/commands/gem.rb +15 -12
  6. data/lib/doubleshot/commands/test.rb +38 -5
  7. data/lib/doubleshot/configuration.rb +2 -2
  8. data/lib/doubleshot/dependencies/dependency.rb +1 -1
  9. data/lib/doubleshot/dependencies/gem_dependency.rb +2 -10
  10. data/lib/doubleshot/dependencies/jar_dependency.rb +12 -2
  11. data/lib/doubleshot/lockfile.rb +9 -6
  12. data/lib/doubleshot/pom.rb +15 -2
  13. data/lib/doubleshot/resolver.rb +1 -0
  14. data/lib/doubleshot/resolver/gem_resolver.rb +45 -0
  15. data/lib/doubleshot/resolver/gem_resolver/artifact.rb +146 -0
  16. data/lib/doubleshot/resolver/gem_resolver/demand.rb +57 -0
  17. data/lib/doubleshot/resolver/gem_resolver/dependency.rb +57 -0
  18. data/lib/doubleshot/resolver/gem_resolver/errors.rb +37 -0
  19. data/lib/doubleshot/resolver/gem_resolver/gem_source.rb +58 -0
  20. data/lib/doubleshot/resolver/gem_resolver/graph.rb +200 -0
  21. data/lib/doubleshot/resolver/gem_resolver/solver.rb +279 -0
  22. data/lib/doubleshot/resolver/gem_resolver/solver/constraint_row.rb +29 -0
  23. data/lib/doubleshot/resolver/gem_resolver/solver/constraint_table.rb +35 -0
  24. data/lib/doubleshot/resolver/gem_resolver/solver/variable_row.rb +47 -0
  25. data/lib/doubleshot/resolver/gem_resolver/solver/variable_table.rb +59 -0
  26. data/lib/doubleshot/resolver/gem_resolver/source.rb +36 -0
  27. data/lib/doubleshot/resolver/jar_resolver.rb +1 -3
  28. data/lib/ruby/gem/requirement.rb +9 -0
  29. data/target/doubleshot.jar +0 -0
  30. data/test/compiler_spec.rb +31 -3
  31. data/test/configuration_spec.rb +11 -3
  32. data/test/dependencies/gem_dependency_spec.rb +3 -17
  33. data/test/dependencies/jar_dependency_spec.rb +20 -0
  34. data/test/helper.rb +3 -1
  35. data/test/helpers/stub_source.rb +120 -0
  36. data/test/lockfile_spec.rb +9 -17
  37. data/test/pom_spec.rb +31 -1
  38. data/test/resolver/gem_resolver/artifact_spec.rb +106 -0
  39. data/test/resolver/gem_resolver/demand_spec.rb +70 -0
  40. data/test/resolver/gem_resolver/dependency_spec.rb +33 -0
  41. data/test/resolver/gem_resolver/gem_source_spec.rb +28 -0
  42. data/test/resolver/gem_resolver/graph_spec.rb +239 -0
  43. data/test/resolver/gem_resolver/solver_spec.rb +449 -0
  44. data/test/resolver/gem_resolver/source_spec.rb +18 -0
  45. data/test/resolver/gem_resolver_spec.rb +102 -0
  46. metadata +35 -73
  47. data/lib/doubleshot/jar.rb +0 -62
data/lib/doubleshot.rb CHANGED
@@ -18,6 +18,7 @@ require "doubleshot/readonly_collection"
18
18
  require "doubleshot/configuration"
19
19
  require "doubleshot/compiler"
20
20
  require "doubleshot/lockfile"
21
+ require "doubleshot/resolver"
21
22
 
22
23
  class Doubleshot
23
24
 
@@ -85,9 +86,72 @@ class Doubleshot
85
86
  end
86
87
  # END: Cleanup tasks
87
88
 
89
+ load_gems! unless @config.runtime.gems.empty? && @config.development.gems.empty?
88
90
  load_jars! unless @config.runtime.jars.empty? && @config.development.jars.empty?
89
91
  end
90
92
 
93
+ def load_gems!
94
+ if lockfile.gems.empty?
95
+ dependencies = @config.runtime.gems + @config.development.gems
96
+
97
+ puts "Dependencies not locked. Resolving the following:"
98
+ dependencies.each do |dependency|
99
+ puts " #{dependency.name}: #{dependency.requirements.map(&:to_s).join(", ")}"
100
+ end
101
+
102
+ unless dependencies.empty?
103
+ resolver = Resolver::GemResolver.new *@config.gem_repositories
104
+ puts "Using repositories: #{@config.gem_repositories.map(&:to_s).join(",")}"
105
+
106
+ resolver.resolve! dependencies
107
+
108
+ puts "Resolved dependencies:"
109
+ dependencies.each do |dependency|
110
+ puts " #{dependency.name}: #{dependency.version}"
111
+ end
112
+
113
+ require "rubygems/dependency_installer"
114
+ Gem::sources = @config.gem_repositories.entries
115
+ installer = Gem::DependencyInstaller.new domain: :both
116
+ dependencies.each do |dependency|
117
+ begin
118
+ puts "Activating: #{dependency.name} #{dependency.version}"
119
+ gem dependency.name, dependency.version
120
+ rescue LoadError
121
+ puts "Gem not installed! Installing: #{dependency.name} #{dependency.version}"
122
+ installer.install dependency.name, dependency.version
123
+ gem dependency.name, dependency.version
124
+ end
125
+ lockfile.add dependency
126
+ end
127
+
128
+ dependencies.each { |dependency| lockfile.add dependency }
129
+ lockfile.flush!
130
+ end
131
+ else
132
+ missing_dependencies = []
133
+ lockfile.gems.each do |dependency|
134
+ begin
135
+ gem dependency.name, dependency.version
136
+ rescue LoadError
137
+ missing_dependencies << dependency
138
+ end
139
+ end
140
+
141
+ unless missing_dependencies.empty?
142
+ # TODO: Figure out how to use #gem_repositories here
143
+ require "rubygems/dependency_installer"
144
+ Gem::sources = @config.gem_repositories.entries
145
+ installer = Gem::DependencyInstaller.new domain: :both
146
+
147
+ missing_dependencies.each do |dependency|
148
+ installer.install dependency.name, dependency.version
149
+ gem dependency.name, dependency.version
150
+ end
151
+ end
152
+ end
153
+ end
154
+
91
155
  def load_jars!
92
156
  if classpath_cache.exist?
93
157
  # We survived the cleanup checks, go ahead and just load
@@ -100,7 +164,7 @@ class Doubleshot
100
164
  require jar.path
101
165
  self.classpath << jar.path
102
166
  rescue LoadError
103
- warn "Could not load: #{jar.path.inspect}"
167
+ warn "Could not load: #{jar.to_s.inspect}"
104
168
  raise
105
169
  end
106
170
  end
@@ -108,46 +172,41 @@ class Doubleshot
108
172
  # No classpath_cache exists, we must resolve the paths
109
173
  # to our dependencies, then store the results in
110
174
  # classpath_cache for future processes to use.
111
- require "doubleshot/resolver"
112
-
113
- if @config.mvn_repositories.empty?
114
- @config.mvn_repository Resolver::JarResolver::DEFAULT_REPOSITORY
115
- end
116
-
117
- resolver = Resolver::JarResolver.new(*@config.mvn_repositories)
118
- jars = nil
119
-
120
- if lockfile.exist?
121
- jars = Dependencies::JarDependencyList.new
122
- lockfile.jars.each do |jar|
123
- jars.add jar
175
+ jars = @config.runtime.jars + @config.development.jars
176
+ unless jars.empty?
177
+
178
+ resolver = Resolver::JarResolver.new(*@config.mvn_repositories)
179
+
180
+ if lockfile.exist? && !lockfile.jars.empty?
181
+ jars = Dependencies::JarDependencyList.new
182
+ lockfile.jars.each do |jar|
183
+ jars.add jar
184
+ end
124
185
  end
125
- else
126
- jars = @config.runtime.jars + @config.development.jars
127
- end
128
-
129
- resolver.resolve! jars
130
-
131
- jars.each { |jar| lockfile.add jar }
132
- lockfile.flush!
133
-
134
- cache = {}
135
- jars.each do |jar|
136
- cache[jar.to_s] = jar.path
137
- begin
138
- require jar.path
139
- self.classpath << jar.path
140
- rescue LoadError
141
- warn "Could not load: #{jar.path.inspect}"
142
- raise
186
+
187
+ resolver.resolve! jars
188
+
189
+ jars.each { |jar| lockfile.add jar }
190
+ lockfile.flush!
191
+
192
+ cache = {}
193
+ jars.each do |jar|
194
+ cache[jar.to_s] = jar.path.to_s
195
+ begin
196
+ require jar.path
197
+ self.classpath << jar.path
198
+ rescue LoadError
199
+ warn "Could not load: #{jar.to_s.inspect}"
200
+ raise
201
+ end
143
202
  end
144
- end
145
-
146
- classpath_cache.open("w+") do |file|
147
- file << cache.to_yaml
148
- end
149
- end
150
- end
203
+
204
+ classpath_cache.open("w+") do |file|
205
+ file << cache.to_yaml
206
+ end
207
+ end # unless jars.empty?
208
+ end # if classpath_cache.exist?
209
+ end # def load_jars!
151
210
 
152
211
  def classpath_cache
153
212
  @classpath_cache ||= Pathname(".classpath.cache")
@@ -169,6 +228,7 @@ class Doubleshot
169
228
  jar = Dependencies::JarDependency.new(coordinate)
170
229
  jar.path = path
171
230
  lockfile.add jar
231
+ # puts "Added coordinate: #{coordinate.inspect} as #{jar.to_s.inspect}"
172
232
  end
173
233
 
174
234
  lockfile.flush!
@@ -177,6 +237,7 @@ class Doubleshot
177
237
  file << resolved.to_yaml
178
238
  end
179
239
  else
240
+ # TODO: This is problematic since Maven and Aether resolve different dependencies...
180
241
  setup!
181
242
  end
182
243
  end
@@ -37,22 +37,25 @@ class Doubleshot::CLI::Commands::Gem < Doubleshot::CLI
37
37
  Doubleshot::CLI::Commands::Build.start(args)
38
38
  end
39
39
 
40
- unless Pathname::glob(doubleshot.config.source.java + "**/*.java").empty?
41
- target = doubleshot.config.target
42
-
43
- jarfile = (target + "#{doubleshot.config.project}.jar")
44
- jarfile.delete if jarfile.exist?
45
-
46
- ant.jar jarfile: jarfile, basedir: target do
47
- doubleshot.lockfile.jars.each do |jar|
48
- zipfileset src: jar.path.expand_path, excludes: "META-INF/*.SF"
40
+ target = doubleshot.config.target
41
+ jarfile = target + "#{doubleshot.config.project}.jar"
42
+ jarfile.delete if jarfile.exist?
43
+
44
+ begin
45
+ unless Pathname::glob(doubleshot.config.source.java + "**/*.java").empty?
46
+ ant.jar jarfile: jarfile, basedir: target do
47
+ doubleshot.lockfile.jars.each do |jar|
48
+ zipfileset src: jar.path.expand_path, excludes: "META-INF/*.SF"
49
+ end
49
50
  end
50
51
  end
52
+
53
+ # WARN: This is version specific since in HEAD they've changed this to Gem::Package::build.
54
+ ::Gem::Builder.new(doubleshot.config.gemspec).build
55
+ ensure
56
+ jarfile.delete if jarfile.exist?
51
57
  end
52
58
 
53
- # WARN: This is version specific since in HEAD they've changed this to Gem::Package::build.
54
- ::Gem::Builder.new(doubleshot.config.gemspec).build
55
-
56
59
  puts(" Size: %.2fM" % (Pathname(doubleshot.config.gemspec.file_name).size.to_f / 1024 / 1024))
57
60
 
58
61
  return 0
@@ -22,6 +22,11 @@ class Doubleshot::CLI::Commands::Test < Doubleshot::CLI
22
22
  options.build = true
23
23
  end
24
24
 
25
+ options.force_tests = false
26
+ options.on "--force", "Run tests, even if doubleshot_test.pid exists." do
27
+ options.force_tests = true
28
+ end
29
+
25
30
  options.separator ""
26
31
  options.separator "Summary: #{summary}"
27
32
  end
@@ -29,6 +34,24 @@ class Doubleshot::CLI::Commands::Test < Doubleshot::CLI
29
34
 
30
35
  def self.start(args)
31
36
  options = self.options.parse!(args)
37
+
38
+ @@pid_file = Pathname(".doubleshot_test.pid")
39
+ if @@pid_file.exist? && !options.force_tests
40
+
41
+ begin
42
+ if Process.getpgid(@@pid_file.read.to_i)
43
+ puts ".doubleshot_test.pid exists: Are you running tests elsewhere? (Use --force to override.)"
44
+ exit 1
45
+ end
46
+ rescue Errno::ESRCH
47
+ @@pid_file.delete
48
+ end
49
+ end
50
+
51
+ @@pid_file.open("w") do |pid|
52
+ pid << $$
53
+ end
54
+
32
55
  doubleshot = Doubleshot::current
33
56
 
34
57
  if Pathname::glob(doubleshot.config.source.tests + "**/*_{spec,test}.rb").empty?
@@ -53,21 +76,25 @@ class Doubleshot::CLI::Commands::Test < Doubleshot::CLI
53
76
  end
54
77
  end
55
78
 
56
- require "listen"
57
-
58
- watcher = new(doubleshot.config, options.ci_test)
79
+ watcher = new(doubleshot.config, options.ci_test, options.force_tests)
59
80
  watcher.run
60
81
  end
61
82
 
62
- def initialize(config, ci_test)
83
+ def initialize(config, ci_test, force_tests)
63
84
  @config = config
64
85
  @interrupted = false
65
86
  @ci_test = ci_test
87
+ @force_tests = force_tests
66
88
 
67
89
  # Hit Ctrl-C once to re-run all specs; twice to exit the program.
68
90
  Signal.trap("INT") do
69
91
  if @interrupted
70
92
  puts "\nShutting down..."
93
+
94
+ unless @force_tests
95
+ @@pid_file.delete if @@pid_file.exist?
96
+ end
97
+
71
98
  exit 0
72
99
  else
73
100
  @interrupted = true
@@ -79,7 +106,11 @@ class Doubleshot::CLI::Commands::Test < Doubleshot::CLI
79
106
 
80
107
  def run
81
108
  if @ci_test
82
- run_all_specs
109
+ exit_status = run_all_specs
110
+ unless @force_tests
111
+ @@pid_file.delete if @@pid_file.exist?
112
+ end
113
+ exit_status
83
114
  else
84
115
  Doubleshot::CLI::Commands::Build.start([ "--conditional" ])
85
116
  # Output here just so you know when changes will be
@@ -91,6 +122,8 @@ class Doubleshot::CLI::Commands::Test < Doubleshot::CLI
91
122
 
92
123
  private
93
124
  def listener
125
+ require "listen"
126
+
94
127
  # This creates a MultiListener
95
128
  Listen.to(@config.source.tests.to_s, @config.source.ruby.to_s, @config.source.java.to_s).change do |modified, added, removed|
96
129
  modified.each do |location|
@@ -179,7 +179,7 @@ class Doubleshot
179
179
  end
180
180
 
181
181
  def gem_repositories
182
- ReadonlyCollection.new(@gem_repositories)
182
+ ReadonlyCollection.new(@gem_repositories.empty? ? [ Resolver::GemResolver::DEFAULT_REPOSITORY ] : @gem_repositories)
183
183
  end
184
184
 
185
185
  def mvn_repository(uri)
@@ -188,7 +188,7 @@ class Doubleshot
188
188
  end
189
189
 
190
190
  def mvn_repositories
191
- ReadonlyCollection.new(@mvn_repositories)
191
+ ReadonlyCollection.new(@mvn_repositories.empty? ? [ Resolver::JarResolver::DEFAULT_REPOSITORY ] : @mvn_repositories)
192
192
  end
193
193
 
194
194
  def source
@@ -1,7 +1,7 @@
1
1
  class Doubleshot
2
2
  class Dependencies
3
3
  class Dependency
4
- attr_reader :name
4
+ attr_reader :name, :version
5
5
 
6
6
  def initialize(name)
7
7
  @name = name.dup.freeze
@@ -24,20 +24,12 @@ class Doubleshot
24
24
  end
25
25
 
26
26
  def to_s(long_form = false)
27
- if long_form && !@requirements.empty?
28
- "#{name} (#{@requirements.sort.map(&:to_s).join(", ")})"
27
+ if long_form && @version
28
+ "#{name}:#{version}"
29
29
  else
30
30
  @name
31
31
  end
32
32
  end
33
-
34
- # def gemspec
35
- # end
36
-
37
- # def dependencies
38
- # #gemspec.runtime_dependencies
39
- # end
40
-
41
33
  end
42
34
  end
43
35
  end
@@ -6,7 +6,7 @@ class Doubleshot
6
6
 
7
7
  PACKAGE_TYPES = [ "pom", "jar", "maven-plugin", "ejb", "war", "ear", "rar", "par", "bundle" ]
8
8
 
9
- attr_reader :group, :artifact, :packaging, :classifier, :version, :path
9
+ attr_reader :group, :artifact, :packaging, :classifier, :version, :path, :exclusions
10
10
 
11
11
  def initialize(maven_coordinate)
12
12
  # This is Maven's default package type, if unspecified.
@@ -32,11 +32,13 @@ class Doubleshot
32
32
  @classifier = classifier
33
33
  end
34
34
 
35
- @name = "#{@group}:#{@artifact}:#{@packaging}#{":#{@classifier}" if @classifier}:#{@version}"
35
+ @name = "#{@group}:#{@artifact}:#{@packaging}:#{@version}"
36
36
 
37
37
  if [ @group, @artifact, @packaging, @version ].any? &:blank?
38
38
  raise ArgumentError.new("Invalid coordinate: #{@name}")
39
39
  end
40
+
41
+ @exclusions = []
40
42
  end
41
43
 
42
44
  def to_s(long_form = false)
@@ -47,6 +49,14 @@ class Doubleshot
47
49
  @path = Pathname(path.to_s)
48
50
  end
49
51
 
52
+ def exclude(coordinate)
53
+ if coordinate.split(":").size != 2
54
+ raise ArgumentError.new("JarDependency#exclude takes a string of format \"groupId:artifactId\", you provided #{coordinate.inspect}")
55
+ end
56
+ @exclusions << coordinate
57
+ self
58
+ end
59
+
50
60
  private
51
61
 
52
62
  def packaging=(value = "jar")
@@ -69,14 +69,17 @@ class Doubleshot
69
69
 
70
70
  def load
71
71
  unless @loaded
72
- (data["JARS"] || []).each do |buildr_string|
73
- @jars.add Dependencies::JarDependency.new(buildr_string)
72
+ (data["JARS"] || []).each do |coordinate|
73
+ @jars.add Dependencies::JarDependency.new(coordinate)
74
74
  end
75
75
 
76
- # TODO: add gems to this method
77
- # (data["GEMS"] || []).each do |gem_string|
78
- # @gems.add Dependencies::GemDependency.new(gem_string)
79
- # end
76
+ (data["GEMS"] || []).each do |spec|
77
+ name, version = *spec.split(":")
78
+ dependency = Dependencies::GemDependency.new(name)
79
+ dependency.lock(version)
80
+
81
+ @gems.add dependency
82
+ end
80
83
  end
81
84
 
82
85
  @loaded = true
@@ -29,7 +29,20 @@ class Doubleshot
29
29
  <type>#{jar.packaging}</type>
30
30
  #{
31
31
  "<classifier>#{jar.classifier}</classifier>" unless jar.classifier.blank?
32
- }<version>#{jar.version}</version>
32
+ }<version>#{jar.version}</version>#{
33
+ unless jar.exclusions.empty?
34
+ "\n <exclusions>\n " +
35
+ jar.exclusions.map do |exclusion|
36
+ groupId, artifactId = exclusion.split(":")
37
+ <<-EXCLUSION.strip
38
+ <exclusion>
39
+ <groupId>#{groupId}</groupId>
40
+ <artifactId>#{artifactId}</artifactId>
41
+ </exclusion>
42
+ EXCLUSION
43
+ end.join("\n ") +
44
+ "\n </exclusions>"
45
+ end}
33
46
  </dependency>
34
47
  JAR
35
48
  end.join("\n ") +
@@ -39,4 +52,4 @@ class Doubleshot
39
52
  EOS
40
53
  end
41
54
  end
42
- end
55
+ end