mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Merge RubyGems 3.2.31 and Bundler 2.2.31
This commit is contained in:
parent
e27381d289
commit
b19b2e9867
111 changed files with 4469 additions and 376 deletions
|
@ -552,7 +552,7 @@ module Bundler
|
|||
method_option :version, :type => :boolean, :default => false, :aliases => "-v", :desc => "Set to show each gem version."
|
||||
method_option :without, :type => :array, :default => [], :aliases => "-W", :banner => "GROUP[ GROUP...]", :desc => "Exclude gems that are part of the specified named group."
|
||||
def viz
|
||||
SharedHelpers.major_deprecation 2, "The `viz` command has been moved to the `bundle-viz` gem, see https://github.com/bundler/bundler-viz"
|
||||
SharedHelpers.major_deprecation 2, "The `viz` command has been moved to the `bundle-viz` gem, see https://github.com/rubygems/bundler-graph"
|
||||
require_relative "cli/viz"
|
||||
Viz.new(options.dup).run
|
||||
end
|
||||
|
@ -575,6 +575,8 @@ module Bundler
|
|||
:desc => "Generate a test directory for your library, either rspec, minitest or test-unit. Set a default with `bundle config set --global gem.test (rspec|minitest|test-unit)`."
|
||||
method_option :ci, :type => :string, :lazy_default => Bundler.settings["gem.ci"] || "",
|
||||
:desc => "Generate CI configuration, either GitHub Actions, Travis CI, GitLab CI or CircleCI. Set a default with `bundle config set --global gem.ci (github|travis|gitlab|circle)`"
|
||||
method_option :linter, :type => :string, :lazy_default => Bundler.settings["gem.linter"] || "",
|
||||
:desc => "Add a linter and code formatter, either RuboCop or Standard. Set a default with `bundle config set --global gem.linter (rubocop|standard)`"
|
||||
method_option :github_username, :type => :string, :default => Bundler.settings["gem.github_username"], :banner => "Set your username on GitHub", :desc => "Fill in GitHub username on README so that you don't have to do it manually. Set a default with `bundle config set --global gem.github_username <your_username>`."
|
||||
|
||||
def gem(name)
|
||||
|
|
|
@ -163,15 +163,16 @@ module Bundler
|
|||
templates.merge!("CHANGELOG.md.tt" => "CHANGELOG.md")
|
||||
end
|
||||
|
||||
if ask_and_set(:rubocop, "Do you want to add rubocop as a dependency for gems you generate?",
|
||||
"RuboCop is a static code analyzer that has out-of-the-box rules for many " \
|
||||
"of the guidelines in the community style guide. " \
|
||||
"For more information, see the RuboCop docs (https://docs.rubocop.org/en/stable/) " \
|
||||
"and the Ruby Style Guides (https://github.com/rubocop-hq/ruby-style-guide).")
|
||||
config[:rubocop] = true
|
||||
config[:rubocop_version] = rubocop_version
|
||||
config[:linter] = ask_and_set_linter
|
||||
case config[:linter]
|
||||
when "rubocop"
|
||||
config[:linter_version] = rubocop_version
|
||||
Bundler.ui.info "RuboCop enabled in config"
|
||||
templates.merge!("rubocop.yml.tt" => ".rubocop.yml")
|
||||
when "standard"
|
||||
config[:linter_version] = standard_version
|
||||
Bundler.ui.info "Standard enabled in config"
|
||||
templates.merge!("standard.yml.tt" => ".standard.yml")
|
||||
end
|
||||
|
||||
templates.merge!("exe/newgem.tt" => "exe/#{name}") if config[:exe]
|
||||
|
@ -317,6 +318,58 @@ module Bundler
|
|||
ci_template
|
||||
end
|
||||
|
||||
def ask_and_set_linter
|
||||
linter_template = options[:linter] || Bundler.settings["gem.linter"]
|
||||
linter_template = deprecated_rubocop_option if linter_template.nil?
|
||||
|
||||
if linter_template.to_s.empty?
|
||||
Bundler.ui.confirm "Do you want to add a code linter and formatter to your gem? " \
|
||||
"Supported Linters:\n" \
|
||||
"* RuboCop: https://rubocop.org\n" \
|
||||
"* Standard: https://github.com/testdouble/standard\n" \
|
||||
"\n"
|
||||
Bundler.ui.info hint_text("linter")
|
||||
|
||||
result = Bundler.ui.ask "Enter a linter. rubocop/standard/(none):"
|
||||
if result =~ /rubocop|standard/
|
||||
linter_template = result
|
||||
else
|
||||
linter_template = false
|
||||
end
|
||||
end
|
||||
|
||||
if Bundler.settings["gem.linter"].nil?
|
||||
Bundler.settings.set_global("gem.linter", linter_template)
|
||||
end
|
||||
|
||||
# Once gem.linter safely set, unset the deprecated gem.rubocop
|
||||
unless Bundler.settings["gem.rubocop"].nil?
|
||||
Bundler.settings.set_global("gem.rubocop", nil)
|
||||
end
|
||||
|
||||
if options[:linter] == Bundler.settings["gem.linter"]
|
||||
Bundler.ui.info "#{options[:linter]} is already configured, ignoring --linter flag."
|
||||
end
|
||||
|
||||
linter_template
|
||||
end
|
||||
|
||||
def deprecated_rubocop_option
|
||||
if !options[:rubocop].nil?
|
||||
if options[:rubocop]
|
||||
Bundler::SharedHelpers.major_deprecation 2, "--rubocop is deprecated, use --linter=rubocop"
|
||||
"rubocop"
|
||||
else
|
||||
Bundler::SharedHelpers.major_deprecation 2, "--no-rubocop is deprecated, use --linter"
|
||||
false
|
||||
end
|
||||
elsif !Bundler.settings["gem.rubocop"].nil?
|
||||
Bundler::SharedHelpers.major_deprecation 2,
|
||||
"config gem.rubocop is deprecated; we've updated your config to use gem.linter instead"
|
||||
Bundler.settings["gem.rubocop"] ? "rubocop" : false
|
||||
end
|
||||
end
|
||||
|
||||
def bundler_dependency_version
|
||||
v = Gem::Version.new(Bundler::VERSION)
|
||||
req = v.segments[0..1]
|
||||
|
@ -367,5 +420,13 @@ module Bundler
|
|||
"1.21"
|
||||
end
|
||||
end
|
||||
|
||||
def standard_version
|
||||
if Gem.ruby_version < Gem::Version.new("2.4.a") then "0.2.5"
|
||||
elsif Gem.ruby_version < Gem::Version.new("2.5.a") then "1.0"
|
||||
else
|
||||
"1.3"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -138,7 +138,7 @@ module Bundler
|
|||
@dependency_changes = converge_dependencies
|
||||
@local_changes = converge_locals
|
||||
|
||||
@locked_specs_incomplete_for_platform = !@locked_specs.for(expand_dependencies(requested_dependencies & locked_dependencies), true, true)
|
||||
@locked_specs_incomplete_for_platform = !@locked_specs.for(requested_dependencies & expand_dependencies(locked_dependencies), true, true)
|
||||
|
||||
@requires = compute_requires
|
||||
end
|
||||
|
@ -234,16 +234,17 @@ module Bundler
|
|||
end
|
||||
|
||||
def specs_for(groups)
|
||||
groups = requested_groups if groups.empty?
|
||||
return specs if groups.empty?
|
||||
deps = dependencies_for(groups)
|
||||
materialize(expand_dependencies(deps))
|
||||
materialize(deps)
|
||||
end
|
||||
|
||||
def dependencies_for(groups)
|
||||
groups.map!(&:to_sym)
|
||||
current_dependencies.reject do |d|
|
||||
deps = current_dependencies.reject do |d|
|
||||
(d.groups & groups).empty?
|
||||
end
|
||||
expand_dependencies(deps)
|
||||
end
|
||||
|
||||
# Resolve all the dependencies specified in Gemfile. It ensures that
|
||||
|
|
|
@ -86,6 +86,7 @@ module Bundler
|
|||
|
||||
def warn_for_outdated_bundler_version
|
||||
return unless bundler_version
|
||||
return if bundler_version.segments.last == "dev"
|
||||
prerelease_text = bundler_version.prerelease? ? " --pre" : ""
|
||||
current_version = Gem::Version.create(Bundler::VERSION)
|
||||
return unless current_version < bundler_version
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-ADD" "1" "June 2021" "" ""
|
||||
.TH "BUNDLE\-ADD" "1" "November 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-BINSTUBS" "1" "June 2021" "" ""
|
||||
.TH "BUNDLE\-BINSTUBS" "1" "November 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-binstubs\fR \- Install the binstubs of the listed gems
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-CACHE" "1" "June 2021" "" ""
|
||||
.TH "BUNDLE\-CACHE" "1" "November 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-cache\fR \- Package your needed \fB\.gem\fR files into your application
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-CHECK" "1" "June 2021" "" ""
|
||||
.TH "BUNDLE\-CHECK" "1" "November 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-check\fR \- Verifies if dependencies are satisfied by installed gems
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-CLEAN" "1" "June 2021" "" ""
|
||||
.TH "BUNDLE\-CLEAN" "1" "November 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-clean\fR \- Cleans up unused gems in your bundler directory
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-CONFIG" "1" "June 2021" "" ""
|
||||
.TH "BUNDLE\-CONFIG" "1" "November 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-config\fR \- Set bundler configuration options
|
||||
|
@ -462,13 +462,13 @@ export BUNDLE_GITHUB__COM=abcd0123generatedtoken:x\-oauth\-basic
|
|||
.IP "" 0
|
||||
.
|
||||
.P
|
||||
Note that any configured credentials will be redacted by informative commands such as \fBbundle config list\fR or \fBbundle config get\fR, unless you use the \fB\-\-parseable\fR flag\. This is to avoid unintentially leaking credentials when copy\-pasting bundler output\.
|
||||
Note that any configured credentials will be redacted by informative commands such as \fBbundle config list\fR or \fBbundle config get\fR, unless you use the \fB\-\-parseable\fR flag\. This is to avoid unintentionally leaking credentials when copy\-pasting bundler output\.
|
||||
.
|
||||
.P
|
||||
Also note that to guarantee a sane mapping between valid environment variable names and valid host names, bundler makes the following transformations:
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
Any \fB\-\fR characters in a host name are mapped to a triple dash (\fB___\fR) in the corresponding enviroment variable\.
|
||||
Any \fB\-\fR characters in a host name are mapped to a triple dash (\fB___\fR) in the corresponding environment variable\.
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
Any \fB\.\fR characters in a host name are mapped to a double dash (\fB__\fR) in the corresponding environment variable\.
|
||||
|
|
|
@ -367,14 +367,14 @@ where you can use personal OAuth tokens:
|
|||
|
||||
Note that any configured credentials will be redacted by informative commands
|
||||
such as `bundle config list` or `bundle config get`, unless you use the
|
||||
`--parseable` flag. This is to avoid unintentially leaking credentials when
|
||||
`--parseable` flag. This is to avoid unintentionally leaking credentials when
|
||||
copy-pasting bundler output.
|
||||
|
||||
Also note that to guarantee a sane mapping between valid environment variable
|
||||
names and valid host names, bundler makes the following transformations:
|
||||
|
||||
* Any `-` characters in a host name are mapped to a triple dash (`___`) in the
|
||||
corresponding enviroment variable.
|
||||
corresponding environment variable.
|
||||
|
||||
* Any `.` characters in a host name are mapped to a double dash (`__`) in the
|
||||
corresponding environment variable.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-DOCTOR" "1" "June 2021" "" ""
|
||||
.TH "BUNDLE\-DOCTOR" "1" "November 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-doctor\fR \- Checks the bundle for common problems
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-EXEC" "1" "June 2021" "" ""
|
||||
.TH "BUNDLE\-EXEC" "1" "November 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-exec\fR \- Execute a command in the context of the bundle
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-GEM" "1" "June 2021" "" ""
|
||||
.TH "BUNDLE\-GEM" "1" "November 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-gem\fR \- Generate a project skeleton for creating a rubygem
|
||||
|
@ -90,6 +90,19 @@ When Bundler is configured to not generate CI files, an interactive prompt will
|
|||
When Bundler is unconfigured, an interactive prompt will be displayed and the answer will be saved in Bundler\'s global config for future \fBbundle gem\fR use\.
|
||||
.
|
||||
.TP
|
||||
\fB\-\-linter\fR, \fB\-\-linter=rubocop\fR, \fB\-\-linter=standard\fR
|
||||
Specify the linter and code formatter that Bundler should add to the project\'s development dependencies\. Acceptable values are \fBrubocop\fR and \fBstandard\fR\. A configuration file will be generated in the project directory\. Given no option is specified:
|
||||
.
|
||||
.IP
|
||||
When Bundler is configured to add a linter, this defaults to Bundler\'s global config setting \fBgem\.linter\fR\.
|
||||
.
|
||||
.IP
|
||||
When Bundler is configured not to add a linter, an interactive prompt will be displayed and the answer will be used for the current rubygem project\.
|
||||
.
|
||||
.IP
|
||||
When Bundler is unconfigured, an interactive prompt will be displayed and the answer will be saved in Bundler\'s global config for future \fBbundle gem\fR use\.
|
||||
.
|
||||
.TP
|
||||
\fB\-e\fR, \fB\-\-edit[=EDITOR]\fR
|
||||
Open the resulting GEM_NAME\.gemspec in EDITOR, or the default editor if not specified\. The default is \fB$BUNDLER_EDITOR\fR, \fB$VISUAL\fR, or \fB$EDITOR\fR\.
|
||||
.
|
||||
|
|
|
@ -92,6 +92,22 @@ configuration file using the following names:
|
|||
the answer will be saved in Bundler's global config for future `bundle gem`
|
||||
use.
|
||||
|
||||
* `--linter`, `--linter=rubocop`, `--linter=standard`:
|
||||
Specify the linter and code formatter that Bundler should add to the
|
||||
project's development dependencies. Acceptable values are `rubocop` and
|
||||
`standard`. A configuration file will be generated in the project directory.
|
||||
Given no option is specified:
|
||||
|
||||
When Bundler is configured to add a linter, this defaults to Bundler's
|
||||
global config setting `gem.linter`.
|
||||
|
||||
When Bundler is configured not to add a linter, an interactive prompt
|
||||
will be displayed and the answer will be used for the current rubygem project.
|
||||
|
||||
When Bundler is unconfigured, an interactive prompt will be displayed and
|
||||
the answer will be saved in Bundler's global config for future `bundle gem`
|
||||
use.
|
||||
|
||||
* `-e`, `--edit[=EDITOR]`:
|
||||
Open the resulting GEM_NAME.gemspec in EDITOR, or the default editor if not
|
||||
specified. The default is `$BUNDLER_EDITOR`, `$VISUAL`, or `$EDITOR`.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-INFO" "1" "June 2021" "" ""
|
||||
.TH "BUNDLE\-INFO" "1" "November 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-info\fR \- Show information for the given gem in your bundle
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-INIT" "1" "June 2021" "" ""
|
||||
.TH "BUNDLE\-INIT" "1" "November 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-init\fR \- Generates a Gemfile into the current working directory
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-INJECT" "1" "June 2021" "" ""
|
||||
.TH "BUNDLE\-INJECT" "1" "November 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-inject\fR \- Add named gem(s) with version requirements to Gemfile
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-INSTALL" "1" "June 2021" "" ""
|
||||
.TH "BUNDLE\-INSTALL" "1" "November 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-install\fR \- Install the dependencies specified in your Gemfile
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-LIST" "1" "June 2021" "" ""
|
||||
.TH "BUNDLE\-LIST" "1" "November 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-list\fR \- List all the gems in the bundle
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-LOCK" "1" "June 2021" "" ""
|
||||
.TH "BUNDLE\-LOCK" "1" "November 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-lock\fR \- Creates / Updates a lockfile without installing
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-OPEN" "1" "June 2021" "" ""
|
||||
.TH "BUNDLE\-OPEN" "1" "November 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-open\fR \- Opens the source directory for a gem in your bundle
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-OUTDATED" "1" "June 2021" "" ""
|
||||
.TH "BUNDLE\-OUTDATED" "1" "November 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-outdated\fR \- List installed gems with newer versions available
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-PLATFORM" "1" "June 2021" "" ""
|
||||
.TH "BUNDLE\-PLATFORM" "1" "November 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-platform\fR \- Displays platform compatibility information
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-PRISTINE" "1" "June 2021" "" ""
|
||||
.TH "BUNDLE\-PRISTINE" "1" "November 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-pristine\fR \- Restores installed gems to their pristine condition
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-REMOVE" "1" "June 2021" "" ""
|
||||
.TH "BUNDLE\-REMOVE" "1" "November 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-remove\fR \- Removes gems from the Gemfile
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-SHOW" "1" "June 2021" "" ""
|
||||
.TH "BUNDLE\-SHOW" "1" "November 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-show\fR \- Shows all the gems in your bundle, or the path to a gem
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-UPDATE" "1" "June 2021" "" ""
|
||||
.TH "BUNDLE\-UPDATE" "1" "November 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-update\fR \- Update your gems to the latest available versions
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-VIZ" "1" "June 2021" "" ""
|
||||
.TH "BUNDLE\-VIZ" "1" "November 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-viz\fR \- Generates a visual dependency graph for your Gemfile
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE" "1" "June 2021" "" ""
|
||||
.TH "BUNDLE" "1" "November 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\fR \- Ruby Dependency Management
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "GEMFILE" "5" "June 2021" "" ""
|
||||
.TH "GEMFILE" "5" "November 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBGemfile\fR \- A format for describing gem dependencies for Ruby programs
|
||||
|
|
|
@ -265,7 +265,7 @@ module Bundler
|
|||
|
||||
return if manuals.empty?
|
||||
Bundler::SharedHelpers.set_env "MANPATH", manuals.concat(
|
||||
ENV["MANPATH"].to_s.split(File::PATH_SEPARATOR)
|
||||
ENV["MANPATH"] ? ENV["MANPATH"].to_s.split(File::PATH_SEPARATOR) : [""]
|
||||
).uniq.join(File::PATH_SEPARATOR)
|
||||
end
|
||||
|
||||
|
|
|
@ -56,7 +56,6 @@ module Bundler
|
|||
@ref = ref
|
||||
@revision = revision
|
||||
@git = git
|
||||
raise GitNotInstalledError.new if allow? && !Bundler.git_present?
|
||||
end
|
||||
|
||||
def revision
|
||||
|
@ -208,7 +207,11 @@ module Bundler
|
|||
end
|
||||
|
||||
def allow?
|
||||
@git ? @git.allow_git_ops? : true
|
||||
allowed = @git ? @git.allow_git_ops? : true
|
||||
|
||||
raise GitNotInstalledError.new if allowed && !Bundler.git_present?
|
||||
|
||||
allowed
|
||||
end
|
||||
|
||||
def with_path(&blk)
|
||||
|
|
|
@ -162,7 +162,7 @@ module Bundler
|
|||
begin
|
||||
s = Bundler.rubygems.spec_from_gem(path, Bundler.settings["trust-policy"])
|
||||
spec.__swap__(s)
|
||||
rescue StandardError
|
||||
rescue Gem::Package::FormatError
|
||||
Bundler.rm_rf(path)
|
||||
raise
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "tsort"
|
||||
require_relative "vendored_tsort"
|
||||
|
||||
module Bundler
|
||||
class SpecSet
|
||||
|
|
|
@ -14,7 +14,10 @@ gem "rake-compiler"
|
|||
|
||||
gem "<%= config[:test] %>", "~> <%= config[:test_framework_version] %>"
|
||||
<%- end -%>
|
||||
<%- if config[:rubocop] -%>
|
||||
<%- if config[:linter] == "rubocop" -%>
|
||||
|
||||
gem "rubocop", "~> <%= config[:rubocop_version] %>"
|
||||
gem "rubocop", "~> <%= config[:linter_version] %>"
|
||||
<%- elsif config[:linter] == "standard" -%>
|
||||
|
||||
gem "standard", "~> <%= config[:linter_version] %>"
|
||||
<%- end -%>
|
||||
|
|
|
@ -18,12 +18,16 @@ require "rspec/core/rake_task"
|
|||
RSpec::Core::RakeTask.new(:spec)
|
||||
|
||||
<% end -%>
|
||||
<% if config[:rubocop] -%>
|
||||
<% if config[:linter] == "rubocop" -%>
|
||||
<% default_task_names << :rubocop -%>
|
||||
require "rubocop/rake_task"
|
||||
|
||||
RuboCop::RakeTask.new
|
||||
|
||||
<% elsif config[:linter] == "standard" -%>
|
||||
<% default_task_names << :standard -%>
|
||||
require "standard/rake"
|
||||
|
||||
<% end -%>
|
||||
<% if config[:ext] -%>
|
||||
<% default_task_names.unshift(:clobber, :compile) -%>
|
||||
|
|
|
@ -3,16 +3,16 @@
|
|||
require_relative "lib/<%=config[:namespaced_path]%>/version"
|
||||
|
||||
Gem::Specification.new do |spec|
|
||||
spec.name = <%= config[:name].inspect %>
|
||||
spec.version = <%= config[:constant_name] %>::VERSION
|
||||
spec.authors = [<%= config[:author].inspect %>]
|
||||
spec.email = [<%= config[:email].inspect %>]
|
||||
spec.name = <%= config[:name].inspect %>
|
||||
spec.version = <%= config[:constant_name] %>::VERSION
|
||||
spec.authors = [<%= config[:author].inspect %>]
|
||||
spec.email = [<%= config[:email].inspect %>]
|
||||
|
||||
spec.summary = "TODO: Write a short summary, because RubyGems requires one."
|
||||
spec.description = "TODO: Write a longer description or delete this line."
|
||||
spec.homepage = "TODO: Put your gem's website or public repo URL here."
|
||||
spec.summary = "TODO: Write a short summary, because RubyGems requires one."
|
||||
spec.description = "TODO: Write a longer description or delete this line."
|
||||
spec.homepage = "TODO: Put your gem's website or public repo URL here."
|
||||
<%- if config[:mit] -%>
|
||||
spec.license = "MIT"
|
||||
spec.license = "MIT"
|
||||
<%- end -%>
|
||||
spec.required_ruby_version = ">= <%= config[:required_ruby_version] %>"
|
||||
|
||||
|
@ -29,11 +29,11 @@ Gem::Specification.new do |spec|
|
|||
(f == __FILE__) || f.match(%r{\A(?:(?:test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
||||
end
|
||||
end
|
||||
spec.bindir = "exe"
|
||||
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
||||
spec.bindir = "exe"
|
||||
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
||||
spec.require_paths = ["lib"]
|
||||
<%- if config[:ext] -%>
|
||||
spec.extensions = ["ext/<%= config[:underscored_name] %>/extconf.rb"]
|
||||
spec.extensions = ["ext/<%= config[:underscored_name] %>/extconf.rb"]
|
||||
<%- end -%>
|
||||
|
||||
# Uncomment to register a new dependency of your gem
|
||||
|
|
4
lib/bundler/templates/newgem/standard.yml.tt
Normal file
4
lib/bundler/templates/newgem/standard.yml.tt
Normal file
|
@ -0,0 +1,4 @@
|
|||
# For available configuration options, see:
|
||||
# https://github.com/testdouble/standard
|
||||
|
||||
default_ignores: false
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'tsort'
|
||||
require_relative '../../../../vendored_tsort'
|
||||
|
||||
require_relative 'dependency_graph/log'
|
||||
require_relative 'dependency_graph/vertex'
|
||||
|
@ -17,7 +17,7 @@ module Bundler::Molinillo
|
|||
vertices.values.each { |v| yield v }
|
||||
end
|
||||
|
||||
include TSort
|
||||
include Bundler::TSort
|
||||
|
||||
# @!visibility private
|
||||
alias tsort_each_node each
|
||||
|
|
453
lib/bundler/vendor/tsort/lib/tsort.rb
vendored
Normal file
453
lib/bundler/vendor/tsort/lib/tsort.rb
vendored
Normal file
|
@ -0,0 +1,453 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
#--
|
||||
# tsort.rb - provides a module for topological sorting and strongly connected components.
|
||||
#++
|
||||
#
|
||||
|
||||
#
|
||||
# TSort implements topological sorting using Tarjan's algorithm for
|
||||
# strongly connected components.
|
||||
#
|
||||
# TSort is designed to be able to be used with any object which can be
|
||||
# interpreted as a directed graph.
|
||||
#
|
||||
# TSort requires two methods to interpret an object as a graph,
|
||||
# tsort_each_node and tsort_each_child.
|
||||
#
|
||||
# * tsort_each_node is used to iterate for all nodes over a graph.
|
||||
# * tsort_each_child is used to iterate for child nodes of a given node.
|
||||
#
|
||||
# The equality of nodes are defined by eql? and hash since
|
||||
# TSort uses Hash internally.
|
||||
#
|
||||
# == A Simple Example
|
||||
#
|
||||
# The following example demonstrates how to mix the TSort module into an
|
||||
# existing class (in this case, Hash). Here, we're treating each key in
|
||||
# the hash as a node in the graph, and so we simply alias the required
|
||||
# #tsort_each_node method to Hash's #each_key method. For each key in the
|
||||
# hash, the associated value is an array of the node's child nodes. This
|
||||
# choice in turn leads to our implementation of the required #tsort_each_child
|
||||
# method, which fetches the array of child nodes and then iterates over that
|
||||
# array using the user-supplied block.
|
||||
#
|
||||
# require 'tsort'
|
||||
#
|
||||
# class Hash
|
||||
# include TSort
|
||||
# alias tsort_each_node each_key
|
||||
# def tsort_each_child(node, &block)
|
||||
# fetch(node).each(&block)
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# {1=>[2, 3], 2=>[3], 3=>[], 4=>[]}.tsort
|
||||
# #=> [3, 2, 1, 4]
|
||||
#
|
||||
# {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}.strongly_connected_components
|
||||
# #=> [[4], [2, 3], [1]]
|
||||
#
|
||||
# == A More Realistic Example
|
||||
#
|
||||
# A very simple `make' like tool can be implemented as follows:
|
||||
#
|
||||
# require 'tsort'
|
||||
#
|
||||
# class Make
|
||||
# def initialize
|
||||
# @dep = {}
|
||||
# @dep.default = []
|
||||
# end
|
||||
#
|
||||
# def rule(outputs, inputs=[], &block)
|
||||
# triple = [outputs, inputs, block]
|
||||
# outputs.each {|f| @dep[f] = [triple]}
|
||||
# @dep[triple] = inputs
|
||||
# end
|
||||
#
|
||||
# def build(target)
|
||||
# each_strongly_connected_component_from(target) {|ns|
|
||||
# if ns.length != 1
|
||||
# fs = ns.delete_if {|n| Array === n}
|
||||
# raise TSort::Cyclic.new("cyclic dependencies: #{fs.join ', '}")
|
||||
# end
|
||||
# n = ns.first
|
||||
# if Array === n
|
||||
# outputs, inputs, block = n
|
||||
# inputs_time = inputs.map {|f| File.mtime f}.max
|
||||
# begin
|
||||
# outputs_time = outputs.map {|f| File.mtime f}.min
|
||||
# rescue Errno::ENOENT
|
||||
# outputs_time = nil
|
||||
# end
|
||||
# if outputs_time == nil ||
|
||||
# inputs_time != nil && outputs_time <= inputs_time
|
||||
# sleep 1 if inputs_time != nil && inputs_time.to_i == Time.now.to_i
|
||||
# block.call
|
||||
# end
|
||||
# end
|
||||
# }
|
||||
# end
|
||||
#
|
||||
# def tsort_each_child(node, &block)
|
||||
# @dep[node].each(&block)
|
||||
# end
|
||||
# include TSort
|
||||
# end
|
||||
#
|
||||
# def command(arg)
|
||||
# print arg, "\n"
|
||||
# system arg
|
||||
# end
|
||||
#
|
||||
# m = Make.new
|
||||
# m.rule(%w[t1]) { command 'date > t1' }
|
||||
# m.rule(%w[t2]) { command 'date > t2' }
|
||||
# m.rule(%w[t3]) { command 'date > t3' }
|
||||
# m.rule(%w[t4], %w[t1 t3]) { command 'cat t1 t3 > t4' }
|
||||
# m.rule(%w[t5], %w[t4 t2]) { command 'cat t4 t2 > t5' }
|
||||
# m.build('t5')
|
||||
#
|
||||
# == Bugs
|
||||
#
|
||||
# * 'tsort.rb' is wrong name because this library uses
|
||||
# Tarjan's algorithm for strongly connected components.
|
||||
# Although 'strongly_connected_components.rb' is correct but too long.
|
||||
#
|
||||
# == References
|
||||
#
|
||||
# R. E. Tarjan, "Depth First Search and Linear Graph Algorithms",
|
||||
# <em>SIAM Journal on Computing</em>, Vol. 1, No. 2, pp. 146-160, June 1972.
|
||||
#
|
||||
module Bundler
|
||||
module TSort
|
||||
class Cyclic < StandardError
|
||||
end
|
||||
|
||||
# Returns a topologically sorted array of nodes.
|
||||
# The array is sorted from children to parents, i.e.
|
||||
# the first element has no child and the last node has no parent.
|
||||
#
|
||||
# If there is a cycle, TSort::Cyclic is raised.
|
||||
#
|
||||
# class G
|
||||
# include TSort
|
||||
# def initialize(g)
|
||||
# @g = g
|
||||
# end
|
||||
# def tsort_each_child(n, &b) @g[n].each(&b) end
|
||||
# def tsort_each_node(&b) @g.each_key(&b) end
|
||||
# end
|
||||
#
|
||||
# graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
|
||||
# p graph.tsort #=> [4, 2, 3, 1]
|
||||
#
|
||||
# graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
|
||||
# p graph.tsort # raises TSort::Cyclic
|
||||
#
|
||||
def tsort
|
||||
each_node = method(:tsort_each_node)
|
||||
each_child = method(:tsort_each_child)
|
||||
TSort.tsort(each_node, each_child)
|
||||
end
|
||||
|
||||
# Returns a topologically sorted array of nodes.
|
||||
# The array is sorted from children to parents, i.e.
|
||||
# the first element has no child and the last node has no parent.
|
||||
#
|
||||
# The graph is represented by _each_node_ and _each_child_.
|
||||
# _each_node_ should have +call+ method which yields for each node in the graph.
|
||||
# _each_child_ should have +call+ method which takes a node argument and yields for each child node.
|
||||
#
|
||||
# If there is a cycle, TSort::Cyclic is raised.
|
||||
#
|
||||
# g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
|
||||
# each_node = lambda {|&b| g.each_key(&b) }
|
||||
# each_child = lambda {|n, &b| g[n].each(&b) }
|
||||
# p TSort.tsort(each_node, each_child) #=> [4, 2, 3, 1]
|
||||
#
|
||||
# g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
|
||||
# each_node = lambda {|&b| g.each_key(&b) }
|
||||
# each_child = lambda {|n, &b| g[n].each(&b) }
|
||||
# p TSort.tsort(each_node, each_child) # raises TSort::Cyclic
|
||||
#
|
||||
def TSort.tsort(each_node, each_child)
|
||||
TSort.tsort_each(each_node, each_child).to_a
|
||||
end
|
||||
|
||||
# The iterator version of the #tsort method.
|
||||
# <tt><em>obj</em>.tsort_each</tt> is similar to <tt><em>obj</em>.tsort.each</tt>, but
|
||||
# modification of _obj_ during the iteration may lead to unexpected results.
|
||||
#
|
||||
# #tsort_each returns +nil+.
|
||||
# If there is a cycle, TSort::Cyclic is raised.
|
||||
#
|
||||
# class G
|
||||
# include TSort
|
||||
# def initialize(g)
|
||||
# @g = g
|
||||
# end
|
||||
# def tsort_each_child(n, &b) @g[n].each(&b) end
|
||||
# def tsort_each_node(&b) @g.each_key(&b) end
|
||||
# end
|
||||
#
|
||||
# graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
|
||||
# graph.tsort_each {|n| p n }
|
||||
# #=> 4
|
||||
# # 2
|
||||
# # 3
|
||||
# # 1
|
||||
#
|
||||
def tsort_each(&block) # :yields: node
|
||||
each_node = method(:tsort_each_node)
|
||||
each_child = method(:tsort_each_child)
|
||||
TSort.tsort_each(each_node, each_child, &block)
|
||||
end
|
||||
|
||||
# The iterator version of the TSort.tsort method.
|
||||
#
|
||||
# The graph is represented by _each_node_ and _each_child_.
|
||||
# _each_node_ should have +call+ method which yields for each node in the graph.
|
||||
# _each_child_ should have +call+ method which takes a node argument and yields for each child node.
|
||||
#
|
||||
# g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
|
||||
# each_node = lambda {|&b| g.each_key(&b) }
|
||||
# each_child = lambda {|n, &b| g[n].each(&b) }
|
||||
# TSort.tsort_each(each_node, each_child) {|n| p n }
|
||||
# #=> 4
|
||||
# # 2
|
||||
# # 3
|
||||
# # 1
|
||||
#
|
||||
def TSort.tsort_each(each_node, each_child) # :yields: node
|
||||
return to_enum(__method__, each_node, each_child) unless block_given?
|
||||
|
||||
TSort.each_strongly_connected_component(each_node, each_child) {|component|
|
||||
if component.size == 1
|
||||
yield component.first
|
||||
else
|
||||
raise Cyclic.new("topological sort failed: #{component.inspect}")
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
# Returns strongly connected components as an array of arrays of nodes.
|
||||
# The array is sorted from children to parents.
|
||||
# Each elements of the array represents a strongly connected component.
|
||||
#
|
||||
# class G
|
||||
# include TSort
|
||||
# def initialize(g)
|
||||
# @g = g
|
||||
# end
|
||||
# def tsort_each_child(n, &b) @g[n].each(&b) end
|
||||
# def tsort_each_node(&b) @g.each_key(&b) end
|
||||
# end
|
||||
#
|
||||
# graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
|
||||
# p graph.strongly_connected_components #=> [[4], [2], [3], [1]]
|
||||
#
|
||||
# graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
|
||||
# p graph.strongly_connected_components #=> [[4], [2, 3], [1]]
|
||||
#
|
||||
def strongly_connected_components
|
||||
each_node = method(:tsort_each_node)
|
||||
each_child = method(:tsort_each_child)
|
||||
TSort.strongly_connected_components(each_node, each_child)
|
||||
end
|
||||
|
||||
# Returns strongly connected components as an array of arrays of nodes.
|
||||
# The array is sorted from children to parents.
|
||||
# Each elements of the array represents a strongly connected component.
|
||||
#
|
||||
# The graph is represented by _each_node_ and _each_child_.
|
||||
# _each_node_ should have +call+ method which yields for each node in the graph.
|
||||
# _each_child_ should have +call+ method which takes a node argument and yields for each child node.
|
||||
#
|
||||
# g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
|
||||
# each_node = lambda {|&b| g.each_key(&b) }
|
||||
# each_child = lambda {|n, &b| g[n].each(&b) }
|
||||
# p TSort.strongly_connected_components(each_node, each_child)
|
||||
# #=> [[4], [2], [3], [1]]
|
||||
#
|
||||
# g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
|
||||
# each_node = lambda {|&b| g.each_key(&b) }
|
||||
# each_child = lambda {|n, &b| g[n].each(&b) }
|
||||
# p TSort.strongly_connected_components(each_node, each_child)
|
||||
# #=> [[4], [2, 3], [1]]
|
||||
#
|
||||
def TSort.strongly_connected_components(each_node, each_child)
|
||||
TSort.each_strongly_connected_component(each_node, each_child).to_a
|
||||
end
|
||||
|
||||
# The iterator version of the #strongly_connected_components method.
|
||||
# <tt><em>obj</em>.each_strongly_connected_component</tt> is similar to
|
||||
# <tt><em>obj</em>.strongly_connected_components.each</tt>, but
|
||||
# modification of _obj_ during the iteration may lead to unexpected results.
|
||||
#
|
||||
# #each_strongly_connected_component returns +nil+.
|
||||
#
|
||||
# class G
|
||||
# include TSort
|
||||
# def initialize(g)
|
||||
# @g = g
|
||||
# end
|
||||
# def tsort_each_child(n, &b) @g[n].each(&b) end
|
||||
# def tsort_each_node(&b) @g.each_key(&b) end
|
||||
# end
|
||||
#
|
||||
# graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
|
||||
# graph.each_strongly_connected_component {|scc| p scc }
|
||||
# #=> [4]
|
||||
# # [2]
|
||||
# # [3]
|
||||
# # [1]
|
||||
#
|
||||
# graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
|
||||
# graph.each_strongly_connected_component {|scc| p scc }
|
||||
# #=> [4]
|
||||
# # [2, 3]
|
||||
# # [1]
|
||||
#
|
||||
def each_strongly_connected_component(&block) # :yields: nodes
|
||||
each_node = method(:tsort_each_node)
|
||||
each_child = method(:tsort_each_child)
|
||||
TSort.each_strongly_connected_component(each_node, each_child, &block)
|
||||
end
|
||||
|
||||
# The iterator version of the TSort.strongly_connected_components method.
|
||||
#
|
||||
# The graph is represented by _each_node_ and _each_child_.
|
||||
# _each_node_ should have +call+ method which yields for each node in the graph.
|
||||
# _each_child_ should have +call+ method which takes a node argument and yields for each child node.
|
||||
#
|
||||
# g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
|
||||
# each_node = lambda {|&b| g.each_key(&b) }
|
||||
# each_child = lambda {|n, &b| g[n].each(&b) }
|
||||
# TSort.each_strongly_connected_component(each_node, each_child) {|scc| p scc }
|
||||
# #=> [4]
|
||||
# # [2]
|
||||
# # [3]
|
||||
# # [1]
|
||||
#
|
||||
# g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
|
||||
# each_node = lambda {|&b| g.each_key(&b) }
|
||||
# each_child = lambda {|n, &b| g[n].each(&b) }
|
||||
# TSort.each_strongly_connected_component(each_node, each_child) {|scc| p scc }
|
||||
# #=> [4]
|
||||
# # [2, 3]
|
||||
# # [1]
|
||||
#
|
||||
def TSort.each_strongly_connected_component(each_node, each_child) # :yields: nodes
|
||||
return to_enum(__method__, each_node, each_child) unless block_given?
|
||||
|
||||
id_map = {}
|
||||
stack = []
|
||||
each_node.call {|node|
|
||||
unless id_map.include? node
|
||||
TSort.each_strongly_connected_component_from(node, each_child, id_map, stack) {|c|
|
||||
yield c
|
||||
}
|
||||
end
|
||||
}
|
||||
nil
|
||||
end
|
||||
|
||||
# Iterates over strongly connected component in the subgraph reachable from
|
||||
# _node_.
|
||||
#
|
||||
# Return value is unspecified.
|
||||
#
|
||||
# #each_strongly_connected_component_from doesn't call #tsort_each_node.
|
||||
#
|
||||
# class G
|
||||
# include TSort
|
||||
# def initialize(g)
|
||||
# @g = g
|
||||
# end
|
||||
# def tsort_each_child(n, &b) @g[n].each(&b) end
|
||||
# def tsort_each_node(&b) @g.each_key(&b) end
|
||||
# end
|
||||
#
|
||||
# graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
|
||||
# graph.each_strongly_connected_component_from(2) {|scc| p scc }
|
||||
# #=> [4]
|
||||
# # [2]
|
||||
#
|
||||
# graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
|
||||
# graph.each_strongly_connected_component_from(2) {|scc| p scc }
|
||||
# #=> [4]
|
||||
# # [2, 3]
|
||||
#
|
||||
def each_strongly_connected_component_from(node, id_map={}, stack=[], &block) # :yields: nodes
|
||||
TSort.each_strongly_connected_component_from(node, method(:tsort_each_child), id_map, stack, &block)
|
||||
end
|
||||
|
||||
# Iterates over strongly connected components in a graph.
|
||||
# The graph is represented by _node_ and _each_child_.
|
||||
#
|
||||
# _node_ is the first node.
|
||||
# _each_child_ should have +call+ method which takes a node argument
|
||||
# and yields for each child node.
|
||||
#
|
||||
# Return value is unspecified.
|
||||
#
|
||||
# #TSort.each_strongly_connected_component_from is a class method and
|
||||
# it doesn't need a class to represent a graph which includes TSort.
|
||||
#
|
||||
# graph = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
|
||||
# each_child = lambda {|n, &b| graph[n].each(&b) }
|
||||
# TSort.each_strongly_connected_component_from(1, each_child) {|scc|
|
||||
# p scc
|
||||
# }
|
||||
# #=> [4]
|
||||
# # [2, 3]
|
||||
# # [1]
|
||||
#
|
||||
def TSort.each_strongly_connected_component_from(node, each_child, id_map={}, stack=[]) # :yields: nodes
|
||||
return to_enum(__method__, node, each_child, id_map, stack) unless block_given?
|
||||
|
||||
minimum_id = node_id = id_map[node] = id_map.size
|
||||
stack_length = stack.length
|
||||
stack << node
|
||||
|
||||
each_child.call(node) {|child|
|
||||
if id_map.include? child
|
||||
child_id = id_map[child]
|
||||
minimum_id = child_id if child_id && child_id < minimum_id
|
||||
else
|
||||
sub_minimum_id =
|
||||
TSort.each_strongly_connected_component_from(child, each_child, id_map, stack) {|c|
|
||||
yield c
|
||||
}
|
||||
minimum_id = sub_minimum_id if sub_minimum_id < minimum_id
|
||||
end
|
||||
}
|
||||
|
||||
if node_id == minimum_id
|
||||
component = stack.slice!(stack_length .. -1)
|
||||
component.each {|n| id_map[n] = nil}
|
||||
yield component
|
||||
end
|
||||
|
||||
minimum_id
|
||||
end
|
||||
|
||||
# Should be implemented by a extended class.
|
||||
#
|
||||
# #tsort_each_node is used to iterate for all nodes over a graph.
|
||||
#
|
||||
def tsort_each_node # :yields: node
|
||||
raise NotImplementedError.new
|
||||
end
|
||||
|
||||
# Should be implemented by a extended class.
|
||||
#
|
||||
# #tsort_each_child is used to iterate for child nodes of _node_.
|
||||
#
|
||||
def tsort_each_child(node) # :yields: child
|
||||
raise NotImplementedError.new
|
||||
end
|
||||
end
|
||||
end
|
4
lib/bundler/vendored_tsort.rb
Normal file
4
lib/bundler/vendored_tsort.rb
Normal file
|
@ -0,0 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Bundler; end
|
||||
require_relative "vendor/tsort/lib/tsort"
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: false
|
||||
|
||||
module Bundler
|
||||
VERSION = "2.2.30".freeze
|
||||
VERSION = "2.2.31".freeze
|
||||
|
||||
def self.bundler_major_version
|
||||
@bundler_major_version ||= VERSION.split(".").first.to_i
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
require 'rbconfig'
|
||||
|
||||
module Gem
|
||||
VERSION = "3.2.30".freeze
|
||||
VERSION = "3.2.31".freeze
|
||||
end
|
||||
|
||||
# Must be first since it unloads the prelude from 1.9.2
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# See LICENSE.txt for permissions.
|
||||
#++
|
||||
|
||||
require 'optparse'
|
||||
require_relative 'optparse'
|
||||
require_relative 'requirement'
|
||||
require_relative 'user_interaction'
|
||||
|
||||
|
@ -19,7 +19,7 @@ require_relative 'user_interaction'
|
|||
class Gem::Command
|
||||
include Gem::UserInteraction
|
||||
|
||||
OptionParser.accept Symbol do |value|
|
||||
Gem::OptionParser.accept Symbol do |value|
|
||||
value.to_sym
|
||||
end
|
||||
|
||||
|
@ -344,7 +344,7 @@ class Gem::Command
|
|||
##
|
||||
# Add a command-line option and handler to the command.
|
||||
#
|
||||
# See OptionParser#make_switch for an explanation of +opts+.
|
||||
# See Gem::OptionParser#make_switch for an explanation of +opts+.
|
||||
#
|
||||
# +handler+ will be called with two values, the value of the argument and
|
||||
# the options hash.
|
||||
|
@ -540,7 +540,7 @@ class Gem::Command
|
|||
# command.
|
||||
|
||||
def create_option_parser
|
||||
@parser = OptionParser.new
|
||||
@parser = Gem::OptionParser.new
|
||||
|
||||
add_parser_options
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ class Gem::Commands::CertCommand < Gem::Command
|
|||
add_option('-s', '--sign CERT',
|
||||
'Signs CERT with the key from -K',
|
||||
'and the certificate from -C') do |cert_file, options|
|
||||
raise OptionParser::InvalidArgument, "#{cert_file}: does not exist" unless
|
||||
raise Gem::OptionParser::InvalidArgument, "#{cert_file}: does not exist" unless
|
||||
File.file? cert_file
|
||||
|
||||
options[:sign] << cert_file
|
||||
|
@ -85,9 +85,9 @@ class Gem::Commands::CertCommand < Gem::Command
|
|||
check_openssl
|
||||
OpenSSL::X509::Certificate.new File.read certificate_file
|
||||
rescue Errno::ENOENT
|
||||
raise OptionParser::InvalidArgument, "#{certificate_file}: does not exist"
|
||||
raise Gem::OptionParser::InvalidArgument, "#{certificate_file}: does not exist"
|
||||
rescue OpenSSL::X509::CertificateError
|
||||
raise OptionParser::InvalidArgument,
|
||||
raise Gem::OptionParser::InvalidArgument,
|
||||
"#{certificate_file}: invalid X509 certificate"
|
||||
end
|
||||
|
||||
|
@ -95,13 +95,13 @@ class Gem::Commands::CertCommand < Gem::Command
|
|||
check_openssl
|
||||
passphrase = ENV['GEM_PRIVATE_KEY_PASSPHRASE']
|
||||
key = OpenSSL::PKey.read File.read(key_file), passphrase
|
||||
raise OptionParser::InvalidArgument,
|
||||
raise Gem::OptionParser::InvalidArgument,
|
||||
"#{key_file}: private key not found" unless key.private?
|
||||
key
|
||||
rescue Errno::ENOENT
|
||||
raise OptionParser::InvalidArgument, "#{key_file}: does not exist"
|
||||
raise Gem::OptionParser::InvalidArgument, "#{key_file}: does not exist"
|
||||
rescue OpenSSL::PKey::PKeyError, ArgumentError
|
||||
raise OptionParser::InvalidArgument, "#{key_file}: invalid RSA, DSA, or EC key"
|
||||
raise Gem::OptionParser::InvalidArgument, "#{key_file}: invalid RSA, DSA, or EC key"
|
||||
end
|
||||
|
||||
def execute
|
||||
|
|
|
@ -60,7 +60,7 @@ then repackaging it.
|
|||
specs_and_sources = filtered unless filtered.empty?
|
||||
end
|
||||
|
||||
spec, source = specs_and_sources.max_by {|s,| s.version }
|
||||
spec, source = specs_and_sources.max_by {|s,| s }
|
||||
|
||||
if spec.nil?
|
||||
show_lookup_failure gem_name, version, errors, options[:domain]
|
||||
|
|
|
@ -11,10 +11,10 @@ class Gem::Commands::ServerCommand < Gem::Command
|
|||
super 'server', 'Documentation and gem repository HTTP server',
|
||||
:port => 8808, :gemdir => [], :daemon => false
|
||||
|
||||
OptionParser.accept :Port do |port|
|
||||
Gem::OptionParser.accept :Port do |port|
|
||||
if port =~ /\A\d+\z/
|
||||
port = Integer port
|
||||
raise OptionParser::InvalidArgument, "#{port}: not a port number" if
|
||||
raise Gem::OptionParser::InvalidArgument, "#{port}: not a port number" if
|
||||
port > 65535
|
||||
|
||||
port
|
||||
|
@ -22,7 +22,7 @@ class Gem::Commands::ServerCommand < Gem::Command
|
|||
begin
|
||||
Socket.getservbyname port
|
||||
rescue SocketError
|
||||
raise OptionParser::InvalidArgument, "#{port}: no such named service"
|
||||
raise Gem::OptionParser::InvalidArgument, "#{port}: no such named service"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -149,13 +149,6 @@ By default, this RubyGems will install gem as:
|
|||
def execute
|
||||
@verbose = Gem.configuration.really_verbose
|
||||
|
||||
install_destdir = options[:destdir]
|
||||
|
||||
unless install_destdir.empty?
|
||||
ENV['GEM_HOME'] ||= File.join(install_destdir,
|
||||
Gem.default_dir.gsub(/^[a-zA-Z]:/, ''))
|
||||
end
|
||||
|
||||
check_ruby_version
|
||||
|
||||
require 'fileutils'
|
||||
|
@ -166,8 +159,8 @@ By default, this RubyGems will install gem as:
|
|||
end
|
||||
extend MakeDirs
|
||||
|
||||
lib_dir, bin_dir = make_destination_dirs install_destdir
|
||||
man_dir = generate_default_man_dir install_destdir
|
||||
lib_dir, bin_dir = make_destination_dirs
|
||||
man_dir = generate_default_man_dir
|
||||
|
||||
install_lib lib_dir
|
||||
|
||||
|
@ -258,35 +251,32 @@ By default, this RubyGems will install gem as:
|
|||
say "Installing #{tool} executable" if @verbose
|
||||
|
||||
Dir.chdir path do
|
||||
bin_files = Dir['*']
|
||||
bin_file = "gem"
|
||||
|
||||
bin_files -= %w[update_rubygems]
|
||||
dest_file = target_bin_path(bin_dir, bin_file)
|
||||
bin_tmp_file = File.join Dir.tmpdir, "#{bin_file}.#{$$}"
|
||||
|
||||
bin_files.each do |bin_file|
|
||||
dest_file = target_bin_path(bin_dir, bin_file)
|
||||
bin_tmp_file = File.join Dir.tmpdir, "#{bin_file}.#{$$}"
|
||||
begin
|
||||
bin = File.readlines bin_file
|
||||
bin[0] = shebang
|
||||
|
||||
begin
|
||||
bin = File.readlines bin_file
|
||||
bin[0] = shebang
|
||||
|
||||
File.open bin_tmp_file, 'w' do |fp|
|
||||
fp.puts bin.join
|
||||
end
|
||||
|
||||
install bin_tmp_file, dest_file, :mode => prog_mode
|
||||
bin_file_names << dest_file
|
||||
ensure
|
||||
rm bin_tmp_file
|
||||
File.open bin_tmp_file, 'w' do |fp|
|
||||
fp.puts bin.join
|
||||
end
|
||||
|
||||
next unless Gem.win_platform?
|
||||
install bin_tmp_file, dest_file, :mode => prog_mode
|
||||
bin_file_names << dest_file
|
||||
ensure
|
||||
rm bin_tmp_file
|
||||
end
|
||||
|
||||
begin
|
||||
bin_cmd_file = File.join Dir.tmpdir, "#{bin_file}.bat"
|
||||
next unless Gem.win_platform?
|
||||
|
||||
File.open bin_cmd_file, 'w' do |file|
|
||||
file.puts <<-TEXT
|
||||
begin
|
||||
bin_cmd_file = File.join Dir.tmpdir, "#{bin_file}.bat"
|
||||
|
||||
File.open bin_cmd_file, 'w' do |file|
|
||||
file.puts <<-TEXT
|
||||
@ECHO OFF
|
||||
IF NOT "%~f0" == "~f0" GOTO :WinNT
|
||||
@"#{File.basename(Gem.ruby).chomp('"')}" "#{dest_file}" %1 %2 %3 %4 %5 %6 %7 %8 %9
|
||||
|
@ -294,12 +284,11 @@ By default, this RubyGems will install gem as:
|
|||
:WinNT
|
||||
@"#{File.basename(Gem.ruby).chomp('"')}" "%~dpn0" %*
|
||||
TEXT
|
||||
end
|
||||
|
||||
install bin_cmd_file, "#{dest_file}.bat", :mode => prog_mode
|
||||
ensure
|
||||
rm bin_cmd_file
|
||||
end
|
||||
|
||||
install bin_cmd_file, "#{dest_file}.bat", :mode => prog_mode
|
||||
ensure
|
||||
rm bin_cmd_file
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -371,8 +360,7 @@ By default, this RubyGems will install gem as:
|
|||
end
|
||||
|
||||
def install_default_bundler_gem(bin_dir)
|
||||
specs_dir = Gem.default_specifications_dir
|
||||
specs_dir = File.join(options[:destdir], specs_dir) unless Gem.win_platform?
|
||||
specs_dir = File.join(default_dir, "specifications", "default")
|
||||
mkdir_p specs_dir, :mode => 0755
|
||||
|
||||
bundler_spec = Dir.chdir("bundler") { Gem::Specification.load("bundler.gemspec") }
|
||||
|
@ -387,8 +375,20 @@ By default, this RubyGems will install gem as:
|
|||
|
||||
bundler_spec = Gem::Specification.load(default_spec_path)
|
||||
|
||||
# The base_dir value for a specification is inferred by walking up from the
|
||||
# folder where the spec was `loaded_from`. In the case of default gems, we
|
||||
# walk up two levels, because they live at `specifications/default/`, whereas
|
||||
# in the case of regular gems we walk up just one level because they live at
|
||||
# `specifications/`. However, in this case, the gem we are installing is
|
||||
# misdetected as a regular gem, when it's a default gem in reality. This is
|
||||
# because when there's a `:destdir`, the `loaded_from` path has changed and
|
||||
# doesn't match `Gem.default_specifications_dir` which is the criteria to
|
||||
# tag a gem as a default gem. So, in that case, write the correct
|
||||
# `@base_dir` directly.
|
||||
bundler_spec.instance_variable_set(:@base_dir, File.dirname(File.dirname(specs_dir)))
|
||||
|
||||
# Remove gemspec that was same version of vendored bundler.
|
||||
normal_gemspec = File.join(Gem.default_dir, "specifications", "bundler-#{bundler_spec.version}.gemspec")
|
||||
normal_gemspec = File.join(default_dir, "specifications", "bundler-#{bundler_spec.version}.gemspec")
|
||||
if File.file? normal_gemspec
|
||||
File.delete normal_gemspec
|
||||
end
|
||||
|
@ -401,7 +401,6 @@ By default, this RubyGems will install gem as:
|
|||
end
|
||||
|
||||
bundler_bin_dir = bundler_spec.bin_dir
|
||||
bundler_bin_dir = File.join(options[:destdir], bundler_bin_dir) unless Gem.win_platform?
|
||||
mkdir_p bundler_bin_dir, :mode => 0755
|
||||
bundler_spec.executables.each do |e|
|
||||
cp File.join("bundler", bundler_spec.bindir, e), File.join(bundler_bin_dir, e)
|
||||
|
@ -424,11 +423,11 @@ By default, this RubyGems will install gem as:
|
|||
say "Bundler #{bundler_spec.version} installed"
|
||||
end
|
||||
|
||||
def make_destination_dirs(install_destdir)
|
||||
def make_destination_dirs
|
||||
lib_dir, bin_dir = Gem.default_rubygems_dirs
|
||||
|
||||
unless lib_dir
|
||||
lib_dir, bin_dir = generate_default_dirs(install_destdir)
|
||||
lib_dir, bin_dir = generate_default_dirs
|
||||
end
|
||||
|
||||
mkdir_p lib_dir, :mode => 0755
|
||||
|
@ -437,7 +436,7 @@ By default, this RubyGems will install gem as:
|
|||
return lib_dir, bin_dir
|
||||
end
|
||||
|
||||
def generate_default_man_dir(install_destdir)
|
||||
def generate_default_man_dir
|
||||
prefix = options[:prefix]
|
||||
|
||||
if prefix.empty?
|
||||
|
@ -447,14 +446,10 @@ By default, this RubyGems will install gem as:
|
|||
man_dir = File.join prefix, 'man'
|
||||
end
|
||||
|
||||
unless install_destdir.empty?
|
||||
man_dir = File.join install_destdir, man_dir.gsub(/^[a-zA-Z]:/, '')
|
||||
end
|
||||
|
||||
man_dir
|
||||
prepend_destdir_if_present(man_dir)
|
||||
end
|
||||
|
||||
def generate_default_dirs(install_destdir)
|
||||
def generate_default_dirs
|
||||
prefix = options[:prefix]
|
||||
site_or_vendor = options[:site_or_vendor]
|
||||
|
||||
|
@ -478,12 +473,7 @@ By default, this RubyGems will install gem as:
|
|||
end
|
||||
end
|
||||
|
||||
unless install_destdir.empty?
|
||||
lib_dir = File.join install_destdir, lib_dir.gsub(/^[a-zA-Z]:/, '')
|
||||
bin_dir = File.join install_destdir, bin_dir.gsub(/^[a-zA-Z]:/, '')
|
||||
end
|
||||
|
||||
[lib_dir, bin_dir]
|
||||
[prepend_destdir_if_present(lib_dir), prepend_destdir_if_present(bin_dir)]
|
||||
end
|
||||
|
||||
def files_in(dir)
|
||||
|
@ -629,6 +619,25 @@ abort "#{deprecation_message}"
|
|||
|
||||
private
|
||||
|
||||
def default_dir
|
||||
prefix = options[:prefix]
|
||||
|
||||
if prefix.empty?
|
||||
dir = Gem.default_dir
|
||||
else
|
||||
dir = prefix
|
||||
end
|
||||
|
||||
prepend_destdir_if_present(dir)
|
||||
end
|
||||
|
||||
def prepend_destdir_if_present(path)
|
||||
destdir = options[:destdir]
|
||||
return path if destdir.empty?
|
||||
|
||||
File.join(options[:destdir], path.gsub(/^[a-zA-Z]:/, ''))
|
||||
end
|
||||
|
||||
def install_file_list(files, dest_dir)
|
||||
files.each do |file|
|
||||
install_file file, dest_dir
|
||||
|
|
|
@ -81,7 +81,7 @@ class Gem::Commands::UninstallCommand < Gem::Command
|
|||
'Uninstall gem from the vendor directory.',
|
||||
'Only for use by gem repackagers.') do |value, options|
|
||||
unless Gem.vendor_dir
|
||||
raise OptionParser::InvalidOption.new 'your platform is not supported'
|
||||
raise Gem::OptionParser::InvalidOption.new 'your platform is not supported'
|
||||
end
|
||||
|
||||
alert_warning 'Use your OS package manager to uninstall vendor gems'
|
||||
|
|
|
@ -25,7 +25,7 @@ class Gem::Commands::UpdateCommand < Gem::Command
|
|||
|
||||
add_install_update_options
|
||||
|
||||
OptionParser.accept Gem::Version do |value|
|
||||
Gem::OptionParser.accept Gem::Version do |value|
|
||||
Gem::Version.new value
|
||||
|
||||
value
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# See LICENSE.txt for permissions.
|
||||
#++
|
||||
|
||||
require 'tsort'
|
||||
require_relative 'tsort'
|
||||
require_relative 'deprecate'
|
||||
|
||||
##
|
||||
|
@ -20,7 +20,7 @@ class Gem::DependencyList
|
|||
attr_reader :specs
|
||||
|
||||
include Enumerable
|
||||
include TSort
|
||||
include Gem::TSort
|
||||
|
||||
##
|
||||
# Allows enabling/disabling use of development dependencies
|
||||
|
|
|
@ -24,13 +24,14 @@ class Gem::Ext::Builder
|
|||
|
||||
# try to find make program from Ruby configure arguments first
|
||||
RbConfig::CONFIG['configure_args'] =~ /with-make-prog\=(\w+)/
|
||||
make_program = ENV['MAKE'] || ENV['make'] || $1
|
||||
unless make_program
|
||||
make_program = (/mswin/ =~ RUBY_PLATFORM) ? 'nmake' : 'make'
|
||||
make_program_name = ENV['MAKE'] || ENV['make'] || $1
|
||||
unless make_program_name
|
||||
make_program_name = (/mswin/ =~ RUBY_PLATFORM) ? 'nmake' : 'make'
|
||||
end
|
||||
make_program = Shellwords.split(make_program)
|
||||
make_program = Shellwords.split(make_program_name)
|
||||
|
||||
destdir = 'DESTDIR=%s' % ENV['DESTDIR']
|
||||
# The installation of the bundled gems is failed when DESTDIR is empty in mswin platform.
|
||||
destdir = (/\bnmake/i !~ make_program_name || ENV['DESTDIR'] && ENV['DESTDIR'] != "") ? 'DESTDIR=%s' % ENV['DESTDIR'] : ''
|
||||
|
||||
['clean', '', 'install'].each do |target|
|
||||
# Pass DESTDIR via command line to override what's in MAKEFLAGS
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
require_relative '../command'
|
||||
|
||||
class Gem::Ext::CmakeBuilder < Gem::Ext::Builder
|
||||
def self.build(extension, dest_path, results, args=[], lib_dir=nil, cmake_dir=Dir.pwd)
|
||||
unless File.exist?(File.join(cmake_dir, 'Makefile'))
|
||||
require_relative '../command'
|
||||
cmd = ["cmake", ".", "-DCMAKE_INSTALL_PREFIX=#{dest_path}", *Gem::Command.build_args]
|
||||
|
||||
run cmd, results, class_name, cmake_dir
|
||||
|
|
|
@ -51,7 +51,7 @@ module Gem::InstallUpdateOptions
|
|||
'Install gem into the vendor directory.',
|
||||
'Only for use by gem repackagers.') do |value, options|
|
||||
unless Gem.vendor_dir
|
||||
raise OptionParser::InvalidOption.new 'your platform is not supported'
|
||||
raise Gem::OptionParser::InvalidOption.new 'your platform is not supported'
|
||||
end
|
||||
|
||||
options[:vendor] = true
|
||||
|
@ -143,7 +143,7 @@ module Gem::InstallUpdateOptions
|
|||
unless v
|
||||
message = v ? v : "(tried #{Gem::GEM_DEP_FILES.join ', '})"
|
||||
|
||||
raise OptionParser::InvalidArgument,
|
||||
raise Gem::OptionParser::InvalidArgument,
|
||||
"cannot find gem dependencies file #{message}"
|
||||
end
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
# See LICENSE.txt for permissions.
|
||||
#++
|
||||
|
||||
require_relative 'command'
|
||||
require_relative 'installer_uninstaller_utils'
|
||||
require_relative 'exceptions'
|
||||
require_relative 'deprecate'
|
||||
|
@ -71,6 +70,23 @@ class Gem::Installer
|
|||
@install_lock = Thread::Mutex.new
|
||||
|
||||
class << self
|
||||
#
|
||||
# Changes in rubygems to lazily loading `rubygems/command` (in order to
|
||||
# lazily load `optparse` as a side effect) affect bundler's custom installer
|
||||
# which uses `Gem::Command` without requiring it (up until bundler 2.2.29).
|
||||
# This hook is to compensate for that missing require.
|
||||
#
|
||||
# TODO: Remove when rubygems no longer supports running on bundler older
|
||||
# than 2.2.29.
|
||||
|
||||
def inherited(klass)
|
||||
if klass.name == "Bundler::RubyGemsGemInstaller"
|
||||
require "rubygems/command"
|
||||
end
|
||||
|
||||
super(klass)
|
||||
end
|
||||
|
||||
##
|
||||
# True if we've warned about PATH not including Gem.bindir
|
||||
|
||||
|
@ -676,7 +692,7 @@ class Gem::Installer
|
|||
@development = options[:development]
|
||||
@build_root = options[:build_root]
|
||||
|
||||
@build_args = options[:build_args] || Gem::Command.build_args
|
||||
@build_args = options[:build_args]
|
||||
|
||||
unless @build_root.nil?
|
||||
@bin_dir = File.join(@build_root, @bin_dir.gsub(/^[a-zA-Z]:/, ''))
|
||||
|
@ -832,7 +848,7 @@ TEXT
|
|||
# configure scripts and rakefiles or mkrf_conf files.
|
||||
|
||||
def build_extensions
|
||||
builder = Gem::Ext::Builder.new spec, @build_args
|
||||
builder = Gem::Ext::Builder.new spec, build_args
|
||||
|
||||
builder.build_extensions
|
||||
end
|
||||
|
@ -919,7 +935,7 @@ TEXT
|
|||
# extensions.
|
||||
|
||||
def write_build_info_file
|
||||
return if @build_args.empty?
|
||||
return if build_args.empty?
|
||||
|
||||
build_info_dir = File.join gem_home, 'build_info'
|
||||
|
||||
|
@ -929,7 +945,7 @@ TEXT
|
|||
build_info_file = File.join build_info_dir, "#{spec.full_name}.info"
|
||||
|
||||
File.open build_info_file, 'w' do |io|
|
||||
@build_args.each do |arg|
|
||||
build_args.each do |arg|
|
||||
io.puts arg
|
||||
end
|
||||
end
|
||||
|
@ -954,4 +970,13 @@ TEXT
|
|||
|
||||
raise Gem::FilePermissionError.new(dir) unless File.writable? dir
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def build_args
|
||||
@build_args ||= begin
|
||||
require_relative "command"
|
||||
Gem::Command.build_args
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -14,14 +14,14 @@ require_relative '../rubygems'
|
|||
module Gem::LocalRemoteOptions
|
||||
|
||||
##
|
||||
# Allows OptionParser to handle HTTP URIs.
|
||||
# Allows Gem::OptionParser to handle HTTP URIs.
|
||||
|
||||
def accept_uri_http
|
||||
OptionParser.accept URI::HTTP do |value|
|
||||
Gem::OptionParser.accept URI::HTTP do |value|
|
||||
begin
|
||||
uri = URI.parse value
|
||||
rescue URI::InvalidURIError
|
||||
raise OptionParser::InvalidArgument, value
|
||||
raise Gem::OptionParser::InvalidArgument, value
|
||||
end
|
||||
|
||||
valid_uri_schemes = ["http", "https", "file", "s3"]
|
||||
|
|
3
lib/rubygems/optparse.rb
Normal file
3
lib/rubygems/optparse.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'optparse/lib/optparse'
|
2
lib/rubygems/optparse/lib/optionparser.rb
Normal file
2
lib/rubygems/optparse/lib/optionparser.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
# frozen_string_literal: false
|
||||
require_relative 'optparse'
|
2230
lib/rubygems/optparse/lib/optparse.rb
Normal file
2230
lib/rubygems/optparse/lib/optparse.rb
Normal file
File diff suppressed because it is too large
Load diff
54
lib/rubygems/optparse/lib/optparse/ac.rb
Normal file
54
lib/rubygems/optparse/lib/optparse/ac.rb
Normal file
|
@ -0,0 +1,54 @@
|
|||
# frozen_string_literal: false
|
||||
require 'rubygems/optparse/lib/optparse'
|
||||
|
||||
class Gem::OptionParser::AC < Gem::OptionParser
|
||||
private
|
||||
|
||||
def _check_ac_args(name, block)
|
||||
unless /\A\w[-\w]*\z/ =~ name
|
||||
raise ArgumentError, name
|
||||
end
|
||||
unless block
|
||||
raise ArgumentError, "no block given", ParseError.filter_backtrace(caller)
|
||||
end
|
||||
end
|
||||
|
||||
ARG_CONV = proc {|val| val.nil? ? true : val}
|
||||
|
||||
def _ac_arg_enable(prefix, name, help_string, block)
|
||||
_check_ac_args(name, block)
|
||||
|
||||
sdesc = []
|
||||
ldesc = ["--#{prefix}-#{name}"]
|
||||
desc = [help_string]
|
||||
q = name.downcase
|
||||
ac_block = proc {|val| block.call(ARG_CONV.call(val))}
|
||||
enable = Switch::PlacedArgument.new(nil, ARG_CONV, sdesc, ldesc, nil, desc, ac_block)
|
||||
disable = Switch::NoArgument.new(nil, proc {false}, sdesc, ldesc, nil, desc, ac_block)
|
||||
top.append(enable, [], ["enable-" + q], disable, ['disable-' + q])
|
||||
enable
|
||||
end
|
||||
|
||||
public
|
||||
|
||||
def ac_arg_enable(name, help_string, &block)
|
||||
_ac_arg_enable("enable", name, help_string, block)
|
||||
end
|
||||
|
||||
def ac_arg_disable(name, help_string, &block)
|
||||
_ac_arg_enable("disable", name, help_string, block)
|
||||
end
|
||||
|
||||
def ac_arg_with(name, help_string, &block)
|
||||
_check_ac_args(name, block)
|
||||
|
||||
sdesc = []
|
||||
ldesc = ["--with-#{name}"]
|
||||
desc = [help_string]
|
||||
q = name.downcase
|
||||
with = Switch::PlacedArgument.new(*search(:atype, String), sdesc, ldesc, nil, desc, block)
|
||||
without = Switch::NoArgument.new(nil, proc {}, sdesc, ldesc, nil, desc, block)
|
||||
top.append(with, [], ["with-" + q], without, ['without-' + q])
|
||||
with
|
||||
end
|
||||
end
|
18
lib/rubygems/optparse/lib/optparse/date.rb
Normal file
18
lib/rubygems/optparse/lib/optparse/date.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: false
|
||||
require 'rubygems/optparse/lib/optparse'
|
||||
require 'date'
|
||||
|
||||
Gem::OptionParser.accept(DateTime) do |s,|
|
||||
begin
|
||||
DateTime.parse(s) if s
|
||||
rescue ArgumentError
|
||||
raise Gem::OptionParser::InvalidArgument, s
|
||||
end
|
||||
end
|
||||
Gem::OptionParser.accept(Date) do |s,|
|
||||
begin
|
||||
Date.parse(s) if s
|
||||
rescue ArgumentError
|
||||
raise Gem::OptionParser::InvalidArgument, s
|
||||
end
|
||||
end
|
22
lib/rubygems/optparse/lib/optparse/kwargs.rb
Normal file
22
lib/rubygems/optparse/lib/optparse/kwargs.rb
Normal file
|
@ -0,0 +1,22 @@
|
|||
# frozen_string_literal: true
|
||||
require 'rubygems/optparse/lib/optparse'
|
||||
|
||||
class Gem::OptionParser
|
||||
# :call-seq:
|
||||
# define_by_keywords(options, method, **params)
|
||||
#
|
||||
# :include: ../../doc/optparse/creates_option.rdoc
|
||||
#
|
||||
def define_by_keywords(options, meth, **opts)
|
||||
meth.parameters.each do |type, name|
|
||||
case type
|
||||
when :key, :keyreq
|
||||
op, cl = *(type == :key ? %w"[ ]" : ["", ""])
|
||||
define("--#{name}=#{op}#{name.upcase}#{cl}", *opts[name]) do |o|
|
||||
options[name] = o
|
||||
end
|
||||
end
|
||||
end
|
||||
options
|
||||
end
|
||||
end
|
7
lib/rubygems/optparse/lib/optparse/shellwords.rb
Normal file
7
lib/rubygems/optparse/lib/optparse/shellwords.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: false
|
||||
# -*- ruby -*-
|
||||
|
||||
require 'shellwords'
|
||||
require 'rubygems/optparse/lib/optparse'
|
||||
|
||||
Gem::OptionParser.accept(Shellwords) {|s,| Shellwords.shellwords(s)}
|
11
lib/rubygems/optparse/lib/optparse/time.rb
Normal file
11
lib/rubygems/optparse/lib/optparse/time.rb
Normal file
|
@ -0,0 +1,11 @@
|
|||
# frozen_string_literal: false
|
||||
require 'rubygems/optparse/lib/optparse'
|
||||
require 'time'
|
||||
|
||||
Gem::OptionParser.accept(Time) do |s,|
|
||||
begin
|
||||
(Time.httpdate(s) rescue Time.parse(s)) if s
|
||||
rescue
|
||||
raise Gem::OptionParser::InvalidArgument, s
|
||||
end
|
||||
end
|
7
lib/rubygems/optparse/lib/optparse/uri.rb
Normal file
7
lib/rubygems/optparse/lib/optparse/uri.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: false
|
||||
# -*- ruby -*-
|
||||
|
||||
require 'rubygems/optparse/lib/optparse'
|
||||
require 'uri'
|
||||
|
||||
Gem::OptionParser.accept(URI) {|s,| URI.parse(s) if s}
|
71
lib/rubygems/optparse/lib/optparse/version.rb
Normal file
71
lib/rubygems/optparse/lib/optparse/version.rb
Normal file
|
@ -0,0 +1,71 @@
|
|||
# frozen_string_literal: false
|
||||
# Gem::OptionParser internal utility
|
||||
|
||||
class << Gem::OptionParser
|
||||
def show_version(*pkgs)
|
||||
progname = ARGV.options.program_name
|
||||
result = false
|
||||
show = proc do |klass, cname, version|
|
||||
str = "#{progname}"
|
||||
unless klass == ::Object and cname == :VERSION
|
||||
version = version.join(".") if Array === version
|
||||
str << ": #{klass}" unless klass == Object
|
||||
str << " version #{version}"
|
||||
end
|
||||
[:Release, :RELEASE].find do |rel|
|
||||
if klass.const_defined?(rel)
|
||||
str << " (#{klass.const_get(rel)})"
|
||||
end
|
||||
end
|
||||
puts str
|
||||
result = true
|
||||
end
|
||||
if pkgs.size == 1 and pkgs[0] == "all"
|
||||
self.search_const(::Object, /\AV(?:ERSION|ersion)\z/) do |klass, cname, version|
|
||||
unless cname[1] == ?e and klass.const_defined?(:Version)
|
||||
show.call(klass, cname.intern, version)
|
||||
end
|
||||
end
|
||||
else
|
||||
pkgs.each do |pkg|
|
||||
begin
|
||||
pkg = pkg.split(/::|\//).inject(::Object) {|m, c| m.const_get(c)}
|
||||
v = case
|
||||
when pkg.const_defined?(:Version)
|
||||
pkg.const_get(n = :Version)
|
||||
when pkg.const_defined?(:VERSION)
|
||||
pkg.const_get(n = :VERSION)
|
||||
else
|
||||
n = nil
|
||||
"unknown"
|
||||
end
|
||||
show.call(pkg, n, v)
|
||||
rescue NameError
|
||||
end
|
||||
end
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
def each_const(path, base = ::Object)
|
||||
path.split(/::|\//).inject(base) do |klass, name|
|
||||
raise NameError, path unless Module === klass
|
||||
klass.constants.grep(/#{name}/i) do |c|
|
||||
klass.const_defined?(c) or next
|
||||
klass.const_get(c)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def search_const(klass, name)
|
||||
klasses = [klass]
|
||||
while klass = klasses.shift
|
||||
klass.constants.each do |cname|
|
||||
klass.const_defined?(cname) or next
|
||||
const = klass.const_get(cname)
|
||||
yield klass, cname, const if name === cname
|
||||
klasses << const if Module === const and const != ::Object
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,5 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
require 'tsort'
|
||||
require_relative 'tsort'
|
||||
|
||||
##
|
||||
# A RequestSet groups a request to activate a set of dependencies.
|
||||
|
@ -15,7 +15,7 @@ require 'tsort'
|
|||
# #=> ["nokogiri-1.6.0", "mini_portile-0.5.1", "pg-0.17.0"]
|
||||
|
||||
class Gem::RequestSet
|
||||
include TSort
|
||||
include Gem::TSort
|
||||
|
||||
##
|
||||
# Array of gems to install even if already installed
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'tsort'
|
||||
require_relative '../../../../tsort'
|
||||
|
||||
require_relative 'dependency_graph/log'
|
||||
require_relative 'dependency_graph/vertex'
|
||||
|
@ -17,7 +17,7 @@ module Gem::Resolver::Molinillo
|
|||
vertices.values.each { |v| yield v }
|
||||
end
|
||||
|
||||
include TSort
|
||||
include Gem::TSort
|
||||
|
||||
# @!visibility private
|
||||
alias tsort_each_node each
|
||||
|
|
|
@ -19,16 +19,16 @@ end
|
|||
|
||||
module Gem::SecurityOption
|
||||
def add_security_option
|
||||
OptionParser.accept Gem::Security::Policy do |value|
|
||||
Gem::OptionParser.accept Gem::Security::Policy do |value|
|
||||
require_relative 'security'
|
||||
|
||||
raise OptionParser::InvalidArgument, 'OpenSSL not installed' unless
|
||||
raise Gem::OptionParser::InvalidArgument, 'OpenSSL not installed' unless
|
||||
defined?(Gem::Security::HighSecurity)
|
||||
|
||||
policy = Gem::Security::Policies[value]
|
||||
unless policy
|
||||
valid = Gem::Security::Policies.keys.sort
|
||||
raise OptionParser::InvalidArgument, "#{value} (#{valid.join ', '} are valid)"
|
||||
raise Gem::OptionParser::InvalidArgument, "#{value} (#{valid.join ', '} are valid)"
|
||||
end
|
||||
policy
|
||||
end
|
||||
|
|
|
@ -324,17 +324,21 @@ class Gem::Specification < Gem::BasicSpecification
|
|||
# This should just be the name of your license. The full text of the license
|
||||
# should be inside of the gem (at the top level) when you build it.
|
||||
#
|
||||
# The simplest way, is to specify the standard SPDX ID
|
||||
# The simplest way is to specify the standard SPDX ID
|
||||
# https://spdx.org/licenses/ for the license.
|
||||
# Ideally you should pick one that is OSI (Open Source Initiative)
|
||||
# Ideally, you should pick one that is OSI (Open Source Initiative)
|
||||
# http://opensource.org/licenses/alphabetical approved.
|
||||
#
|
||||
# The most commonly used OSI approved licenses are MIT and Apache-2.0.
|
||||
# The most commonly used OSI-approved licenses are MIT and Apache-2.0.
|
||||
# GitHub also provides a license picker at http://choosealicense.com/.
|
||||
#
|
||||
# You can also use a custom license file along with your gemspec and specify
|
||||
# a LicenseRef-<idstring>, where idstring is the name of the file containing
|
||||
# the license text.
|
||||
#
|
||||
# You should specify a license for your gem so that people know how they are
|
||||
# permitted to use it, and any restrictions you're placing on it. Not
|
||||
# specifying a license means all rights are reserved; others have no rights
|
||||
# permitted to use it and any restrictions you're placing on it. Not
|
||||
# specifying a license means all rights are reserved; others have no right
|
||||
# to use the code for any purpose.
|
||||
#
|
||||
# You can set multiple licenses with #licenses=
|
||||
|
|
3
lib/rubygems/tsort.rb
Normal file
3
lib/rubygems/tsort.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'tsort/lib/tsort'
|
454
lib/rubygems/tsort/lib/tsort.rb
Normal file
454
lib/rubygems/tsort/lib/tsort.rb
Normal file
|
@ -0,0 +1,454 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
#--
|
||||
# tsort.rb - provides a module for topological sorting and strongly connected components.
|
||||
#++
|
||||
#
|
||||
|
||||
#
|
||||
# Gem::TSort implements topological sorting using Tarjan's algorithm for
|
||||
# strongly connected components.
|
||||
#
|
||||
# Gem::TSort is designed to be able to be used with any object which can be
|
||||
# interpreted as a directed graph.
|
||||
#
|
||||
# Gem::TSort requires two methods to interpret an object as a graph,
|
||||
# tsort_each_node and tsort_each_child.
|
||||
#
|
||||
# * tsort_each_node is used to iterate for all nodes over a graph.
|
||||
# * tsort_each_child is used to iterate for child nodes of a given node.
|
||||
#
|
||||
# The equality of nodes are defined by eql? and hash since
|
||||
# Gem::TSort uses Hash internally.
|
||||
#
|
||||
# == A Simple Example
|
||||
#
|
||||
# The following example demonstrates how to mix the Gem::TSort module into an
|
||||
# existing class (in this case, Hash). Here, we're treating each key in
|
||||
# the hash as a node in the graph, and so we simply alias the required
|
||||
# #tsort_each_node method to Hash's #each_key method. For each key in the
|
||||
# hash, the associated value is an array of the node's child nodes. This
|
||||
# choice in turn leads to our implementation of the required #tsort_each_child
|
||||
# method, which fetches the array of child nodes and then iterates over that
|
||||
# array using the user-supplied block.
|
||||
#
|
||||
# require 'rubygems/tsort/lib/tsort'
|
||||
#
|
||||
# class Hash
|
||||
# include Gem::TSort
|
||||
# alias tsort_each_node each_key
|
||||
# def tsort_each_child(node, &block)
|
||||
# fetch(node).each(&block)
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# {1=>[2, 3], 2=>[3], 3=>[], 4=>[]}.tsort
|
||||
# #=> [3, 2, 1, 4]
|
||||
#
|
||||
# {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}.strongly_connected_components
|
||||
# #=> [[4], [2, 3], [1]]
|
||||
#
|
||||
# == A More Realistic Example
|
||||
#
|
||||
# A very simple `make' like tool can be implemented as follows:
|
||||
#
|
||||
# require 'rubygems/tsort/lib/tsort'
|
||||
#
|
||||
# class Make
|
||||
# def initialize
|
||||
# @dep = {}
|
||||
# @dep.default = []
|
||||
# end
|
||||
#
|
||||
# def rule(outputs, inputs=[], &block)
|
||||
# triple = [outputs, inputs, block]
|
||||
# outputs.each {|f| @dep[f] = [triple]}
|
||||
# @dep[triple] = inputs
|
||||
# end
|
||||
#
|
||||
# def build(target)
|
||||
# each_strongly_connected_component_from(target) {|ns|
|
||||
# if ns.length != 1
|
||||
# fs = ns.delete_if {|n| Array === n}
|
||||
# raise Gem::TSort::Cyclic.new("cyclic dependencies: #{fs.join ', '}")
|
||||
# end
|
||||
# n = ns.first
|
||||
# if Array === n
|
||||
# outputs, inputs, block = n
|
||||
# inputs_time = inputs.map {|f| File.mtime f}.max
|
||||
# begin
|
||||
# outputs_time = outputs.map {|f| File.mtime f}.min
|
||||
# rescue Errno::ENOENT
|
||||
# outputs_time = nil
|
||||
# end
|
||||
# if outputs_time == nil ||
|
||||
# inputs_time != nil && outputs_time <= inputs_time
|
||||
# sleep 1 if inputs_time != nil && inputs_time.to_i == Time.now.to_i
|
||||
# block.call
|
||||
# end
|
||||
# end
|
||||
# }
|
||||
# end
|
||||
#
|
||||
# def tsort_each_child(node, &block)
|
||||
# @dep[node].each(&block)
|
||||
# end
|
||||
# include Gem::TSort
|
||||
# end
|
||||
#
|
||||
# def command(arg)
|
||||
# print arg, "\n"
|
||||
# system arg
|
||||
# end
|
||||
#
|
||||
# m = Make.new
|
||||
# m.rule(%w[t1]) { command 'date > t1' }
|
||||
# m.rule(%w[t2]) { command 'date > t2' }
|
||||
# m.rule(%w[t3]) { command 'date > t3' }
|
||||
# m.rule(%w[t4], %w[t1 t3]) { command 'cat t1 t3 > t4' }
|
||||
# m.rule(%w[t5], %w[t4 t2]) { command 'cat t4 t2 > t5' }
|
||||
# m.build('t5')
|
||||
#
|
||||
# == Bugs
|
||||
#
|
||||
# * 'tsort.rb' is wrong name because this library uses
|
||||
# Tarjan's algorithm for strongly connected components.
|
||||
# Although 'strongly_connected_components.rb' is correct but too long.
|
||||
#
|
||||
# == References
|
||||
#
|
||||
# R. E. Tarjan, "Depth First Search and Linear Graph Algorithms",
|
||||
# <em>SIAM Journal on Computing</em>, Vol. 1, No. 2, pp. 146-160, June 1972.
|
||||
#
|
||||
|
||||
module Gem
|
||||
module TSort
|
||||
class Cyclic < StandardError
|
||||
end
|
||||
|
||||
# Returns a topologically sorted array of nodes.
|
||||
# The array is sorted from children to parents, i.e.
|
||||
# the first element has no child and the last node has no parent.
|
||||
#
|
||||
# If there is a cycle, Gem::TSort::Cyclic is raised.
|
||||
#
|
||||
# class G
|
||||
# include Gem::TSort
|
||||
# def initialize(g)
|
||||
# @g = g
|
||||
# end
|
||||
# def tsort_each_child(n, &b) @g[n].each(&b) end
|
||||
# def tsort_each_node(&b) @g.each_key(&b) end
|
||||
# end
|
||||
#
|
||||
# graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
|
||||
# p graph.tsort #=> [4, 2, 3, 1]
|
||||
#
|
||||
# graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
|
||||
# p graph.tsort # raises Gem::TSort::Cyclic
|
||||
#
|
||||
def tsort
|
||||
each_node = method(:tsort_each_node)
|
||||
each_child = method(:tsort_each_child)
|
||||
Gem::TSort.tsort(each_node, each_child)
|
||||
end
|
||||
|
||||
# Returns a topologically sorted array of nodes.
|
||||
# The array is sorted from children to parents, i.e.
|
||||
# the first element has no child and the last node has no parent.
|
||||
#
|
||||
# The graph is represented by _each_node_ and _each_child_.
|
||||
# _each_node_ should have +call+ method which yields for each node in the graph.
|
||||
# _each_child_ should have +call+ method which takes a node argument and yields for each child node.
|
||||
#
|
||||
# If there is a cycle, Gem::TSort::Cyclic is raised.
|
||||
#
|
||||
# g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
|
||||
# each_node = lambda {|&b| g.each_key(&b) }
|
||||
# each_child = lambda {|n, &b| g[n].each(&b) }
|
||||
# p Gem::TSort.tsort(each_node, each_child) #=> [4, 2, 3, 1]
|
||||
#
|
||||
# g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
|
||||
# each_node = lambda {|&b| g.each_key(&b) }
|
||||
# each_child = lambda {|n, &b| g[n].each(&b) }
|
||||
# p Gem::TSort.tsort(each_node, each_child) # raises Gem::TSort::Cyclic
|
||||
#
|
||||
def TSort.tsort(each_node, each_child)
|
||||
Gem::TSort.tsort_each(each_node, each_child).to_a
|
||||
end
|
||||
|
||||
# The iterator version of the #tsort method.
|
||||
# <tt><em>obj</em>.tsort_each</tt> is similar to <tt><em>obj</em>.tsort.each</tt>, but
|
||||
# modification of _obj_ during the iteration may lead to unexpected results.
|
||||
#
|
||||
# #tsort_each returns +nil+.
|
||||
# If there is a cycle, Gem::TSort::Cyclic is raised.
|
||||
#
|
||||
# class G
|
||||
# include Gem::TSort
|
||||
# def initialize(g)
|
||||
# @g = g
|
||||
# end
|
||||
# def tsort_each_child(n, &b) @g[n].each(&b) end
|
||||
# def tsort_each_node(&b) @g.each_key(&b) end
|
||||
# end
|
||||
#
|
||||
# graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
|
||||
# graph.tsort_each {|n| p n }
|
||||
# #=> 4
|
||||
# # 2
|
||||
# # 3
|
||||
# # 1
|
||||
#
|
||||
def tsort_each(&block) # :yields: node
|
||||
each_node = method(:tsort_each_node)
|
||||
each_child = method(:tsort_each_child)
|
||||
Gem::TSort.tsort_each(each_node, each_child, &block)
|
||||
end
|
||||
|
||||
# The iterator version of the Gem::TSort.tsort method.
|
||||
#
|
||||
# The graph is represented by _each_node_ and _each_child_.
|
||||
# _each_node_ should have +call+ method which yields for each node in the graph.
|
||||
# _each_child_ should have +call+ method which takes a node argument and yields for each child node.
|
||||
#
|
||||
# g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
|
||||
# each_node = lambda {|&b| g.each_key(&b) }
|
||||
# each_child = lambda {|n, &b| g[n].each(&b) }
|
||||
# Gem::TSort.tsort_each(each_node, each_child) {|n| p n }
|
||||
# #=> 4
|
||||
# # 2
|
||||
# # 3
|
||||
# # 1
|
||||
#
|
||||
def TSort.tsort_each(each_node, each_child) # :yields: node
|
||||
return to_enum(__method__, each_node, each_child) unless block_given?
|
||||
|
||||
Gem::TSort.each_strongly_connected_component(each_node, each_child) {|component|
|
||||
if component.size == 1
|
||||
yield component.first
|
||||
else
|
||||
raise Cyclic.new("topological sort failed: #{component.inspect}")
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
# Returns strongly connected components as an array of arrays of nodes.
|
||||
# The array is sorted from children to parents.
|
||||
# Each elements of the array represents a strongly connected component.
|
||||
#
|
||||
# class G
|
||||
# include Gem::TSort
|
||||
# def initialize(g)
|
||||
# @g = g
|
||||
# end
|
||||
# def tsort_each_child(n, &b) @g[n].each(&b) end
|
||||
# def tsort_each_node(&b) @g.each_key(&b) end
|
||||
# end
|
||||
#
|
||||
# graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
|
||||
# p graph.strongly_connected_components #=> [[4], [2], [3], [1]]
|
||||
#
|
||||
# graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
|
||||
# p graph.strongly_connected_components #=> [[4], [2, 3], [1]]
|
||||
#
|
||||
def strongly_connected_components
|
||||
each_node = method(:tsort_each_node)
|
||||
each_child = method(:tsort_each_child)
|
||||
Gem::TSort.strongly_connected_components(each_node, each_child)
|
||||
end
|
||||
|
||||
# Returns strongly connected components as an array of arrays of nodes.
|
||||
# The array is sorted from children to parents.
|
||||
# Each elements of the array represents a strongly connected component.
|
||||
#
|
||||
# The graph is represented by _each_node_ and _each_child_.
|
||||
# _each_node_ should have +call+ method which yields for each node in the graph.
|
||||
# _each_child_ should have +call+ method which takes a node argument and yields for each child node.
|
||||
#
|
||||
# g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
|
||||
# each_node = lambda {|&b| g.each_key(&b) }
|
||||
# each_child = lambda {|n, &b| g[n].each(&b) }
|
||||
# p Gem::TSort.strongly_connected_components(each_node, each_child)
|
||||
# #=> [[4], [2], [3], [1]]
|
||||
#
|
||||
# g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
|
||||
# each_node = lambda {|&b| g.each_key(&b) }
|
||||
# each_child = lambda {|n, &b| g[n].each(&b) }
|
||||
# p Gem::TSort.strongly_connected_components(each_node, each_child)
|
||||
# #=> [[4], [2, 3], [1]]
|
||||
#
|
||||
def TSort.strongly_connected_components(each_node, each_child)
|
||||
Gem::TSort.each_strongly_connected_component(each_node, each_child).to_a
|
||||
end
|
||||
|
||||
# The iterator version of the #strongly_connected_components method.
|
||||
# <tt><em>obj</em>.each_strongly_connected_component</tt> is similar to
|
||||
# <tt><em>obj</em>.strongly_connected_components.each</tt>, but
|
||||
# modification of _obj_ during the iteration may lead to unexpected results.
|
||||
#
|
||||
# #each_strongly_connected_component returns +nil+.
|
||||
#
|
||||
# class G
|
||||
# include Gem::TSort
|
||||
# def initialize(g)
|
||||
# @g = g
|
||||
# end
|
||||
# def tsort_each_child(n, &b) @g[n].each(&b) end
|
||||
# def tsort_each_node(&b) @g.each_key(&b) end
|
||||
# end
|
||||
#
|
||||
# graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
|
||||
# graph.each_strongly_connected_component {|scc| p scc }
|
||||
# #=> [4]
|
||||
# # [2]
|
||||
# # [3]
|
||||
# # [1]
|
||||
#
|
||||
# graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
|
||||
# graph.each_strongly_connected_component {|scc| p scc }
|
||||
# #=> [4]
|
||||
# # [2, 3]
|
||||
# # [1]
|
||||
#
|
||||
def each_strongly_connected_component(&block) # :yields: nodes
|
||||
each_node = method(:tsort_each_node)
|
||||
each_child = method(:tsort_each_child)
|
||||
Gem::TSort.each_strongly_connected_component(each_node, each_child, &block)
|
||||
end
|
||||
|
||||
# The iterator version of the Gem::TSort.strongly_connected_components method.
|
||||
#
|
||||
# The graph is represented by _each_node_ and _each_child_.
|
||||
# _each_node_ should have +call+ method which yields for each node in the graph.
|
||||
# _each_child_ should have +call+ method which takes a node argument and yields for each child node.
|
||||
#
|
||||
# g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
|
||||
# each_node = lambda {|&b| g.each_key(&b) }
|
||||
# each_child = lambda {|n, &b| g[n].each(&b) }
|
||||
# Gem::TSort.each_strongly_connected_component(each_node, each_child) {|scc| p scc }
|
||||
# #=> [4]
|
||||
# # [2]
|
||||
# # [3]
|
||||
# # [1]
|
||||
#
|
||||
# g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
|
||||
# each_node = lambda {|&b| g.each_key(&b) }
|
||||
# each_child = lambda {|n, &b| g[n].each(&b) }
|
||||
# Gem::TSort.each_strongly_connected_component(each_node, each_child) {|scc| p scc }
|
||||
# #=> [4]
|
||||
# # [2, 3]
|
||||
# # [1]
|
||||
#
|
||||
def TSort.each_strongly_connected_component(each_node, each_child) # :yields: nodes
|
||||
return to_enum(__method__, each_node, each_child) unless block_given?
|
||||
|
||||
id_map = {}
|
||||
stack = []
|
||||
each_node.call {|node|
|
||||
unless id_map.include? node
|
||||
Gem::TSort.each_strongly_connected_component_from(node, each_child, id_map, stack) {|c|
|
||||
yield c
|
||||
}
|
||||
end
|
||||
}
|
||||
nil
|
||||
end
|
||||
|
||||
# Iterates over strongly connected component in the subgraph reachable from
|
||||
# _node_.
|
||||
#
|
||||
# Return value is unspecified.
|
||||
#
|
||||
# #each_strongly_connected_component_from doesn't call #tsort_each_node.
|
||||
#
|
||||
# class G
|
||||
# include Gem::TSort
|
||||
# def initialize(g)
|
||||
# @g = g
|
||||
# end
|
||||
# def tsort_each_child(n, &b) @g[n].each(&b) end
|
||||
# def tsort_each_node(&b) @g.each_key(&b) end
|
||||
# end
|
||||
#
|
||||
# graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
|
||||
# graph.each_strongly_connected_component_from(2) {|scc| p scc }
|
||||
# #=> [4]
|
||||
# # [2]
|
||||
#
|
||||
# graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
|
||||
# graph.each_strongly_connected_component_from(2) {|scc| p scc }
|
||||
# #=> [4]
|
||||
# # [2, 3]
|
||||
#
|
||||
def each_strongly_connected_component_from(node, id_map={}, stack=[], &block) # :yields: nodes
|
||||
Gem::TSort.each_strongly_connected_component_from(node, method(:tsort_each_child), id_map, stack, &block)
|
||||
end
|
||||
|
||||
# Iterates over strongly connected components in a graph.
|
||||
# The graph is represented by _node_ and _each_child_.
|
||||
#
|
||||
# _node_ is the first node.
|
||||
# _each_child_ should have +call+ method which takes a node argument
|
||||
# and yields for each child node.
|
||||
#
|
||||
# Return value is unspecified.
|
||||
#
|
||||
# #Gem::TSort.each_strongly_connected_component_from is a class method and
|
||||
# it doesn't need a class to represent a graph which includes Gem::TSort.
|
||||
#
|
||||
# graph = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
|
||||
# each_child = lambda {|n, &b| graph[n].each(&b) }
|
||||
# Gem::TSort.each_strongly_connected_component_from(1, each_child) {|scc|
|
||||
# p scc
|
||||
# }
|
||||
# #=> [4]
|
||||
# # [2, 3]
|
||||
# # [1]
|
||||
#
|
||||
def TSort.each_strongly_connected_component_from(node, each_child, id_map={}, stack=[]) # :yields: nodes
|
||||
return to_enum(__method__, node, each_child, id_map, stack) unless block_given?
|
||||
|
||||
minimum_id = node_id = id_map[node] = id_map.size
|
||||
stack_length = stack.length
|
||||
stack << node
|
||||
|
||||
each_child.call(node) {|child|
|
||||
if id_map.include? child
|
||||
child_id = id_map[child]
|
||||
minimum_id = child_id if child_id && child_id < minimum_id
|
||||
else
|
||||
sub_minimum_id =
|
||||
Gem::TSort.each_strongly_connected_component_from(child, each_child, id_map, stack) {|c|
|
||||
yield c
|
||||
}
|
||||
minimum_id = sub_minimum_id if sub_minimum_id < minimum_id
|
||||
end
|
||||
}
|
||||
|
||||
if node_id == minimum_id
|
||||
component = stack.slice!(stack_length .. -1)
|
||||
component.each {|n| id_map[n] = nil}
|
||||
yield component
|
||||
end
|
||||
|
||||
minimum_id
|
||||
end
|
||||
|
||||
# Should be implemented by a extended class.
|
||||
#
|
||||
# #tsort_each_node is used to iterate for all nodes over a graph.
|
||||
#
|
||||
def tsort_each_node # :yields: node
|
||||
raise NotImplementedError.new
|
||||
end
|
||||
|
||||
# Should be implemented by a extended class.
|
||||
#
|
||||
# #tsort_each_child is used to iterate for child nodes of _node_.
|
||||
#
|
||||
def tsort_each_child(node) # :yields: child
|
||||
raise NotImplementedError.new
|
||||
end
|
||||
end
|
||||
end
|
|
@ -5,6 +5,7 @@ class Gem::Licenses
|
|||
extend Gem::Text
|
||||
|
||||
NONSTANDARD = 'Nonstandard'.freeze
|
||||
LICENSE_REF = 'LicenseRef-.+'.freeze
|
||||
|
||||
# Software Package Data Exchange (SPDX) standard open-source software
|
||||
# license identifiers
|
||||
|
@ -523,6 +524,7 @@ class Gem::Licenses
|
|||
\+?
|
||||
(?:\s WITH \s #{Regexp.union(EXCEPTION_IDENTIFIERS)})?
|
||||
| #{NONSTANDARD}
|
||||
| #{LICENSE_REF}
|
||||
)
|
||||
\Z
|
||||
}ox.freeze
|
||||
|
|
|
@ -16,7 +16,7 @@ module Gem::VersionOption
|
|||
# Add the --platform option to the option parser.
|
||||
|
||||
def add_platform_option(task = command, *wrap)
|
||||
OptionParser.accept Gem::Platform do |value|
|
||||
Gem::OptionParser.accept Gem::Platform do |value|
|
||||
if value == Gem::Platform::RUBY
|
||||
value
|
||||
else
|
||||
|
@ -51,7 +51,7 @@ module Gem::VersionOption
|
|||
# Add the --version option to the option parser.
|
||||
|
||||
def add_version_option(task = command, *wrap)
|
||||
OptionParser.accept Gem::Requirement do |value|
|
||||
Gem::OptionParser.accept Gem::Requirement do |value|
|
||||
Gem::Requirement.new(*value.split(/\s*,\s*/))
|
||||
end
|
||||
|
||||
|
|
|
@ -193,7 +193,7 @@ RSpec.describe Bundler::Fetcher::Downloader do
|
|||
let(:message) { "undefined method 'undefined_method_call'" }
|
||||
|
||||
it "should raise the original NoMethodError" do
|
||||
expect { subject.request(uri, options) }.to raise_error(NoMethodError, "undefined method 'undefined_method_call'")
|
||||
expect { subject.request(uri, options) }.to raise_error(NoMethodError, /undefined method 'undefined_method_call'/)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,7 +9,7 @@ RSpec.describe Bundler::GemHelper do
|
|||
let(:app_gemspec_path) { app_path.join("#{app_name}.gemspec") }
|
||||
|
||||
before(:each) do
|
||||
global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__RUBOCOP" => "false",
|
||||
global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__LINTER" => "false",
|
||||
"BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__CHANGELOG" => "false"
|
||||
bundle "gem #{app_name}"
|
||||
prepare_gemspec(app_gemspec_path)
|
||||
|
|
|
@ -612,6 +612,36 @@ RSpec.describe "bundle exec" do
|
|||
expect(out).to include("Installing foo 1.0")
|
||||
end
|
||||
|
||||
it "loads the correct optparse when `auto_install` is set, and optparse is a dependency" do
|
||||
if Gem.ruby_version >= Gem::Version.new("3.0.0") && Gem.rubygems_version < Gem::Version.new("3.3.0.a")
|
||||
skip "optparse is a default gem, and rubygems loads install during install"
|
||||
end
|
||||
|
||||
build_repo4 do
|
||||
build_gem "fastlane", "2.192.0" do |s|
|
||||
s.executables = "fastlane"
|
||||
s.add_dependency "optparse", "~> 0.1.1"
|
||||
end
|
||||
|
||||
build_gem "optparse", "0.1.0"
|
||||
build_gem "optparse", "0.1.1"
|
||||
end
|
||||
|
||||
system_gems "optparse-0.1.0", :gem_repo => gem_repo4
|
||||
|
||||
bundle "config set auto_install 1"
|
||||
bundle "config set --local path vendor/bundle"
|
||||
|
||||
gemfile <<~G
|
||||
source "#{file_uri_for(gem_repo4)}"
|
||||
gem "fastlane"
|
||||
G
|
||||
|
||||
bundle "exec fastlane"
|
||||
expect(out).to include("Installing optparse 0.1.1")
|
||||
expect(out).to include("2.192.0")
|
||||
end
|
||||
|
||||
describe "with gems bundled via :path with invalid gemspecs" do
|
||||
it "outputs the gemspec validation errors" do
|
||||
build_lib "foo"
|
||||
|
|
|
@ -16,6 +16,12 @@ RSpec.describe "bundle gem" do
|
|||
bundle "exec rubocop --debug --config .rubocop.yml", :dir => bundled_app(gem_name)
|
||||
end
|
||||
|
||||
def bundle_exec_standardrb
|
||||
prepare_gemspec(bundled_app(gem_name, "#{gem_name}.gemspec"))
|
||||
bundle "config set path #{standard_gems}", :dir => bundled_app(gem_name)
|
||||
bundle "exec standardrb --debug", :dir => bundled_app(gem_name)
|
||||
end
|
||||
|
||||
let(:generated_gemspec) { Bundler.load_gemspec_uncached(bundled_app(gem_name).join("#{gem_name}.gemspec")) }
|
||||
|
||||
let(:gem_name) { "mygem" }
|
||||
|
@ -138,8 +144,68 @@ RSpec.describe "bundle gem" do
|
|||
end
|
||||
|
||||
shared_examples_for "--rubocop flag" do
|
||||
context "is deprecated", :bundler => "< 3" do
|
||||
before do
|
||||
bundle "gem #{gem_name} --rubocop"
|
||||
end
|
||||
|
||||
it "generates a gem skeleton with rubocop" do
|
||||
gem_skeleton_assertions
|
||||
expect(bundled_app("test-gem/Rakefile")).to read_as(
|
||||
include("# frozen_string_literal: true").
|
||||
and(include('require "rubocop/rake_task"').
|
||||
and(include("RuboCop::RakeTask.new").
|
||||
and(match(/default:.+:rubocop/))))
|
||||
)
|
||||
end
|
||||
|
||||
it "includes rubocop in generated Gemfile" do
|
||||
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
|
||||
builder = Bundler::Dsl.new
|
||||
builder.eval_gemfile(bundled_app("#{gem_name}/Gemfile"))
|
||||
builder.dependencies
|
||||
rubocop_dep = builder.dependencies.find {|d| d.name == "rubocop" }
|
||||
expect(rubocop_dep).not_to be_nil
|
||||
end
|
||||
|
||||
it "generates a default .rubocop.yml" do
|
||||
expect(bundled_app("#{gem_name}/.rubocop.yml")).to exist
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples_for "--no-rubocop flag" do
|
||||
context "is deprecated", :bundler => "< 3" do
|
||||
define_negated_matcher :exclude, :include
|
||||
|
||||
before do
|
||||
bundle "gem #{gem_name} --no-rubocop"
|
||||
end
|
||||
|
||||
it "generates a gem skeleton without rubocop" do
|
||||
gem_skeleton_assertions
|
||||
expect(bundled_app("test-gem/Rakefile")).to read_as(exclude("rubocop"))
|
||||
expect(bundled_app("test-gem/#{gem_name}.gemspec")).to read_as(exclude("rubocop"))
|
||||
end
|
||||
|
||||
it "does not include rubocop in generated Gemfile" do
|
||||
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
|
||||
builder = Bundler::Dsl.new
|
||||
builder.eval_gemfile(bundled_app("#{gem_name}/Gemfile"))
|
||||
builder.dependencies
|
||||
rubocop_dep = builder.dependencies.find {|d| d.name == "rubocop" }
|
||||
expect(rubocop_dep).to be_nil
|
||||
end
|
||||
|
||||
it "doesn't generate a default .rubocop.yml" do
|
||||
expect(bundled_app("#{gem_name}/.rubocop.yml")).to_not exist
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples_for "--linter=rubocop flag" do
|
||||
before do
|
||||
bundle "gem #{gem_name} --rubocop"
|
||||
bundle "gem #{gem_name} --linter=rubocop"
|
||||
end
|
||||
|
||||
it "generates a gem skeleton with rubocop" do
|
||||
|
@ -166,11 +232,38 @@ RSpec.describe "bundle gem" do
|
|||
end
|
||||
end
|
||||
|
||||
shared_examples_for "--no-rubocop flag" do
|
||||
shared_examples_for "--linter=standard flag" do
|
||||
before do
|
||||
bundle "gem #{gem_name} --linter=standard"
|
||||
end
|
||||
|
||||
it "generates a gem skeleton with standard" do
|
||||
gem_skeleton_assertions
|
||||
expect(bundled_app("test-gem/Rakefile")).to read_as(
|
||||
include('require "standard/rake"').
|
||||
and(match(/default:.+:standard/))
|
||||
)
|
||||
end
|
||||
|
||||
it "includes standard in generated Gemfile" do
|
||||
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
|
||||
builder = Bundler::Dsl.new
|
||||
builder.eval_gemfile(bundled_app("#{gem_name}/Gemfile"))
|
||||
builder.dependencies
|
||||
standard_dep = builder.dependencies.find {|d| d.name == "standard" }
|
||||
expect(standard_dep).not_to be_nil
|
||||
end
|
||||
|
||||
it "generates a default .standard.yml" do
|
||||
expect(bundled_app("#{gem_name}/.standard.yml")).to exist
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples_for "--linter=none flag" do
|
||||
define_negated_matcher :exclude, :include
|
||||
|
||||
before do
|
||||
bundle "gem #{gem_name} --no-rubocop"
|
||||
bundle "gem #{gem_name} --linter=none"
|
||||
end
|
||||
|
||||
it "generates a gem skeleton without rubocop" do
|
||||
|
@ -188,46 +281,66 @@ RSpec.describe "bundle gem" do
|
|||
expect(rubocop_dep).to be_nil
|
||||
end
|
||||
|
||||
it "does not include standard in generated Gemfile" do
|
||||
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
|
||||
builder = Bundler::Dsl.new
|
||||
builder.eval_gemfile(bundled_app("#{gem_name}/Gemfile"))
|
||||
builder.dependencies
|
||||
standard_dep = builder.dependencies.find {|d| d.name == "standard" }
|
||||
expect(standard_dep).to be_nil
|
||||
end
|
||||
|
||||
it "doesn't generate a default .rubocop.yml" do
|
||||
expect(bundled_app("#{gem_name}/.rubocop.yml")).to_not exist
|
||||
end
|
||||
|
||||
it "doesn't generate a default .standard.yml" do
|
||||
expect(bundled_app("#{gem_name}/.standard.yml")).to_not exist
|
||||
end
|
||||
end
|
||||
|
||||
it "has no rubocop offenses when using --rubocop flag", :readline do
|
||||
it "has no rubocop offenses when using --linter=rubocop flag", :readline do
|
||||
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
|
||||
bundle "gem #{gem_name} --rubocop"
|
||||
bundle "gem #{gem_name} --linter=rubocop"
|
||||
bundle_exec_rubocop
|
||||
expect(last_command).to be_success
|
||||
end
|
||||
|
||||
it "has no rubocop offenses when using --ext and --rubocop flag", :readline do
|
||||
it "has no rubocop offenses when using --ext and --linter=rubocop flag", :readline do
|
||||
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
|
||||
bundle "gem #{gem_name} --ext --rubocop"
|
||||
bundle "gem #{gem_name} --ext --linter=rubocop"
|
||||
bundle_exec_rubocop
|
||||
expect(last_command).to be_success
|
||||
end
|
||||
|
||||
it "has no rubocop offenses when using --ext, --test=minitest, and --rubocop flag", :readline do
|
||||
it "has no rubocop offenses when using --ext, --test=minitest, and --linter=rubocop flag", :readline do
|
||||
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
|
||||
bundle "gem #{gem_name} --ext --test=minitest --rubocop"
|
||||
bundle "gem #{gem_name} --ext --test=minitest --linter=rubocop"
|
||||
bundle_exec_rubocop
|
||||
expect(last_command).to be_success
|
||||
end
|
||||
|
||||
it "has no rubocop offenses when using --ext, --test=rspec, and --rubocop flag", :readline do
|
||||
it "has no rubocop offenses when using --ext, --test=rspec, and --linter=rubocop flag", :readline do
|
||||
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
|
||||
bundle "gem #{gem_name} --ext --test=rspec --rubocop"
|
||||
bundle "gem #{gem_name} --ext --test=rspec --linter=rubocop"
|
||||
bundle_exec_rubocop
|
||||
expect(last_command).to be_success
|
||||
end
|
||||
|
||||
it "has no rubocop offenses when using --ext, --ext=test-unit, and --rubocop flag", :readline do
|
||||
it "has no rubocop offenses when using --ext, --ext=test-unit, and --linter=rubocop flag", :readline do
|
||||
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
|
||||
bundle "gem #{gem_name} --ext --test=test-unit --rubocop"
|
||||
bundle "gem #{gem_name} --ext --test=test-unit --linter=rubocop"
|
||||
bundle_exec_rubocop
|
||||
expect(last_command).to be_success
|
||||
end
|
||||
|
||||
it "has no standard offenses when using --linter=standard flag", :readline do
|
||||
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
|
||||
bundle "gem #{gem_name} --linter=standard"
|
||||
bundle_exec_standardrb
|
||||
expect(err).to be_empty
|
||||
end
|
||||
|
||||
shared_examples_for "CI config is absent" do
|
||||
it "does not create any CI files" do
|
||||
expect(bundled_app("#{gem_name}/.github/workflows/main.yml")).to_not exist
|
||||
|
@ -889,6 +1002,127 @@ RSpec.describe "bundle gem" do
|
|||
end
|
||||
end
|
||||
|
||||
context "--linter with no argument" do
|
||||
it "does not generate any linter config" do
|
||||
bundle "gem #{gem_name}"
|
||||
|
||||
expect(bundled_app("#{gem_name}/.rubocop.yml")).to_not exist
|
||||
expect(bundled_app("#{gem_name}/.standard.yml")).to_not exist
|
||||
end
|
||||
end
|
||||
|
||||
context "--linter set to rubocop" do
|
||||
it "generates a RuboCop config" do
|
||||
bundle "gem #{gem_name} --linter=rubocop"
|
||||
|
||||
expect(bundled_app("#{gem_name}/.rubocop.yml")).to exist
|
||||
expect(bundled_app("#{gem_name}/.standard.yml")).to_not exist
|
||||
end
|
||||
end
|
||||
|
||||
context "--linter set to standard" do
|
||||
it "generates a Standard config" do
|
||||
bundle "gem #{gem_name} --linter=standard"
|
||||
|
||||
expect(bundled_app("#{gem_name}/.standard.yml")).to exist
|
||||
expect(bundled_app("#{gem_name}/.rubocop.yml")).to_not exist
|
||||
end
|
||||
end
|
||||
|
||||
context "gem.linter setting set to none" do
|
||||
it "doesn't generate any linter config" do
|
||||
bundle "gem #{gem_name}"
|
||||
|
||||
expect(bundled_app("#{gem_name}/.rubocop.yml")).to_not exist
|
||||
expect(bundled_app("#{gem_name}/.standard.yml")).to_not exist
|
||||
end
|
||||
end
|
||||
|
||||
context "gem.linter setting set to rubocop" do
|
||||
it "generates a RuboCop config file" do
|
||||
bundle "config set gem.linter rubocop"
|
||||
bundle "gem #{gem_name}"
|
||||
|
||||
expect(bundled_app("#{gem_name}/.rubocop.yml")).to exist
|
||||
end
|
||||
end
|
||||
|
||||
context "gem.linter setting set to standard" do
|
||||
it "generates a Standard config file" do
|
||||
bundle "config set gem.linter standard"
|
||||
bundle "gem #{gem_name}"
|
||||
|
||||
expect(bundled_app("#{gem_name}/.standard.yml")).to exist
|
||||
end
|
||||
end
|
||||
|
||||
context "gem.rubocop setting set to true", :bundler => "< 3" do
|
||||
before do
|
||||
bundle "config set gem.rubocop true"
|
||||
bundle "gem #{gem_name}"
|
||||
end
|
||||
|
||||
it "generates rubocop config" do
|
||||
expect(bundled_app("#{gem_name}/.rubocop.yml")).to exist
|
||||
end
|
||||
|
||||
it "unsets gem.rubocop" do
|
||||
bundle "config gem.rubocop"
|
||||
expect(out).to include("You have not configured a value for `gem.rubocop`")
|
||||
end
|
||||
|
||||
it "sets gem.linter=rubocop instead" do
|
||||
bundle "config gem.linter"
|
||||
expect(out).to match(/Set for the current user .*: "rubocop"/)
|
||||
end
|
||||
end
|
||||
|
||||
context "gem.linter set to rubocop and --linter with no arguments", :hint_text do
|
||||
before do
|
||||
bundle "config set gem.linter rubocop"
|
||||
bundle "gem #{gem_name} --linter"
|
||||
end
|
||||
|
||||
it "generates a RuboCop config file" do
|
||||
expect(bundled_app("#{gem_name}/.rubocop.yml")).to exist
|
||||
end
|
||||
|
||||
it "hints that --linter is already configured" do
|
||||
expect(out).to match("rubocop is already configured, ignoring --linter flag.")
|
||||
end
|
||||
end
|
||||
|
||||
context "gem.linter setting set to false and --linter with no arguments", :hint_text do
|
||||
before do
|
||||
bundle "config set gem.linter false"
|
||||
bundle "gem #{gem_name} --linter"
|
||||
end
|
||||
|
||||
it "asks to setup a linter" do
|
||||
expect(out).to match("Do you want to add a code linter and formatter to your gem?")
|
||||
end
|
||||
|
||||
it "hints that the choice will only be applied to the current gem" do
|
||||
expect(out).to match("Your choice will only be applied to this gem.")
|
||||
end
|
||||
end
|
||||
|
||||
context "gem.linter setting not set and --linter with no arguments", :hint_text do
|
||||
before do
|
||||
bundle "gem #{gem_name} --linter"
|
||||
end
|
||||
|
||||
it "asks to setup a linter" do
|
||||
expect(out).to match("Do you want to add a code linter and formatter to your gem?")
|
||||
end
|
||||
|
||||
it "hints that the choice will be applied to future bundle gem calls" do
|
||||
hint = "Future `bundle gem` calls will use your choice. " \
|
||||
"This setting can be changed anytime with `bundle config gem.linter`."
|
||||
expect(out).to match(hint)
|
||||
end
|
||||
end
|
||||
|
||||
context "--edit option" do
|
||||
it "opens the generated gemspec in the user's text editor" do
|
||||
output = bundle "gem #{gem_name} --edit=echo"
|
||||
|
@ -939,6 +1173,9 @@ RSpec.describe "bundle gem" do
|
|||
before do
|
||||
global_config "BUNDLE_GEM__RUBOCOP" => "true"
|
||||
end
|
||||
it_behaves_like "--linter=rubocop flag"
|
||||
it_behaves_like "--linter=standard flag"
|
||||
it_behaves_like "--linter=none flag"
|
||||
it_behaves_like "--rubocop flag"
|
||||
it_behaves_like "--no-rubocop flag"
|
||||
end
|
||||
|
@ -947,10 +1184,40 @@ RSpec.describe "bundle gem" do
|
|||
before do
|
||||
global_config "BUNDLE_GEM__RUBOCOP" => "false"
|
||||
end
|
||||
it_behaves_like "--linter=rubocop flag"
|
||||
it_behaves_like "--linter=standard flag"
|
||||
it_behaves_like "--linter=none flag"
|
||||
it_behaves_like "--rubocop flag"
|
||||
it_behaves_like "--no-rubocop flag"
|
||||
end
|
||||
|
||||
context "with linter option in bundle config settings set to rubocop" do
|
||||
before do
|
||||
global_config "BUNDLE_GEM__LINTER" => "rubocop"
|
||||
end
|
||||
it_behaves_like "--linter=rubocop flag"
|
||||
it_behaves_like "--linter=standard flag"
|
||||
it_behaves_like "--linter=none flag"
|
||||
end
|
||||
|
||||
context "with linter option in bundle config settings set to standard" do
|
||||
before do
|
||||
global_config "BUNDLE_GEM__LINTER" => "standard"
|
||||
end
|
||||
it_behaves_like "--linter=rubocop flag"
|
||||
it_behaves_like "--linter=standard flag"
|
||||
it_behaves_like "--linter=none flag"
|
||||
end
|
||||
|
||||
context "with linter option in bundle config settings set to false" do
|
||||
before do
|
||||
global_config "BUNDLE_GEM__LINTER" => "false"
|
||||
end
|
||||
it_behaves_like "--linter=rubocop flag"
|
||||
it_behaves_like "--linter=standard flag"
|
||||
it_behaves_like "--linter=none flag"
|
||||
end
|
||||
|
||||
context "with changelog option in bundle config settings set to true" do
|
||||
before do
|
||||
global_config "BUNDLE_GEM__CHANGELOG" => "true"
|
||||
|
@ -1172,7 +1439,7 @@ Usage: "bundle gem NAME [OPTIONS]"
|
|||
end
|
||||
|
||||
it "asks about CI service" do
|
||||
global_config "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__RUBOCOP" => "false"
|
||||
global_config "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__LINTER" => "false"
|
||||
|
||||
bundle "gem foobar" do |input, _, _|
|
||||
input.puts "github"
|
||||
|
@ -1182,7 +1449,7 @@ Usage: "bundle gem NAME [OPTIONS]"
|
|||
end
|
||||
|
||||
it "asks about MIT license" do
|
||||
global_config "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__RUBOCOP" => "false"
|
||||
global_config "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__LINTER" => "false"
|
||||
|
||||
bundle "config list"
|
||||
|
||||
|
@ -1194,7 +1461,7 @@ Usage: "bundle gem NAME [OPTIONS]"
|
|||
end
|
||||
|
||||
it "asks about CoC" do
|
||||
global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__RUBOCOP" => "false"
|
||||
global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__LINTER" => "false"
|
||||
|
||||
bundle "gem foobar" do |input, _, _|
|
||||
input.puts "yes"
|
||||
|
@ -1204,7 +1471,7 @@ Usage: "bundle gem NAME [OPTIONS]"
|
|||
end
|
||||
|
||||
it "asks about CHANGELOG" do
|
||||
global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__RUBOCOP" => "false",
|
||||
global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__LINTER" => "false",
|
||||
"BUNDLE_GEM__COC" => "false"
|
||||
|
||||
bundle "gem foobar" do |input, _, _|
|
||||
|
|
|
@ -1436,7 +1436,44 @@ In Gemfile:
|
|||
end
|
||||
|
||||
describe "without git installed" do
|
||||
it "prints a better error message" do
|
||||
it "prints a better error message when installing" do
|
||||
build_git "foo"
|
||||
|
||||
gemfile <<-G
|
||||
source "#{file_uri_for(gem_repo1)}"
|
||||
|
||||
gem "rake", git: "https://github.com/ruby/rake"
|
||||
G
|
||||
|
||||
lockfile <<-L
|
||||
GIT
|
||||
remote: https://github.com/ruby/rake
|
||||
revision: 5c60da8644a9e4f655e819252e3b6ca77f42b7af
|
||||
specs:
|
||||
rake (13.0.6)
|
||||
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
|
||||
PLATFORMS
|
||||
#{lockfile_platforms}
|
||||
|
||||
DEPENDENCIES
|
||||
rake!
|
||||
|
||||
BUNDLED WITH
|
||||
#{Bundler::VERSION}
|
||||
L
|
||||
|
||||
with_path_as("") do
|
||||
bundle "install", :raise_on_error => false
|
||||
end
|
||||
expect(err).
|
||||
to include("You need to install git to be able to use gems from git repositories. For help installing git, please refer to GitHub's tutorial at https://help.github.com/articles/set-up-git")
|
||||
end
|
||||
|
||||
it "prints a better error message when updating" do
|
||||
build_git "foo"
|
||||
|
||||
install_gemfile <<-G
|
||||
|
|
|
@ -20,7 +20,7 @@ RSpec.describe "bundle install with specific platforms" do
|
|||
])
|
||||
end
|
||||
|
||||
it "understands that a non-plaform specific gem in a old lockfile doesn't necessarily mean installing the non-specific variant" do
|
||||
it "understands that a non-platform specific gem in a old lockfile doesn't necessarily mean installing the non-specific variant" do
|
||||
setup_multiplatform_gem
|
||||
|
||||
system_gems "bundler-2.1.4"
|
||||
|
@ -54,7 +54,7 @@ RSpec.describe "bundle install with specific platforms" do
|
|||
expect(the_bundle).to include_gem("google-protobuf 3.0.0.alpha.5.0.5.1 universal-darwin")
|
||||
end
|
||||
|
||||
it "understands that a non-plaform specific gem in a new lockfile locked only to RUBY doesn't necessarily mean installing the non-specific variant" do
|
||||
it "understands that a non-platform specific gem in a new lockfile locked only to RUBY doesn't necessarily mean installing the non-specific variant" do
|
||||
setup_multiplatform_gem
|
||||
|
||||
system_gems "bundler-2.1.4"
|
||||
|
|
|
@ -115,7 +115,7 @@ RSpec.shared_examples "bundle install --standalone" do
|
|||
|
||||
realworld_system_gems "fiddle --version 1.0.6", "tsort --version 0.1.0"
|
||||
|
||||
necessary_system_gems = ["optparse --version 0.1.1", "psych --version 3.3.2", "yaml --version 0.1.1", "logger --version 1.4.3", "etc --version 1.2.0"]
|
||||
necessary_system_gems = ["optparse --version 0.1.1", "psych --version 3.3.2", "yaml --version 0.1.1", "logger --version 1.4.3", "etc --version 1.2.0", "stringio --version 3.0.0"]
|
||||
necessary_system_gems += ["shellwords --version 0.1.0", "base64 --version 0.1.0", "resolv --version 0.2.1"] if Gem.rubygems_version < Gem::Version.new("3.3.3.a")
|
||||
realworld_system_gems(*necessary_system_gems, :path => scoped_gem_path(bundled_app("bundle")))
|
||||
|
||||
|
|
|
@ -166,9 +166,10 @@ RSpec.describe "the lockfile format" do
|
|||
G
|
||||
end
|
||||
|
||||
it "warns if the current is older than lockfile's bundler version" do
|
||||
current_version = Bundler::VERSION
|
||||
newer_minor = bump_minor(current_version)
|
||||
it "warns if the current version is older than lockfile's bundler version, and locked version is a final release" do
|
||||
current_version = "999.998.999"
|
||||
system_gems "bundler-#{current_version}"
|
||||
newer_minor = "999.999.0"
|
||||
|
||||
lockfile <<-L
|
||||
GEM
|
||||
|
@ -186,17 +187,16 @@ RSpec.describe "the lockfile format" do
|
|||
#{newer_minor}
|
||||
L
|
||||
|
||||
install_gemfile <<-G
|
||||
install_gemfile <<-G, :env => { "BUNDLER_VERSION" => current_version }
|
||||
source "#{file_uri_for(gem_repo2)}"
|
||||
|
||||
gem "rack"
|
||||
G
|
||||
|
||||
pre_flag = prerelease?(newer_minor) ? " --pre" : ""
|
||||
warning_message = "the running version of Bundler (#{current_version}) is older " \
|
||||
"than the version that created the lockfile (#{newer_minor}). " \
|
||||
"We suggest you to upgrade to the version that created the " \
|
||||
"lockfile by running `gem install bundler:#{newer_minor}#{pre_flag}`."
|
||||
"lockfile by running `gem install bundler:#{newer_minor}`."
|
||||
expect(err).to include warning_message
|
||||
|
||||
lockfile_should_be <<-G
|
||||
|
@ -216,6 +216,102 @@ RSpec.describe "the lockfile format" do
|
|||
G
|
||||
end
|
||||
|
||||
it "warns if the current version is older than lockfile's bundler version, and locked version is a prerelease" do
|
||||
current_version = "999.998.999"
|
||||
system_gems "bundler-#{current_version}"
|
||||
newer_minor = "999.999.0.pre1"
|
||||
|
||||
lockfile <<-L
|
||||
GEM
|
||||
remote: #{file_uri_for(gem_repo2)}/
|
||||
specs:
|
||||
rack (1.0.0)
|
||||
|
||||
PLATFORMS
|
||||
#{lockfile_platforms}
|
||||
|
||||
DEPENDENCIES
|
||||
rack
|
||||
|
||||
BUNDLED WITH
|
||||
#{newer_minor}
|
||||
L
|
||||
|
||||
install_gemfile <<-G, :env => { "BUNDLER_VERSION" => current_version }
|
||||
source "#{file_uri_for(gem_repo2)}"
|
||||
|
||||
gem "rack"
|
||||
G
|
||||
|
||||
warning_message = "the running version of Bundler (#{current_version}) is older " \
|
||||
"than the version that created the lockfile (#{newer_minor}). " \
|
||||
"We suggest you to upgrade to the version that created the " \
|
||||
"lockfile by running `gem install bundler:#{newer_minor} --pre`."
|
||||
expect(err).to include warning_message
|
||||
|
||||
lockfile_should_be <<-G
|
||||
GEM
|
||||
remote: #{file_uri_for(gem_repo2)}/
|
||||
specs:
|
||||
rack (1.0.0)
|
||||
|
||||
PLATFORMS
|
||||
#{lockfile_platforms}
|
||||
|
||||
DEPENDENCIES
|
||||
rack
|
||||
|
||||
BUNDLED WITH
|
||||
#{newer_minor}
|
||||
G
|
||||
end
|
||||
|
||||
it "doesn't warn if the current version is older than lockfile's bundler version, and locked version is a dev version" do
|
||||
current_version = "999.998.999"
|
||||
system_gems "bundler-#{current_version}"
|
||||
newer_minor = "999.999.0.dev"
|
||||
|
||||
lockfile <<-L
|
||||
GEM
|
||||
remote: #{file_uri_for(gem_repo2)}/
|
||||
specs:
|
||||
rack (1.0.0)
|
||||
|
||||
PLATFORMS
|
||||
#{lockfile_platforms}
|
||||
|
||||
DEPENDENCIES
|
||||
rack
|
||||
|
||||
BUNDLED WITH
|
||||
#{newer_minor}
|
||||
L
|
||||
|
||||
install_gemfile <<-G, :env => { "BUNDLER_VERSION" => current_version }
|
||||
source "#{file_uri_for(gem_repo2)}"
|
||||
|
||||
gem "rack"
|
||||
G
|
||||
|
||||
expect(err).to be_empty
|
||||
|
||||
lockfile_should_be <<-G
|
||||
GEM
|
||||
remote: #{file_uri_for(gem_repo2)}/
|
||||
specs:
|
||||
rack (1.0.0)
|
||||
|
||||
PLATFORMS
|
||||
#{lockfile_platforms}
|
||||
|
||||
DEPENDENCIES
|
||||
rack
|
||||
|
||||
BUNDLED WITH
|
||||
#{newer_minor}
|
||||
G
|
||||
end
|
||||
|
||||
it "warns when updating bundler major version" do
|
||||
current_version = Bundler::VERSION
|
||||
older_major = previous_major(current_version)
|
||||
|
|
|
@ -665,9 +665,55 @@ The :gist git source is deprecated, and will be removed in the future. Add this
|
|||
end
|
||||
|
||||
it "prints a deprecation warning", :bundler => "< 3" do
|
||||
expect(deprecations).to include "The `viz` command has been moved to the `bundle-viz` gem, see https://github.com/bundler/bundler-viz"
|
||||
expect(deprecations).to include "The `viz` command has been moved to the `bundle-viz` gem, see https://github.com/rubygems/bundler-graph"
|
||||
end
|
||||
|
||||
pending "fails with a helpful message", :bundler => "3"
|
||||
end
|
||||
|
||||
describe "deprecating rubocop", :readline do
|
||||
context "bundle gem --rubocop" do
|
||||
before do
|
||||
bundle "gem my_new_gem --rubocop", :raise_on_error => false
|
||||
end
|
||||
|
||||
it "prints a deprecation warning", :bundler => "< 3" do
|
||||
expect(deprecations).to include \
|
||||
"--rubocop is deprecated, use --linter=rubocop"
|
||||
end
|
||||
end
|
||||
|
||||
context "bundle gem --no-rubocop" do
|
||||
before do
|
||||
bundle "gem my_new_gem --no-rubocop", :raise_on_error => false
|
||||
end
|
||||
|
||||
it "prints a deprecation warning", :bundler => "< 3" do
|
||||
expect(deprecations).to include \
|
||||
"--no-rubocop is deprecated, use --linter"
|
||||
end
|
||||
end
|
||||
|
||||
context "bundle gem with gem.rubocop set to true" do
|
||||
before do
|
||||
bundle "gem my_new_gem", :env => { "BUNDLE_GEM__RUBOCOP" => "true" }, :raise_on_error => false
|
||||
end
|
||||
|
||||
it "prints a deprecation warning", :bundler => "< 3" do
|
||||
expect(deprecations).to include \
|
||||
"config gem.rubocop is deprecated; we've updated your config to use gem.linter instead"
|
||||
end
|
||||
end
|
||||
|
||||
context "bundle gem with gem.rubocop set to false" do
|
||||
before do
|
||||
bundle "gem my_new_gem", :env => { "BUNDLE_GEM__RUBOCOP" => "false" }, :raise_on_error => false
|
||||
end
|
||||
|
||||
it "prints a deprecation warning", :bundler => "< 3" do
|
||||
expect(deprecations).to include \
|
||||
"config gem.rubocop is deprecated; we've updated your config to use gem.linter instead"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,25 +3,6 @@
|
|||
require "set"
|
||||
|
||||
RSpec.describe "The library itself" do
|
||||
def check_for_debugging_mechanisms(filename)
|
||||
debugging_mechanisms_regex = /
|
||||
(binding\.pry)|
|
||||
(debugger)|
|
||||
(sleep\s*\(?\d+)|
|
||||
(fit\s*\(?("|\w))
|
||||
/x
|
||||
|
||||
failing_lines = []
|
||||
each_line(filename) do |line, number|
|
||||
if line =~ debugging_mechanisms_regex && !line.end_with?("# ignore quality_spec\n")
|
||||
failing_lines << number + 1
|
||||
end
|
||||
end
|
||||
|
||||
return if failing_lines.empty?
|
||||
"#{filename} has debugging mechanisms (like binding.pry, sleep, debugger, rspec focusing, etc.) on lines #{failing_lines.join(", ")}"
|
||||
end
|
||||
|
||||
def check_for_git_merge_conflicts(filename)
|
||||
merge_conflicts_regex = /
|
||||
<<<<<<<|
|
||||
|
@ -125,16 +106,6 @@ RSpec.describe "The library itself" do
|
|||
expect(error_messages.compact).to be_well_formed
|
||||
end
|
||||
|
||||
it "does not include any leftover debugging or development mechanisms" do
|
||||
exempt = %r{quality_spec.rb|support/helpers|vcr_cassettes|\.md|\.ronn|index\.txt|\.5|\.1}
|
||||
error_messages = []
|
||||
tracked_files.each do |filename|
|
||||
next if filename =~ exempt
|
||||
error_messages << check_for_debugging_mechanisms(filename)
|
||||
end
|
||||
expect(error_messages.compact).to be_well_formed
|
||||
end
|
||||
|
||||
it "does not include any unresolved merge conflicts" do
|
||||
error_messages = []
|
||||
exempt = %r{lock/lockfile_spec|quality_spec|vcr_cassettes|\.ronn|lockfile_parser\.rb}
|
||||
|
|
|
@ -197,10 +197,11 @@ RSpec.describe "real world edgecases", :realworld => true do
|
|||
end
|
||||
|
||||
it "outputs a helpful error message when gems have invalid gemspecs" do
|
||||
install_gemfile <<-G, :standalone => true, :raise_on_error => false
|
||||
install_gemfile <<-G, :standalone => true, :raise_on_error => false, :env => { "BUNDLE_FORCE_RUBY_PLATFORM" => "1" }
|
||||
source 'https://rubygems.org'
|
||||
gem "resque-scheduler", "2.2.0"
|
||||
gem "redis-namespace", "1.6.0" # for a consistent resolution including ruby 2.3.0
|
||||
gem "ruby2_keywords", "0.0.5"
|
||||
G
|
||||
expect(err).to include("You have one or more invalid gemspecs that need to be fixed.")
|
||||
expect(err).to include("resque-scheduler 2.2.0 has an invalid gemspec")
|
||||
|
|
|
@ -74,10 +74,10 @@ RSpec.describe "fetching dependencies with a not available mirror", :realworld =
|
|||
bundle :install, :artifice => nil, :raise_on_error => false
|
||||
|
||||
expect(out).to include("Fetching source index from #{mirror}")
|
||||
expect(err).to include("Retrying fetcher due to error (2/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2) for \"#{host}\" port #{@mirror_port}) (#{mirror}/specs.4.8.gz)>")
|
||||
expect(err).to include("Retrying fetcher due to error (3/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2) for \"#{host}\" port #{@mirror_port}) (#{mirror}/specs.4.8.gz)>")
|
||||
expect(err).to include("Retrying fetcher due to error (4/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2) for \"#{host}\" port #{@mirror_port}) (#{mirror}/specs.4.8.gz)>")
|
||||
expect(err).to include("Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2) for \"#{host}\" port #{@mirror_port}) (#{mirror}/specs.4.8.gz)>")
|
||||
expect(err).to include("Retrying fetcher due to error (2/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2)")
|
||||
expect(err).to include("Retrying fetcher due to error (3/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2)")
|
||||
expect(err).to include("Retrying fetcher due to error (4/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2)")
|
||||
expect(err).to include("Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2)")
|
||||
end
|
||||
|
||||
it "prints each error and warning on a new line" do
|
||||
|
@ -89,12 +89,7 @@ RSpec.describe "fetching dependencies with a not available mirror", :realworld =
|
|||
bundle :install, :artifice => nil, :raise_on_error => false
|
||||
|
||||
expect(out).to include "Fetching source index from #{mirror}/"
|
||||
expect(err).to include <<-EOS.strip
|
||||
Retrying fetcher due to error (2/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2) for \"#{host}\" port #{@mirror_port}) (#{mirror}/specs.4.8.gz)>
|
||||
Retrying fetcher due to error (3/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2) for \"#{host}\" port #{@mirror_port}) (#{mirror}/specs.4.8.gz)>
|
||||
Retrying fetcher due to error (4/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2) for \"#{host}\" port #{@mirror_port}) (#{mirror}/specs.4.8.gz)>
|
||||
Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2) for \"#{host}\" port #{@mirror_port}) (#{mirror}/specs.4.8.gz)>
|
||||
EOS
|
||||
expect(err.split("\n").count).to eq(4)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -112,10 +107,10 @@ Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUS
|
|||
bundle :install, :artifice => nil, :raise_on_error => false
|
||||
|
||||
expect(out).to include("Fetching source index from #{mirror}")
|
||||
expect(err).to include("Retrying fetcher due to error (2/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2) for \"#{host}\" port #{@mirror_port}) (#{mirror}/specs.4.8.gz)>")
|
||||
expect(err).to include("Retrying fetcher due to error (3/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2) for \"#{host}\" port #{@mirror_port}) (#{mirror}/specs.4.8.gz)>")
|
||||
expect(err).to include("Retrying fetcher due to error (4/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2) for \"#{host}\" port #{@mirror_port}) (#{mirror}/specs.4.8.gz)>")
|
||||
expect(err).to include("Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2) for \"#{host}\" port #{@mirror_port}) (#{mirror}/specs.4.8.gz)>")
|
||||
expect(err).to include("Retrying fetcher due to error (2/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2)")
|
||||
expect(err).to include("Retrying fetcher due to error (3/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2)")
|
||||
expect(err).to include("Retrying fetcher due to error (4/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2)")
|
||||
expect(err).to include("Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2)")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -390,7 +390,7 @@ RSpec.describe "bundler/inline#gemfile" do
|
|||
dependency_installer_loads_fileutils = ruby "require 'rubygems/dependency_installer'; puts $LOADED_FEATURES.grep(/fileutils/)", :raise_on_error => false
|
||||
skip "does not work if rubygems/dependency_installer loads fileutils, which happens until rubygems 3.2.0" unless dependency_installer_loads_fileutils.empty?
|
||||
|
||||
skip "does not work on ruby 3.0 because it changes the path to look for default gems, tsort is a default gem there, and we can't install it either like we do with fiddle because it doesn't yet exist" unless RUBY_VERSION < "3.0.0"
|
||||
skip "pathname does not install cleanly on this ruby" if RUBY_VERSION < "2.7.0"
|
||||
|
||||
Dir.mkdir tmp("path_without_gemfile")
|
||||
|
||||
|
@ -399,6 +399,8 @@ RSpec.describe "bundler/inline#gemfile" do
|
|||
|
||||
realworld_system_gems "fileutils --version 1.4.1"
|
||||
|
||||
realworld_system_gems "pathname --version 0.2.0"
|
||||
|
||||
realworld_system_gems "fiddle" # not sure why, but this is needed on Windows to boot rubygems successfully
|
||||
|
||||
realworld_system_gems "timeout uri" # this spec uses net/http which requires these default gems
|
||||
|
|
|
@ -61,7 +61,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
|
|||
build_repo4 do
|
||||
build_gem "nokogiri", "1.11.1" do |s|
|
||||
s.add_dependency "mini_portile2", "~> 2.5.0"
|
||||
s.add_dependency "racc", "~> 1.4"
|
||||
s.add_dependency "racc", "~> 1.5.2"
|
||||
end
|
||||
|
||||
build_gem "nokogiri", "1.11.1" do |s|
|
||||
|
@ -80,7 +80,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
|
|||
mini_portile2 (2.5.0)
|
||||
nokogiri (1.11.1)
|
||||
mini_portile2 (~> 2.5.0)
|
||||
racc (~> 1.4)
|
||||
racc (~> 1.5.2)
|
||||
nokogiri (1.11.1-#{Bundler.local_platform})
|
||||
racc (~> 1.4)
|
||||
racc (1.5.2)
|
||||
|
|
|
@ -745,41 +745,68 @@ end
|
|||
expect(err).to be_empty
|
||||
end
|
||||
|
||||
describe "$MANPATH" do
|
||||
before do
|
||||
context "when the user has `MANPATH` set", :man do
|
||||
before { ENV["MANPATH"] = "/foo#{File::PATH_SEPARATOR}" }
|
||||
|
||||
it "adds the gem's man dir to the MANPATH" do
|
||||
build_repo4 do
|
||||
build_gem "with_man" do |s|
|
||||
s.write("man/man1/page.1", "MANPAGE")
|
||||
end
|
||||
end
|
||||
|
||||
install_gemfile <<-G
|
||||
source "#{file_uri_for(gem_repo4)}"
|
||||
gem "with_man"
|
||||
G
|
||||
|
||||
run "puts ENV['MANPATH']"
|
||||
expect(out).to eq("#{default_bundle_path("gems/with_man-1.0/man")}#{File::PATH_SEPARATOR}/foo")
|
||||
end
|
||||
end
|
||||
|
||||
context "when the user has one set" do
|
||||
before { ENV["MANPATH"] = "/foo#{File::PATH_SEPARATOR}" }
|
||||
context "when the user does not have `MANPATH` set", :man do
|
||||
before { ENV.delete("MANPATH") }
|
||||
|
||||
it "adds the gem's man dir to the MANPATH" do
|
||||
install_gemfile <<-G
|
||||
source "#{file_uri_for(gem_repo4)}"
|
||||
gem "with_man"
|
||||
G
|
||||
it "adds the gem's man dir to the MANPATH, leaving : in the end so that system man pages still work" do
|
||||
build_repo4 do
|
||||
build_gem "with_man" do |s|
|
||||
s.write("man/man1/page.1", "MANPAGE")
|
||||
end
|
||||
|
||||
run "puts ENV['MANPATH']"
|
||||
expect(out).to eq("#{default_bundle_path("gems/with_man-1.0/man")}#{File::PATH_SEPARATOR}/foo")
|
||||
build_gem "with_man_overriding_system_man" do |s|
|
||||
s.write("man/man1/ls.1", "LS MANPAGE")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when the user does not have one set" do
|
||||
before { ENV.delete("MANPATH") }
|
||||
install_gemfile <<-G
|
||||
source "#{file_uri_for(gem_repo4)}"
|
||||
gem "with_man"
|
||||
G
|
||||
|
||||
it "adds the gem's man dir to the MANPATH" do
|
||||
install_gemfile <<-G
|
||||
source "#{file_uri_for(gem_repo4)}"
|
||||
gem "with_man"
|
||||
G
|
||||
run <<~RUBY
|
||||
puts ENV['MANPATH']
|
||||
require "open3"
|
||||
puts Open3.capture2e("man", "ls")[1].success?
|
||||
RUBY
|
||||
|
||||
run "puts ENV['MANPATH']"
|
||||
expect(out).to eq(default_bundle_path("gems/with_man-1.0/man").to_s)
|
||||
end
|
||||
expect(out).to eq("#{default_bundle_path("gems/with_man-1.0/man")}#{File::PATH_SEPARATOR}\ntrue")
|
||||
|
||||
install_gemfile <<-G
|
||||
source "#{file_uri_for(gem_repo4)}"
|
||||
gem "with_man_overriding_system_man"
|
||||
G
|
||||
|
||||
run <<~RUBY
|
||||
puts ENV['MANPATH']
|
||||
require "open3"
|
||||
puts Open3.capture2e("man", "ls")[0]
|
||||
RUBY
|
||||
|
||||
lines = out.split("\n")
|
||||
|
||||
expect(lines).to include("#{default_bundle_path("gems/with_man_overriding_system_man-1.0/man")}#{File::PATH_SEPARATOR}")
|
||||
expect(lines).to include("LS MANPAGE")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1298,7 +1325,9 @@ end
|
|||
exempts << "uri" if Gem.ruby_version >= Gem::Version.new("2.7")
|
||||
exempts << "pathname" if Gem.ruby_version >= Gem::Version.new("3.0")
|
||||
exempts << "set" unless Gem.rubygems_version >= Gem::Version.new("3.2.6")
|
||||
exempts << "tsort" if Gem.ruby_version >= Gem::Version.new("3.0")
|
||||
exempts << "tsort" unless Gem.rubygems_version >= Gem::Version.new("3.2.31")
|
||||
exempts << "error_highlight" # added in Ruby 3.1 as a default gem
|
||||
exempts << "ruby2_keywords" # added in Ruby 3.1 as a default gem
|
||||
exempts
|
||||
end
|
||||
|
||||
|
@ -1466,5 +1495,21 @@ end
|
|||
|
||||
expect(last_command.stdboth).to eq("true")
|
||||
end
|
||||
|
||||
it "memoizes initial set of specs when requiring bundler/setup, so that even if further code mutates dependencies, Bundler.definition.specs is not affected" do
|
||||
install_gemfile <<~G
|
||||
source "#{file_uri_for(gem_repo1)}"
|
||||
gem "yard"
|
||||
gem "rack", :group => :test
|
||||
G
|
||||
|
||||
ruby <<-RUBY, :raise_on_error => false
|
||||
require "bundler/setup"
|
||||
Bundler.require(:test).select! {|d| (d.groups & [:test]).any? }
|
||||
puts Bundler.definition.specs.map(&:name).join(", ")
|
||||
RUBY
|
||||
|
||||
expect(out).to include("rack, yard")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -34,6 +34,7 @@ RSpec.configure do |config|
|
|||
config.filter_run_excluding :readline => Gem.win_platform?
|
||||
config.filter_run_excluding :jruby => RUBY_ENGINE != "jruby"
|
||||
config.filter_run_excluding :truffleruby => RUBY_ENGINE != "truffleruby"
|
||||
config.filter_run_excluding :man => Gem.win_platform?
|
||||
|
||||
config.filter_run_when_matching :focus unless ENV["CI"]
|
||||
end
|
||||
|
|
|
@ -10,7 +10,7 @@ module Spec
|
|||
|
||||
def reset!
|
||||
Dir.glob("#{tmp}/{gems/*,*}", File::FNM_DOTMATCH).each do |dir|
|
||||
next if %w[base base_system remote1 rubocop gems rubygems . ..].include?(File.basename(dir))
|
||||
next if %w[base base_system remote1 rubocop standard gems rubygems . ..].include?(File.basename(dir))
|
||||
FileUtils.rm_rf(dir)
|
||||
end
|
||||
FileUtils.mkdir_p(home)
|
||||
|
|
|
@ -37,6 +37,10 @@ module Spec
|
|||
@rubocop_gemfile ||= source_root.join(rubocop_gemfile_basename)
|
||||
end
|
||||
|
||||
def standard_gemfile
|
||||
@standard_gemfile ||= source_root.join(standard_gemfile_basename)
|
||||
end
|
||||
|
||||
def dev_gemfile
|
||||
@dev_gemfile ||= git_root.join("dev_gems.rb")
|
||||
end
|
||||
|
@ -150,6 +154,10 @@ module Spec
|
|||
tmp.join("gems/rubocop")
|
||||
end
|
||||
|
||||
def standard_gems
|
||||
tmp.join("gems/standard")
|
||||
end
|
||||
|
||||
def file_uri_for(path)
|
||||
protocol = "file://"
|
||||
root = Gem.win_platform? ? "/" : ""
|
||||
|
@ -285,6 +293,17 @@ module Spec
|
|||
source_root.join("tool/bundler/#{filename}.rb")
|
||||
end
|
||||
|
||||
def standard_gemfile_basename
|
||||
filename = if RUBY_VERSION.start_with?("2.3")
|
||||
"standard23_gems"
|
||||
elsif RUBY_VERSION.start_with?("2.4")
|
||||
"standard24_gems"
|
||||
else
|
||||
"standard_gems"
|
||||
end
|
||||
source_root.join("tool/bundler/#{filename}.rb")
|
||||
end
|
||||
|
||||
extend self
|
||||
end
|
||||
end
|
||||
|
|
|
@ -69,6 +69,7 @@ module Spec
|
|||
|
||||
install_gems(test_gemfile)
|
||||
install_gems(rubocop_gemfile, Path.rubocop_gems.to_s)
|
||||
install_gems(standard_gemfile, Path.standard_gems.to_s)
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -118,6 +119,10 @@ module Spec
|
|||
Path.rubocop_gemfile
|
||||
end
|
||||
|
||||
def standard_gemfile
|
||||
Path.standard_gemfile
|
||||
end
|
||||
|
||||
def dev_gemfile
|
||||
Path.dev_gemfile
|
||||
end
|
||||
|
|
|
@ -1,30 +1,30 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: DES-CBC,4E38D58B5A059DB6
|
||||
DEK-Info: AES-256-CBC,CB6FD0B173EF450C6EE21A01DD785C1D
|
||||
|
||||
IgWLfnHVnkErKkhysrUMoE0ubkRDtJXZv9KR02jGGFk/kGqWyTqPk08uzhwVNM+l
|
||||
eOk0qfPykkJM3KZgqTsD6xfA1D5WqFp5mLoFXVVTn9I3acSZsqOY0FweCipwdVpI
|
||||
x+9Fl+v62kIW06dOjyWLE1abed9hHiXesGGsD87/RJSywy4OBxOcrhR1fJLK4ElR
|
||||
ya0UzI7rWnmZMChjaZBssfzT1DR79/dARXhon2m5EiIJDjMpc8BKGYlQy5RHCHwA
|
||||
cnrhUTTvsggZbQtmLZ/yVx8FSJ273XpYR0pmwbw4j1R+zeXQRK5MroBnCfOGcYa7
|
||||
rmpERmDW3VAuxXR20SUAGdo1XOMTDe1uLbaotn6e56pXghIaYROTPS+HsuOkAZGY
|
||||
OYWEkUoyog4l4n+h/C1umFfTFGvKNATLgDugONFvTw/PLbjvl+sWMy2QfqH0MlNB
|
||||
DIUPxhEVCFD9oB4nfB86WDAmPp1DH9/IBet/21kbQ2eTIzakTdG3XiC+xzAQRu68
|
||||
EOCTbasFWGxlCix66gt4xWMLksEg8UhWSpjS3/HsifrKyNMB8sfUFYmZmOYMW4mf
|
||||
NuEtpBL3AdHNObN8nQ75HfehukzNpbYVRsLzWrVgtxvXHVpnvoCCpCvQBMHeRZxK
|
||||
6m028mhH1m6yYE/uGFiRKLrN7BKAttbUiqnGgVIg/lQQilFWwylxQ6aXqJGmNgxa
|
||||
oihzWZRlXivIhhrM7VMnLoKAF/YfmWpP3zahGpBQGfObtPtm44R0ezXPdtsivnyu
|
||||
CmFOPGzRNMKZtH/lwVhuIIK3AFIGDsRRP9ySN4YfjQZnTdu2sRlxBnANP9m8W9T2
|
||||
p+C4zVkDYAbsuWq2HpHwsdL8gqIiXeptsHLqkNw+ulSSLyeBCgM9fpV3RsNGjwqu
|
||||
k8QLb1CYp2VX46CE8UKvOd/nyFnEsD+EAc3WangEwA41m2IaXcbs9Au7xsG9oacZ
|
||||
DrxlJVNxlxO9YyP9dNOTfP0fHIiygKQQY2aU3y3oRneu7ogYES5V2mUNH7cYUWVL
|
||||
CHPXAoUXJErvDQ/opW2DroA9Eqv9sST6WqBf6LXRcWU0ntfzcFUbEqgmCmB7Cbu2
|
||||
8udEn6iWilQahLyDoAShLkU7+Tk78Z1c6RuqjyY4VboZPzxrTYK8YIXzwX+jj9bG
|
||||
KIIGS5eghK185+AjlwtzJ7MBdoL323YIik6uOZluhnJHLaxjxUXGa1VqDgsyqGi7
|
||||
ISRMTpVTrbR+UtoEi4ZhMjobtFUr7lGkt24VkXwBKdoyryj4RPHGdp7Tf6XDJufQ
|
||||
+KKhqt8QrpOTPiMskFN2disOSF5/YZCmtT84nkhU7Hf1lkQ2kfx1zfNk0GqYYXOW
|
||||
zHOAczy8gWBRetDMnhRYohDzQGWn//b+2Wr2n1RD8D9kyjMRhpFMYfQGfRcuPGjW
|
||||
91k/T0XFcjcjeZPL9s+HITmrh7zg5WxbCfTEp91j3Oy1bns196SY77TE0BzUsqR2
|
||||
geJggcUMEfyvHiiCMtijmSSD9nf8tNIxLVL8Jaf1coA6e1CrlHnYAu2f/Q3GIcvU
|
||||
EEEmw+cZRwsk4fffYzh5psxxGdXKBv1KcQ/CeBhZL0WJsCp2y5oxwg==
|
||||
KqHn2Df8hSuwNE+W+60MnGtc6xpoXmF3iN25iVwcN67krYn+N6cBhjFeXwXccYwJ
|
||||
2gHSu4iEK9Qe32vK0yuv8N9h/fmsabZl0TotnEem/pqO5T8W4LxyK+Rw0s6RB30S
|
||||
C+mUisRADTanAxyBxsNU8xR8OAUNMAAxV1me6It0W2lfNE3t5jg/Kr0NWMoRUNRx
|
||||
dkE6WlD5D8jBeC3QdZ6OuE7QXOCEAWAjcFMc0d1WJq2t2r3TrLVfTH7EOoRyvL1H
|
||||
rrFRx/dEW1UJfM6P11wB5R0nhg3rDXF7oDFszjwO/3tzARke0NZuN37l301lYRl1
|
||||
aolO6sShJLa0Ml/TgNcJw0S6rc6a1Z52gTfQKztKcL1UX4HLZg75zKmn6qfatMBC
|
||||
iXn+pQRYNsOPQ5h4r7lBBqvuV+gBw+rN768tYpZ2/YVDaygxETHcZAFCdAw/JNbP
|
||||
d0XPIbP79NRrCgzSo58LKQGuOQf3Hh0vp1YS+MilMtm/eogoj1enSPM+ymStHRwG
|
||||
i+D00xCQ6blSOZ2eUUBJXt11YzP22GYnv+XTR/5kGKkTIvoRMfd+39bQyR32IEv2
|
||||
Z+yweAGQInD94eifT9ObbIayJ47y01KP0+Vj6hz4RCFsmJKsYiai5JiKlmf7lV9w
|
||||
7zH3TtCOx/xSyomesXVRkqvFkdyeguU72kXc5tiMPaDXGCOeV0GWyR1GU1DUX9/K
|
||||
60E7ym0Wx77WGMKk2fkirZzBdOeliyCRUXd7ccN2rBCjTwtjAUIk27lwzdUaTUv7
|
||||
EmjauDvSMFtir58c+zjlLmBaSQOzKcj0KXMp0Oucls9bD85WGGbGyzGhTa0AZ+/+
|
||||
cCEJt7RAwW0kTEO/uO+BAZe/zBoi9ek+QBn54FK3E7CXfS4Oi9Qbc3fwlVyTlVmz
|
||||
ZGrCncO0TIVGErFWK24Z7lX8rBnk8enfnamrPfKtwn4LG9aDfhSj8DtisjlRUVT5
|
||||
chDQ+CCi9rh3wXh28lyS+nXJ3yFidCzRgcsc3PpN/c4DNRggZc+C/KDw+J2FW+8Y
|
||||
p65OliBQHQcG0PnCa2xRyCGevytPG0rfNDgyaY33dPEo90mBLVcwLbzGiSGBHgFl
|
||||
pr8A/rqbnFpRO39NYbACeRFCqPpzyzfARCCcjcDoFrENdIaJui0fjlBkoV3B/KiK
|
||||
EVjDcgwt1HAtz8bV2YJ+OpQbhD7E90e2vTRMuXAH21Ygo32VOS0LRlCRc9ZyZW4z
|
||||
PTyO/6a+FbXZ1zhVJxu/0bmBERZ14WVmWq56oxQav8knpxYeYPgpEmIZnrHnJ1Ko
|
||||
UoXcc8Hy4NKtaBmDcaF8TCobNsRZTxO/htqpdyNsOrBSsnX2kP5D/O1l1vuVYi1/
|
||||
RYfUqL9dvGzvfsFuuDDjDlQ/fIA6pFzJV3fy4KJHlF1r33qaE/lNMdpKljBwvUII
|
||||
Vog4cGmzxssqK5q9kuogcuyeOuFODjBNW4qt0WylSi9bwwy3ZwaZLRqhngz6+tCV
|
||||
Jp45Gk881XiVe3aVU0l+4DmJJ9/5vwqjH5Vo/GJqFU6gzB+Zv/0plYeNkuE0Xo2z
|
||||
ecdxnGKVPl42q44lvczjDw2KX0ahxQrfrbcl48//zR295u9POzCL97d6zpioI2NR
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
|
|
@ -16,16 +16,6 @@ begin
|
|||
rescue Gem::LoadError
|
||||
end
|
||||
|
||||
begin
|
||||
require 'simplecov'
|
||||
SimpleCov.start do
|
||||
add_filter "/test/"
|
||||
add_filter "/bundler/"
|
||||
add_filter "/lib/rubygems/resolver/molinillo"
|
||||
end
|
||||
rescue LoadError
|
||||
end
|
||||
|
||||
if File.exist?(bundler_gemspec)
|
||||
require_relative '../../bundler/lib/bundler'
|
||||
else
|
||||
|
@ -409,6 +399,14 @@ class Gem::TestCase < Test::Unit::TestCase
|
|||
@orig_bindir = RbConfig::CONFIG["bindir"]
|
||||
RbConfig::CONFIG["bindir"] = File.join @gemhome, "bin"
|
||||
|
||||
@orig_sitelibdir = RbConfig::CONFIG["sitelibdir"]
|
||||
new_sitelibdir = @orig_sitelibdir.sub(RbConfig::CONFIG["prefix"], @gemhome)
|
||||
$LOAD_PATH.insert(Gem.load_path_insert_index, new_sitelibdir)
|
||||
RbConfig::CONFIG["sitelibdir"] = new_sitelibdir
|
||||
|
||||
@orig_mandir = RbConfig::CONFIG["mandir"]
|
||||
RbConfig::CONFIG["mandir"] = File.join @gemhome, "share", "man"
|
||||
|
||||
Gem::Specification.unresolved_deps.clear
|
||||
Gem.use_paths(@gemhome)
|
||||
|
||||
|
@ -480,6 +478,8 @@ class Gem::TestCase < Test::Unit::TestCase
|
|||
|
||||
Gem.ruby = @orig_ruby if @orig_ruby
|
||||
|
||||
RbConfig::CONFIG['mandir'] = @orig_mandir
|
||||
RbConfig::CONFIG['sitelibdir'] = @orig_sitelibdir
|
||||
RbConfig::CONFIG['bindir'] = @orig_bindir
|
||||
|
||||
Gem.instance_variable_set :@default_specifications_dir, nil
|
||||
|
@ -1084,19 +1084,23 @@ Also, a list:
|
|||
@fetcher.data["#{@gem_repo}latest_specs.#{v}.gz"] = l_zip
|
||||
@fetcher.data["#{@gem_repo}prerelease_specs.#{v}.gz"] = p_zip
|
||||
|
||||
v = Gem.marshal_version
|
||||
|
||||
all_specs.each do |spec|
|
||||
path = "#{@gem_repo}quick/Marshal.#{v}/#{spec.original_name}.gemspec.rz"
|
||||
data = Marshal.dump spec
|
||||
data_deflate = Zlib::Deflate.deflate data
|
||||
@fetcher.data[path] = data_deflate
|
||||
end
|
||||
write_marshalled_gemspecs(*all_specs)
|
||||
end
|
||||
|
||||
nil # force errors
|
||||
end
|
||||
|
||||
def write_marshalled_gemspecs(*all_specs)
|
||||
v = Gem.marshal_version
|
||||
|
||||
all_specs.each do |spec|
|
||||
path = "#{@gem_repo}quick/Marshal.#{v}/#{spec.original_name}.gemspec.rz"
|
||||
data = Marshal.dump spec
|
||||
data_deflate = Zlib::Deflate.deflate data
|
||||
@fetcher.data[path] = data_deflate
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Deflates +data+
|
||||
|
||||
|
|
|
@ -118,7 +118,7 @@ class TestGemCommand < Gem::TestCase
|
|||
use_ui @ui do
|
||||
@cmd.when_invoked { true }
|
||||
|
||||
ex = assert_raise OptionParser::InvalidOption do
|
||||
ex = assert_raise Gem::OptionParser::InvalidOption do
|
||||
@cmd.invoke('-zzz')
|
||||
end
|
||||
|
||||
|
|
|
@ -745,7 +745,7 @@ ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exis
|
|||
|
||||
def test_handle_options_add_bad
|
||||
nonexistent = File.join @tempdir, 'nonexistent'
|
||||
e = assert_raise OptionParser::InvalidArgument do
|
||||
e = assert_raise Gem::OptionParser::InvalidArgument do
|
||||
@cmd.handle_options %W[--add #{nonexistent}]
|
||||
end
|
||||
|
||||
|
@ -755,7 +755,7 @@ ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exis
|
|||
bad = File.join @tempdir, 'bad'
|
||||
FileUtils.touch bad
|
||||
|
||||
e = assert_raise OptionParser::InvalidArgument do
|
||||
e = assert_raise Gem::OptionParser::InvalidArgument do
|
||||
@cmd.handle_options %W[--add #{bad}]
|
||||
end
|
||||
|
||||
|
@ -765,7 +765,7 @@ ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exis
|
|||
|
||||
def test_handle_options_certificate
|
||||
nonexistent = File.join @tempdir, 'nonexistent'
|
||||
e = assert_raise OptionParser::InvalidArgument do
|
||||
e = assert_raise Gem::OptionParser::InvalidArgument do
|
||||
@cmd.handle_options %W[--certificate #{nonexistent}]
|
||||
end
|
||||
|
||||
|
@ -775,7 +775,7 @@ ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exis
|
|||
bad = File.join @tempdir, 'bad'
|
||||
FileUtils.touch bad
|
||||
|
||||
e = assert_raise OptionParser::InvalidArgument do
|
||||
e = assert_raise Gem::OptionParser::InvalidArgument do
|
||||
@cmd.handle_options %W[--certificate #{bad}]
|
||||
end
|
||||
|
||||
|
@ -786,7 +786,7 @@ ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exis
|
|||
|
||||
def test_handle_options_key_bad
|
||||
nonexistent = File.join @tempdir, 'nonexistent'
|
||||
e = assert_raise OptionParser::InvalidArgument do
|
||||
e = assert_raise Gem::OptionParser::InvalidArgument do
|
||||
@cmd.handle_options %W[--private-key #{nonexistent}]
|
||||
end
|
||||
|
||||
|
@ -797,14 +797,14 @@ ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exis
|
|||
bad = File.join @tempdir, 'bad'
|
||||
FileUtils.touch bad
|
||||
|
||||
e = assert_raise OptionParser::InvalidArgument do
|
||||
e = assert_raise Gem::OptionParser::InvalidArgument do
|
||||
@cmd.handle_options %W[--private-key #{bad}]
|
||||
end
|
||||
|
||||
assert_equal "invalid argument: --private-key #{bad}: invalid RSA, DSA, or EC key",
|
||||
e.message
|
||||
|
||||
e = assert_raise OptionParser::InvalidArgument do
|
||||
e = assert_raise Gem::OptionParser::InvalidArgument do
|
||||
@cmd.handle_options %W[--private-key #{PUBLIC_KEY_FILE}]
|
||||
end
|
||||
|
||||
|
@ -851,7 +851,7 @@ ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exis
|
|||
|
||||
def test_handle_options_sign_nonexistent
|
||||
nonexistent = File.join @tempdir, 'nonexistent'
|
||||
e = assert_raise OptionParser::InvalidArgument do
|
||||
e = assert_raise Gem::OptionParser::InvalidArgument do
|
||||
@cmd.handle_options %W[
|
||||
--private-key #{ALTERNATE_KEY_FILE}
|
||||
|
||||
|
|
|
@ -79,6 +79,42 @@ class TestGemCommandsFetchCommand < Gem::TestCase
|
|||
"#{a2.full_name} not fetched")
|
||||
end
|
||||
|
||||
def test_execute_platform
|
||||
a2_spec, a2 = util_gem("a", "2")
|
||||
|
||||
a2_universal_darwin_spec, a2_universal_darwin = util_gem("a", "2") do |s|
|
||||
s.platform = 'universal-darwin'
|
||||
end
|
||||
|
||||
Gem::RemoteFetcher.fetcher = @fetcher = Gem::FakeFetcher.new
|
||||
|
||||
write_marshalled_gemspecs(a2_spec, a2_universal_darwin_spec)
|
||||
|
||||
@cmd.options[:args] = %w[a]
|
||||
|
||||
@fetcher.data["#{@gem_repo}latest_specs.#{Gem.marshal_version}.gz"] = util_gzip(Marshal.dump([
|
||||
Gem::NameTuple.new(a2_spec.name, a2_spec.version, a2_spec.platform),
|
||||
Gem::NameTuple.new(a2_universal_darwin_spec.name, a2_universal_darwin_spec.version, a2_universal_darwin_spec.platform),
|
||||
]))
|
||||
|
||||
@fetcher.data["#{@gem_repo}gems/#{a2_spec.file_name}"] = Gem.read_binary(a2)
|
||||
FileUtils.cp a2, a2_spec.cache_file
|
||||
|
||||
@fetcher.data["#{@gem_repo}gems/#{a2_universal_darwin_spec.file_name}"] = Gem.read_binary(a2_universal_darwin)
|
||||
FileUtils.cp a2_universal_darwin, a2_universal_darwin_spec.cache_file
|
||||
|
||||
util_set_arch 'arm64-darwin20' do
|
||||
use_ui @ui do
|
||||
Dir.chdir @tempdir do
|
||||
@cmd.execute
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assert_path_exist(File.join(@tempdir, a2_universal_darwin_spec.file_name),
|
||||
"#{a2_universal_darwin_spec.full_name} not fetched")
|
||||
end
|
||||
|
||||
def test_execute_specific_prerelease
|
||||
specs = spec_fetcher do |fetcher|
|
||||
fetcher.gem 'a', 2
|
||||
|
|
|
@ -40,18 +40,18 @@ class TestGemCommandsServerCommand < Gem::TestCase
|
|||
begin
|
||||
@cmd.send :handle_options, %w[-p discard]
|
||||
assert_equal 9, @cmd.options[:port]
|
||||
rescue OptionParser::InvalidArgument
|
||||
rescue Gem::OptionParser::InvalidArgument
|
||||
# for container environment on GitHub Actions
|
||||
end
|
||||
|
||||
e = assert_raise OptionParser::InvalidArgument do
|
||||
e = assert_raise Gem::OptionParser::InvalidArgument do
|
||||
@cmd.send :handle_options, %w[-p nonexistent]
|
||||
end
|
||||
|
||||
assert_equal 'invalid argument: -p nonexistent: no such named service',
|
||||
e.message
|
||||
|
||||
e = assert_raise OptionParser::InvalidArgument do
|
||||
e = assert_raise Gem::OptionParser::InvalidArgument do
|
||||
@cmd.send :handle_options, %w[-p 65536]
|
||||
end
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue