guard 0.9.0 → 0.10.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/CHANGELOG.md CHANGED
@@ -1,8 +1,49 @@
1
- ## Dev
1
+ ## 0.10.0 - 1 January, 2012
2
+
3
+ ### Improvement
4
+
5
+ - Improved Readline constraints. ([@netzpirat][])
6
+ - Stop & start all guards on Guardfile reevaluation. ([@thibaudgg][])
2
7
 
3
8
  ### Bug fix
4
9
 
5
- - [#173](https://github.com/guard/guard/issues/173): Cannot set the watch_all_modifications option. (reported by [@sutherland][], fixed by [@netzpirat][]
10
+ - Terminal keep-alive causing ERROR: Unknown command. ([@waldo][])
11
+
12
+ ## 0.9.4 - December 25, 2011
13
+
14
+ ### Improvement
15
+
16
+ - Add the ability to load user defined templates. ([@hawx][])
17
+
18
+ ### Bug fix
19
+
20
+ - Fix guard-rspec notifications by using ENV variable to store Notifier.notifications. ([@thibaudgg][])
21
+
22
+ ## 0.9.3 - December 23, 2011
23
+
24
+ ### Improvement
25
+
26
+ - Fix terminal status after interrupting the Readline interactor. ([@Maher4Ever][])
27
+
28
+ ## 0.9.2 - December 22, 2011
29
+
30
+ ### Improvements
31
+
32
+ - Add `interactor` to DSL to allow switching Guard interaction implementation. ([@netzpirat][])
33
+ - Add quit action to the interactor. ([@Maher4Ever][])
34
+
35
+ ## 0.9.1 - December 19, 2011
36
+
37
+ ### Bug fixes
38
+
39
+ - Fix wrong `--no-vendor` option. ([@netzpirat][])
40
+ - [#195](https://github.com/guard/guard/issues/195): Empty watch directory prohibit Guard from running. (reported by [@madtrick][], fixed by [@netzpirat][])
41
+
42
+ ## 0.9.0 - December 19, 2011
43
+
44
+ ### Bug fixes
45
+
46
+ - [#173](https://github.com/guard/guard/issues/173): Cannot set the watch_all_modifications option. (reported by [@sutherland][], fixed by [@netzpirat][])
6
47
  - Fix `guard init` when a guard name is given. ([@rymai][])
7
48
 
8
49
  ### Improvements
@@ -346,6 +387,7 @@
346
387
  [@fnichol]: https://github.com/fnichol
347
388
  [@Gazer]: https://github.com/Gazer
348
389
  [@gix]: https://github.com/gix
390
+ [@hawx]: https://github.com/hawx
349
391
  [@hron]: https://github.com/hron
350
392
  [@hardipe]: https://github.com/hardipe
351
393
  [@hashrocketeer]: https://github.com/hashrocketeer
@@ -356,6 +398,8 @@
356
398
  [@jrsacks]: https://github.com/jrsacks
357
399
  [@koshigoe]: https://github.com/koshigoe
358
400
  [@limeyd]: https://github.com/limeyd
401
+ [@madtrick]: https://github.com/madtrick
402
+ [@Maher4Ever]: https://github.com/Maher4Ever
359
403
  [@mcmire]: https://github.com/mcmire
360
404
  [@mislav]: https://github.com/mislav
361
405
  [@monocle]: https://github.com/monocle
@@ -380,6 +424,7 @@
380
424
  [@tpope]: https://github.com/tpope
381
425
  [@uk-ar]: https://github.com/uk-ar
382
426
  [@veged]: https://github.com/veged
427
+ [@waldo]: https://github.com/waldo
383
428
  [@wereHamster]: https://github.com/wereHamster
384
429
  [@yannlugrin]: https://github.com/yannlugrin
385
430
  [@zonque]: https://github.com/zonque
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2011 Thibaud Guillaume-Gentil
1
+ Copyright (c) 2009-2012 Thibaud Guillaume-Gentil
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -34,10 +34,6 @@ Add Guard to your `Gemfile`:
34
34
  ```ruby
35
35
  group :development do
36
36
  gem 'guard'
37
-
38
- platforms :ruby do
39
- gem 'rb-readline'
40
- end
41
37
  end
42
38
  ```
43
39
 
@@ -67,7 +63,8 @@ the time, try the [Rubygems Bundler](https://github.com/mpapis/rubygems-bundler)
67
63
 
68
64
  ### System notifications
69
65
 
70
- You can configure Guard to make use of the following system notification libraries:
66
+ You can configure Guard to make use of the following system notification libraries, but it's strongly recommended
67
+ to use either Ruby GNTP, Libnotify or Notifu:
71
68
 
72
69
  #### Ruby GNTP
73
70
 
@@ -91,31 +88,6 @@ group :development do
91
88
  end
92
89
  ```
93
90
 
94
- #### Growl
95
-
96
- * Runs on Mac OS X
97
- * Supports all [Growl](http://growl.info/) versions
98
-
99
- The [growl](https://rubygems.org/gems/growl) gem is compatible with all versions of Growl and uses a command line tool
100
- [growlnotify](http://growl.info/extras.php#growlnotify) that must be separately downloaded and installed. The version of
101
- the command line tool must match your Growl version. The `growl` gem does **not** support multiple notification
102
- channels.
103
-
104
- You can download an installer for `growlnotify` from the [Growl download section](http://growl.info/downloads) or
105
- install it with HomeBrew:
106
-
107
- ```bash
108
- $ brew install growlnotify
109
- ```
110
-
111
- To use `growl` you have to add it to your `Gemfile` and run bundler:
112
-
113
- ```ruby
114
- group :development do
115
- gem 'growl'
116
- end
117
- ```
118
-
119
91
  #### Libnotify
120
92
 
121
93
  * Runs on Linux, FreeBSD, OpenBSD and Solaris
@@ -148,6 +120,26 @@ group :development do
148
120
  end
149
121
  ```
150
122
 
123
+ #### Growl
124
+
125
+ * Runs on Mac OS X
126
+ * Supports all [Growl](http://growl.info/) versions
127
+
128
+ The [growl](https://rubygems.org/gems/growl) gem is compatible with all versions of Growl and uses a command line tool
129
+ [growlnotify](http://growl.info/extras.php#growlnotify) that must be separately downloaded and installed. The version of
130
+ the command line tool must match your Growl version. The `growl` gem does **not** support multiple notification
131
+ channels.
132
+
133
+ You have to download the installer for `growlnotify` from the [Growl download section](http://growl.info/downloads).
134
+
135
+ To use `growl` you have to add it to your `Gemfile` and run bundler:
136
+
137
+ ```ruby
138
+ group :development do
139
+ gem 'growl'
140
+ end
141
+ ```
142
+
151
143
  #### GrowlNotify
152
144
 
153
145
  * Runs on Mac OS X
@@ -222,6 +214,13 @@ In addition, the `init` task can be used to append a supplied Guard template fro
222
214
  $ guard init <guard-name>
223
215
  ```
224
216
 
217
+ You can also define your own templates in `~/.guard/templates/` which can be appended in the same way to your existing
218
+ `Guardfile`:
219
+
220
+ ```bash
221
+ $ guard init <template-name>
222
+ ```
223
+
225
224
  ### Start
226
225
 
227
226
  Just launch Guard inside your Ruby or Rails project with:
@@ -361,11 +360,7 @@ read more about these files in the shared configuration section below.
361
360
  Interactions
362
361
  ------------
363
362
 
364
- You can interact with Guard and enter commands when Guard has nothing to do. You'll see a command prompt `>` when Guard
365
- is ready to accept a command. The command line supports history navigation with the `↑` and `↓` arrow keys, and
366
- command auto-completion with the `⇥` key.
367
-
368
- You can execute the following commands:
363
+ You can interact with Guard and enter commands when Guard has nothing to do. Guard understands the following commands:
369
364
 
370
365
  * `↩`: Run all Guards.
371
366
  * `h`, `help`: Show a help of the available interactor commands.
@@ -399,6 +394,23 @@ This will reload only the Ronn Guard. You can also reload all Guards within a gr
399
394
  > backend reload
400
395
  ```
401
396
 
397
+ ### Readline support
398
+
399
+ With Readline enabled, you'll see a command prompt `>` when Guard is ready to accept a command. The command line
400
+ supports history navigation with the `↑` and `↓` arrow keys, and command auto-completion with the `⇥` key.
401
+
402
+ Unfortunately Readline [does not work on MRI](http://bugs.ruby-lang.org/issues/5539) on Mac OS X by default. You can
403
+ work around the issue by installing a pure Ruby implementation:
404
+
405
+ ```ruby
406
+ platforms :ruby do
407
+ gem 'rb-readline'
408
+ end
409
+ ```
410
+
411
+ Guard will automatically enable Readline support if your environment supports it, but you can disable Readline with the
412
+ `interactor` DSL method or turn off completely with the `--no-interactions` option.
413
+
402
414
  Guardfile DSL
403
415
  -------------
404
416
 
@@ -529,6 +541,26 @@ or using the cli switch `-n`:
529
541
  notification :off
530
542
  ```
531
543
 
544
+ ### interactor
545
+
546
+ You can disable the interactor auto detection and for a specific implementation:
547
+
548
+ ```ruby
549
+ interactor :readline
550
+ ```
551
+
552
+ will select Readline interactor. You can also force the simple interactor without Readline support with:
553
+
554
+ ```ruby
555
+ interactor :simple
556
+ ```
557
+
558
+ If you do not need the keyboard interactions with Guard at all, you can turn them off:
559
+
560
+ ```ruby
561
+ interactor :off
562
+ ```
563
+
532
564
  ### callback
533
565
 
534
566
  The `callback` method allows you to execute arbitrary code before or after any of the `start`, `stop`, `reload`,
@@ -810,6 +842,7 @@ Pull requests are very welcome! Please try to follow these simple rules if appli
810
842
 
811
843
  * Please create a topic branch for every separate change you make.
812
844
  * Make sure your patches are well tested. All specs run with `rake spec:portability` must pass.
845
+ * On OS X you need to compile once rb-fsevent executable with `rake build_mac_exec`.
813
846
  * Update the [Yard](http://yardoc.org/) documentation.
814
847
  * Update the README.
815
848
  * Update the CHANGELOG for noteworthy changes.
Binary file
data/lib/guard/cli.rb CHANGED
@@ -72,6 +72,8 @@ module Guard
72
72
  #
73
73
  def start
74
74
  ::Guard.start(options)
75
+ rescue Interrupt
76
+ ::Guard.stop
75
77
  end
76
78
 
77
79
  desc 'list', 'Lists guards that can be used with init'
data/lib/guard/dsl.rb CHANGED
@@ -107,14 +107,24 @@ module Guard
107
107
  # Re-evaluate the `Guardfile` to update the current Guard configuration.
108
108
  #
109
109
  def reevaluate_guardfile
110
- ::Guard.guards.clear
111
- ::Guard.reset_groups
112
- ::Guard::Notifier.notifications.clear
113
- @@options.delete(:guardfile_contents)
114
- Dsl.evaluate_guardfile(@@options)
115
- msg = 'Guardfile has been re-evaluated.'
116
- UI.info(msg)
117
- Notifier.notify(msg)
110
+ ::Guard.run do
111
+ # Stop each old guards
112
+ ::Guard.run_on_guards do |guard|
113
+ ::Guard.run_supervised_task(guard, :stop)
114
+ end
115
+ ::Guard.guards.clear
116
+ ::Guard.reset_groups
117
+ ::Guard::Notifier.clear_notifications
118
+ @@options.delete(:guardfile_contents)
119
+ Dsl.evaluate_guardfile(@@options)
120
+ msg = 'Guardfile has been re-evaluated.'
121
+ UI.info(msg)
122
+ Notifier.notify(msg)
123
+ # Start each new guards
124
+ ::Guard.run_on_guards do |guard|
125
+ ::Guard.run_supervised_task(guard, :start)
126
+ end
127
+ end
118
128
  end
119
129
 
120
130
  # Evaluate the content of the `Guardfile`.
@@ -276,6 +286,21 @@ module Guard
276
286
  ::Guard::Notifier.add_notification(notifier.to_sym, options, false)
277
287
  end
278
288
 
289
+ # Sets the interactor to use.
290
+ #
291
+ # @example Use the readline interactor
292
+ # interactor :readline
293
+ #
294
+ # @example Use the gets interactor
295
+ # interactor :gets
296
+ #
297
+ # @example Turn off interactions
298
+ # interactor :off
299
+ #
300
+ def interactor(interactor)
301
+ ::Guard::Interactor.interactor = interactor.to_sym
302
+ end
303
+
279
304
  # Declares a group of guards to be run with `guard start --group group_name`.
280
305
  #
281
306
  # @example Declare two groups of Guards
@@ -1,21 +1,20 @@
1
- require 'readline'
2
-
3
1
  module Guard
4
2
 
5
- # The interactor reads user input and triggers
6
- # specific action upon them unless its locked.
7
- #
8
- # It used the readline library for history and
9
- # completion support.
3
+ autoload :ReadlineInteractor, 'guard/interactors/readline'
4
+ autoload :SimpleInteractor, 'guard/interactors/simple'
5
+
6
+ # The interactor triggers specific action from input
7
+ # read by a interactor implementation.
10
8
  #
11
9
  # Currently the following actions are implemented:
12
10
  #
13
- # - h, help => Show help
14
- # - e, exit => Exit Guard
15
- # - r, reload => Reload Guard
16
- # - p, pause => Toggle file modification listener
17
- # - n, notification => Toggle notifications
18
- # - <enter> => Run all
11
+ # - h, help => Show help
12
+ # - e, exit,
13
+ # q. quit => Exit Guard
14
+ # - r, reload => Reload Guard
15
+ # - p, pause => Toggle file modification listener
16
+ # - n, notification => Toggle notifications
17
+ # - <enter> => Run all
19
18
  #
20
19
  # It's also possible to scope `reload` and `run all` actions to only a specified group or a guard.
21
20
  #
@@ -28,29 +27,62 @@ module Guard
28
27
  # @example Run all jasmine specs
29
28
  # jasmine
30
29
  #
30
+ # @abstract
31
+ #
31
32
  class Interactor
32
33
 
33
34
  HELP_ENTRIES = %w[help h]
34
35
  RELOAD_ENTRIES = %w[reload r]
35
- STOP_ENTRIES = %w[exit e]
36
+ STOP_ENTRIES = %w[exit e quit q]
36
37
  PAUSE_ENTRIES = %w[pause p]
37
38
  NOTIFICATION_ENTRIES = %w[notification n]
38
39
 
39
- COMPLETION_ACTIONS = %w[help reload exit pause notification]
40
+ # Set the interactor implementation
41
+ #
42
+ # @param [Symbol] interactor the name of the interactor
43
+ #
44
+ def self.interactor=(interactor)
45
+ @interactor = interactor
46
+ end
40
47
 
41
- # Initialize the interactor.
48
+ # Get an instance of the currently configured
49
+ # interactor implementation.
42
50
  #
43
- def initialize
44
- unless defined?(RbReadline) || defined?(JRUBY_VERSION)
45
- ::Guard::UI.info 'Please add rb-readline for proper Readline support.'
51
+ # @return [Interactor] an interactor implementation
52
+ #
53
+ def self.fabricate
54
+ case @interactor
55
+ when :readline
56
+ ReadlineInteractor.new
57
+ when :simple
58
+ SimpleInteractor.new
59
+ when :off
60
+ nil
61
+ else
62
+ auto_detect
46
63
  end
47
-
48
- Readline.completion_proc = proc { |word| auto_complete(word) }
64
+ end
65
+
66
+ # Tries to detect an optimal interactor for the
67
+ # current environment.
68
+ #
69
+ # It returns the Readline implementation when:
70
+ #
71
+ # * rb-readline is installed
72
+ # * The Ruby implementation is JRuby
73
+ # * The current OS is not Mac OS X
74
+ #
75
+ # Otherwise the plain gets interactor is returned.
76
+ #
77
+ # @return [Interactor] an interactor implementation
78
+ #
79
+ def self.auto_detect
80
+ require 'readline'
49
81
 
50
- begin
51
- Readline.completion_append_character = ' '
52
- rescue NotImplementedError
53
- # Ignore, we just don't support it then
82
+ if defined?(RbReadline) || defined?(JRUBY_VERSION) || RbConfig::CONFIG['target_os'] =~ /linux/i
83
+ ReadlineInteractor.new
84
+ else
85
+ SimpleInteractor.new
54
86
  end
55
87
  end
56
88
 
@@ -69,40 +101,13 @@ module Guard
69
101
  end
70
102
  end
71
103
 
72
- # Read a line from stdin with Readline.
104
+ # Read the user input. This method must be implemented
105
+ # by each interactor implementation.
73
106
  #
74
- def read_line
75
- while line = Readline.readline(prompt, true)
76
- process_input(line)
77
- end
78
- end
79
-
80
- # Auto complete the given word.
81
- #
82
- # @param [String] word the partial word
83
- # @return [Array<String>] the matching words
84
- #
85
- def auto_complete(word)
86
- completion_list.grep(/^#{ Regexp.escape(word) }/)
87
- end
88
-
89
- # Get the auto completion list.
90
- #
91
- # @return [Array<String>] the list of words
107
+ # @abstract
92
108
  #
93
- def completion_list
94
- groups = ::Guard.groups.map { |group| group.name.to_s }
95
- guards = ::Guard.guards.map { |guard| guard.class.to_s.downcase.sub('guard::', '') }
96
-
97
- COMPLETION_ACTIONS + groups + guards - ['default']
98
- end
99
-
100
- # The current interactor prompt
101
- #
102
- # @return [String] the prompt to show
103
- #
104
- def prompt
105
- ::Guard.listener.paused? ? 'p> ' : '> '
109
+ def read_line
110
+ raise NotImplementedError
106
111
  end
107
112
 
108
113
  # Process the input from readline.
@@ -110,10 +115,6 @@ module Guard
110
115
  # @param [String] line the input line
111
116
  #
112
117
  def process_input(line)
113
- if line =~ /^\s*$/ or Readline::HISTORY.to_a[-2] == line
114
- Readline::HISTORY.pop
115
- end
116
-
117
118
  scopes, action = extract_scopes_and_action(line)
118
119
 
119
120
  case action
@@ -159,10 +160,10 @@ module Guard
159
160
  #
160
161
  def help
161
162
  puts ''
162
- puts 'e, exit Exit Guard'
163
- puts 'p, pause Toggle file modification listener'
164
- puts 'r, reload Reload Guard'
165
- puts 'n, notification Toggle notifications'
163
+ puts '[e]xit, [q]uit Exit Guard'
164
+ puts '[p]ause Toggle file modification listener'
165
+ puts '[r]eload Reload Guard'
166
+ puts '[n]otification Toggle notifications'
166
167
  puts '<enter> Run all Guards'
167
168
  puts ''
168
169
  puts 'You can scope the reload action to a specific guard or group:'
@@ -0,0 +1,110 @@
1
+ module Guard
2
+
3
+ # Interactor that used readline for getting the user input.
4
+ # This enables history support and auto-completion, but is
5
+ # broken on OS X without installing `rb-readline` or using JRuby.
6
+ #
7
+ # @see http://bugs.ruby-lang.org/issues/5539
8
+ #
9
+ class ReadlineInteractor < Interactor
10
+
11
+ COMPLETION_ACTIONS = %w[help reload exit pause notification]
12
+
13
+ # Initialize the interactor.
14
+ #
15
+ def initialize
16
+ require 'readline'
17
+
18
+ unless defined?(RbReadline) || defined?(JRUBY_VERSION) || RbConfig::CONFIG['target_os'] =~ /linux/i
19
+ ::Guard::UI.info 'Please add rb-readline for proper Readline support.'
20
+ end
21
+
22
+ Readline.completion_proc = proc { |word| auto_complete(word) }
23
+
24
+ begin
25
+ Readline.completion_append_character = ' '
26
+ rescue NotImplementedError
27
+ # Ignore, we just don't support it then
28
+ end
29
+ end
30
+
31
+ # Start the interactor.
32
+ #
33
+ def start
34
+ store_terminal_settings if stty_exists?
35
+ super
36
+ end
37
+
38
+ # Stop the interactor.
39
+ #
40
+ def stop
41
+ super
42
+ restore_terminal_settings if stty_exists?
43
+ end
44
+
45
+ # Read a line from stdin with Readline.
46
+ #
47
+ def read_line
48
+ while line = Readline.readline(prompt, true)
49
+ line.gsub!(/^\W*/, '')
50
+ if line =~ /^\s*$/ or Readline::HISTORY.to_a[-2] == line
51
+ Readline::HISTORY.pop
52
+ end
53
+
54
+ process_input(line)
55
+ end
56
+ end
57
+
58
+ # Auto complete the given word.
59
+ #
60
+ # @param [String] word the partial word
61
+ # @return [Array<String>] the matching words
62
+ #
63
+ def auto_complete(word)
64
+ completion_list.grep(/^#{ Regexp.escape(word) }/)
65
+ end
66
+
67
+ # Get the auto completion list.
68
+ #
69
+ # @return [Array<String>] the list of words
70
+ #
71
+ def completion_list
72
+ groups = ::Guard.groups.map { |group| group.name.to_s }
73
+ guards = ::Guard.guards.map { |guard| guard.class.to_s.downcase.sub('guard::', '') }
74
+
75
+ COMPLETION_ACTIONS + groups + guards - ['default']
76
+ end
77
+
78
+ # The current interactor prompt
79
+ #
80
+ # @return [String] the prompt to show
81
+ #
82
+ def prompt
83
+ ::Guard.listener.paused? ? 'p> ' : '> '
84
+ end
85
+
86
+ private
87
+
88
+ # Detects whether or not the stty command exists
89
+ # on the user machine.
90
+ #
91
+ # @return [Boolean] the status of stty
92
+ #
93
+ def stty_exists?
94
+ system('hash', 'stty')
95
+ end
96
+
97
+ # Stores the terminal settings so we can resore them
98
+ # when stopping.
99
+ #
100
+ def store_terminal_settings
101
+ @stty_save = `stty -g`.chomp
102
+ end
103
+
104
+ # Restore terminal settings
105
+ #
106
+ def restore_terminal_settings
107
+ system('stty', @stty_save)
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,17 @@
1
+ module Guard
2
+
3
+ # Simple interactor that that reads user
4
+ # input from standard input.
5
+ #
6
+ class SimpleInteractor < Interactor
7
+
8
+ # Read a line from stdin with Readline.
9
+ #
10
+ def read_line
11
+ while line = $stdin.gets
12
+ process_input(line.gsub(/^\W*/, '').chomp)
13
+ end
14
+ end
15
+
16
+ end
17
+ end
@@ -28,11 +28,16 @@ module Guard
28
28
  # Select the appropriate listener implementation for the
29
29
  # current OS and initializes it.
30
30
  #
31
- # @param [Array] args the arguments for the listener
31
+ # @param [Hash] options the options for the listener
32
+ # @option options [String] watchdir the directory to watch
32
33
  # @return [Guard::Listener] the chosen listener
33
34
  #
34
- def self.select_and_init(watchdir = Dir.pwd, options = nil)
35
- no_vendor = options && options.key?(:no_vendor) ? options[:no_vendor] : false
35
+ def self.select_and_init(options = nil)
36
+ watchdir = options && options[:watchdir] && File.expand_path(options[:watchdir])
37
+ watchdir = Dir.pwd unless watchdir
38
+
39
+ no_vendor = options && options[:no_vendor] ? options[:no_vendor] : false
40
+
36
41
  if mac? && Darwin.usable?(no_vendor)
37
42
  Darwin.new(watchdir, options)
38
43
  elsif linux? && Linux.usable?(no_vendor)
@@ -1,3 +1,5 @@
1
+ require 'yaml'
2
+
1
3
  require 'rbconfig'
2
4
  require 'pathname'
3
5
  require 'guard/ui'
@@ -53,7 +55,7 @@ module Guard
53
55
  # @return [Hash] the notifications
54
56
  #
55
57
  def notifications
56
- @notifications ||= []
58
+ ENV['GUARD_NOTIFICATIONS'] ? YAML::load(ENV['GUARD_NOTIFICATIONS']) : []
57
59
  end
58
60
 
59
61
  # Set the available notifications.
@@ -61,7 +63,13 @@ module Guard
61
63
  # @param [Array<Hash>] notifications the notifications
62
64
  #
63
65
  def notifications=(notifications)
64
- @notifications = notifications
66
+ ENV['GUARD_NOTIFICATIONS'] = YAML::dump(notifications)
67
+ end
68
+
69
+ # Clear available notifications.
70
+ #
71
+ def clear_notifications
72
+ ENV['GUARD_NOTIFICATIONS'] = nil
65
73
  end
66
74
 
67
75
  # Turn notifications on. If no notifications are defined
@@ -107,7 +115,7 @@ module Guard
107
115
  return turn_off if name == :off
108
116
 
109
117
  if NOTIFIERS.has_key?(name) && NOTIFIERS[name].available?(silent)
110
- notifications << { :name => name, :options => options }
118
+ self.notifications = notifications << { :name => name, :options => options }
111
119
  true
112
120
  else
113
121
  false
data/lib/guard/version.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Guard
2
2
  unless defined? Guard::VERSION
3
3
  # The current gem version of Guard
4
- VERSION = '0.9.0'
4
+ VERSION = '0.10.0'
5
5
  end
6
6
  end
data/lib/guard.rb CHANGED
@@ -17,6 +17,8 @@ module Guard
17
17
 
18
18
  # The Guardfile template for `guard init`
19
19
  GUARDFILE_TEMPLATE = File.expand_path('../guard/templates/Guardfile', __FILE__)
20
+ # The location of user defined templates
21
+ HOME_TEMPLATES = File.expand_path('~/.guard/templates')
20
22
 
21
23
  class << self
22
24
  attr_accessor :options, :interactor, :listener, :lock
@@ -26,7 +28,7 @@ module Guard
26
28
  #
27
29
  # @see Guard::Guard.init
28
30
  #
29
- # @param [String] guard_name the name of the Guard to initialize
31
+ # @param [String] guard_name the name of the Guard or template to initialize
30
32
  #
31
33
  def initialize_template(guard_name = nil)
32
34
  if !File.exist?('Guardfile')
@@ -38,8 +40,24 @@ module Guard
38
40
  end
39
41
 
40
42
  if guard_name
41
- guard_class = ::Guard.get_guard_class(guard_name)
42
- guard_class.init(guard_name)
43
+ guard_class = ::Guard.get_guard_class(guard_name, true)
44
+ if guard_class
45
+ guard_class.init(guard_name)
46
+ elsif File.exist?(File.join(HOME_TEMPLATES, guard_name))
47
+ content = File.read('Guardfile')
48
+ template = File.read(File.join(HOME_TEMPLATES, guard_name))
49
+
50
+ File.open('Guardfile', 'wb') do |f|
51
+ f.puts(content)
52
+ f.puts("")
53
+ f.puts(template)
54
+ end
55
+
56
+ ::Guard::UI.info "#{ guard_name } template added to Guardfile, feel free to edit it"
57
+ else
58
+ const_name = guard_name.downcase.gsub('-', '')
59
+ UI.error "Could not load 'guard/#{ guard_name.downcase }' or '~/.guard/templates/#{ guard_name.downcase }' or find class Guard::#{ const_name.capitalize }"
60
+ end
43
61
  end
44
62
  end
45
63
 
@@ -62,8 +80,7 @@ module Guard
62
80
  @options = options
63
81
  @guards = []
64
82
  self.reset_groups
65
- @interactor = Interactor.new unless options[:no_interactions]
66
- @listener = Listener.select_and_init(options[:watchdir] && File.expand_path(options[:watchdir]), options)
83
+ @listener = Listener.select_and_init(options)
67
84
 
68
85
  UI.clear if @options[:clear]
69
86
  debug_command_execution if @options[:verbose]
@@ -177,7 +194,11 @@ module Guard
177
194
  run_supervised_task(guard, :start)
178
195
  end
179
196
 
180
- interactor.start if interactor
197
+ unless options[:no_interactions]
198
+ @interactor = Interactor.fabricate
199
+ @interactor.start if @interactor
200
+ end
201
+
181
202
  listener.start
182
203
  end
183
204
 
@@ -190,6 +211,7 @@ module Guard
190
211
  run_supervised_task(guard, :stop)
191
212
  end
192
213
 
214
+ interactor.stop if interactor
193
215
  listener.stop
194
216
  abort
195
217
  end
@@ -428,9 +450,10 @@ module Guard
428
450
  # * `rspec` will find a class `Guard::RSpec`
429
451
  #
430
452
  # @param [String] name the name of the Guard
453
+ # @param [Boolean] fail_gracefully whether error messages should not be printed
431
454
  # @return [Class, nil] the loaded class
432
455
  #
433
- def get_guard_class(name)
456
+ def get_guard_class(name, fail_gracefully=false)
434
457
  name = name.to_s
435
458
  try_require = false
436
459
  const_name = name.gsub(/\/(.?)/) { "::#{ $1.upcase }" }.gsub(/(?:^|[_-])(.)/) { $1.upcase }
@@ -445,8 +468,10 @@ module Guard
445
468
  UI.error "Could not find class Guard::#{ const_name.capitalize }"
446
469
  end
447
470
  rescue LoadError => loadError
448
- UI.error "Could not load 'guard/#{ name.downcase }' or find class Guard::#{ const_name.capitalize }"
449
- UI.error loadError.to_s
471
+ unless fail_gracefully
472
+ UI.error "Could not load 'guard/#{ name.downcase }' or find class Guard::#{ const_name.capitalize }"
473
+ UI.error loadError.to_s
474
+ end
450
475
  end
451
476
  end
452
477
 
data/man/guard.1 CHANGED
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "GUARD" "1" "October 2011" "" ""
4
+ .TH "GUARD" "1" "December 2011" "" ""
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBguard\fR \- Guard keeps an eye on your file modifications\.
@@ -27,7 +27,7 @@ The following options are available:
27
27
  \fB\-n\fR, \fB\-\-notify\fR \fIFLAG\fR Disable notifications (Growl or Libnotify depending on your system)\. Notifications can be disabled globally by setting a GUARD_NOTIFY environment variable to false\. FLAG can be \fBtrue\fR/\fBfalse\fR or \fBt\fR/\fBf\fR\.
28
28
  .
29
29
  .P
30
- \fB\-d\fR, \fB\-\-debug\fR Runs Guard in debug mode\.
30
+ \fB\-v\fR, \fB\-\-verbose\fR Runs Guard in verbose mode\.
31
31
  .
32
32
  .P
33
33
  \fB\-g\fR, \fB\-\-group\fR \fIGROUP1\fR \fIGROUP2\fR\.\.\. Runs only the groups specified by GROUP1, GROUP2 etc\. Groups name should be separated by spaces\. Guards that don\'t belong to a group are considered global and are always run\.
@@ -44,7 +44,7 @@ The following options are available:
44
44
  .P
45
45
  \fB\-i\fR, \fB\-\-no\-interactions\fR Turn off completely any Guard terminal interactions\.
46
46
  .
47
- .SS "init <a href=\"guard\.html\">GUARD</a>"
47
+ .SS "init [GUARD]"
48
48
  If no Guardfile is present in the current directory, creates an empty Guardfile\.
49
49
  .
50
50
  .P
data/man/guard.1.html CHANGED
@@ -97,8 +97,8 @@
97
97
  Notifications can be disabled globally by setting a GUARD_NOTIFY environment variable to false.
98
98
  FLAG can be <code>true</code>/<code>false</code> or <code>t</code>/<code>f</code>.</p>
99
99
 
100
- <p><code>-d</code>, <code>--debug</code>
101
- Runs Guard in debug mode.</p>
100
+ <p><code>-v</code>, <code>--verbose</code>
101
+ Runs Guard in verbose mode.</p>
102
102
 
103
103
  <p><code>-g</code>, <code>--group</code> <var>GROUP1</var> <var>GROUP2</var>...
104
104
  Runs only the groups specified by GROUP1, GROUP2 etc.
@@ -117,7 +117,7 @@
117
117
  <p><code>-i</code>, <code>--no-interactions</code>
118
118
  Turn off completely any Guard terminal interactions.</p>
119
119
 
120
- <h3 id="init-GUARD">init <a href="guard.html">GUARD</a></h3>
120
+ <h3 id="init-GUARD-">init [GUARD]</h3>
121
121
 
122
122
  <p>If no Guardfile is present in the current directory, creates an empty Guardfile.</p>
123
123
 
@@ -172,7 +172,7 @@ https://github.com/guard/guard/blob/master/CHANGELOG.md</p>
172
172
 
173
173
  <ol class='man-decor man-foot man foot'>
174
174
  <li class='tl'></li>
175
- <li class='tc'>October 2011</li>
175
+ <li class='tc'>December 2011</li>
176
176
  <li class='tr'>guard(1)</li>
177
177
  </ol>
178
178
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: guard
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.10.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-12-19 00:00:00.000000000Z
12
+ date: 2012-01-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
16
- requirement: &70141887669800 !ruby/object:Gem::Requirement
16
+ requirement: &70103690365860 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 0.14.6
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70141887669800
24
+ version_requirements: *70103690365860
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: ffi
27
- requirement: &70141887668820 !ruby/object:Gem::Requirement
27
+ requirement: &70103690365180 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 0.5.0
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70141887668820
35
+ version_requirements: *70103690365180
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: bundler
38
- requirement: &70141887668060 !ruby/object:Gem::Requirement
38
+ requirement: &70103690358380 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70141887668060
46
+ version_requirements: *70103690358380
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rspec
49
- requirement: &70141887652680 !ruby/object:Gem::Requirement
49
+ requirement: &70103690357140 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 2.7.0
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70141887652680
57
+ version_requirements: *70103690357140
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: guard-rspec
60
- requirement: &70141887651580 !ruby/object:Gem::Requirement
60
+ requirement: &70103690356380 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 0.5.0
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70141887651580
68
+ version_requirements: *70103690356380
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: yard
71
- requirement: &70141887650780 !ruby/object:Gem::Requirement
71
+ requirement: &70103690355840 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ~>
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: 0.7.3
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70141887650780
79
+ version_requirements: *70103690355840
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: redcarpet
82
- requirement: &70141887649460 !ruby/object:Gem::Requirement
82
+ requirement: &70103690355140 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ~>
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: 1.17.2
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *70141887649460
90
+ version_requirements: *70103690355140
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: pry
93
- requirement: &70141887648300 !ruby/object:Gem::Requirement
93
+ requirement: &70103690354660 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ~>
@@ -98,7 +98,7 @@ dependencies:
98
98
  version: 0.9.6.2
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *70141887648300
101
+ version_requirements: *70103690354660
102
102
  description: Guard is a command line tool to easily handle events on file system modifications.
103
103
  email:
104
104
  - thibaud@thibaud.me
@@ -119,6 +119,8 @@ files:
119
119
  - lib/guard/guard.rb
120
120
  - lib/guard/hook.rb
121
121
  - lib/guard/interactor.rb
122
+ - lib/guard/interactors/readline.rb
123
+ - lib/guard/interactors/simple.rb
122
124
  - lib/guard/listener.rb
123
125
  - lib/guard/listeners/darwin.rb
124
126
  - lib/guard/listeners/linux.rb
@@ -201,7 +203,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
201
203
  version: 1.3.6
202
204
  requirements: []
203
205
  rubyforge_project: guard
204
- rubygems_version: 1.8.10
206
+ rubygems_version: 1.8.12
205
207
  signing_key:
206
208
  specification_version: 3
207
209
  summary: Guard keeps an eye on your file modifications