doubleshot 0.1.0-java → 0.2.0-java
Sign up to get free protection for your applications and to get access to all the features.
- data/Doubleshot +21 -10
- data/README.textile +13 -5
- data/bin/doubleshot +9 -1
- data/ext/java/Aether.java +199 -0
- data/ext/java/ManualWagonProvider.java +24 -0
- data/ext/java/SimpleRepositoryListener.java +77 -0
- data/lib/doubleshot.rb +155 -9
- data/lib/doubleshot/cli.rb +2 -1
- data/lib/doubleshot/cli/options.rb +3 -1
- data/lib/doubleshot/commands/build.rb +47 -9
- data/lib/doubleshot/commands/gem.rb +30 -9
- data/lib/doubleshot/commands/init.rb +41 -10
- data/lib/doubleshot/commands/install.rb +4 -4
- data/lib/doubleshot/commands/jar.rb +60 -2
- data/lib/doubleshot/commands/pom.rb +29 -0
- data/lib/doubleshot/commands/test.rb +85 -32
- data/lib/doubleshot/compiler.rb +20 -17
- data/lib/doubleshot/compiler/classpath.rb +46 -0
- data/lib/doubleshot/configuration.rb +158 -8
- data/lib/doubleshot/dependencies/dependency.rb +16 -15
- data/lib/doubleshot/dependencies/dependency_list.rb +20 -5
- data/lib/doubleshot/dependencies/gem_dependency.rb +35 -0
- data/lib/doubleshot/dependencies/gem_dependency_list.rb +1 -1
- data/lib/doubleshot/dependencies/jar_dependency.rb +64 -1
- data/lib/doubleshot/dependencies/jar_dependency_list.rb +1 -1
- data/lib/doubleshot/jar.rb +13 -2
- data/lib/doubleshot/lockfile.rb +108 -0
- data/lib/doubleshot/pom.rb +42 -0
- data/lib/doubleshot/readonly_collection.rb +6 -2
- data/lib/doubleshot/resolver.rb +22 -0
- data/lib/doubleshot/resolver/jar_resolver.rb +36 -0
- data/lib/doubleshot/setup.rb +1 -47
- data/lib/ruby/blank.rb +3 -3
- data/lib/ruby/pathname.rb +8 -4
- data/lib/ruby/time.rb +1 -2
- data/target/doubleshot.jar +0 -0
- data/test/compiler/classpath_spec.rb +74 -0
- data/test/compiler_spec.rb +89 -10
- data/test/configuration/source_locations_spec.rb +2 -2
- data/test/configuration_spec.rb +115 -17
- data/test/dependencies/dependency_list_spec.rb +26 -4
- data/test/dependencies/dependency_spec.rb +19 -18
- data/test/dependencies/gem_dependency_list_spec.rb +0 -0
- data/test/dependencies/gem_dependency_spec.rb +54 -0
- data/test/dependencies/jar_dependency_list_spec.rb +0 -0
- data/test/dependencies/jar_dependency_spec.rb +62 -1
- data/test/dependencies_spec.rb +4 -4
- data/test/doubleshot_spec.rb +34 -2
- data/test/helper.rb +36 -1
- data/test/lockfile_spec.rb +236 -0
- data/test/pom_spec.rb +66 -0
- data/test/readonly_collection_spec.rb +10 -3
- data/test/resolver/jar_resolver_spec.rb +34 -0
- data/test/resolver_spec.rb +25 -0
- metadata +28 -28
- data/ext/java/Empty.java +0 -0
@@ -3,6 +3,41 @@ require "doubleshot/dependencies/dependency"
|
|
3
3
|
class Doubleshot
|
4
4
|
class Dependencies
|
5
5
|
class GemDependency < Dependency
|
6
|
+
|
7
|
+
def initialize(name)
|
8
|
+
super
|
9
|
+
@requirements = Set.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def requirements
|
13
|
+
ReadonlyCollection.new(@requirements)
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_requirement(requirement)
|
17
|
+
requirement = Gem::Requirement.new(requirement)
|
18
|
+
@requirements << requirement
|
19
|
+
requirement
|
20
|
+
end
|
21
|
+
|
22
|
+
def ==(other)
|
23
|
+
eql?(other) && requirements == other.requirements
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_s(long_form = false)
|
27
|
+
if long_form && !@requirements.empty?
|
28
|
+
"#{name} (#{@requirements.sort.map(&:to_s).join(", ")})"
|
29
|
+
else
|
30
|
+
@name
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# def gemspec
|
35
|
+
# end
|
36
|
+
|
37
|
+
# def dependencies
|
38
|
+
# #gemspec.runtime_dependencies
|
39
|
+
# end
|
40
|
+
|
6
41
|
end
|
7
42
|
end
|
8
43
|
end
|
@@ -3,6 +3,69 @@ require "doubleshot/dependencies/dependency"
|
|
3
3
|
class Doubleshot
|
4
4
|
class Dependencies
|
5
5
|
class JarDependency < Dependency
|
6
|
+
|
7
|
+
PACKAGE_TYPES = [ "pom", "jar", "maven-plugin", "ejb", "war", "ear", "rar", "par", "bundle" ]
|
8
|
+
|
9
|
+
attr_reader :group, :artifact, :packaging, :classifier, :version, :path
|
10
|
+
|
11
|
+
def initialize(maven_coordinate)
|
12
|
+
# This is Maven's default package type, if unspecified.
|
13
|
+
@packaging = "jar"
|
14
|
+
|
15
|
+
maven_coordinate_parts = maven_coordinate.split(":")
|
16
|
+
@group = maven_coordinate_parts.shift
|
17
|
+
@artifact = maven_coordinate_parts.shift
|
18
|
+
|
19
|
+
if version = maven_coordinate_parts.pop
|
20
|
+
if !PACKAGE_TYPES.include?(version)
|
21
|
+
self.version = version
|
22
|
+
else
|
23
|
+
raise ArgumentError.new("Expected last coordinate part to be a Version but was a Package Type: #{maven_coordinate}")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
if packaging = maven_coordinate_parts.shift
|
28
|
+
self.packaging = packaging
|
29
|
+
end
|
30
|
+
|
31
|
+
if classifier = maven_coordinate_parts.shift
|
32
|
+
@classifier = classifier
|
33
|
+
end
|
34
|
+
|
35
|
+
@name = "#{@group}:#{@artifact}:#{@packaging}#{":#{@classifier}" if @classifier}:#{@version}"
|
36
|
+
|
37
|
+
if [ @group, @artifact, @packaging, @version ].any? &:blank?
|
38
|
+
raise ArgumentError.new("Invalid coordinate: #{@name}")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_s(long_form = false)
|
43
|
+
@name
|
44
|
+
end
|
45
|
+
|
46
|
+
def path=(path)
|
47
|
+
@path = Pathname(path.to_s)
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def packaging=(value = "jar")
|
53
|
+
if PACKAGE_TYPES.include?(value.downcase)
|
54
|
+
@packaging = value.downcase
|
55
|
+
else
|
56
|
+
raise ArgumentError.new("Invalid Packaging Type: #{value.inspect}")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def version=(value)
|
61
|
+
if !value.blank?
|
62
|
+
@version = value
|
63
|
+
else
|
64
|
+
raise ArgumentError.new("Version must not be blank")
|
65
|
+
end
|
66
|
+
# compare version against rules specified here: http://www.sonatype.com/books/mvnref-book/reference/pom-relationships-sect-pom-syntax.html#pom-relationships-sect-version-build-numbers
|
67
|
+
# http://stackoverflow.com/questions/30571/how-do-i-tell-maven-to-use-the-latest-version-of-a-dependency
|
68
|
+
end
|
6
69
|
end
|
7
70
|
end
|
8
|
-
end
|
71
|
+
end
|
data/lib/doubleshot/jar.rb
CHANGED
@@ -37,7 +37,14 @@ target = Pathname "target"
|
|
37
37
|
|
38
38
|
target.mkdir unless target.exist?
|
39
39
|
|
40
|
-
ant.path id: "classpath" do
|
40
|
+
ant.path id: "classpath" do
|
41
|
+
fileset dir: "target"
|
42
|
+
["ext/java"].each do |jar|
|
43
|
+
fileset dir: Pathname(jar).dirname
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
ant.path id: "classpath" do
|
41
48
|
fileset dir: target.to_s
|
42
49
|
JBUNDLER_CLASSPATH.each do |jar|
|
43
50
|
fileset dir: Pathname(jar).dirname
|
@@ -48,4 +55,8 @@ ant.javac srcdir: source.to_s, destdir: target.to_s, debug: "yes", includeantrun
|
|
48
55
|
|
49
56
|
$CLASSPATH << target.to_s
|
50
57
|
|
51
|
-
ant.jar jarfile: "example.jar", basedir: target.to_s
|
58
|
+
ant.jar jarfile: "example.jar", basedir: target.to_s do
|
59
|
+
@config.runtime.jars.each do |jar|
|
60
|
+
ant.zipgroupfileset dir: jar.path.dirname, includes: jar.path.to_s
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
class Doubleshot
|
2
|
+
class Lockfile
|
3
|
+
|
4
|
+
class UnlockedDependencyError < StandardError
|
5
|
+
def initialize(dependency)
|
6
|
+
super "Dependency #{dependency.to_s.inspect} is unlocked!"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class UnknownDependencyTypeError < NotImplementedError
|
11
|
+
def initialize(dependency)
|
12
|
+
super "Handling for this dependency is not implemented: #{dependency.inspect}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :path
|
17
|
+
|
18
|
+
def initialize(path = "Doubleshot.lock")
|
19
|
+
@path = Pathname(path.to_s)
|
20
|
+
@gems = Dependencies::GemDependencyList.new
|
21
|
+
@jars = Dependencies::JarDependencyList.new
|
22
|
+
end
|
23
|
+
|
24
|
+
def delete
|
25
|
+
@path.delete
|
26
|
+
end
|
27
|
+
|
28
|
+
def exist?
|
29
|
+
@path.exist?
|
30
|
+
end
|
31
|
+
|
32
|
+
def mtime
|
33
|
+
@path.mtime
|
34
|
+
end
|
35
|
+
|
36
|
+
def gems
|
37
|
+
load
|
38
|
+
ReadonlyCollection.new @gems
|
39
|
+
end
|
40
|
+
|
41
|
+
def jars
|
42
|
+
load
|
43
|
+
ReadonlyCollection.new @jars
|
44
|
+
end
|
45
|
+
|
46
|
+
def empty?
|
47
|
+
@gems.empty? && @jars.empty?
|
48
|
+
end
|
49
|
+
|
50
|
+
def add(dependency)
|
51
|
+
if dependency.class == Dependencies::Dependency
|
52
|
+
raise ArgumentError.new("+dependency+ must be a concrete type (JarDependency or GemDependency).")
|
53
|
+
elsif dependency.class < Dependencies::Dependency
|
54
|
+
if dependency.locked?
|
55
|
+
case dependency
|
56
|
+
when Dependencies::JarDependency then @jars.add(dependency)
|
57
|
+
when Dependencies::GemDependency then @gems.add(dependency)
|
58
|
+
else raise UnknownDependencyTypeError.new(dependency)
|
59
|
+
end
|
60
|
+
else
|
61
|
+
raise UnlockedDependencyError.new(dependency)
|
62
|
+
end
|
63
|
+
else
|
64
|
+
raise ArgumentError.new("+dependency+ must be a type of Doubleshot::Dependencies::Dependency.")
|
65
|
+
end
|
66
|
+
|
67
|
+
self
|
68
|
+
end
|
69
|
+
|
70
|
+
def load
|
71
|
+
unless @loaded
|
72
|
+
(data["JARS"] || []).each do |buildr_string|
|
73
|
+
@jars.add Dependencies::JarDependency.new(buildr_string)
|
74
|
+
end
|
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
|
80
|
+
end
|
81
|
+
|
82
|
+
@loaded = true
|
83
|
+
end
|
84
|
+
|
85
|
+
def flush!
|
86
|
+
output = { "JARS" => [], "GEMS" => [] }
|
87
|
+
|
88
|
+
jars.each do |jar|
|
89
|
+
output["JARS"] << jar.to_s(true)
|
90
|
+
end
|
91
|
+
|
92
|
+
gems.each do |gem|
|
93
|
+
output["GEMS"] << gem.to_s(true)
|
94
|
+
end
|
95
|
+
|
96
|
+
@path.open("w+") do |file|
|
97
|
+
file << output.to_yaml
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
def data
|
104
|
+
@data ||= (@path.exist? ? YAML.load(@path.read) : {})
|
105
|
+
end
|
106
|
+
|
107
|
+
end # class Lockfile
|
108
|
+
end # class Doubleshot
|
@@ -0,0 +1,42 @@
|
|
1
|
+
class Doubleshot
|
2
|
+
class Pom
|
3
|
+
def initialize(config)
|
4
|
+
@config = config
|
5
|
+
end
|
6
|
+
|
7
|
+
def to_s
|
8
|
+
jars = @config.runtime.jars + @config.development.jars
|
9
|
+
|
10
|
+
<<-EOS.margin
|
11
|
+
<?xml version="1.0"?>
|
12
|
+
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
13
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
14
|
+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
15
|
+
<modelVersion>4.0.0</modelVersion>
|
16
|
+
<groupId>#{@config.group}</groupId>
|
17
|
+
<artifactId>#{@config.project}</artifactId>
|
18
|
+
<version>#{@config.version}</version>
|
19
|
+
<packaging>pom</packaging>
|
20
|
+
<name>#{@config.project}</name>
|
21
|
+
#{
|
22
|
+
unless jars.empty?
|
23
|
+
"<dependencies>\n " +
|
24
|
+
jars.map do |jar|
|
25
|
+
<<-JAR.strip
|
26
|
+
<dependency>
|
27
|
+
<groupId>#{jar.group}</groupId>
|
28
|
+
<artifactId>#{jar.artifact}</artifactId>
|
29
|
+
<type>#{jar.packaging}</type>
|
30
|
+
#{
|
31
|
+
"<classifier>#{jar.classifier}</classifier>" unless jar.classifier.blank?
|
32
|
+
}<version>#{jar.version}</version>
|
33
|
+
</dependency>
|
34
|
+
JAR
|
35
|
+
end.join("\n ") +
|
36
|
+
"\n </dependencies>\n"
|
37
|
+
end
|
38
|
+
} </project>
|
39
|
+
EOS
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -22,11 +22,15 @@ class Doubleshot
|
|
22
22
|
def empty?
|
23
23
|
entries.empty?
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
def eql?(other)
|
27
27
|
other.is_a?(self.class) && entries == other.entries
|
28
28
|
end
|
29
29
|
alias :== :eql?
|
30
|
+
|
31
|
+
def +(other)
|
32
|
+
ReadonlyCollection.new(entries + other.entries)
|
33
|
+
end
|
30
34
|
end
|
31
35
|
|
32
|
-
end
|
36
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require "uri"
|
2
|
+
|
3
|
+
class Doubleshot
|
4
|
+
class Resolver
|
5
|
+
def initialize(*repositories)
|
6
|
+
@repositories = repositories.map do |repository|
|
7
|
+
URI.parse repository.to_s
|
8
|
+
end
|
9
|
+
raise ArgumentError.new("no repositories specified") if @repositories.empty?
|
10
|
+
end
|
11
|
+
|
12
|
+
def fetch(dependencies)
|
13
|
+
raise NotImplementedError.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def repositories
|
17
|
+
ReadonlyCollection.new(@repositories)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
require "doubleshot/resolver/jar_resolver"
|
@@ -0,0 +1,36 @@
|
|
1
|
+
java_import "org.sam.doubleshot.Aether"
|
2
|
+
|
3
|
+
class Doubleshot
|
4
|
+
class Resolver
|
5
|
+
class JarResolver < Resolver
|
6
|
+
DEFAULT_REPOSITORY = "http://repo1.maven.org/maven2"
|
7
|
+
|
8
|
+
def initialize(*repositories)
|
9
|
+
super
|
10
|
+
# Change the second argument to "true" to get verbose output.
|
11
|
+
@aether = Aether.new(Pathname("~/.m2").expand_path.to_s, false, false)
|
12
|
+
@repositories.each do |repository|
|
13
|
+
@aether.add_repository repository.host, repository.to_s
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def resolve!(dependencies)
|
18
|
+
dependencies.each do |dependency|
|
19
|
+
@aether.add_artifact dependency.to_s
|
20
|
+
end
|
21
|
+
|
22
|
+
@aether.resolve
|
23
|
+
classpath_map = @aether.classpath_map
|
24
|
+
|
25
|
+
@aether.resolved_coordinates.each do |coordinate|
|
26
|
+
dependencies.add Dependencies::JarDependency.new coordinate
|
27
|
+
end
|
28
|
+
|
29
|
+
dependencies.each do |dependency|
|
30
|
+
dependency.path = classpath_map[dependency.to_s]
|
31
|
+
end
|
32
|
+
dependencies
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/doubleshot/setup.rb
CHANGED
@@ -1,49 +1,3 @@
|
|
1
1
|
require_relative "../doubleshot"
|
2
2
|
|
3
|
-
|
4
|
-
gemfile_lock = Pathname "Gemfile.lock"
|
5
|
-
|
6
|
-
install_gems = -> do
|
7
|
-
require "bundler"
|
8
|
-
require "bundler/cli"
|
9
|
-
Bundler::CLI.new.install
|
10
|
-
end
|
11
|
-
|
12
|
-
if gemfile.exist?
|
13
|
-
begin
|
14
|
-
install_gems.call if !gemfile_lock.exist? || gemfile.mtime > gemfile_lock.mtime
|
15
|
-
require "bundler/setup"
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
install_jars = -> do
|
20
|
-
require "jbundler/cli"
|
21
|
-
JBundler::Cli.new.install
|
22
|
-
end
|
23
|
-
|
24
|
-
jarfile = Pathname "Jarfile"
|
25
|
-
jarfile_lock = Pathname "Jarfile.lock"
|
26
|
-
|
27
|
-
if jarfile.exist?
|
28
|
-
require "bundler" unless Object::const_defined?("Bundler")
|
29
|
-
require "jbundler"
|
30
|
-
install_jars.call if !jarfile_lock.exist? || jarfile.mtime > jarfile_lock.mtime
|
31
|
-
end
|
32
|
-
|
33
|
-
require "ant"
|
34
|
-
|
35
|
-
source = Pathname "ext/java"
|
36
|
-
target = Pathname "target"
|
37
|
-
|
38
|
-
target.mkdir unless target.exist?
|
39
|
-
|
40
|
-
ant.path id: "classpath" do
|
41
|
-
fileset dir: target.to_s
|
42
|
-
JBUNDLER_CLASSPATH.each do |jar|
|
43
|
-
fileset dir: Pathname(jar).dirname
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
ant.javac srcdir: source.to_s, destdir: target.to_s, debug: "yes", includeantruntime: "no", classpathref: "classpath"
|
48
|
-
|
49
|
-
$CLASSPATH << target.to_s
|
3
|
+
Doubleshot::current.setup!
|
data/lib/ruby/blank.rb
CHANGED
@@ -9,10 +9,10 @@
|
|
9
9
|
# distribute, sublicense, and/or sell copies of the Software, and to
|
10
10
|
# permit persons to whom the Software is furnished to do so, subject to
|
11
11
|
# the following conditions:
|
12
|
-
#
|
12
|
+
#
|
13
13
|
# The above copyright notice and this permission notice shall be
|
14
14
|
# included in all copies or substantial portions of the Software.
|
15
|
-
#
|
15
|
+
#
|
16
16
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
17
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
18
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
@@ -129,4 +129,4 @@ class Numeric #:nodoc:
|
|
129
129
|
def blank?
|
130
130
|
false
|
131
131
|
end
|
132
|
-
end
|
132
|
+
end
|