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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 28682823686b0e99c68d8e89e8dda278cedcbd7f
|
4
|
+
data.tar.gz: 35eaf912683fd1e7f183d21cf55f998652f04348
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 98811a3dfc69cda04149f26361b3b31d7b8525bb79b7151db8bba034c88e4468e93ebff266f9472026741c27b2ca53b72179c015822bee0c16461b5060aa4cc0
|
7
|
+
data.tar.gz: dec72fe9319649dfb226b22946b3bb2678443b0e83a8f39411e02b346d4d805c639d22d69b9fc678eb7aa931d78b89606deb906c12f6058e9f759e550ce88c00
|
data/.gitignore
CHANGED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
jruby-1.7.
|
1
|
+
jruby-1.7.18
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'bundler'
|
2
2
|
require 'rake/clean'
|
3
|
+
require 'rspec/core/rake_task'
|
3
4
|
Bundler::GemHelper.install_tasks
|
4
5
|
|
5
6
|
@types = %w[rb]
|
@@ -19,3 +20,7 @@ namespace :whitespace do
|
|
19
20
|
end
|
20
21
|
|
21
22
|
CLEAN.include('spec/shoes/.furoshiki', 'spec/shoes/sample_app')
|
23
|
+
|
24
|
+
RSpec::Core::RakeTask.new(:spec)
|
25
|
+
|
26
|
+
task :default => :spec
|
data/furoshiki.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |s|
|
|
21
21
|
s.add_dependency 'rubyzip', '>= 1.0.0'
|
22
22
|
|
23
23
|
s.add_development_dependency 'rake'
|
24
|
-
s.add_development_dependency 'rspec'
|
24
|
+
s.add_development_dependency 'rspec', '>= 3.0.0'
|
25
25
|
s.add_development_dependency 'rspec-its'
|
26
26
|
s.add_development_dependency 'pry'
|
27
27
|
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'yaml'
|
3
|
+
require 'furoshiki/validator'
|
4
|
+
require 'furoshiki/warbler_extensions'
|
5
|
+
require 'furoshiki/util'
|
6
|
+
|
7
|
+
module Furoshiki
|
8
|
+
# Configuration for Furoshiki packagers.
|
9
|
+
#
|
10
|
+
# If your configuration uses hashes, the keys will always be
|
11
|
+
# symbols, even if you have created it with string keys. It's just
|
12
|
+
# easier that way.
|
13
|
+
#
|
14
|
+
# This is a value object. If you need to modify your configuration
|
15
|
+
# after initialization, dump it with #to_hash, make your changes,
|
16
|
+
# and instantiate a new object.
|
17
|
+
class Configuration
|
18
|
+
JAR_APP_TEMPLATE_URL = 'https://s3.amazonaws.com/net.wasnotrice.shoes/wrappers/shoes-app-template-0.0.1.zip'
|
19
|
+
|
20
|
+
include Util
|
21
|
+
|
22
|
+
# @param [Hash] config user options
|
23
|
+
# @param [String] working_dir directory in which to do packaging work
|
24
|
+
def initialize(config = {})
|
25
|
+
merge_config config
|
26
|
+
sanitize_config
|
27
|
+
define_readers
|
28
|
+
end
|
29
|
+
|
30
|
+
def shortname
|
31
|
+
@config[:shortname] || name.downcase.gsub(/\W+/, '')
|
32
|
+
end
|
33
|
+
|
34
|
+
def validator
|
35
|
+
@validator ||= validator_class.new(self)
|
36
|
+
end
|
37
|
+
|
38
|
+
def warbler_extensions
|
39
|
+
@warbler_extensions ||= warbler_extensions_class.new(self)
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_hash
|
43
|
+
@config
|
44
|
+
end
|
45
|
+
|
46
|
+
def valid?
|
47
|
+
validator.valid?
|
48
|
+
end
|
49
|
+
|
50
|
+
def validate
|
51
|
+
return unless validator.respond_to? :reset_and_validate
|
52
|
+
validator.reset_and_validate
|
53
|
+
end
|
54
|
+
|
55
|
+
def error_message_list
|
56
|
+
validator.error_message_list
|
57
|
+
end
|
58
|
+
|
59
|
+
def ==(other)
|
60
|
+
super unless other.class == self.class && other.respond_to?(:to_hash)
|
61
|
+
@config == other.to_hash && working_dir == other.working_dir
|
62
|
+
end
|
63
|
+
|
64
|
+
def to_warbler_config
|
65
|
+
warbler_config = nil
|
66
|
+
Dir.chdir working_dir do
|
67
|
+
warbler_config = Warbler::Config.new do |config|
|
68
|
+
config.jar_name = self.shortname
|
69
|
+
specs = self.gems.map do |gem|
|
70
|
+
# This is rather a hack as Gem::Specification.find_by_name(gem)
|
71
|
+
# seems to break Travis.
|
72
|
+
# See: https://github.com/shoes/shoes4/pull/989#issuecomment-68170746
|
73
|
+
Gem::Specification.find_all_by_name(gem).first
|
74
|
+
end
|
75
|
+
dependencies = specs.map { |s| s.runtime_dependencies }.flatten
|
76
|
+
(specs + dependencies).uniq.each { |g| config.gems << g }
|
77
|
+
ignore = self.ignore.map do |f|
|
78
|
+
path = f.to_s
|
79
|
+
children = Dir.glob("#{path}/**/*") if File.directory?(path)
|
80
|
+
[path, *children]
|
81
|
+
end.flatten
|
82
|
+
config.excludes.add FileList.new(ignore.flatten).pathmap(config.pathmaps.application.first)
|
83
|
+
config.gem_excludes += [/^samples/, /^examples/, /^test/, /^spec/]
|
84
|
+
|
85
|
+
warbler_extensions.customize(config) if warbler_extensions.respond_to? :customize
|
86
|
+
end
|
87
|
+
end
|
88
|
+
warbler_config
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
def warbler_extensions_class
|
93
|
+
@warbler_extensions_class ||= @config.fetch(:warbler_extensions)
|
94
|
+
end
|
95
|
+
|
96
|
+
def validator_class
|
97
|
+
@validator_class ||= @config.fetch(:validator)
|
98
|
+
end
|
99
|
+
|
100
|
+
# Overwrite defaults with supplied config
|
101
|
+
def merge_config(config)
|
102
|
+
defaults = {
|
103
|
+
name: 'Ruby App',
|
104
|
+
version: '0.0.0',
|
105
|
+
release: 'Rookie',
|
106
|
+
ignore: 'pkg',
|
107
|
+
# TODO: Establish these default icons and paths. These would be
|
108
|
+
# default icons for generic Ruby apps.
|
109
|
+
icons: {
|
110
|
+
#osx: 'path/to/default/App.icns',
|
111
|
+
#gtk: 'path/to/default/app.png',
|
112
|
+
#win32: 'path/to/default/App.ico',
|
113
|
+
},
|
114
|
+
template_urls: {
|
115
|
+
jar_app: JAR_APP_TEMPLATE_URL,
|
116
|
+
},
|
117
|
+
validator: Furoshiki::Validator,
|
118
|
+
warbler_extensions: Furoshiki::WarblerExtensions,
|
119
|
+
working_dir: Dir.pwd,
|
120
|
+
}
|
121
|
+
|
122
|
+
@config = merge_with_symbolized_keys(defaults, config)
|
123
|
+
end
|
124
|
+
|
125
|
+
# Ensure these keys have workable values
|
126
|
+
def sanitize_config
|
127
|
+
[:ignore, :gems].each { |k| @config[k] = Array(@config[k]) }
|
128
|
+
@config[:working_dir] = Pathname.new(@config[:working_dir])
|
129
|
+
end
|
130
|
+
|
131
|
+
# Define reader for each top-level config key (except those already defined
|
132
|
+
# explicitly)
|
133
|
+
def define_readers
|
134
|
+
metaclass = class << self; self; end
|
135
|
+
@config.keys.reject {|k| self.respond_to?(k) }.each do |k|
|
136
|
+
metaclass.send(:define_method, k) do
|
137
|
+
@config[k]
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'warbler'
|
2
|
+
require 'warbler/traits/furoshiki'
|
3
|
+
|
4
|
+
module Furoshiki
|
5
|
+
class Jar
|
6
|
+
# @param [Furoshiki::Shoes::Configuration] config user configuration
|
7
|
+
def initialize(config)
|
8
|
+
@furoshiki_config = config
|
9
|
+
|
10
|
+
unless config.valid?
|
11
|
+
raise Furoshiki::ConfigurationError, "Invalid configuration.\n#{config.error_message_list}"
|
12
|
+
end
|
13
|
+
|
14
|
+
@config = @furoshiki_config.to_warbler_config
|
15
|
+
end
|
16
|
+
|
17
|
+
def package(dir = default_dir)
|
18
|
+
Dir.chdir working_dir do
|
19
|
+
jar = Warbler::Jar.new
|
20
|
+
jar.apply @config
|
21
|
+
package_dir = dir.relative_path_from(working_dir)
|
22
|
+
package_dir.mkpath
|
23
|
+
path = package_dir.join(filename).to_s
|
24
|
+
jar.create path
|
25
|
+
File.expand_path path
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def default_dir
|
30
|
+
working_dir.join 'pkg'
|
31
|
+
end
|
32
|
+
|
33
|
+
def filename
|
34
|
+
"#{@config.jar_name}.#{@config.jar_extension}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def working_dir
|
38
|
+
@furoshiki_config.working_dir
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,225 @@
|
|
1
|
+
require 'furoshiki/exceptions'
|
2
|
+
require 'furoshiki/zip/directory'
|
3
|
+
require 'furoshiki/jar'
|
4
|
+
require 'fileutils'
|
5
|
+
require 'plist'
|
6
|
+
require 'open-uri'
|
7
|
+
require 'net/http'
|
8
|
+
|
9
|
+
module Furoshiki
|
10
|
+
class JarApp
|
11
|
+
include FileUtils
|
12
|
+
|
13
|
+
# @param [Furoshiki::Shoes::Configuration] config user configuration
|
14
|
+
def initialize(config)
|
15
|
+
@config = config
|
16
|
+
|
17
|
+
unless config.valid?
|
18
|
+
raise Furoshiki::ConfigurationError, "Invalid configuration.\n#{config.error_message_list}"
|
19
|
+
end
|
20
|
+
|
21
|
+
home = ENV['FUROSHIKI_HOME'] || Dir.home
|
22
|
+
@cache_dir = Pathname.new(home).join('.furoshiki', 'cache')
|
23
|
+
@default_package_dir = working_dir.join('pkg')
|
24
|
+
@package_dir = default_package_dir
|
25
|
+
@default_template_path = cache_dir.join(template_filename)
|
26
|
+
@template_path = default_template_path
|
27
|
+
@tmp = @package_dir.join('tmp')
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [Pathname] default package directory: ./pkg
|
31
|
+
attr_reader :default_package_dir
|
32
|
+
|
33
|
+
# @return [Pathname] package directory
|
34
|
+
attr_accessor :package_dir
|
35
|
+
|
36
|
+
# @return [Pathname] default path to .app template
|
37
|
+
attr_reader :default_template_path
|
38
|
+
|
39
|
+
# @return [Pathname] path to .app template
|
40
|
+
attr_accessor :template_path
|
41
|
+
|
42
|
+
# @return [Pathname] cache directory
|
43
|
+
attr_reader :cache_dir
|
44
|
+
|
45
|
+
attr_reader :config
|
46
|
+
|
47
|
+
attr_reader :tmp
|
48
|
+
|
49
|
+
def package
|
50
|
+
remove_tmp
|
51
|
+
create_tmp
|
52
|
+
cache_template
|
53
|
+
extract_template
|
54
|
+
inject_icon
|
55
|
+
inject_config
|
56
|
+
jar_path = ensure_jar_exists
|
57
|
+
inject_jar jar_path
|
58
|
+
move_to_package_dir tmp_app_path
|
59
|
+
tweak_permissions
|
60
|
+
rescue => e
|
61
|
+
raise e
|
62
|
+
ensure
|
63
|
+
remove_tmp
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
def create_tmp
|
68
|
+
tmp.mkpath
|
69
|
+
end
|
70
|
+
|
71
|
+
def remove_tmp
|
72
|
+
tmp.rmtree if tmp.exist?
|
73
|
+
end
|
74
|
+
|
75
|
+
def cache_template
|
76
|
+
cache_dir.mkpath unless cache_dir.exist?
|
77
|
+
download_template unless template_path.size?
|
78
|
+
end
|
79
|
+
|
80
|
+
def template_basename
|
81
|
+
'shoes-app-template'
|
82
|
+
end
|
83
|
+
|
84
|
+
def template_extension
|
85
|
+
'.zip'
|
86
|
+
end
|
87
|
+
|
88
|
+
def template_filename
|
89
|
+
"#{template_basename}#{template_extension}"
|
90
|
+
end
|
91
|
+
|
92
|
+
def latest_template_version
|
93
|
+
'0.0.1'
|
94
|
+
end
|
95
|
+
|
96
|
+
def download_template
|
97
|
+
download remote_template_url, template_path
|
98
|
+
end
|
99
|
+
|
100
|
+
def download(remote_url, local_path)
|
101
|
+
download_following_redirects remote_url, local_path
|
102
|
+
end
|
103
|
+
|
104
|
+
def download_following_redirects(remote_url, local_path, redirect_limit = 5)
|
105
|
+
if redirect_limit == 0
|
106
|
+
raise Furoshiki::DownloadError,
|
107
|
+
"Too many redirects trying to reach #{remote_url}"
|
108
|
+
end
|
109
|
+
|
110
|
+
uri = URI(remote_url)
|
111
|
+
Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
|
112
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
113
|
+
http.request request do |response|
|
114
|
+
case response
|
115
|
+
when Net::HTTPSuccess then
|
116
|
+
warn "Downloading #{remote_url} to #{local_path}"
|
117
|
+
open(local_path, 'wb') do |file|
|
118
|
+
response.read_body do |chunk|
|
119
|
+
file.write chunk
|
120
|
+
end
|
121
|
+
end
|
122
|
+
when Net::HTTPRedirection then
|
123
|
+
location = response['location']
|
124
|
+
warn "Redirected to #{location}"
|
125
|
+
download_following_redirects(location, local_path, redirect_limit - 1)
|
126
|
+
else
|
127
|
+
raise Furoshiki::DownloadError, "Couldn't download app template at #{remote_url}. #{response.value}"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def downloads_url
|
134
|
+
"http://shoesrb.com/downloads"
|
135
|
+
end
|
136
|
+
|
137
|
+
def remote_template_url
|
138
|
+
config.template_urls.fetch(:jar_app)
|
139
|
+
end
|
140
|
+
|
141
|
+
def move_to_package_dir(path)
|
142
|
+
dest = package_dir.join(path.basename)
|
143
|
+
dest.rmtree if dest.exist?
|
144
|
+
mv path.to_s, dest
|
145
|
+
end
|
146
|
+
|
147
|
+
def ensure_jar_exists
|
148
|
+
jar = Jar.new(@config)
|
149
|
+
path = tmp.join(jar.filename)
|
150
|
+
jar.package(tmp) unless File.exist?(path)
|
151
|
+
path
|
152
|
+
end
|
153
|
+
|
154
|
+
# Injects JAR into APP. The JAR should be the only item in the
|
155
|
+
# Contents/Java directory. If this directory contains more than one
|
156
|
+
# JAR, the "first" one gets run, which may not be what we want.
|
157
|
+
#
|
158
|
+
# @param [Pathname, String] jar_path the location of the JAR to inject
|
159
|
+
def inject_jar(jar_path)
|
160
|
+
jar_dir = tmp_app_path.join('Contents/Java')
|
161
|
+
jar_dir.rmtree
|
162
|
+
jar_dir.mkdir
|
163
|
+
cp Pathname.new(jar_path), jar_dir
|
164
|
+
end
|
165
|
+
|
166
|
+
def extract_template
|
167
|
+
raise IOError, "Couldn't find app template at #{template_path}." unless template_path.size?
|
168
|
+
extracted_app = nil
|
169
|
+
|
170
|
+
::Zip::File.open(template_path) do |zip_file|
|
171
|
+
zip_file.each do |entry|
|
172
|
+
extracted_app = template_path.join(entry.name) if Pathname.new(entry.name).extname == '.app'
|
173
|
+
p = tmp.join(entry.name)
|
174
|
+
p.dirname.mkpath
|
175
|
+
entry.extract(p)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
mv tmp.join(extracted_app.basename.to_s), tmp_app_path
|
179
|
+
end
|
180
|
+
|
181
|
+
def inject_config
|
182
|
+
plist = tmp_app_path.join 'Contents/Info.plist'
|
183
|
+
template = Plist.parse_xml(plist)
|
184
|
+
template['CFBundleIdentifier'] = "com.hackety.shoes.#{config.shortname}"
|
185
|
+
template['CFBundleDisplayName'] = config.name
|
186
|
+
template['CFBundleName'] = config.name
|
187
|
+
template['CFBundleVersion'] = config.version
|
188
|
+
template['CFBundleIconFile'] = Pathname.new(config.icons[:osx]).basename.to_s if config.icons[:osx]
|
189
|
+
File.open(plist, 'w') { |f| f.write template.to_plist }
|
190
|
+
end
|
191
|
+
|
192
|
+
def inject_icon
|
193
|
+
if config.icons[:osx]
|
194
|
+
icon_path = working_dir.join(config.icons[:osx])
|
195
|
+
raise IOError, "Couldn't find app icon at #{icon_path}" unless icon_path.exist?
|
196
|
+
resources_dir = tmp_app_path.join('Contents/Resources')
|
197
|
+
cp icon_path, resources_dir.join(icon_path.basename)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def tweak_permissions
|
202
|
+
executable_path.chmod 0755
|
203
|
+
end
|
204
|
+
|
205
|
+
def app_name
|
206
|
+
"#{config.name}.app"
|
207
|
+
end
|
208
|
+
|
209
|
+
def tmp_app_path
|
210
|
+
tmp.join app_name
|
211
|
+
end
|
212
|
+
|
213
|
+
def app_path
|
214
|
+
package_dir.join app_name
|
215
|
+
end
|
216
|
+
|
217
|
+
def executable_path
|
218
|
+
app_path.join('Contents/MacOS/JavaAppLauncher')
|
219
|
+
end
|
220
|
+
|
221
|
+
def working_dir
|
222
|
+
config.working_dir
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Furoshiki
|
2
|
+
module Util
|
3
|
+
# Ensure symbol keys, even in nested hashes
|
4
|
+
#
|
5
|
+
# @param [Hash] config the hash to set (key: value) on
|
6
|
+
# @param [#to_sym] k the key
|
7
|
+
# @param [Object] v the value
|
8
|
+
# @return [Hash] an updated hash
|
9
|
+
def deep_set_symbol_key(hash, key, value)
|
10
|
+
if value.kind_of? Hash
|
11
|
+
hash[key.to_sym] = value.inject({}) { |inner_hash, (inner_key, inner_value)| deep_set_symbol_key(inner_hash, inner_key, inner_value) }
|
12
|
+
else
|
13
|
+
hash[key.to_sym] = value
|
14
|
+
end
|
15
|
+
hash
|
16
|
+
end
|
17
|
+
|
18
|
+
def deep_symbolize_keys(hash)
|
19
|
+
merge_with_symbolized_keys({}, hash)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Assumes that defaults already has symbolized keys
|
23
|
+
def merge_with_symbolized_keys(defaults, hash)
|
24
|
+
hash.inject(defaults) { |symbolized, (k, v)| deep_set_symbol_key(symbolized, k, v) }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Furoshiki
|
2
|
+
class Validator
|
3
|
+
def initialize(config)
|
4
|
+
@config = config
|
5
|
+
@errors = []
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_reader :config
|
9
|
+
|
10
|
+
def valid?
|
11
|
+
reset_and_validate
|
12
|
+
return errors.empty?
|
13
|
+
end
|
14
|
+
|
15
|
+
def reset_and_validate
|
16
|
+
@errors.clear
|
17
|
+
validate if respond_to? :validate
|
18
|
+
end
|
19
|
+
|
20
|
+
def errors
|
21
|
+
@errors.dup
|
22
|
+
end
|
23
|
+
|
24
|
+
def error_message_list
|
25
|
+
@errors.map {|m| " - #{m}"}.join("\n")
|
26
|
+
end
|
27
|
+
|
28
|
+
def working_dir
|
29
|
+
@config.working_dir
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
def add_error(message)
|
34
|
+
@errors << message
|
35
|
+
end
|
36
|
+
|
37
|
+
def add_missing_file_error(value, description)
|
38
|
+
message = "#{description} configured as '#{value}', but couldn't find file at #{working_dir.join(value.to_s)}"
|
39
|
+
add_error(message)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/furoshiki/version.rb
CHANGED
data/lib/furoshiki.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
require 'furoshiki/configuration'
|
2
|
+
require 'furoshiki/exceptions'
|
3
|
+
require 'furoshiki/jar'
|
4
|
+
require 'furoshiki/jar_app'
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'warbler'
|
2
|
+
require 'warbler/traits'
|
3
|
+
|
4
|
+
module Warbler
|
5
|
+
module Traits
|
6
|
+
# Hack to stop bundler injecting itself
|
7
|
+
class Bundler
|
8
|
+
def self.detect?
|
9
|
+
false
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Furoshiki
|
14
|
+
include ::Warbler::Trait
|
15
|
+
include PathmapHelper
|
16
|
+
|
17
|
+
def self.detect?
|
18
|
+
true
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.requires?(trait)
|
22
|
+
[Traits::Jar].include? trait
|
23
|
+
end
|
24
|
+
|
25
|
+
def update_archive(jar)
|
26
|
+
# Not sure why Warbler doesn't do this automatically
|
27
|
+
jar.files.delete_if { |k, v| @config.excludes.include? k }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|