puck 1.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1d3c8ed8c414ffb5241dd8dd7b903686ea9d1bf5
4
+ data.tar.gz: 67e2972eaafcac0792998786d3d65b96942dc4f2
5
+ SHA512:
6
+ metadata.gz: 32db0d6f29e15a77dc05cb24078c18333c1bf2de228ee1bf8b5fcd113c1eab0c1a4308d972411b6690e1f6da2f2b828376e704d94eba27e63cdcc0c4a20b89cd
7
+ data.tar.gz: 9fd222f28c53f4d6f61a4532b14d56cbd077d09efccdd68b05a334f891084e930cf541ac6e97d989bf4d6e0fe6637d8d6b0fe0daa50f8f59e82c52e1b0fa3fe9
@@ -0,0 +1,4 @@
1
+ --no-private
2
+ --markup markdown
3
+ lib/**/*.rb
4
+ -- README
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'puck'
4
+
5
+
6
+ Puck::Jar.new(Puck::Configuration.get).create
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+
3
+ module Puck
4
+ PuckError = Class.new(StandardError)
5
+ GemNotFoundError = Class.new(PuckError)
6
+ end
7
+
8
+ require 'puck/configuration'
9
+ require 'puck/dependency_resolver'
10
+ require 'puck/jar'
@@ -0,0 +1,12 @@
1
+ if ARGV.any?
2
+ file_name = ARGV.shift
3
+ PUCK_BIN_PATH.each do |dir|
4
+ relative_path = File.join(dir, file_name)
5
+ if File.exists?("classpath:/#{relative_path}")
6
+ $0 = relative_path
7
+ load(relative_path)
8
+ return
9
+ end
10
+ end
11
+ abort(%(No "#{file_name}" in #{PUCK_BIN_PATH.join(File::PATH_SEPARATOR)}))
12
+ end
@@ -0,0 +1,52 @@
1
+ # encoding: utf-8
2
+
3
+ require 'optparse'
4
+
5
+
6
+ module Puck
7
+ # @private
8
+ class Configuration
9
+ def initialize(defaults={})
10
+ @argv = defaults[:argv] || ARGV
11
+ end
12
+
13
+ def self.get(defaults={})
14
+ new(defaults).get
15
+ end
16
+
17
+ def get
18
+ command_line_options
19
+ end
20
+
21
+ private
22
+
23
+ SCALAR_ARGS = [:app_name, :app_dir, :build_dir, :jruby_complete].freeze
24
+ LIST_ARGS = [:extra_files].freeze
25
+ ARG_PREFIX = '--'.freeze
26
+
27
+ def command_line_options
28
+ state = nil
29
+ option = nil
30
+ @argv.each_with_object({}) do |arg, options|
31
+ if arg.start_with?(ARG_PREFIX)
32
+ option = arg.sub(/^--/, '').gsub('-', '_').to_sym
33
+ if LIST_ARGS.include?(option)
34
+ options[option] = []
35
+ state = :list
36
+ else
37
+ state = :scalar
38
+ end
39
+ else
40
+ case state
41
+ when :list
42
+ options[option] << arg
43
+ when :scalar
44
+ options[option] = arg
45
+ option = nil
46
+ state = nil
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,75 @@
1
+ require 'stringio'
2
+ require 'bundler'
3
+
4
+ module Puck
5
+ # @private
6
+ class DependencyResolver
7
+ def resolve_gem_dependencies(options = {})
8
+ gem_home = options[:gem_home] || ENV['GEM_HOME']
9
+ gemfile = options[:gemfile] || File.expand_path('Gemfile', options[:app_dir] || Dir.pwd)
10
+ lockfile = options[:lockfile] || "#{gemfile}.lock"
11
+ groups = options[:gem_groups] || [:default]
12
+
13
+ bundler_specs = contained_bundler(gem_home, gemfile, lockfile, groups)
14
+ bundler_specs.delete_if { |spec| spec[:name] == 'bundler' }
15
+ bundler_specs.map do |spec|
16
+ base_path = spec[:full_gem_path].chomp('/')
17
+ load_paths = spec[:load_paths].map do |load_path|
18
+ unless load_path.start_with?(base_path)
19
+ raise PuckError, 'Unsupported load path "%s" in gem "%s"' % [load_path, bundler_spec.name]
20
+ end
21
+ load_path[base_path.size + 1, load_path.length - base_path.size - 1]
22
+ end
23
+ {
24
+ :name => spec[:name],
25
+ :versioned_name => spec[:full_name],
26
+ :base_path => base_path,
27
+ :load_paths => load_paths,
28
+ :bin_path => spec[:bindir],
29
+ }
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def contained_bundler(gem_home, gemfile, lockfile, groups)
36
+ Bundler.with_clean_env do
37
+ scripting_container = Java::OrgJrubyEmbed::ScriptingContainer.new(Java::OrgJrubyEmbed::LocalContextScope::SINGLETHREAD)
38
+ scripting_container.compat_version = Java::OrgJruby::CompatVersion::RUBY1_9
39
+ scripting_container.current_directory = Dir.pwd
40
+ scripting_container.environment = Hash[ENV.merge('GEM_HOME' => gem_home).map { |k,v| [k.to_java, v.to_java] }]
41
+ scripting_container.put('arguments', Marshal.dump([gemfile, lockfile, groups]).to_java_bytes)
42
+ begin
43
+ line = __LINE__ + 1 # as __LINE__ represents next statement line i JRuby, and that becomes difficult to offset
44
+ unit = scripting_container.parse(StringIO.new(<<-"EOS").to_inputstream, __FILE__, line)
45
+ begin
46
+ require 'bundler'
47
+ gemfile, lockfile, groups = Marshal.load(String.from_java_bytes(arguments))
48
+ definition = Bundler::Definition.build(gemfile, lockfile, false)
49
+ ENV['BUNDLE_WITHOUT'] = (definition.groups - groups).join(':')
50
+ specs = definition.specs.map do |gem_spec|
51
+ {
52
+ :name => gem_spec.name,
53
+ :full_name => gem_spec.full_name,
54
+ :full_gem_path => gem_spec.full_gem_path,
55
+ :load_paths => gem_spec.load_paths,
56
+ :bindir => gem_spec.bindir,
57
+ }
58
+ end
59
+ Marshal.dump([specs]).to_java_bytes
60
+ rescue => e
61
+ Marshal.dump([nil, e.class, e.message, e.backtrace]).to_java_bytes
62
+ end
63
+ EOS
64
+ result, error, message, backtrace = Marshal.load(String.from_java_bytes(unit.run))
65
+ if error
66
+ raise error, message, Array(backtrace)+caller
67
+ end
68
+ result
69
+ ensure
70
+ scripting_container.terminate
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,168 @@
1
+ # encoding: utf-8
2
+
3
+ require 'fileutils'
4
+ require 'tmpdir'
5
+ require 'pathname'
6
+ require 'set'
7
+ require 'ant'
8
+ require 'puck/version'
9
+
10
+ begin
11
+ require 'jruby-jars'
12
+ rescue LoadError
13
+ end
14
+
15
+ module Puck
16
+ # Creates a standalone Jar file from your application.
17
+ #
18
+ # The Jar will contain your application code (which is assumed to be in the
19
+ # "lib" directory), bin files (assumed to be in the "bin" directory), all the
20
+ # gems in your default group (i.e. those that are not in a `group` block in
21
+ # your Gemfile), including gems loaded from git, or from a path. It will also
22
+ # contain a JRuby runtime so that to run it you only need a Java runtime.
23
+ #
24
+ # The Jar file will be configured so that you can run your application's bin
25
+ # files by passing their name as the first argument after the Jar file (see example below).
26
+ #
27
+ # @example Creating a Jar from a Rake task
28
+ # task :jar do
29
+ # Puck::Jar.new.create
30
+ # end
31
+ #
32
+ # @example Configuring the Jar file
33
+ # task :jar do
34
+ # jar = Puck::Jar.new(
35
+ # extra_files: Dir['config/*.yml'],
36
+ # jruby_complete: 'build/custom-jruby-complete.jar'
37
+ # )
38
+ # jar.create
39
+ # end
40
+ #
41
+ # @example Running a bin file
42
+ # java -jar path/to/application.jar my-bin-file arg1 arg2
43
+ #
44
+ class Jar
45
+ # Create a new instance with the specified configuration.
46
+ #
47
+ # Puck tries to use sane defaults like assuming that the application name
48
+ # is the same as the name of the directory containing the "lib" directory.
49
+ #
50
+ # @param [Hash] configuration
51
+ # @option configuration [String] :extra_files a list of files to include in
52
+ # the Jar. The paths must be below the `:app_dir`.
53
+ # @option configuration [String] :gem_groups ([:default]) a list of gem
54
+ # groups to include in the Jar. Remember to include the default group if
55
+ # you override this option.
56
+ # @option configuration [String] :jruby_complete a path to the
57
+ # `jruby-complete.jar` that you want to use. If you don't specify this
58
+ # option you need to have `jruby-jars` in your `Gemfile` (it contains
59
+ # the equivalent of `jruby-complete.jar`. This option is mostly useful
60
+ # when you have a customized JRuby runtime that you want to use.
61
+ # @option configuration [String] :app_dir (Dir.pwd)
62
+ # the application's base directory (i.e. the directory that contains the
63
+ # "lib" directory)
64
+ # @option configuration [String] :app_name (File.basename(configuration[:app_dir]))
65
+ # the name of the application, primarily used to name the Jar
66
+ # @option configuration [String] :build_dir ("build") the directory where
67
+ # the Jar file will be created
68
+ #
69
+ def initialize(configuration={})
70
+ @configuration = configuration.dup
71
+ @configuration[:app_dir] ||= Dir.pwd
72
+ @configuration[:app_name] ||= File.basename(@configuration[:app_dir])
73
+ @configuration[:build_dir] ||= File.join(@configuration[:app_dir], 'build')
74
+ @configuration[:jar_name] ||= @configuration[:app_name] + '.jar'
75
+ @configuration[:gem_groups] ||= [:default]
76
+ @dependency_resolver = @configuration[:dependency_resolver] || DependencyResolver.new
77
+ end
78
+
79
+ # Create the Jar file using the instance's configuration.
80
+ #
81
+ # @return The path to the Jar file
82
+ #
83
+ def create
84
+ FileUtils.mkdir_p(@configuration[:build_dir])
85
+
86
+ Dir.mktmpdir do |tmp_dir|
87
+ output_path = File.join(@configuration[:build_dir], @configuration[:jar_name])
88
+ project_dir = Pathname.new(@configuration[:app_dir]).expand_path.cleanpath
89
+ extra_files = @configuration[:extra_files] || []
90
+ jruby_complete_path = @configuration[:jruby_complete]
91
+
92
+ if !(defined? JRubyJars) && !(jruby_complete_path && File.exists?(jruby_complete_path))
93
+ raise PuckError, 'Cannot build Jar: jruby-jars must be installed, or :jruby_complete must be specified'
94
+ end
95
+
96
+ gem_dependencies = @dependency_resolver.resolve_gem_dependencies(@configuration)
97
+ create_jar_bootstrap!(tmp_dir, gem_dependencies)
98
+
99
+ ant = Ant.new(output_level: 1)
100
+ ant.jar(destfile: output_path) do
101
+ manifest do
102
+ attribute name: 'Main-Class', value: 'org.jruby.JarBootstrapMain'
103
+ attribute name: 'Created-By', value: "Puck v#{Puck::VERSION}"
104
+ end
105
+
106
+ zipfileset dir: tmp_dir, includes: 'jar-bootstrap.rb'
107
+
108
+ if jruby_complete_path
109
+ zipfileset src: jruby_complete_path
110
+ else
111
+ zipfileset src: JRubyJars.core_jar_path
112
+ zipfileset src: JRubyJars.stdlib_jar_path
113
+ end
114
+
115
+ %w[bin lib].each do |sub_dir|
116
+ path = project_dir + sub_dir
117
+ if File.exists?(path)
118
+ zipfileset dir: path, prefix: File.join(JAR_APP_HOME, sub_dir)
119
+ end
120
+ end
121
+
122
+ extra_files.each do |ef|
123
+ path = Pathname.new(ef).expand_path.cleanpath
124
+ prefix = File.join(JAR_APP_HOME, path.relative_path_from(project_dir).dirname.to_s)
125
+ zipfileset dir: path.dirname, prefix: prefix, includes: path.basename
126
+ end
127
+
128
+ gem_dependencies.each do |spec|
129
+ base_path = Pathname.new(spec[:base_path]).expand_path.cleanpath
130
+ unless project_dir == base_path
131
+ zipfileset dir: spec[:base_path], prefix: File.join(JAR_GEM_HOME, spec[:versioned_name])
132
+ end
133
+ end
134
+ end
135
+
136
+ output_path
137
+ end
138
+ end
139
+
140
+ # @deprecated Use #create
141
+ def create!
142
+ create
143
+ end
144
+
145
+ private
146
+
147
+ JAR_APP_HOME = 'META-INF/app.home'.freeze
148
+ JAR_GEM_HOME = 'META-INF/gem.home'.freeze
149
+ JAR_JRUBY_HOME = 'META-INF/jruby.home'.freeze
150
+
151
+ def create_jar_bootstrap!(tmp_dir, gem_dependencies)
152
+ File.open(File.join(tmp_dir, 'jar-bootstrap.rb'), 'w') do |io|
153
+ io.puts(%(PUCK_BIN_PATH = ['#{JAR_APP_HOME}/bin', '#{JAR_JRUBY_HOME}/bin']))
154
+ gem_dependencies.each do |spec|
155
+ io.puts("PUCK_BIN_PATH << '#{JAR_GEM_HOME}/#{spec[:versioned_name]}/#{spec[:bin_path]}'")
156
+ end
157
+ io.puts
158
+ gem_dependencies.each do |spec|
159
+ spec[:load_paths].each do |load_path|
160
+ io.puts(%($LOAD_PATH << 'classpath:#{JAR_GEM_HOME}/#{spec[:versioned_name]}/#{load_path}'))
161
+ end
162
+ end
163
+ io.puts
164
+ io.puts(File.read(File.expand_path('../bootstrap.rb', __FILE__)))
165
+ end
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,5 @@
1
+ # encoding: utf-8
2
+
3
+ module Puck
4
+ VERSION = '1.0.0'.freeze
5
+ end
metadata ADDED
@@ -0,0 +1,54 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: puck
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: java
6
+ authors:
7
+ - Theo Hultberg
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-12 00:00:00.000000000 Z
12
+ dependencies: []
13
+ 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 …`
14
+ email:
15
+ - theo@iconara.net
16
+ executables:
17
+ - puck
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - .yardopts
22
+ - bin/puck
23
+ - lib/puck.rb
24
+ - lib/puck/bootstrap.rb
25
+ - lib/puck/configuration.rb
26
+ - lib/puck/dependency_resolver.rb
27
+ - lib/puck/jar.rb
28
+ - lib/puck/version.rb
29
+ homepage: http://github.com/iconara/puck
30
+ licenses:
31
+ - Apache License 2.0
32
+ metadata: {}
33
+ post_install_message:
34
+ rdoc_options: []
35
+ require_paths:
36
+ - lib
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ required_rubygems_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ requirements: []
48
+ rubyforge_project: puck
49
+ rubygems_version: 2.2.2
50
+ signing_key:
51
+ specification_version: 4
52
+ summary: Packs your JRuby app as a standalone Jar file
53
+ test_files: []
54
+ has_rdoc: