guard 0.4.0 → 0.5.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.
@@ -23,10 +23,13 @@ module Guard
23
23
 
24
24
  def self.usable?
25
25
  require 'rb-fsevent'
26
- if !defined?(FSEvent::VERSION) || Gem::Version.new(FSEvent::VERSION) < Gem::Version.new('0.4.0')
26
+ if !defined?(FSEvent::VERSION) || (defined?(Gem::Version) &&
27
+ Gem::Version.new(FSEvent::VERSION) < Gem::Version.new('0.4.0'))
27
28
  UI.info "Please update rb-fsevent (>= 0.4.0)"
29
+ false
30
+ else
31
+ true
28
32
  end
29
- true
30
33
  rescue LoadError
31
34
  UI.info "Please install rb-fsevent gem for Mac OSX FSEvents support"
32
35
  false
@@ -24,10 +24,13 @@ module Guard
24
24
 
25
25
  def self.usable?
26
26
  require 'rb-inotify'
27
- if !defined?(INotify::VERSION) || Gem::Version.new(INotify::VERSION.join('.')) < Gem::Version.new('0.8.5')
27
+ if !defined?(INotify::VERSION) || (defined?(Gem::Version) &&
28
+ Gem::Version.new(INotify::VERSION.join('.')) < Gem::Version.new('0.8.5'))
28
29
  UI.info "Please update rb-inotify (>= 0.8.5)"
30
+ false
31
+ else
32
+ true
29
33
  end
30
- true
31
34
  rescue LoadError
32
35
  UI.info "Please install rb-inotify gem for Linux inotify support"
33
36
  false
@@ -44,7 +47,8 @@ module Guard
44
47
  end
45
48
 
46
49
  def watch(directory)
47
- worker.watch(directory, :recursive, :modify, :create) do |event|
50
+ # The event selection is based on https://github.com/guard/guard/wiki/Analysis-of-inotify-events-for-different-editors
51
+ worker.watch(directory, :recursive, :create, :move_self, :close_write) do |event|
48
52
  unless event.name == "" # Event on root directory
49
53
  @files << event.absolute_name
50
54
  end
@@ -55,18 +59,15 @@ module Guard
55
59
  def watch_change
56
60
  @watch_change = true
57
61
  until @stop
58
- if Config::CONFIG['build'] =~ /java/ || IO.select([inotify.to_io], [], [], latency)
62
+ if RbConfig::CONFIG['build'] =~ /java/ || IO.select([inotify.to_io], [], [], latency)
59
63
  break if @stop
60
64
 
61
65
  sleep latency
62
66
  inotify.process
63
- update_last_event
64
67
 
65
- unless files.empty?
66
- files.uniq!
67
- callback.call( relativate_paths(files) )
68
- files.clear
69
- end
68
+ modified_files = modified_files(files.shift(files.size).map{|f| File.dirname(f) + '/' }.uniq)
69
+ update_last_event
70
+ callback.call(modified_files) unless modified_files.empty?
70
71
  end
71
72
  end
72
73
  @watch_change = false
@@ -2,8 +2,9 @@ module Guard
2
2
  class Windows < Listener
3
3
  attr_reader :fchange
4
4
 
5
- def initialize
5
+ def initialize(*)
6
6
  super
7
+
7
8
  @fchange = FChange::Notifier.new
8
9
  end
9
10
 
@@ -11,7 +11,7 @@ module Guard
11
11
 
12
12
  def self.turn_on
13
13
  ENV["GUARD_NOTIFY"] = 'true'
14
- case Config::CONFIG['target_os']
14
+ case RbConfig::CONFIG['target_os']
15
15
  when /darwin/i
16
16
  require_growl
17
17
  when /linux/i
@@ -26,7 +26,7 @@ module Guard
26
26
  image = options.delete(:image) || :success
27
27
  title = options.delete(:title) || "Guard"
28
28
 
29
- case Config::CONFIG['target_os']
29
+ case RbConfig::CONFIG['target_os']
30
30
  when /darwin/i
31
31
  notify_mac(title, message, image, options)
32
32
  when /linux/i
@@ -46,19 +46,19 @@ module Guard
46
46
  def self.notify_mac(title, message, image, options)
47
47
  require_growl # need for guard-rspec formatter that is called out of guard scope
48
48
  default_options = { :title => title, :icon => image_path(image), :name => "Guard" }
49
- Growl.notify message, default_options.merge(options)
49
+ Growl.notify message, default_options.merge(options) if enabled?
50
50
  end
51
51
 
52
52
  def self.notify_linux(title, message, image, options)
53
53
  require_libnotify # need for guard-rspec formatter that is called out of guard scope
54
54
  default_options = { :body => message, :summary => title, :icon_path => image_path(image) }
55
- Libnotify.show default_options.merge(options)
55
+ Libnotify.show default_options.merge(options) if enabled?
56
56
  end
57
57
 
58
58
  def self.notify_windows(title, message, image, options)
59
59
  require_rbnotifu # need for guard-rspec formatter that is called out of guard scope
60
60
  default_options = { :message => message, :title => title, :type => image_level(image), :time => 3 }
61
- Notifu.show default_options.merge(options)
61
+ Notifu.show default_options.merge(options) if enabled?
62
62
  end
63
63
 
64
64
  def self.image_path(image)
data/lib/guard/ui.rb CHANGED
@@ -12,7 +12,14 @@ module Guard
12
12
  def error(message, options = {})
13
13
  unless ENV["GUARD_ENV"] == "test"
14
14
  reset_line if options[:reset]
15
- puts "ERROR: #{message}"
15
+ puts "#{color('ERROR:', ';31')} #{message}"
16
+ end
17
+ end
18
+
19
+ def deprecation(message, options = {})
20
+ unless ENV["GUARD_ENV"] == "test"
21
+ reset_line if options[:reset]
22
+ puts "#{color('DEPRECATION:', ';31')} #{message}"
16
23
  end
17
24
  end
18
25
 
@@ -24,11 +31,7 @@ module Guard
24
31
  end
25
32
 
26
33
  def reset_line
27
- if color_enabled?
28
- print "\r\e[0m"
29
- else
30
- print "\r\n"
31
- end
34
+ print(color_enabled? ? "\r\e[0m" : "\r\n")
32
35
  end
33
36
 
34
37
  def clear
@@ -38,24 +41,21 @@ module Guard
38
41
  private
39
42
 
40
43
  def reset_color(text)
41
- color(text, "\e[0m")
44
+ color(text, "")
42
45
  end
43
46
 
44
47
  def color(text, color_code)
45
- if color_enabled?
46
- return "#{color_code}#{text}\e[0m"
47
- else
48
- return text
49
- end
48
+ color_enabled? ? "\e[0#{color_code}m#{text}\e[0m" : text
50
49
  end
51
50
 
52
51
  def color_enabled?
53
- @color_enabled ||= if Config::CONFIG['target_os'] =~ /mswin|mingw/i
52
+ @color_enabled ||= if RbConfig::CONFIG['target_os'] =~ /mswin|mingw/i
54
53
  unless ENV['ANSICON']
55
54
  begin
56
55
  require 'rubygems' unless ENV['NO_RUBYGEMS']
57
56
  require 'Win32/Console/ANSI'
58
57
  rescue LoadError
58
+ @color_enabled = false
59
59
  info "You must 'gem install win32console' to use color on Windows"
60
60
  false
61
61
  end
data/lib/guard/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Guard
2
- VERSION = "0.4.0"
2
+ VERSION = "0.5.0" unless defined? Guard::VERSION
3
3
  end
data/lib/guard/watcher.rb CHANGED
@@ -1,11 +1,11 @@
1
1
  module Guard
2
2
  class Watcher
3
3
  attr_accessor :pattern, :action
4
-
4
+
5
5
  def initialize(pattern, action = nil)
6
6
  @pattern, @action = pattern, action
7
7
  @@warning_printed ||= false
8
-
8
+
9
9
  # deprecation warning
10
10
  if @pattern.is_a?(String) && @pattern =~ /(^(\^))|(>?(\\\.)|(\.\*))|(\(.*\))|(\[.*\])|(\$$)/
11
11
  unless @@warning_printed
@@ -17,7 +17,7 @@ module Guard
17
17
  @pattern = Regexp.new(@pattern)
18
18
  end
19
19
  end
20
-
20
+
21
21
  def self.match_files(guard, files)
22
22
  guard.watchers.inject([]) do |paths, watcher|
23
23
  files.each do |file|
@@ -33,7 +33,7 @@ module Guard
33
33
  paths.flatten.map { |p| p.to_s }
34
34
  end
35
35
  end
36
-
36
+
37
37
  def self.match_files?(guards, files)
38
38
  guards.any? do |guard|
39
39
  guard.watchers.any? do |watcher|
@@ -41,7 +41,7 @@ module Guard
41
41
  end
42
42
  end
43
43
  end
44
-
44
+
45
45
  def match_file?(file)
46
46
  if @pattern.is_a?(Regexp)
47
47
  file.match(@pattern)
@@ -49,14 +49,18 @@ module Guard
49
49
  file == @pattern ? [file] : nil
50
50
  end
51
51
  end
52
-
52
+
53
+ def self.match_guardfile?(files)
54
+ files.any? { |file| "#{Dir.pwd}/#{file}" == Dsl.guardfile_path }
55
+ end
56
+
53
57
  def call_action(matches)
54
58
  begin
55
59
  @action.arity > 0 ? @action.call(matches) : @action.call
56
- rescue
57
- UI.error "Problem with watch action!"
60
+ rescue Exception => e
61
+ UI.error "Problem with watch action!\n#{e.message}\n\n#{e.backtrace.join("\n")}"
58
62
  end
59
63
  end
60
-
64
+
61
65
  end
62
66
  end
data/lib/guard.rb CHANGED
@@ -1,11 +1,12 @@
1
1
  module Guard
2
2
 
3
- autoload :UI, 'guard/ui'
4
- autoload :Dsl, 'guard/dsl'
5
- autoload :Interactor, 'guard/interactor'
6
- autoload :Listener, 'guard/listener'
7
- autoload :Watcher, 'guard/watcher'
8
- autoload :Notifier, 'guard/notifier'
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'
9
10
 
10
11
  class << self
11
12
  attr_accessor :options, :guards, :listener
@@ -22,22 +23,21 @@ module Guard
22
23
  end
23
24
 
24
25
  def start(options = {})
26
+ UI.clear if options[:clear]
25
27
  setup(options)
26
28
 
27
29
  Interactor.init_signal_traps
28
30
  Dsl.evaluate_guardfile(options)
29
31
 
30
- if guards.empty?
31
- UI.error "No guards found in Guardfile, please add at least one."
32
- else
33
- listener.on_change do |files|
34
- run { run_on_change_for_all_guards(files) } if Watcher.match_files?(guards, files)
35
- end
32
+ listener.on_change do |files|
33
+ Dsl.revaluate_guardfile if Watcher.match_guardfile?(files)
36
34
 
37
- UI.info "Guard is now watching at '#{Dir.pwd}'"
38
- guards.each { |guard| supervised_task(guard, :start) }
39
- listener.start
35
+ run { run_on_change_for_all_guards(files) } if Watcher.match_files?(guards, files)
40
36
  end
37
+
38
+ UI.info "Guard is now watching at '#{Dir.pwd}'"
39
+ guards.each { |guard| supervised_task(guard, :start) }
40
+ listener.start
41
41
  end
42
42
 
43
43
  def run_on_change_for_all_guards(files)
@@ -58,11 +58,12 @@ module Guard
58
58
  # fire it if his work leads to a system failure
59
59
  def supervised_task(guard, task_to_supervise, *args)
60
60
  guard.send(task_to_supervise, *args)
61
- rescue Exception
62
- UI.error("#{guard.class.name} guard failed to achieve its <#{task_to_supervise.to_s}> command: #{$!}")
61
+ rescue Exception => ex
62
+ UI.error("#{guard.class.name} failed to achieve its <#{task_to_supervise.to_s}>, exception was:" +
63
+ "\n#{ex.class}: #{ex.message}\n#{ex.backtrace.join("\n")}")
63
64
  guards.delete guard
64
- UI.info("Guard #{guard.class.name} has just been fired")
65
- return $!
65
+ UI.info("\n#{guard.class.name} has just been fired")
66
+ return ex
66
67
  end
67
68
 
68
69
  def run
@@ -76,20 +77,30 @@ module Guard
76
77
  end
77
78
 
78
79
  def add_guard(name, watchers = [], options = {})
79
- guard_class = get_guard_class(name)
80
- @guards << guard_class.new(watchers, options)
80
+ if name.downcase == 'ego'
81
+ UI.deprecation("Guard::Ego is now part of Guard you can removed it from your Guardfile.")
82
+ else
83
+ guard_class = get_guard_class(name)
84
+ @guards << guard_class.new(watchers, options)
85
+ end
81
86
  end
82
87
 
83
88
  def get_guard_class(name)
84
- try_to_load_gem(name)
85
- self.const_get(self.constants.find { |klass_name| klass_name.to_s.downcase == name.to_s.downcase.gsub('-', '') })
86
- rescue TypeError
87
- UI.error "Could not find load find gem 'guard-#{name}' or find class Guard::#{name}"
88
- end
89
-
90
- def try_to_load_gem(name)
91
- require "guard/#{name.to_s.downcase}"
92
- rescue LoadError
89
+ try_require = false
90
+ const_name = name.to_s.downcase.gsub('-', '')
91
+ begin
92
+ require "guard/#{name.to_s.downcase}" if try_require
93
+ self.const_get(self.constants.find {|c| c.to_s.downcase == const_name })
94
+ rescue TypeError
95
+ unless try_require
96
+ try_require = true
97
+ retry
98
+ else
99
+ UI.error "Could not find class Guard::#{const_name.capitalize}"
100
+ end
101
+ rescue LoadError
102
+ UI.error "Could not load 'guard/#{name.downcase}' or find class Guard::#{const_name.capitalize}"
103
+ end
93
104
  end
94
105
 
95
106
  def locate_guard(name)
data/man/guard.1 ADDED
@@ -0,0 +1,70 @@
1
+ .\" generated with Ronn/v0.7.3
2
+ .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
+ .
4
+ .TH "GUARD" "1" "June 2011" "" ""
5
+ .
6
+ .SH "NAME"
7
+ \fBguard\fR \- Guard keeps an eye on your file modifications\.
8
+ .
9
+ .SH "SYNOPSIS"
10
+ guard \fIcommand\fR \fIoptions\fR
11
+ .
12
+ .SH "DESCRIPTION"
13
+ Guard is a command line tool that easily handle events on files modifications\.
14
+ .
15
+ .SH "HOMEPAGE"
16
+ https://github\.com/guard/guard
17
+ .
18
+ .SH "OPTIONS"
19
+ .
20
+ .TP
21
+ \fB\-c\fR, \fB\-\-clear\fR
22
+ Clears the Shell after each change\.
23
+ .
24
+ .TP
25
+ \fB\-n\fR \fIflag\fR, \fB\-\-notify\fR \fIflag\fR
26
+ Disable notifications (Growl or Libnotify depending on your system)\. Note that notifications can also be disabled globally by setting a GUARD_NOTIFY environment variable to false\. The \fIflag\fR part can be passed to guard using true/false or t/f\.
27
+ .
28
+ .TP
29
+ \fB\-g\fR \fIgroup\fR \.\.\., \fB\-\-group\fR \fIgroup\fR \.\.\.
30
+ Runs only the groups specified\.
31
+ .
32
+ .TP
33
+ \fB\-d\fR, \fB\-\-debug\fR
34
+ Runs Guard in debug mode\.
35
+ .
36
+ .TP
37
+ \fB\-h\fR
38
+ List all of Guard\'s available commands\.
39
+ .
40
+ .SH "COMMANDS"
41
+ .
42
+ .TP
43
+ \fBstart\fR
44
+ Starts Guard\. This is the default command if none is provided\.
45
+ .
46
+ .TP
47
+ \fBinit\fR [guard]
48
+ Add the requested guard\'s default Guardfile configuration to the current Guardfile\.
49
+ .
50
+ .TP
51
+ \fBshow\fR, \fB\-T\fR
52
+ List defined groups and guards for the current Guardfile\.
53
+ .
54
+ .SH "EXAMPLES"
55
+ \fB[bundle exec] guard \-\-clear \-\-group backend frontend \-\-notify false \-\-debug\fR
56
+ .
57
+ .P
58
+ or in a more concise way:
59
+ .
60
+ .P
61
+ \fB[bundle exec] guard \-c \-g backend frontend \-n f \-d\fR
62
+ .
63
+ .SH "AUTHORS / CONTRIBUTORS"
64
+ Thibaud Guillaume\-Gentil is the main author\.
65
+ .
66
+ .P
67
+ A list of contributors based on all commits can be found here: https://github\.com/guard/guard/contributors
68
+ .
69
+ .P
70
+ For an exhaustive list of all the contributors, please see the CHANGELOG: https://github\.com/guard/guard/blob/master/CHANGELOG\.md
data/man/guard.1.html ADDED
@@ -0,0 +1,138 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv='content-type' value='text/html;charset=utf8'>
5
+ <meta name='generator' value='Ronn/v0.7.3 (http://github.com/rtomayko/ronn/tree/0.7.3)'>
6
+ <title>guard(1) - Guard keeps an eye on your file modifications.</title>
7
+ <style type='text/css' media='all'>
8
+ /* style: man */
9
+ body#manpage {margin:0}
10
+ .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
11
+ .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
12
+ .mp h2 {margin:10px 0 0 0}
13
+ .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
14
+ .mp h3 {margin:0 0 0 4ex}
15
+ .mp dt {margin:0;clear:left}
16
+ .mp dt.flush {float:left;width:8ex}
17
+ .mp dd {margin:0 0 0 9ex}
18
+ .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
19
+ .mp pre {margin-bottom:20px}
20
+ .mp pre+h2,.mp pre+h3 {margin-top:22px}
21
+ .mp h2+pre,.mp h3+pre {margin-top:5px}
22
+ .mp img {display:block;margin:auto}
23
+ .mp h1.man-title {display:none}
24
+ .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
25
+ .mp h2 {font-size:16px;line-height:1.25}
26
+ .mp h1 {font-size:20px;line-height:2}
27
+ .mp {text-align:justify;background:#fff}
28
+ .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
29
+ .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
30
+ .mp u {text-decoration:underline}
31
+ .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
32
+ .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
33
+ .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
34
+ .mp b.man-ref {font-weight:normal;color:#434241}
35
+ .mp pre {padding:0 4ex}
36
+ .mp pre code {font-weight:normal;color:#434241}
37
+ .mp h2+pre,h3+pre {padding-left:0}
38
+ ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
39
+ ol.man-decor {width:100%}
40
+ ol.man-decor li.tl {text-align:left}
41
+ ol.man-decor li.tc {text-align:center;letter-spacing:4px}
42
+ ol.man-decor li.tr {text-align:right;float:right}
43
+ </style>
44
+ </head>
45
+ <!--
46
+ The following styles are deprecated and will be removed at some point:
47
+ div#man, div#man ol.man, div#man ol.head, div#man ol.man.
48
+
49
+ The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
50
+ .man-navigation should be used instead.
51
+ -->
52
+ <body id='manpage'>
53
+ <div class='mp' id='man'>
54
+
55
+ <div class='man-navigation' style='display:none'>
56
+ <a href="#NAME">NAME</a>
57
+ <a href="#SYNOPSIS">SYNOPSIS</a>
58
+ <a href="#DESCRIPTION">DESCRIPTION</a>
59
+ <a href="#HOMEPAGE">HOMEPAGE</a>
60
+ <a href="#OPTIONS">OPTIONS</a>
61
+ <a href="#COMMANDS">COMMANDS</a>
62
+ <a href="#EXAMPLES">EXAMPLES</a>
63
+ <a href="#AUTHORS-CONTRIBUTORS">AUTHORS / CONTRIBUTORS</a>
64
+ </div>
65
+
66
+ <ol class='man-decor man-head man head'>
67
+ <li class='tl'>guard(1)</li>
68
+ <li class='tc'></li>
69
+ <li class='tr'>guard(1)</li>
70
+ </ol>
71
+
72
+ <h2 id="NAME">NAME</h2>
73
+ <p class="man-name">
74
+ <code>guard</code> - <span class="man-whatis">Guard keeps an eye on your file modifications.</span>
75
+ </p>
76
+
77
+ <h2 id="SYNOPSIS">SYNOPSIS</h2>
78
+
79
+ <p>guard <var>command</var> <var>options</var></p>
80
+
81
+ <h2 id="DESCRIPTION">DESCRIPTION</h2>
82
+
83
+ <p>Guard is a command line tool that easily handle events on files modifications.</p>
84
+
85
+ <h2 id="HOMEPAGE">HOMEPAGE</h2>
86
+
87
+ <p>https://github.com/guard/guard</p>
88
+
89
+ <h2 id="OPTIONS">OPTIONS</h2>
90
+
91
+ <dl>
92
+ <dt><code>-c</code>, <code>--clear</code></dt><dd><p>Clears the Shell after each change.</p></dd>
93
+ <dt><code>-n</code> <var>flag</var>, <code>--notify</code> <var>flag</var></dt><dd><p>Disable notifications (Growl or Libnotify depending on your system).
94
+ Note that notifications can also be disabled globally by setting a GUARD_NOTIFY environment variable to false.
95
+ The <var>flag</var> part can be passed to guard using true/false or t/f.</p></dd>
96
+ <dt><code>-g</code> <var>group</var> ..., <code>--group</code> <var>group</var> ...</dt><dd><p>Runs only the groups specified.</p></dd>
97
+ <dt><code>-d</code>, <code>--debug</code></dt><dd><p>Runs Guard in debug mode.</p></dd>
98
+ <dt class="flush"><code>-h</code></dt><dd><p>List all of Guard's available commands.</p></dd>
99
+ </dl>
100
+
101
+
102
+ <h2 id="COMMANDS">COMMANDS</h2>
103
+
104
+ <dl>
105
+ <dt class="flush"><code>start</code></dt><dd><p>Starts Guard. This is the default command if none is provided.</p></dd>
106
+ <dt><code>init</code> [guard]</dt><dd><p>Add the requested guard's default Guardfile configuration to the current Guardfile.</p></dd>
107
+ <dt><code>show</code>, <code>-T</code></dt><dd><p>List defined groups and guards for the current Guardfile.</p></dd>
108
+ </dl>
109
+
110
+
111
+ <h2 id="EXAMPLES">EXAMPLES</h2>
112
+
113
+ <p><code>[bundle exec] guard --clear --group backend frontend --notify false --debug</code></p>
114
+
115
+ <p>or in a more concise way:</p>
116
+
117
+ <p><code>[bundle exec] guard -c -g backend frontend -n f -d</code></p>
118
+
119
+ <h2 id="AUTHORS-CONTRIBUTORS">AUTHORS / CONTRIBUTORS</h2>
120
+
121
+ <p>Thibaud Guillaume-Gentil is the main author.</p>
122
+
123
+ <p>A list of contributors based on all commits can be found here:
124
+ https://github.com/guard/guard/contributors</p>
125
+
126
+ <p>For an exhaustive list of all the contributors, please see the CHANGELOG:
127
+ https://github.com/guard/guard/blob/master/CHANGELOG.md</p>
128
+
129
+
130
+ <ol class='man-decor man-foot man foot'>
131
+ <li class='tl'></li>
132
+ <li class='tc'>June 2011</li>
133
+ <li class='tr'>guard(1)</li>
134
+ </ol>
135
+
136
+ </div>
137
+ </body>
138
+ </html>