doubleshot 0.1.0-java → 0.2.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.
- 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
|