Class: Guard::Sass

Inherits:
Guard
  • Object
show all
Defined in:
lib/guard/sass.rb,
lib/guard/sass/runner.rb,
lib/guard/sass/importer.rb,
lib/guard/sass/formatter.rb

Defined Under Namespace

Classes: Formatter, Importer, Runner

Constant Summary collapse

DEFAULTS =
{
  :all_on_start => false,
  :output       => 'css',
  :extension    => '.css',
  :style        => :nested,
  :shallow      => false,
  :line_numbers => false,
  :debug_info   => false,
  :noop         => false,
  :hide_success => false,
  :load_paths   => ::Sass::Plugin.template_location_array.map(&:first)
}

Instance Method Summary collapse

Constructor Details

#initialize(watchers = [], options = {}) ⇒ Sass

Returns a new instance of Sass.

Parameters:

  • watchers (Array<Guard::Watcher>) (defaults to: [])
  • options (Hash) (defaults to: {})

Options Hash (options):

  • :input (String)

    The input directory

  • :output (String)

    The output directory

  • :extension (String)

    The extension to replace the ‘.sss’ part of the file name with

  • :load_paths (Array<String>)

    List of directories you can @import from

  • :shallow (Boolean)

    Whether to output nested directories

  • :line_numbers (Boolean)

    Whether to output human readable line numbers as comments in the file

  • :debug_info (Boolean)

    Whether to output file and line number info for FireSass

  • :noop (Boolean)

    Whether to run in “asset pipe” mode, no ouput, just validation

  • :hide_success (Boolean)

    Whether to hide all success messages

  • :style (Symbol)


46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/guard/sass.rb', line 46

def initialize(watchers=[], options={})
  load_paths = options.delete(:load_paths) || []

  if options[:input]
    load_paths << options[:input]
    options[:output] = options[:input] unless options.has_key?(:output)
    watchers << ::Guard::Watcher.new(%r{^#{ options[:input] }/(.+\.s[ac]ss)$})
  end
  options = DEFAULTS.merge(options)

  if compass = options.delete(:compass)
    require 'compass'
    compass = {} unless compass.is_a?(Hash)

    Compass.configuration.project_path   ||= Dir.pwd

    compass.each do |key, value|
      Compass.configuration.send("#{key}=".to_sym, value)

      if key.to_s.include?('dir') && !key.to_s.include?('http')
        options[:load_paths] << value
      end
    end

    Compass.configuration.asset_cache_buster = Proc.new {|*| {:query => Time.now.to_i} }
    options[:load_paths] ||= []
    options[:load_paths] << Compass.configuration.sass_load_paths
  end

  options[:load_paths] += load_paths
  options[:load_paths].flatten!

  @formatter = Formatter.new(:hide_success => options[:hide_success])
  @runner = Runner.new(watchers, @formatter, options)
  super(watchers, options)
end

Instance Method Details

#filesArray<String>

Returns Paths of all sass/scss files.

Returns:

  • (Array<String>)

    Paths of all sass/scss files



84
85
86
# File 'lib/guard/sass.rb', line 84

def files
  Watcher.match_files self, Dir['**/*.s[ac]ss']
end

#partial?(path) ⇒ Boolean

Returns Whether path is a partial.

Returns:

  • (Boolean)

    Whether path is a partial



159
160
161
# File 'lib/guard/sass.rb', line 159

def partial?(path)
  File.basename(path).start_with? '_'
end

#resolve_partials_to_owners(paths) ⇒ Object



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/guard/sass.rb', line 102

def resolve_partials_to_owners(paths)
  # Get all files that might have imports
  search_files = Dir.glob("#{options[:input]}/**/*.s[ac]ss")
  search_files = Watcher.match_files(self, search_files)

  # Get owners
  owners = search_files.select do |file|
    deps = []
     begin
       # Get dependencies of file
       deps = ::Sass::Engine.for_file(file, @options).dependencies.collect! {|dep| dep.options[:filename] }

     rescue ::Sass::SyntaxError => e
       message = "Resolving partial owners of #{file} failed"
       @formatter.error "Sass > #{e.sass_backtrace_str(file)}", :notification => message
     end

     # Find intersection with paths
     deps_in_paths = deps.intersection paths
     # Any paths in the dependencies?
     !deps_in_paths.empty?
  end

  # Return our resolved set of paths to recompile
  owners
end

#run_allObject

Build all files being watched

Raises:

  • (:task_has_failed)


98
99
100
# File 'lib/guard/sass.rb', line 98

def run_all
  run_on_changes files.reject {|f| partial?(f) }
end

#run_on_changes(paths) ⇒ Object

Builds the files given. If a ‘partial’ file is found (name begins with ‘_’), calls #run_with_partials so that files which include it are rebuilt.

Parameters:

  • paths (Array<String>)

Raises:

  • (:task_has_failed)


144
145
146
147
148
149
150
# File 'lib/guard/sass.rb', line 144

def run_on_changes(paths)
  return run_with_partials(paths) if paths.any? {|f| partial?(f) }

  changed_files, success = @runner.run(paths)

  throw :task_has_failed unless success
end

#run_on_removals(paths) ⇒ Object

Restore previous behaviour, when a file is removed we don’t want to call #run_on_changes.



154
155
156
# File 'lib/guard/sass.rb', line 154

def run_on_removals(paths)

end

#run_with_partials(paths) ⇒ Object



129
130
131
132
133
134
135
136
# File 'lib/guard/sass.rb', line 129

def run_with_partials(paths)
  if options[:smart_partials]
    paths = resolve_partials_to_owners(paths)
    run_on_changes Watcher.match_files(self, paths) unless paths.nil?
  else
    run_all
  end
end

#startObject

If option set to run all on start, run all when started.

Raises:

  • (:task_has_failed)


91
92
93
# File 'lib/guard/sass.rb', line 91

def start
  run_all if options[:all_on_start]
end