furoshiki 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/.ruby-version +1 -1
- data/Gemfile +0 -1
- data/Rakefile +5 -0
- data/furoshiki.gemspec +1 -1
- data/lib/furoshiki/configuration.rb +142 -0
- data/lib/furoshiki/jar.rb +41 -0
- data/lib/furoshiki/jar_app.rb +225 -0
- data/lib/furoshiki/util.rb +27 -0
- data/lib/furoshiki/validator.rb +42 -0
- data/lib/furoshiki/version.rb +1 -1
- data/lib/furoshiki/warbler_extensions.rb +12 -0
- data/lib/furoshiki.rb +4 -3
- data/lib/warbler/traits/furoshiki.rb +31 -0
- data/spec/{shoes/swt_app_spec.rb → app_spec.rb} +29 -22
- data/spec/configuration_spec.rb +12 -0
- data/spec/fixtures/config.yaml +1 -0
- data/spec/{shoes → fixtures}/test_app/app.yaml +0 -0
- data/spec/{shoes → fixtures}/test_app/bin/hello_world +0 -0
- data/spec/{shoes → fixtures}/test_app/dir_to_ignore/file_to_ignore.txt +0 -0
- data/spec/{shoes → fixtures}/test_app/img/boots.icns +0 -0
- data/spec/{shoes → fixtures}/test_app/img/boots.ico +0 -0
- data/spec/{shoes → fixtures}/test_app/img/boots_512x512x32.png +0 -0
- data/spec/{shoes → fixtures}/test_app/sibling.rb +0 -0
- data/spec/fixtures/test_project/bin/hello.rb +1 -0
- data/spec/fixtures/test_project/dir_to_ignore/file_to_ignore.txt +1 -0
- data/spec/{shoes/swt_jar_spec.rb → jar_spec.rb} +25 -12
- data/spec/spec_helper.rb +51 -0
- data/spec/support/shared_config.rb +19 -0
- data/spec/support/shared_zip.rb +1 -1
- data/spec/util_spec.rb +57 -0
- metadata +73 -45
- data/lib/furoshiki/shoes/configuration.rb +0 -184
- data/lib/furoshiki/shoes/swt_app.rb +0 -230
- data/lib/furoshiki/shoes/swt_jar.rb +0 -67
- data/lib/furoshiki/shoes.rb +0 -15
- data/lib/warbler/traits/shoes.rb +0 -51
- data/spec/shoes/configuration_spec.rb +0 -198
- data/spec/shoes/spec_helper.rb +0 -70
- data/spec/shoes/support/shared_config.rb +0 -8
@@ -1,184 +0,0 @@
|
|
1
|
-
require 'pathname'
|
2
|
-
require 'yaml'
|
3
|
-
|
4
|
-
module Furoshiki
|
5
|
-
module Shoes
|
6
|
-
# Configuration for Shoes packagers.
|
7
|
-
#
|
8
|
-
# @example
|
9
|
-
# config_file = '/path/to/app.yaml'
|
10
|
-
# config = Shoes::Package::Configuration.load(config_file)
|
11
|
-
#
|
12
|
-
# If your configuration uses hashes, the keys will always be
|
13
|
-
# symbols, even if you have created it with string keys. It's just
|
14
|
-
# easier that way.
|
15
|
-
#
|
16
|
-
# This is a value object. If you need to modify your configuration
|
17
|
-
# after initialization, dump it with #to_hash, make your changes,
|
18
|
-
# and instantiate a new object.
|
19
|
-
class Configuration
|
20
|
-
# Convenience method for loading config from a file. Note that you
|
21
|
-
# can pass four kinds of paths to the loader. Given the following
|
22
|
-
# file structure:
|
23
|
-
#
|
24
|
-
# ├── a
|
25
|
-
# │ ├── app.yaml
|
26
|
-
# │ └── shoes-app-a.rb
|
27
|
-
# └── b
|
28
|
-
# └── shoes-app-b.rb
|
29
|
-
#
|
30
|
-
# To package an app that has an `app.yaml`, like `shoes-app-a.rb`,
|
31
|
-
# you can call the loader with any of:
|
32
|
-
#
|
33
|
-
# - a/app.yaml
|
34
|
-
# - a
|
35
|
-
# - a/shoes-app-a.rb
|
36
|
-
#
|
37
|
-
# These will all find and use your configuration in `a/app.yaml`.
|
38
|
-
# To package an app that does not have an `app.yaml`, like
|
39
|
-
# `b/shoes-app-b.rb`, you must call the loader with the path of
|
40
|
-
# the script itself. Note that without an `app.yaml`, you will
|
41
|
-
# only bundle a single file, and your app will simply use the
|
42
|
-
# Shoes app icon.
|
43
|
-
#
|
44
|
-
# @overload load(path)
|
45
|
-
# @param [String] path location of the app's 'app.yaml'
|
46
|
-
# @overload load(path)
|
47
|
-
# @param [String] path location of the directory that
|
48
|
-
# contains the app's 'app.yaml'
|
49
|
-
# @overload load(path)
|
50
|
-
# @param [String] path location of the app
|
51
|
-
def self.load(path = 'app.yaml')
|
52
|
-
pathname = Pathname.new(path)
|
53
|
-
app_yaml = Pathname.new('app.yaml')
|
54
|
-
|
55
|
-
dummy_file = Struct.new(:read)
|
56
|
-
|
57
|
-
if pathname.basename == app_yaml
|
58
|
-
file, dir = pathname, pathname.dirname
|
59
|
-
elsif pathname.directory?
|
60
|
-
file, dir = pathname.join(app_yaml), pathname
|
61
|
-
elsif pathname.file? && pathname.parent.children.include?(pathname.parent.join app_yaml)
|
62
|
-
file, dir = pathname.parent.join(app_yaml), pathname.parent
|
63
|
-
else
|
64
|
-
# Can't find any 'app.yaml', so assume we just want to wrap
|
65
|
-
# this file. If it exists, load default options. If not, let
|
66
|
-
# the filesystem raise an error.
|
67
|
-
default_options = {
|
68
|
-
run: pathname.basename.to_s,
|
69
|
-
name: pathname.basename(pathname.extname).to_s.gsub(/\W/, '-')
|
70
|
-
}.to_yaml
|
71
|
-
options = pathname.exist? ? default_options : pathname
|
72
|
-
file = dummy_file.new(options)
|
73
|
-
dir = pathname.parent
|
74
|
-
end
|
75
|
-
config = YAML.load(file.read)
|
76
|
-
config[:working_dir] = dir
|
77
|
-
new(config)
|
78
|
-
end
|
79
|
-
|
80
|
-
# @param [Hash] config user options
|
81
|
-
# @param [String] working_dir directory in which do packaging work
|
82
|
-
def initialize(config = {})
|
83
|
-
defaults = {
|
84
|
-
name: 'Shoes App',
|
85
|
-
version: '0.0.0',
|
86
|
-
release: 'Rookie',
|
87
|
-
run: nil,
|
88
|
-
ignore: 'pkg',
|
89
|
-
icons: {
|
90
|
-
#osx: 'path/to/default/App.icns',
|
91
|
-
#gtk: 'path/to/default/app.png',
|
92
|
-
#win32: 'path/to/default/App.ico',
|
93
|
-
},
|
94
|
-
dmg: {
|
95
|
-
ds_store: 'path/to/default/.DS_Store',
|
96
|
-
background: 'path/to/default/background.png'
|
97
|
-
},
|
98
|
-
working_dir: Dir.pwd
|
99
|
-
}
|
100
|
-
|
101
|
-
# Overwrite defaults with supplied config
|
102
|
-
@config = config.inject(defaults) { |c, (k, v)| set_symbol_key c, k, v }
|
103
|
-
|
104
|
-
# Ensure that we always have what we need
|
105
|
-
[:ignore, :gems].each { |k| @config[k] = Array(@config[k]) }
|
106
|
-
@config[:gems] << 'shoes'
|
107
|
-
@config[:working_dir] = Pathname.new(@config[:working_dir])
|
108
|
-
|
109
|
-
# Define reader for each key (#shortname defined below)
|
110
|
-
metaclass = class << self; self; end
|
111
|
-
@config.keys.reject {|k| k == :shortname}.each do |k|
|
112
|
-
metaclass.send(:define_method, k) do
|
113
|
-
@config[k]
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
@errors = []
|
118
|
-
end
|
119
|
-
|
120
|
-
def shortname
|
121
|
-
@config[:shortname] || @config[:name].downcase.gsub(/\W+/, '')
|
122
|
-
end
|
123
|
-
|
124
|
-
def to_hash
|
125
|
-
@config
|
126
|
-
end
|
127
|
-
|
128
|
-
def validate
|
129
|
-
unless @config[:run] && working_dir.join(@config[:run]).exist?
|
130
|
-
add_missing_file_error(@config[:run], "Run file")
|
131
|
-
end
|
132
|
-
|
133
|
-
if @config[:icons][:osx] && !working_dir.join(@config[:icons][:osx]).exist?
|
134
|
-
add_missing_file_error(@config[:icons][:osx], "OS X icon file")
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
def valid?
|
139
|
-
validate
|
140
|
-
return errors.empty?
|
141
|
-
end
|
142
|
-
|
143
|
-
def errors
|
144
|
-
@errors.dup
|
145
|
-
end
|
146
|
-
|
147
|
-
def error_message_list
|
148
|
-
@errors.map {|m| " - #{m}"}.join("\n")
|
149
|
-
end
|
150
|
-
|
151
|
-
def ==(other)
|
152
|
-
super unless other.class == self.class && other.respond_to?(:to_hash)
|
153
|
-
@config == other.to_hash &&
|
154
|
-
working_dir == other.working_dir &&
|
155
|
-
errors == other.errors
|
156
|
-
end
|
157
|
-
|
158
|
-
private
|
159
|
-
# Ensure symbol keys, even in nested hashes
|
160
|
-
#
|
161
|
-
# @param [Hash] config the hash to set (key: value) on
|
162
|
-
# @param [#to_sym] k the key
|
163
|
-
# @param [Object] v the value
|
164
|
-
# @return [Hash] an updated hash
|
165
|
-
def set_symbol_key(config, k, v)
|
166
|
-
if v.kind_of? Hash
|
167
|
-
config[k.to_sym] = v.inject({}) { |hash, (k, v)| set_symbol_key(hash, k, v) }
|
168
|
-
else
|
169
|
-
config[k.to_sym] = v
|
170
|
-
end
|
171
|
-
config
|
172
|
-
end
|
173
|
-
|
174
|
-
def add_error(message)
|
175
|
-
@errors << message
|
176
|
-
end
|
177
|
-
|
178
|
-
def add_missing_file_error(value, description)
|
179
|
-
message = "#{description} configured as '#{value}', but couldn't find file at #{working_dir.join(value.to_s)}"
|
180
|
-
add_error(message)
|
181
|
-
end
|
182
|
-
end
|
183
|
-
end
|
184
|
-
end
|
@@ -1,230 +0,0 @@
|
|
1
|
-
require 'furoshiki/exceptions'
|
2
|
-
require 'furoshiki/shoes/configuration'
|
3
|
-
require 'furoshiki/zip/directory'
|
4
|
-
require 'furoshiki/shoes/swt_jar'
|
5
|
-
require 'fileutils'
|
6
|
-
require 'plist'
|
7
|
-
require 'open-uri'
|
8
|
-
require 'net/http'
|
9
|
-
|
10
|
-
module Furoshiki
|
11
|
-
module Shoes
|
12
|
-
class SwtApp
|
13
|
-
include FileUtils
|
14
|
-
|
15
|
-
REMOTE_TEMPLATE_URL = 'https://s3.amazonaws.com/net.wasnotrice.shoes/wrappers/shoes-app-template-0.0.1.zip'
|
16
|
-
|
17
|
-
# @param [Shoes::Package::Configuration] config user configuration
|
18
|
-
def initialize(config)
|
19
|
-
@config = config
|
20
|
-
|
21
|
-
unless config.valid?
|
22
|
-
raise Furoshiki::ConfigurationError, "Invalid configuration.\n#{config.error_message_list}"
|
23
|
-
end
|
24
|
-
|
25
|
-
home = ENV['FUROSHIKI_HOME'] || Dir.home
|
26
|
-
@cache_dir = Pathname.new(home).join('.furoshiki', 'cache')
|
27
|
-
@default_package_dir = working_dir.join('pkg')
|
28
|
-
@package_dir = default_package_dir
|
29
|
-
@default_template_path = cache_dir.join(template_filename)
|
30
|
-
@template_path = default_template_path
|
31
|
-
@tmp = @package_dir.join('tmp')
|
32
|
-
end
|
33
|
-
|
34
|
-
# @return [Pathname] default package directory: ./pkg
|
35
|
-
attr_reader :default_package_dir
|
36
|
-
|
37
|
-
# @return [Pathname] package directory
|
38
|
-
attr_accessor :package_dir
|
39
|
-
|
40
|
-
# @return [Pathname] default path to .app template
|
41
|
-
attr_reader :default_template_path
|
42
|
-
|
43
|
-
# @return [Pathname] path to .app template
|
44
|
-
attr_accessor :template_path
|
45
|
-
|
46
|
-
# @return [Pathname] cache directory
|
47
|
-
attr_reader :cache_dir
|
48
|
-
|
49
|
-
attr_reader :config
|
50
|
-
|
51
|
-
attr_reader :tmp
|
52
|
-
|
53
|
-
def package
|
54
|
-
remove_tmp
|
55
|
-
create_tmp
|
56
|
-
cache_template
|
57
|
-
extract_template
|
58
|
-
inject_icon
|
59
|
-
inject_config
|
60
|
-
jar_path = ensure_jar_exists
|
61
|
-
inject_jar jar_path
|
62
|
-
move_to_package_dir tmp_app_path
|
63
|
-
tweak_permissions
|
64
|
-
rescue => e
|
65
|
-
raise e
|
66
|
-
ensure
|
67
|
-
remove_tmp
|
68
|
-
end
|
69
|
-
|
70
|
-
def create_tmp
|
71
|
-
tmp.mkpath
|
72
|
-
end
|
73
|
-
|
74
|
-
def remove_tmp
|
75
|
-
tmp.rmtree if tmp.exist?
|
76
|
-
end
|
77
|
-
|
78
|
-
def cache_template
|
79
|
-
cache_dir.mkpath unless cache_dir.exist?
|
80
|
-
download_template unless template_path.size?
|
81
|
-
end
|
82
|
-
|
83
|
-
def template_basename
|
84
|
-
'shoes-app-template'
|
85
|
-
end
|
86
|
-
|
87
|
-
def template_extension
|
88
|
-
'.zip'
|
89
|
-
end
|
90
|
-
|
91
|
-
def template_filename
|
92
|
-
"#{template_basename}#{template_extension}"
|
93
|
-
end
|
94
|
-
|
95
|
-
def latest_template_version
|
96
|
-
'0.0.1'
|
97
|
-
end
|
98
|
-
|
99
|
-
def download_template
|
100
|
-
download remote_template_url, template_path
|
101
|
-
end
|
102
|
-
|
103
|
-
def download(remote_url, local_path)
|
104
|
-
download_following_redirects remote_url, local_path
|
105
|
-
end
|
106
|
-
|
107
|
-
def download_following_redirects(remote_url, local_path, redirect_limit = 5)
|
108
|
-
if redirect_limit == 0
|
109
|
-
raise Furoshiki::DownloadError,
|
110
|
-
"Too many redirects trying to reach #{remote_url}"
|
111
|
-
end
|
112
|
-
|
113
|
-
uri = URI(remote_url)
|
114
|
-
Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
|
115
|
-
request = Net::HTTP::Get.new(uri.request_uri)
|
116
|
-
http.request request do |response|
|
117
|
-
case response
|
118
|
-
when Net::HTTPSuccess then
|
119
|
-
warn "Downloading #{remote_url} to #{local_path}"
|
120
|
-
open(local_path, 'wb') do |file|
|
121
|
-
response.read_body do |chunk|
|
122
|
-
file.write chunk
|
123
|
-
end
|
124
|
-
end
|
125
|
-
when Net::HTTPRedirection then
|
126
|
-
location = response['location']
|
127
|
-
warn "Redirected to #{location}"
|
128
|
-
download_following_redirects(location, local_path, redirect_limit - 1)
|
129
|
-
else
|
130
|
-
raise Furoshiki::DownloadError, "Couldn't download app template at #{remote_url}. #{response.value}"
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
def downloads_url
|
137
|
-
"http://shoesrb.com/downloads"
|
138
|
-
end
|
139
|
-
|
140
|
-
def remote_template_url
|
141
|
-
#"#{downloads_url}/#{template_basename}-#{latest_template_version}#{template_extension}"
|
142
|
-
REMOTE_TEMPLATE_URL
|
143
|
-
end
|
144
|
-
|
145
|
-
def move_to_package_dir(path)
|
146
|
-
dest = package_dir.join(path.basename)
|
147
|
-
dest.rmtree if dest.exist?
|
148
|
-
mv path.to_s, dest
|
149
|
-
end
|
150
|
-
|
151
|
-
def ensure_jar_exists
|
152
|
-
jar = SwtJar.new(@config)
|
153
|
-
path = tmp.join(jar.filename)
|
154
|
-
jar.package(tmp) unless File.exist?(path)
|
155
|
-
path
|
156
|
-
end
|
157
|
-
|
158
|
-
# Injects JAR into APP. The JAR should be the only item in the
|
159
|
-
# Contents/Java directory. If this directory contains more than one
|
160
|
-
# JAR, the "first" one gets run, which may not be what we want.
|
161
|
-
#
|
162
|
-
# @param [Pathname, String] jar_path the location of the JAR to inject
|
163
|
-
def inject_jar(jar_path)
|
164
|
-
jar_dir = tmp_app_path.join('Contents/Java')
|
165
|
-
jar_dir.rmtree
|
166
|
-
jar_dir.mkdir
|
167
|
-
cp Pathname.new(jar_path), jar_dir
|
168
|
-
end
|
169
|
-
|
170
|
-
def extract_template
|
171
|
-
raise IOError, "Couldn't find app template at #{template_path}." unless template_path.size?
|
172
|
-
extracted_app = nil
|
173
|
-
|
174
|
-
::Zip::File.open(template_path) do |zip_file|
|
175
|
-
zip_file.each do |entry|
|
176
|
-
extracted_app = template_path.join(entry.name) if Pathname.new(entry.name).extname == '.app'
|
177
|
-
p = tmp.join(entry.name)
|
178
|
-
p.dirname.mkpath
|
179
|
-
entry.extract(p)
|
180
|
-
end
|
181
|
-
end
|
182
|
-
mv tmp.join(extracted_app.basename.to_s), tmp_app_path
|
183
|
-
end
|
184
|
-
|
185
|
-
def inject_config
|
186
|
-
plist = tmp_app_path.join 'Contents/Info.plist'
|
187
|
-
template = Plist.parse_xml(plist)
|
188
|
-
template['CFBundleIdentifier'] = "com.hackety.shoes.#{config.shortname}"
|
189
|
-
template['CFBundleDisplayName'] = config.name
|
190
|
-
template['CFBundleName'] = config.name
|
191
|
-
template['CFBundleVersion'] = config.version
|
192
|
-
template['CFBundleIconFile'] = Pathname.new(config.icons[:osx]).basename.to_s if config.icons[:osx]
|
193
|
-
File.open(plist, 'w') { |f| f.write template.to_plist }
|
194
|
-
end
|
195
|
-
|
196
|
-
def inject_icon
|
197
|
-
if config.icons[:osx]
|
198
|
-
icon_path = working_dir.join(config.icons[:osx])
|
199
|
-
raise IOError, "Couldn't find app icon at #{icon_path}" unless icon_path.exist?
|
200
|
-
resources_dir = tmp_app_path.join('Contents/Resources')
|
201
|
-
cp icon_path, resources_dir.join(icon_path.basename)
|
202
|
-
end
|
203
|
-
end
|
204
|
-
|
205
|
-
def tweak_permissions
|
206
|
-
executable_path.chmod 0755
|
207
|
-
end
|
208
|
-
|
209
|
-
def app_name
|
210
|
-
"#{config.name}.app"
|
211
|
-
end
|
212
|
-
|
213
|
-
def tmp_app_path
|
214
|
-
tmp.join app_name
|
215
|
-
end
|
216
|
-
|
217
|
-
def app_path
|
218
|
-
package_dir.join app_name
|
219
|
-
end
|
220
|
-
|
221
|
-
def executable_path
|
222
|
-
app_path.join('Contents/MacOS/JavaAppLauncher')
|
223
|
-
end
|
224
|
-
|
225
|
-
def working_dir
|
226
|
-
config.working_dir
|
227
|
-
end
|
228
|
-
end
|
229
|
-
end
|
230
|
-
end
|
@@ -1,67 +0,0 @@
|
|
1
|
-
require 'furoshiki/shoes/configuration'
|
2
|
-
require 'warbler'
|
3
|
-
require 'warbler/traits/shoes'
|
4
|
-
|
5
|
-
module Furoshiki
|
6
|
-
module Shoes
|
7
|
-
class SwtJar
|
8
|
-
# @param [Furoshiki::Shoes::Configuration] config user configuration
|
9
|
-
def initialize(config = nil)
|
10
|
-
@shoes_config = config || Furoshiki::Shoes::Configuration.load
|
11
|
-
|
12
|
-
unless config.valid?
|
13
|
-
raise Furoshiki::ConfigurationError, "Invalid configuration.\n#{config.error_message_list}"
|
14
|
-
end
|
15
|
-
|
16
|
-
Dir.chdir working_dir do
|
17
|
-
@config = Warbler::Config.new do |config|
|
18
|
-
config.jar_name = @shoes_config.shortname
|
19
|
-
config.pathmaps.application = ['shoes-app/%p']
|
20
|
-
specs = @shoes_config.gems.map { |g| Gem::Specification.find_by_name(g) }
|
21
|
-
dependencies = specs.map { |s| s.runtime_dependencies }.flatten
|
22
|
-
(specs + dependencies).uniq.each { |g| config.gems << g }
|
23
|
-
ignore = @shoes_config.ignore.map do |f|
|
24
|
-
path = f.to_s
|
25
|
-
children = Dir.glob("#{path}/**/*") if File.directory?(path)
|
26
|
-
[path, *children]
|
27
|
-
end.flatten
|
28
|
-
config.excludes.add FileList.new(ignore.flatten).pathmap(config.pathmaps.application.first)
|
29
|
-
config.gem_excludes += [/^samples/, /^examples/, /^test/, /^spec/]
|
30
|
-
end
|
31
|
-
@config.extend ShoesWarblerConfig
|
32
|
-
@config.run = @shoes_config.run.split(/\s/).first
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def package(dir = default_dir)
|
37
|
-
Dir.chdir working_dir do
|
38
|
-
jar = Warbler::Jar.new
|
39
|
-
jar.apply @config
|
40
|
-
package_dir = dir.relative_path_from(working_dir)
|
41
|
-
package_dir.mkpath
|
42
|
-
path = package_dir.join(filename).to_s
|
43
|
-
jar.create path
|
44
|
-
File.expand_path path
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def default_dir
|
49
|
-
working_dir.join 'pkg'
|
50
|
-
end
|
51
|
-
|
52
|
-
def filename
|
53
|
-
"#{@config.jar_name}.#{@config.jar_extension}"
|
54
|
-
end
|
55
|
-
|
56
|
-
def working_dir
|
57
|
-
@shoes_config.working_dir
|
58
|
-
end
|
59
|
-
|
60
|
-
private
|
61
|
-
# Adds Shoes-specific functionality to the Warbler Config
|
62
|
-
module ShoesWarblerConfig
|
63
|
-
attr_accessor :run
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
data/lib/furoshiki/shoes.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
require 'furoshiki/shoes/swt_jar'
|
2
|
-
require 'furoshiki/shoes/swt_app'
|
3
|
-
|
4
|
-
module Furoshiki
|
5
|
-
module Shoes
|
6
|
-
def self.new(backend, wrapper, config)
|
7
|
-
class_name = class_name_for(backend, wrapper)
|
8
|
-
self.const_get(class_name).new(config)
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.class_name_for(backend, wrapper)
|
12
|
-
[backend, wrapper].map { |name| name.to_s.capitalize }.join
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
data/lib/warbler/traits/shoes.rb
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
require 'furoshiki/shoes/configuration'
|
2
|
-
|
3
|
-
module Warbler
|
4
|
-
module Traits
|
5
|
-
# Hack to control the executable
|
6
|
-
class NoGemspec
|
7
|
-
def update_archive(jar); end
|
8
|
-
end
|
9
|
-
|
10
|
-
class Shoes
|
11
|
-
include Trait
|
12
|
-
include PathmapHelper
|
13
|
-
|
14
|
-
def self.detect?
|
15
|
-
#File.exist? "app.yaml"
|
16
|
-
true
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.requires?(trait)
|
20
|
-
# Actually, it would be better to dump the NoGemspec trait, but since
|
21
|
-
# we can't do that, we can at least make sure that this trait gets
|
22
|
-
# processed later by declaring that it requires NoGemspec.
|
23
|
-
[Traits::Jar, Traits::NoGemspec].include? trait
|
24
|
-
end
|
25
|
-
|
26
|
-
def after_configure
|
27
|
-
config.init_contents << StringIO.new("require 'shoes'\nShoes.configuration.backend = :swt\n")
|
28
|
-
end
|
29
|
-
|
30
|
-
def update_archive(jar)
|
31
|
-
# Not sure why Warbler doesn't do this automatically
|
32
|
-
jar.files.delete_if { |k, v| @config.excludes.include? k }
|
33
|
-
add_main_rb(jar, apply_pathmaps(config, default_executable, :application))
|
34
|
-
end
|
35
|
-
|
36
|
-
# Uses the `@config.run` if it exists. Otherwise, looks in the
|
37
|
-
# application's `bin` directory for an executable with the same name as
|
38
|
-
# the jar. If this also fails, defaults to the first executable (alphabetically) in the
|
39
|
-
# applications `bin` directory.
|
40
|
-
#
|
41
|
-
# @return [String] filename of the executable to run
|
42
|
-
def default_executable
|
43
|
-
return @config.run if @config.run
|
44
|
-
exes = Dir['bin/*'].sort
|
45
|
-
exe = exes.grep(/#{config.jar_name}/).first || exes.first
|
46
|
-
raise "No executable script found" unless exe
|
47
|
-
exe
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|