File: generator.rb

package info (click to toggle)
ruby-guard 2.18.1-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,344 kB
  • sloc: ruby: 9,256; makefile: 6
file content (128 lines) | stat: -rw-r--r-- 3,562 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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
require "guard/ui"
require "guard/plugin_util"

# Add Pathname#binwrite to 1.9.3
unless Pathname.instance_methods.include?(:binwrite)
  class Pathname
    def binwrite(*args)
      IO.binwrite(to_s, *args)
    end
  end
end

module Guard
  module Guardfile
    # This class is responsible for generating the Guardfile and adding Guard'
    # plugins' templates into it.
    #
    # @see Guard::CLI
    #
    class Generator
      require "guard"
      require "guard/ui"

      INFO_TEMPLATE_ADDED =
        "%s template added to Guardfile, feel free to edit it"

      # The Guardfile template for `guard init`
      GUARDFILE_TEMPLATE = File.expand_path(
        "../../../guard/templates/Guardfile",
        __FILE__
      )

      # The location of user defined templates
      begin
        HOME_TEMPLATES = Pathname.new("~/.guard/templates").expand_path
      rescue ArgumentError
        # home isn't defined.  Set to the root of the drive.  Trust that there
        # won't be user defined templates there
        HOME_TEMPLATES = Pathname.new("/").expand_path
      end

      class Error < RuntimeError
      end

      class NoSuchPlugin < Error
        attr_reader :plugin_name, :class_name

        def initialize(plugin_name)
          @plugin_name = plugin_name
          @class_name = plugin_name.delete("-").capitalize
        end

        def message
          "Could not load 'guard/#{plugin_name}'"\
          " or '~/.guard/templates/#{plugin_name}'"\
          " or find class Guard::#{class_name}\n"
        end
      end

      # Creates the initial Guardfile template when it does not
      # already exist.
      #
      # @see Guard::CLI#init
      #
      def create_guardfile
        path = Pathname.new("Guardfile").expand_path
        if path.exist?
          _ui(:error, "Guardfile already exists at #{path}")
          abort
        end

        _ui(:info, "Writing new Guardfile to #{path}")
        FileUtils.cp(GUARDFILE_TEMPLATE, path.to_s)
      end

      # Adds the Guardfile template of a Guard plugin to an existing Guardfile.
      #
      # @see Guard::CLI#init
      #
      # @param [String] plugin_name the name of the Guard plugin or template to
      #   initialize
      #
      def initialize_template(plugin_name)
        guardfile = Pathname.new("Guardfile")

        plugin_util = PluginUtil.new(plugin_name)
        # TODO: change to "valid?" method
        plugin_class = plugin_util.plugin_class(fail_gracefully: true)
        if plugin_class
          begin
            plugin_util.add_to_guardfile
          rescue Errno::ENOENT => error
            # TODO: refactor
            template = plugin_class.template(plugin_util.plugin_location)
            _ui(:error, "Found class #{plugin_class} but loading it's template"\
              "failed: '#{template}'")
            _ui(:error, "Error is: #{error}")
            return
          end
          return
        end

        template_code = (HOME_TEMPLATES + plugin_name).read
        guardfile.binwrite(format("\n%s\n", template_code), open_args: ["a"])

        _ui(:info, format(INFO_TEMPLATE_ADDED, plugin_name))

      rescue Errno::ENOENT
        fail NoSuchPlugin, plugin_name.downcase
      end

      # Adds the templates of all installed Guard implementations to an
      # existing Guardfile.
      #
      # @see Guard::CLI#init
      #
      def initialize_all_templates
        PluginUtil.plugin_names.each { |g| initialize_template(g) }
      end

      private

      def _ui(*args)
        UI.send(*args)
      end
    end
  end
end