guard 1.8.3 → 2.0.0.pre
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 +4 -4
- data/CHANGELOG.md +68 -10
- data/README.md +54 -33
- data/lib/guard.rb +133 -483
- data/lib/guard/cli.rb +78 -82
- data/lib/guard/commander.rb +121 -0
- data/lib/guard/commands/all.rb +1 -1
- data/lib/guard/commands/reload.rb +1 -1
- data/lib/guard/deprecated_methods.rb +59 -0
- data/lib/guard/deprecator.rb +107 -0
- data/lib/guard/dsl.rb +143 -329
- data/lib/guard/dsl_describer.rb +101 -57
- data/lib/guard/group.rb +27 -8
- data/lib/guard/guard.rb +25 -150
- data/lib/guard/guardfile.rb +35 -85
- data/lib/guard/guardfile/evaluator.rb +245 -0
- data/lib/guard/guardfile/generator.rb +89 -0
- data/lib/guard/interactor.rb +147 -163
- data/lib/guard/notifier.rb +83 -137
- data/lib/guard/notifiers/base.rb +220 -0
- data/lib/guard/notifiers/emacs.rb +39 -37
- data/lib/guard/notifiers/file_notifier.rb +29 -25
- data/lib/guard/notifiers/gntp.rb +68 -75
- data/lib/guard/notifiers/growl.rb +49 -52
- data/lib/guard/notifiers/growl_notify.rb +51 -56
- data/lib/guard/notifiers/libnotify.rb +41 -48
- data/lib/guard/notifiers/notifysend.rb +58 -38
- data/lib/guard/notifiers/rb_notifu.rb +54 -54
- data/lib/guard/notifiers/terminal_notifier.rb +48 -36
- data/lib/guard/notifiers/terminal_title.rb +23 -19
- data/lib/guard/notifiers/tmux.rb +110 -93
- data/lib/guard/options.rb +21 -0
- data/lib/guard/plugin.rb +66 -0
- data/lib/guard/plugin/base.rb +178 -0
- data/lib/guard/plugin/hooker.rb +123 -0
- data/lib/guard/plugin_util.rb +158 -0
- data/lib/guard/rake_task.rb +47 -0
- data/lib/guard/runner.rb +62 -82
- data/lib/guard/setuper.rb +248 -0
- data/lib/guard/ui.rb +24 -80
- data/lib/guard/ui/colors.rb +60 -0
- data/lib/guard/version.rb +1 -2
- data/lib/guard/watcher.rb +30 -30
- data/man/guard.1 +4 -4
- data/man/guard.1.html +6 -4
- metadata +25 -11
- data/lib/guard/hook.rb +0 -120
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ec53a40ba0d6bb529aba462d295f5959631fc2de
|
4
|
+
data.tar.gz: 730479188a61cfdafea27ee0ed417ef72ef09fc2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b98bfa844663944ed92554b69af8edb2f8cc1f63de2d7d0ef374c828414ceb5ebbd7fb5f07b7ecb904f52c86522ac721c973062e331c5677dfa47da8572faae3
|
7
|
+
data.tar.gz: f9d2785f7edf80c6e81fac7d05f87dfb732442e9bf38b27ba3e8a2decbb2f5f3817f0e1c5d9411c5508bd61f8710ed7bebec31b0b465ef9df8b24c2daef1a4df
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,55 @@
|
|
1
1
|
## Master
|
2
2
|
|
3
|
-
No changes
|
3
|
+
No changes.
|
4
|
+
|
5
|
+
## 2.0.0.pre - 12 September, 2013
|
6
|
+
|
7
|
+
### Removals & deprecations
|
8
|
+
|
9
|
+
- Remove `Guard::Guardfile.duplicate_definitions?`. ([@rymai][])
|
10
|
+
- Remove the deprecated `watch_all_modifications` start option. ([@rymai][])
|
11
|
+
- Remove the deprecated `no_vendor` start option. ([@rymai][])
|
12
|
+
- Remove the deprecated `reset_color` UI method. ([@rymai][])
|
13
|
+
- Remove the deprecated `match_file?` Watcher method. ([@rymai][])
|
14
|
+
- Remove the deprecated `ignore_paths` DSL method. ([@rymai][])
|
15
|
+
- Remove the deprecation warning for the `interactor` DSL method. ([@rymai][])
|
16
|
+
- Remove the deprecation warning for when a plugin defines the `run_on_change` method. ([@rymai][])
|
17
|
+
- Remove the deprecation warning for when a plugin defines the `run_on_deletion` method. ([@rymai][])
|
18
|
+
- Deprecate `Guard.guards(filter)` in favor of `Guard.plugins(filter)`. ([@rymai][])
|
19
|
+
- Deprecate `Guard.add_guard(name, options = {})` in favor of `Guard.add_plugin(name, options = {})`. ([@rymai][])
|
20
|
+
- Deprecate `Guard.get_guard_class(name, fail_gracefully)` in favor of `Guard::PluginUtil.new(name).plugin_class(fail_gracefully: fail_gracefully)`. ([@rymai][])
|
21
|
+
- Deprecate `Guard.locate_guard(name)` in favor of `Guard::PluginUtil.new(name).plugin_location`. ([@rymai][])
|
22
|
+
- Deprecate `Guard.guard_gem_names` in favor of `Guard::PluginUtil.plugin_names`. ([@rymai][])
|
23
|
+
- Deprecate `Guard::Guard` in favor of `Guard::Plugin`. ([@rymai][])
|
24
|
+
- Deprecate `Guard::Dsl.evaluate_guardfile(options)` in favor of `Guard::Guardfile::Evaluator.new(options).evaluate_guardfile`. ([@rymai][])
|
25
|
+
- Deprecate `Guard::Guardfile.create_guardfile(options)` in favor of `Guard::Guardfile::Generator.new(options).create_guardfile`. ([@rymai][])
|
26
|
+
- Deprecate `Guard::Guardfile.initialize_template(plugin_name)` in favor of `Guard::Guardfile::Generator.new.initialize_template(plugin_name)`. ([@rymai][])
|
27
|
+
- Deprecate `Guard::Guardfile.initialize_all_templates` in favor of `Guard::Guardfile::Generator.new.initialize_all_templates`. ([@rymai][])
|
28
|
+
|
29
|
+
### New features & improvements
|
30
|
+
|
31
|
+
- [#469][] List available notifiers. ([@netzpirat][])
|
32
|
+
- Refactor `Guard::Notifier` and the whole notifiers system. ([@rymai][])
|
33
|
+
- Allow to pass symbols or actual Guard plugins / groups for the `scope` parameter to `Guard::Runner#run`. ([@rymai][])
|
34
|
+
- Ensure Guard API calls are not order dependent. ([@rymai][])
|
35
|
+
- Ensure Guard has sensible defaults. ([@rymai][])
|
36
|
+
- New `#title` method for `Guard::Group` & `Guard::Plugin`. ([@rymai][])
|
37
|
+
- New `Guard::Plugin::Base` module common to `Guard::Guard` (deprecated) & `Guard::Plugin`. ([@rymai][])
|
38
|
+
- New `Guard::PluginUtil` that contains useful methods to find and instantiate Guard plugins. ([@rymai][])
|
39
|
+
- New `Guard.plugin` method to find the first plugin matching a filter. ([@rymai][])
|
40
|
+
- New `Guard.group` method to find the first group matching a filter. ([@rymai][])
|
41
|
+
- Don't swallow exceptions when evaluating the Guardfile. ([@rymai][])
|
42
|
+
- Rename `Guard::Hook` to `Guard::Plugin::Hooker`. ([@rymai][])
|
43
|
+
- Move setup stuff into a new `Guard::Setuper` module. ([@rymai][])
|
44
|
+
- Move deprecation stuff inside a new `Guard::Deprecator` class. ([@rymai][])
|
45
|
+
|
46
|
+
### Bug fixes
|
47
|
+
|
48
|
+
- [#472][] Clear terminal title notification on exit. Fixes [#472][]. ([@netzpirat][])
|
49
|
+
- [#457][] Raise an exception when a group is called "all". Fixes [#457][]. (reported by [@rweng][], fixed by [@rymai][])
|
50
|
+
- [#471][] Only init once per plugin when running `guard init` (reported by [@simon-ohara][], fixed by [@thibaudgg][])
|
51
|
+
- [#456][] Fix notifu notifier. ([@netzpirat][])
|
52
|
+
- [#435][] Fix pressing `C-c` when interactor thread is not started. ([@netzpirat][])
|
4
53
|
|
5
54
|
## 1.8.2 - 30 July, 2013
|
6
55
|
|
@@ -25,6 +74,7 @@ No changes yet.
|
|
25
74
|
|
26
75
|
### Improvements
|
27
76
|
|
77
|
+
- Listen 1.0.0 support. ([@thibaudgg][])
|
28
78
|
- [#416][] Support .guardrc file on the folder from which Guard is executed as well. ([@Nerian][])
|
29
79
|
- Display an info message when a plugin throws `:task_has_failed`. ([@rymai][])
|
30
80
|
- Ensure compatibility with new Listen's API. ([@rymai][])
|
@@ -79,10 +129,10 @@ No changes yet.
|
|
79
129
|
|
80
130
|
### New features
|
81
131
|
|
82
|
-
- Allow the Guard scope to be defined from the `Guardfile` with the `scope`
|
132
|
+
- Allow the Guard scope to be defined from the `Guardfile` with the `scope` Dsl method. ([@netzpirat][])
|
83
133
|
- [#378][] Scope plugins and groups from CLI and interactor. ([@netzpirat][])
|
84
134
|
- [#369][] Allow Guard plugins to specify their template location. ([@schmurfy][])
|
85
|
-
- [#364][] Add `ignore!` and `filter!`
|
135
|
+
- [#364][] Add `ignore!` and `filter!` Dsl methods. ([@tarsolya][])
|
86
136
|
- [#362][] Add interactor options `:history_file` and `:guard_rc`. ([@netzpirat][])
|
87
137
|
|
88
138
|
### Improvements
|
@@ -310,7 +360,7 @@ The Listen integration has been supervised by [@thibaudgg][] and executed by [@M
|
|
310
360
|
|
311
361
|
### Improvements
|
312
362
|
|
313
|
-
- Add `interactor` to
|
363
|
+
- Add `interactor` to Dsl to allow switching Guard interaction implementation. ([@netzpirat][])
|
314
364
|
- Add quit action to the interactor. ([@Maher4Ever][])
|
315
365
|
|
316
366
|
## 0.9.1 - December 19, 2011
|
@@ -410,7 +460,7 @@ The Listen integration has been supervised by [@thibaudgg][] and executed by [@M
|
|
410
460
|
### New feature
|
411
461
|
|
412
462
|
- [#136][] New CLI `:watch_all_modifications`/`-A` option to watch for deleted and moved files too. ([@limeyd][] and [@netzpirat][])
|
413
|
-
- [#97][] Guard dependencies. Task execution can now be halted if a Guard throws `:task_has_failed` and `Guard::Dsl#group` options include
|
463
|
+
- [#97][] Guard dependencies. Task execution can now be halted if a Guard throws `:task_has_failed` and `Guard::Dsl#group` options include `halt_on_fail: true`. ([@rymai][])
|
414
464
|
- [#121][] `Guard.guards` and `Guard.groups` are now smart accessors. Filters can be passed to find a specific Guard/group or several Guard plugins/groups that match (see YARDoc). ([@rymai][] and [@ches][])
|
415
465
|
- New `Guard::Group` class to store groups defined in Guardfile (with `Guard::Dsl#group`). ([@rymai][])
|
416
466
|
|
@@ -441,7 +491,7 @@ The Listen integration has been supervised by [@thibaudgg][] and executed by [@M
|
|
441
491
|
|
442
492
|
### New features
|
443
493
|
|
444
|
-
- [#130][] Add `ignore_paths` method to
|
494
|
+
- [#130][] Add `ignore_paths` method to Dsl. ([@ianwhite][])
|
445
495
|
- [#128][] Users can add additional settings to `~/.guard.rb` that augment the existing Guardfile. ([@tpope][])
|
446
496
|
|
447
497
|
## 0.6.2 - August 17, 2011
|
@@ -481,7 +531,7 @@ The Listen integration has been supervised by [@thibaudgg][] and executed by [@M
|
|
481
531
|
### Improvements
|
482
532
|
|
483
533
|
- [#99][] [OS X] Switch from growl gem to growl_notify gem. ([@johnbintz][])
|
484
|
-
- [#115][] [Linux] Add
|
534
|
+
- [#115][] [Linux] Add `transient: true` to default libnotify options. ([@zonque][])
|
485
535
|
- [#95][] Output system commands and options to be executed when in debug mode. ([@uk-ar][] and [@netzpirat][])
|
486
536
|
- `Guard::Dsl.revaluate_guardfile` has been renamed to `Guard::Dsl.reevaluate_guardfile`. ([@rymai][])
|
487
537
|
- New CLI options: ([@nestegg][])
|
@@ -537,7 +587,7 @@ The Listen integration has been supervised by [@thibaudgg][] and executed by [@M
|
|
537
587
|
|
538
588
|
### New features
|
539
589
|
|
540
|
-
- [#73][] Allow
|
590
|
+
- [#73][] Allow Dsl's `group` method to accept a Symbol as group name. ([@johnbintz][])
|
541
591
|
- [#51][] Allow options (like `:priority`) to be passed through to the Notifier. ([@indirect][] and [@netzpirat][])
|
542
592
|
|
543
593
|
### Improvement
|
@@ -612,7 +662,7 @@ The Listen integration has been supervised by [@thibaudgg][] and executed by [@M
|
|
612
662
|
### New features
|
613
663
|
|
614
664
|
- The whole directory is now watched during `run_on_change` to detect new files modifications. ([@thibaudgg][])
|
615
|
-
- [#26][] New
|
665
|
+
- [#26][] New Dsl method: `group` allows you to group several guards. New CLI option: `--group group_name` to specify certain groups of guards to start. ([@netzpirat][])
|
616
666
|
- `watch` patterns are now more strict: strings are matched with `String#==`, `Regexp` are matched with `Regexp#match`. ([@rymai][])
|
617
667
|
- A deprecation warning is displayed if your `Guardfile` contains `String` that look like `Regexp` (bad!). ([@rymai][])
|
618
668
|
- It's now possible to return an `Enumerable` in the `watch` optional blocks in the `Guardfile`. ([@rymai][])
|
@@ -620,7 +670,7 @@ The Listen integration has been supervised by [@thibaudgg][] and executed by [@M
|
|
620
670
|
### New specs
|
621
671
|
|
622
672
|
- `Guard::Watcher`. ([@rymai][])
|
623
|
-
- [#13][] `Guard::
|
673
|
+
- [#13][] `Guard::DSL`. ([@oliamb][])
|
624
674
|
|
625
675
|
## 0.2.2 - October 25, 2010
|
626
676
|
|
@@ -786,11 +836,17 @@ The Listen integration has been supervised by [@thibaudgg][] and executed by [@M
|
|
786
836
|
[#413]: https://github.com/guard/guard/issues/413
|
787
837
|
[#414]: https://github.com/guard/guard/issues/414
|
788
838
|
[#416]: https://github.com/guard/guard/issues/416
|
839
|
+
[#435]: https://github.com/guard/guard/issues/435
|
789
840
|
[#443]: https://github.com/guard/guard/issues/443
|
790
841
|
[#450]: https://github.com/guard/guard/issues/450
|
791
842
|
[#453]: https://github.com/guard/guard/issues/453
|
843
|
+
[#456]: https://github.com/guard/guard/issues/456
|
844
|
+
[#457]: https://github.com/guard/guard/issues/457
|
792
845
|
[#460]: https://github.com/guard/guard/issues/460
|
793
846
|
[#463]: https://github.com/guard/guard/issues/463
|
847
|
+
[#469]: https://github.com/guard/guard/issues/469
|
848
|
+
[#471]: https://github.com/guard/guard/issues/471
|
849
|
+
[#472]: https://github.com/guard/guard/issues/472
|
794
850
|
[@Gazer]: https://github.com/Gazer
|
795
851
|
[@Maher4Ever]: https://github.com/Maher4Ever
|
796
852
|
[@Nerian]: https://github.com/Nerian
|
@@ -861,10 +917,12 @@ The Listen integration has been supervised by [@thibaudgg][] and executed by [@M
|
|
861
917
|
[@royvandewater]: https://github.com/royvandewater
|
862
918
|
[@rudicode]: https://github.com/rudicode
|
863
919
|
[@rupert654]: https://github.com/rupert654
|
920
|
+
[@rweng]: https://github.com/rweng
|
864
921
|
[@rymai]: https://github.com/rymai
|
865
922
|
[@schmurfy]: https://github.com/schmurfy
|
866
923
|
[@scottdavis]: https://github.com/scottdavis
|
867
924
|
[@semperos]: https://github.com/semperos
|
925
|
+
[@simon-ohara]: https://github.com/simon-ohara
|
868
926
|
[@spadin]: https://github.com/spadin
|
869
927
|
[@steakknife]: https://github.com/steakknife
|
870
928
|
[@stereobooster]: https://github.com/stereobooster
|
data/README.md
CHANGED
@@ -16,21 +16,21 @@ the following places:
|
|
16
16
|
Information on advanced topics like creating your own Guard plugin, programatic use of Guard, hooks and callbacks and
|
17
17
|
more can be found in the [Guard wiki](https://github.com/guard/guard/wiki).
|
18
18
|
|
19
|
-
Before you file an issue, make sure you have read the _[known issues](#
|
19
|
+
Before you file an issue, make sure you have read the _[known issues](#issues)_ and _[file an issue](#file-an-issue)_ sections that contains some important information.
|
20
20
|
|
21
21
|
#### Features
|
22
22
|
|
23
23
|
* File system changes handled by our awesome [Listen](https://github.com/guard/listen) gem.
|
24
24
|
* Support for visual system notifications.
|
25
|
-
* Huge eco-system with [more than
|
26
|
-
* Tested against Ruby 1.
|
25
|
+
* Huge eco-system with [more than 220](https://rubygems.org/search?query=guard-) Guard plugins.
|
26
|
+
* Tested against Ruby 1.9.2, 1.9.3, 2.0.0, JRuby (1.9 mode) & Rubinius (1.9 mode).
|
27
27
|
|
28
28
|
#### Screencast
|
29
29
|
|
30
|
-
Two nice
|
30
|
+
Two nice screencasts are available to help you get started:
|
31
31
|
|
32
|
-
* [Guard
|
33
|
-
* [Guard](http://
|
32
|
+
* [Guard](http://railscasts.com/episodes/264-guard) on RailsCast.
|
33
|
+
* [Guard is Your Best Friend](http://net.tutsplus.com/tutorials/tools-and-tips/guard-is-your-best-friend) on Net Tuts+.
|
34
34
|
|
35
35
|
Installation
|
36
36
|
------------
|
@@ -57,6 +57,7 @@ Generate an empty `Guardfile` with:
|
|
57
57
|
$ guard init
|
58
58
|
```
|
59
59
|
|
60
|
+
|
60
61
|
Run Guard through Bundler with:
|
61
62
|
|
62
63
|
```bash
|
@@ -99,7 +100,7 @@ You can always get help on the available tasks with the `help` task:
|
|
99
100
|
$ guard help
|
100
101
|
```
|
101
102
|
|
102
|
-
|
103
|
+
Requesting more detailed help on a specific task is simple: just append the task name to the help task.
|
103
104
|
For example, to get help for the `start` task, simply run:
|
104
105
|
|
105
106
|
```bash
|
@@ -172,7 +173,7 @@ $ guard -c # shortcut
|
|
172
173
|
You can add the following snippet to your `~/.guardrc` to have the clear option always be enabled:
|
173
174
|
|
174
175
|
```
|
175
|
-
Guard.options
|
176
|
+
Guard.options.clear = true
|
176
177
|
```
|
177
178
|
|
178
179
|
#### `-n`/`--notify` option
|
@@ -312,7 +313,26 @@ $ guard show
|
|
312
313
|
```
|
313
314
|
|
314
315
|
This shows the internal structure of the evaluated `Guardfile` or `.Guardfile`, with the `.guard.rb` file. You can
|
315
|
-
read more about these files in the [shared configuration section](https://github.com/guard/guard
|
316
|
+
read more about these files in the [shared configuration section](https://github.com/guard/guard/wiki/Shared-configurations).
|
317
|
+
|
318
|
+
### Notifiers
|
319
|
+
|
320
|
+
You can show the notifiers, their availablity and options with the `notifier` task:
|
321
|
+
|
322
|
+
```bash
|
323
|
+
$ guard notifiers
|
324
|
+
+-------------------+-----------+------+------------------------+-------------------+
|
325
|
+
| Name | Available | Used | Option | Value |
|
326
|
+
+-------------------+-----------+------+------------------------+-------------------+
|
327
|
+
| gntp | ✔ | ✘ | sticky | false |
|
328
|
+
+-------------------+-----------+------+------------------------+-------------------+
|
329
|
+
| growl | ✘ | ✘ | sticky | false |
|
330
|
+
| | | | priority | 0 |
|
331
|
+
+-------------------+-----------+------+------------------------+-------------------+
|
332
|
+
```
|
333
|
+
|
334
|
+
This shows if a notifier is available on the current system, it it's being used and the
|
335
|
+
current options (which reflects your custom options merged into the default options).
|
316
336
|
|
317
337
|
Interactions
|
318
338
|
------------
|
@@ -385,14 +405,14 @@ The `guard` method allows you to add a Guard plugin to your toolchain and config
|
|
385
405
|
options after the name of the plugin:
|
386
406
|
|
387
407
|
```ruby
|
388
|
-
guard :coffeescript, :
|
408
|
+
guard :coffeescript, input: 'coffeescripts', output: 'javascripts'
|
389
409
|
```
|
390
410
|
|
391
411
|
You can define the same plugin more than once:
|
392
412
|
|
393
413
|
```ruby
|
394
|
-
guard :coffeescript, :
|
395
|
-
guard :coffeescript, :
|
414
|
+
guard :coffeescript, input: 'coffeescripts', output: 'javascripts'
|
415
|
+
guard :coffeescript, input: 'specs', output: 'specs'
|
396
416
|
```
|
397
417
|
|
398
418
|
### watch
|
@@ -472,7 +492,7 @@ to make this work, the group needs to have the `halt_on_fail` option enabled and
|
|
472
492
|
needs to throw `:task_has_failed` to indicate that the action was not successful.
|
473
493
|
|
474
494
|
```ruby
|
475
|
-
group :specs, :
|
495
|
+
group :specs, halt_on_fail: true do
|
476
496
|
guard :rspec do
|
477
497
|
watch(/.../)
|
478
498
|
end
|
@@ -492,20 +512,22 @@ the DSL scope configuration.
|
|
492
512
|
You can define either a single plugin or group:
|
493
513
|
|
494
514
|
```ruby
|
495
|
-
scope :
|
496
|
-
scope :
|
515
|
+
scope plugin: :rspec
|
516
|
+
scope group: :docs
|
497
517
|
```
|
498
518
|
|
499
519
|
or specify multiple plugins or groups.
|
500
520
|
|
501
521
|
```ruby
|
502
|
-
scope :
|
503
|
-
scope :
|
522
|
+
scope plugins: [:test, :jasmine]
|
523
|
+
scope groups: [:docs, :frontend]
|
504
524
|
```
|
505
525
|
|
506
526
|
If you define both the plugin and group scope, the plugin scope has precedence. If you use both the
|
507
527
|
plural and the singular option, the plural has precedence.
|
508
528
|
|
529
|
+
**Please be sure to call the `scope` method after you've declared your Guard plugins!**
|
530
|
+
|
509
531
|
### notification
|
510
532
|
|
511
533
|
If you don't specify any notification configuration in your `Guardfile`, Guard goes through the list of available
|
@@ -519,17 +541,17 @@ notification :growl
|
|
519
541
|
will select the `growl` gem for notifications. You can also set options for a notifier:
|
520
542
|
|
521
543
|
```ruby
|
522
|
-
notification :growl, :
|
544
|
+
notification :growl, sticky: true
|
523
545
|
```
|
524
546
|
|
525
547
|
Each notifier has a slightly different set of supported options:
|
526
548
|
|
527
549
|
```ruby
|
528
|
-
notification :growl, :
|
529
|
-
notification :gntp, :
|
530
|
-
notification :growl_notify, :
|
531
|
-
notification :libnotify, :
|
532
|
-
notification :notifu, :
|
550
|
+
notification :growl, sticky: true, host: '192.168.1.5', password: 'secret'
|
551
|
+
notification :gntp, sticky: true, host: '192.168.1.5', password: 'secret'
|
552
|
+
notification :growl_notify, sticky: true, priority: 0
|
553
|
+
notification :libnotify, timeout: 5, transient: true, append: false, urgency: :critical
|
554
|
+
notification :notifu, time: 5, nosound: true, xp: true
|
533
555
|
notification :emacs
|
534
556
|
```
|
535
557
|
|
@@ -548,7 +570,7 @@ notification :off
|
|
548
570
|
You can customize the Pry interactor history and RC file like:
|
549
571
|
|
550
572
|
```ruby
|
551
|
-
interactor :
|
573
|
+
interactor guard_rc: '~/.my_guard-rc', history_file: '~/.my_guard_history_file'
|
552
574
|
```
|
553
575
|
|
554
576
|
If you do not need the Pry interactions with Guard at all, you can turn it off:
|
@@ -585,7 +607,7 @@ This comes in handy when you have large amounts of non-source data in you projec
|
|
585
607
|
are ignored.
|
586
608
|
|
587
609
|
Please note that method only accept regexps. More on the
|
588
|
-
[Listen README](https://github.com/guard/listen#the-patterns-for-
|
610
|
+
[Listen README](https://github.com/guard/listen#note-on-the-patterns-for-ignoring-and-filtering-paths).
|
589
611
|
|
590
612
|
To append to the default ignored files and directories, use the `ignore` method:
|
591
613
|
|
@@ -606,7 +628,7 @@ The `filter` method allows you to focus by filtering files and directories witho
|
|
606
628
|
the `filter` method.
|
607
629
|
|
608
630
|
Please note that method only accept regexps. More on the
|
609
|
-
[Listen README](https://github.com/guard/listen#the-patterns-for-
|
631
|
+
[Listen README](https://github.com/guard/listen#note-on-the-patterns-for-ignoring-and-filtering-paths).
|
610
632
|
|
611
633
|
```ruby
|
612
634
|
filter /\.txt$/, /.*\.zip/
|
@@ -624,12 +646,12 @@ The `logger` method allows you to customize the [Lumberjack](https://github.com/
|
|
624
646
|
needs by specifying one or more options like:
|
625
647
|
|
626
648
|
```ruby
|
627
|
-
logger :
|
628
|
-
:
|
629
|
-
:
|
630
|
-
:
|
631
|
-
:
|
632
|
-
:
|
649
|
+
logger level: :warn,
|
650
|
+
template: '[:severity - :time - :progname] :message',
|
651
|
+
time_format: 'at %I:%M%p',
|
652
|
+
only: [:rspec, :jasmine, 'coffeescript'],
|
653
|
+
except: :jammit,
|
654
|
+
device: 'guard.log'
|
633
655
|
```
|
634
656
|
|
635
657
|
Log `:level` option must be either `:debug`, `:info`, `:warn` or `:error`. If Guard is started in debug mode, the log
|
@@ -713,7 +735,6 @@ Please try to follow these simple rules:
|
|
713
735
|
|
714
736
|
#### Core Team
|
715
737
|
|
716
|
-
* [Maher Sallam](https://github.com/Maher4Ever) ([@mahersalam](http://twitter.com/mahersalam))
|
717
738
|
* [Michael Kessler](https://github.com/netzpirat) ([@netzpirat](http://twitter.com/netzpirat), [mksoft.ch](https://mksoft.ch))
|
718
739
|
* [Rémy Coutable](https://github.com/rymai) ([@rymai](http://twitter.com/rymai), [rymai.me](http://rymai.me))
|
719
740
|
* [Thibaud Guillaume-Gentil](https://github.com/thibaudgg) ([@thibaudgg](http://twitter.com/thibaudgg), [thibaud.me](http://thibaud.me/))
|
data/lib/guard.rb
CHANGED
@@ -1,320 +1,112 @@
|
|
1
1
|
require 'rbconfig'
|
2
|
-
|
3
|
-
require '
|
2
|
+
|
3
|
+
require 'guard/commander'
|
4
|
+
require 'guard/deprecated_methods'
|
5
|
+
require 'guard/deprecator'
|
6
|
+
require 'guard/dsl'
|
7
|
+
require 'guard/group'
|
8
|
+
require 'guard/guardfile'
|
9
|
+
require 'guard/interactor'
|
10
|
+
require 'guard/notifier'
|
11
|
+
require 'guard/plugin_util'
|
12
|
+
require 'guard/runner'
|
13
|
+
require 'guard/setuper'
|
14
|
+
require 'guard/ui'
|
15
|
+
require 'guard/watcher'
|
4
16
|
|
5
17
|
# Guard is the main module for all Guard related modules and classes.
|
6
18
|
# Also Guard plugins should use this namespace.
|
7
19
|
#
|
8
20
|
module Guard
|
9
21
|
|
10
|
-
|
11
|
-
require 'guard/guardfile'
|
12
|
-
require 'guard/group'
|
13
|
-
require 'guard/interactor'
|
14
|
-
require 'guard/notifier'
|
15
|
-
require 'guard/runner'
|
16
|
-
require 'guard/ui'
|
17
|
-
require 'guard/watcher'
|
18
|
-
|
19
|
-
# The Guardfile template for `guard init`
|
20
|
-
GUARDFILE_TEMPLATE = File.expand_path('../guard/templates/Guardfile', __FILE__)
|
21
|
-
|
22
|
-
# The location of user defined templates
|
23
|
-
HOME_TEMPLATES = File.expand_path('~/.guard/templates')
|
24
|
-
|
25
|
-
WINDOWS = RbConfig::CONFIG['host_os'] =~ %r!(msdos|mswin|djgpp|mingw)!
|
22
|
+
WINDOWS = RbConfig::CONFIG['host_os'] =~ %r!(msdos|mswin|djgpp|mingw)!
|
26
23
|
DEV_NULL = WINDOWS ? 'NUL' : '/dev/null'
|
27
24
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
# Initialize the Guard singleton:
|
32
|
-
#
|
33
|
-
# - Initialize the internal Guard state.
|
34
|
-
# - Create the interactor when necessary for user interaction.
|
35
|
-
# - Select and initialize the file change listener.
|
36
|
-
#
|
37
|
-
# @option options [Boolean] clear if auto clear the UI should be done
|
38
|
-
# @option options [Boolean] notify if system notifications should be shown
|
39
|
-
# @option options [Boolean] debug if debug output should be shown
|
40
|
-
# @option options [Array<String>] group the list of groups to start
|
41
|
-
# @option options [Array<String>] watchdir the directories to watch
|
42
|
-
# @option options [String] guardfile the path to the Guardfile
|
43
|
-
# @deprecated @option options [Boolean] watch_all_modifications watches all file modifications if true
|
44
|
-
# @deprecated @option options [Boolean] no_vendor ignore vendored dependencies
|
45
|
-
#
|
46
|
-
def setup(options = {})
|
47
|
-
@running = true
|
48
|
-
@lock = Mutex.new
|
49
|
-
@options = options.dup
|
50
|
-
@runner = ::Guard::Runner.new
|
51
|
-
@scope = { :plugins => [], :groups => [] }
|
52
|
-
|
53
|
-
@watchdirs = [Dir.pwd]
|
54
|
-
|
55
|
-
if options[:watchdir]
|
56
|
-
# Ensure we have an array
|
57
|
-
@watchdirs = Array(options[:watchdir]).map { |dir| File.expand_path dir }
|
58
|
-
end
|
59
|
-
|
60
|
-
::Guard::UI.clear(:force => true)
|
61
|
-
setup_debug
|
62
|
-
deprecated_options_warning
|
63
|
-
|
64
|
-
setup_groups
|
65
|
-
setup_guards
|
66
|
-
setup_listener
|
67
|
-
setup_signal_traps
|
68
|
-
setup_from_guardfile
|
69
|
-
setup_scopes
|
70
|
-
|
71
|
-
runner.deprecation_warning if options[:show_deprecations]
|
72
|
-
|
73
|
-
setup_notifier
|
74
|
-
setup_interactor
|
75
|
-
|
76
|
-
self
|
77
|
-
end
|
25
|
+
extend Commander
|
26
|
+
extend DeprecatedMethods
|
27
|
+
extend Setuper
|
78
28
|
|
79
|
-
|
80
|
-
|
81
|
-
Thread.abort_on_exception = true
|
82
|
-
::Guard::UI.options[:level] = :debug
|
83
|
-
debug_command_execution
|
84
|
-
end
|
85
|
-
end
|
29
|
+
class << self
|
30
|
+
attr_accessor :evaluator, :interactor, :runner, :listener, :lock, :scope, :running
|
86
31
|
|
87
|
-
#
|
32
|
+
# Smart accessor for retrieving specific plugins at once.
|
88
33
|
#
|
34
|
+
# @see Guard.plugin
|
35
|
+
# @see Guard.group
|
89
36
|
# @see Guard.groups
|
90
37
|
#
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
#
|
96
|
-
#
|
97
|
-
#
|
98
|
-
#
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
#
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
#
|
137
|
-
#
|
138
|
-
# Currently two signals are caught:
|
139
|
-
# - `USR1` which pauses listening to changes.
|
140
|
-
# - `USR2` which resumes listening to changes.
|
141
|
-
# - 'INT' which is delegated to Pry if active, otherwise stops Guard.
|
142
|
-
#
|
143
|
-
def setup_signal_traps
|
144
|
-
unless defined?(JRUBY_VERSION)
|
145
|
-
if Signal.list.keys.include?('USR1')
|
146
|
-
Signal.trap('USR1') { ::Guard.pause unless listener.paused? }
|
147
|
-
end
|
148
|
-
|
149
|
-
if Signal.list.keys.include?('USR2')
|
150
|
-
Signal.trap('USR2') { ::Guard.pause if listener.paused? }
|
151
|
-
end
|
152
|
-
|
153
|
-
if Signal.list.keys.include?('INT')
|
154
|
-
Signal.trap('INT') do
|
155
|
-
if interactor
|
156
|
-
interactor.thread.raise(Interrupt)
|
157
|
-
else
|
158
|
-
::Guard.stop
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
|
-
def setup_from_guardfile
|
166
|
-
::Guard::Dsl.evaluate_guardfile(options)
|
167
|
-
::Guard::UI.error 'No guards found in Guardfile, please add at least one.' if @guards.empty?
|
168
|
-
end
|
169
|
-
|
170
|
-
def setup_scopes
|
171
|
-
scope[:groups] = options[:group].map { |g| ::Guard.groups(g) } if options[:group]
|
172
|
-
scope[:plugins] = options[:plugin].map { |p| ::Guard.guards(p) } if options[:plugin]
|
173
|
-
end
|
174
|
-
|
175
|
-
# Enables or disables the notifier based on user's configurations.
|
176
|
-
#
|
177
|
-
def setup_notifier
|
178
|
-
options[:notify] && ENV['GUARD_NOTIFY'] != 'false' ? ::Guard::Notifier.turn_on : ::Guard::Notifier.turn_off
|
179
|
-
end
|
180
|
-
|
181
|
-
# Initializes the interactor unless the user has specified not to.
|
182
|
-
#
|
183
|
-
def setup_interactor
|
184
|
-
unless options[:no_interactions] || !::Guard::Interactor.enabled
|
185
|
-
@interactor = ::Guard::Interactor.new
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
# Start Guard by evaluating the `Guardfile`, initializing declared Guard plugins
|
190
|
-
# and starting the available file change listener.
|
191
|
-
# Main method for Guard that is called from the CLI when Guard starts.
|
192
|
-
#
|
193
|
-
# - Setup Guard internals
|
194
|
-
# - Evaluate the `Guardfile`
|
195
|
-
# - Configure Notifiers
|
196
|
-
# - Initialize the declared Guard plugins
|
197
|
-
# - Start the available file change listener
|
198
|
-
#
|
199
|
-
# @option options [Boolean] clear if auto clear the UI should be done
|
200
|
-
# @option options [Boolean] notify if system notifications should be shown
|
201
|
-
# @option options [Boolean] debug if debug output should be shown
|
202
|
-
# @option options [Array<String>] group the list of groups to start
|
203
|
-
# @option options [String] watchdir the director to watch
|
204
|
-
# @option options [String] guardfile the path to the Guardfile
|
205
|
-
#
|
206
|
-
def start(options = {})
|
207
|
-
setup(options)
|
208
|
-
|
209
|
-
within_preserved_state do
|
210
|
-
::Guard::UI.debug 'Guard starts all plugins'
|
211
|
-
runner.run(:start)
|
212
|
-
::Guard::UI.info "Guard is now watching at '#{ @watchdirs.join "', '" }'"
|
213
|
-
listener.start
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
|
-
# Stop Guard listening to file changes
|
218
|
-
#
|
219
|
-
def stop
|
220
|
-
within_preserved_state(false) do
|
221
|
-
::Guard::UI.debug 'Guard stops all plugins'
|
222
|
-
runner.run(:stop)
|
223
|
-
::Guard::Notifier.turn_off
|
224
|
-
::Guard::UI.info 'Bye bye...', :reset => true
|
225
|
-
listener.stop
|
226
|
-
@running = false
|
227
|
-
end
|
228
|
-
end
|
229
|
-
|
230
|
-
# Reload Guardfile and all Guard plugins currently enabled.
|
231
|
-
# If no scope is given, then the Guardfile will be re-evaluated,
|
232
|
-
# which results in a stop/start, which makes the reload obsolete.
|
233
|
-
#
|
234
|
-
# @param [Hash] scopes hash with a Guard plugin or a group scope
|
235
|
-
#
|
236
|
-
def reload(scopes = {})
|
237
|
-
scopes = convert_scopes(scopes)
|
238
|
-
|
239
|
-
within_preserved_state do
|
240
|
-
::Guard::UI.clear(:force => true)
|
241
|
-
::Guard::UI.action_with_scopes('Reload', scopes)
|
242
|
-
|
243
|
-
if scopes.empty?
|
244
|
-
::Guard::Dsl.reevaluate_guardfile
|
245
|
-
else
|
246
|
-
runner.run(:reload, scopes)
|
247
|
-
end
|
248
|
-
end
|
249
|
-
end
|
250
|
-
|
251
|
-
# Trigger `run_all` on all Guard plugins currently enabled.
|
252
|
-
#
|
253
|
-
# @param [Hash] scopes hash with a Guard plugin or a group scope
|
254
|
-
#
|
255
|
-
def run_all(scopes = {})
|
256
|
-
scopes = convert_scopes(scopes)
|
257
|
-
|
258
|
-
within_preserved_state do
|
259
|
-
::Guard::UI.clear(:force => true)
|
260
|
-
::Guard::UI.action_with_scopes('Run', scopes)
|
261
|
-
runner.run(:run_all, scopes)
|
262
|
-
end
|
263
|
-
end
|
264
|
-
|
265
|
-
# Pause Guard listening to file changes.
|
266
|
-
#
|
267
|
-
def pause
|
268
|
-
if listener.paused?
|
269
|
-
::Guard::UI.info 'Un-paused files modification listening', :reset => true
|
270
|
-
listener.unpause
|
271
|
-
else
|
272
|
-
::Guard::UI.info 'Paused files modification listening', :reset => true
|
273
|
-
listener.pause
|
274
|
-
end
|
275
|
-
end
|
276
|
-
|
277
|
-
# Smart accessor for retrieving a specific Guard plugin or several Guard plugins at once.
|
278
|
-
#
|
38
|
+
# @example Filter plugins by String or Symbol
|
39
|
+
# Guard.plugins('rspec')
|
40
|
+
# Guard.plugins(:rspec)
|
41
|
+
#
|
42
|
+
# @example Filter plugins by Regexp
|
43
|
+
# Guard.plugins(/rsp.+/)
|
44
|
+
#
|
45
|
+
# @example Filter plugins by Hash
|
46
|
+
# Guard.plugins(name: 'rspec', group: 'backend')
|
47
|
+
#
|
48
|
+
# @param [String, Symbol, Regexp, Hash] filter the filter to apply to the plugins
|
49
|
+
# @return [Plugin, Array<Plugin>] the filtered plugin(s)
|
50
|
+
#
|
51
|
+
def plugins(filter = nil)
|
52
|
+
@plugins ||= []
|
53
|
+
|
54
|
+
return @plugins if filter.nil?
|
55
|
+
|
56
|
+
filtered_plugins = case filter
|
57
|
+
when String, Symbol
|
58
|
+
@plugins.find_all do |plugin|
|
59
|
+
plugin.name == filter.to_s.downcase.gsub('-', '')
|
60
|
+
end
|
61
|
+
when Regexp
|
62
|
+
@plugins.find_all do |plugin|
|
63
|
+
plugin.name =~ filter
|
64
|
+
end
|
65
|
+
when Hash
|
66
|
+
@plugins.find_all do |plugin|
|
67
|
+
filter.all? do |k, v|
|
68
|
+
case k
|
69
|
+
when :name
|
70
|
+
plugin.name == v.to_s.downcase.gsub('-', '')
|
71
|
+
when :group
|
72
|
+
plugin.group.name == v.to_sym
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
filtered_plugins
|
79
|
+
end
|
80
|
+
|
81
|
+
# Smart accessor for retrieving a specific plugin.
|
82
|
+
#
|
83
|
+
# @see Guard.plugins
|
84
|
+
# @see Guard.group
|
279
85
|
# @see Guard.groups
|
280
86
|
#
|
281
|
-
# @example
|
282
|
-
# Guard.
|
283
|
-
# Guard.
|
87
|
+
# @example Find a plugin by String or Symbol
|
88
|
+
# Guard.plugin('rspec')
|
89
|
+
# Guard.plugin(:rspec)
|
284
90
|
#
|
285
|
-
# @example
|
286
|
-
# Guard.
|
91
|
+
# @example Find a plugin by Regexp
|
92
|
+
# Guard.plugin(/rsp.+/)
|
287
93
|
#
|
288
|
-
# @example
|
289
|
-
# Guard.
|
94
|
+
# @example Find a plugin by Hash
|
95
|
+
# Guard.plugin(name: 'rspec', group: 'backend')
|
290
96
|
#
|
291
|
-
# @param [String, Symbol, Regexp, Hash] filter the filter
|
292
|
-
#
|
97
|
+
# @param [String, Symbol, Regexp, Hash] filter the filter for finding the plugin
|
98
|
+
# the Guard plugin
|
99
|
+
# @return [Plugin, nil] the plugin found, nil otherwise
|
293
100
|
#
|
294
|
-
def
|
295
|
-
|
296
|
-
|
297
|
-
case filter
|
298
|
-
when String, Symbol
|
299
|
-
@guards.find { |guard| guard.class.to_s.downcase.sub('guard::', '') == filter.to_s.downcase.gsub('-', '') }
|
300
|
-
when Regexp
|
301
|
-
@guards.find_all { |guard| guard.class.to_s.downcase.sub('guard::', '') =~ filter }
|
302
|
-
when Hash
|
303
|
-
filter.inject(@guards) do |matches, (k, v)|
|
304
|
-
if k.to_sym == :name
|
305
|
-
matches.find_all { |guard| guard.class.to_s.downcase.sub('guard::', '') == v.to_s.downcase.gsub('-', '') }
|
306
|
-
else
|
307
|
-
matches.find_all { |guard| guard.send(k).to_sym == v.to_sym }
|
308
|
-
end
|
309
|
-
end
|
310
|
-
else
|
311
|
-
@guards
|
312
|
-
end
|
101
|
+
def plugin(filter)
|
102
|
+
plugins(filter).first
|
313
103
|
end
|
314
104
|
|
315
|
-
# Smart accessor for retrieving
|
105
|
+
# Smart accessor for retrieving specific groups at once.
|
316
106
|
#
|
317
|
-
# @see Guard.
|
107
|
+
# @see Guard.plugin
|
108
|
+
# @see Guard.plugins
|
109
|
+
# @see Guard.group
|
318
110
|
#
|
319
111
|
# @example Filter groups by String or Symbol
|
320
112
|
# Guard.groups('backend')
|
@@ -324,219 +116,77 @@ module Guard
|
|
324
116
|
# Guard.groups(/(back|front)end/)
|
325
117
|
#
|
326
118
|
# @param [String, Symbol, Regexp] filter the filter to apply to the Groups
|
327
|
-
# @return [Array<Group>] the filtered
|
119
|
+
# @return [Array<Group>] the filtered group(s)
|
328
120
|
#
|
329
121
|
def groups(filter = nil)
|
330
|
-
|
331
|
-
when String, Symbol
|
332
|
-
@groups.find { |group| group.name == filter.to_sym }
|
333
|
-
when Regexp
|
334
|
-
@groups.find_all { |group| group.name.to_s =~ filter }
|
335
|
-
else
|
336
|
-
@groups
|
337
|
-
end
|
338
|
-
end
|
122
|
+
return @groups if filter.nil?
|
339
123
|
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
# @return [Guard::Guard] the added Guard plugin
|
347
|
-
#
|
348
|
-
def add_guard(name, watchers = [], callbacks = [], options = {})
|
349
|
-
if name.to_sym == :ego
|
350
|
-
::Guard::UI.deprecation('Guard::Ego is now part of Guard. You can remove it from your Guardfile.')
|
351
|
-
else
|
352
|
-
guard_class = get_guard_class(name)
|
353
|
-
callbacks.each { |callback| Hook.add_callback(callback[:listener], guard_class, callback[:events]) }
|
354
|
-
guard = guard_class.new(watchers, options)
|
355
|
-
@guards << guard
|
356
|
-
guard
|
357
|
-
end
|
358
|
-
end
|
124
|
+
filtered_groups = case filter
|
125
|
+
when String, Symbol
|
126
|
+
@groups.find_all { |group| group.name == filter.to_sym }
|
127
|
+
when Regexp
|
128
|
+
@groups.find_all { |group| group.name.to_s =~ filter }
|
129
|
+
end
|
359
130
|
|
360
|
-
|
361
|
-
#
|
362
|
-
# @param [String] name the group name
|
363
|
-
# @option options [Boolean] halt_on_fail if a task execution
|
364
|
-
# should be halted for all Guard plugins in this group if one Guard throws `:task_has_failed`
|
365
|
-
# @return [Guard::Group] the group added (or retrieved from the `@groups` variable if already present)
|
366
|
-
#
|
367
|
-
def add_group(name, options = {})
|
368
|
-
group = groups(name)
|
369
|
-
if group.nil?
|
370
|
-
group = ::Guard::Group.new(name, options)
|
371
|
-
@groups << group
|
372
|
-
end
|
373
|
-
group
|
131
|
+
filtered_groups
|
374
132
|
end
|
375
133
|
|
376
|
-
#
|
377
|
-
# blocked and execution is synchronized
|
378
|
-
# to avoid state inconsistency.
|
134
|
+
# Smart accessor for retrieving a specific group.
|
379
135
|
#
|
380
|
-
# @
|
381
|
-
# @
|
382
|
-
#
|
383
|
-
def within_preserved_state(restart_interactor = true)
|
384
|
-
lock.synchronize do
|
385
|
-
begin
|
386
|
-
interactor.stop if interactor
|
387
|
-
@result = yield
|
388
|
-
rescue Interrupt
|
389
|
-
# Bring back Pry when the block is halted with Ctrl-C
|
390
|
-
end
|
391
|
-
|
392
|
-
interactor.start if interactor && restart_interactor
|
393
|
-
end
|
394
|
-
|
395
|
-
@result
|
396
|
-
end
|
397
|
-
|
398
|
-
# Tries to load the Guard plugin main class. This transforms the supplied Guard plugin
|
399
|
-
# name into a class name:
|
400
|
-
#
|
401
|
-
# * `guardname` will become `Guard::Guardname`
|
402
|
-
# * `dashed-guard-name` will become `Guard::DashedGuardName`
|
403
|
-
# * `underscore_guard_name` will become `Guard::UnderscoreGuardName`
|
404
|
-
#
|
405
|
-
# When no class is found with the strict case sensitive rules, another
|
406
|
-
# try is made to locate the class without matching case:
|
407
|
-
#
|
408
|
-
# * `rspec` will find a class `Guard::RSpec`
|
136
|
+
# @see Guard.plugin
|
137
|
+
# @see Guard.plugins
|
138
|
+
# @see Guard.groups
|
409
139
|
#
|
410
|
-
# @
|
411
|
-
#
|
412
|
-
#
|
140
|
+
# @example Find a group by String or Symbol
|
141
|
+
# Guard.group('backend')
|
142
|
+
# Guard.group(:backend)
|
413
143
|
#
|
414
|
-
|
415
|
-
|
416
|
-
try_require = false
|
417
|
-
const_name = name.gsub(/\/(.?)/) { "::#{ $1.upcase }" }.gsub(/(?:^|[_-])(.)/) { $1.upcase }
|
418
|
-
begin
|
419
|
-
require "guard/#{ name.downcase }" if try_require
|
420
|
-
self.const_get(self.constants.find { |c| c.to_s == const_name } || self.constants.find { |c| c.to_s.downcase == const_name.downcase })
|
421
|
-
rescue TypeError
|
422
|
-
if try_require
|
423
|
-
::Guard::UI.error "Could not find class Guard::#{ const_name.capitalize }"
|
424
|
-
else
|
425
|
-
try_require = true
|
426
|
-
retry
|
427
|
-
end
|
428
|
-
rescue LoadError => loadError
|
429
|
-
unless fail_gracefully
|
430
|
-
::Guard::UI.error "Could not load 'guard/#{ name.downcase }' or find class Guard::#{ const_name.capitalize }"
|
431
|
-
::Guard::UI.error loadError.to_s
|
432
|
-
end
|
433
|
-
end
|
434
|
-
end
|
435
|
-
|
436
|
-
# Locate a path to a Guard plugin gem.
|
144
|
+
# @example Find a group by Regexp
|
145
|
+
# Guard.group(/(back|front)end/)
|
437
146
|
#
|
438
|
-
# @param [String
|
439
|
-
# @return [
|
147
|
+
# @param [String, Symbol, Regexp] filter the filter for finding the group
|
148
|
+
# @return [Group] the group found, nil otherwise
|
440
149
|
#
|
441
|
-
def
|
442
|
-
|
443
|
-
Gem::Specification.find_by_name("guard-#{ name }").full_gem_path
|
444
|
-
else
|
445
|
-
Gem.source_index.find_name("guard-#{ name }").last.full_gem_path
|
446
|
-
end
|
447
|
-
rescue
|
448
|
-
::Guard::UI.error "Could not find 'guard-#{ name }' gem path."
|
150
|
+
def group(filter)
|
151
|
+
groups(filter).first
|
449
152
|
end
|
450
153
|
|
451
|
-
#
|
452
|
-
#
|
453
|
-
# @return [Array<String>] a list of Guard plugin gem names
|
154
|
+
# Add a Guard plugin to use.
|
454
155
|
#
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
File.exists?( guard_plugin_path )
|
463
|
-
end
|
464
|
-
end
|
465
|
-
else
|
466
|
-
Gem.source_index.find_name(/^guard-/)
|
467
|
-
end.map { |x| x.name.sub(/^guard-/, '') }
|
468
|
-
end
|
469
|
-
|
470
|
-
# Adds a command logger in debug mode. This wraps common command
|
471
|
-
# execution functions and logs the executed command before execution.
|
156
|
+
# @param [String] name the Guard name
|
157
|
+
# @param [Hash] options the plugin options (see the given Guard documentation)
|
158
|
+
# @option options [String] group the group to which the Guard plugin belongs
|
159
|
+
# @option options [Array<Watcher>] watchers the list of declared watchers
|
160
|
+
# @option options [Array<Hash>] callbacks the list of callbacks
|
161
|
+
# @return [Plugin] the added Guard plugin
|
162
|
+
# @see Plugin
|
472
163
|
#
|
473
|
-
def
|
474
|
-
|
475
|
-
|
476
|
-
::Guard::UI.debug "Command execution: #{ command } #{ args.join(' ') }"
|
477
|
-
original_system command, *args
|
478
|
-
end
|
164
|
+
def add_plugin(name, options = {})
|
165
|
+
plugin_instance = ::Guard::PluginUtil.new(name).initialize_plugin(options)
|
166
|
+
@plugins << plugin_instance
|
479
167
|
|
480
|
-
|
481
|
-
Kernel.send(:define_method, :'`') do |command|
|
482
|
-
::Guard::UI.debug "Command execution: #{ command }"
|
483
|
-
original_backtick command
|
484
|
-
end
|
168
|
+
plugin_instance
|
485
169
|
end
|
486
170
|
|
487
|
-
#
|
488
|
-
WATCH_ALL_MODIFICATIONS_DEPRECATION = <<-EOS.gsub(/^\s*/, '')
|
489
|
-
Starting with Guard v1.1 the 'watch_all_modifications' option is removed and is now always on.
|
490
|
-
EOS
|
491
|
-
|
492
|
-
# Deprecation message for the `no_vendor` start option
|
493
|
-
NO_VENDOR_DEPRECATION = <<-EOS.gsub(/^\s*/, '')
|
494
|
-
Starting with Guard v1.1 the 'no_vendor' option is removed because the monitoring
|
495
|
-
gems are now part of a new gem called Listen. (https://github.com/guard/listen)
|
496
|
-
|
497
|
-
You can specify a custom version of any monitoring gem directly in your Gemfile
|
498
|
-
if you want to overwrite Listen's default monitoring gems.
|
499
|
-
EOS
|
500
|
-
|
501
|
-
# Displays a warning for each deprecated options used.
|
171
|
+
# Add a Guard plugin group.
|
502
172
|
#
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
#
|
173
|
+
# @param [String] name the group name
|
174
|
+
# @option options [Boolean] halt_on_fail if a task execution
|
175
|
+
# should be halted for all Guard plugins in this group if
|
176
|
+
# one Guard throws `:task_has_failed`
|
177
|
+
# @return [Group] the group added (or retrieved from the `@groups`
|
178
|
+
# variable if already present)
|
509
179
|
#
|
510
|
-
# @
|
511
|
-
# convert_scopes({ :guard => :rspec, :group => :backend })
|
512
|
-
# => { :plugins => [:rspec], :groups => [:backend] }
|
180
|
+
# @see Group
|
513
181
|
#
|
514
|
-
def
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
if group = scopes.delete(:group)
|
520
|
-
scopes[:groups] = [group]
|
182
|
+
def add_group(name, options = {})
|
183
|
+
unless group = group(name)
|
184
|
+
group = ::Guard::Group.new(name, options)
|
185
|
+
@groups << group
|
521
186
|
end
|
522
187
|
|
523
|
-
|
188
|
+
group
|
524
189
|
end
|
525
190
|
|
526
|
-
# Determine if Guard needs to quit. This
|
527
|
-
# checks for Ctrl-D pressed.
|
528
|
-
#
|
529
|
-
# @return [Boolean] whether to quit or not
|
530
|
-
#
|
531
|
-
def quit?
|
532
|
-
STDIN.read_nonblock(1)
|
533
|
-
false
|
534
|
-
rescue Errno::EINTR
|
535
|
-
false
|
536
|
-
rescue Errno::EAGAIN
|
537
|
-
false
|
538
|
-
rescue EOFError
|
539
|
-
true
|
540
|
-
end
|
541
191
|
end
|
542
192
|
end
|