guard 1.8.3 → 2.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +68 -10
  3. data/README.md +54 -33
  4. data/lib/guard.rb +133 -483
  5. data/lib/guard/cli.rb +78 -82
  6. data/lib/guard/commander.rb +121 -0
  7. data/lib/guard/commands/all.rb +1 -1
  8. data/lib/guard/commands/reload.rb +1 -1
  9. data/lib/guard/deprecated_methods.rb +59 -0
  10. data/lib/guard/deprecator.rb +107 -0
  11. data/lib/guard/dsl.rb +143 -329
  12. data/lib/guard/dsl_describer.rb +101 -57
  13. data/lib/guard/group.rb +27 -8
  14. data/lib/guard/guard.rb +25 -150
  15. data/lib/guard/guardfile.rb +35 -85
  16. data/lib/guard/guardfile/evaluator.rb +245 -0
  17. data/lib/guard/guardfile/generator.rb +89 -0
  18. data/lib/guard/interactor.rb +147 -163
  19. data/lib/guard/notifier.rb +83 -137
  20. data/lib/guard/notifiers/base.rb +220 -0
  21. data/lib/guard/notifiers/emacs.rb +39 -37
  22. data/lib/guard/notifiers/file_notifier.rb +29 -25
  23. data/lib/guard/notifiers/gntp.rb +68 -75
  24. data/lib/guard/notifiers/growl.rb +49 -52
  25. data/lib/guard/notifiers/growl_notify.rb +51 -56
  26. data/lib/guard/notifiers/libnotify.rb +41 -48
  27. data/lib/guard/notifiers/notifysend.rb +58 -38
  28. data/lib/guard/notifiers/rb_notifu.rb +54 -54
  29. data/lib/guard/notifiers/terminal_notifier.rb +48 -36
  30. data/lib/guard/notifiers/terminal_title.rb +23 -19
  31. data/lib/guard/notifiers/tmux.rb +110 -93
  32. data/lib/guard/options.rb +21 -0
  33. data/lib/guard/plugin.rb +66 -0
  34. data/lib/guard/plugin/base.rb +178 -0
  35. data/lib/guard/plugin/hooker.rb +123 -0
  36. data/lib/guard/plugin_util.rb +158 -0
  37. data/lib/guard/rake_task.rb +47 -0
  38. data/lib/guard/runner.rb +62 -82
  39. data/lib/guard/setuper.rb +248 -0
  40. data/lib/guard/ui.rb +24 -80
  41. data/lib/guard/ui/colors.rb +60 -0
  42. data/lib/guard/version.rb +1 -2
  43. data/lib/guard/watcher.rb +30 -30
  44. data/man/guard.1 +4 -4
  45. data/man/guard.1.html +6 -4
  46. metadata +25 -11
  47. data/lib/guard/hook.rb +0 -120
@@ -1,5 +1,10 @@
1
1
  require 'thor'
2
2
 
3
+ require 'guard'
4
+ require 'guard/version'
5
+ require 'guard/dsl_describer'
6
+ require 'guard/guardfile'
7
+
3
8
  module Guard
4
9
 
5
10
  # Facade for the Guard command line interface managed by [Thor](https://github.com/wycats/thor).
@@ -8,97 +13,78 @@ module Guard
8
13
  #
9
14
  class CLI < Thor
10
15
 
11
- require 'guard'
12
- require 'guard/version'
13
- require 'guard/dsl_describer'
14
- require 'guard/guardfile'
15
-
16
16
  default_task :start
17
17
 
18
18
  desc 'start', 'Starts Guard'
19
19
 
20
20
  method_option :clear,
21
- :type => :boolean,
22
- :default => false,
23
- :aliases => '-c',
24
- :banner => 'Auto clear shell before each action'
21
+ type: :boolean,
22
+ default: false,
23
+ aliases: '-c',
24
+ banner: 'Auto clear shell before each action'
25
25
 
26
26
  method_option :notify,
27
- :type => :boolean,
28
- :default => true,
29
- :aliases => '-n',
30
- :banner => 'Notifications feature'
27
+ type: :boolean,
28
+ default: true,
29
+ aliases: '-n',
30
+ banner: 'Notifications feature'
31
31
 
32
32
  method_option :debug,
33
- :type => :boolean,
34
- :default => false,
35
- :aliases => '-d',
36
- :banner => 'Show debug information'
33
+ type: :boolean,
34
+ default: false,
35
+ aliases: '-d',
36
+ banner: 'Show debug information'
37
37
 
38
38
  method_option :group,
39
- :type => :array,
40
- :default => [],
41
- :aliases => '-g',
42
- :banner => 'Run only the passed groups'
39
+ type: :array,
40
+ default: [],
41
+ aliases: '-g',
42
+ banner: 'Run only the passed groups'
43
43
 
44
44
  method_option :plugin,
45
- :type => :array,
46
- :default => [],
47
- :aliases => '-P',
48
- :banner => 'Run only the passed plugins'
45
+ type: :array,
46
+ default: [],
47
+ aliases: '-P',
48
+ banner: 'Run only the passed plugins'
49
49
 
50
50
  method_option :watchdir,
51
- :type => :array,
52
- :aliases => '-w',
53
- :banner => 'Specify the directories to watch'
51
+ type: :array,
52
+ aliases: '-w',
53
+ banner: 'Specify the directories to watch'
54
54
 
55
55
  method_option :guardfile,
56
- :type => :string,
57
- :aliases => '-G',
58
- :banner => 'Specify a Guardfile'
59
-
60
- # DEPRECATED
61
- method_option :no_vendor,
62
- :type => :boolean,
63
- :default => false,
64
- :aliases => '-I',
65
- :banner => 'DEPRECATED: Ignore vendored dependencies'
66
-
67
- # DEPRECATED
68
- method_option :watch_all_modifications,
69
- :type => :boolean,
70
- :default => false,
71
- :aliases => '-A',
72
- :banner => 'DEPRECATED: Watch for all file modifications including moves and deletions'
56
+ type: :string,
57
+ aliases: '-G',
58
+ banner: 'Specify a Guardfile'
73
59
 
74
60
  method_option :no_interactions,
75
- :type => :boolean,
76
- :default => false,
77
- :aliases => '-i',
78
- :banner => 'Turn off completely any guard terminal interactions'
61
+ type: :boolean,
62
+ default: false,
63
+ aliases: '-i',
64
+ banner: 'Turn off completely any Guard terminal interactions'
79
65
 
80
66
  method_option :no_bundler_warning,
81
- :type => :boolean,
82
- :default => false,
83
- :aliases => '-B',
84
- :banner => 'Turn off warning when Bundler is not present'
67
+ type: :boolean,
68
+ default: false,
69
+ aliases: '-B',
70
+ banner: 'Turn off warning when Bundler is not present'
85
71
 
86
72
  method_option :show_deprecations,
87
- :type => :boolean,
88
- :default => false,
89
- :banner => 'Turn on deprecation warnings'
73
+ type: :boolean,
74
+ default: false,
75
+ banner: 'Turn on deprecation warnings'
90
76
 
91
77
  # Listen options
92
78
  method_option :latency,
93
- :type => :numeric,
94
- :aliases => '-l',
95
- :banner => 'Overwrite Listen\'s default latency'
79
+ type: :numeric,
80
+ aliases: '-l',
81
+ banner: 'Overwrite Listen\'s default latency'
96
82
 
97
83
  method_option :force_polling,
98
- :type => :boolean,
99
- :default => false,
100
- :aliases => '-p',
101
- :banner => 'Force usage of the Listen polling listener'
84
+ type: :boolean,
85
+ default: false,
86
+ aliases: '-p',
87
+ banner: 'Force usage of the Listen polling listener'
102
88
 
103
89
  # Start Guard by initializing the defined Guard plugins and watch the file system.
104
90
  # This is the default task, so calling `guard` is the same as calling `guard start`.
@@ -106,7 +92,7 @@ module Guard
106
92
  # @see Guard.start
107
93
  #
108
94
  def start
109
- verify_bundler_presence unless options[:no_bundler_warning]
95
+ _verify_bundler_presence unless options[:no_bundler_warning]
110
96
  ::Guard.start(options)
111
97
 
112
98
  return if ENV['GUARD_ENV'] == 'test'
@@ -116,7 +102,7 @@ module Guard
116
102
  end
117
103
  end
118
104
 
119
- desc 'list', 'Lists guards that can be used with init'
105
+ desc 'list', 'Lists Guard plugins that can be used with init'
120
106
 
121
107
  # List the Guard plugins that are available for use in your system and marks
122
108
  # those that are currently used in your `Guardfile`.
@@ -124,7 +110,17 @@ module Guard
124
110
  # @see Guard::DslDescriber.list
125
111
  #
126
112
  def list
127
- ::Guard::DslDescriber.list(options)
113
+ ::Guard::DslDescriber.new(options).list
114
+ end
115
+
116
+ desc 'notifiers', 'Lists notifiers and its options'
117
+
118
+ # List the Notifiers for use in your system.
119
+ #
120
+ # @see Guard::DslDescriber.notifiers
121
+ #
122
+ def notifiers
123
+ ::Guard::DslDescriber.new(options).notifiers
128
124
  end
129
125
 
130
126
  desc 'version', 'Show the Guard version'
@@ -138,35 +134,35 @@ module Guard
138
134
  puts "Guard version #{ ::Guard::VERSION }"
139
135
  end
140
136
 
141
- desc 'init [GUARDS]', 'Generates a Guardfile at the current directory (if it is not already there) and adds all installed guards or the given GUARDS into it'
137
+ desc 'init [GUARDS]', 'Generates a Guardfile at the current directory (if it is not already there) and adds all installed Guard plugins or the given GUARDS into it'
142
138
 
143
139
  method_option :bare,
144
- :type => :boolean,
145
- :default => false,
146
- :aliases => '-b',
147
- :banner => 'Generate a bare Guardfile without adding any installed guard into it'
140
+ type: :boolean,
141
+ default: false,
142
+ aliases: '-b',
143
+ banner: 'Generate a bare Guardfile without adding any installed plugin into it'
148
144
 
149
145
  # Initializes the templates of all installed Guard plugins and adds them
150
146
  # to the `Guardfile` when no Guard name is passed. When passing
151
147
  # Guard plugin names it does the same but only for those Guard plugins.
152
148
  #
153
- # @see Guard::Guard.initialize_template
154
- # @see Guard::Guard.initialize_all_templates
149
+ # @see Guard::Guardfile.initialize_template
150
+ # @see Guard::Guardfile.initialize_all_templates
155
151
  #
156
- # @param [Array<String>] guard_names the name of the Guard plugins to initialize
152
+ # @param [Array<String>] plugin_names the name of the Guard plugins to initialize
157
153
  #
158
- def init(*guard_names)
159
- verify_bundler_presence
154
+ def init(*plugin_names)
155
+ _verify_bundler_presence
160
156
 
161
- ::Guard::Guardfile.create_guardfile(:abort_on_existence => options[:bare])
157
+ ::Guard::Guardfile.create_guardfile(abort_on_existence: options[:bare])
162
158
 
163
159
  return if options[:bare]
164
160
 
165
- if guard_names.empty?
161
+ if plugin_names.empty?
166
162
  ::Guard::Guardfile.initialize_all_templates
167
163
  else
168
- guard_names.each do |guard_name|
169
- ::Guard::Guardfile.initialize_template(guard_name)
164
+ plugin_names.each do |plugin_name|
165
+ ::Guard::Guardfile.initialize_template(plugin_name)
170
166
  end
171
167
  end
172
168
  end
@@ -180,7 +176,7 @@ module Guard
180
176
  # @see Guard::DslDescriber.show
181
177
  #
182
178
  def show
183
- ::Guard::DslDescriber.show(options)
179
+ ::Guard::DslDescriber.new(options).show
184
180
  end
185
181
 
186
182
  private
@@ -188,7 +184,7 @@ module Guard
188
184
  # Verifies if Guard is run with `bundle exec` and
189
185
  # shows a hint to do so if not.
190
186
  #
191
- def verify_bundler_presence
187
+ def _verify_bundler_presence
192
188
  if File.exists?('Gemfile') && !ENV['BUNDLE_GEMFILE']
193
189
  ::Guard::UI.info <<EOF
194
190
 
@@ -0,0 +1,121 @@
1
+ module Guard
2
+
3
+ module Commander
4
+
5
+ # Start Guard by evaluating the `Guardfile`, initializing declared Guard plugins
6
+ # and starting the available file change listener.
7
+ # Main method for Guard that is called from the CLI when Guard starts.
8
+ #
9
+ # - Setup Guard internals
10
+ # - Evaluate the `Guardfile`
11
+ # - Configure Notifiers
12
+ # - Initialize the declared Guard plugins
13
+ # - Start the available file change listener
14
+ #
15
+ # @option options [Boolean] clear if auto clear the UI should be done
16
+ # @option options [Boolean] notify if system notifications should be shown
17
+ # @option options [Boolean] debug if debug output should be shown
18
+ # @option options [Array<String>] group the list of groups to start
19
+ # @option options [String] watchdir the director to watch
20
+ # @option options [String] guardfile the path to the Guardfile
21
+ # @see CLI#start
22
+ #
23
+ def start(options = {})
24
+ setup(options) unless running
25
+
26
+ within_preserved_state do
27
+ ::Guard::UI.debug 'Guard starts all plugins'
28
+ runner.run(:start)
29
+ ::Guard::UI.info "Guard is now watching at '#{ @watchdirs.join "', '" }'"
30
+ listener.start
31
+ end
32
+ end
33
+
34
+ # Stop Guard listening to file changes.
35
+ #
36
+ def stop
37
+ setup unless running
38
+
39
+ within_preserved_state do
40
+ ::Guard::UI.debug 'Guard stops all plugins'
41
+ runner.run(:stop)
42
+ ::Guard::Notifier.turn_off
43
+ ::Guard::UI.info 'Bye bye...', reset: true
44
+ listener.stop
45
+ @running = false
46
+ end
47
+ end
48
+
49
+ # Reload Guardfile and all Guard plugins currently enabled.
50
+ # If no scope is given, then the Guardfile will be re-evaluated,
51
+ # which results in a stop/start, which makes the reload obsolete.
52
+ #
53
+ # @param [Hash] scopes hash with a Guard plugin or a group scope
54
+ #
55
+ def reload(scopes = {})
56
+ setup unless running
57
+
58
+ within_preserved_state do
59
+ ::Guard::UI.clear(force: true)
60
+ ::Guard::UI.action_with_scopes('Reload', scopes)
61
+
62
+ if scopes.empty?
63
+ evaluator.reevaluate_guardfile
64
+ else
65
+ runner.run(:reload, scopes)
66
+ end
67
+ end
68
+ end
69
+
70
+ # Trigger `run_all` on all Guard plugins currently enabled.
71
+ #
72
+ # @param [Hash] scopes hash with a Guard plugin or a group scope
73
+ #
74
+ def run_all(scopes = {})
75
+ setup unless running
76
+
77
+ within_preserved_state do
78
+ ::Guard::UI.clear(force: true)
79
+ ::Guard::UI.action_with_scopes('Run all', scopes)
80
+ runner.run(:run_all, scopes)
81
+ end
82
+ end
83
+
84
+ # Pause Guard listening to file changes.
85
+ #
86
+ def pause
87
+ if listener.paused?
88
+ ::Guard::UI.info 'Un-paused files modification listening', reset: true
89
+ listener.unpause
90
+ else
91
+ ::Guard::UI.info 'Paused files modification listening', reset: true
92
+ listener.pause
93
+ end
94
+ end
95
+
96
+ # Runs a block where the interactor is
97
+ # blocked and execution is synchronized
98
+ # to avoid state inconsistency.
99
+ #
100
+ # @param [Boolean] restart_interactor whether to restart the interactor or
101
+ # not
102
+ # @yield the block to run
103
+ #
104
+ def within_preserved_state
105
+ lock.synchronize do
106
+ begin
107
+ interactor.stop if interactor
108
+ @result = yield
109
+ rescue Interrupt
110
+ # Bring back Pry when the block is halted with Ctrl-C
111
+ end
112
+
113
+ interactor.start if running
114
+ end
115
+
116
+ @result
117
+ end
118
+
119
+ end
120
+
121
+ end
@@ -22,7 +22,7 @@ module Guard
22
22
  if rest.empty?
23
23
  ::Guard.run_all scopes
24
24
  else
25
- output.puts "Unkown scope #{ rest.join(', ') }"
25
+ output.puts "Unknown scope #{ rest.join(', ') }"
26
26
  end
27
27
  end
28
28
  end
@@ -22,7 +22,7 @@ module Guard
22
22
  if rest.empty?
23
23
  ::Guard.reload scopes
24
24
  else
25
- output.puts "Unkown scope #{ rest.join(', ') }"
25
+ output.puts "Unknown scope #{ rest.join(', ') }"
26
26
  end
27
27
  end
28
28
 
@@ -0,0 +1,59 @@
1
+ module Guard
2
+
3
+ module DeprecatedMethods
4
+
5
+ # @deprecated Use `Guard.plugins(filter)` instead.
6
+ #
7
+ # @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
8
+ # upgrade for Guard 2.0
9
+ #
10
+ def guards(filter = nil)
11
+ ::Guard::UI.deprecation(::Guard::Deprecator::GUARDS_DEPRECATION)
12
+ plugins(filter)
13
+ end
14
+
15
+ # @deprecated Use `Guard.add_plugin(name, options = {})` instead.
16
+ #
17
+ # @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
18
+ # upgrade for Guard 2.0
19
+ #
20
+ def add_guard(*args)
21
+ ::Guard::UI.deprecation(::Guard::Deprecator::ADD_GUARD_DEPRECATION)
22
+ add_plugin(*args)
23
+ end
24
+
25
+ # @deprecated Use
26
+ # `Guard::PluginUtil.new(name).plugin_class(fail_gracefully:
27
+ # fail_gracefully)` instead.
28
+ #
29
+ # @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
30
+ # upgrade for Guard 2.0
31
+ #
32
+ def get_guard_class(name, fail_gracefully = false)
33
+ ::Guard::UI.deprecation(::Guard::Deprecator::GET_GUARD_CLASS_DEPRECATION)
34
+ ::Guard::PluginUtil.new(name).plugin_class(fail_gracefully: fail_gracefully)
35
+ end
36
+
37
+ # @deprecated Use `Guard::PluginUtil.new(name).plugin_location` instead.
38
+ #
39
+ # @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
40
+ # upgrade for Guard 2.0
41
+ #
42
+ def locate_guard(name)
43
+ ::Guard::UI.deprecation(::Guard::Deprecator::LOCATE_GUARD_DEPRECATION)
44
+ ::Guard::PluginUtil.new(name).plugin_location
45
+ end
46
+
47
+ # @deprecated Use `Guard::PluginUtil.plugin_names` instead.
48
+ #
49
+ # @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
50
+ # upgrade for Guard 2.0
51
+ #
52
+ def guard_gem_names
53
+ ::Guard::UI.deprecation(::Guard::Deprecator::GUARD_GEM_NAMES_DEPRECATION)
54
+ ::Guard::PluginUtil.plugin_names
55
+ end
56
+
57
+ end
58
+
59
+ end