html_mockup 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/mockup CHANGED
File without changes
@@ -6,29 +6,32 @@ require 'fileutils'
6
6
  include FileUtils
7
7
 
8
8
  require File.dirname(__FILE__) + "/template"
9
+ require File.dirname(__FILE__) + "/project"
9
10
  require File.dirname(__FILE__) + "/w3c_validator"
10
11
 
11
12
  module HtmlMockup
12
13
  class Cli < Thor
13
14
  desc "serve [directory]","Serve directory as HTML, defaults to current directory"
14
15
  method_options :port => :string, # Defaults to 9000
15
- :partial_path => :string, # Defaults to [directory]/../partials
16
- :validate => :boolean, # Automatically validate all HTML responses @ the w3c
16
+ :html_path => :string, # The document root, defaults to "[directory]/html"
17
+ :partial_path => :string, # Defaults to [directory]/partials
17
18
  :handler => :string # The handler to use (defaults to mongrel)
18
- def serve(path=".")
19
- require File.dirname(__FILE__) + '/server'
19
+ def serve(path=".")
20
+ # Load the project, it should take care of all the paths
21
+ @project = initialize_project(path, options)
20
22
 
21
- @path,@partial_path = template_paths(path,options["partial_path"])
23
+ server = @project.server
22
24
 
23
- server_options = {}
24
- server_options[:Port] = options["port"] || "9000"
25
-
26
- server = Server.new(@path,@partial_path,options,server_options)
27
-
28
- puts "Running HtmlMockup with #{server.handler.inspect} on port #{server_options[:Port]}"
29
- puts " Taking partials from #{@partial_path} (#{HtmlMockup::Template.partial_files(@partial_path).size} found)"
25
+ puts "Running HtmlMockup with #{server.handler.inspect} on port #{server.port}"
26
+ puts banner(@project)
30
27
 
31
- server.run
28
+ server.run!
29
+ end
30
+
31
+ desc "release [directory]", "Create a release for the project"
32
+ def release(path=".")
33
+ project = initialize_project(path, options)
34
+ project.release.run!
32
35
  end
33
36
 
34
37
  desc "validate [directory/file]", "Validates the file or all HTML in directory"
@@ -84,72 +87,35 @@ module HtmlMockup
84
87
  end
85
88
  end
86
89
 
87
- desc "convert [directory]","Inject all partials, into all HTML files within directory"
88
- method_options :partial_path => :string, # Defaults to [directory]/../partials
89
- :filter => :string # What files should be converted defaults to **/*.html
90
- def convert(path=".")
91
- path,partial_path = template_paths(path,options["partial_path"])
92
- filter = options["filter"] || "**/*.html"
93
- puts "Converting #{filter} in #{path}"
94
- puts " Taking partials from #{partial_path} (#{HtmlMockup::Template.partial_files(partial_path).size} found)"
95
-
96
- if path.directory?
97
- Dir.glob("#{path}/#{filter}").each do |file|
98
- puts " Converting file: " + file
99
- HtmlMockup::Template.open(file, :partial_path => partial_path).save
100
- end
101
- else
102
- HtmlMockup::Template.open(path, :partial_path => partial_path).save
103
- end
104
-
105
- end
106
-
107
90
  desc "extract [source_path] [target_path]", "Extract a fully relative html mockup into target_path. It will expand all absolute href's, src's and action's into relative links if they are absolute"
108
- method_options :partial_path => :string, # Defaults to [directory]/../partials
91
+ method_options :partial_path => :string, # Defaults to [directory]/partials
109
92
  :filter => :string # What files should be converted defaults to **/*.html
110
- def extract(source_path=".",target_path="../out")
111
- require 'hpricot'
112
- source_path,target_path = Pathname.new(source_path),Pathname.new(target_path)
113
- source_path,partial_path = template_paths(source_path,options["partial_path"])
114
- filter = options["filter"] || "**/*.html"
115
- raise "Target #{target_path} already exists, please choose a new directory to extract into" if target_path.exist?
116
-
117
- mkdir_p(target_path)
118
- target_path = target_path.realpath
119
-
120
- # Copy source to target first, we'll overwrite the templates later on.
121
- cp_r(source_path.children,target_path)
122
-
123
- Dir.chdir(source_path) do
124
- Dir.glob(filter).each do |file_name|
125
- source = HtmlMockup::Template.open(file_name, :partial_path => partial_path).render
126
- cur_dir = Pathname.new(file_name).dirname
127
- up_to_root = File.join([".."] * (file_name.split("/").size - 1))
128
- doc = Hpricot(source)
129
- %w{src href action}.each do |attribute|
130
- (doc/"*[@#{attribute}]").each do |tag|
131
- next unless tag[attribute] =~ /\A\//
132
- if true_file = resolve_path(cur_dir + up_to_root + tag[attribute].sub(/\A\//,""))
133
- tag[attribute] = true_file.relative_path_from(cur_dir).to_s
134
- else
135
- puts "Could not resolve link #{tag[attribute]} in #{file_name}"
136
- end
137
- end
138
- end
139
-
140
- File.open(target_path + file_name,"w"){|f| f.write(doc.to_original_html) }
141
- end
142
- end
93
+ def extract(source_path=".", target_path="../out")
94
+ project = initialize_project(source_path)
95
+ extractor = HtmlMockup::Extractor.new(project, target_path)
96
+ puts "Extracting mockup"
97
+ puts banner(project)
98
+ extractor.run!
143
99
  end
144
100
 
145
101
  protected
146
102
 
147
- def template_paths(path,partial_path=nil)
148
- path = Pathname.new(path)
149
- partial_path = partial_path && Pathname.new(partial_path) || (path + "../partials/").realpath
150
- [path,partial_path]
103
+ def banner(project)
104
+ puts " Html: \"#{project.html_path}\""
105
+ puts " Partials: \"#{project.partial_path}\" (#{HtmlMockup::Template.partial_files(project.partial_path).size} found)"
151
106
  end
152
107
 
108
+ # TODO: handle options
109
+ def initialize_project(path, options={})
110
+
111
+ if((Pathname.new(path) + "../partials").exist?)
112
+ puts "[ERROR]: Don't use the \"html\" path, use the project base path instead"
113
+ exit(1)
114
+ end
115
+
116
+ Project.new(path)
117
+ end
118
+
153
119
  def w3cvalidate(file)
154
120
  validator = W3CValidator.new(File.read(file))
155
121
  validator.validate!
@@ -160,19 +126,6 @@ module HtmlMockup
160
126
  validator.valid
161
127
  end
162
128
 
163
- def resolve_path(path)
164
- path = Pathname.new(path) unless path.kind_of?(Pathname)
165
- # Append index.html/index.htm/index.rhtml if it's a diretory
166
- if path.directory?
167
- search_files = %w{.html .htm}.map!{|p| path + "index#{p}" }
168
- # If it ends with a slash or does not contain a . and it's not a directory
169
- # try to add .html/.htm/.rhtml to see if that exists.
170
- elsif (path.to_s =~ /\/$/) || (path.to_s =~ /^[^.]+$/)
171
- search_files = [path.to_s + ".html", path.to_s + ".htm"].map!{|p| Pathname.new(p) }
172
- else
173
- search_files = [path]
174
- end
175
- search_files.find{|p| p.exist? }
176
- end
129
+
177
130
  end
178
131
  end
@@ -0,0 +1,100 @@
1
+ require 'hpricot'
2
+
3
+ module HtmlMockup
4
+ class Extractor
5
+
6
+ attr_reader :project, :target_path
7
+
8
+ def initialize(project, target_path)
9
+ @project = project
10
+ @target_path = Pathname.new(target_path)
11
+ end
12
+
13
+ def run!
14
+ target_path = self.target_path
15
+ source_path, partial_path = self.project.html_path, self.project.partial_path
16
+
17
+
18
+ filter = "**/*.html"
19
+ raise ArgumentError, "Target #{target_path} already exists, please choose a new directory to extract into" if target_path.exist?
20
+
21
+ mkdir_p(target_path)
22
+ target_path = target_path.realpath
23
+
24
+ # Copy source to target first, we'll overwrite the templates later on.
25
+ cp_r(source_path.children, target_path)
26
+
27
+ Dir.chdir(source_path) do
28
+ Dir.glob(filter).each do |file_name|
29
+ source = HtmlMockup::Template.open(file_name, :partial_path => partial_path).render
30
+ cur_dir = Pathname.new(file_name).dirname
31
+ up_to_root = File.join([".."] * (file_name.split("/").size - 1))
32
+ doc = Hpricot(source)
33
+ %w{src href action}.each do |attribute|
34
+ (doc/"*[@#{attribute}]").each do |tag|
35
+ converted_url = convert_relative_url_to_absolute_url(tag[attribute], cur_dir, up_to_root)
36
+
37
+ case converted_url
38
+ when String
39
+ tag[attribute] = converted_url
40
+ when nil
41
+ puts "Could not resolve link #{tag[attribute]} in #{file_name}"
42
+ end
43
+ end
44
+ end
45
+
46
+ File.open(target_path + file_name,"w"){|f| f.write(doc.to_original_html) }
47
+ end
48
+ end
49
+ end
50
+
51
+
52
+ protected
53
+
54
+ # @return [false, nil, String] False if it can't be converted, nil if it can't be resolved and the converted string if it can be resolved.
55
+ def convert_relative_url_to_absolute_url(url, cur_dir, up_to_root)
56
+ # Skip if the url doesn't start with a / (but not with //)
57
+ return false unless url =~ /\A\/[^\/]/
58
+
59
+ # Strip off anchors
60
+ anchor = nil
61
+ url.gsub!(/(#.+)\Z/) do |r|
62
+ anchor = r
63
+ ""
64
+ end
65
+
66
+ # Strip off query strings
67
+ query = nil
68
+ url.gsub!(/(\?.+)\Z/) do |r|
69
+ query = r
70
+ ""
71
+ end
72
+
73
+ if true_file = resolve_path(cur_dir + up_to_root + url.sub(/\A\//,""))
74
+ url = true_file.relative_path_from(cur_dir).to_s
75
+ url += query if query
76
+ url += anchor if anchor
77
+ url
78
+ else
79
+ nil
80
+ end
81
+
82
+ end
83
+
84
+ def resolve_path(path)
85
+ path = Pathname.new(path) unless path.kind_of?(Pathname)
86
+ # Append index.html/index.htm/index.rhtml if it's a diretory
87
+ if path.directory?
88
+ search_files = %w{.html .htm}.map!{|p| path + "index#{p}" }
89
+ # If it ends with a slash or does not contain a . and it's not a directory
90
+ # try to add .html/.htm to see if that exists.
91
+ elsif (path.to_s =~ /\/$/) || (path.to_s =~ /^[^.]+$/)
92
+ search_files = [path.to_s + ".html", path.to_s + ".htm"].map!{|p| Pathname.new(p) }
93
+ else
94
+ search_files = [path]
95
+ end
96
+ search_files.find{|p| p.exist? }
97
+ end
98
+
99
+ end
100
+ end
@@ -0,0 +1,63 @@
1
+ module HtmlMockup
2
+ # Loader for mockupfile
3
+ class Mockupfile
4
+
5
+ # This is the context for the mockupfile evaluation. It should be empty except for the
6
+ # #mockup method.
7
+ class Context
8
+
9
+ def initialize(mockupfile)
10
+ @_mockupfile = mockupfile
11
+ end
12
+
13
+ def mockup
14
+ @_mockupfile
15
+ end
16
+
17
+ def binding
18
+ ::Kernel.binding
19
+ end
20
+
21
+ end
22
+
23
+ # @attr :path [Pathname] The path of the Mockupfile for this project
24
+ attr_accessor :path, :project
25
+
26
+ def initialize(project)
27
+ @project = project
28
+ @path = Pathname.new(project.path + "Mockupfile")
29
+ end
30
+
31
+ # Actually load the mockupfile
32
+ def load
33
+ if File.exist?(@path) && !self.loaded?
34
+ @source = File.read(@path)
35
+ context = Context.new(self)
36
+ eval @source, context.binding
37
+ @loaded = true
38
+ end
39
+ end
40
+
41
+ # Wether or not the Mockupfile has been loaded
42
+ def loaded?
43
+ @loaded
44
+ end
45
+
46
+ def release
47
+ if block_given?
48
+ yield(self.project.release)
49
+ end
50
+ self.project.release
51
+ end
52
+
53
+ def serve
54
+ if block_given?
55
+ yield(self.project.server)
56
+ end
57
+ self.project.server
58
+ end
59
+
60
+ alias :server :serve
61
+
62
+ end
63
+ end
@@ -0,0 +1,54 @@
1
+ require File.dirname(__FILE__) + "/release"
2
+ require File.dirname(__FILE__) + "/server"
3
+ require File.dirname(__FILE__) + "/mockupfile"
4
+
5
+ module HtmlMockup
6
+ # Loader for mockupfile
7
+ class Project
8
+
9
+ # @attr :path [Pathname] The project path
10
+ # @attr :html_path [Pathname] The path of the HTML mockup
11
+ # @attr :partial_path [Pathname] The path for the partials for this mockup
12
+ # @attr :mockupfile [Mockupfile] The Mockupfile for this project
13
+ attr_accessor :path, :html_path, :partial_path, :mockupfile
14
+
15
+ def initialize(path, options={})
16
+ @path = Pathname.new(path)
17
+
18
+ options = {
19
+ :html_path => @path + "html",
20
+ :partial_path => @path + "partials"
21
+ }.update(options)
22
+
23
+ html_path, partial_path = mockup_paths(options[:html_path], options[:partial_path])
24
+ @mockupfile = Mockupfile.new(self)
25
+ @mockupfile.load
26
+ end
27
+
28
+ def server
29
+ @server ||= Server.new(self.html_path, self.partial_path)
30
+ end
31
+
32
+ def release
33
+ @release ||= Release.new(self)
34
+ end
35
+
36
+ def html_path=(p)
37
+ @html_path = Pathname.new(p).realpath
38
+ end
39
+
40
+ def partial_path=(p)
41
+ @partial_path = Pathname.new(p).realpath
42
+ end
43
+
44
+ protected
45
+
46
+ def mockup_paths(html_path, partial_path = nil)
47
+ html_path = Pathname.new(html_path)
48
+ partial_path = partial_path && Pathname.new(partial_path) || (html_path + "../partials/")
49
+ [html_path, partial_path]
50
+ end
51
+
52
+
53
+ end
54
+ end
@@ -14,16 +14,18 @@ module HtmlMockup
14
14
  def call(env)
15
15
  path = env["PATH_INFO"]
16
16
 
17
- # Append index.html/index.htm/index.rhtml if it's a diretory
17
+ # TODO: Combine with Extractor#resolve_path
18
+
19
+ # Append index.html/index.htm if it's a diretory
18
20
  if File.directory?(File.join(@docroot,path))
19
- search_files = %w{.html .htm .rhtml}.map!{|p| File.join(@docroot,path,"index#{p}")}
20
- # If it's already a .html/.htm/.rhtml file, render that file
21
- elsif (path =~ /\.r?html?$/)
21
+ search_files = %w{.html .htm}.map!{|p| File.join(@docroot,path,"index#{p}")}
22
+ # If it's already a .html/.htm file, render that file
23
+ elsif (path =~ /\.html?$/)
22
24
  search_files = [File.join(@docroot,path)]
23
25
  # If it ends with a slash or does not contain a . and it's not a directory
24
- # try to add .html/.htm/.rhtml to see if that exists.
26
+ # try to add .html/.htm to see if that exists.
25
27
  elsif (path =~ /\/$/) || (path =~ /^[^.]+$/)
26
- search_files = [path + ".html", path + ".htm", path + ".rhtml"].map!{|p| File.join(@docroot,p) }
28
+ search_files = [path + ".html", path + ".htm"].map!{|p| File.join(@docroot,p) }
27
29
  # Otherwise don't render anything at all.
28
30
  else
29
31
  search_files = []
@@ -0,0 +1,21 @@
1
+ module HtmlMockup
2
+ module Rack
3
+ # Listens to the "sleep" parameter and sleeps the amount of seconds specified by the parameter. There is however a maximum of 5 seconds.
4
+ class Sleep
5
+
6
+ def initialize(app)
7
+ @app = app
8
+ end
9
+
10
+ def call(env)
11
+ r = Rack::Request.new(env)
12
+ if r.params["sleep"]
13
+ sleeptime = [r.params["sleep"].to_i, 5].min
14
+ sleep sleeptime
15
+ end
16
+ @app.call(env)
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,24 @@
1
+ require 'fileutils'
2
+
3
+ # Finalizes the release into a directory in target_path
4
+ #
5
+ # The directory name will have the format PREFIX-VERSION
6
+ #
7
+ module HtmlMockup::Release::Finalizers
8
+ class Dir < Base
9
+
10
+ # @option options :prefix Prefix to put before the version (default = "html")
11
+ def call(release, options = {})
12
+ name = [(options[:prefix] || "html"), release.scm.version].join("-")
13
+
14
+ release.log(self, "Finalizing release to #{release.target_path + name}")
15
+
16
+ if File.exist?(release.target_path + name)
17
+ release.log(self, "Removing existing target #{release.target_path + name}")
18
+ FileUtils.rm_rf(release.target_path + name)
19
+ end
20
+
21
+ FileUtils.cp_r release.build_path, release.target_path + name
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,4 @@
1
+ module HtmlMockup::Release::Finalizers
2
+ class Zip < Base
3
+ end
4
+ end
@@ -0,0 +1,11 @@
1
+ module HtmlMockup::Release::Finalizers
2
+ class Base
3
+ def call(release, options = {})
4
+ raise ArgumentError, "Implement in subclass"
5
+ end
6
+ end
7
+ end
8
+
9
+ require File.dirname(__FILE__) + "/finalizers/zip"
10
+ require File.dirname(__FILE__) + "/finalizers/dir"
11
+
@@ -0,0 +1,98 @@
1
+ require 'tilt'
2
+ module HtmlMockup
3
+
4
+ # Inject VERSION / DATE (i.e. in TOC)
5
+ # r.inject({"VERSION" => release.version, "DATE" => release.date}, :into => %w{_doc/toc.html})
6
+
7
+ # Inject CHANGELOG
8
+ # r.inject({"CHANGELOG" => {:file => "", :filter => BlueCloth}}, :into => %w{_doc/changelog.html})
9
+
10
+ class Release::Injector
11
+
12
+ # @example Simple variable injection (replaces [VARIABLE] into all .css files)
13
+ # {"[VARIABLE]" => "replacement"}, :into => %w{**/*.css}
14
+ #
15
+ # @example Regex variable injection (replaces all matches into test.js files)
16
+ # {/\/\*\s*\[BANNER\]\s*\*\// => "replacement"}, :into => %w{javacripts/test.js}
17
+ #
18
+ # @example Simple variable injection with filtering (replaces [VARIABLE] with :content run through the markdown processor into all .html files)
19
+ # {"[VARIABLE]" => {:content => "# header one", :processor => "md"}, :into => %w{**/*.html}
20
+ #
21
+ # @example Full file injection (replaces all matches of [CHANGELOG] with the contents of "CHANGELOG.md" into _doc/changelog.html)
22
+ #
23
+ # {"CHANGELOG" => {:file => "CHANGELOG.md"}}, :into => %w{_doc/changelog.html}
24
+ #
25
+ # @example Full file injection with filtering (replaces all matches of [CHANGELOG] with the contents of "CHANGELOG" which ran through Markdown compresser into _doc/changelog.html)
26
+ #
27
+ # {"CHANGELOG" => {:file => "CHANGELOG", :processor => "md"}}, :into => %w{_doc/changelog.html}
28
+ #
29
+ # Processors are based on Tilt (https://github.com/rtomayko/tilt).
30
+ # Currently supported/tested processors are:
31
+ #
32
+ # * 'md' for Markdown (bluecloth)
33
+ #
34
+ # Injection files are relative to the :source_path
35
+ #
36
+ # @param [Hash] variables Variables to inject. See example for more info
37
+ # @option options [Array] :into An array of file globs relative to the build_path
38
+ def initialize(variables, options)
39
+ @variables = variables
40
+ @into = options[:into]
41
+ end
42
+
43
+ def call(release)
44
+ files = release.get_files(@into)
45
+
46
+ files.each do |f|
47
+ c = File.read(f)
48
+ injected_vars = []
49
+ @variables.each do |variable, injection|
50
+ if c.gsub!(variable, get_content(injection, release))
51
+ injected_vars << variable
52
+ end
53
+ end
54
+ release.log(self, "Injected variables #{injected_vars.inspect} into #{f}") if injected_vars.size > 0
55
+ File.open(f,"w") { |fh| fh.write c }
56
+ end
57
+
58
+ end
59
+
60
+ def get_content(injection, release)
61
+ case injection
62
+ when String
63
+ injection
64
+ when Hash
65
+ get_complex_injection(injection, release)
66
+ else
67
+ if injection.respond_to?(:to_s)
68
+ injection.to_s
69
+ else
70
+ raise ArgumentError, "Woah, what's this? #{injection.inspect}"
71
+ end
72
+ end
73
+ end
74
+
75
+ def get_complex_injection(injection, release)
76
+
77
+ if injection[:file]
78
+ content = File.read(release.source_path + injection[:file])
79
+ else
80
+ content = injection[:content]
81
+ end
82
+
83
+ raise ArgumentError, "No :content or :file specified" if !content
84
+
85
+ if injection[:processor]
86
+ if tmpl = Tilt[injection[:processor]]
87
+ (tmpl.new{ content }).render
88
+ else
89
+ raise ArgumentError, "Unknown processor #{injection[:processor]}"
90
+ end
91
+ else
92
+ content
93
+ end
94
+
95
+ end
96
+
97
+ end
98
+ end
@@ -0,0 +1,54 @@
1
+ require 'fileutils'
2
+ module HtmlMockup::Release::Processors
3
+ class Requirejs < Base
4
+
5
+ # @option options [Hash] :build_files An a hash of files to build (as key) and the target directory in the release to put it as value, each one will be built in a separate directory. (default is {"javascripts/site.build.js" => "javascripts"})
6
+ # @option options [String] :node The system path for node (defaults to "node" in path)
7
+ # @option options [String] :rjs The system path to the requirejs optimizer (r.js) (defaults to "../vendor/requirejs/r.js" (relative to source_path))
8
+ def call(release, options={})
9
+ options = {
10
+ :build_files => {"javascripts/site.build.js" => "javascripts"},
11
+ :rjs => release.source_path + "../vendor/requirejs/r.js",
12
+ :node => "node"
13
+ }.update(options)
14
+
15
+ begin
16
+ `#{options[:node]} -v`
17
+ rescue Errno::ENOENT
18
+ raise RuntimeError, "Could not find node in #{node.inspect}"
19
+ end
20
+
21
+ if !File.exist?(options[:rjs])
22
+ raise RuntimeError, "Could not find r.js optimizer at #{options[:rjs].inspect}"
23
+ end
24
+
25
+ options[:build_files].each do |build_file, target|
26
+ build_file = release.build_path + build_file
27
+ target = release.build_path + target
28
+ release.log(self, "Optimizing #{build_file}")
29
+
30
+ # Hack to create tempfile in build
31
+ t = Tempfile.new("requirejs", release.build_path)
32
+ tmp_build_dir = t.path
33
+ t.close
34
+ t.unlink
35
+
36
+ # Run r.js optimizer
37
+ output = `#{options[:node]} #{options[:rjs]} -o #{build_file} dir=#{tmp_build_dir}`
38
+
39
+ # Check if r.js succeeded
40
+ unless $?.success?
41
+ raise RuntimeError, "Asset compilation with node failed.\nr.js output:\n #{output}"
42
+ end
43
+
44
+ if File.exist?(target)
45
+ release.log(self, "Removing target #{target}")
46
+ FileUtils.rm_rf(target)
47
+ end
48
+
49
+ # Move the tmp_build_dir to target
50
+ FileUtils.mv(tmp_build_dir, target)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,38 @@
1
+ # Use the sass gem
2
+ require 'sass'
3
+
4
+ module HtmlMockup::Release::Processors
5
+ class Sass < Base
6
+ # @param [Hash] options Options as described below, all other options will be passed to Sass.compile_file.
7
+ #
8
+ # @option options [Array] :match An array of shell globs, defaults to ["stylesheets/**/*.scss"]
9
+ # @option options [Array] :skip An array of regexps which will be skipped, defaults to [/_.*\.scss\Z/], Attention! Skipped files will be deleted as well!
10
+ def call(release, options={})
11
+ options = {
12
+ :match => ["stylesheets/**/*.scss"],
13
+ :skip => [/_.*\.scss\Z/],
14
+ :style => :expanded
15
+ }.update(options)
16
+
17
+ match = options.delete(:match)
18
+ skip = options.delete(:skip)
19
+
20
+ # Sassify SCSS files
21
+ files = release.get_files(match)
22
+ files.each do |f|
23
+ if !skip.detect{|r| r.match(f) }
24
+ release.log(self, "Processing: #{f}")
25
+ # Compile SCSS
26
+ ::Sass.compile_file(f, f.gsub(/\.scss$/, ".css"), options)
27
+ end
28
+ end
29
+
30
+ # Cleanup
31
+ files.each do |f|
32
+ # Remove source file
33
+ File.unlink(f)
34
+ end
35
+
36
+ end
37
+ end
38
+ end