jsus 0.2.6 → 0.2.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (7) hide show
  1. data/CHANGELOG +5 -0
  2. data/Gemfile +1 -0
  3. data/Gemfile.lock +2 -0
  4. data/VERSION +1 -1
  5. data/bin/jsus +290 -148
  6. data/jsus.gemspec +5 -2
  7. metadata +18 -4
data/CHANGELOG CHANGED
@@ -1,4 +1,9 @@
1
1
  = Jsus Changelog
2
+ == Version 0.2.7
3
+ * Brushed up CLI code
4
+ * Added --watch option for cli (using fssm gem and fs backend for your operating system)
5
+ * Added --compress option for cli (using yui-compressor gem)
6
+
2
7
  == Version 0.2.6
3
8
  * Moved support classes to Jsus::Util module namespace
4
9
  * Now using autoload instead of require's for stuff
data/Gemfile CHANGED
@@ -13,4 +13,5 @@ group :development do
13
13
  gem "murdoc"
14
14
  gem "ruby-debug19", :platforms => :ruby_19
15
15
  gem "ruby-debug", :platforms => :ruby_18
16
+ gem 'fssm'
16
17
  end
data/Gemfile.lock CHANGED
@@ -12,6 +12,7 @@ GEM
12
12
  json (~> 1.4.6)
13
13
  term-ansicolor (~> 1.0.5)
14
14
  diff-lcs (1.1.2)
15
+ fssm (0.2.5)
15
16
  gherkin (2.3.3)
16
17
  json (~> 1.4.6)
17
18
  git (1.2.5)
@@ -68,6 +69,7 @@ DEPENDENCIES
68
69
  activesupport
69
70
  bundler
70
71
  cucumber
72
+ fssm
71
73
  jeweler
72
74
  json_pure
73
75
  murdoc
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.6
1
+ 0.2.7
data/bin/jsus CHANGED
@@ -20,175 +20,317 @@ require 'jsus'
20
20
  require "fileutils"
21
21
  require "optparse"
22
22
 
23
- start_time = Time.now
23
+ module Jsus
24
+ class CLI
25
+ class <<self
26
+ attr_accessor :cli_options
27
+
28
+ def parse_command_line!
29
+ options = {}
30
+ cli = OptionParser.new do |opts|
31
+ opts.banner = "jsus #{Jsus.version}. Usage: jsus [options] <input_dir> <output_dir>"
32
+
33
+ opts.on('-i', '--input-directory [DIR]', '[DEPRECATED] path to input directory ') do |dir|
34
+ $stderr.puts "DEPRECATION NOTICE: please do not use -i command-line argument"
35
+ options[:input_dir] = dir
36
+ end
37
+
38
+ opts.on('-o', '--output-directory [DIR]', '[DEPRECATED] path to output directory ') do |dir|
39
+ $stderr.puts "DEPRECATION NOTICE: please do not use -o command-line argument"
40
+ options[:output_dir] = dir
41
+ end
42
+
43
+ opts.on('-d', '--with-dependencies [DEPS]', 'path to directory containing dependency packages') do |dir|
44
+ options[:deps_dir] = dir
45
+ end
46
+
47
+ opts.on('-g', '--generate-includes [ROOT]', 'generates includes.js file that you may use for ad-hoc requiring of dependencies, defaults to output directory') do |dir|
48
+ options[:generate_includes] = true
49
+ options[:includes_root] = dir
50
+ end
51
+
52
+ opts.on('--generate-docs [*CLASSES]', Array, "generate docs for some of the sources. When given empty array, defaults to /**/*") do |docs|
53
+ if !docs
54
+ options[:documented_classes] = ["/**/*"]
55
+ else
56
+ options[:documented_classes] = docs
57
+ end
58
+ end
59
+
60
+ opts.on('--no-syntax-highlight', 'if you turned on docs generation, it will use syntax highlighting by default. This option prevents it') do
61
+ options[:no_syntax_highlight] = true
62
+ end
63
+
64
+ opts.on('--validate-with [*VALIDATORS]', Array, 'performs a check against some of the validators. Available validators: mooforge') do |validators|
65
+ options[:validators] = (validators || []).map {|v| v.downcase }
66
+ end
67
+
68
+ opts.on('--postproc [*PROCESSORS]', Array, 'performs postprocessing. Available postprocs:\n* moocompat12 -- removes mootools 1.2compat tags and their contents\n* mooltIE8 -- removes mootools ltIE8 compat tags and their contents') do |postprocs|
69
+ options[:postproc] = postprocs
70
+ end
71
+
72
+ opts.on('--compress', 'compresses resulting file with YUI compressor') do
73
+ options[:compress] = true
74
+ end
75
+
76
+ opts.on_tail('-v', '--verbose', 'verbose mode, shows various debug messages') do
77
+ Jsus.verbose = true
78
+ end
79
+
80
+ opts.on_tail('-b', '--benchmark', 'shows time spent on various stages') do
81
+ options[:benchmark] = true
82
+ end
83
+
84
+ opts.on_tail('--without-scripts-info', 'do not generate scripts.json') do
85
+ options[:without_scripts_info] = true
86
+ end
87
+
88
+ opts.on_tail('--without-tree-info', 'do not generate tree.json') do
89
+ options[:without_tree_info] = true
90
+ end
91
+
92
+ opts.on_tail('--watch', 'watch file system events for *.js files in subdirectories and rerun jsus with the same parameters') do
93
+ options[:watch] = true
94
+ end
95
+
96
+ opts.on_tail('-h', '--help', 'Show this message') do
97
+ puts opts
98
+ exit
99
+ end
100
+ end
101
+ cli.parse!
102
+
103
+ options[:input_dir] ||= ARGV[0]
104
+ options[:output_dir] ||= ARGV[1]
105
+
106
+ if !(options[:input_dir] && options[:output_dir])
107
+ puts cli
108
+ exit
109
+ end
110
+ options[:input_dir] = File.expand_path(options[:input_dir])
111
+ options[:output_dir] = File.expand_path(options[:output_dir])
112
+ self.cli_options = options
113
+ end
114
+
115
+ def watch?
116
+ cli_options[:watch]
117
+ end
118
+
119
+ def launch!
120
+ new.launch
121
+ end
122
+
123
+ def run!
124
+ parse_command_line!
125
+ if watch?
126
+ watch do |base, match|
127
+ full_path = File.join(base, match)
128
+ unless full_path.include?(cli_options[:output_dir])
129
+ puts "#{match} has changed, relaunching jsus..."
130
+ launch!
131
+ puts "... done"
132
+ puts ""
133
+ end
134
+ end
135
+ else
136
+ launch!
137
+ end
138
+ end
139
+
140
+ def watch
141
+ require 'fssm'
142
+ puts "Jsus enters watch mode, it will watch your files for changes and relaunch itself"
143
+ puts ""
144
+ start_directory = Dir.pwd
145
+ watched_dirs = [cli_options[:input_dir], cli_options[:deps_dir]].compact.map {|path| File.expand_path(path)}
146
+ FSSM.monitor do
147
+ watched_dirs.each do |dir|
148
+ path dir do
149
+ glob ["**/*.js", "**/package.yml", "**/package.json"]
150
+ update {|base, relative| yield base, relative }
151
+ delete {|base, relative| yield base, relative }
152
+ create {|base, relative| yield base, relative }
153
+ end
154
+ end
155
+ end
156
+
157
+ rescue LoadError => e
158
+ puts "You need to install fssm gem for --watch option."
159
+ puts "You may also want to install rb-fsevent for OS X"
160
+ raise e
161
+ end
24
162
 
25
- options = {}
26
- cli = OptionParser.new do |opts|
27
- opts.banner = "jsus #{Jsus.version}. Usage: jsus [options] <input_dir> <output_dir>"
28
-
29
- opts.on('-i', '--input-directory [DIR]', '[DEPRECATED] path to input directory ') do |dir|
30
- $stderr.puts "DEPRECATION NOTICE: please do not use -i command-line argument"
31
- options[:input_dir] = dir
32
- end
33
-
34
- opts.on('-o', '--output-directory [DIR]', '[DEPRECATED] path to output directory ') do |dir|
35
- $stderr.puts "DEPRECATION NOTICE: please do not use -o command-line argument"
36
- options[:output_dir] = dir
37
- end
38
-
39
- opts.on('-d', '--with-dependencies [DEPS]', 'path to directory containing dependency packages') do |dir|
40
- options[:deps_dir] = dir
41
- end
163
+ end
42
164
 
43
- opts.on('-g', '--generate-includes [ROOT]', 'generates includes.js file that you may use for ad-hoc requiring of dependencies, defaults to output directory') do |dir|
44
- options[:generate_includes] = true
45
- options[:includes_root] = dir
46
- end
165
+ attr_accessor :options
47
166
 
48
- opts.on('--generate-docs [*CLASSES]', Array, "generate docs for some of the sources. When given empty array, defaults to /**/*") do |docs|
49
- if !docs
50
- options[:documented_classes] = ["/**/*"]
51
- else
52
- options[:documented_classes] = docs
167
+ def initialize(options = Jsus::CLI.cli_options)
168
+ @options = options
53
169
  end
54
- end
55
170
 
56
- opts.on('--no-syntax-highlight', 'if you turned on docs generation, it will use syntax highlighting by default. This option prevents it') do
57
- options[:no_syntax_highlight] = true
58
- end
171
+ def launch
172
+ checkpoint(:start)
173
+ setup_output_directory
174
+ preload_pool
175
+ load_package
176
+ compile_package
177
+ post_process if options[:postproc]
178
+ compress_package if options[:compress]
179
+ package_filename = File.join(@output_dir, @package.filename)
180
+ File.open(package_filename, 'w') {|f| f << @package_content }
181
+ generate_supplemental_files
182
+ validate_sources
183
+ generate_includes if options[:generate_includes]
184
+ generate_docs if options[:documented_classes] && !options[:documented_classes].empty?
185
+ output_benchmarks
186
+ end
59
187
 
60
- opts.on('--validate-with [*VALIDATORS]', Array, 'performs a check against some of the validators. Available validators: mooforge') do |validators|
61
- options[:validators] = (validators || []).map {|v| v.downcase }
62
- end
188
+ def setup_output_directory
189
+ @output_dir = options[:output_dir]
190
+ FileUtils.mkdir_p(@output_dir)
191
+ end
63
192
 
64
- opts.on('--postproc [*PROCESSORS]', Array, 'performs postprocessing. Available postprocs:\n* moocompat12 -- removes mootools 1.2compat tags and their contents\n* mooltIE8 -- removes mootools ltIE8 compat tags and their contents') do |postprocs|
65
- options[:postproc] = postprocs
66
- end
193
+ def preload_pool
194
+ @pool = if options[:deps_dir]
195
+ Jsus::Pool.new(options[:deps_dir])
196
+ else
197
+ Jsus::Pool.new
198
+ end
199
+ checkpoint(:pool)
200
+ end
67
201
 
68
- opts.on_tail('-v', '--verbose', 'verbose mode, shows various debug messages') do
69
- options[:verbose] = true
70
- end
202
+ def load_package
203
+ @package = Jsus::Package.new(options[:input_dir], :pool => @pool)
204
+ @package.include_dependencies!
205
+ checkpoint(:dependencies)
206
+ end
71
207
 
72
- opts.on_tail('-b', '--benchmark', 'shows time spent on various stages') do
73
- options[:benchmark] = true
74
- end
208
+ def compile_package
209
+ @package_content = @package.compile(nil)
210
+ checkpoint(:compilation)
211
+ end
75
212
 
76
- opts.on_tail('--without-scripts-info', 'do not generate scripts.json') do
77
- options[:without_scripts_info] = true
78
- end
213
+ def post_process
214
+ options[:postproc].each do |processor|
215
+ case processor.strip
216
+ when /^moocompat12$/i
217
+ @package_content.gsub!(/\/\/<1.2compat>.*?\/\/<\/1.2compat>/m, '')
218
+ @package_content.gsub!(/\/\*<1.2compat>\*\/.*?\/\*<\/1.2compat>\*\//m, '')
219
+ when /^mooltie8$/i
220
+ @package_content.gsub!(/\/\/<ltIE8>.*?\/\/<\/ltIE8>/m, '')
221
+ @package_content.gsub!(/\/\*<ltIE8>\*\/.*?\/\*<\/ltIE8>\*\//m, '')
222
+ else
223
+ $stderr.puts "Unknown post-processor: #{processor}"
224
+ end
225
+ end
226
+ checkpoint(:postproc)
227
+ end
79
228
 
80
- opts.on_tail('--without-tree-info', 'do not generate tree.json') do
81
- options[:without_tree_info] = true
82
- end
229
+ def compress_package
230
+ require 'yui/compressor'
231
+ compressor = YUI::JavaScriptCompressor.new(:munge => true)
232
+ compressed_content = compressor.compress(@package_content)
233
+ if compressed_content != ""
234
+ compression_ratio = compressed_content.size.to_f / @package_content.size.to_f
235
+ @package_content = compressed_content
236
+ else
237
+ compression_ratio = 1.00
238
+ puts "ERROR: YUI compressor could not parse input. Falling back to uncompressed version"
239
+ puts "Compressor command used: #{compressor.command.join(' ')}"
240
+ end
241
+ puts "Compression ratio: #{sprintf("%.2f%%", compression_ratio * 100)}" if Jsus.verbose?
242
+ checkpoint(:compress)
243
+ rescue LoadError
244
+ puts 'ERROR: You need "yui-compressor" gem in order to use --compress option'
245
+ end
83
246
 
247
+ def generate_supplemental_files
248
+ @package.generate_scripts_info(@output_dir) unless options[:without_scripts_info]
249
+ @package.generate_tree(@output_dir) unless options[:without_tree_info]
250
+ checkpoint(:supplemental_files)
251
+ end
84
252
 
253
+ def generate_includes
254
+ includes_root = options[:includes_root] || @output_dir
255
+ File.open(File.join(@output_dir, "includes.js"), "w") do |f|
256
+ c = Jsus::Container.new(*(@package.source_files.to_a + @package.linked_external_dependencies.to_a))
257
+ script = %{
258
+ (function(prefix, loader) {
259
+ var sources = %sources%;
260
+ if (!loader) loader = function(path) {
261
+ document.write('<scr' + 'ipt src="' + (prefix || '') + path + '"></script>');
262
+ }
263
+ for (var i = 0, j = sources.length; i < j; i++) loader(sources[i]);
264
+ })(window.prefix, window.loader);}.sub("%sources%", JSON.pretty_generate(c.required_files(includes_root)))
265
+ f.puts script
266
+ end
267
+ checkpoint(:includes)
268
+ end
85
269
 
86
- opts.on_tail('-h', '--help', 'Show this message') do
87
- puts opts
88
- exit
89
- end
90
- end
91
- cli.parse!
270
+ def generate_docs
271
+ documenter = Jsus::Util::Documenter.new(:highlight_source => !options[:no_syntax_highlight])
272
+ @package.source_files.each {|source| documenter << source }
273
+ @pool.sources.each {|source| documenter << source }
274
+ documenter.only(options[:documented_classes]).generate(@output_dir + "/docs")
275
+ checkpoint(:documentation)
276
+ end
92
277
 
93
- options[:input_dir] ||= ARGV[0]
94
- options[:output_dir] ||= ARGV[1]
278
+ def validate_sources
279
+ validators_map = {"mooforge" => Jsus::Util::Validator::Mooforge}
280
+ (options[:validators] || []).each do |validator_name|
281
+ if validator = validators_map[validator_name]
282
+ errors = validator.new(@pool.sources.to_a & @package.source_files.to_a).validation_errors
283
+ unless errors.empty?
284
+ puts "Validator #{validator_name} found errors: "
285
+ errors.each {|e| puts " * #{e}"}
286
+ end
287
+ else
288
+ puts "No such validator: #{validator_name}"
289
+ end
290
+ end
291
+ checkpoint(:validators)
292
+ end
95
293
 
96
- if !(options[:input_dir] && options[:output_dir])
97
- puts cli
98
- exit
99
- end
294
+ def output_benchmarks
295
+ if options[:benchmark]
296
+ puts "Benchmarking results:"
297
+ puts "Total execution time: #{formatted_time_for(:all)}"
298
+ puts ""
299
+ puts "Of them:"
300
+ puts "Pool preloading time: #{formatted_time_for(:pool)}"
301
+ puts "Docs generation time: #{formatted_time_for(:documentation)}" if options[:documented_classes] && !options[:documented_classes].empty?
302
+ puts "Total compilation time: #{formatted_time_for(:compilation)}"
303
+ puts "Post-processing time: #{formatted_time_for(:postproc)}" if options[:postproc]
304
+ puts "Compression time: #{formatted_time_for(:compress)}" if options[:compress]
305
+ end
306
+ end
100
307
 
101
- compile_start_time = Time.now
308
+ def checkpoint(checkpoint_name)
309
+ @checkpoints ||= {}
310
+ @time_for ||= {}
311
+ @checkpoints[checkpoint_name] = Time.now
312
+ if @last_checkpoint
313
+ @time_for[checkpoint_name] = @checkpoints[checkpoint_name] - @last_checkpoint
314
+ end
315
+ @last_checkpoint = Time.now
316
+ end
102
317
 
103
- Jsus.verbose = options[:verbose]
318
+ def checkpoint?(checkpoint_name)
319
+ @checkpoints[checkpoint_name]
320
+ end
104
321
 
105
- pool_load_start_time = Time.now
106
- pool = if options[:deps_dir]
107
- Jsus::Pool.new(options[:deps_dir])
108
- else
109
- Jsus::Pool.new
110
- end
111
- pool_load_finish_time = Time.now
112
-
113
- package = Jsus::Package.new(options[:input_dir], :pool => pool)
114
- package.include_dependencies!
115
- output_dir = options[:output_dir]
116
-
117
- package_content = package.compile(nil)
118
-
119
- if options[:postproc]
120
- options[:postproc].each do |processor|
121
- case processor.strip
122
- when /^moocompat12$/i
123
- package_content.gsub!(/\/\/<1.2compat>.*?\/\/<\/1.2compat>/m, '')
124
- package_content.gsub!(/\/\*<1.2compat>\*\/.*?\/\*<\/1.2compat>\*\//m, '')
125
- when /^mooltie8$/i
126
- package_content.gsub!(/\/\/<ltIE8>.*?\/\/<\/ltIE8>/m, '')
127
- package_content.gsub!(/\/\*<ltIE8>\*\/.*?\/\*<\/ltIE8>\*\//m, '')
128
- else
129
- $stderr.puts "Unknown post-processor: #{processor}"
322
+ def time_for(checkpoint_name)
323
+ if checkpoint_name == :all
324
+ @last_checkpoint - @checkpoints[:start]
325
+ else
326
+ @time_for[checkpoint_name]
327
+ end
130
328
  end
131
- end
132
- end
133
- FileUtils.mkdir_p(output_dir)
134
- package_filename = File.join(output_dir, package.filename)
135
- File.open(package_filename, 'w') {|f| f << package_content }
136
-
137
- package.generate_scripts_info(output_dir) unless options[:without_scripts_info]
138
- package.generate_tree(output_dir) unless options[:without_tree_info]
139
-
140
- # Validations
141
- validators_map = {"mooforge" => Jsus::Util::Validator::Mooforge}
142
- (options[:validators] || []).each do |validator_name|
143
- if validator = validators_map[validator_name]
144
- errors = validator.new(pool.sources.to_a & package.source_files.to_a).validation_errors
145
- unless errors.empty?
146
- puts "Validator #{validator_name} found errors: "
147
- errors.each {|e| puts " * #{e}"}
148
- end
149
- else
150
- puts "No such validator: #{validator_name}"
151
- end
152
- end
153
329
 
154
- # Postprocs, sort of hack
155
-
156
- # Hack, hack, hack >:E
157
- if options[:generate_includes]
158
- includes_root = options[:includes_root] || output_dir
159
- File.open(File.join(output_dir, "includes.js"), "w") do |f|
160
- c = Jsus::Container.new(*(package.source_files.to_a + package.linked_external_dependencies.to_a))
161
- script = %{
162
- (function(prefix, loader) {
163
- var sources = %sources%;
164
- if (!loader) loader = function(path) {
165
- document.write('<scr' + 'ipt src="' + (prefix || '') + path + '"></script>');
166
- }
167
- for (var i = 0, j = sources.length; i < j; i++) loader(sources[i]);
168
- })(window.prefix, window.loader);}.sub("%sources%", JSON.pretty_generate(c.required_files(includes_root)))
169
- f.puts script
330
+ def formatted_time_for(checkpoint_name)
331
+ "#{format("%.3f", time_for(checkpoint_name))}s"
332
+ end
170
333
  end
171
334
  end
172
335
 
173
- docs_start_time = Time.now
174
- # Generate documentation
175
- if options[:documented_classes] && !options[:documented_classes].empty?
176
- documenter = Jsus::Util::Documenter.new(:highlight_source => !options[:no_syntax_highlight])
177
- package.source_files.each {|source| documenter << source }
178
- pool.sources.each {|source| documenter << source } if pool
179
- documenter.only(options[:documented_classes]).generate(output_dir + "/docs")
180
- end
181
- docs_finish_time = Time.now
182
-
183
- finish_time = Time.now
184
-
185
-
186
- if options[:benchmark]
187
- puts "Benchmarking results:"
188
- puts "Total execution time: #{format("%.3f" ,finish_time - start_time)}s"
189
- puts ""
190
- puts "Of them:"
191
- puts "Pool preloading time: #{format("%.3f", pool_load_finish_time - pool_load_start_time)}s"
192
- puts "Docs generation time: #{format("%.3f", docs_finish_time - docs_start_time)}s" if options[:documented_classes]
193
- puts "Total compilation time: #{format("%.3f", finish_time - compile_start_time - (pool_load_finish_time - pool_load_start_time))}s"
194
- end
336
+ Jsus::CLI.run!
data/jsus.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{jsus}
8
- s.version = "0.2.6"
8
+ s.version = "0.2.7"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Mark Abramov"]
12
- s.date = %q{2011-03-07}
12
+ s.date = %q{2011-03-10}
13
13
  s.default_executable = %q{jsus}
14
14
  s.description = %q{Javascript packager and dependency resolver}
15
15
  s.email = %q{markizko@gmail.com}
@@ -210,6 +210,7 @@ Gem::Specification.new do |s|
210
210
  s.add_development_dependency(%q<murdoc>, [">= 0"])
211
211
  s.add_development_dependency(%q<ruby-debug19>, [">= 0"])
212
212
  s.add_development_dependency(%q<ruby-debug>, [">= 0"])
213
+ s.add_development_dependency(%q<fssm>, [">= 0"])
213
214
  else
214
215
  s.add_dependency(%q<activesupport>, [">= 0"])
215
216
  s.add_dependency(%q<json_pure>, [">= 0"])
@@ -221,6 +222,7 @@ Gem::Specification.new do |s|
221
222
  s.add_dependency(%q<murdoc>, [">= 0"])
222
223
  s.add_dependency(%q<ruby-debug19>, [">= 0"])
223
224
  s.add_dependency(%q<ruby-debug>, [">= 0"])
225
+ s.add_dependency(%q<fssm>, [">= 0"])
224
226
  end
225
227
  else
226
228
  s.add_dependency(%q<activesupport>, [">= 0"])
@@ -233,6 +235,7 @@ Gem::Specification.new do |s|
233
235
  s.add_dependency(%q<murdoc>, [">= 0"])
234
236
  s.add_dependency(%q<ruby-debug19>, [">= 0"])
235
237
  s.add_dependency(%q<ruby-debug>, [">= 0"])
238
+ s.add_dependency(%q<fssm>, [">= 0"])
236
239
  end
237
240
  end
238
241
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsus
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 25
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 6
10
- version: 0.2.6
9
+ - 7
10
+ version: 0.2.7
11
11
  platform: ruby
12
12
  authors:
13
13
  - Mark Abramov
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-03-07 00:00:00 -05:00
18
+ date: 2011-03-10 00:00:00 -05:00
19
19
  default_executable: jsus
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -158,6 +158,20 @@ dependencies:
158
158
  - 0
159
159
  version: "0"
160
160
  requirement: *id010
161
+ - !ruby/object:Gem::Dependency
162
+ type: :development
163
+ prerelease: false
164
+ name: fssm
165
+ version_requirements: &id011 !ruby/object:Gem::Requirement
166
+ none: false
167
+ requirements:
168
+ - - ">="
169
+ - !ruby/object:Gem::Version
170
+ hash: 3
171
+ segments:
172
+ - 0
173
+ version: "0"
174
+ requirement: *id011
161
175
  description: Javascript packager and dependency resolver
162
176
  email: markizko@gmail.com
163
177
  executables: