guard 2.10.2 → 2.10.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3106af4e3722da1f4bd41e051e5baf1ff8ace4f7
4
- data.tar.gz: 0ef587f058e7f02bc5b4195a0b3b3b4d25847ddd
3
+ metadata.gz: 12901ae839ae58fdc3f18c932ffc1aef5fbd5f93
4
+ data.tar.gz: 05665929d7b77277aa5cd37156e6984b11651379
5
5
  SHA512:
6
- metadata.gz: b5f3825c29f9c01f14b50051055e105a3695288da0ce2ba2d42fdd4e4af92881afb455515da551a1faaf192b28ba8eb2e599f0640002ff9c1d2d8db0796c734a
7
- data.tar.gz: c107a499ff6e9814b536a9c1f723c5a7badc97e33f74ae8409f5b72d082fff63c09d3eac630cd9b6b12c9591ed1210b907ea05680f2b615d62bcde31b2eb5784
6
+ metadata.gz: 8d850a23954953c2a6b2ba15813ee408d8fa29d8a85dec0c15b5fb68ab7e51b7bc2e1cb87951975991e5ac24305e58b99ac41088f7e2c96b1f662119e3ad924f
7
+ data.tar.gz: 067ca85ff9546dfedd73972e87acdf97c6aa48cdbfa3ea6475df7280bd8f52bab9b587bd0117511b12410f6bb79c781c8c46e88c6e3fc0698f569fefddf75a99
@@ -3,38 +3,27 @@ require "listen"
3
3
 
4
4
  require "guard/config"
5
5
  require "guard/deprecated/guard" unless Guard::Config.new.strict?
6
+ require "guard/internals/helpers"
6
7
 
7
8
  require "guard/internals/debugging"
8
9
  require "guard/internals/traps"
9
- require "guard/internals/helpers"
10
-
11
10
  require "guard/internals/queue"
12
- require "guard/internals/state"
13
11
 
14
- require "guard/options"
15
- require "guard/commander"
16
- require "guard/dsl"
17
- require "guard/group"
12
+ # TODO: remove this class altogether
18
13
  require "guard/interactor"
19
- require "guard/notifier"
20
- require "guard/plugin_util"
21
- require "guard/runner"
22
- require "guard/sheller"
23
- require "guard/ui"
24
- require "guard/watcher"
25
- require "guard/guardfile/evaluator"
26
14
 
27
15
  # Guard is the main module for all Guard related modules and classes.
28
16
  # Also Guard plugins should use this namespace.
29
- #
30
17
  module Guard
31
18
  Deprecated::Guard.add_deprecated(self) unless Config.new.strict?
32
19
 
33
20
  class << self
21
+ attr_reader :state
22
+ attr_reader :queue
34
23
  attr_reader :listener
24
+ attr_reader :interactor
35
25
 
36
26
  # @private api
37
- attr_reader :queue
38
27
 
39
28
  include Internals::Helpers
40
29
 
@@ -85,10 +74,6 @@ module Guard
85
74
  @state = Internals::State.new(cmdline_options)
86
75
  end
87
76
 
88
- attr_reader :state
89
-
90
- attr_reader :interactor
91
-
92
77
  # Asynchronously trigger changes
93
78
  #
94
79
  # Currently supported args:
@@ -133,21 +118,15 @@ module Guard
133
118
  removed: _relative_pathnames(removed)
134
119
  }
135
120
 
121
+ _guardfile_deprecated_check(relative_paths[:modified])
122
+
136
123
  async_queue_add(relative_paths) if _relevant_changes?(relative_paths)
137
124
  end
138
125
  end
139
126
 
140
127
  # TODO: obsoleted? (move to Dsl?)
141
128
  def _pluginless_guardfile?
142
- # no Reevaluator means there was no Guardfile configured that could be
143
- # reevaluated, so we don't have a pluginless guardfile, because we don't
144
- # have a Guardfile to begin with...
145
- #
146
- # But, if we have a Guardfile, we'll at least have the built-in
147
- # Reevaluator, so the following will work:
148
-
149
- plugins = state.session.plugins.all
150
- plugins.empty? || plugins.map(&:name) == ["reevaluator"]
129
+ state.session.plugins.all.empty?
151
130
  end
152
131
 
153
132
  def _evaluate(options)
@@ -170,5 +149,26 @@ module Guard
170
149
  rescue Guardfile::Evaluator::NoPluginsError => e
171
150
  UI.error(e.message)
172
151
  end
152
+
153
+ # TODO: remove at some point
154
+ # TODO: not tested because collides with ongoing refactoring
155
+ def _guardfile_deprecated_check(modified)
156
+ modified.map!(&:to_s)
157
+ guardfiles = modified.select { |path| /^(?:.+\/)?Guardfile$/.match(path) }
158
+ return if guardfiles.empty?
159
+
160
+ if guardfiles.any? { |path| /^Guardfile$/.match(path) }
161
+ UI.warning <<EOS
162
+ Guardfile changed - Guard will exit so you can restart it manually.
163
+
164
+ More info here: https://github.com/guard/guard/wiki/Guard-2.10.3-exits-when-Guardfile-is-changed
165
+ EOS
166
+ exit 2 # nonzero to break any while loop
167
+ else
168
+ msg = "Config changed: %s - Guard will exit so it can be restarted."
169
+ UI.info format(msg, guardfiles.inspect)
170
+ exit 0 # 0 so any shell while loop can continue
171
+ end
172
+ end
173
173
  end
174
174
  end
@@ -1,9 +1,10 @@
1
1
  require "thor"
2
2
 
3
- require "guard"
4
3
  require "guard/version"
5
- require "guard/guardfile/generator"
4
+
6
5
  require "guard/dsl_describer"
6
+ require "guard/cli/environments/valid"
7
+ require "guard/cli/environments/evaluate_only"
7
8
 
8
9
  module Guard
9
10
  # Facade for the Guard command line interface managed by
@@ -104,8 +105,7 @@ module Guard
104
105
  # @see Guard.start
105
106
  #
106
107
  def start
107
- _verify_bundler_presence unless options[:no_bundler_warning]
108
- _start(options)
108
+ exit(Cli::Environments::Valid.new(options).start_guard)
109
109
  end
110
110
 
111
111
  desc "list", "Lists Guard plugins that can be used with init"
@@ -116,7 +116,7 @@ module Guard
116
116
  # @see Guard::DslDescriber.list
117
117
  #
118
118
  def list
119
- _require_guardfile(options) # just to show which plugins are actually used
119
+ Cli::Environments::EvaluateOnly.new(options).evaluate
120
120
  DslDescriber.new.list
121
121
  end
122
122
 
@@ -127,7 +127,8 @@ module Guard
127
127
  # @see Guard::DslDescriber.notifiers
128
128
  #
129
129
  def notifiers
130
- _require_guardfile(options)
130
+ Cli::Environments::EvaluateOnly.new(options).evaluate
131
+ # TODO: pass the data directly to the notifiers?
131
132
  DslDescriber.new.notifiers
132
133
  end
133
134
 
@@ -164,32 +165,9 @@ module Guard
164
165
  # initialize
165
166
  #
166
167
  def init(*plugin_names)
167
- _verify_bundler_presence unless options[:no_bundler_warning]
168
- bare = options[:bare]
169
-
170
- generator = Guardfile::Generator.new
171
- Guard.init(options)
172
- session = Guard.state.session
173
-
174
- begin
175
- Guardfile::Evaluator.new(session.evaluator_options).evaluate
176
- rescue Guardfile::Evaluator::NoGuardfileError
177
- generator.create_guardfile
178
- end
179
-
180
- return if bare
181
-
182
- # Evaluate because it might have existed and creating was skipped
183
- # FIXME: still, I don't know why this is needed
184
- Guardfile::Evaluator.new(session.evaluator_options).evaluate
185
-
186
- if plugin_names.empty?
187
- generator.initialize_all_templates
188
- else
189
- plugin_names.each do |plugin_name|
190
- generator.initialize_template(plugin_name)
191
- end
192
- end
168
+ env = Cli::Environments::Valid.new(options)
169
+ exitcode = env.initialize_guardfile(plugin_names)
170
+ exit(exitcode)
193
171
  end
194
172
 
195
173
  desc "show", "Show all defined Guard plugins and their options"
@@ -201,53 +179,8 @@ module Guard
201
179
  # @see Guard::DslDescriber.show
202
180
  #
203
181
  def show
204
- _require_guardfile(options)
205
- # TODO: use Metadata class
182
+ Cli::Environments::EvaluateOnly.new(options).evaluate
206
183
  DslDescriber.new.show
207
184
  end
208
-
209
- private
210
-
211
- # Verifies if Guard is run with `bundle exec` and
212
- # shows a hint to do so if not.
213
- #
214
- # TODO: move this elsewhere!!! (because of complex specs)
215
- def _verify_bundler_presence
216
- return unless File.exist?("Gemfile")
217
- return if ENV["BUNDLE_GEMFILE"] || ENV["RUBYGEMS_GEMDEPS"]
218
-
219
- UI.info <<EOF
220
-
221
- Guard here! It looks like your project has a Gemfile, yet you are running
222
- `guard` outside of Bundler. If this is your intent, feel free to ignore this
223
- message. Otherwise, consider using `bundle exec guard` to ensure your
224
- dependencies are loaded correctly.
225
- (You can run `guard` with --no-bundler-warning to get rid of this message.)
226
- EOF
227
- end
228
-
229
- def _require_guardfile(options)
230
- Guard.init(options) # to setup metadata
231
- session = Guard.state.session
232
- Guardfile::Evaluator.new(session.evaluator_options).evaluate
233
- rescue Dsl::Error,
234
- Guardfile::Evaluator::NoPluginsError,
235
- Guardfile::Evaluator::NoGuardfileError,
236
- Guardfile::Evaluator::NoCustomGuardfile => e
237
- # catch to throw message instead of call stack
238
- UI.error(e.message)
239
- abort
240
- end
241
-
242
- def _start(options)
243
- Guard.start(options)
244
- rescue Dsl::Error,
245
- Guardfile::Evaluator::NoPluginsError,
246
- Guardfile::Evaluator::NoGuardfileError,
247
- Guardfile::Evaluator::NoCustomGuardfile => e
248
- # catch to throw message instead of call stack
249
- UI.error(e.message)
250
- abort
251
- end
252
185
  end
253
186
  end
@@ -0,0 +1,22 @@
1
+ require "guard/ui"
2
+
3
+ module Guard
4
+ module Cli
5
+ module Environments
6
+ class Bundler
7
+ def verify
8
+ return unless File.exist?("Gemfile")
9
+ return if ENV["BUNDLE_GEMFILE"] || ENV["RUBYGEMS_GEMDEPS"]
10
+ UI.info <<EOF
11
+
12
+ Guard here! It looks like your project has a Gemfile, yet you are running
13
+ `guard` outside of Bundler. If this is your intent, feel free to ignore this
14
+ message. Otherwise, consider using `bundle exec guard` to ensure your
15
+ dependencies are loaded correctly.
16
+ (You can run `guard` with --no-bundler-warning to get rid of this message.)
17
+ EOF
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,35 @@
1
+ require "guard"
2
+
3
+ module Guard
4
+ module Cli
5
+ module Environments
6
+ class EvaluateOnly
7
+ def initialize(options)
8
+ @options = options
9
+ end
10
+
11
+ def evaluate
12
+ # TODO: check bundler setup first?
13
+ #
14
+ # TODO: it should be easier to pass options created with init
15
+ # directly to evaluator
16
+ #
17
+ # TODO: guardfile/DSL should interact only with a given object, and
18
+ # not global Guard object (setting global state only needed before
19
+ # start() is called)
20
+ #
21
+ Guard.init(@options)
22
+ session = Guard.state.session
23
+ Guardfile::Evaluator.new(session.evaluator_options).evaluate
24
+ rescue \
25
+ Dsl::Error,
26
+ Guardfile::Evaluator::NoPluginsError,
27
+ Guardfile::Evaluator::NoGuardfileError,
28
+ Guardfile::Evaluator::NoCustomGuardfile => e
29
+ UI.error(e.message)
30
+ abort
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,59 @@
1
+ require "guard/cli/environments/bundler"
2
+ require "guard/commander"
3
+ require "guard/guardfile/generator"
4
+
5
+ module Guard
6
+ module Cli
7
+ module Environments
8
+ class Valid
9
+ def initialize(options)
10
+ @options = options
11
+ end
12
+
13
+ def start_guard
14
+ # TODO: just to make sure tests are ok
15
+ Bundler.new.verify unless @options[:no_bundler_warning]
16
+ Guard.start(@options)
17
+ rescue Dsl::Error,
18
+ Guardfile::Evaluator::NoPluginsError,
19
+ Guardfile::Evaluator::NoGuardfileError,
20
+ Guardfile::Evaluator::NoCustomGuardfile => e
21
+ # catch to throw message instead of call stack
22
+ UI.error(e.message)
23
+ abort
24
+ end
25
+
26
+ def initialize_guardfile(plugin_names = [])
27
+ bare = @options[:bare]
28
+
29
+ Guard.init(@options)
30
+ session = Guard.state.session
31
+
32
+ generator = Guardfile::Generator.new
33
+ begin
34
+ Guardfile::Evaluator.new(session.evaluator_options).evaluate
35
+ rescue Guardfile::Evaluator::NoGuardfileError
36
+ generator.create_guardfile
37
+ end
38
+
39
+ return 0 if bare # 0 - exit code
40
+
41
+ # Evaluate because it might have existed and creating was skipped
42
+ # FIXME: still, I don't know why this is needed
43
+ Guardfile::Evaluator.new(session.evaluator_options).evaluate
44
+
45
+ if plugin_names.empty?
46
+ generator.initialize_all_templates
47
+ else
48
+ plugin_names.each do |plugin_name|
49
+ generator.initialize_template(plugin_name)
50
+ end
51
+ end
52
+ # TODO: capture exceptions to show msg and return exit code on
53
+ # failures
54
+ 0 # exit code
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -3,9 +3,9 @@ require "listen"
3
3
  require "guard/notifier"
4
4
  require "guard/interactor"
5
5
  require "guard/runner"
6
- require "guard/reevaluator"
7
6
  require "guard/dsl_describer"
8
- require "guard"
7
+
8
+ require "guard/internals/state"
9
9
 
10
10
  module Guard
11
11
  # Commands supported by guard
@@ -37,14 +37,18 @@ module Guard
37
37
  watched = Guard.state.session.watchdirs.join("', '")
38
38
  UI.info "Guard is now watching at '#{ watched }'"
39
39
 
40
+ exitcode = 0
40
41
  begin
41
42
  while interactor.foreground != :exit
42
43
  Guard.queue.process while Guard.queue.pending?
43
44
  end
44
45
  rescue Interrupt
46
+ rescue SystemExit => e
47
+ exitcode = e.status
45
48
  end
46
49
 
47
50
  stop
51
+ exitcode
48
52
  end
49
53
 
50
54
  def stop
@@ -63,15 +67,9 @@ module Guard
63
67
  # @param [Hash] scopes hash with a Guard plugin or a group scope
64
68
  #
65
69
  def reload(scopes = {})
66
- # TODO: guard reevaluator should probably handle all this
67
70
  UI.clear(force: true)
68
71
  UI.action_with_scopes("Reload", scopes)
69
-
70
- if scopes.empty?
71
- Reevaluator.new.reevaluate
72
- else
73
- Runner.new.run(:reload, scopes)
74
- end
72
+ Runner.new.run(:reload, scopes)
75
73
  end
76
74
 
77
75
  # Trigger `run_all` on all Guard plugins currently enabled.
@@ -1,7 +1,6 @@
1
1
  # required for async_queue_add
2
2
  require "pry"
3
3
 
4
- require "guard/interactor"
5
4
  require "guard"
6
5
 
7
6
  module Guard
@@ -22,7 +21,7 @@ module Guard
22
21
  BANNER
23
22
 
24
23
  def process(*entries)
25
- scopes, unknown = Interactor.convert_scope(entries)
24
+ scopes, unknown = ::Guard.state.session.convert_scope(entries)
26
25
 
27
26
  unless unknown.empty?
28
27
  output.puts "Unknown scopes: #{ unknown.join(", ") }"
@@ -1,6 +1,5 @@
1
1
  require "pry"
2
2
 
3
- require "guard/interactor"
4
3
  require "guard"
5
4
 
6
5
  module Guard
@@ -21,7 +20,7 @@ module Guard
21
20
  BANNER
22
21
 
23
22
  def process(*entries)
24
- scopes, unknown = Interactor.convert_scope(entries)
23
+ scopes, unknown = ::Guard.state.session.convert_scope(entries)
25
24
 
26
25
  unless unknown.empty?
27
26
  output.puts "Unknown scopes: #{ unknown.join(", ") }"