aboutsummaryrefslogtreecommitdiffstats
path: root/lib/bundler/plugin.rb
blob: 1421b6fdcb59b152d544e6629505ab7df81a2ae3 (plain)
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
# frozen_string_literal: true

module Bundler
  class Plugin
    autoload :Dsl,        "bundler/plugin/dsl"
    autoload :Index,      "bundler/plugin/index"
    autoload :Installer,  "bundler/plugin/installer"
    autoload :SourceList, "bundler/plugin/source_list"

    class << self
      # Installs a new plugin by the given name
      #
      # @param [String] name the name of plugin to be installed
      # @param [Hash] options various parameters as described in description
      # @option options [String] :source rubygems source to fetch the plugin gem from
      # @option options [String] :version (optional) the version of the plugin to install
      def install(name, options)
        plugin_path = Pathname.new Installer.new.install(name, options)

        validate_plugin! plugin_path

        register_plugin name, plugin_path

        Bundler.ui.info "Installed plugin #{name}"
      rescue StandardError => e
        Bundler.rm_rf(plugin_path) if plugin_path
        Bundler.ui.error "Failed to install plugin #{name}: #{e.message}\n  #{e.backtrace.join("\n  ")}"
      end

      def eval_gemfile(gemfile)
        definition = Dsl.evaluate(gemfile, nil, {})
        return unless definition.dependencies.any?

        plugins = Installer.new.install_definition(definition)

        plugins.each do |name, path|
          path = Pathname.new path
          validate_plugin! path
          register_plugin name, path
          Bundler.ui.info "Installed plugin #{name}"
        end
      end

      # The index object used to store the details about the plugin
      def index
        @index ||= Index.new
      end

      # The directory root to all plugin related data
      def root
        @root ||= Bundler.user_bundle_path.join("plugin")
      end

      # The cache directory for plugin stuffs
      def cache
        @cache ||= root.join("cache")
      end

    private

      # Checks if the gem is good to be a plugin
      #
      # At present it only checks whether it contains plugin.rb file
      #
      # @param [Pathname] plugin_path the path plugin is installed at
      #
      # @raise [Error] if plugin.rb file is not found
      def validate_plugin!(plugin_path)
        plugin_file = plugin_path.join("plugin.rb")
        raise "plugin.rb was not found in the plugin!" unless plugin_file.file?
      end

      # Runs the plugin.rb file, records the plugin actions it registers for and
      # then passes the data to index to be stored
      #
      # @param [String] name the name of the plugin
      # @param [Pathname] path the path where the plugin is installed at
      def register_plugin(name, path)
        require path.join("plugin.rb") # this shall latter be used to find the actions the plugin performs

        index.register_plugin name, path.to_s
      end
    end
  end
end