skyrocket 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
File without changes
data/README.md ADDED
@@ -0,0 +1,4 @@
1
+ skyrocket
2
+ ======
3
+
4
+ Yet another opinionated static content/ web asset generation gem
data/bin/skyrocket ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'skyrocket/cmd'
4
+ Skyrocket::Cmd.new(ARGV).run
@@ -0,0 +1,34 @@
1
+ require 'fileutils'
2
+
3
+ module Skyrocket
4
+ class Asset
5
+ attr_reader :filename, :dir, :output_dir, :processor
6
+
7
+ def initialize(dir, filename, output_dir, processor)
8
+ @dir = dir
9
+ @filename = filename
10
+ @output_dir = output_dir
11
+ @processor = processor
12
+ end
13
+
14
+ def name
15
+ @processor.post_process_name(@filename)
16
+ end
17
+
18
+ def output_path
19
+ @output_dir + "/" + @processor.post_process_name(@filename)
20
+ end
21
+
22
+ def content
23
+ return @content if @content
24
+ @content = raw
25
+ @content = @processor.process(@content) if @processor
26
+ return @content
27
+ end
28
+
29
+ def raw
30
+ File.read(File.join(@dir, @filename))
31
+ end
32
+ end
33
+ end
34
+
@@ -0,0 +1,54 @@
1
+ module Skyrocket
2
+ class AssetFactory
3
+ attr_reader :asset_dirs, :lib_dirs, :output_dir
4
+ def initialize(asset_dirs, lib_dirs = [], output_dir)
5
+ @asset_dirs = asset_dirs
6
+ @lib_dirs = lib_dirs
7
+ @output_dir = output_dir
8
+ @pf = ProcessorFactory.new
9
+ end
10
+
11
+ def build_asset(filepath)
12
+ dir, file = parts(filepath)
13
+ Asset.new(dir, file, @output_dir, @pf.processor(file))
14
+ end
15
+
16
+ def from_name(name)
17
+ found = dir_search(name, @asset_dirs + @lib_dirs)
18
+ if found.length > 0
19
+ found.each do |file|
20
+ if @pf.post_process_name(file) =~ /#{name}$/
21
+ dir, file = parts(file)
22
+ return Asset.new(dir, file, @output_dir, @pf.processor(file))
23
+ end
24
+ end
25
+ end
26
+
27
+ raise AssetNotFoundError
28
+ end
29
+
30
+ private
31
+ def parts(filepath)
32
+ dir = file_dir(filepath, @asset_dirs + @lib_dirs)
33
+ file = filepath.gsub("#{dir}/", '')
34
+ [dir, file]
35
+ end
36
+
37
+ def file_dir(filepath, dirs)
38
+ dirs.each do |dir|
39
+ if(filepath.start_with?(dir))
40
+ return dir
41
+ end
42
+ end
43
+ raise PathNotInAssetsError.new
44
+ end
45
+
46
+ def dir_search(part, dirs)
47
+ found = Array.new
48
+ dirs.each do |dir|
49
+ found += Dir[dir + "/" + part + ".*"]
50
+ end
51
+ found
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,40 @@
1
+ require 'shellwords'
2
+
3
+ # components of this file were borrowed from ruby sprokets, https://github.com/sstephenson/sprockets
4
+ module Skyrocket
5
+ class AssetLoader
6
+ HEADER_PATTERN = /
7
+ \A (
8
+ (?m:\s*) (
9
+ (\/\* (?m:.*?) \*\/) |
10
+ (\#\#\# (?m:.*?) \#\#\#) |
11
+ (\/\/ .* \n?)+ |
12
+ (\# .* \n?)+
13
+ )
14
+ )+
15
+ /x
16
+
17
+ DIRECTIVE_PATTERN = /
18
+ ^ [\W]* = \s* (\w+.*?) (\*\/)? $
19
+ /x
20
+
21
+ attr_reader :headers, :body
22
+
23
+ def initialize(filepath)
24
+ raw = File.read(filepath)
25
+ @headers = raw[HEADER_PATTERN, 0].lines || [""]
26
+ @body = $' || data
27
+ # Ensure body ends in a new line
28
+ @body += "\n" if @body != "" && @body !~ /\n\Z/m
29
+ end
30
+
31
+ def requires
32
+ @requires ||= @headers.each.map do |line|
33
+ if directive = line[DIRECTIVE_PATTERN, 1]
34
+ name, arg = Shellwords.shellwords(directive)
35
+ arg if name == 'require'
36
+ end
37
+ end.compact
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,26 @@
1
+ require 'skyrocket/dir_ext'
2
+
3
+ module Skyrocket
4
+ class AssetLocator
5
+ def initialize(asset_factory)
6
+ @af = asset_factory
7
+ end
8
+
9
+ def all_assets
10
+ dirs = @af.asset_dirs + @af.lib_dirs
11
+ paths = Array.new
12
+ dirs.each do |dir|
13
+ paths += Dir.glob_files(dir + "/**/*")
14
+ end
15
+ paths.map{ |p| @af.build_asset(p) }
16
+ end
17
+
18
+ def missing_asset_paths
19
+ out_cont = Dir.glob_files(@af.output_dir + "/**/*")
20
+ assets = all_assets
21
+ a_m = all_assets.inject(Hash.new) { |h, a| h[a.output_path] = a; h }
22
+ out_cont.select { |file| !a_m.keys.include?(file) }
23
+ end
24
+ end
25
+ end
26
+
@@ -0,0 +1,59 @@
1
+ require 'pathname'
2
+
3
+ module Skyrocket
4
+ class AssetManager
5
+ attr_reader :asset_dirs, :lib_dirs, :output_dir, :base_url, :style
6
+
7
+ def initialize(options)
8
+ @asset_dirs = options[:asset_dirs].map{ |ad| Pathname.new(ad).realpath.to_s }
9
+ @lib_dirs = options[:lib_dirs].map{ |ld| Pathname.new(ld).realpath.to_s }
10
+ @output_dir = Pathname.new(options[:output_dir]).realpath.to_s
11
+ @base_url = options[:base_url]
12
+ @style = options[:style]
13
+ @af = AssetFactory.new(@asset_dirs, @lib_dirs, @output_dir)
14
+ @aw = AssetWriter.new
15
+ @al = AssetLocator.new(@af)
16
+ Processor.asset_factory = @af
17
+ Processor.base_url = @base_url
18
+ end
19
+
20
+ def compile(&block)
21
+ update_public(&block)
22
+ end
23
+
24
+ def watch(&block)
25
+ gem 'listen', '>=0.4.2'
26
+ require 'listen'
27
+
28
+ update_public(&block)
29
+
30
+ Listen.to(*(@asset_dirs + @lib_dirs)) do |modified, added, removed|
31
+ (modified + added).each { |am| process_change(@af.build_asset(am), &block) }
32
+ removed.each do |del|
33
+ as = @af.build_asset(del)
34
+ process_deleted(as.output_path, &block)
35
+ end
36
+ end
37
+ end
38
+
39
+ private
40
+ def update_public(&block)
41
+ @al.missing_asset_paths.each { |p| process_deleted(p, &block) }
42
+ @al.all_assets.each { |a| process_change(a, &block) }
43
+ end
44
+
45
+ def process_change(asset)
46
+ case @aw.write(asset)
47
+ when :created
48
+ yield(:created, asset.name) if block_given?
49
+ when :modified
50
+ yield(:modified, asset.name) if block_given?
51
+ end
52
+ end
53
+
54
+ def process_deleted(path)
55
+ @aw.delete(path)
56
+ yield(:deleted, path.gsub(@output_dir + '/', '')) if block_given?
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,37 @@
1
+ require 'fileutils'
2
+ require 'skyrocket/file_ext'
3
+
4
+ module Skyrocket
5
+ class AssetWriter
6
+ def write(asset)
7
+ if(File.exist?(asset.output_path))
8
+ existing = File.read(asset.output_path)
9
+ if existing != asset.content
10
+ File.write_file(asset.output_path, asset.content)
11
+ :modified
12
+ else
13
+ :no_change
14
+ end
15
+ else
16
+ dirname = File.dirname(asset.output_path)
17
+ FileUtils.mkdir_p(dirname)
18
+ File.write_file(asset.output_path, asset.content)
19
+ :created
20
+ end
21
+ end
22
+
23
+ def delete(output_path)
24
+ File.delete(output_path)
25
+ dir_parts = output_path.split(File::SEPARATOR)[0..-2]
26
+ dir_parts.length.times do |index|
27
+ neg_index = -1 - index
28
+ path = dir_parts[0..neg_index].join(File::SEPARATOR)
29
+ if Dir.entries(path).empty?
30
+ Dir.rmdir(path)
31
+ else
32
+ break
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,87 @@
1
+ require 'optparse'
2
+ require 'fileutils'
3
+ require 'skyrocket'
4
+
5
+ module Skyrocket
6
+ # CMD execution controller
7
+ class Cmd
8
+ COMMANDS = %w(compile init watch)
9
+
10
+ def initialize(argv)
11
+ @options = {
12
+ :asset_dirs => Array.new,
13
+ :lib_dirs => Array.new,
14
+ :output_dir => './public',
15
+ :base_url => '/',
16
+ :style => :raw
17
+ }
18
+
19
+ parser.parse!(argv)
20
+ @command = argv.shift
21
+ @arguments = argv
22
+
23
+ @options[:asset_dirs] << './assets/public' unless @options[:asset_dirs].length > 0
24
+ @options[:lib_dirs] << './assets/lib' unless @options[:lib_dirs].length > 0
25
+ end
26
+
27
+ def parser
28
+ @parser ||= OptionParser.new do |opts|
29
+ opts.banner = "Usage: skyrocket [options] #{COMMANDS.join('|')}"
30
+
31
+ opts.separator ""
32
+ opts.separator "Options:"
33
+ opts.on("-s", "--style MODE", "Compilation style ('concat' for concat only, 'minify' for concat and minification, default 'raw' for neither)") do |style|
34
+ @options[:style] = style.to_sym
35
+ end
36
+ opts.on("-b", "--base URL", "Base url for assets location/ link generation") { |base| @options[:base_url] = base }
37
+ opts.on("-a", "--asset DIR", "Assets directory. Use more than once for multiple assets directories") { |asset| @options[:asset_dirs] << asset }
38
+ opts.on("-l", "--asset-lib DIR", "Asset lib directory. Use more than once for multiple lib directories") { |lib| @options[:lib_dirs] << lib }
39
+ opts.on("-o", "--output DIR", "Output directory for compiled assets.") { |output| @options[:output_dir] = output}
40
+
41
+ opts.on_tail("-h", "-?", "--help", "Show this message") { puts opts; exit }
42
+ opts.on_tail("-v", "--version", "Show version") { puts Skyrocket::VERSION; exit }
43
+ end
44
+ end
45
+
46
+ def format_results(action, asset_name)
47
+ case action
48
+ when :deleted
49
+ puts " \e[31;40m** Deleted **\e[0m #{asset_name}"
50
+ when :created
51
+ puts " \e[32;40m** Created **\e[0m #{asset_name}"
52
+ when :modified
53
+ puts " \e[33;40m** Modified **\e[0m #{asset_name}"
54
+ end
55
+ end
56
+
57
+ def run
58
+ if COMMANDS.include?(@command)
59
+ am = AssetManager.new(@options)
60
+ case @command
61
+ when "compile"
62
+ am.compile(&method(:format_results))
63
+ when "init"
64
+ @options[:asset_dirs].each{ |dir| FileUtils.mkdir_p(dir) }
65
+ @options[:lib_dirs].each{ |dir| FileUtils.mkdir_p(dir) }
66
+ FileUtils.mkdir_p(@options[:output_dir])
67
+ when "watch"
68
+ trap("SIGINT") do
69
+ puts "Ending watch..."
70
+ exit!
71
+ end
72
+ begin
73
+ am.watch(&method(:format_results))
74
+ rescue Gem::LoadError => e
75
+ puts "'watch' command requires the gem '#{e.name}' of version '#{e.requirement}'' be installed."
76
+ end
77
+ end
78
+ elsif @command.nil?
79
+ puts "Command required"
80
+ puts @parser
81
+ exit 1
82
+ else
83
+ abort "Unknown command: #{@command}. Valid commands include: #{COMMANDS.join(', ')}"
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,13 @@
1
+ require 'coffee-script'
2
+
3
+ module Skyrocket
4
+ class CoffeescriptProcessor
5
+ include Processor
6
+
7
+ def extension; '.coffee'; end
8
+
9
+ def process(contents)
10
+ CoffeeScript.compile(contents)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ class Dir
2
+ def self.glob_files(pattern, flags = nil)
3
+ if block_given?
4
+ Dir.glob(pattern, flags || 0) do |filename|
5
+ if File.file?(filename)
6
+ yield(filename)
7
+ end
8
+ end
9
+ else
10
+ Dir.glob(pattern, flags || 0).select { |f| File.file?(f) }
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ module Skyrocket
2
+ class EmptyProcessor
3
+ include Processor
4
+
5
+ def extension; ''; end
6
+ def process(contents); contents; end;
7
+
8
+ end
9
+ end
@@ -0,0 +1,100 @@
1
+ require 'erb'
2
+
3
+ module Skyrocket
4
+ class ErbProcessor
5
+ include Processor
6
+
7
+ def extension; '.erb'; end
8
+
9
+ def process(contents)
10
+ template = ERB.new(contents, nil, '-', '@out')
11
+ results = template.result(get_binding { |name=nil| '' })
12
+ if(@layout)
13
+ outer_contents = asset_factory.from_name(@layout).raw
14
+ outer_template = ERB.new(outer_contents, nil, '-', '@out')
15
+ results = outer_template.result(get_binding do |name=nil|
16
+ if name == nil
17
+ results
18
+ else
19
+ @content_for[name.to_sym]
20
+ end
21
+ end)
22
+ end
23
+ results
24
+ end
25
+
26
+ def get_binding
27
+ binding
28
+ end
29
+
30
+ def layout(name)
31
+ @layout = name
32
+ nil
33
+ end
34
+
35
+ def stylesheet_link_tag(path)
36
+ "<link rel=\"stylesheet\" href=\"#{resolve(path)}\">"
37
+ end
38
+
39
+ def javascript_include_tag(path)
40
+ "<script src=\"#{resolve(path)}\"></script>"
41
+ end
42
+
43
+ def link_to(content, path, options)
44
+ opt_s = to_opt_s(options)
45
+ "<a href=\"#{resolve(path)}\"#{opt_s}>#{content}</a>"
46
+ end
47
+
48
+ def image_tag(path, options)
49
+ opt_s = to_opt_s(options)
50
+ "<img src=\"#{resolve(path)}\"#{opt_s} />"
51
+ end
52
+
53
+ def href(path)
54
+ resolve(path)
55
+ end
56
+
57
+ def content_for(key)
58
+ # swap current ERB output buffer with a 'fake' buffer
59
+ # otherwise calling yield will write contents of block
60
+ # to ERB results output
61
+ old = @out
62
+ @out = ''
63
+ results = yield.chomp
64
+ @out = old
65
+ @content_for ||= Hash.new
66
+ @content_for[key.to_sym] = results
67
+ nil
68
+ end
69
+
70
+ def render(asset_name)
71
+ contents = asset_factory.from_name(asset_name).raw
72
+ old = @out # save current ERB buffer
73
+ @out = ''
74
+ template = ERB.new(contents, nil, '-', '@out')
75
+ results = template.result(get_binding do |name=nil|
76
+ if name == nil
77
+ results
78
+ else
79
+ @content_for[name.to_sym]
80
+ end
81
+ end)
82
+ @out = old
83
+ results
84
+ end
85
+
86
+ private
87
+ def resolve(path)
88
+ if(path.start_with?("/") || path =~ /^\w+:\/\//)
89
+ path
90
+ else
91
+ base_url == '/' ? "#{base_url}#{path}" : "#{base_url}/#{path}"
92
+ end
93
+ end
94
+
95
+ def to_opt_s(options)
96
+ opt_s = options.keys.map{ |k| "#{k}=\"#{options[k]}\"" }.join(' ')
97
+ opt_s = " " + opt_s unless opt_s == ''
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,5 @@
1
+ module Skyrocket
2
+ class AssetNotFoundError < Exception; end;
3
+ class PathNotInAssetsError < Exception; end;
4
+ class NoValidProcessorError < Exception; end;
5
+ end
@@ -0,0 +1,5 @@
1
+ class File
2
+ def self.write_file(file, string)
3
+ File.open(file, 'w') { |f| f.write(string) }
4
+ end
5
+ end
@@ -0,0 +1,19 @@
1
+ require 'less'
2
+
3
+ module Skyrocket
4
+ class LessProcessor
5
+ include Processor
6
+
7
+ def extension; '.less'; end
8
+
9
+ def process(contents)
10
+ tree = parser.parse(contents)
11
+ tree.to_css
12
+ end
13
+
14
+ private
15
+ def parser
16
+ @@parser ||= Less::Parser.new(:paths => asset_factory.asset_dirs + asset_factory.lib_dirs)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,36 @@
1
+ module Skyrocket
2
+ module Processor
3
+ def extension
4
+ raise NotImplimentedError.new("must impliment #{caller[0][/`.*'/][1..-2]} for #{self.class.name}")
5
+ end
6
+
7
+ def process(contents)
8
+ raise NotImplimentedError.new("must impliment #{caller[0][/`.*'/][1..-2]} for #{self.class.name}")
9
+ end
10
+
11
+ def process?(file)
12
+ ext = File.extname(file)
13
+ (ext =~ /#{extension}$/) != nil
14
+ end
15
+
16
+ def post_process_name(file)
17
+ file.chomp(extension)
18
+ end
19
+
20
+ def self.asset_factory=(asset_factory)
21
+ @@af = asset_factory
22
+ end
23
+
24
+ def asset_factory
25
+ @@af
26
+ end
27
+
28
+ def self.base_url=(base_url)
29
+ @@bu = base_url
30
+ end
31
+
32
+ def base_url
33
+ @@bu
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,28 @@
1
+ module Skyrocket
2
+ class ProcessorFactory
3
+
4
+ PROCESSORS = [ CoffeescriptProcessor, ErbProcessor, LessProcessor, EmptyProcessor ]
5
+
6
+ def process?(filename)
7
+ PROCESSORS.each do |processor|
8
+ return true if processor.new.process?(filename)
9
+ end
10
+ return false
11
+ end
12
+
13
+ def post_process_name(filename)
14
+ if process?(filename)
15
+ processor(filename).post_process_name(filename)
16
+ else
17
+ filename
18
+ end
19
+ end
20
+
21
+ def processor(filename)
22
+ PROCESSORS.each do |processor|
23
+ return processor.new if processor.new.process?(filename)
24
+ end
25
+ raise NoValidProcessorError
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,3 @@
1
+ module Skyrocket
2
+ VERSION = "0.0.1"
3
+ end
data/lib/skyrocket.rb ADDED
@@ -0,0 +1,19 @@
1
+ require 'skyrocket/version'
2
+
3
+ module Skyrocket
4
+ autoload :Asset, "skyrocket/asset"
5
+ autoload :AssetLocator, "skyrocket/asset_locator"
6
+ autoload :AssetFactory, "skyrocket/asset_factory"
7
+ autoload :AssetManager, "skyrocket/asset_manager"
8
+ autoload :AssetWriter, "skyrocket/asset_writer"
9
+ autoload :CoffeescriptProcessor, "skyrocket/coffeescript_processor"
10
+ autoload :EmptyProcessor, "skyrocket/empty_processor"
11
+ autoload :ErbProcessor, "skyrocket/erb_processor"
12
+ autoload :LessProcessor, "skyrocket/less_processor"
13
+ autoload :Processor, "skyrocket/processor"
14
+ autoload :ProcessorFactory, "skyrocket/processor_factory"
15
+
16
+ autoload :AssetNotFoundError, "skyrocket/errors"
17
+ autoload :NoValidProcessorError, "skyrocket/errors"
18
+ autoload :PathNotInAssetsError, "skyrocket/errors"
19
+ end
metadata ADDED
@@ -0,0 +1,134 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: skyrocket
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Michael Wasser
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-09 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: therubyracer
16
+ requirement: &70197185909260 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70197185909260
25
+ - !ruby/object:Gem::Dependency
26
+ name: less
27
+ requirement: &70197185908840 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70197185908840
36
+ - !ruby/object:Gem::Dependency
37
+ name: coffee-script
38
+ requirement: &70197185908420 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70197185908420
47
+ - !ruby/object:Gem::Dependency
48
+ name: rack-test
49
+ requirement: &70197185908000 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70197185908000
58
+ - !ruby/object:Gem::Dependency
59
+ name: rspec
60
+ requirement: &70197185907500 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: '2.0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70197185907500
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: &70197185907080 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70197185907080
80
+ description: An alternative and opinionated static content/ asset management tool
81
+ that will concatenate/ render javascript, coffeescript, css, less, erb and html
82
+ email:
83
+ - michael@raveld.com
84
+ executables:
85
+ - skyrocket
86
+ extensions: []
87
+ extra_rdoc_files: []
88
+ files:
89
+ - README.md
90
+ - LICENSE
91
+ - lib/skyrocket/asset.rb
92
+ - lib/skyrocket/asset_factory.rb
93
+ - lib/skyrocket/asset_loader.rb
94
+ - lib/skyrocket/asset_locator.rb
95
+ - lib/skyrocket/asset_manager.rb
96
+ - lib/skyrocket/asset_writer.rb
97
+ - lib/skyrocket/cmd.rb
98
+ - lib/skyrocket/coffeescript_processor.rb
99
+ - lib/skyrocket/dir_ext.rb
100
+ - lib/skyrocket/empty_processor.rb
101
+ - lib/skyrocket/erb_processor.rb
102
+ - lib/skyrocket/errors.rb
103
+ - lib/skyrocket/file_ext.rb
104
+ - lib/skyrocket/less_processor.rb
105
+ - lib/skyrocket/processor.rb
106
+ - lib/skyrocket/processor_factory.rb
107
+ - lib/skyrocket/version.rb
108
+ - lib/skyrocket.rb
109
+ - bin/skyrocket
110
+ homepage: http://www.raveld.com/
111
+ licenses: []
112
+ post_install_message:
113
+ rdoc_options: []
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ none: false
118
+ requirements:
119
+ - - ! '>='
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ! '>='
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ requirements: []
129
+ rubyforge_project:
130
+ rubygems_version: 1.8.15
131
+ signing_key:
132
+ specification_version: 3
133
+ summary: Yet another opinionated static content/ web asset generation system
134
+ test_files: []