summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAsutosh Palai <asupalai@gmail.com>2016-05-20 14:06:28 +0530
committerAsutosh Palai <asupalai@gmail.com>2016-05-24 21:15:01 +0530
commit011c69901ae3a103ec91385378f3df70b0f778d2 (patch)
treea5da1887f763a3ba63df38e676835ac323b87696
parentdbad52b5b477936b25c2c5605247a9e70a0796cb (diff)
downloadbundler-011c69901ae3a103ec91385378f3df70b0f778d2.tar.gz
Added plugin module with install functionality
-rw-r--r--lib/bundler.rb1
-rw-r--r--lib/bundler/cli.rb4
-rw-r--r--lib/bundler/cli/plugin.rb18
-rw-r--r--lib/bundler/plugin.rb34
-rw-r--r--lib/bundler/plugin/installer.rb49
-rw-r--r--lib/bundler/source/rubygems.rb5
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