guard 2.7.0 → 2.7.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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