puck 1.0.0-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: