Class: Compass::Commands::WatchProject

Inherits:
UpdateProject show all
Includes:
MemoryDebugger
Defined in:
lib/compass/commands/watch_project.rb

Instance Attribute Summary collapse

Attributes inherited from ProjectBase

#options, #project_name

Attributes inherited from Base

#options, #working_path

Attributes included from Actions

#logger

Class Method Summary collapse

Instance Method Summary collapse

Methods included from MemoryDebugger

#report_on_instances

Methods inherited from UpdateProject

#check_for_sass_files!, #determine_cache_location, #dry_run?, #explicit_sass_files, #initialize, #new_compiler_instance, parse!, parse_arguments!, primary, usage

Methods inherited from ProjectBase

#execute, #initialize

Methods inherited from Base

#execute, #failed!, #initialize, register, #successful?

Methods included from Actions

#basename, #copy, #directory, #log_action, #process_erb, #relativize, #remove, #separate, #strip_trailing_separator, #write_file

Constructor Details

This class inherits a constructor from Compass::Commands::UpdateProject

Instance Attribute Details

#last_sass_filesObject

Returns the value of attribute last_sass_files.



57
58
59
# File 'lib/compass/commands/watch_project.rb', line 57

def last_sass_files
  @last_sass_files
end

#last_update_timeObject

Returns the value of attribute last_update_time.



57
58
59
# File 'lib/compass/commands/watch_project.rb', line 57

def last_update_time
  @last_update_time
end

Class Method Details

.description(command) ⇒ Object



156
157
158
# File 'lib/compass/commands/watch_project.rb', line 156

def description(command)
  "Compile Sass stylesheets to CSS when they change"
end

.option_parser(arguments) ⇒ Object



160
161
162
163
164
165
166
# File 'lib/compass/commands/watch_project.rb', line 160

def option_parser(arguments)
  parser = Compass::Exec::CommandOptionParser.new(arguments)
  parser.extend(Compass::Exec::GlobalOptionsParser)
  parser.extend(Compass::Exec::ProjectOptionsParser)
  parser.extend(CompileProjectOptionsParser)
  parser.extend(WatchProjectOptionsParser)
end

Instance Method Details

#performObject



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
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/compass/commands/watch_project.rb', line 61

def perform
  Signal.trap("INT") do
    puts ""
    exit 0
  end

  check_for_sass_files!(new_compiler_instance)
  recompile

  require 'fssm'


  if options[:poll]
    require "fssm/backends/polling"
    # have to silence the ruby warning about chaning a constant.
    stderr, $stderr = $stderr, StringIO.new
    FSSM::Backends.const_set("Default", FSSM::Backends::Polling)
    $stderr = stderr
  end

  action = FSSM::Backends::Default.to_s == "FSSM::Backends::Polling" ? "polling" : "watching"

  puts ">>> Compass is #{action} for changes. Press Ctrl-C to Stop."
  $stdout.flush

  begin
  FSSM.monitor do |monitor|
    Compass.configuration.sass_load_paths.each do |load_path|
      load_path = load_path.root if load_path.respond_to?(:root)
      next unless load_path.is_a? String
      monitor.path load_path do |path|
        path.glob '**/*.s[ac]ss'

        path.update &method(:recompile)
        path.delete {|base, relative| remove_obsolete_css(base,relative); recompile(base, relative)}
        path.create &method(:recompile)
      end
    end
    Compass.configuration.watches.each do |glob, callback|
      monitor.path Compass.configuration.project_path do |path|
        path.glob glob
        path.update do |base, relative|
          puts ">>> Change detected to: #{relative}"
          $stdout.flush
          callback.call(base, relative)
        end
        path.create do |base, relative|
          puts ">>> New file detected: #{relative}"
          $stdout.flush
          callback.call(base, relative)
        end
        path.delete do |base, relative|
          puts ">>> File Removed: #{relative}"
          $stdout.flush
          callback.call(base, relative)
        end
      end
    end

  end
rescue FSSM::CallbackError => e
  # FSSM catches exit? WTF.
  if e.message =~ /exit/
    exit
  end
end
end

#recompile(base = nil, relative = nil) ⇒ Object



140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/compass/commands/watch_project.rb', line 140

def recompile(base = nil, relative = nil)
  @memory_cache.reset! if @memory_cache
  compiler = new_compiler_instance(:quiet => true, :loud => [:identical, :overwrite, :create])
  if file = compiler.out_of_date?
    begin
      puts ">>> Change detected at "+Time.now.strftime("%T")+" to: #{relative || compiler.relative_stylesheet_name(file)}"
      $stdout.flush
      compiler.run
      GC.start
    rescue StandardError => e
      ::Compass::Exec::Helpers.report_error(e, options)
    end
  end
end

#remove_obsolete_css(base = nil, relative = nil) ⇒ Object



129
130
131
132
133
134
135
136
137
138
# File 'lib/compass/commands/watch_project.rb', line 129

def remove_obsolete_css(base = nil, relative = nil)
  compiler = new_compiler_instance(:quiet => true)
  sass_files = compiler.sass_files
  deleted_sass_files = (last_sass_files || []) - sass_files
  deleted_sass_files.each do |deleted_sass_file|
    css_file = compiler.corresponding_css_file(deleted_sass_file)
    remove(css_file) if File.exists?(css_file)
  end
  self.last_sass_files = sass_files
end