Class: Guard::PluginUtil

Inherits:
Object
  • Object
show all
Defined in:
lib/guard/plugin_util.rb

Overview

This class contains useful methods to:

  • Fetch all the Guard plugins names;
  • Initialize a plugin, get its location;
  • Return its class name;
  • Add its template to the Guardfile.

Constant Summary collapse

ERROR_NO_GUARD_OR_CLASS =
"Could not load 'guard/%s' or" \
" find class Guard::%s"
INFO_ADDED_GUARD_TO_GUARDFILE =
"%s guard added to Guardfile,"\
" feel free to edit it"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name) ⇒ PluginUtil

Initializes a new Guard::PluginUtil object.

Parameters:

  • name (String)

    the name of the Guard plugin


38
39
40
# File 'lib/guard/plugin_util.rb', line 38

def initialize(name)
  @name = name.to_s.sub(/^guard-/, "")
end

Instance Attribute Details

#nameObject

Returns the value of attribute name


20
21
22
# File 'lib/guard/plugin_util.rb', line 20

def name
  @name
end

Class Method Details

._gem_valid?(gem) ⇒ Boolean

Returns:

  • (Boolean)

184
185
186
187
188
189
190
191
# File 'lib/guard/plugin_util.rb', line 184

def _gem_valid?(gem)
  return false if gem.name == "guard-compat"
  return true if gem.name =~ /^guard-/

  full_path = gem.full_gem_path
  file = File.join(full_path, "lib", "guard", "#{gem.name}.rb")
  File.exist?(file)
end

.plugin_namesArray<String>

Returns a list of Guard plugin Gem names installed locally.

Returns:

  • (Array<String>)

    a list of Guard plugin gem names


26
27
28
29
30
31
32
# File 'lib/guard/plugin_util.rb', line 26

def self.plugin_names
  valid = Gem::Specification.find_all.select do |gem|
    _gem_valid?(gem)
  end

  valid.map { |x| x.name.sub(/^guard-/, "") }.uniq
end

Instance Method Details

#add_to_guardfileObject

Adds a plugin's template to the Guardfile.


128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/guard/plugin_util.rb', line 128

def add_to_guardfile
  klass = plugin_class # call here to avoid failing later

  require_relative "guardfile/evaluator"
  # TODO: move this to Generator?
  options = Guard.state.session.evaluator_options
  evaluator = Guardfile::Evaluator.new(options)
  begin
    evaluator.evaluate
  rescue Guard::Guardfile::Evaluator::NoPluginsError
  end

  if evaluator.guardfile_include?(name)
    UI.info "Guardfile already includes #{name} guard"
  else
    content = File.read("Guardfile")
    File.open("Guardfile", "wb") do |f|
      f.puts(content)
      f.puts("")
      f.puts(klass.template(plugin_location))
    end

    UI.info INFO_ADDED_GUARD_TO_GUARDFILE % name
  end
end

#initialize_plugin(options) ⇒ Guard::Plugin, Guard::Guard

Initializes a new Guard::Plugin with the given options hash. This methods handles plugins that inherit from the deprecated Guard::Guard class as well as plugins that inherit from Guard::Plugin.

upgrade for Guard 2.0

Returns:

See Also:


57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/guard/plugin_util.rb', line 57

def initialize_plugin(options)
  klass = plugin_class
  fail "Could not load class: #{_constant_name.inspect}" unless klass

  if klass.ancestors.include?(Guard)
    klass.new(options.delete(:watchers), options)
  else
    begin
      klass.new(options)
    rescue ArgumentError => e
      fail "Failed to call #{klass}.new(options): #{e}"
    end
  end
end

#plugin_class(options = {}) ⇒ Class?

Tries to load the Guard plugin main class. This transforms the supplied plugin name into a class name:

  • guardname will become Guard::Guardname
  • dashed-guard-name will become Guard::DashedGuardName
  • underscore_guard_name will become Guard::UnderscoreGuardName

When no class is found with the strict case sensitive rules, another try is made to locate the class without matching case:

  • rspec will find a class Guard::RSpec

not be printed

Parameters:

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • fail_gracefully (Boolean)

    whether error messages should

Returns:

  • (Class, nil)

    the loaded class


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
# File 'lib/guard/plugin_util.rb', line 99

def plugin_class(options = {})
  options = { fail_gracefully: false }.merge(options)

  const = _plugin_constant
  fail TypeError, "no constant: #{_constant_name}" unless const

  @plugin_class ||= Guard.const_get(const)
rescue TypeError
  begin
    require "guard/#{name.downcase}"
    const = _plugin_constant
    @plugin_class ||= Guard.const_get(const)
  rescue TypeError => e
    UI.error "Could not find class Guard::#{_constant_name}"
    UI.error e.backtrace.join("\n")
    # TODO: return value or move exception higher
  rescue LoadError => e
    unless options[:fail_gracefully]
      msg = format(ERROR_NO_GUARD_OR_CLASS, name.downcase, _constant_name)
      UI.error(msg)
      UI.error("Error is: #{e}")
      UI.error(e.backtrace.join("\n"))
      # TODO: return value or move exception higher
    end
  end
end

#plugin_locationString

Locates a path to a Guard plugin gem.

Returns:

  • (String)

    the full path to the plugin gem


76
77
78
79
80
# File 'lib/guard/plugin_util.rb', line 76

def plugin_location
  @plugin_location ||= _full_gem_path("guard-#{name}")
rescue Gem::LoadError
  UI.error "Could not find 'guard-#{name}' gem path."
end