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,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