skyrocket 0.0.1

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.
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: []