Coveralls logob
Coveralls logo
  • Home
  • Features
  • Pricing
  • Docs
  • Sign In

guard / guard / 1459

13 Jan 2015 - 1:05 coverage decreased (-0.2%) to 95.448%
1459

Pull #724

travis-ci

4658fff974e40b29dae3a63001c30f70?size=18&default=identicontrayo
Fixed a typo
Pull Request #724: Fixed a typo

5200 of 5448 relevant lines covered (95.45%)

14.2 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

89.71
/lib/guard/plugin_util.rb
1
require "guard/ui"
5×
2

3
module Guard
5×
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
5×
12
    ERROR_NO_GUARD_OR_CLASS = "Could not load 'guard/%s' or'\
5×
13
    ' find class Guard::%s"
14

15
    INFO_ADDED_GUARD_TO_GUARDFILE = "%s guard added to Guardfile,"\
5×
16
      " feel free to edit it"
17

18
    attr_accessor :name
5×
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
5×
25
      valid = Gem::Specification.find_all.select do |gem|
all except jruby and rbx - 9×
26
        _gem_valid?(gem)
all except jruby and rbx - 36×
27
      end
28

29
      valid.map { |x| x.name.sub(/^guard-/, "") }.uniq
all except jruby and rbx - 27×
30
    end
31

32
    # Initializes a new `Guard::PluginUtil` object.
33
    #
34
    # @param [String] name the name of the Guard plugin
35
    #
36
    def initialize(name)
5×
37
      @name = name.to_s.sub(/^guard-/, "")
all except jruby and rbx - 42×
38
    end
39

40
    # Initializes a new `Guard::Plugin` with the given `options` hash. This
41
    # methods handles plugins that inherit from the deprecated `Guard::Guard`
42
    # class as well as plugins that inherit from `Guard::Plugin`.
43
    #
44
    # @see Guard::Plugin
45
    # @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
46
    # upgrade for Guard 2.0
47
    #
48
    # @return [Guard::Plugin] the initialized plugin
49
    # @return [Guard::Guard] the initialized plugin. This return type is
50
    #   deprecated and the plugin's maintainer should update it to be
51
    #   compatible with Guard 2.0. For more information on how to upgrade for
52
    #   Guard 2.0, please head over to:
53
    #   https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0
54
    #
55
    def initialize_plugin(options)
5×
56
      klass = plugin_class
all except jruby and rbx - 3×
57
      fail "Could not load class: #{_constant_name.inspect}" unless klass
all except jruby and rbx - 3×
58
      if klass.superclass.to_s == "Guard::Guard"
all except jruby and rbx - 3×
59
        klass.new(options.delete(:watchers), options)
!
60
      else
61
        begin
all except jruby and rbx - 3×
62
          klass.new(options)
all except jruby and rbx - 3×
63
        rescue ArgumentError => e
!
64
          fail "Failed to call #{klass}.new(options): #{e}"
!
65
        end
66
      end
67
    end
68

69
    # Locates a path to a Guard plugin gem.
70
    #
71
    # @return [String] the full path to the plugin gem
72
    #
73
    def plugin_location
5×
74
      @plugin_location ||= _full_gem_path("guard-#{name}")
all except jruby and rbx - 6×
75
    rescue Gem::LoadError
76
      UI.error "Could not find 'guard-#{ name }' gem path."
!
77
    end
78

79
    # Tries to load the Guard plugin main class. This transforms the supplied
80
    # plugin name into a class name:
81
    #
82
    # * `guardname` will become `Guard::Guardname`
83
    # * `dashed-guard-name` will become `Guard::DashedGuardName`
84
    # * `underscore_guard_name` will become `Guard::UnderscoreGuardName`
85
    #
86
    # When no class is found with the strict case sensitive rules, another
87
    # try is made to locate the class without matching case:
88
    #
89
    # * `rspec` will find a class `Guard::RSpec`
90
    #
91
    # @option options [Boolean] fail_gracefully whether error messages should
92
    # not be printed
93
    #
94
    # @return [Class, nil] the loaded class
95
    #
96
    def plugin_class(options = {})
5×
97
      options = { fail_gracefully: false }.merge(options)
all except jruby and rbx - 30×
98

99
      const = _plugin_constant
all except jruby and rbx - 30×
100
      fail TypeError, "no constant: #{_constant_name}" unless const
all except jruby and rbx - 30×
101
      @plugin_class ||= Guard.const_get(const)
all except jruby and rbx - 6×
102

103
    rescue TypeError
104
      begin
all except jruby and rbx - 24×
105
        require "guard/#{ name.downcase }"
all except jruby and rbx - 24×
106
        const = _plugin_constant
all except jruby and rbx - 15×
107
        @plugin_class ||= Guard.const_get(const)
all except jruby and rbx - 15×
108

109
      rescue TypeError => error
110
        UI.error "Could not find class Guard::#{ _constant_name }"
!
111
        UI.error error.backtrace.join("\n")
!
112
      rescue LoadError => error
113
        unless options[:fail_gracefully]
all except jruby and rbx - 9×
114
          UI.error ERROR_NO_GUARD_OR_CLASS % [name.downcase, _constant_name]
all except jruby and rbx - 6×
115
          UI.error "Error is: #{error}"
all except jruby and rbx - 6×
116
          UI.error error.backtrace.join("\n")
all except jruby and rbx - 6×
117
        end
118
      end
119
    end
120

121
    # Adds a plugin's template to the Guardfile.
122
    #
123
    def add_to_guardfile
5×
124
      klass = plugin_class # call here to avoid failing later
all except jruby and rbx - 6×
125

126
      require "guard/guardfile/evaluator"
all except jruby and rbx - 6×
127
      # TODO: move this to Generator?
128
      options = Guard.state.session.evaluator_options
all except jruby and rbx - 6×
129
      evaluator = Guardfile::Evaluator.new(options)
all except jruby and rbx - 6×
130
      evaluator.evaluate
all except jruby and rbx - 6×
131
      if evaluator.guardfile_include?(name)
all except jruby and rbx - 6×
132
        UI.info "Guardfile already includes #{ name } guard"
all except jruby and rbx - 3×
133
      else
134
        content = File.read("Guardfile")
all except jruby and rbx - 3×
135
        File.open("Guardfile", "wb") do |f|
all except jruby and rbx - 3×
136
          f.puts(content)
all except jruby and rbx - 3×
137
          f.puts("")
all except jruby and rbx - 3×
138
          f.puts(klass.template(plugin_location))
all except jruby and rbx - 3×
139
        end
140

141
        UI.info INFO_ADDED_GUARD_TO_GUARDFILE % name
all except jruby and rbx - 3×
142
      end
143
    end
144

145
    private
5×
146

147
    # Returns the constant for the current plugin.
148
    #
149
    # @example Returns the constant for a plugin
150
    #   > Guard::PluginUtil.new('rspec').send(:_plugin_constant)
151
    #   => Guard::RSpec
152
    #
153
    def _plugin_constant
5×
UNCOV
154
      @_plugin_constant ||= Guard.constants.detect do |c|
!
155
        c.to_s.downcase == _constant_name.downcase
all except jruby and rbx - 879×
156
      end
all except jruby and rbx - 45×
157
    end
158

159
    # Guesses the most probable name for the current plugin based on its name.
160
    #
161
    # @example Returns the most probable name for a plugin
162
    #   > Guard::PluginUtil.new('rspec').send(:_constant_name)
163
    #   => "Rspec"
164
    #
165
    def _constant_name
5×
UNCOV
166
      @_constant_name ||= name.gsub(/\/(.?)/) { "::#{ $1.upcase }" }.
!
167
        gsub(/(?:^|[_-])(.)/) { $1.upcase }
all except jruby and rbx - 951×
168
    end
169

170
    def self._gem_valid?(gem)
5×
171
      return false if gem.name == "guard-compat"
all except jruby and rbx - 36×
172
      return true if gem.name =~ /^guard-/
all except jruby and rbx - 27×
173
      full_path = gem.full_gem_path
all except jruby and rbx - 18×
174
      file = File.join(full_path, "lib", "guard", "#{gem.name}.rb")
all except jruby and rbx - 18×
175
      File.exist?(file)
all except jruby and rbx - 18×
176
    end
177

178
    def _full_gem_path(name)
5×
179
      Gem::Specification.find_by_name(name).full_gem_path
all except jruby and rbx - 6×
180
    end
181
  end
182
end
Troubleshooting · Open an Issue · Sales · Support · ENTERPRISE · CAREERS · STATUS
BLOG · TWITTER · Legal & Privacy · Supported CI Services · What's a CI service? · Automated Testing

© 2022 Coveralls, Inc