diff options
author | Asutosh Palai <asupalai@gmail.com> | 2016-05-20 14:06:28 +0530 |
---|---|---|
committer | Asutosh Palai <asupalai@gmail.com> | 2016-05-24 21:15:01 +0530 |
commit | 011c69901ae3a103ec91385378f3df70b0f778d2 (patch) | |
tree | a5da1887f763a3ba63df38e676835ac323b87696 | |
parent | dbad52b5b477936b25c2c5605247a9e70a0796cb (diff) | |
download | bundler-011c69901ae3a103ec91385378f3df70b0f778d2.tar.gz |
Added plugin module with install functionality
-rw-r--r-- | lib/bundler.rb | 1 | ||||
-rw-r--r-- | lib/bundler/cli.rb | 4 | ||||
-rw-r--r-- | lib/bundler/cli/plugin.rb | 18 | ||||
-rw-r--r-- | lib/bundler/plugin.rb | 34 | ||||
-rw-r--r-- | lib/bundler/plugin/installer.rb | 49 | ||||
-rw-r--r-- | lib/bundler/source/rubygems.rb | 5 |
6 files changed, 109 insertions, 2 deletions
diff --git a/lib/bundler.rb b/lib/bundler.rb index ace1e7f3c4..45d735daa2 100644 --- a/lib/bundler.rb +++ b/lib/bundler.rb @@ -38,6 +38,7 @@ module Bundler autoload :MatchPlatform, "bundler/match_platform" autoload :Mirror, "bundler/mirror" autoload :Mirrors, "bundler/mirror" + autoload :Plugin, "bundler/plugin" autoload :RemoteSpecification, "bundler/remote_specification" autoload :Resolver, "bundler/resolver" autoload :Retry, "bundler/retry" diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb index f2af5d71f7..75d4581e12 100644 --- a/lib/bundler/cli.rb +++ b/lib/bundler/cli.rb @@ -433,6 +433,10 @@ module Bundler Env.new.write($stdout) end + require "bundler/cli/plugin" + desc "plugin SUBCOMMAND ...ARGS", "manage the bundler plugins" + subcommand "plugin", Plugin + # Reformat the arguments passed to bundle that include a --help flag # into the corresponding `bundle help #{command}` call def self.reformatted_help_args(args) diff --git a/lib/bundler/cli/plugin.rb b/lib/bundler/cli/plugin.rb new file mode 100644 index 0000000000..504f8726f9 --- /dev/null +++ b/lib/bundler/cli/plugin.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true +require "bundler/vendored_thor" +module Bundler + class CLI::Plugin < Thor + + desc "install PLUGIN", "Install the plugin from the source" + long_desc <<-D + Install a plugin named PLUGIN wither from the rubygems source provided (with --source option) or from a git source provided with (--git option). + D + method_option "source", :type=> :string, :default => nil, :banner => + "Url of the RubyGems source to fetch the plugin from" + method_option "version", :type=> :string, :default => nil, :banner => + "The version of the plugin to fetch from" + def install(plugin) + Bundler::Plugin.install(plugin, options) + end + end +end diff --git a/lib/bundler/plugin.rb b/lib/bundler/plugin.rb new file mode 100644 index 0000000000..364401ded1 --- /dev/null +++ b/lib/bundler/plugin.rb @@ -0,0 +1,34 @@ +#frozen_string_literal: true + +module Bundler + class Plugin + + class << self + + def install(name, options) + require "bundler/plugin/installer.rb" + + source = options[:source] || raise(ArgumentError, "You need to provide the source") + version = options[:version] || [">= 0"] + + plugin_path = Installer.install(name, source, version) + + puts plugin_path + + Bundler.ui.info "Installed plugin #{name}" + rescue StandardError => e + Bundler.ui.error "Failed to install plugin #{name}: #{e.message}\n #{e.backtrace.join("\n ")}" + Bundler.ui.trace e + end + + + def root + @root ||= Bundler.user_bundle_path.join("plugin") + end + + def cache + @cache ||= root.join "cache" + end + end + end +end diff --git a/lib/bundler/plugin/installer.rb b/lib/bundler/plugin/installer.rb new file mode 100644 index 0000000000..8477ffad2c --- /dev/null +++ b/lib/bundler/plugin/installer.rb @@ -0,0 +1,49 @@ +#frozen_string_literal: true + +module Bundler + class Plugin::Installer + + # Installs the plugin and returns the path where the plugin was installed + def self.install(name, source, version = nil) + rg_source = Source::Rubygems.new "remotes" => source, :ignore_app_cache => true + rg_source.remote! + rg_source.dependency_names << name + + dep = Dependency.new name, version + + deps_proxies = [DepProxy.new(dep, GemHelpers.generic_local_platform)] + idx = rg_source.specs + + specs = Resolver.resolve(deps_proxies, idx).materialize([dep]) + + raise InstallError, "Plugin dependencies are not supported currently" unless specs.size == 1 + + install_from_spec specs.first + end + + + # Installs the plugin from the provided spec and returns the path where the plugin was installed + def self.install_from_spec(spec) + raise ArgumentError, "Spec #{spec.name} doesn't have remote set" unless spec.remote + + uri = spec.remote.uri + spec.fetch_platform + + download_path = Plugin.cache + + path = Bundler.rubygems.download_gem(spec, uri, download_path) + + Bundler.rubygems.preserve_paths do + Bundler::RubyGemsGemInstaller.new( + path, + :install_dir => Plugin.root.to_s, + :ignore_dependencies => true, + :wrappers => true, + :env_shebang => true + + ).install.full_gem_path + end + end + + end +end diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb index d8ca36e3f9..33e0e0be3f 100644 --- a/lib/bundler/source/rubygems.rb +++ b/lib/bundler/source/rubygems.rb @@ -21,7 +21,8 @@ module Bundler @dependency_names = [] @allow_remote = false @allow_cached = false - @caches = [Bundler.app_cache, *Bundler.rubygems.gem_cache] + @caches = [*Bundler.rubygems.gem_cache] + @caches << Bundler.app_cache unless options[:ignore_app_cache] # To use this class for installing plugins Array(options["remotes"] || []).reverse_each {|r| add_remote(r) } end @@ -80,7 +81,7 @@ module Bundler # sources, and large_idx.use small_idx is way faster than # small_idx.use large_idx. idx = @allow_remote ? remote_specs.dup : Index.new - idx.use(cached_specs, :override_dupes) if @allow_cached || @allow_remote + idx.use(cached_specs, :override_dupes) if @allow_cached || @allow_remote && !@options[:ignore_app_cache] idx.use(installed_specs, :override_dupes) idx end |