puck 1.0.0.pre1 → 1.0.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,10 +1,12 @@
1
1
  if ARGV.any?
2
2
  file_name = ARGV.shift
3
- bootstrap_path = __FILE__.sub('jar-bootstrap.rb', "META-INF/app.home/bin/#{file_name}")
4
- begin
5
- load(bootstrap_path)
6
- rescue LoadError => e
7
- abort(e.message)
3
+ PUCK_BIN_PATH.each do |dir|
4
+ path = __FILE__.sub('jar-bootstrap.rb', File.join(dir, file_name))
5
+ if File.exists?(path)
6
+ load(path)
7
+ return
8
+ end
8
9
  end
10
+ abort(%(No "#{file_name}" in #{PUCK_BIN_PATH.join(File::PATH_SEPARATOR)}))
9
11
  end
10
12
 
@@ -4,6 +4,7 @@ require 'optparse'
4
4
 
5
5
 
6
6
  module Puck
7
+ # @private
7
8
  class Configuration
8
9
  def initialize(defaults={})
9
10
  @argv = defaults[:argv] || ARGV
@@ -14,15 +14,70 @@ rescue LoadError
14
14
  end
15
15
 
16
16
  module Puck
17
+ # Creates a standalone Jar file from your application.
18
+ #
19
+ # The Jar will contain your application code (which is assumed to be in the
20
+ # "lib" directory), bin files (assumed to be in the "bin" directory), all the
21
+ # gems in your default group (i.e. those that are not in a `group` block in
22
+ # your Gemfile), including gems loaded from git, or from a path. It will also
23
+ # contain a JRuby runtime so that to run it you only need a Java runtime.
24
+ #
25
+ # The Jar file will be configured so that you can run your application's bin
26
+ # files by passing their name as the first argument after the Jar file (see example below).
27
+ #
28
+ # @example Creating a Jar from a Rake task
29
+ # task :jar do
30
+ # Puck::Jar.new.create!
31
+ # end
32
+ #
33
+ # @example Configuring the Jar file
34
+ # task :jar do
35
+ # jar = Puck::Jar.new(
36
+ # extra_files: Dir['config/*.yml'],
37
+ # jruby_complete: 'build/custom-jruby-complete.jar'
38
+ # )
39
+ # jar.create!
40
+ # end
41
+ #
42
+ # @example Running a bin file
43
+ # java -jar path/to/application.jar my-bin-file arg1 arg2
44
+ #
17
45
  class Jar
46
+ # Create a new instance with the specified configuration.
47
+ #
48
+ # Puck tries to use sane defaults like assuming that the application name
49
+ # is the same as the name of the directory containing the "lib" directory.
50
+ #
51
+ # @param [Hash] configuration
52
+ # @option configuration [String] :extra_files a list of files to include in
53
+ # the Jar. The paths must be below the `:app_dir`.
54
+ # @option configuration [String] :gem_groups ([:default]) a list of gem
55
+ # groups to include in the Jar. Remember to include the default group if
56
+ # you override this option.
57
+ # @option configuration [String] :jruby_complete a path to the
58
+ # `jruby-complete.jar` that you want to use. If you don't specify this
59
+ # option you need to have `jruby-jars` in your `Gemfile` (it contains
60
+ # the equivalent of `jruby-complete.jar`. This option is mostly useful
61
+ # when you have a customized JRuby runtime that you want to use.
62
+ # @option configuration [String] :app_dir (Dir.pwd)
63
+ # the application's base directory (i.e. the directory that contains the
64
+ # "lib" directory)
65
+ # @option configuration [String] :app_name (File.basename(configuration[:app_dir]))
66
+ # the name of the application, primarily used to name the Jar
67
+ # @option configuration [String] :build_dir ("build") the directory where
68
+ # the Jar file will be created
69
+ #
18
70
  def initialize(configuration={})
19
71
  @configuration = configuration.dup
20
72
  @configuration[:app_dir] ||= Dir.pwd
21
73
  @configuration[:app_name] ||= File.basename(@configuration[:app_dir])
22
74
  @configuration[:build_dir] ||= File.join(@configuration[:app_dir], 'build')
23
75
  @configuration[:jar_name] ||= @configuration[:app_name] + '.jar'
76
+ @configuration[:gem_groups] ||= [:default]
24
77
  end
25
78
 
79
+ # Create the Jar file using the instance's configuration.
80
+ #
26
81
  def create!
27
82
  FileUtils.mkdir_p(@configuration[:build_dir])
28
83
 
@@ -33,7 +88,7 @@ module Puck
33
88
  jruby_complete_path = @configuration[:jruby_complete]
34
89
 
35
90
  if !(defined? JRubyJars) && !(jruby_complete_path && File.exists?(jruby_complete_path))
36
- raise ArgumentError, 'Cannot build Jar: jruby-jars must be installed, or :jruby_complete must be specified'
91
+ raise PuckError, 'Cannot build Jar: jruby-jars must be installed, or :jruby_complete must be specified'
37
92
  end
38
93
 
39
94
  gem_dependencies = resolve_gem_dependencies
@@ -56,12 +111,12 @@ module Puck
56
111
  end
57
112
 
58
113
  %w[bin lib].each do |sub_dir|
59
- zipfileset dir: project_dir + sub_dir, prefix: "META-INF/app.home/#{sub_dir}"
114
+ zipfileset dir: project_dir + sub_dir, prefix: File.join(JAR_APP_HOME, sub_dir)
60
115
  end
61
116
 
62
117
  extra_files.each do |ef|
63
118
  path = Pathname.new(ef).expand_path.cleanpath
64
- prefix = 'META-INF/app.home/' + path.relative_path_from(project_dir).dirname.to_s
119
+ prefix = File.join(JAR_APP_HOME, path.relative_path_from(project_dir).dirname.to_s)
65
120
  zipfileset dir: path.dirname, prefix: prefix, includes: path.basename
66
121
  end
67
122
 
@@ -72,10 +127,16 @@ module Puck
72
127
  end
73
128
  end
74
129
 
130
+ private
131
+
132
+ JAR_APP_HOME = 'META-INF/app.home'.freeze
133
+ JAR_GEM_HOME = 'META-INF/gem.home'.freeze
134
+ JAR_JRUBY_HOME = 'META-INF/jruby.home'.freeze
135
+
75
136
  def resolve_gem_dependencies
76
137
  gem_specs = Bundler::LockfileParser.new(File.read('Gemfile.lock')).specs.group_by(&:name)
77
138
  definition = Bundler::Definition.build('Gemfile', 'Gemfile.lock', false)
78
- dependencies = definition.dependencies.select { |d| d.groups.include?(:default) }.map(&:name)
139
+ dependencies = definition.dependencies.select { |d| (d.groups & @configuration[:gem_groups]).any? }.map(&:name)
79
140
  specs = resolve_gem_specs(gem_specs, dependencies)
80
141
  specs = specs.map do |bundler_spec|
81
142
  case bundler_spec.source
@@ -91,14 +152,16 @@ module Puck
91
152
  gem_spec = Gem::Specification.load(gemspec_path)
92
153
  load_paths = gem_spec.load_paths.map do |load_path|
93
154
  index = load_path.index(gem_spec.full_name)
94
- 'META-INF/gem.home/' + load_path[index, load_path.length - index]
155
+ File.join(JAR_GEM_HOME, load_path[index, load_path.length - index])
95
156
  end
157
+ bin_path = File.join(JAR_GEM_HOME, gem_spec.full_name, gem_spec.bindir)
96
158
  {
97
159
  :name => gem_spec.name,
98
160
  :versioned_name => gem_spec.full_name,
99
161
  :base_path => base_path,
100
- :jar_path => "META-INF/gem.home/#{gem_spec.full_name}",
101
- :load_paths => load_paths
162
+ :jar_path => File.join(JAR_GEM_HOME, gem_spec.full_name),
163
+ :load_paths => load_paths,
164
+ :bin_path => bin_path,
102
165
  }
103
166
  else
104
167
  nil
@@ -117,6 +180,11 @@ module Puck
117
180
 
118
181
  def create_jar_bootstrap!(tmp_dir, gem_dependencies)
119
182
  File.open(File.join(tmp_dir, 'jar-bootstrap.rb'), 'w') do |io|
183
+ io.puts(%(PUCK_BIN_PATH = ['/#{JAR_APP_HOME}/bin', '/#{JAR_JRUBY_HOME}/bin']))
184
+ gem_dependencies.each do |spec|
185
+ io.puts("PUCK_BIN_PATH << '/#{spec[:bin_path]}'")
186
+ end
187
+ io.puts
120
188
  gem_dependencies.each do |spec|
121
189
  spec[:load_paths].each do |load_path|
122
190
  io.puts(%($LOAD_PATH << 'classpath:#{load_path}'))
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Puck
4
- VERSION = '1.0.0.pre1'.freeze
4
+ VERSION = '1.0.0.pre2'.freeze
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puck
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.pre1
4
+ version: 1.0.0.pre2
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-19 00:00:00.000000000 Z
12
+ date: 2013-07-20 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Puck takes your app and packs it along with all your gems and a complete JRuby runtime in a standalone Jar file that can be run with just `java -jar …`
15
15
  email:
@@ -53,3 +53,4 @@ signing_key:
53
53
  specification_version: 3
54
54
  summary: Packs your JRuby app as a standalone Jar file
55
55
  test_files: []
56
+ has_rdoc: