furoshiki 0.2.0 → 0.3.0
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.
- 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
|