guard 2.7.0 → 2.7.1

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.
@@ -1,184 +0,0 @@
1
- # encoding: utf-8
2
- require "formatador"
3
-
4
- require "guard/guardfile/evaluator"
5
- require "guard/ui"
6
-
7
- module Guard
8
- # The DslDescriber evaluates the Guardfile and creates an internal structure
9
- # of it that is used in some inspection utility methods like the CLI commands
10
- # `show` and `list`.
11
- #
12
- # @see Guard::Dsl
13
- # @see Guard::CLI
14
- #
15
- class DslDescriber
16
- attr_reader :options
17
-
18
- # Initializes a new DslDescriber object.
19
- #
20
- # @option options [String] guardfile the path to a valid Guardfile
21
- #
22
- # @option options [String] guardfile_contents a string representing the
23
- # content of a valid Guardfile
24
- #
25
- # @see Guard::Guardfile::Evaluator#initialize
26
- #
27
- def initialize(options = {})
28
- @options = options
29
- ::Guard.reset_groups
30
- ::Guard.reset_plugins
31
- ::Guard.reset_scope
32
- end
33
-
34
- # List the Guard plugins that are available for use in your system and marks
35
- # those that are currently used in your `Guardfile`.
36
- #
37
- # @see CLI#list
38
- #
39
- def list
40
- _evaluate_guardfile
41
-
42
- names = ::Guard::PluginUtil.plugin_names.sort.uniq
43
- final_rows = names.inject([]) do |rows, name|
44
- rows << {
45
- Plugin: name.capitalize,
46
- Guardfile: ::Guard.plugins(name) ? "✔" : "✘"
47
- }
48
- end
49
-
50
- Formatador.display_compact_table(final_rows, [:Plugin, :Guardfile])
51
- end
52
-
53
- # Shows all Guard plugins and their options that are defined in
54
- # the `Guardfile`.
55
- #
56
- # @see CLI#show
57
- #
58
- def show
59
- _evaluate_guardfile
60
- groups = ::Guard.groups
61
-
62
- final_rows = groups.each_with_object([]) do |group, rows|
63
-
64
- plugins = Array(::Guard.plugins(group: group.name))
65
-
66
- plugins.each do |plugin|
67
- options = plugin.options.inject({}) do |o, (k, v)|
68
- o.tap { |option| option[k.to_s] = v }
69
- end.sort
70
-
71
- if options.empty?
72
- rows << :split
73
- rows << {
74
- Group: group.title,
75
- Plugin: plugin.title,
76
- Option: "",
77
- Value: ""
78
- }
79
- else
80
- options.each_with_index do |(option, value), index|
81
- if index == 0
82
- rows << :split
83
- rows << {
84
- Group: group.title,
85
- Plugin: plugin.title,
86
- Option: option.to_s,
87
- Value: value.inspect
88
- }
89
- else
90
- rows << {
91
- Group: "",
92
- Plugin: "",
93
- Option: option.to_s,
94
- Value: value.inspect
95
- }
96
- end
97
- end
98
- end
99
- end
100
-
101
- rows
102
- end
103
-
104
- Formatador.display_compact_table(
105
- final_rows.drop(1),
106
- [:Group, :Plugin, :Option, :Value]
107
- )
108
- end
109
-
110
- # Shows all notifiers and their options that are defined in
111
- # the `Guardfile`.
112
- #
113
- # @see CLI#show
114
- #
115
- def notifiers
116
- _evaluate_guardfile
117
-
118
- merged_notifiers = ::Guard::Notifier::NOTIFIERS.inject(:merge)
119
- final_rows = merged_notifiers.each_with_object([]) do |definition, rows|
120
-
121
- name = definition[0]
122
- clazz = definition[1]
123
- available = clazz.available?(silent: true) ? "✔" : "✘"
124
- notifier = ::Guard::Notifier.notifiers.detect { |n| n[:name] == name }
125
- used = notifier ? "✔" : "✘"
126
-
127
- options = _merge_options(clazz, notifier)
128
- options.delete(:silent)
129
-
130
- if options.empty?
131
- rows << :split
132
- _add_row(rows, name, available, used, "", "")
133
- else
134
- options.each_with_index do |(option, value), index|
135
- if index == 0
136
- rows << :split
137
- _add_row(rows, name, available, used, option.to_s, value.inspect)
138
- else
139
- _add_row(rows, "", "", "", option.to_s, value.inspect)
140
- end
141
- end
142
- end
143
-
144
- rows
145
- end
146
-
147
- Formatador.display_compact_table(
148
- final_rows.drop(1),
149
- [:Name, :Available, :Used, :Option, :Value]
150
- )
151
- end
152
-
153
- private
154
-
155
- # Evaluates the `Guardfile` by delegating to
156
- # {Guard::Guardfile::Evaluator#evaluate_guardfile}.
157
- #
158
- def _evaluate_guardfile
159
- ::Guard.save_scope
160
- ::Guard::Guardfile::Evaluator.new(options).evaluate_guardfile
161
- ::Guard.restore_scope
162
- end
163
-
164
- def _merge_options(klass, notifier)
165
- notify_options = notifier ? notifier[:options] : {}
166
-
167
- if klass.const_defined?(:DEFAULTS)
168
- klass.const_get(:DEFAULTS).merge(notify_options)
169
- else
170
- notify_options
171
- end
172
- end
173
-
174
- def _add_row(rows, name, available, used, option, value)
175
- rows << {
176
- Name: name,
177
- Available: available,
178
- Used: used,
179
- Option: option,
180
- Value: value
181
- }
182
- end
183
- end
184
- end
@@ -1,42 +0,0 @@
1
- require "guard/plugin/base"
2
-
3
- module Guard
4
- # @deprecated Inheriting from `Guard::Guard` is deprecated, please inherit
5
- # from {Plugin} instead. Please note that the constructor signature has
6
- # changed from `Guard::Guard#initialize(watchers = [], options = {})` to
7
- # `Guard::Plugin#initialize(options = {})`.
8
- #
9
- # @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
10
- # upgrade for Guard 2.0
11
- #
12
- class Guard
13
- include ::Guard::Plugin::Base
14
-
15
- # @deprecated Inheriting from `Guard::Guard` is deprecated, please inherit
16
- # from {Plugin} instead. Please note that the constructor signature
17
- # has changed from `Guard::Guard#initialize(watchers = [], options = {})`
18
- # to `Guard::Plugin#initialize(options = {})`.
19
- #
20
- # Initializes a Guard plugin. Don't do any work here,
21
- # especially as Guard plugins get initialized even if they are not in an
22
- # active group!
23
- #
24
- # @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
25
- # upgrade for Guard 2.0
26
- #
27
- # @param [Array<Guard::Watcher>] watchers the Guard plugin file watchers
28
- # @param [Hash] options the custom Guard plugin options
29
- # @option options [Symbol] group the group this Guard plugin belongs to
30
- # @option options [Boolean] any_return allow any object to be returned from
31
- # a watcher
32
- # @option options [Boolean] first_match stop after the first watcher that
33
- # returns a valid result
34
- #
35
- def initialize(watchers = [], options = {})
36
- UI.deprecation(Deprecator::GUARD_GUARD_DEPRECATION % title)
37
-
38
- _set_instance_variables_from_options(options.merge(watchers: watchers))
39
- _register_callbacks
40
- end
41
- end
42
- end
@@ -1,275 +0,0 @@
1
- require "guard/options"
2
- require "guard/plugin"
3
-
4
- module Guard
5
- module Guardfile
6
- # This class is responsible for evaluating the Guardfile. It delegates to
7
- # Guard::Dsl for the actual objects generation from the Guardfile content.
8
- #
9
- # @see Guard::Dsl
10
- #
11
- class Evaluator
12
- attr_reader :options, :guardfile_path
13
-
14
- def guardfile_source
15
- @source
16
- end
17
-
18
- # Initializes a new Guard::Guardfile::Evaluator object.
19
- #
20
- # @option opts [String] guardfile the path to a valid Guardfile
21
- # @option opts [String] guardfile_contents a string representing the
22
- # content of a valid Guardfile
23
- #
24
- def initialize(opts = {})
25
- @source = nil
26
- @guardfile_path = nil
27
-
28
- valid_options = opts.select do |k, _|
29
- [:guardfile, :guardfile_contents].include?(k.to_sym)
30
- end
31
-
32
- @options = ::Guard::Options.new(valid_options)
33
- end
34
-
35
- # Evaluates the DSL methods in the `Guardfile`.
36
- #
37
- # @example Programmatically evaluate a Guardfile
38
- # Guard::Guardfile::Evaluator.new.evaluate_guardfile
39
- #
40
- # @example Programmatically evaluate a Guardfile with a custom Guardfile
41
- # path
42
- #
43
- # options = { guardfile: '/Users/guardfile/MyAwesomeGuardfile' }
44
- # Guard::Guardfile::Evaluator.new(options).evaluate_guardfile
45
- #
46
- # @example Programmatically evaluate a Guardfile with an inline Guardfile
47
- #
48
- # options = { guardfile_contents: 'guard :rspec' }
49
- # Guard::Guardfile::Evaluator.new(options).evaluate_guardfile
50
- #
51
- def evaluate_guardfile
52
- _fetch_guardfile_contents
53
- ::Guard.add_builtin_plugins
54
- _instance_eval_guardfile(guardfile_contents)
55
- end
56
-
57
- # Re-evaluates the `Guardfile` to update
58
- # the current Guard configuration.
59
- #
60
- def reevaluate_guardfile
61
- # Don't re-evaluate inline Guardfile
62
- return if @source == :inline
63
-
64
- _before_reevaluate_guardfile
65
- evaluate_guardfile
66
- _after_reevaluate_guardfile
67
- end
68
-
69
- # Tests if the current `Guardfile` contains a specific Guard plugin.
70
- #
71
- # @example Programmatically test if a Guardfile contains a specific Guard
72
- # plugin
73
- #
74
- # File.read('Guardfile')
75
- # => "guard :rspec"
76
- #
77
- # Guard::Guardfile::Evaluator.new.guardfile_include?('rspec)
78
- # => true
79
- #
80
- # @param [String] plugin_name the name of the Guard
81
- # @return [Boolean] whether the Guard plugin has been declared
82
- #
83
- def guardfile_include?(plugin_name)
84
- regexp = /^guard\s*\(?\s*['":]#{ plugin_name }['"]?/
85
- _guardfile_contents_without_user_config.match(regexp)
86
- end
87
-
88
- # Gets the content of the `Guardfile` concatenated with the global
89
- # user configuration file.
90
- #
91
- # @example Programmatically get the content of the current Guardfile
92
- # Guard::Guardfile::Evaluator.new.guardfile_contents
93
- # => "guard :rspec"
94
- #
95
- # @return [String] the Guardfile content
96
- #
97
- def guardfile_contents
98
- config = File.read(_user_config_path) if File.exist?(_user_config_path)
99
- [_guardfile_contents_without_user_config, config].compact.join("\n")
100
- end
101
-
102
- private
103
-
104
- # Gets the content of the `Guardfile`.
105
- #
106
- # @return [String] the Guardfile content
107
- #
108
- def _guardfile_contents_without_user_config
109
- @guardfile_contents || ""
110
- end
111
-
112
- # Evaluates the content of the `Guardfile`.
113
- #
114
- # @param [String] contents the content to evaluate.
115
- #
116
- def _instance_eval_guardfile(contents)
117
- ::Guard::Dsl.new.instance_eval(contents, @guardfile_path || "", 1)
118
- rescue => ex
119
- ::Guard::UI.error "Invalid Guardfile, original error is:\n#{ $! }"
120
- raise ex
121
- end
122
-
123
- # Gets the content to evaluate and stores it into @guardfile_contents.
124
- #
125
- def _fetch_guardfile_contents
126
- _use_inline || _use_provided || _use_default
127
-
128
- return if _guardfile_contents_usable?
129
- ::Guard::UI.error "No Guard plugins found in Guardfile,"\
130
- " please add at least one."
131
- end
132
-
133
- # Use the provided inline Guardfile if provided.
134
- #
135
- def _use_inline
136
- source_from_option = @source.nil? && options[:guardfile_contents]
137
- inline = @source == :inline
138
-
139
- return false unless (source_from_option) || inline
140
-
141
- @source = :inline
142
- @guardfile_contents = options[:guardfile_contents]
143
-
144
- ::Guard::UI.info "Using inline Guardfile."
145
- true
146
- end
147
-
148
- # Try to use the provided Guardfile. Exits Guard if the Guardfile cannot
149
- # be found.
150
- #
151
- def _use_provided
152
- source_from_file = @source.nil? && options[:guardfile]
153
- return false unless source_from_file || (@source == :custom)
154
-
155
- @source = :custom
156
-
157
- options[:guardfile] = File.expand_path(options[:guardfile])
158
- if File.exist?(options[:guardfile])
159
- _read_guardfile(options[:guardfile])
160
- ::Guard::UI.info "Using Guardfile at #{ options[:guardfile] }."
161
- true
162
- else
163
- ::Guard::UI.error "No Guardfile exists at #{ options[:guardfile] }."
164
- exit 1
165
- end
166
-
167
- true
168
- end
169
-
170
- # Try to use one of the default Guardfiles (local or home Guardfile).
171
- # Exits Guard if no Guardfile is found.
172
- #
173
- def _use_default
174
- if guardfile_path = _find_default_guardfile
175
- @source = :default
176
- _read_guardfile(guardfile_path)
177
- else
178
- ::Guard::UI.error \
179
- "No Guardfile found, please create one with `guard init`."
180
- exit 1
181
- end
182
- end
183
-
184
- # Returns the first default Guardfile (either local or home Guardfile)
185
- # or nil otherwise.
186
- #
187
- def _find_default_guardfile
188
- [_local_guardfile_path, _home_guardfile_path].detect do |path|
189
- File.exist?(path)
190
- end
191
- end
192
-
193
- # Reads the current `Guardfile` content.
194
- #
195
- # @param [String] guardfile_path the path to the Guardfile
196
- #
197
- def _read_guardfile(guardfile_path)
198
- @guardfile_path = guardfile_path
199
- @guardfile_contents = File.read(guardfile_path)
200
- rescue => ex
201
- ::Guard::UI.error "Error reading file #{ guardfile_path }:"
202
- ::Guard::UI.error ex.inspect
203
- ::Guard::UI.error ex.backtrace
204
- exit 1
205
- end
206
-
207
- # Stops Guard and clear internal state
208
- # before the Guardfile will be re-evaluated.
209
- #
210
- def _before_reevaluate_guardfile
211
- ::Guard.runner.run(:stop)
212
- ::Guard.reset_groups
213
- ::Guard.reset_plugins
214
- ::Guard.reset_scope
215
- ::Guard::Notifier.clear_notifiers
216
- end
217
-
218
- # Starts Guard and notification and show a message
219
- # after the Guardfile has been re-evaluated.
220
- #
221
- def _after_reevaluate_guardfile
222
- ::Guard::Notifier.turn_on if ::Guard::Notifier.enabled?
223
-
224
- if !::Guard.send(:_non_builtin_plugins?)
225
- ::Guard::Notifier.notify(
226
- "No plugins found in Guardfile, please add at least one.",
227
- title: "Guard re-evaluate",
228
- image: :failed)
229
- else
230
- msg = "Guardfile has been re-evaluated."
231
- ::Guard::UI.info(msg)
232
- ::Guard::Notifier.notify(msg, title: "Guard re-evaluate")
233
-
234
- ::Guard.setup_scope
235
- ::Guard.runner.run(:start)
236
- end
237
- end
238
-
239
- # Tests if the current `Guardfile` content is usable.
240
- #
241
- # @return [Boolean] if the Guardfile is usable
242
- #
243
- def _guardfile_contents_usable?
244
- guardfile_contents && guardfile_contents =~ /guard/m
245
- end
246
-
247
- # The path to the `Guardfile` that is located at
248
- # the directory, where Guard has been started from.
249
- #
250
- # @return [String] the path to the local Guardfile
251
- #
252
- def _local_guardfile_path
253
- File.expand_path(File.join(Dir.pwd, "Guardfile"))
254
- end
255
-
256
- # The path to the `.Guardfile` that is located at
257
- # the users home directory.
258
- #
259
- # @return [String] the path to `~/.Guardfile`
260
- #
261
- def _home_guardfile_path
262
- File.expand_path(File.join("~", ".Guardfile"))
263
- end
264
-
265
- # The path to the user configuration `.guard.rb`
266
- # that is located at the users home directory.
267
- #
268
- # @return [String] the path to `~/.guard.rb`
269
- #
270
- def _user_config_path
271
- File.expand_path(File.join("~", ".guard.rb"))
272
- end
273
- end
274
- end
275
- end