diff options
Diffstat (limited to 'lib/bundler/plugin')
| -rw-r--r-- | lib/bundler/plugin/api/source.rb | 14 | ||||
| -rw-r--r-- | lib/bundler/plugin/events.rb | 24 | ||||
| -rw-r--r-- | lib/bundler/plugin/index.rb | 14 | ||||
| -rw-r--r-- | lib/bundler/plugin/installer.rb | 55 | ||||
| -rw-r--r-- | lib/bundler/plugin/installer/path.rb | 26 | ||||
| -rw-r--r-- | lib/bundler/plugin/source_list.rb | 10 |
6 files changed, 110 insertions, 33 deletions
diff --git a/lib/bundler/plugin/api/source.rb b/lib/bundler/plugin/api/source.rb index 67c45bd204..6c888d0373 100644 --- a/lib/bundler/plugin/api/source.rb +++ b/lib/bundler/plugin/api/source.rb @@ -39,7 +39,7 @@ module Bundler # is present to be compatible with `Definition` and is used by # rubygems source. module Source - attr_reader :uri, :options, :name + attr_reader :uri, :options, :name, :checksum_store attr_accessor :dependency_names def initialize(opts) @@ -48,6 +48,7 @@ module Bundler @uri = opts["uri"] @type = opts["type"] @name = opts["name"] || "#{@type} at #{@uri}" + @checksum_store = Checksum::Store.new end # This is used by the default `spec` method to constructs the @@ -66,7 +67,7 @@ module Bundler # to check out same version of gem later. # # There options are passed when the source plugin is created from the - # lock file. + # lockfile. # # @return [Hash] def options_to_lock @@ -95,7 +96,7 @@ module Bundler # # Note: Do not override if you don't know what you are doing. def post_install(spec, disable_exts = false) - opts = { :env_shebang => false, :disable_extensions => disable_exts } + opts = { env_shebang: false, disable_extensions: disable_exts } installer = Bundler::Source::Path::Installer.new(spec, opts) installer.post_install end @@ -106,7 +107,7 @@ module Bundler def install_path @install_path ||= begin - base_name = File.basename(Bundler::URI.parse(uri).normalize.path) + base_name = File.basename(Gem::URI.parse(uri).normalize.path) gem_install_dir.join("#{base_name}-#{uri_hash[0..11]}") end @@ -130,7 +131,7 @@ module Bundler Bundler::Index.build do |index| files.each do |file| next unless spec = Bundler.load_gemspec(file) - Bundler.rubygems.set_installed_by_version(spec) + spec.installed_by_version = Gem::VERSION spec.source = self Bundler.rubygems.validate(spec) @@ -175,7 +176,7 @@ module Bundler # # This is used by `app_cache_path` def app_cache_dirname - base_name = File.basename(Bundler::URI.parse(uri).normalize.path) + base_name = File.basename(Gem::URI.parse(uri).normalize.path) "#{base_name}-#{uri_hash}" end @@ -195,6 +196,7 @@ module Bundler FileUtils.rm_rf(new_cache_path) FileUtils.cp_r(install_path, new_cache_path) + FileUtils.rm_rf(app_cache_path.join(".git")) FileUtils.touch(app_cache_path.join(".bundlecache")) end diff --git a/lib/bundler/plugin/events.rb b/lib/bundler/plugin/events.rb index bc037d1af5..29c05098ae 100644 --- a/lib/bundler/plugin/events.rb +++ b/lib/bundler/plugin/events.rb @@ -56,6 +56,30 @@ module Bundler # Includes an Array of Bundler::Dependency objects # GEM_AFTER_INSTALL_ALL = "after-install-all" define :GEM_AFTER_INSTALL_ALL, "after-install-all" + + # @!parse + # A hook called before each individual gem is required + # Includes a Bundler::Dependency. + # GEM_BEFORE_REQUIRE = "before-require" + define :GEM_BEFORE_REQUIRE, "before-require" + + # @!parse + # A hook called after each individual gem is required + # Includes a Bundler::Dependency. + # GEM_AFTER_REQUIRE = "after-require" + define :GEM_AFTER_REQUIRE, "after-require" + + # @!parse + # A hook called before any gems require + # Includes an Array of Bundler::Dependency objects. + # GEM_BEFORE_REQUIRE_ALL = "before-require-all" + define :GEM_BEFORE_REQUIRE_ALL, "before-require-all" + + # @!parse + # A hook called after all gems required + # Includes an Array of Bundler::Dependency objects. + # GEM_AFTER_REQUIRE_ALL = "after-require-all" + define :GEM_AFTER_REQUIRE_ALL, "after-require-all" end end end diff --git a/lib/bundler/plugin/index.rb b/lib/bundler/plugin/index.rb index a2d5eaa38a..0682d37772 100644 --- a/lib/bundler/plugin/index.rb +++ b/lib/bundler/plugin/index.rb @@ -31,9 +31,13 @@ module Bundler begin load_index(global_index_file, true) - rescue GenericSystemCallError + rescue PermissionError # no need to fail when on a read-only FS, for example nil + rescue ArgumentError => e + # ruby 3.4 checks writability in Dir.tmpdir + raise unless e.message&.include?("could not find a temporary directory") + nil end load_index(local_index_file) if SharedHelpers.in_bundle? end @@ -136,6 +140,14 @@ module Bundler @hooks[event] || [] end + # This plugin is installed inside the .bundle/plugin directory, + # and thus is managed solely by Bundler + def installed_in_plugin_root?(name) + return false unless (path = installed?(name)) + + path.start_with?("#{Plugin.root}/") + end + private # Reads the index file from the directory and initializes the instance diff --git a/lib/bundler/plugin/installer.rb b/lib/bundler/plugin/installer.rb index 81ecafa470..853ad9edca 100644 --- a/lib/bundler/plugin/installer.rb +++ b/lib/bundler/plugin/installer.rb @@ -10,6 +10,7 @@ module Bundler class Installer autoload :Rubygems, File.expand_path("installer/rubygems", __dir__) autoload :Git, File.expand_path("installer/git", __dir__) + autoload :Path, File.expand_path("installer/path", __dir__) def install(names, options) check_sources_consistency!(options) @@ -18,8 +19,8 @@ module Bundler if options[:git] install_git(names, version, options) - elsif options[:local_git] - install_local_git(names, version, options) + elsif options[:path] + install_path(names, version, options[:path]) else sources = options[:source] || Gem.sources install_rubygems(names, version, sources) @@ -33,7 +34,7 @@ module Bundler # @return [Hash] map of names to their specs they are installed with def install_definition(definition) def definition.lock(*); end - definition.resolve_remotely! + definition.remotely! specs = definition.specs install_from_specs specs @@ -42,23 +43,33 @@ module Bundler private def check_sources_consistency!(options) - if options.key?(:git) && options.key?(:local_git) - raise InvalidOption, "Remote and local plugin git sources can't be both specified" + if (options.keys & [:source, :git, :path]).length > 1 + raise InvalidOption, "Only one of --source, --git, or --path may be specified" + end + + if (options.key?(:branch) || options.key?(:ref)) && !options.key?(:git) + raise InvalidOption, "--#{options.key?(:branch) ? "branch" : "ref"} can only be used with git sources" + end + + if options.key?(:branch) && options.key?(:ref) + raise InvalidOption, "--branch and --ref can't be both specified" end end def install_git(names, version, options) - uri = options.delete(:git) - options["uri"] = uri + source_list = SourceList.new + source = source_list.add_git_source({ "uri" => options[:git], + "branch" => options[:branch], + "ref" => options[:ref] }) - install_all_sources(names, version, options, options[:source]) + install_all_sources(names, version, source_list, source) end - def install_local_git(names, version, options) - uri = options.delete(:local_git) - options["uri"] = uri + def install_path(names, version, path) + source_list = SourceList.new + source = source_list.add_path_source({ "path" => path, "root_path" => SharedHelpers.pwd }) - install_all_sources(names, version, options, options[:source]) + install_all_sources(names, version, source_list, source) end # Installs the plugin from rubygems source and returns the path where the @@ -70,21 +81,23 @@ module Bundler # # @return [Hash] map of names to the specs of plugins installed def install_rubygems(names, version, sources) - install_all_sources(names, version, nil, sources) - end - - def install_all_sources(names, version, git_source_options, rubygems_source) source_list = SourceList.new - source_list.add_git_source(git_source_options) if git_source_options - Array(rubygems_source).each {|remote| source_list.add_global_rubygems_remote(remote) } if rubygems_source + Array(sources).each {|remote| source_list.add_global_rubygems_remote(remote) } + + install_all_sources(names, version, source_list) + end - deps = names.map {|name| Dependency.new name, version } + def install_all_sources(names, version, source_list, source = nil) + deps = names.map {|name| Dependency.new(name, version, { "source" => source }) } Bundler.configure_gem_home_and_path(Plugin.root) - definition = Definition.new(nil, deps, source_list, true) - install_definition(definition) + Bundler.settings.temporary(deployment: false, frozen: false) do + definition = Definition.new(nil, deps, source_list, true) + + install_definition(definition) + end end # Installs the plugins and deps from the provided specs and returns map of diff --git a/lib/bundler/plugin/installer/path.rb b/lib/bundler/plugin/installer/path.rb new file mode 100644 index 0000000000..58c4924eb0 --- /dev/null +++ b/lib/bundler/plugin/installer/path.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module Bundler + module Plugin + class Installer + class Path < Bundler::Source::Path + def root + SharedHelpers.in_bundle? ? Bundler.root : Plugin.root + end + + def eql?(other) + return unless other.class == self.class + expanded_original_path == other.expanded_original_path && + version == other.version + end + + alias_method :==, :eql? + + def generate_bin(spec, disable_extensions = false) + # Need to find a way without code duplication + # For now, we can ignore this + end + end + end + end +end diff --git a/lib/bundler/plugin/source_list.rb b/lib/bundler/plugin/source_list.rb index 547661cf2f..d929ade29e 100644 --- a/lib/bundler/plugin/source_list.rb +++ b/lib/bundler/plugin/source_list.rb @@ -9,6 +9,10 @@ module Bundler add_source_to_list Plugin::Installer::Git.new(options), git_sources end + def add_path_source(options = {}) + add_source_to_list Plugin::Installer::Path.new(options), path_sources + end + def add_rubygems_source(options = {}) add_source_to_list Plugin::Installer::Rubygems.new(options), @rubygems_sources end @@ -17,13 +21,9 @@ module Bundler path_sources + git_sources + rubygems_sources + [metadata_source] end - def default_source - git_sources.first || global_rubygems_source - end - private - def rubygems_aggregate_class + def source_class Plugin::Installer::Rubygems end end |
