guard 1.4.0 → 2.18.0
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 +7 -0
- data/CHANGELOG.md +1 -677
- data/LICENSE +4 -2
- data/README.md +91 -753
- data/bin/_guard-core +11 -0
- data/bin/guard +108 -3
- data/lib/guard/aruba_adapter.rb +59 -0
- data/lib/guard/cli/environments/bundler.rb +22 -0
- data/lib/guard/cli/environments/evaluate_only.rb +35 -0
- data/lib/guard/cli/environments/valid.rb +69 -0
- data/lib/guard/cli.rb +129 -128
- data/lib/guard/commander.rb +104 -0
- data/lib/guard/commands/all.rb +37 -0
- data/lib/guard/commands/change.rb +31 -0
- data/lib/guard/commands/notification.rb +26 -0
- data/lib/guard/commands/pause.rb +29 -0
- data/lib/guard/commands/reload.rb +36 -0
- data/lib/guard/commands/scope.rb +38 -0
- data/lib/guard/commands/show.rb +24 -0
- data/lib/guard/config.rb +18 -0
- data/lib/guard/deprecated/dsl.rb +45 -0
- data/lib/guard/deprecated/evaluator.rb +39 -0
- data/lib/guard/deprecated/guard.rb +328 -0
- data/lib/guard/deprecated/guardfile.rb +84 -0
- data/lib/guard/deprecated/watcher.rb +27 -0
- data/lib/guard/dsl.rb +332 -363
- data/lib/guard/dsl_describer.rb +132 -122
- data/lib/guard/dsl_reader.rb +51 -0
- data/lib/guard/group.rb +34 -14
- data/lib/guard/guardfile/evaluator.rb +232 -0
- data/lib/guard/guardfile/generator.rb +128 -0
- data/lib/guard/guardfile.rb +24 -60
- data/lib/guard/interactor.rb +31 -255
- data/lib/guard/internals/debugging.rb +68 -0
- data/lib/guard/internals/groups.rb +40 -0
- data/lib/guard/internals/helpers.rb +13 -0
- data/lib/guard/internals/plugins.rb +53 -0
- data/lib/guard/internals/queue.rb +51 -0
- data/lib/guard/internals/scope.rb +121 -0
- data/lib/guard/internals/session.rb +180 -0
- data/lib/guard/internals/state.rb +25 -0
- data/lib/guard/internals/tracing.rb +33 -0
- data/lib/guard/internals/traps.rb +10 -0
- data/lib/guard/jobs/base.rb +21 -0
- data/lib/guard/jobs/pry_wrapper.rb +336 -0
- data/lib/guard/jobs/sleep.rb +26 -0
- data/lib/guard/notifier.rb +46 -212
- data/lib/guard/options.rb +22 -0
- data/lib/guard/plugin.rb +303 -0
- data/lib/guard/plugin_util.rb +191 -0
- data/lib/guard/rake_task.rb +42 -0
- data/lib/guard/runner.rb +80 -140
- data/lib/guard/templates/Guardfile +14 -0
- data/lib/guard/terminal.rb +13 -0
- data/lib/guard/ui/colors.rb +56 -0
- data/lib/guard/ui/config.rb +70 -0
- data/lib/guard/ui/logger.rb +30 -0
- data/lib/guard/ui.rb +163 -128
- data/lib/guard/version.rb +1 -2
- data/lib/guard/watcher/pattern/deprecated_regexp.rb +45 -0
- data/lib/guard/watcher/pattern/match_result.rb +18 -0
- data/lib/guard/watcher/pattern/matcher.rb +33 -0
- data/lib/guard/watcher/pattern/pathname_path.rb +15 -0
- data/lib/guard/watcher/pattern/simple_path.rb +23 -0
- data/lib/guard/watcher/pattern.rb +24 -0
- data/lib/guard/watcher.rb +52 -95
- data/lib/guard.rb +108 -376
- data/lib/tasks/releaser.rb +116 -0
- data/man/guard.1 +12 -9
- data/man/guard.1.html +18 -12
- metadata +148 -77
- data/images/guard.png +0 -0
- data/lib/guard/guard.rb +0 -156
- data/lib/guard/hook.rb +0 -120
- data/lib/guard/interactors/coolline.rb +0 -64
- data/lib/guard/interactors/helpers/completion.rb +0 -32
- data/lib/guard/interactors/helpers/terminal.rb +0 -46
- data/lib/guard/interactors/readline.rb +0 -94
- data/lib/guard/interactors/simple.rb +0 -19
- data/lib/guard/notifiers/emacs.rb +0 -69
- data/lib/guard/notifiers/gntp.rb +0 -118
- data/lib/guard/notifiers/growl.rb +0 -99
- data/lib/guard/notifiers/growl_notify.rb +0 -92
- data/lib/guard/notifiers/libnotify.rb +0 -96
- data/lib/guard/notifiers/notifysend.rb +0 -84
- data/lib/guard/notifiers/rb_notifu.rb +0 -102
- data/lib/guard/notifiers/terminal_notifier.rb +0 -66
- data/lib/guard/notifiers/tmux.rb +0 -69
- data/lib/guard/version.rbc +0 -130
data/lib/guard/dsl_describer.rb
CHANGED
@@ -1,150 +1,160 @@
|
|
1
|
-
|
1
|
+
# encoding: utf-8
|
2
|
+
require "formatador"
|
3
|
+
|
4
|
+
require "guard/ui"
|
5
|
+
require "guard/notifier"
|
6
|
+
require "guard"
|
7
|
+
|
8
|
+
require "set"
|
9
|
+
require "ostruct"
|
2
10
|
|
3
|
-
|
4
|
-
#
|
5
|
-
# like the CLI commands
|
11
|
+
module Guard
|
12
|
+
# The DslDescriber evaluates the Guardfile and creates an internal structure
|
13
|
+
# of it that is used in some inspection utility methods like the CLI commands
|
14
|
+
# `show` and `list`.
|
6
15
|
#
|
7
16
|
# @see Guard::Dsl
|
8
17
|
# @see Guard::CLI
|
9
18
|
#
|
10
|
-
class DslDescriber
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
class << self
|
16
|
-
|
17
|
-
# Evaluate the DSL methods in the `Guardfile`.
|
18
|
-
#
|
19
|
-
# @option options [Array<Symbol,String>] groups the groups to evaluate
|
20
|
-
# @option options [String] guardfile the path to a valid Guardfile
|
21
|
-
# @option options [String] guardfile_contents a string representing the content of a valid Guardfile
|
22
|
-
# @raise [ArgumentError] when options are not a Hash
|
23
|
-
#
|
24
|
-
def evaluate_guardfile(options = {})
|
25
|
-
@@guardfile_structure = [{ :guards => [] }]
|
26
|
-
super options
|
27
|
-
end
|
28
|
-
|
29
|
-
# List the Guard plugins that are available for use in your system and marks
|
30
|
-
# those that are currently used in your `Guardfile`.
|
31
|
-
#
|
32
|
-
# @example Guard list output
|
33
|
-
#
|
34
|
-
# Available guards:
|
35
|
-
# bundler *
|
36
|
-
# livereload
|
37
|
-
# ronn
|
38
|
-
# rspec *
|
39
|
-
# spork
|
40
|
-
#
|
41
|
-
# See also https://github.com/guard/guard/wiki/List-of-available-Guards
|
42
|
-
# * denotes ones already in your Guardfile
|
43
|
-
#
|
44
|
-
# @param [Hash] options the Guard options
|
45
|
-
#
|
46
|
-
def list(options)
|
47
|
-
evaluate_guardfile(options)
|
48
|
-
|
49
|
-
installed_guards = guardfile_structure.inject([]) do |installed, group|
|
50
|
-
group[:guards].each { |guard| installed << guard[:name].to_s } if group[:guards]
|
51
|
-
installed
|
52
|
-
end
|
53
|
-
|
54
|
-
::Guard::UI.info 'Available guards:'
|
55
|
-
|
56
|
-
::Guard.guard_gem_names.sort.uniq.each do |name|
|
57
|
-
::Guard::UI.info " #{ name }#{ installed_guards.include?(name) ? '*' : '' }"
|
58
|
-
end
|
19
|
+
class DslDescriber
|
20
|
+
def initialize(options = nil)
|
21
|
+
fail "options passed to DslDescriber are ignored!" unless options.nil?
|
22
|
+
end
|
59
23
|
|
60
|
-
|
61
|
-
|
62
|
-
|
24
|
+
# List the Guard plugins that are available for use in your system and marks
|
25
|
+
# those that are currently used in your `Guardfile`.
|
26
|
+
#
|
27
|
+
# @see CLI#list
|
28
|
+
#
|
29
|
+
def list
|
30
|
+
# TODO: remove dependency on Guard in this whole file
|
31
|
+
# collect metadata
|
32
|
+
data = PluginUtil.plugin_names.sort.inject({}) do |hash, name|
|
33
|
+
hash[name.capitalize] = Guard.state.session.plugins.all(name).any?
|
34
|
+
hash
|
63
35
|
end
|
64
36
|
|
65
|
-
#
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
# bundler
|
72
|
-
# coffeescript: input => "app/assets/javascripts", noop => true
|
73
|
-
# jasmine
|
74
|
-
# rspec: cli => "--fail-fast --format Fuubar
|
75
|
-
#
|
76
|
-
# @param [Hash] options the Guard options
|
77
|
-
#
|
78
|
-
def show(options)
|
79
|
-
evaluate_guardfile(options)
|
80
|
-
|
81
|
-
guardfile_structure.each do |group|
|
82
|
-
unless group[:guards].empty?
|
83
|
-
if group[:group]
|
84
|
-
::Guard::UI.info "Group #{ group[:group] }:"
|
85
|
-
else
|
86
|
-
::Guard::UI.info '(global):'
|
87
|
-
end
|
88
|
-
|
89
|
-
group[:guards].each do |guard|
|
90
|
-
line = " #{ guard[:name] }"
|
37
|
+
# presentation
|
38
|
+
header = [:Plugin, :Guardfile]
|
39
|
+
final_rows = []
|
40
|
+
data.each do |name, used|
|
41
|
+
final_rows << { Plugin: name, Guardfile: used ? "✔" : "✘" }
|
42
|
+
end
|
91
43
|
|
92
|
-
|
93
|
-
|
94
|
-
|
44
|
+
# render
|
45
|
+
Formatador.display_compact_table(final_rows, header)
|
46
|
+
end
|
95
47
|
|
96
|
-
|
97
|
-
|
48
|
+
# Shows all Guard plugins and their options that are defined in
|
49
|
+
# the `Guardfile`.
|
50
|
+
#
|
51
|
+
# @see CLI#show
|
52
|
+
#
|
53
|
+
def show
|
54
|
+
# collect metadata
|
55
|
+
groups = Guard.state.session.groups.all
|
56
|
+
|
57
|
+
objects = []
|
58
|
+
|
59
|
+
empty_plugin = OpenStruct.new
|
60
|
+
empty_plugin.options = [["", nil]]
|
61
|
+
|
62
|
+
groups.each do |group|
|
63
|
+
plugins = Array(Guard.state.session.plugins.all(group: group.name))
|
64
|
+
plugins = [empty_plugin] if plugins.empty?
|
65
|
+
plugins.each do |plugin|
|
66
|
+
options = plugin.options
|
67
|
+
options = [["", nil]] if options.empty?
|
68
|
+
options.each do |option, raw_value|
|
69
|
+
value = raw_value.nil? ? "" : raw_value.inspect
|
70
|
+
objects << [group.title, plugin.title, option.to_s, value]
|
98
71
|
end
|
99
72
|
end
|
100
|
-
|
101
|
-
::Guard::UI.info ''
|
102
73
|
end
|
103
74
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
75
|
+
# presentation
|
76
|
+
rows = []
|
77
|
+
prev_group = prev_plugin = prev_option = prev_value = nil
|
78
|
+
objects.each do |group, plugin, option, value|
|
79
|
+
group_changed = prev_group != group
|
80
|
+
plugin_changed = (prev_plugin != plugin || group_changed)
|
81
|
+
|
82
|
+
rows << :split if group_changed || plugin_changed
|
83
|
+
|
84
|
+
rows << {
|
85
|
+
Group: group_changed ? group : "",
|
86
|
+
Plugin: plugin_changed ? plugin : "",
|
87
|
+
Option: option,
|
88
|
+
Value: value
|
89
|
+
}
|
90
|
+
|
91
|
+
prev_group = group
|
92
|
+
prev_plugin = plugin
|
93
|
+
prev_option = option
|
94
|
+
prev_value = value
|
112
95
|
end
|
113
96
|
|
97
|
+
# render
|
98
|
+
Formatador.display_compact_table(
|
99
|
+
rows.drop(1),
|
100
|
+
[:Group, :Plugin, :Option, :Value]
|
101
|
+
)
|
114
102
|
end
|
115
103
|
|
116
|
-
|
117
|
-
|
118
|
-
# Declares a group of guards.
|
104
|
+
# Shows all notifiers and their options that are defined in
|
105
|
+
# the `Guardfile`.
|
119
106
|
#
|
120
|
-
# @
|
121
|
-
# @yield a block where you can declare several guards
|
107
|
+
# @see CLI#show
|
122
108
|
#
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
109
|
+
def notifiers
|
110
|
+
supported = Notifier.supported
|
111
|
+
Notifier.connect(notify: true, silent: true)
|
112
|
+
detected = Notifier.detected
|
113
|
+
Notifier.disconnect
|
114
|
+
|
115
|
+
detected_names = detected.map { |item| item[:name] }
|
116
|
+
|
117
|
+
final_rows = supported.each_with_object([]) do |(name, _), rows|
|
118
|
+
available = detected_names.include?(name) ? "✔" : "✘"
|
119
|
+
|
120
|
+
notifier = detected.detect { |n| n[:name] == name }
|
121
|
+
used = notifier ? "✔" : "✘"
|
122
|
+
|
123
|
+
options = notifier ? notifier[:options] : {}
|
124
|
+
|
125
|
+
if options.empty?
|
126
|
+
rows << :split
|
127
|
+
_add_row(rows, name, available, used, "", "")
|
128
|
+
else
|
129
|
+
options.each_with_index do |(option, value), index|
|
130
|
+
if index == 0
|
131
|
+
rows << :split
|
132
|
+
_add_row(rows, name, available, used, option.to_s, value.inspect)
|
133
|
+
else
|
134
|
+
_add_row(rows, "", "", "", option.to_s, value.inspect)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
128
138
|
|
129
|
-
|
139
|
+
rows
|
140
|
+
end
|
130
141
|
|
131
|
-
|
142
|
+
Formatador.display_compact_table(
|
143
|
+
final_rows.drop(1),
|
144
|
+
[:Name, :Available, :Used, :Option, :Value]
|
145
|
+
)
|
132
146
|
end
|
133
147
|
|
134
|
-
|
135
|
-
#
|
136
|
-
# @param [String] name the Guard name
|
137
|
-
# @param [Hash] options the options accepted by the Guard
|
138
|
-
# @yield a block where you can declare several watch patterns and actions
|
139
|
-
#
|
140
|
-
# @see Guard::Dsl#guard
|
141
|
-
#
|
142
|
-
def guard(name, options = { })
|
143
|
-
@group ||= false
|
144
|
-
node = (@group ? @@guardfile_structure.last : @@guardfile_structure.first)
|
148
|
+
private
|
145
149
|
|
146
|
-
|
150
|
+
def _add_row(rows, name, available, used, option, value)
|
151
|
+
rows << {
|
152
|
+
Name: name,
|
153
|
+
Available: available,
|
154
|
+
Used: used,
|
155
|
+
Option: option,
|
156
|
+
Value: value
|
157
|
+
}
|
147
158
|
end
|
148
|
-
|
149
159
|
end
|
150
160
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require "guard/dsl"
|
2
|
+
|
3
|
+
module Guard
|
4
|
+
# TODO: this should probably be a base class for Dsl instead (in Guard 3.x)
|
5
|
+
class DslReader < Dsl
|
6
|
+
attr_reader :plugin_names
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
super
|
10
|
+
@plugin_names = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def guard(name, _options = {})
|
14
|
+
@plugin_names << name.to_s
|
15
|
+
end
|
16
|
+
|
17
|
+
# Stub everything else
|
18
|
+
def notification(_notifier, _opts = {})
|
19
|
+
end
|
20
|
+
|
21
|
+
def interactor(_options)
|
22
|
+
end
|
23
|
+
|
24
|
+
def group(*_args)
|
25
|
+
end
|
26
|
+
|
27
|
+
def watch(_pattern, &_action)
|
28
|
+
end
|
29
|
+
|
30
|
+
def callback(*_args, &_block)
|
31
|
+
end
|
32
|
+
|
33
|
+
def ignore(*_regexps)
|
34
|
+
end
|
35
|
+
|
36
|
+
def ignore!(*_regexps)
|
37
|
+
end
|
38
|
+
|
39
|
+
def logger(_options)
|
40
|
+
end
|
41
|
+
|
42
|
+
def scope(_scope = {})
|
43
|
+
end
|
44
|
+
|
45
|
+
def directories(_directories)
|
46
|
+
end
|
47
|
+
|
48
|
+
def clearing(_on)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/guard/group.rb
CHANGED
@@ -1,23 +1,27 @@
|
|
1
1
|
module Guard
|
2
|
-
|
3
|
-
#
|
2
|
+
# A group of Guard plugins. There are two reasons why you want to group your
|
3
|
+
# Guard plugins:
|
4
4
|
#
|
5
|
-
#
|
6
|
-
#
|
5
|
+
# * You can start only certain groups from the command line by passing the
|
6
|
+
# `--group` option to `guard start`.
|
7
|
+
# * Abort task execution chain on failure within a group with the
|
8
|
+
# `:halt_on_fail` option.
|
7
9
|
#
|
8
10
|
# @example Group that aborts on failure
|
9
11
|
#
|
10
|
-
# group :frontend, :
|
11
|
-
# guard 'coffeescript', :
|
12
|
+
# group :frontend, halt_on_fail: true do
|
13
|
+
# guard 'coffeescript', input: 'spec/coffeescripts',
|
14
|
+
# output: 'spec/javascripts'
|
12
15
|
# guard 'jasmine-headless-webkit' do
|
13
|
-
# watch(%r{^spec/javascripts/(.*)\..*})
|
16
|
+
# watch(%r{^spec/javascripts/(.*)\..*}) do |m|
|
17
|
+
# newest_js_file("spec/javascripts/#{m[1]}_spec")
|
18
|
+
# end
|
14
19
|
# end
|
15
20
|
# end
|
16
21
|
#
|
17
22
|
# @see Guard::CLI
|
18
23
|
#
|
19
24
|
class Group
|
20
|
-
|
21
25
|
attr_accessor :name, :options
|
22
26
|
|
23
27
|
# Initializes a Group.
|
@@ -25,20 +29,36 @@ module Guard
|
|
25
29
|
# @param [String] name the name of the group
|
26
30
|
# @param [Hash] options the group options
|
27
31
|
# @option options [Boolean] halt_on_fail if a task execution
|
28
|
-
# should be halted for all Guard plugins in this group if a Guard plugin
|
32
|
+
# should be halted for all Guard plugins in this group if a Guard plugin
|
33
|
+
# throws `:task_has_failed`
|
29
34
|
#
|
30
35
|
def initialize(name, options = {})
|
31
|
-
@name
|
36
|
+
@name = name.to_sym
|
32
37
|
@options = options
|
33
38
|
end
|
34
39
|
|
35
|
-
#
|
40
|
+
# Returns the group title.
|
36
41
|
#
|
37
|
-
# @
|
42
|
+
# @example Title for a group named 'backend'
|
43
|
+
# > Guard::Group.new('backend').title
|
44
|
+
# => "Backend"
|
38
45
|
#
|
39
|
-
|
40
|
-
|
46
|
+
# @return [String]
|
47
|
+
#
|
48
|
+
def title
|
49
|
+
@title ||= name.to_s.capitalize
|
41
50
|
end
|
42
51
|
|
52
|
+
# String representation of the group.
|
53
|
+
#
|
54
|
+
# @example String representation of a group named 'backend'
|
55
|
+
# > Guard::Group.new('backend').to_s
|
56
|
+
# => "#<Guard::Group @name=backend @options={}>"
|
57
|
+
#
|
58
|
+
# @return [String] the string representation
|
59
|
+
#
|
60
|
+
def to_s
|
61
|
+
"#<#{self.class} @name=#{name} @options=#{options}>"
|
62
|
+
end
|
43
63
|
end
|
44
64
|
end
|
@@ -0,0 +1,232 @@
|
|
1
|
+
require "guard/config"
|
2
|
+
require "guard/deprecated/evaluator" unless Guard::Config.new.strict?
|
3
|
+
|
4
|
+
require "guard/options"
|
5
|
+
require "guard/plugin"
|
6
|
+
|
7
|
+
require "guard/dsl"
|
8
|
+
require "guard/dsl_reader"
|
9
|
+
|
10
|
+
module Guard
|
11
|
+
module Guardfile
|
12
|
+
# This class is responsible for evaluating the Guardfile. It delegates to
|
13
|
+
# Guard::Dsl for the actual objects generation from the Guardfile content.
|
14
|
+
#
|
15
|
+
# @see Guard::Dsl
|
16
|
+
#
|
17
|
+
# TODO: rename this to a Locator or Loader or something
|
18
|
+
class Evaluator
|
19
|
+
Deprecated::Evaluator.add_deprecated(self) unless Config.new.strict?
|
20
|
+
|
21
|
+
DEFAULT_GUARDFILES = %w(
|
22
|
+
guardfile.rb
|
23
|
+
Guardfile
|
24
|
+
~/.Guardfile
|
25
|
+
).freeze
|
26
|
+
|
27
|
+
ERROR_NO_GUARDFILE = "No Guardfile found,"\
|
28
|
+
" please create one with `guard init`."
|
29
|
+
|
30
|
+
attr_reader :options, :guardfile_path
|
31
|
+
|
32
|
+
ERROR_NO_PLUGINS = "No Guard plugins found in Guardfile,"\
|
33
|
+
" please add at least one."
|
34
|
+
|
35
|
+
class Error < RuntimeError
|
36
|
+
end
|
37
|
+
|
38
|
+
class NoGuardfileError < Error
|
39
|
+
end
|
40
|
+
|
41
|
+
class NoCustomGuardfile < Error
|
42
|
+
end
|
43
|
+
|
44
|
+
class NoPluginsError < Error
|
45
|
+
end
|
46
|
+
|
47
|
+
def guardfile_source
|
48
|
+
@source
|
49
|
+
end
|
50
|
+
|
51
|
+
# Initializes a new Guard::Guardfile::Evaluator object.
|
52
|
+
#
|
53
|
+
# @option opts [String] guardfile the path to a valid Guardfile
|
54
|
+
# @option opts [String] contents a string representing the
|
55
|
+
# content of a valid Guardfile
|
56
|
+
#
|
57
|
+
def initialize(opts = {})
|
58
|
+
@type = nil
|
59
|
+
@path = nil
|
60
|
+
@user_config = nil
|
61
|
+
|
62
|
+
opts = _from_deprecated(opts)
|
63
|
+
|
64
|
+
if opts[:contents]
|
65
|
+
@type = :inline
|
66
|
+
@contents = opts[:contents]
|
67
|
+
elsif opts[:guardfile]
|
68
|
+
@type = :custom
|
69
|
+
@path = Pathname.new(opts[:guardfile]) # may be updated by _read
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Evaluates the DSL methods in the `Guardfile`.
|
74
|
+
#
|
75
|
+
# @example Programmatically evaluate a Guardfile
|
76
|
+
# Guard::Guardfile::Evaluator.new.evaluate
|
77
|
+
#
|
78
|
+
# @example Programmatically evaluate a Guardfile with a custom Guardfile
|
79
|
+
# path
|
80
|
+
#
|
81
|
+
# options = { guardfile: '/Users/guardfile/MyAwesomeGuardfile' }
|
82
|
+
# Guard::Guardfile::Evaluator.new(options).evaluate
|
83
|
+
#
|
84
|
+
# @example Programmatically evaluate a Guardfile with an inline Guardfile
|
85
|
+
#
|
86
|
+
# options = { contents: 'guard :rspec' }
|
87
|
+
# Guard::Guardfile::Evaluator.new(options).evaluate
|
88
|
+
#
|
89
|
+
def evaluate
|
90
|
+
inline? || _use_provided || _use_default!
|
91
|
+
|
92
|
+
contents = _guardfile_contents
|
93
|
+
fail NoPluginsError, ERROR_NO_PLUGINS unless /guard/m =~ contents
|
94
|
+
|
95
|
+
Dsl.new.evaluate(contents, @path || "", 1)
|
96
|
+
end
|
97
|
+
|
98
|
+
# Tests if the current `Guardfile` contains a specific Guard plugin.
|
99
|
+
#
|
100
|
+
# @example Programmatically test if a Guardfile contains a specific Guard
|
101
|
+
# plugin
|
102
|
+
#
|
103
|
+
# File.read('Guardfile')
|
104
|
+
# => "guard :rspec"
|
105
|
+
#
|
106
|
+
# Guard::Guardfile::Evaluator.new.guardfile_include?('rspec)
|
107
|
+
# => true
|
108
|
+
#
|
109
|
+
# @param [String] plugin_name the name of the Guard
|
110
|
+
# @return [Boolean] whether the Guard plugin has been declared
|
111
|
+
#
|
112
|
+
# TODO: rename this method to it matches RSpec examples better
|
113
|
+
def guardfile_include?(plugin_name)
|
114
|
+
reader = DslReader.new
|
115
|
+
reader.evaluate(@contents, @path || "", 1)
|
116
|
+
reader.plugin_names.include?(plugin_name)
|
117
|
+
end
|
118
|
+
|
119
|
+
attr_reader :path
|
120
|
+
|
121
|
+
def custom?
|
122
|
+
@type == :custom
|
123
|
+
end
|
124
|
+
|
125
|
+
# Gets the content of the `Guardfile` concatenated with the global
|
126
|
+
# user configuration file.
|
127
|
+
#
|
128
|
+
# @example Programmatically get the content of the current Guardfile
|
129
|
+
# Guard::Guardfile::Evaluator.new.guardfile_contents
|
130
|
+
# => "guard :rspec"
|
131
|
+
#
|
132
|
+
# @return [String] the Guardfile content
|
133
|
+
#
|
134
|
+
def guardfile_contents
|
135
|
+
config = File.read(_user_config_path) if File.exist?(_user_config_path)
|
136
|
+
[_guardfile_contents_without_user_config, config].compact.join("\n")
|
137
|
+
end
|
138
|
+
|
139
|
+
def inline?
|
140
|
+
@type == :inline
|
141
|
+
end
|
142
|
+
|
143
|
+
private
|
144
|
+
|
145
|
+
def _guardfile_contents_without_user_config
|
146
|
+
@guardfile_contents || ""
|
147
|
+
end
|
148
|
+
|
149
|
+
def _instance_eval_guardfile(contents)
|
150
|
+
Dsl.new.evaluate(contents, @guardfile_path || "", 1)
|
151
|
+
rescue => ex
|
152
|
+
UI.error "Invalid Guardfile, original error is:\n#{ $! }"
|
153
|
+
raise ex
|
154
|
+
end
|
155
|
+
|
156
|
+
def _fetch_guardfile_contents
|
157
|
+
_use_inline || _use_provided || _use_default
|
158
|
+
@evaluated = true
|
159
|
+
|
160
|
+
return if _guardfile_contents_usable?
|
161
|
+
UI.error "No Guard plugins found in Guardfile,"\
|
162
|
+
" please add at least one."
|
163
|
+
end
|
164
|
+
|
165
|
+
def _use_inline
|
166
|
+
source_from_option = @source.nil? && options[:guardfile_contents]
|
167
|
+
inline = @source == :inline
|
168
|
+
|
169
|
+
return false unless source_from_option || inline
|
170
|
+
|
171
|
+
@source = :inline
|
172
|
+
@guardfile_contents = options[:guardfile_contents]
|
173
|
+
|
174
|
+
UI.info "Using inline Guardfile."
|
175
|
+
true
|
176
|
+
end
|
177
|
+
|
178
|
+
def _use_provided
|
179
|
+
return unless custom?
|
180
|
+
@path, @contents = _read(@path)
|
181
|
+
true
|
182
|
+
rescue Errno::ENOENT
|
183
|
+
fail NoCustomGuardfile, "No Guardfile exists at #{ @path }."
|
184
|
+
end
|
185
|
+
|
186
|
+
def _use_default!
|
187
|
+
DEFAULT_GUARDFILES.each do |guardfile|
|
188
|
+
begin
|
189
|
+
@path, @contents = _read(guardfile)
|
190
|
+
@type = :default
|
191
|
+
break
|
192
|
+
rescue Errno::ENOENT
|
193
|
+
if guardfile == DEFAULT_GUARDFILES.last
|
194
|
+
fail NoGuardfileError, ERROR_NO_GUARDFILE
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def _read(path)
|
201
|
+
full_path = Pathname.new(path.to_s).expand_path
|
202
|
+
[full_path, full_path.read]
|
203
|
+
rescue Errno::ENOENT
|
204
|
+
fail
|
205
|
+
rescue SystemCallError => e
|
206
|
+
UI.error "Error reading file #{full_path}:"
|
207
|
+
UI.error e.inspect
|
208
|
+
UI.error e.backtrace
|
209
|
+
abort
|
210
|
+
end
|
211
|
+
|
212
|
+
def _guardfile_contents
|
213
|
+
@user_config ||= Pathname.new("~/.guard.rb").expand_path.read
|
214
|
+
[@contents, @user_config].compact.join("\n")
|
215
|
+
rescue Errno::ENOENT
|
216
|
+
@contents || ""
|
217
|
+
end
|
218
|
+
|
219
|
+
def _guardfile_contents_usable?
|
220
|
+
guardfile_contents && guardfile_contents =~ /guard/m
|
221
|
+
end
|
222
|
+
|
223
|
+
def _from_deprecated(opts)
|
224
|
+
res = opts.dup
|
225
|
+
if opts.key?(:guardfile_contents)
|
226
|
+
res[:contents] = opts[:guardfile_contents]
|
227
|
+
end
|
228
|
+
res
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|