1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
This commit is contained in:
Hiroshi SHIBATA 2022-09-05 09:15:30 +09:00
parent 3767c6a90d
commit 3eca1e438d
Notes: git 2022-09-05 14:37:35 +09:00
69 changed files with 502 additions and 834 deletions

View file

@ -488,41 +488,9 @@ EOF
configured_bundle_path.use_system_gems?
end
def requires_sudo?
return @requires_sudo if defined?(@requires_sudo_ran)
sudo_present = which "sudo" if settings.allow_sudo?
if sudo_present
# the bundle path and subdirectories need to be writable for RubyGems
# to be able to unpack and install gems without exploding
path = bundle_path
path = path.parent until path.exist?
# bins are written to a different location on OS X
bin_dir = Pathname.new(Bundler.system_bindir)
bin_dir = bin_dir.parent until bin_dir.exist?
# if any directory is not writable, we need sudo
files = [path, bin_dir] | Dir[bundle_path.join("build_info/*").to_s] | Dir[bundle_path.join("*").to_s]
unwritable_files = files.reject {|f| File.writable?(f) }
sudo_needed = !unwritable_files.empty?
if sudo_needed
Bundler.ui.warn "Following files may not be writable, so sudo is needed:\n #{unwritable_files.map(&:to_s).sort.join("\n ")}"
end
end
@requires_sudo_ran = true
@requires_sudo = settings.allow_sudo? && sudo_present && sudo_needed
end
def mkdir_p(path, options = {})
if requires_sudo? && !options[:no_sudo]
sudo "mkdir -p '#{path}'" unless File.exist?(path)
else
SharedHelpers.filesystem_access(path, :write) do |p|
FileUtils.mkdir_p(p)
end
SharedHelpers.filesystem_access(path, :write) do |p|
FileUtils.mkdir_p(p)
end
end
@ -539,31 +507,6 @@ EOF
end
end
def sudo(str)
SUDO_MUTEX.synchronize do
prompt = "\n\n" + <<-PROMPT.gsub(/^ {6}/, "").strip + " "
Your user account isn't allowed to install to the system RubyGems.
You can cancel this installation and run:
bundle config set --local path 'vendor/bundle'
bundle install
to install the gems into ./vendor/bundle/, or you can enter your password
and install the bundled gems to RubyGems using sudo.
Password:
PROMPT
unless @prompted_for_sudo ||= system(%(sudo -k -p "#{prompt}" true))
raise SudoNotPermittedError,
"Bundler requires sudo access to install at the moment. " \
"Try installing again, granting Bundler sudo access when prompted, or installing into a different path."
end
`sudo -p "#{prompt}" #{str}`
end
end
def read_file(file)
SharedHelpers.filesystem_access(file, :read) do
File.open(file, "r:UTF-8", &:read)

View file

@ -94,9 +94,8 @@ module Bundler
def warn_if_root
return if Bundler.settings[:silence_root_warning] || Gem.win_platform? || !Process.uid.zero?
Bundler.ui.warn "Don't run Bundler as root. Bundler can ask for sudo " \
"if it is needed, and installing your bundle as root will break this " \
"application for all non-root users on this machine.", :wrap => true
Bundler.ui.warn "Don't run Bundler as root. Installing your bundle as root " \
"will break this application for all non-root users on this machine.", :wrap => true
end
def dependencies_count_for(definition)

View file

@ -485,7 +485,7 @@ module Bundler
@resolver ||= begin
last_resolve = converge_locked_specs
remove_ruby_from_platforms_if_necessary!(dependencies)
Resolver.new(source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms)
Resolver.new(source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve(last_resolve), platforms)
end
end
@ -878,9 +878,9 @@ module Bundler
end
end
def additional_base_requirements_for_resolve
def additional_base_requirements_for_resolve(last_resolve)
return [] unless @locked_gems && unlocking? && !sources.expired_sources?(@locked_gems.sources)
converge_specs(@originally_locked_specs).map do |locked_spec|
converge_specs(@originally_locked_specs - last_resolve).map do |locked_spec|
Dependency.new(locked_spec.name, ">= #{locked_spec.version}")
end.uniq
end

View file

@ -55,7 +55,6 @@ module Bundler
class CyclicDependencyError < BundlerError; status_code(21); end
class GemfileLockNotFound < BundlerError; status_code(22); end
class PluginError < BundlerError; status_code(29); end
class SudoNotPermittedError < BundlerError; status_code(30); end
class ThreadCreationError < BundlerError; status_code(33); end
class APIResponseMismatchError < BundlerError; status_code(34); end
class APIResponseInvalidDependenciesError < BundlerError; status_code(35); end

View file

@ -39,7 +39,6 @@ module Bundler
settings_flag(:setup_makes_kernel_gem_public) { !bundler_3_mode? }
settings_flag(:suppress_install_using_messages) { bundler_3_mode? }
settings_flag(:update_requires_all_flag) { bundler_4_mode? }
settings_flag(:use_gem_version_promoter_for_major_updates) { bundler_3_mode? }
settings_option(:default_cli_command) { bundler_3_mode? ? :cli_help : :install }

View file

@ -55,19 +55,17 @@ module Bundler
@level = v
end
# Given a Dependency and an Array of SpecGroups of available versions for a
# gem, this method will return the Array of SpecGroups sorted (and possibly
# Given a Dependency and an Array of Specifications of available versions for a
# gem, this method will return the Array of Specifications sorted (and possibly
# truncated if strict is true) in an order to give preference to the current
# level (:major, :minor or :patch) when resolution is deciding what versions
# best resolve all dependencies in the bundle.
# @param dep [Dependency] The Dependency of the gem.
# @param spec_groups [SpecGroup] An array of SpecGroups for the same gem
# @param spec_groups [Specification] An array of Specifications for the same gem
# named in the @dep param.
# @return [SpecGroup] A new instance of the SpecGroup Array sorted and
# @return [Specification] A new instance of the Specification Array sorted and
# possibly filtered.
def sort_versions(dep, spec_groups)
before_result = "before sort_versions: #{debug_format_result(dep, spec_groups).inspect}" if DEBUG
@sort_versions[dep] ||= begin
gem_name = dep.name
@ -79,11 +77,6 @@ module Bundler
filter_dep_specs(spec_groups, locked_spec)
else
sort_dep_specs(spec_groups, locked_spec)
end.tap do |specs|
if DEBUG
puts before_result
puts " after sort_versions: #{debug_format_result(dep, specs).inspect}"
end
end
end
end
@ -183,12 +176,5 @@ module Bundler
move, keep = result.partition {|s| s.version.to_s == version.to_s }
keep.concat(move)
end
def debug_format_result(dep, spec_groups)
a = [dep.to_s,
spec_groups.map {|sg| [sg.version, sg.dependencies_for_activated_platforms.map {|dp| [dp.name, dp.requirement.to_s] }] }]
last_map = a.last.map {|sg_data| [sg_data.first.version, sg_data.last.map {|aa| aa.join(" ") }] }
[a.first, last_map, level, strict ? :strict : :not_strict]
end
end
end

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-ADD" "1" "July 2022" "" ""
.TH "BUNDLE\-ADD" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-BINSTUBS" "1" "July 2022" "" ""
.TH "BUNDLE\-BINSTUBS" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-binstubs\fR \- Install the binstubs of the listed gems

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-CACHE" "1" "July 2022" "" ""
.TH "BUNDLE\-CACHE" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-cache\fR \- Package your needed \fB\.gem\fR files into your application

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-CHECK" "1" "July 2022" "" ""
.TH "BUNDLE\-CHECK" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-check\fR \- Verifies if dependencies are satisfied by installed gems

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-CLEAN" "1" "July 2022" "" ""
.TH "BUNDLE\-CLEAN" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-clean\fR \- Cleans up unused gems in your bundler directory

View file

@ -1,13 +1,22 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-CONFIG" "1" "July 2022" "" ""
.TH "BUNDLE\-CONFIG" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-config\fR \- Set bundler configuration options
.
.SH "SYNOPSIS"
\fBbundle config\fR [list|get|set|unset] [\fIname\fR [\fIvalue\fR]]
\fBbundle config\fR list
.
.br
\fBbundle config\fR [get] NAME
.
.br
\fBbundle config\fR [set] NAME VALUE
.
.br
\fBbundle config\fR unset NAME
.
.SH "DESCRIPTION"
This command allows you to interact with Bundler\'s configuration system\.

View file

@ -3,7 +3,10 @@ bundle-config(1) -- Set bundler configuration options
## SYNOPSIS
`bundle config` [list|get|set|unset] [<name> [<value>]]
`bundle config` list<br>
`bundle config` [get] NAME<br>
`bundle config` [set] NAME VALUE<br>
`bundle config` unset NAME
## DESCRIPTION

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-DOCTOR" "1" "July 2022" "" ""
.TH "BUNDLE\-DOCTOR" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-doctor\fR \- Checks the bundle for common problems

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-EXEC" "1" "July 2022" "" ""
.TH "BUNDLE\-EXEC" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-exec\fR \- Execute a command in the context of the bundle

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-GEM" "1" "July 2022" "" ""
.TH "BUNDLE\-GEM" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-gem\fR \- Generate a project skeleton for creating a rubygem

View file

@ -0,0 +1,13 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-HELP" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-help\fR \- Displays detailed help for each subcommand
.
.SH "SYNOPSIS"
\fBbundle help\fR [COMMAND]
.
.SH "DESCRIPTION"
Displays detailed help for the given subcommand\. You can specify a single \fBCOMMAND\fR at the same time\. When \fBCOMMAND\fR is omitted, help for \fBhelp\fR command will be displayed\.

View file

@ -0,0 +1,12 @@
bundle-help(1) -- Displays detailed help for each subcommand
============================================================
## SYNOPSIS
`bundle help` [COMMAND]
## DESCRIPTION
Displays detailed help for the given subcommand.
You can specify a single `COMMAND` at the same time.
When `COMMAND` is omitted, help for `help` command will be displayed.

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-INFO" "1" "July 2022" "" ""
.TH "BUNDLE\-INFO" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-info\fR \- Show information for the given gem in your bundle

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-INIT" "1" "July 2022" "" ""
.TH "BUNDLE\-INIT" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-init\fR \- Generates a Gemfile into the current working directory

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-INJECT" "1" "July 2022" "" ""
.TH "BUNDLE\-INJECT" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-inject\fR \- Add named gem(s) with version requirements to Gemfile

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-INSTALL" "1" "July 2022" "" ""
.TH "BUNDLE\-INSTALL" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-install\fR \- Install the dependencies specified in your Gemfile
@ -170,35 +170,6 @@ As a result, \fBbundle install \-\-deployment\fR installs gems to the \fBvendor/
.
.IP "" 0
.
.SH "SUDO USAGE"
By default, Bundler installs gems to the same location as \fBgem install\fR\.
.
.P
In some cases, that location may not be writable by your Unix user\. In that case, Bundler will stage everything in a temporary directory, then ask you for your \fBsudo\fR password in order to copy the gems into their system location\.
.
.P
From your perspective, this is identical to installing the gems directly into the system\.
.
.P
You should never use \fBsudo bundle install\fR\. This is because several other steps in \fBbundle install\fR must be performed as the current user:
.
.IP "\(bu" 4
Updating your \fBGemfile\.lock\fR
.
.IP "\(bu" 4
Updating your \fBvendor/cache\fR, if necessary
.
.IP "\(bu" 4
Checking out private git repositories using your user\'s SSH keys
.
.IP "" 0
.
.P
Of these three, the first two could theoretically be performed by \fBchown\fRing the resulting files to \fB$SUDO_USER\fR\. The third, however, can only be performed by invoking the \fBgit\fR command as the current user\. Therefore, git gems are downloaded and installed into \fB~/\.bundle\fR rather than $GEM_HOME or $BUNDLE_PATH\.
.
.P
As a result, you should run \fBbundle install\fR as the current user, and Bundler will ask for your password if it is needed to put the gems into their final location\.
.
.SH "INSTALLING GROUPS"
By default, \fBbundle install\fR will install all gems in all groups in your Gemfile(5), except those declared for a different platform\.
.

View file

@ -224,35 +224,6 @@ will cause an error when the Gemfile(5) is modified.
the `vendor/bundle` directory in the application. This may be
overridden using the `--path` option.
## SUDO USAGE
By default, Bundler installs gems to the same location as `gem install`.
In some cases, that location may not be writable by your Unix user. In
that case, Bundler will stage everything in a temporary directory,
then ask you for your `sudo` password in order to copy the gems into
their system location.
From your perspective, this is identical to installing the gems
directly into the system.
You should never use `sudo bundle install`. This is because several
other steps in `bundle install` must be performed as the current user:
* Updating your `Gemfile.lock`
* Updating your `vendor/cache`, if necessary
* Checking out private git repositories using your user's SSH keys
Of these three, the first two could theoretically be performed by
`chown`ing the resulting files to `$SUDO_USER`. The third, however,
can only be performed by invoking the `git` command as
the current user. Therefore, git gems are downloaded and installed
into `~/.bundle` rather than $GEM_HOME or $BUNDLE_PATH.
As a result, you should run `bundle install` as the current user,
and Bundler will ask for your password if it is needed to put the
gems into their final location.
## INSTALLING GROUPS
By default, `bundle install` will install all gems in all groups

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-LIST" "1" "July 2022" "" ""
.TH "BUNDLE\-LIST" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-list\fR \- List all the gems in the bundle

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-LOCK" "1" "July 2022" "" ""
.TH "BUNDLE\-LOCK" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-lock\fR \- Creates / Updates a lockfile without installing

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-OPEN" "1" "July 2022" "" ""
.TH "BUNDLE\-OPEN" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-open\fR \- Opens the source directory for a gem in your bundle

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-OUTDATED" "1" "July 2022" "" ""
.TH "BUNDLE\-OUTDATED" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-outdated\fR \- List installed gems with newer versions available

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-PLATFORM" "1" "July 2022" "" ""
.TH "BUNDLE\-PLATFORM" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-platform\fR \- Displays platform compatibility information

View file

@ -0,0 +1,81 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-PLUGIN" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-plugin\fR \- Manage Bundler plugins
.
.SH "SYNOPSIS"
\fBbundle plugin\fR install PLUGINS [\-\-source=\fISOURCE\fR] [\-\-version=\fIversion\fR] [\-\-git|\-\-local_git=\fIgit\-url\fR] [\-\-branch=\fIbranch\fR|\-\-ref=\fIrev\fR]
.
.br
\fBbundle plugin\fR uninstall PLUGINS
.
.br
\fBbundle plugin\fR list
.
.br
\fBbundle plugin\fR help [COMMAND]
.
.SH "DESCRIPTION"
You can install, uninstall, and list plugin(s) with this command to extend functionalities of Bundler\.
.
.SH "SUB\-COMMANDS"
.
.SS "install"
Install the given plugin(s)\.
.
.IP "\(bu" 4
\fBbundle plugin install bundler\-graph\fR: Install bundler\-graph gem from RubyGems\.org\. The global source, specified in source in Gemfile is ignored\.
.
.IP "\(bu" 4
\fBbundle plugin install bundler\-graph \-\-source https://example\.com\fR: Install bundler\-graph gem from example\.com\. The global source, specified in source in Gemfile is not considered\.
.
.IP "\(bu" 4
\fBbundle plugin install bundler\-graph \-\-version 0\.2\.1\fR: You can specify the version of the gem via \fB\-\-version\fR\.
.
.IP "\(bu" 4
\fBbundle plugin install bundler\-graph \-\-git https://github\.com/rubygems/bundler\-graph\fR: Install bundler\-graph gem from Git repository\. \fB\-\-git\fR can be replaced with \fB\-\-local\-git\fR\. You cannot use both \fB\-\-git\fR and \fB\-\-local\-git\fR\. You can use standard Git URLs like:
.
.IP "\(bu" 4
\fBssh://[user@]host\.xz[:port]/path/to/repo\.git\fR
.
.IP "\(bu" 4
\fBhttp[s]://host\.xz[:port]/path/to/repo\.git\fR
.
.IP "\(bu" 4
\fB/path/to/repo\fR
.
.IP "\(bu" 4
\fBfile:///path/to/repo\fR
.
.IP "" 0
.
.IP
When you specify \fB\-\-git\fR/\fB\-\-local\-git\fR, you can use \fB\-\-branch\fR or \fB\-\-ref\fR to specify any branch, tag, or commit hash (revision) to use\. When you specify both, only the latter is used\.
.
.IP "" 0
.
.SS "uninstall"
Uninstall the plugin(s) specified in PLUGINS\.
.
.SS "list"
List the installed plugins and available commands\.
.
.P
No options\.
.
.SS "help"
Describe subcommands or one specific subcommand\.
.
.P
No options\.
.
.SH "SEE ALSO"
.
.IP "\(bu" 4
How to write a Bundler plugin \fIhttps://bundler\.io/guides/bundler_plugins\.html\fR
.
.IP "" 0

View file

@ -0,0 +1,59 @@
bundle-plugin(1) -- Manage Bundler plugins
==========================================
## SYNOPSIS
`bundle plugin` install PLUGINS [--source=<SOURCE>] [--version=<version>]
[--git|--local_git=<git-url>] [--branch=<branch>|--ref=<rev>]<br>
`bundle plugin` uninstall PLUGINS<br>
`bundle plugin` list<br>
`bundle plugin` help [COMMAND]
## DESCRIPTION
You can install, uninstall, and list plugin(s) with this command to extend functionalities of Bundler.
## SUB-COMMANDS
### install
Install the given plugin(s).
* `bundle plugin install bundler-graph`:
Install bundler-graph gem from RubyGems.org. The global source, specified in source in Gemfile is ignored.
* `bundle plugin install bundler-graph --source https://example.com`:
Install bundler-graph gem from example.com. The global source, specified in source in Gemfile is not considered.
* `bundle plugin install bundler-graph --version 0.2.1`:
You can specify the version of the gem via `--version`.
* `bundle plugin install bundler-graph --git https://github.com/rubygems/bundler-graph`:
Install bundler-graph gem from Git repository. `--git` can be replaced with `--local-git`. You cannot use both `--git` and `--local-git`. You can use standard Git URLs like:
* `ssh://[user@]host.xz[:port]/path/to/repo.git`
* `http[s]://host.xz[:port]/path/to/repo.git`
* `/path/to/repo`
* `file:///path/to/repo`
When you specify `--git`/`--local-git`, you can use `--branch` or `--ref` to specify any branch, tag, or commit hash (revision) to use. When you specify both, only the latter is used.
### uninstall
Uninstall the plugin(s) specified in PLUGINS.
### list
List the installed plugins and available commands.
No options.
### help
Describe subcommands or one specific subcommand.
No options.
## SEE ALSO
* [How to write a Bundler plugin](https://bundler.io/guides/bundler_plugins.html)

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-PRISTINE" "1" "July 2022" "" ""
.TH "BUNDLE\-PRISTINE" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-pristine\fR \- Restores installed gems to their pristine condition

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-REMOVE" "1" "July 2022" "" ""
.TH "BUNDLE\-REMOVE" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-remove\fR \- Removes gems from the Gemfile

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-SHOW" "1" "July 2022" "" ""
.TH "BUNDLE\-SHOW" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-show\fR \- Shows all the gems in your bundle, or the path to a gem

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-UPDATE" "1" "July 2022" "" ""
.TH "BUNDLE\-UPDATE" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-update\fR \- Update your gems to the latest available versions

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-VIZ" "1" "July 2022" "" ""
.TH "BUNDLE\-VIZ" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-viz\fR \- Generates a visual dependency graph for your Gemfile

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE" "1" "July 2022" "" ""
.TH "BUNDLE" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\fR \- Ruby Dependency Management
@ -55,7 +55,7 @@ Execute a script in the current bundle
Specify and read configuration options for Bundler
.
.TP
\fBbundle help(1)\fR
\fBbundle help(1)\fR \fIbundle\-help\.1\.html\fR
Display detailed help for each subcommand
.
.SH "UTILITIES"
@ -120,6 +120,10 @@ Display warnings about common problems
\fBbundle remove(1)\fR \fIbundle\-remove\.1\.html\fR
Removes gems from the Gemfile
.
.TP
\fBbundle plugin(1)\fR \fIbundle\-plugin\.1\.html\fR
Manage Bundler plugins
.
.SH "PLUGINS"
When running a command that isn\'t listed in PRIMARY COMMANDS or UTILITIES, Bundler will try to find an executable on your path named \fBbundler\-<command>\fR and execute it, passing down any extra arguments to it\.
.

View file

@ -46,7 +46,7 @@ We divide `bundle` subcommands into primary commands and utilities:
* [`bundle config(1)`](bundle-config.1.html):
Specify and read configuration options for Bundler
* `bundle help(1)`:
* [`bundle help(1)`](bundle-help.1.html):
Display detailed help for each subcommand
## UTILITIES
@ -97,6 +97,9 @@ We divide `bundle` subcommands into primary commands and utilities:
* [`bundle remove(1)`](bundle-remove.1.html):
Removes gems from the Gemfile
* [`bundle plugin(1)`](bundle-plugin.1.html):
Manage Bundler plugins
## PLUGINS
When running a command that isn't listed in PRIMARY COMMANDS or UTILITIES,

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "GEMFILE" "5" "July 2022" "" ""
.TH "GEMFILE" "5" "August 2022" "" ""
.
.SH "NAME"
\fBGemfile\fR \- A format for describing gem dependencies for Ruby programs

View file

@ -9,6 +9,7 @@ bundle-config(1) bundle-config.1
bundle-doctor(1) bundle-doctor.1
bundle-exec(1) bundle-exec.1
bundle-gem(1) bundle-gem.1
bundle-help(1) bundle-help.1
bundle-info(1) bundle-info.1
bundle-init(1) bundle-init.1
bundle-inject(1) bundle-inject.1
@ -18,6 +19,7 @@ bundle-lock(1) bundle-lock.1
bundle-open(1) bundle-open.1
bundle-outdated(1) bundle-outdated.1
bundle-platform(1) bundle-platform.1
bundle-plugin(1) bundle-plugin.1
bundle-pristine(1) bundle-pristine.1
bundle-remove(1) bundle-remove.1
bundle-show(1) bundle-show.1

View file

@ -2,8 +2,11 @@
module Bundler
module FetchMetadata
# A fallback is included because the original version of the specification
# API didn't include that field, so some marshalled specs in the index have it
# set to +nil+.
def matches_current_ruby?
@required_ruby_version ||= _remote_specification.required_ruby_version
@required_ruby_version ||= _remote_specification.required_ruby_version || Gem::Requirement.default
super
end

View file

@ -36,6 +36,8 @@ module Bundler
# @param [Hash] options various parameters as described in description.
# Refer to cli/plugin for available options
def install(names, options)
raise InvalidOption, "You cannot specify `--branch` and `--ref` at the same time." if options["branch"] && options["ref"]
specs = Installer.new.install(names, options)
save_plugins names, specs

View file

@ -6,10 +6,6 @@ module Bundler
class Rubygems < Bundler::Source::Rubygems
private
def requires_sudo?
false # Will change on implementation of project level plugins
end
def rubygems_dir
Plugin.root
end

View file

@ -3,6 +3,7 @@
module Bundler
class Resolver
require_relative "vendored_molinillo"
require_relative "resolver/base"
require_relative "resolver/spec_group"
include GemHelpers
@ -25,15 +26,13 @@ module Bundler
def initialize(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
@source_requirements = source_requirements
@base = base
@base = Resolver::Base.new(base, additional_base_requirements)
@resolver = Molinillo::Resolver.new(self, self)
@results_for = {}
@search_for = {}
@additional_base_requirements = additional_base_requirements
@platforms = platforms
@resolving_only_for_ruby = platforms == [Gem::Platform::RUBY]
@gem_version_promoter = gem_version_promoter
@use_gvp = Bundler.feature_flag.use_gem_version_promoter_for_major_updates? || !@gem_version_promoter.major?
end
def start(requirements, exclude_specs: [])
@ -43,18 +42,11 @@ module Bundler
remove_from_candidates(spec)
end
@base_dg = Molinillo::DependencyGraph.new
@base.each do |ls|
dep = Dependency.new(ls.name, ls.version)
@base_dg.add_vertex(ls.name, DepProxy.get_proxy(dep, ls.platform), true)
end
@additional_base_requirements.each {|d| @base_dg.add_vertex(d.name, d) }
@gem_version_promoter.prerelease_specified = @prerelease_specified = {}
requirements.each {|dep| @prerelease_specified[dep.name] ||= dep.prerelease? }
verify_gemfile_dependencies_are_found!(requirements)
result = @resolver.resolve(requirements, @base_dg).
result = @resolver.resolve(requirements).
map(&:payload).
reject {|sg| sg.name.end_with?("\0") }.
map(&:to_specs).
@ -62,8 +54,20 @@ module Bundler
SpecSet.new(SpecSet.new(result).for(regular_requirements, false, @platforms))
rescue Molinillo::VersionConflict => e
conflicts = e.conflicts
deps_to_unlock = conflicts.values.inject([]) do |deps, conflict|
deps |= conflict.requirement_trees.flatten.map {|req| base_requirements[req.name] }.compact
end
if deps_to_unlock.any?
@base.unlock_deps(deps_to_unlock)
reset_spec_cache
retry
end
message = version_conflict_message(e)
raise VersionConflict.new(e.conflicts.keys.uniq, message)
raise VersionConflict.new(conflicts.keys.uniq, message)
rescue Molinillo::CircularDependencyError => e
names = e.dependencies.sort_by(&:name).map {|d| "gem '#{d.name}'" }
raise CyclicDependencyError, "Your bundle requires gems that depend" \
@ -118,31 +122,22 @@ module Bundler
dependency = dependency_proxy.dep
name = dependency.name
@search_for[dependency_proxy] ||= begin
results = results_for(dependency) + @base[name].select {|spec| requirement_satisfied_by?(dependency, nil, spec) }
locked_results = @base[name].select {|spec| requirement_satisfied_by?(dependency, nil, spec) }
locked_requirement = base_requirements[name]
results = results_for(dependency) + locked_results
results = results.select {|spec| requirement_satisfied_by?(locked_requirement, nil, spec) } if locked_requirement
if vertex = @base_dg.vertex_named(name)
locked_requirement = vertex.payload.requirement
end
if !@prerelease_specified[name] && (!@use_gvp || locked_requirement.nil?)
if !@prerelease_specified[name] && locked_results.empty?
# Move prereleases to the beginning of the list, so they're considered
# last during resolution.
pre, results = results.partition {|spec| spec.version.prerelease? }
results = pre + results
end
spec_groups = if results.any?
nested = []
results.each do |spec|
version, specs = nested.last
if version == spec.version
specs << spec
else
nested << [spec.version, [spec]]
end
end
nested.reduce([]) do |groups, (version, specs)|
next groups if locked_requirement && !locked_requirement.satisfied_by?(version)
if results.any?
results = @gem_version_promoter.sort_versions(dependency, results)
results.group_by(&:version).reduce([]) do |groups, (_, specs)|
next groups unless specs.any? {|spec| spec.match_platform(platform) }
specs_by_platform = Hash.new do |current_specs, current_platform|
@ -165,13 +160,6 @@ module Bundler
else
[]
end
# GVP handles major itself, but it's still a bit risky to trust it with it
# until we get it settled with new behavior. For 2.x it can take over all cases.
if !@use_gvp
spec_groups
else
@gem_version_promoter.sort_versions(dependency, spec_groups)
end
end
end
@ -197,12 +185,6 @@ module Bundler
"Gemfile"
end
def name_for_locking_dependency_source
Bundler.default_lockfile.basename.to_s
rescue StandardError
"Gemfile.lock"
end
def requirement_satisfied_by?(requirement, activated, spec)
requirement.matches_spec?(spec) || spec.source.is_a?(Source::Gemspec)
end
@ -216,7 +198,7 @@ module Bundler
name = name_for(dependency)
vertex = activated.vertex_named(name)
[
@base_dg.vertex_named(name) ? 0 : 1,
@base[name].any? ? 0 : 1,
vertex.payload ? 0 : 1,
vertex.root? ? 0 : 1,
amount_constrained(dependency),
@ -235,9 +217,12 @@ module Bundler
private
def base_requirements
@base.base_requirements
end
def remove_from_candidates(spec)
@base.delete(spec)
@gem_version_promoter.reset
@results_for.keys.each do |dep|
next unless dep.name == spec.name
@ -245,7 +230,12 @@ module Bundler
@results_for[dep].reject {|s| s.name == spec.name && s.version == spec.version }
end
reset_spec_cache
end
def reset_spec_cache
@search_for = {}
@gem_version_promoter.reset
end
# returns an integer \in (-\infty, 0]
@ -337,18 +327,6 @@ module Bundler
e.message_with_trees(
:full_message_for_conflict => lambda do |name, conflict|
o = if name.end_with?("\0")
String.new("Bundler found conflicting requirements for the #{name} version:")
else
String.new("Bundler could not find compatible versions for gem \"#{name}\":")
end
o << %(\n)
if conflict.locked_requirement
o << %( In snapshot (#{name_for_locking_dependency_source}):\n)
o << %( #{SharedHelpers.pretty_dependency(conflict.locked_requirement)}\n)
o << %(\n)
end
o << %( In #{name_for_explicit_dependency_source}:\n)
trees = conflict.requirement_trees
# called first, because we want to reduce the amount of work required to find maximal empty sets
@ -367,30 +345,41 @@ module Bundler
trees.sort_by! {|t| t.reverse.map(&:name) }
end
o << trees.map do |tree|
t = "".dup
depth = 2
base_tree = tree.first
base_tree_name = base_tree.name
if base_tree_name.end_with?("\0")
t = nil
if trees.size > 1 || name == "bundler"
o = if name.end_with?("\0")
String.new("Bundler found conflicting requirements for the #{name} version:")
else
tree.each do |req|
t << " " * depth << SharedHelpers.pretty_dependency(req)
unless tree.last == req
if spec = conflict.activated_by_name[req.name]
t << %( was resolved to #{spec.version}, which)
end
t << %( depends on)
end
t << %(\n)
depth += 1
end
String.new("Bundler could not find compatible versions for gem \"#{name}\":")
end
t
end.compact.join("\n")
o << %(\n)
o << %( In #{name_for_explicit_dependency_source}:\n)
o << trees.map do |tree|
t = "".dup
depth = 2
base_tree = tree.first
base_tree_name = base_tree.name
if base_tree_name.end_with?("\0")
t = nil
else
tree.each do |req|
t << " " * depth << SharedHelpers.pretty_dependency(req)
unless tree.last == req
if spec = conflict.activated_by_name[req.name]
t << %( was resolved to #{spec.version}, which)
end
t << %( depends on)
end
t << %(\n)
depth += 1
end
end
t
end.compact.join("\n")
else
o = String.new
end
if name == "bundler"
o << %(\n Current Bundler version:\n bundler (#{Bundler::VERSION}))
@ -414,17 +403,13 @@ module Bundler
end
elsif name.end_with?("\0")
o << %(\n Current #{name} version:\n #{SharedHelpers.pretty_dependency(@metadata_requirements.find {|req| req.name == name })}\n\n)
elsif conflict.locked_requirement
o << "\n"
o << %(Deleting your #{name_for_locking_dependency_source} file and running `bundle install` will rebuild your snapshot from scratch, using only\n)
o << %(the gems in your Gemfile, which may resolve the conflict.\n)
elsif !conflict.existing
o << "\n"
relevant_source = conflict.requirement.source || source_for(name)
extra_message = if conflict.requirement_trees.first.size > 1
", which is required by gem '#{SharedHelpers.pretty_dependency(conflict.requirement_trees.first[-2])}',"
extra_message = if trees.first.size > 1
", which is required by gem '#{SharedHelpers.pretty_dependency(trees.first[-2])}',"
else
""
end

View file

@ -0,0 +1,50 @@
# frozen_string_literal: true
module Bundler
class Resolver
class Base
def initialize(base, additional_base_requirements)
@base = base
@additional_base_requirements = additional_base_requirements
end
def [](name)
@base[name]
end
def delete(spec)
@base.delete(spec)
end
def base_requirements
@base_requirements ||= build_base_requirements
end
def unlock_deps(deps)
exact, lower_bound = deps.partition(&:specific?)
exact.each do |exact_dep|
@base.delete_by_name_and_version(exact_dep.name, exact_dep.requirement.requirements.first.last)
end
lower_bound.each do |lower_bound_dep|
@additional_base_requirements.delete(lower_bound_dep)
end
@base_requirements = nil
end
private
def build_base_requirements
base_requirements = {}
@base.each do |ls|
dep = Dependency.new(ls.name, ls.version)
base_requirements[ls.name] = DepProxy.get_proxy(dep, ls.platform)
end
@additional_base_requirements.each {|d| base_requirements[d.name] = d }
base_requirements
end
end
end
end

View file

@ -504,10 +504,6 @@ module Bundler
Gem::Package.build(spec, skip_validation)
end
def repository_subdirectories
Gem::REPOSITORY_SUBDIRECTORIES
end
def path_separator
Gem.path_separator
end

View file

@ -45,7 +45,6 @@ module Bundler
silence_root_warning
suppress_install_using_messages
update_requires_all_flag
use_gem_version_promoter_for_major_updates
].freeze
NUMBER_KEYS = %w[
@ -278,12 +277,6 @@ module Bundler
end
end
def allow_sudo?
key = key_for(:path)
path_configured = @temporary.key?(key) || @local_config.key?(key)
!path_configured
end
def ignore_config?
ENV["BUNDLE_IGNORE_CONFIG"]
end

View file

@ -102,13 +102,7 @@ module Bundler
@install_path ||= begin
git_scope = "#{base_name}-#{shortref_for_path(revision)}"
path = Bundler.install_path.join(git_scope)
if !path.exist? && Bundler.requires_sudo?
Bundler.user_bundle_path.join(Bundler.ruby_scope).join(git_scope)
else
path
end
Bundler.install_path.join(git_scope)
end
end
@ -219,7 +213,7 @@ module Bundler
# across different projects, this cache will be shared.
# When using local git repos, this is set to the local repo.
def cache_path
@cache_path ||= if Bundler.requires_sudo? || Bundler.feature_flag.global_gem_cache?
@cache_path ||= if Bundler.feature_flag.global_gem_cache?
Bundler.user_cache
else
Bundler.bundle_path.join("cache", "bundler")

View file

@ -18,13 +18,7 @@ module Bundler
@build_args = options[:build_args] || Bundler.rubygems.build_args
@gem_bin_dir = "#{Bundler.rubygems.gem_dir}/bin"
@disable_extensions = options[:disable_extensions]
if Bundler.requires_sudo?
@tmp_dir = Bundler.tmp(spec.full_name).to_s
@bin_dir = "#{@tmp_dir}/bin"
else
@bin_dir = @gem_bin_dir
end
@bin_dir = @gem_bin_dir
end
def post_install
@ -38,25 +32,10 @@ module Bundler
generate_bin unless spec.executables.empty?
run_hooks(:post_install)
ensure
Bundler.rm_rf(@tmp_dir) if Bundler.requires_sudo?
end
private
def generate_bin
super
if Bundler.requires_sudo?
SharedHelpers.filesystem_access(@gem_bin_dir) do |p|
Bundler.mkdir_p(p)
end
spec.executables.each do |exe|
Bundler.sudo "cp -R #{@bin_dir}/#{exe} #{@gem_bin_dir}"
end
end
end
def run_hooks(type)
hooks_meth = "#{type}_hooks"
return unless Gem.respond_to?(hooks_meth)

View file

@ -160,15 +160,10 @@ module Bundler
return if Bundler.settings[:no_install]
if requires_sudo?
install_path = Bundler.tmp(spec.full_name)
bin_path = install_path.join("bin")
else
install_path = rubygems_dir
bin_path = Bundler.system_bindir
end
install_path = rubygems_dir
bin_path = Bundler.system_bindir
Bundler.mkdir_p bin_path, :no_sudo => true unless spec.executables.empty? || Bundler.rubygems.provides?(">= 2.7.5")
Bundler.mkdir_p bin_path unless spec.executables.empty? || Bundler.rubygems.provides?(">= 2.7.5")
require_relative "../rubygems_gem_installer"
@ -209,34 +204,7 @@ module Bundler
spec.full_gem_path = installed_spec.full_gem_path
spec.loaded_from = installed_spec.loaded_from
# SUDO HAX
if requires_sudo?
Bundler.rubygems.repository_subdirectories.each do |name|
src = File.join(install_path, name, "*")
dst = File.join(rubygems_dir, name)
if name == "extensions" && Dir.glob(src).any?
src = File.join(src, "*/*")
ext_src = Dir.glob(src).first
ext_src.gsub!(src[0..-6], "")
dst = File.dirname(File.join(dst, ext_src))
end
SharedHelpers.filesystem_access(dst) do |p|
Bundler.mkdir_p(p)
end
Bundler.sudo "cp -R #{src} #{dst}" if Dir[src].any?
end
spec.executables.each do |exe|
SharedHelpers.filesystem_access(Bundler.system_bindir) do |p|
Bundler.mkdir_p(p)
end
Bundler.sudo "cp -R #{install_path}/bin/#{exe} #{Bundler.system_bindir}/"
end
end
spec.post_install_message
ensure
Bundler.rm_rf(install_path) if requires_sudo?
end
def cache(spec, custom_path = nil)
@ -475,38 +443,18 @@ module Bundler
gem_path = package_path(cache_path, spec)
return gem_path if File.exist?(gem_path)
if requires_sudo?
download_path = Bundler.tmp(spec.full_name)
download_cache_path = default_cache_path_for(download_path)
else
download_cache_path = cache_path
end
SharedHelpers.filesystem_access(download_cache_path) do |p|
SharedHelpers.filesystem_access(cache_path) do |p|
FileUtils.mkdir_p(p)
end
download_gem(spec, download_cache_path, previous_spec)
if requires_sudo?
SharedHelpers.filesystem_access(cache_path) do |p|
Bundler.mkdir_p(p)
end
Bundler.sudo "mv #{package_path(download_cache_path, spec)} #{gem_path}"
end
download_gem(spec, cache_path, previous_spec)
gem_path
ensure
Bundler.rm_rf(download_path) if requires_sudo?
end
def installed?(spec)
installed_specs[spec].any? && !spec.deleted_gem?
end
def requires_sudo?
Bundler.requires_sudo?
end
def rubygems_dir
Bundler.bundle_path
end

View file

@ -114,10 +114,20 @@ module Bundler
SpecSet.new(arr)
end
def -(other)
SpecSet.new(to_a - other.to_a)
end
def find_by_name_and_platform(name, platform)
@specs.detect {|spec| spec.name == name && spec.match_platform(platform) }
end
def delete_by_name_and_version(name, version)
@specs.reject! {|spec| spec.name == name && spec.version == version }
@lookup = nil
@sorted = nil
end
def what_required(spec)
unless req = find {|s| s.dependencies.any? {|d| d.type == :runtime && d.name == spec.name } }
return [spec]

View file

@ -189,22 +189,6 @@ EOF
Bundler.mkdir_p(bundled_app.join("foo", "bar"))
expect(bundled_app.join("foo", "bar")).to exist
end
context "when mkdir_p requires sudo" do
it "creates a new folder using sudo" do
expect(Bundler).to receive(:requires_sudo?).and_return(true)
expect(Bundler).to receive(:sudo).and_return true
Bundler.mkdir_p(bundled_app.join("foo"))
end
end
context "with :no_sudo option" do
it "forces mkdir_p to not use sudo" do
expect(Bundler).to receive(:requires_sudo?).and_return(true)
expect(Bundler).to_not receive(:sudo)
Bundler.mkdir_p(bundled_app.join("foo"), :no_sudo => true)
end
end
end
describe "#user_home" do
@ -268,118 +252,6 @@ EOF
end
end
describe "#requires_sudo?" do
let!(:tmpdir) { Dir.mktmpdir }
let(:bundle_path) { Pathname("#{tmpdir}/bundle") }
def clear_cached_requires_sudo
return unless Bundler.instance_variable_defined?(:@requires_sudo_ran)
Bundler.remove_instance_variable(:@requires_sudo_ran)
Bundler.remove_instance_variable(:@requires_sudo)
end
before do
clear_cached_requires_sudo
allow(Bundler).to receive(:which).with("sudo").and_return("/usr/bin/sudo")
allow(Bundler).to receive(:bundle_path).and_return(bundle_path)
end
after do
FileUtils.rm_rf(tmpdir)
clear_cached_requires_sudo
end
subject { Bundler.requires_sudo? }
context "bundle_path doesn't exist" do
it { should be false }
context "and parent dir can't be written" do
before do
FileUtils.chmod(0o500, tmpdir)
end
it { should be true }
end
context "with unwritable files in a parent dir" do
# Regression test for https://github.com/rubygems/bundler/pull/6316
# It doesn't matter if there are other unwritable files so long as
# bundle_path can be created
before do
file = File.join(tmpdir, "unrelated_file")
FileUtils.touch(file)
FileUtils.chmod(0o400, file)
end
it { should be false }
end
end
context "bundle_path exists" do
before do
FileUtils.mkdir_p(bundle_path)
end
it { should be false }
context "and is unwritable" do
before do
FileUtils.chmod(0o500, bundle_path)
end
it { should be true }
end
end
context "path writability" do
before do
FileUtils.mkdir_p("tmp/vendor/bundle")
FileUtils.mkdir_p("tmp/vendor/bin_dir")
end
after do
FileUtils.rm_rf("tmp/vendor/bundle")
FileUtils.rm_rf("tmp/vendor/bin_dir")
end
context "writable paths" do
it "should return false and display nothing" do
allow(Bundler).to receive(:bundle_path).and_return(Pathname("tmp/vendor/bundle"))
expect(Bundler.ui).to_not receive(:warn)
expect(Bundler.requires_sudo?).to eq(false)
end
end
context "unwritable paths" do
before do
FileUtils.touch("tmp/vendor/bundle/unwritable1.txt")
FileUtils.touch("tmp/vendor/bundle/unwritable2.txt")
FileUtils.touch("tmp/vendor/bin_dir/unwritable3.txt")
FileUtils.chmod(0o400, "tmp/vendor/bundle/unwritable1.txt")
FileUtils.chmod(0o400, "tmp/vendor/bundle/unwritable2.txt")
FileUtils.chmod(0o400, "tmp/vendor/bin_dir/unwritable3.txt")
end
it "should return true and display warn message" do
allow(Bundler).to receive(:bundle_path).and_return(Pathname("tmp/vendor/bundle"))
bin_dir = Pathname("tmp/vendor/bin_dir/")
# allow File#writable? to be called with args other than the stubbed on below
allow(File).to receive(:writable?).and_call_original
# fake make the directory unwritable
allow(File).to receive(:writable?).with(bin_dir).and_return(false)
allow(Bundler).to receive(:system_bindir).and_return(Pathname("tmp/vendor/bin_dir/"))
message = <<-MESSAGE.chomp
Following files may not be writable, so sudo is needed:
tmp/vendor/bin_dir/
tmp/vendor/bundle/unwritable1.txt
tmp/vendor/bundle/unwritable2.txt
MESSAGE
expect(Bundler.ui).to receive(:warn).with(message)
expect(Bundler.requires_sudo?).to eq(true)
end
end
end
end
context "user cache dir" do
let(:home_path) { Pathname.new(ENV["HOME"]) }

View file

@ -48,6 +48,33 @@ RSpec.describe Bundler::EndpointSpecification do
end
end
describe "#required_ruby_version" do
context "required_ruby_version is already set on endpoint specification" do
existing_value = "already set value"
let(:required_ruby_version) { existing_value }
it "should return the current value when already set on endpoint specification" do
remote_spec = double(:remote_spec, :required_ruby_version => "remote_value", :required_rubygems_version => nil)
expect(spec.required_ruby_version). eql?(existing_value)
end
end
it "should return the remote spec value when not set on endpoint specification and remote spec has one" do
remote_value = "remote_value"
remote_spec = double(:remote_spec, :required_ruby_version => remote_value, :required_rubygems_version => nil)
allow(spec_fetcher).to receive(:fetch_spec).and_return(remote_spec)
expect(spec.required_ruby_version). eql?(remote_value)
end
it "should use the default Gem Requirement value when not set on endpoint specification and not set on remote spec" do
remote_spec = double(:remote_spec, :required_ruby_version => nil, :required_rubygems_version => nil)
allow(spec_fetcher).to receive(:fetch_spec).and_return(remote_spec)
expect(spec.required_ruby_version). eql?(Gem::Requirement.default)
end
end
it "supports equality comparison" do
remote_spec = double(:remote_spec, :required_ruby_version => nil, :required_rubygems_version => nil)
allow(spec_fetcher).to receive(:fetch_spec).and_return(remote_spec)

View file

@ -166,14 +166,5 @@ RSpec.describe Bundler::GemVersionPromoter do
end
end
end
context "debug output" do
it "should not kerblooie on its own debug output" do
gvp = unlocking(:level => :patch)
dep = Bundler::DepProxy.get_proxy(dep("foo", "1.2.0").first, "ruby")
result = gvp.send(:debug_format_result, dep, build_spec_groups("foo", %w[1.2.0 1.3.0]))
expect(result.class).to eq Array
end
end
end
end

View file

@ -2,10 +2,8 @@
RSpec.describe "bundle install" do
describe "when system_bindir is set" do
# On OS X, Gem.bindir defaults to /usr/bin, so system_bindir is useful if
# you want to avoid sudo installs for system gems with OS X's default ruby
it "overrides Gem.bindir" do
expect(Pathname.new("/usr/bin")).not_to be_writable unless Process.euid == 0
expect(Pathname.new("/usr/bin")).not_to be_writable
gemfile <<-G
def Gem.bindir; "/usr/bin"; end
source "#{file_uri_for(gem_repo1)}"

View file

@ -1470,6 +1470,59 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
end
context "when default source includes old gems with nil required_ruby_version" do
before do
build_repo2 do
build_gem "ruport", "1.7.0.3" do |s|
s.add_dependency "pdf-writer", "1.1.8"
end
end
build_repo gem_repo4 do
build_gem "pdf-writer", "1.1.8"
end
path = "#{gem_repo4}/#{Gem::MARSHAL_SPEC_DIR}/pdf-writer-1.1.8.gemspec.rz"
spec = Marshal.load(Bundler.rubygems.inflate(File.binread(path)))
spec.instance_variable_set(:@required_ruby_version, nil)
File.open(path, "wb") do |f|
f.write Gem.deflate(Marshal.dump(spec))
end
gemfile <<~G
source "https://localgemserver.test"
gem "ruport", "= 1.7.0.3", :source => "https://localgemserver.test/extra"
G
end
it "handles that fine" do
bundle "install", :artifice => "compact_index_extra", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
expect(lockfile).to eq <<~L
GEM
remote: https://localgemserver.test/
specs:
pdf-writer (1.1.8)
GEM
remote: https://localgemserver.test/extra/
specs:
ruport (1.7.0.3)
pdf-writer (= 1.1.8)
PLATFORMS
#{specific_local_platform}
DEPENDENCIES
ruport (= 1.7.0.3)!
BUNDLED WITH
#{Bundler::VERSION}
L
end
end
context "when default source includes old gems with nil required_rubygems_version" do
before do
build_repo2 do

View file

@ -519,18 +519,6 @@ The checksum of /versions does not match the checksum provided by the server! So
expect(out).to include("Fetching gem metadata from #{source_uri}")
end
it "should install when EndpointSpecification has a bin dir owned by root", :sudo => true do
sudo "mkdir -p #{system_gem_path("bin")}"
sudo "chown -R root #{system_gem_path("bin")}"
gemfile <<-G
source "#{source_uri}"
gem "rails"
G
bundle :install, :artifice => "compact_index"
expect(the_bundle).to include_gems "rails 2.3.2"
end
it "installs the binstubs", :bundler => "< 3" do
gemfile <<-G
source "#{source_uri}"

View file

@ -476,18 +476,6 @@ RSpec.describe "gemcutter's dependency API" do
expect(out).to include("Fetching gem metadata from #{source_uri}")
end
it "should install when EndpointSpecification has a bin dir owned by root", :sudo => true do
sudo "mkdir -p #{system_gem_path("bin")}"
sudo "chown -R root #{system_gem_path("bin")}"
gemfile <<-G
source "#{source_uri}"
gem "rails"
G
bundle :install, :artifice => "endpoint"
expect(the_bundle).to include_gems "rails 2.3.2"
end
it "installs the binstubs", :bundler => "< 3" do
gemfile <<-G
source "#{source_uri}"

View file

@ -190,28 +190,33 @@ RSpec.describe "bundle flex_install" do
expect(err).to match(/could not find gem 'rack-obama/i)
end
it "suggests deleting the Gemfile.lock file when the Gemfile requires different versions than the lock" do
it "discards the locked gems when the Gemfile requires different versions than the lock" do
bundle "config set force_ruby_platform true"
nice_error = <<-E.strip.gsub(/^ {8}/, "")
Bundler could not find compatible versions for gem "rack":
In snapshot (Gemfile.lock):
rack (= 0.9.1)
Could not find gem 'rack (= 1.2)', which is required by gem 'rack-obama (= 2.0)', in rubygems repository #{file_uri_for(gem_repo2)}/ or installed locally.
In Gemfile:
rack-obama (= 2.0) was resolved to 2.0, which depends on
rack (= 1.2)
rack_middleware was resolved to 1.0, which depends on
rack (= 0.9.1)
Deleting your Gemfile.lock file and running `bundle install` will rebuild your snapshot from scratch, using only
the gems in your Gemfile, which may resolve the conflict.
The source contains the following gems matching 'rack':
* rack-0.9.1
* rack-1.0.0
E
bundle :install, :retry => 0, :raise_on_error => false
expect(err).to end_with(nice_error)
end
it "does not include conflicts with a single requirement tree, because that can't possibly be a conflict" do
bundle "config set force_ruby_platform true"
bad_error = <<-E.strip.gsub(/^ {8}/, "")
Bundler could not find compatible versions for gem "rack-obama":
In Gemfile:
rack-obama (= 2.0)
E
bundle "update rack_middleware", :retry => 0, :raise_on_error => false
expect(err).not_to end_with(bad_error)
end
end
describe "when running bundle update and Gemfile conflicts with lockfile" do
@ -230,22 +235,6 @@ RSpec.describe "bundle flex_install" do
gem "jekyll-feed", "~> 0.12"
G
lockfile <<-L
GEM
remote: #{file_uri_for(gem_repo4)}/
specs:
jekyll-feed (0.16.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
jekyll-feed
BUNDLED WITH
#{Bundler::VERSION}
L
gemfile <<-G
source "#{file_uri_for(gem_repo4)}"
gem "github-pages", "~> 226"
@ -253,24 +242,9 @@ RSpec.describe "bundle flex_install" do
G
end
it "suggests deleting the Gemfile.lock file when the Gemfile requires different versions than the lock" do
nice_error = <<-E.strip.gsub(/^ {8}/, "")
Bundler could not find compatible versions for gem "jekyll-feed":
In snapshot (Gemfile.lock):
jekyll-feed (>= 0.16.0)
In Gemfile:
jekyll-feed (~> 0.12)
github-pages (~> 226) was resolved to 226, which depends on
jekyll-feed (= 0.15.1)
Deleting your Gemfile.lock file and running `bundle install` will rebuild your snapshot from scratch, using only
the gems in your Gemfile, which may resolve the conflict.
E
bundle :update, :raise_on_error => false
expect(err).to end_with(nice_error)
it "discards the conflicting lockfile information and resolves properly" do
bundle :update, :raise_on_error => false, :all => true
expect(err).to be_empty
end
end
@ -374,7 +348,7 @@ RSpec.describe "bundle flex_install" do
end
end
it "prints the correct error message" do
it "resolves them" do
# install Rails 3.0.0.rc
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
@ -383,13 +357,12 @@ RSpec.describe "bundle flex_install" do
G
# upgrade Rails to 3.0.0 and then install again
install_gemfile <<-G, :raise_on_error => false
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
gem "rails", "3.0.0"
gem "capybara", "0.3.9"
G
expect(err).to include("Gemfile.lock")
expect(err).to be_empty
end
end
end

View file

@ -1,205 +0,0 @@
# frozen_string_literal: true
RSpec.describe "when using sudo", :sudo => true do
describe "and BUNDLE_PATH is writable" do
context "but BUNDLE_PATH/build_info is not writable" do
let(:subdir) do
system_gem_path("cache")
end
before do
bundle "config set path.system true"
subdir.mkpath
sudo "chmod u-w #{subdir}"
end
after do
sudo "chmod u+w #{subdir}"
end
it "installs" do
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
expect(out).to_not match(/an error occurred/i)
expect(system_gem_path("cache/rack-1.0.0.gem")).to exist
expect(the_bundle).to include_gems "rack 1.0"
end
end
end
describe "and GEM_HOME is owned by root" do
before :each do
bundle "config set path.system true"
chown_system_gems_to_root
end
it "installs" do
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rack", '1.0'
gem "thin"
G
expect(system_gem_path("gems/rack-1.0.0")).to exist
expect(system_gem_path("gems/rack-1.0.0").stat.uid).to eq(0)
expect(the_bundle).to include_gems "rack 1.0"
end
it "installs rake and a gem dependent on rake in the same session" do
build_repo2 do
build_gem "another_implicit_rake_dep" do |s|
s.extensions << "Rakefile"
s.write "Rakefile", <<-RUBY
task :default do
path = File.expand_path("lib", __dir__)
FileUtils.mkdir_p(path)
File.open("\#{path}/another_implicit_rake_dep.rb", "w") do |f|
f.puts "ANOTHER_IMPLICIT_RAKE_DEP = 'YES'"
end
end
RUBY
end
end
gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
gem "rake"
gem "another_implicit_rake_dep"
G
bundle "install"
expect(system_gem_path("gems/another_implicit_rake_dep-1.0")).to exist
end
it "installs when BUNDLE_PATH is owned by root" do
bundle_path = tmp("owned_by_root")
FileUtils.mkdir_p bundle_path
sudo "chown -R root #{bundle_path}"
ENV["BUNDLE_PATH"] = bundle_path.to_s
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rack", '1.0'
G
expect(bundle_path.join(Bundler.ruby_scope, "gems/rack-1.0.0")).to exist
expect(bundle_path.join(Bundler.ruby_scope, "gems/rack-1.0.0").stat.uid).to eq(0)
expect(the_bundle).to include_gems "rack 1.0"
end
it "installs when BUNDLE_PATH does not exist" do
root_path = tmp("owned_by_root")
FileUtils.mkdir_p root_path
sudo "chown -R root #{root_path}"
bundle_path = root_path.join("does_not_exist")
ENV["BUNDLE_PATH"] = bundle_path.to_s
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rack", '1.0'
G
expect(bundle_path.join(Bundler.ruby_scope, "gems/rack-1.0.0")).to exist
expect(bundle_path.join(Bundler.ruby_scope, "gems/rack-1.0.0").stat.uid).to eq(0)
expect(the_bundle).to include_gems "rack 1.0"
end
it "installs extensions/" do
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "very_simple_binary"
G
expect(system_gem_path("gems/very_simple_binary-1.0")).to exist
binary_glob = system_gem_path("extensions/*/*/very_simple_binary-1.0")
expect(Dir.glob(binary_glob).first).to be
end
end
describe "and BUNDLE_PATH is not writable" do
before do
bundle "config set --local path .bundle"
sudo "chmod ugo-w .bundle"
end
after do
sudo "chmod ugo+w .bundle"
end
it "installs" do
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rack", '1.0'
G
expect(local_gem_path("gems/rack-1.0.0")).to exist
expect(the_bundle).to include_gems "rack 1.0"
end
it "cleans up the tmpdirs generated" do
require "tmpdir"
Dir.glob("#{Dir.tmpdir}/bundler*").each do |tmpdir|
FileUtils.remove_entry_secure(tmpdir)
end
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
tmpdirs = Dir.glob("#{Dir.tmpdir}/bundler*")
expect(tmpdirs).to be_empty
end
end
describe "and GEM_HOME is not writable" do
it "installs" do
bundle "config set path.system true"
gem_home = tmp("sudo_gem_home")
sudo "mkdir -p #{gem_home}"
sudo "chmod ugo-w #{gem_home}"
system_gems :bundler, :path => gem_home
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rack", '1.0'
G
bundle :install, :env => { "GEM_HOME" => gem_home.to_s, "GEM_PATH" => nil }
expect(gem_home.join("bin/rackup")).to exist
expect(the_bundle).to include_gems "rack 1.0", :env => { "GEM_HOME" => gem_home.to_s, "GEM_PATH" => nil }
sudo "rm -rf #{tmp("sudo_gem_home")}"
end
end
describe "and root runs install" do
let(:warning) { "Don't run Bundler as root." }
before do
gemfile %(source "#{file_uri_for(gem_repo1)}")
end
it "warns against that" do
bundle :install, :sudo => :preserve_env
expect(err).to include(warning)
end
context "when ENV['BUNDLE_SILENCE_ROOT_WARNING'] is set" do
it "skips the warning" do
bundle :install, :sudo => :preserve_env, :env => { "BUNDLE_SILENCE_ROOT_WARNING" => "true" }
expect(err).to_not include(warning)
end
end
context "when silence_root_warning = false" do
it "warns against that" do
bundle :install, :sudo => :preserve_env, :env => { "BUNDLE_SILENCE_ROOT_WARNING" => "false" }
expect(err).to include(warning)
end
end
end
end

View file

@ -32,7 +32,8 @@ RSpec.describe "bundler plugin install" do
it "shows help when --help flag is given" do
bundle "plugin install --help"
expect(out).to include("bundle plugin install PLUGINS # Install the plugin from the source")
# The help message defined in ../../lib/bundler/man/bundle-plugin.1.ronn will be output.
expect(out).to include("You can install, uninstall, and list plugin(s)")
end
context "plugin is already installed" do
@ -84,6 +85,26 @@ RSpec.describe "bundler plugin install" do
expect(out).to include("Using foo 1.1")
end
it "installs when --branch specified" do
bundle "plugin install foo --branch main --source #{file_uri_for(gem_repo2)}"
expect(out).to include("Installed plugin foo")
end
it "installs when --ref specified" do
bundle "plugin install foo --ref v1.2.3 --source #{file_uri_for(gem_repo2)}"
expect(out).to include("Installed plugin foo")
end
it "raises error when both --branch and --ref options are specified" do
bundle "plugin install foo --source #{file_uri_for(gem_repo2)} --branch main --ref v1.2.3", :raise_on_error => false
expect(out).not_to include("Installed plugin foo")
expect(err).to include("You cannot specify `--branch` and `--ref` at the same time.")
end
it "works with different load paths" do
build_repo2 do
build_plugin "testing" do |s|

View file

@ -304,13 +304,7 @@ RSpec.describe "real source plugins" do
@install_path ||= begin
git_scope = "\#{base_name}-\#{shortref_for_path(revision)}"
path = gem_install_dir.join(git_scope)
if !path.exist? && requires_sudo?
user_bundle_path.join(ruby_scope).join(git_scope)
else
path
end
gem_install_dir.join(git_scope)
end
end

View file

@ -151,7 +151,6 @@ RSpec.describe "The library itself" do
git.allow_insecure
inline
trust-policy
use_gem_version_promoter_for_major_updates
]
all_settings = Hash.new {|h, k| h[k] = [] }

View file

@ -23,7 +23,6 @@ require_relative "support/indexes"
require_relative "support/matchers"
require_relative "support/permissions"
require_relative "support/platforms"
require_relative "support/sudo"
$debug = false
@ -40,7 +39,6 @@ RSpec.configure do |config|
config.include Spec::Matchers
config.include Spec::Path
config.include Spec::Platforms
config.include Spec::Sudo
config.include Spec::Permissions
# Enable flags like --only-failures and --next-failure
@ -115,10 +113,6 @@ RSpec.configure do |config|
end
end
config.before :each, :sudo => true do
Spec::Sudo.write_safe_config
end
config.after :suite do
FileUtils.rm_r Spec::Path.pristine_system_gem_path
end

View file

@ -1,7 +1,5 @@
# frozen_string_literal: true
require_relative "sudo"
class RequirementChecker < Proc
def self.against(present)
provided = Gem::Version.new(present)
@ -21,7 +19,6 @@ class RequirementChecker < Proc
end
RSpec.configure do |config|
config.filter_run_excluding :sudo => true
config.filter_run_excluding :realworld => true
git_version = Bundler::Source::Git::GitProxy.new(nil, nil, nil).version

View file

@ -78,9 +78,6 @@ module Spec
end
def bundle(cmd, options = {}, &block)
with_sudo = options.delete(:sudo)
sudo = with_sudo == :preserve_env ? "sudo -E --preserve-env=RUBYOPT" : "sudo" if with_sudo
bundle_bin = options.delete(:bundle_bin)
bundle_bin ||= installed_bindir.join("bundle")
@ -119,7 +116,7 @@ module Spec
end
end.join
ruby_cmd = build_ruby_cmd({ :sudo => sudo, :load_path => load_path, :requires => requires })
ruby_cmd = build_ruby_cmd({ :load_path => load_path, :requires => requires })
cmd = "#{ruby_cmd} #{bundle_bin} #{cmd}#{args}"
sys_exec(cmd, { :env => env, :dir => dir, :raise_on_error => raise_on_error }, &block)
end
@ -146,8 +143,6 @@ module Spec
end
def build_ruby_cmd(options = {})
sudo = options.delete(:sudo)
libs = options.delete(:load_path)
lib_option = libs ? "-I#{libs.join(File::PATH_SEPARATOR)}" : []
@ -155,7 +150,7 @@ module Spec
requires << "#{Path.spec_dir}/support/hax.rb"
require_option = requires.map {|r| "-r#{r}" }
[sudo, Gem.ruby, *lib_option, *require_option].compact.join(" ")
[Gem.ruby, *lib_option, *require_option].compact.join(" ")
end
def gembin(cmd, options = {})

View file

@ -1,22 +0,0 @@
# frozen_string_literal: true
module Spec
module Sudo
def self.present?
@which_sudo ||= Bundler.which("sudo")
end
def self.write_safe_config
File.write(Spec::Path.tmp("gitconfig"), "[safe]\n\tdirectory = #{Spec::Path.git_root}")
end
def sudo(cmd)
raise "sudo not present" unless Sudo.present?
sys_exec("sudo #{cmd}")
end
def chown_system_gems_to_root
sudo "chown -R root #{system_gem_path}"
end
end
end

View file

@ -463,14 +463,7 @@ class Gem::TestCase < Test::Unit::TestCase
Dir.chdir @current_dir
# Prevent a race condition on removing TMPDIR being written by MJIT
if defined?(RubyVM::MJIT.enabled?) && RubyVM::MJIT.enabled?
RubyVM::MJIT.pause(wait: false)
end
FileUtils.rm_rf @tempdir
if defined?(RubyVM::MJIT.enabled?) && RubyVM::MJIT.enabled?
RubyVM::MJIT.resume
end
ENV.replace(@orig_env)

View file

@ -44,6 +44,7 @@ GEM
unicode-display_width (2.1.0)
PLATFORMS
aarch64-linux
arm64-darwin-20
arm64-darwin-21
universal-java-11

View file

@ -50,6 +50,7 @@ GEM
unicode-display_width (2.1.0)
PLATFORMS
aarch64-linux
arm64-darwin-20
arm64-darwin-21
universal-java-11