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,293 +0,0 @@
1
- require "guard/commands/all"
2
- require "guard/commands/change"
3
- require "guard/commands/notification"
4
- require "guard/commands/pause"
5
- require "guard/commands/reload"
6
- require "guard/commands/scope"
7
- require "guard/commands/show"
8
-
9
- require "guard/jobs/base"
10
-
11
- module Guard
12
- module Jobs
13
- class TerminalSettings
14
- def initialize
15
- @settings = nil
16
- @works = ::Guard::Sheller.run("hash", "stty") || false
17
- end
18
-
19
- def restore
20
- return unless configurable? && @settings
21
- ::Guard::Sheller.run("stty #{ @setting } 2>#{ DEV_NULL }")
22
- end
23
-
24
- def save
25
- return unless configurable?
26
- @settings = ::Guard::Sheller.stdout("stty -g 2>#{ DEV_NULL }").chomp
27
- end
28
-
29
- def echo
30
- return unless configurable?
31
- ::Guard::Sheller.run("stty echo 2>#{ DEV_NULL }")
32
- end
33
-
34
- def configurable?
35
- @works
36
- end
37
- end
38
-
39
- class PryWrapper < Base
40
- # The default Ruby script to configure Guard Pry if the option `:guard_rc`
41
- # is not defined.
42
- GUARD_RC = "~/.guardrc"
43
-
44
- # The default Guard Pry history file if the option `:history_file` is not
45
- # defined.
46
- HISTORY_FILE = "~/.guard_history"
47
-
48
- # List of shortcuts for each interactor command
49
- SHORTCUTS = {
50
- help: "h",
51
- all: "a",
52
- reload: "r",
53
- change: "c",
54
- show: "s",
55
- scope: "o",
56
- notification: "n",
57
- pause: "p",
58
- exit: "e",
59
- quit: "q"
60
- }
61
-
62
- def initialize(options)
63
- @mutex = Mutex.new
64
- @thread = nil
65
- @terminal_settings = TerminalSettings.new
66
-
67
- _setup(options)
68
- end
69
-
70
- def foreground
71
- ::Guard::UI.debug "Start interactor"
72
- @terminal_settings.save
73
-
74
- _start_pry
75
- @thread.join
76
- thread = @thread
77
- thread.nil? ? :stopped : :exit
78
- ensure
79
- ::Guard::UI.reset_line
80
- ::Guard::UI.debug "Interactor was stopped or killed"
81
- @terminal_settings.restore
82
- end
83
-
84
- def background
85
- _kill_pry
86
- end
87
-
88
- def handle_interrupt
89
- thread = @thread
90
- fail Interrupt unless thread
91
- thread.raise Interrupt
92
- end
93
-
94
- private
95
-
96
- attr_reader :thread
97
-
98
- def _start_pry
99
- @mutex.synchronize do
100
- unless @thread
101
- @thread = Thread.new { Pry.start }
102
- @thread.join(0.5) # give pry a chance to start
103
- end
104
- end
105
- end
106
-
107
- def _kill_pry
108
- @mutex.synchronize do
109
- unless @thread.nil?
110
- @thread.kill
111
- @thread = nil # set to nil so we know we were killed
112
- end
113
- end
114
- end
115
-
116
- def _setup(options)
117
- Pry.config.should_load_rc = false
118
- Pry.config.should_load_local_rc = false
119
- history_file_path = options[:history_file] || HISTORY_FILE
120
- Pry.config.history.file = File.expand_path(history_file_path)
121
-
122
- _add_hooks
123
-
124
- Guard::Commands::All.import
125
- Guard::Commands::Change.import
126
- Guard::Commands::Notification.import
127
- Guard::Commands::Pause.import
128
- Guard::Commands::Reload.import
129
- Guard::Commands::Show.import
130
- Guard::Commands::Scope.import
131
-
132
- _setup_commands
133
- _configure_prompt
134
- end
135
-
136
- # Add Pry hooks:
137
- #
138
- # * Load `~/.guardrc` within each new Pry session.
139
- # * Load project's `.guardrc` within each new Pry session.
140
- # * Restore prompt after each evaluation.
141
- #
142
- def _add_hooks
143
- _add_load_guard_rc_hook
144
- _add_load_project_guard_rc_hook
145
- _add_restore_visibility_hook if @terminal_settings.configurable?
146
- end
147
-
148
- # Add a `when_started` hook that loads a global .guardrc if it exists.
149
- #
150
- def _add_load_guard_rc_hook
151
- Pry.config.hooks.add_hook :when_started, :load_guard_rc do
152
- (self.class.options[:guard_rc] || GUARD_RC).tap do |p|
153
- load p if File.exist?(File.expand_path(p))
154
- end
155
- end
156
- end
157
-
158
- # Add a `when_started` hook that loads a project .guardrc if it exists.
159
- #
160
- def _add_load_project_guard_rc_hook
161
- Pry.config.hooks.add_hook :when_started, :load_project_guard_rc do
162
- project_guard_rc = Dir.pwd + "/.guardrc"
163
- load project_guard_rc if File.exist?(project_guard_rc)
164
- end
165
- end
166
-
167
- # Add a `after_eval` hook that restores visibility after a command is
168
- # eval.
169
- def _add_restore_visibility_hook
170
- Pry.config.hooks.add_hook :after_eval, :restore_visibility do
171
- @terminal_settings.echo
172
- end
173
- end
174
-
175
- def _setup_commands
176
- _replace_reset_command
177
- _create_run_all_command
178
- _create_command_aliases
179
- _create_guard_commands
180
- _create_group_commands
181
- end
182
-
183
- # Replaces reset defined inside of Pry with a reset that
184
- # instead restarts guard.
185
- #
186
- def _replace_reset_command
187
- Pry.commands.command "reset", "Reset the Guard to a clean state." do
188
- output.puts "Guard reset."
189
- exec "guard"
190
- end
191
- end
192
-
193
- # Creates a command that triggers the `:run_all` action
194
- # when the command is empty (just pressing enter on the
195
- # beginning of a line).
196
- #
197
- def _create_run_all_command
198
- Pry.commands.block_command(/^$/, "Hit enter to run all") do
199
- Pry.run_command "all"
200
- end
201
- end
202
-
203
- # Creates command aliases for the commands: `help`, `reload`, `change`,
204
- # `scope`, `notification`, `pause`, `exit` and `quit`, which will be the
205
- # first letter of the command.
206
- #
207
- def _create_command_aliases
208
- SHORTCUTS.each do |command, shortcut|
209
- Pry.commands.alias_command shortcut, command.to_s
210
- end
211
- end
212
-
213
- # Create a shorthand command to run the `:run_all`
214
- # action on a specific Guard plugin. For example,
215
- # when guard-rspec is available, then a command
216
- # `rspec` is created that runs `all rspec`.
217
- #
218
- def _create_guard_commands
219
- ::Guard.plugins.each do |guard_plugin|
220
- cmd = "Run all #{ guard_plugin.title }"
221
- Pry.commands.create_command guard_plugin.name, cmd do
222
- group "Guard"
223
-
224
- def process
225
- Pry.run_command "all #{ match }"
226
- end
227
- end
228
- end
229
- end
230
-
231
- # Create a shorthand command to run the `:run_all`
232
- # action on a specific Guard group. For example,
233
- # when you have a group `frontend`, then a command
234
- # `frontend` is created that runs `all frontend`.
235
- #
236
- def _create_group_commands
237
- ::Guard.groups.each do |group|
238
- next if group.name == :default
239
-
240
- cmd = "Run all #{ group.title }"
241
- Pry.commands.create_command group.name.to_s, cmd do
242
- group "Guard"
243
-
244
- def process
245
- Pry.run_command "all #{ match }"
246
- end
247
- end
248
- end
249
- end
250
-
251
- # Configures the pry prompt to see `guard` instead of
252
- # `pry`.
253
- #
254
- def _configure_prompt
255
- Pry.config.prompt = [_prompt(">"), _prompt("*")]
256
- end
257
-
258
- # Returns the plugins scope, or the groups scope ready for display in the
259
- # prompt.
260
- #
261
- def _scope_for_prompt
262
- scope_name = [:plugins, :groups].detect do |name|
263
- ! ::Guard.scope[name].empty?
264
- end
265
- scope_name ? "#{_join_scope_for_prompt(scope_name)} " : ""
266
- end
267
-
268
- # Joins the scope corresponding to the given scope name with commas.
269
- #
270
- def _join_scope_for_prompt(scope_name)
271
- ::Guard.scope[scope_name].map(&:title).join(",")
272
- end
273
-
274
- # Returns a proc that will return itself a string ending with the given
275
- # `ending_char` when called.
276
- #
277
- def _prompt(ending_char)
278
- proc do |target_self, nest_level, pry|
279
- history = pry.input_array.size
280
- process = ::Guard.listener.paused? ? "pause" : "guard"
281
- level = ":#{ nest_level }" unless nest_level.zero?
282
-
283
- "[#{ history }] #{ _scope_for_prompt }#{ process }"\
284
- "(#{ _clip_name(target_self) })#{ level }#{ ending_char } "
285
- end
286
- end
287
-
288
- def _clip_name(target)
289
- Pry.view_clip(target)
290
- end
291
- end
292
- end
293
- end
@@ -1,178 +0,0 @@
1
- require "guard/ui"
2
-
3
- module Guard
4
- # This class contains useful methods to:
5
- #
6
- # * Fetch all the Guard plugins names;
7
- # * Initialize a plugin, get its location;
8
- # * Return its class name;
9
- # * Add its template to the Guardfile.
10
- #
11
- class PluginUtil
12
- ERROR_NO_GUARD_OR_CLASS = "Could not load 'guard/%s' or'\
13
- ' find class Guard::%s"
14
-
15
- INFO_ADDED_GUARD_TO_GUARDFILE = "%s guard added to Guardfile,"\
16
- " feel free to edit it"
17
-
18
- attr_accessor :name
19
-
20
- # Returns a list of Guard plugin Gem names installed locally.
21
- #
22
- # @return [Array<String>] a list of Guard plugin gem names
23
- #
24
- def self.plugin_names
25
- if Gem::Version.create(Gem::VERSION) >= Gem::Version.create("1.8.0")
26
- Gem::Specification.find_all.select do |x|
27
- if x.name =~ /^guard-/
28
- true
29
- elsif x.name != "guard"
30
-
31
- guard_plugin_path = File.join(
32
- x.full_gem_path,
33
- "lib/guard/#{ x.name }.rb"
34
- )
35
-
36
- File.exist?(guard_plugin_path)
37
- end
38
- end
39
- else
40
- ::Guard::UI.deprecation \
41
- "Rubygems version prior to 1.8.0 are no longer supported"\
42
- " and may not work"
43
-
44
- Gem.source_index.find_name(/^guard-/)
45
- end.map { |x| x.name.sub(/^guard-/, "") }.uniq
46
- end
47
-
48
- # Initializes a new `Guard::PluginUtil` object.
49
- #
50
- # @param [String] name the name of the Guard plugin
51
- #
52
- def initialize(name)
53
- @name = name.to_s.sub(/^guard-/, "")
54
- end
55
-
56
- # Initializes a new `Guard::Plugin` with the given `options` hash. This
57
- # methods handles plugins that inherit from the deprecated `Guard::Guard`
58
- # class as well as plugins that inherit from `Guard::Plugin`.
59
- #
60
- # @see Guard::Plugin
61
- # @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
62
- # upgrade for Guard 2.0
63
- #
64
- # @return [Guard::Plugin] the initialized plugin
65
- # @return [Guard::Guard] the initialized plugin. This return type is
66
- # deprecated and the plugin's maintainer should update it to be
67
- # compatible with Guard 2.0. For more information on how to upgrade for
68
- # Guard 2.0, please head over to:
69
- # https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0
70
- #
71
- def initialize_plugin(options)
72
- if plugin_class.superclass.to_s == "Guard::Guard"
73
- plugin_class.new(options.delete(:watchers), options)
74
- else
75
- plugin_class.new(options)
76
- end
77
- end
78
-
79
- # Locates a path to a Guard plugin gem.
80
- #
81
- # @return [String] the full path to the plugin gem
82
- #
83
- def plugin_location
84
- @plugin_location ||= begin
85
- if Gem::Version.create(Gem::VERSION) >= Gem::Version.create("1.8.0")
86
- Gem::Specification.find_by_name("guard-#{ name }").full_gem_path
87
- else
88
- Gem.source_index.find_name("guard-#{ name }").last.full_gem_path
89
- end
90
- end
91
- rescue
92
- ::Guard::UI.error "Could not find 'guard-#{ name }' gem path."
93
- end
94
-
95
- # Tries to load the Guard plugin main class. This transforms the supplied
96
- # plugin name into a class name:
97
- #
98
- # * `guardname` will become `Guard::Guardname`
99
- # * `dashed-guard-name` will become `Guard::DashedGuardName`
100
- # * `underscore_guard_name` will become `Guard::UnderscoreGuardName`
101
- #
102
- # When no class is found with the strict case sensitive rules, another
103
- # try is made to locate the class without matching case:
104
- #
105
- # * `rspec` will find a class `Guard::RSpec`
106
- #
107
- # @option options [Boolean] fail_gracefully whether error messages should
108
- # not be printed
109
- #
110
- # @return [Class, nil] the loaded class
111
- #
112
- def plugin_class(options = {})
113
- options = { fail_gracefully: false }.merge(options)
114
-
115
- try_require = false
116
- begin
117
- require "guard/#{ name.downcase }" if try_require
118
-
119
- @plugin_class ||= ::Guard.const_get(_plugin_constant)
120
- rescue TypeError => error
121
- if try_require
122
- ::Guard::UI.error "Could not find class Guard::#{ _constant_name }"
123
- ::Guard::UI.error error.backtrace.join("\n")
124
- else
125
- try_require = true
126
- retry
127
- end
128
- rescue LoadError => error
129
- unless options[:fail_gracefully]
130
- UI.error ERROR_NO_GUARD_OR_CLASS % [name.downcase, _constant_name]
131
- UI.error error.backtrace.join("\n")
132
- end
133
- end
134
- end
135
-
136
- # Adds a plugin's template to the Guardfile.
137
- #
138
- def add_to_guardfile
139
- if ::Guard.evaluator.guardfile_include?(name)
140
- ::Guard::UI.info "Guardfile already includes #{ name } guard"
141
- else
142
- content = File.read("Guardfile")
143
- File.open("Guardfile", "wb") do |f|
144
- f.puts(content)
145
- f.puts("")
146
- f.puts(plugin_class.template(plugin_location))
147
- end
148
-
149
- UI.info INFO_ADDED_GUARD_TO_GUARDFILE % name
150
- end
151
- end
152
-
153
- private
154
-
155
- # Returns the constant for the current plugin.
156
- #
157
- # @example Returns the constant for a plugin
158
- # > Guard::PluginUtil.new('rspec').send(:_plugin_constant)
159
- # => Guard::RSpec
160
- #
161
- def _plugin_constant
162
- @_plugin_constant ||= ::Guard.constants.detect do |c|
163
- c.to_s.downcase == _constant_name.downcase
164
- end
165
- end
166
-
167
- # Guesses the most probable name for the current plugin based on its name.
168
- #
169
- # @example Returns the most probable name for a plugin
170
- # > Guard::PluginUtil.new('rspec').send(:_constant_name)
171
- # => "Rspec"
172
- #
173
- def _constant_name
174
- @_constant_name ||= name.gsub(/\/(.?)/) { "::#{ $1.upcase }" }.
175
- gsub(/(?:^|[_-])(.)/) { $1.upcase }
176
- end
177
- end
178
- end