guard 0.7.0.rc1 → 0.7.0

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/bin/guard CHANGED
@@ -1,6 +1,6 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'guard'
4
- require 'guard/cli'
5
-
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'guard'
4
+ require 'guard/cli'
5
+
6
6
  Guard::CLI.start
data/lib/guard.rb CHANGED
@@ -1,186 +1,186 @@
1
- module Guard
2
-
3
- autoload :UI, 'guard/ui'
4
- autoload :Dsl, 'guard/dsl'
5
- autoload :DslDescriber, 'guard/dsl_describer'
6
- autoload :Interactor, 'guard/interactor'
7
- autoload :Listener, 'guard/listener'
8
- autoload :Watcher, 'guard/watcher'
9
- autoload :Notifier, 'guard/notifier'
10
- autoload :Hook, 'guard/hook'
11
-
12
- class << self
13
- attr_accessor :options, :guards, :groups, :interactor, :listener
14
-
15
- # initialize this singleton
16
- def setup(options = {})
17
- @options = options
18
- @guards = []
19
- @groups = [:default]
20
- @interactor = Interactor.new
21
- @listener = Listener.select_and_init(@options[:watchdir] ? File.expand_path(@options[:watchdir]) : Dir.pwd)
22
-
23
- @options[:notify] && ENV["GUARD_NOTIFY"] != 'false' ? Notifier.turn_on : Notifier.turn_off
24
-
25
- UI.clear if @options[:clear]
26
- debug_command_execution if @options[:debug]
27
-
28
- self
29
- end
30
-
31
- def start(options = {})
32
- setup(options)
33
-
34
- Dsl.evaluate_guardfile(options)
35
-
36
- listener.on_change do |files|
37
- Dsl.reevaluate_guardfile if Watcher.match_guardfile?(files)
38
- listener.changed_files += files if Watcher.match_files?(guards, files)
39
- end
40
-
41
- UI.info "Guard is now watching at '#{listener.directory}'"
42
- guards.each { |guard| supervised_task(guard, :start) }
43
-
44
- interactor.start
45
- listener.start
46
- end
47
-
48
- def stop
49
- UI.info "Bye bye...", :reset => true
50
- listener.stop
51
- guards.each { |guard| supervised_task(guard, :stop) }
52
- abort
53
- end
54
-
55
- def reload
56
- run do
57
- guards.each { |guard| supervised_task(guard, :reload) }
58
- end
59
- end
60
-
61
- def run_all
62
- run do
63
- guards.each { |guard| supervised_task(guard, :run_all) }
64
- end
65
- end
66
-
67
- def pause
68
- if listener.locked
69
- UI.info "Un-paused files modification listening", :reset => true
70
- listener.clear_changed_files
71
- listener.unlock
72
- else
73
- UI.info "Paused files modification listening", :reset => true
74
- listener.lock
75
- end
76
- end
77
-
78
- def run_on_change(files)
79
- run do
80
- guards.each do |guard|
81
- paths = Watcher.match_files(guard, files)
82
- unless paths.empty?
83
- UI.debug "#{guard.class.name}#run_on_change with #{paths.inspect}"
84
- supervised_task(guard, :run_on_change, paths)
85
- end
86
- end
87
- end
88
- end
89
-
90
- def run
91
- listener.lock
92
- interactor.lock
93
- UI.clear if options[:clear]
94
- begin
95
- yield
96
- rescue Interrupt
97
- end
98
- interactor.unlock
99
- listener.unlock
100
- end
101
-
102
- # Let a guard execute its task but
103
- # fire it if his work leads to a system failure
104
- def supervised_task(guard, task_to_supervise, *args)
105
- guard.hook("#{task_to_supervise}_begin", *args)
106
- result = guard.send(task_to_supervise, *args)
107
- guard.hook("#{task_to_supervise}_end", result)
108
- result
109
- rescue Exception => ex
110
- UI.error("#{guard.class.name} failed to achieve its <#{task_to_supervise.to_s}>, exception was:" +
111
- "\n#{ex.class}: #{ex.message}\n#{ex.backtrace.join("\n")}")
112
- guards.delete guard
113
- UI.info("\n#{guard.class.name} has just been fired")
114
- return ex
115
- end
116
-
117
- def add_guard(name, watchers = [], callbacks = [], options = {})
118
- if name.to_sym == :ego
119
- UI.deprecation("Guard::Ego is now part of Guard. You can remove it from your Guardfile.")
120
- else
121
- guard_class = get_guard_class(name)
122
- callbacks.each { |callback| Hook.add_callback(callback[:listener], guard_class, callback[:events]) }
123
- @guards << guard_class.new(watchers, options)
124
- end
125
- end
126
-
127
- def add_group(name)
128
- @groups << name.to_sym unless name.nil?
129
- end
130
-
131
- def get_guard_class(name)
132
- name = name.to_s
133
- try_require = false
134
- const_name = name.downcase.gsub('-', '')
135
- begin
136
- require "guard/#{name.downcase}" if try_require
137
- self.const_get(self.constants.find { |c| c.to_s.downcase == const_name })
138
- rescue TypeError
139
- unless try_require
140
- try_require = true
141
- retry
142
- else
143
- UI.error "Could not find class Guard::#{const_name.capitalize}"
144
- end
145
- rescue LoadError => loadError
146
- UI.error "Could not load 'guard/#{name.downcase}' or find class Guard::#{const_name.capitalize}"
147
- UI.error loadError.to_s
148
- end
149
- end
150
-
151
- def locate_guard(name)
152
- if Gem::Version.create(Gem::VERSION) >= Gem::Version.create('1.8.0')
153
- Gem::Specification.find_by_name("guard-#{name}").full_gem_path
154
- else
155
- Gem.source_index.find_name("guard-#{name}").last.full_gem_path
156
- end
157
- rescue
158
- UI.error "Could not find 'guard-#{name}' gem path."
159
- end
160
-
161
- ##
162
- # Returns a list of guard Gem names installed locally.
163
- def guard_gem_names
164
- if Gem::Version.create(Gem::VERSION) >= Gem::Version.create('1.8.0')
165
- Gem::Specification.find_all.select { |x| x.name =~ /^guard-/ }
166
- else
167
- Gem.source_index.find_name(/^guard-/)
168
- end.map { |x| x.name.sub /^guard-/, '' }
169
- end
170
-
171
- def debug_command_execution
172
- Kernel.send(:alias_method, :original_system, :system)
173
- Kernel.send(:define_method, :system) do |command, *args|
174
- ::Guard::UI.debug "Command execution: #{command} #{args.join(' ')}"
175
- original_system command, *args
176
- end
177
-
178
- Kernel.send(:alias_method, :original_backtick, :"`")
179
- Kernel.send(:define_method, :"`") do |command|
180
- ::Guard::UI.debug "Command execution: #{command}"
181
- original_backtick command
182
- end
183
- end
184
-
185
- end
186
- end
1
+ module Guard
2
+
3
+ autoload :UI, 'guard/ui'
4
+ autoload :Dsl, 'guard/dsl'
5
+ autoload :DslDescriber, 'guard/dsl_describer'
6
+ autoload :Interactor, 'guard/interactor'
7
+ autoload :Listener, 'guard/listener'
8
+ autoload :Watcher, 'guard/watcher'
9
+ autoload :Notifier, 'guard/notifier'
10
+ autoload :Hook, 'guard/hook'
11
+
12
+ class << self
13
+ attr_accessor :options, :guards, :groups, :interactor, :listener
14
+
15
+ # initialize this singleton
16
+ def setup(options = {})
17
+ @options = options
18
+ @guards = []
19
+ @groups = [:default]
20
+ @interactor = Interactor.new
21
+ @listener = Listener.select_and_init(@options[:watchdir] ? File.expand_path(@options[:watchdir]) : Dir.pwd)
22
+
23
+ @options[:notify] && ENV["GUARD_NOTIFY"] != 'false' ? Notifier.turn_on : Notifier.turn_off
24
+
25
+ UI.clear if @options[:clear]
26
+ debug_command_execution if @options[:debug]
27
+
28
+ self
29
+ end
30
+
31
+ def start(options = {})
32
+ setup(options)
33
+
34
+ Dsl.evaluate_guardfile(options)
35
+
36
+ listener.on_change do |files|
37
+ Dsl.reevaluate_guardfile if Watcher.match_guardfile?(files)
38
+ listener.changed_files += files if Watcher.match_files?(guards, files)
39
+ end
40
+
41
+ UI.info "Guard is now watching at '#{listener.directory}'"
42
+ guards.each { |guard| supervised_task(guard, :start) }
43
+
44
+ interactor.start
45
+ listener.start
46
+ end
47
+
48
+ def stop
49
+ UI.info "Bye bye...", :reset => true
50
+ listener.stop
51
+ guards.each { |guard| supervised_task(guard, :stop) }
52
+ abort
53
+ end
54
+
55
+ def reload
56
+ run do
57
+ guards.each { |guard| supervised_task(guard, :reload) }
58
+ end
59
+ end
60
+
61
+ def run_all
62
+ run do
63
+ guards.each { |guard| supervised_task(guard, :run_all) }
64
+ end
65
+ end
66
+
67
+ def pause
68
+ if listener.locked
69
+ UI.info "Un-paused files modification listening", :reset => true
70
+ listener.clear_changed_files
71
+ listener.unlock
72
+ else
73
+ UI.info "Paused files modification listening", :reset => true
74
+ listener.lock
75
+ end
76
+ end
77
+
78
+ def run_on_change(files)
79
+ run do
80
+ guards.each do |guard|
81
+ paths = Watcher.match_files(guard, files)
82
+ unless paths.empty?
83
+ UI.debug "#{guard.class.name}#run_on_change with #{paths.inspect}"
84
+ supervised_task(guard, :run_on_change, paths)
85
+ end
86
+ end
87
+ end
88
+ end
89
+
90
+ def run
91
+ listener.lock
92
+ interactor.lock
93
+ UI.clear if options[:clear]
94
+ begin
95
+ yield
96
+ rescue Interrupt
97
+ end
98
+ interactor.unlock
99
+ listener.unlock
100
+ end
101
+
102
+ # Let a guard execute its task but
103
+ # fire it if his work leads to a system failure
104
+ def supervised_task(guard, task_to_supervise, *args)
105
+ guard.hook("#{task_to_supervise}_begin", *args)
106
+ result = guard.send(task_to_supervise, *args)
107
+ guard.hook("#{task_to_supervise}_end", result)
108
+ result
109
+ rescue Exception => ex
110
+ UI.error("#{guard.class.name} failed to achieve its <#{task_to_supervise.to_s}>, exception was:" +
111
+ "\n#{ex.class}: #{ex.message}\n#{ex.backtrace.join("\n")}")
112
+ guards.delete guard
113
+ UI.info("\n#{guard.class.name} has just been fired")
114
+ return ex
115
+ end
116
+
117
+ def add_guard(name, watchers = [], callbacks = [], options = {})
118
+ if name.to_sym == :ego
119
+ UI.deprecation("Guard::Ego is now part of Guard. You can remove it from your Guardfile.")
120
+ else
121
+ guard_class = get_guard_class(name)
122
+ callbacks.each { |callback| Hook.add_callback(callback[:listener], guard_class, callback[:events]) }
123
+ @guards << guard_class.new(watchers, options)
124
+ end
125
+ end
126
+
127
+ def add_group(name)
128
+ @groups << name.to_sym unless name.nil?
129
+ end
130
+
131
+ def get_guard_class(name)
132
+ name = name.to_s
133
+ try_require = false
134
+ const_name = name.downcase.gsub('-', '')
135
+ begin
136
+ require "guard/#{name.downcase}" if try_require
137
+ self.const_get(self.constants.find { |c| c.to_s.downcase == const_name })
138
+ rescue TypeError
139
+ unless try_require
140
+ try_require = true
141
+ retry
142
+ else
143
+ UI.error "Could not find class Guard::#{const_name.capitalize}"
144
+ end
145
+ rescue LoadError => loadError
146
+ UI.error "Could not load 'guard/#{name.downcase}' or find class Guard::#{const_name.capitalize}"
147
+ UI.error loadError.to_s
148
+ end
149
+ end
150
+
151
+ def locate_guard(name)
152
+ if Gem::Version.create(Gem::VERSION) >= Gem::Version.create('1.8.0')
153
+ Gem::Specification.find_by_name("guard-#{name}").full_gem_path
154
+ else
155
+ Gem.source_index.find_name("guard-#{name}").last.full_gem_path
156
+ end
157
+ rescue
158
+ UI.error "Could not find 'guard-#{name}' gem path."
159
+ end
160
+
161
+ ##
162
+ # Returns a list of guard Gem names installed locally.
163
+ def guard_gem_names
164
+ if Gem::Version.create(Gem::VERSION) >= Gem::Version.create('1.8.0')
165
+ Gem::Specification.find_all.select { |x| x.name =~ /^guard-/ }
166
+ else
167
+ Gem.source_index.find_name(/^guard-/)
168
+ end.map { |x| x.name.sub /^guard-/, '' }
169
+ end
170
+
171
+ def debug_command_execution
172
+ Kernel.send(:alias_method, :original_system, :system)
173
+ Kernel.send(:define_method, :system) do |command, *args|
174
+ ::Guard::UI.debug "Command execution: #{command} #{args.join(' ')}"
175
+ original_system command, *args
176
+ end
177
+
178
+ Kernel.send(:alias_method, :original_backtick, :"`")
179
+ Kernel.send(:define_method, :"`") do |command|
180
+ ::Guard::UI.debug "Command execution: #{command}"
181
+ original_backtick command
182
+ end
183
+ end
184
+
185
+ end
186
+ end
data/lib/guard/cli.rb CHANGED
@@ -1,90 +1,90 @@
1
- require 'thor'
2
- require 'guard/version'
3
-
4
- module Guard
5
- class CLI < Thor
6
- default_task :start
7
-
8
- method_option :clear, :type => :boolean, :default => false, :aliases => '-c', :banner => "Auto clear shell before each change/run_all/reload"
9
- method_option :notify, :type => :boolean, :default => true, :aliases => '-n', :banner => "Notifications feature (growl/libnotify)"
10
- method_option :debug, :type => :boolean, :default => false, :aliases => '-d', :banner => "Print debug messages"
11
- method_option :group, :type => :array, :default => [], :aliases => '-g', :banner => "Run only the passed groups"
12
- method_option :watchdir, :type => :string, :aliases => '-w', :banner => "Specify the directory to watch"
13
- method_option :guardfile, :type => :string, :aliases => '-G', :banner => "Specify a Guardfile"
14
-
15
- desc "start", "Starts Guard"
16
- def start
17
- ::Guard.start(options)
18
- end
19
-
20
- desc "list", "Lists guards that can be used with init"
21
- def list
22
- ::Guard::DslDescriber.evaluate_guardfile(options)
23
- installed = []
24
- ::Guard::DslDescriber.guardfile_structure.each do |group|
25
- group[:guards].each {|x| installed << x[:name]} if group[:guards]
26
- end
27
-
28
- ::Guard::UI.info "Available guards:"
29
- ::Guard::guard_gem_names.sort.each do |name|
30
- if installed.include? name
31
- ::Guard::UI.info " #{name} *"
32
- else
33
- ::Guard::UI.info " #{name}"
34
- end
35
- end
36
- ::Guard::UI.info ' '
37
- ::Guard::UI.info "See also https://github.com/guard/guard/wiki/List-of-available-Guards"
38
- ::Guard::UI.info "* denotes ones already in your Guardfile"
39
- end
40
-
41
- desc "version", "Prints Guard's version"
42
- def version
43
- ::Guard::UI.info "Guard version #{Guard::VERSION}"
44
- end
45
- map %w(-v --version) => :version
46
-
47
- desc "init [GUARD]", "Generates a Guardfile into the current working directory, or insert the given GUARD in an existing Guardfile"
48
- def init(guard_name = nil)
49
- if !File.exist?("Guardfile")
50
- puts "Writing new Guardfile to #{Dir.pwd}/Guardfile"
51
- FileUtils.cp(File.expand_path('../templates/Guardfile', __FILE__), 'Guardfile')
52
- elsif guard_name.nil?
53
- ::Guard::UI.error "Guardfile already exists at #{Dir.pwd}/Guardfile"
54
- exit 1
55
- end
56
-
57
- if guard_name
58
- guard_class = ::Guard.get_guard_class(guard_name)
59
- guard_class.init(guard_name)
60
- end
61
- end
62
-
63
- desc "show", "Show all defined Guards and their options"
64
- def show
65
- ::Guard::DslDescriber.evaluate_guardfile(options)
66
-
67
- ::Guard::DslDescriber.guardfile_structure.each do |group|
68
- if !group[:guards].empty?
69
- if group[:group]
70
- ::Guard::UI.info "Group #{group[:group]}:"
71
- else
72
- ::Guard::UI.info "(global):"
73
- end
74
-
75
- group[:guards].each do |guard|
76
- line = " #{guard[:name]}"
77
-
78
- if !guard[:options].empty?
79
- line += ": #{guard[:options].collect { |k, v| "#{k} => #{v.inspect}" }.join(", ")}"
80
- end
81
- ::Guard::UI.info line
82
- end
83
- end
84
- end
85
-
86
- ::Guard::UI.info ''
87
- end
88
- map %w(-T) => :show
89
- end
90
- end
1
+ require 'thor'
2
+ require 'guard/version'
3
+
4
+ module Guard
5
+ class CLI < Thor
6
+ default_task :start
7
+
8
+ method_option :clear, :type => :boolean, :default => false, :aliases => '-c', :banner => "Auto clear shell before each change/run_all/reload"
9
+ method_option :notify, :type => :boolean, :default => true, :aliases => '-n', :banner => "Notifications feature (growl/libnotify)"
10
+ method_option :debug, :type => :boolean, :default => false, :aliases => '-d', :banner => "Print debug messages"
11
+ method_option :group, :type => :array, :default => [], :aliases => '-g', :banner => "Run only the passed groups"
12
+ method_option :watchdir, :type => :string, :aliases => '-w', :banner => "Specify the directory to watch"
13
+ method_option :guardfile, :type => :string, :aliases => '-G', :banner => "Specify a Guardfile"
14
+
15
+ desc "start", "Starts Guard"
16
+ def start
17
+ ::Guard.start(options)
18
+ end
19
+
20
+ desc "list", "Lists guards that can be used with init"
21
+ def list
22
+ ::Guard::DslDescriber.evaluate_guardfile(options)
23
+ installed = []
24
+ ::Guard::DslDescriber.guardfile_structure.each do |group|
25
+ group[:guards].each {|x| installed << x[:name]} if group[:guards]
26
+ end
27
+
28
+ ::Guard::UI.info "Available guards:"
29
+ ::Guard::guard_gem_names.sort.each do |name|
30
+ if installed.include? name
31
+ ::Guard::UI.info " #{name} *"
32
+ else
33
+ ::Guard::UI.info " #{name}"
34
+ end
35
+ end
36
+ ::Guard::UI.info ' '
37
+ ::Guard::UI.info "See also https://github.com/guard/guard/wiki/List-of-available-Guards"
38
+ ::Guard::UI.info "* denotes ones already in your Guardfile"
39
+ end
40
+
41
+ desc "version", "Prints Guard's version"
42
+ def version
43
+ ::Guard::UI.info "Guard version #{Guard::VERSION}"
44
+ end
45
+ map %w(-v --version) => :version
46
+
47
+ desc "init [GUARD]", "Generates a Guardfile into the current working directory, or insert the given GUARD in an existing Guardfile"
48
+ def init(guard_name = nil)
49
+ if !File.exist?("Guardfile")
50
+ puts "Writing new Guardfile to #{Dir.pwd}/Guardfile"
51
+ FileUtils.cp(File.expand_path('../templates/Guardfile', __FILE__), 'Guardfile')
52
+ elsif guard_name.nil?
53
+ ::Guard::UI.error "Guardfile already exists at #{Dir.pwd}/Guardfile"
54
+ exit 1
55
+ end
56
+
57
+ if guard_name
58
+ guard_class = ::Guard.get_guard_class(guard_name)
59
+ guard_class.init(guard_name)
60
+ end
61
+ end
62
+
63
+ desc "show", "Show all defined Guards and their options"
64
+ def show
65
+ ::Guard::DslDescriber.evaluate_guardfile(options)
66
+
67
+ ::Guard::DslDescriber.guardfile_structure.each do |group|
68
+ if !group[:guards].empty?
69
+ if group[:group]
70
+ ::Guard::UI.info "Group #{group[:group]}:"
71
+ else
72
+ ::Guard::UI.info "(global):"
73
+ end
74
+
75
+ group[:guards].each do |guard|
76
+ line = " #{guard[:name]}"
77
+
78
+ if !guard[:options].empty?
79
+ line += ": #{guard[:options].collect { |k, v| "#{k} => #{v.inspect}" }.join(", ")}"
80
+ end
81
+ ::Guard::UI.info line
82
+ end
83
+ end
84
+ end
85
+
86
+ ::Guard::UI.info ''
87
+ end
88
+ map %w(-T) => :show
89
+ end
90
+ end