summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/bundler.rb4
-rw-r--r--lib/bundler/cli.rb5
-rw-r--r--lib/bundler/cli/add.rb9
-rw-r--r--lib/bundler/injector.rb12
-rw-r--r--lib/bundler/installer.rb2
-rw-r--r--lib/bundler/plugin.rb7
-rw-r--r--lib/bundler/plugin/events.rb39
-rw-r--r--lib/bundler/templates/newgem/travis.yml.tt2
-rw-r--r--man/bundle-add.ronn15
-rw-r--r--man/bundle-binstubs.ronn2
-rw-r--r--man/bundle-config.ronn8
-rw-r--r--man/bundle-exec.ronn4
-rw-r--r--man/bundle-gem.ronn2
-rw-r--r--man/bundle-install.ronn2
-rw-r--r--man/bundle-lock.ronn2
-rw-r--r--man/bundle-outdated.ronn2
-rw-r--r--man/bundle-package.ronn6
-rw-r--r--man/bundle-update.ronn16
-rw-r--r--man/bundle-viz.ronn2
-rw-r--r--man/bundle.ronn36
-rw-r--r--man/gemfile.5.ronn4
-rw-r--r--spec/bundler/plugin/events_spec.rb18
-rw-r--r--spec/bundler/plugin_spec.rb40
-rw-r--r--spec/commands/add_spec.rb42
24 files changed, 219 insertions, 62 deletions
diff --git a/lib/bundler.rb b/lib/bundler.rb
index 3239e83885..7904496e96 100644
--- a/lib/bundler.rb
+++ b/lib/bundler.rb
@@ -421,7 +421,9 @@ EOF
end
def read_file(file)
- File.open(file, "rb", &:read)
+ SharedHelpers.filesystem_access(file, :read) do
+ File.open(file, "rb", &:read)
+ end
end
def load_marshal(data)
diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb
index 1b913024e2..926a748231 100644
--- a/lib/bundler/cli.rb
+++ b/lib/bundler/cli.rb
@@ -333,7 +333,10 @@ module Bundler
method_option "version", :aliases => "-v", :type => :string
method_option "group", :aliases => "-g", :type => :string
method_option "source", :aliases => "-s", :type => :string
-
+ method_option "skip-install", :type => :boolean, :banner =>
+ "Adds gem to the Gemfile but does not install it"
+ method_option "optimistic", :type => :boolean, :banner => "Adds optimistic declaration of version to gem"
+ method_option "strict", :type => :boolean, :banner => "Adds strict declaration of version to gem"
def add(gem_name)
require "bundler/cli/add"
Add.new(options.dup, gem_name).run
diff --git a/lib/bundler/cli/add.rb b/lib/bundler/cli/add.rb
index 1fcbd22f28..6adccb13d0 100644
--- a/lib/bundler/cli/add.rb
+++ b/lib/bundler/cli/add.rb
@@ -9,6 +9,8 @@ module Bundler
end
def run
+ raise InvalidOption, "You can not specify `--strict` and `--optimistic` at the same time." if @options[:strict] && @options[:optimistic]
+
version = @options[:version].nil? ? nil : @options[:version].split(",").map(&:strip)
unless version.nil?
@@ -18,8 +20,11 @@ module Bundler
end
dependency = Bundler::Dependency.new(@gem_name, version, @options)
- Injector.inject([dependency], :conservative_versioning => @options[:version].nil?) # Perform conservative versioning only when version is not specified
- Installer.install(Bundler.root, Bundler.definition)
+ Injector.inject([dependency],
+ :conservative_versioning => @options[:version].nil?, # Perform conservative versioning only when version is not specified
+ :optimistic => @options[:optimistic],
+ :strict => @options[:strict])
+ Installer.install(Bundler.root, Bundler.definition) unless @options["skip-install"]
end
end
end
diff --git a/lib/bundler/injector.rb b/lib/bundler/injector.rb
index 9c67a80777..b62279b94c 100644
--- a/lib/bundler/injector.rb
+++ b/lib/bundler/injector.rb
@@ -61,7 +61,17 @@ module Bundler
seg_end_index = version >= Gem::Version.new("1.0") ? 1 : 2
prerelease_suffix = version.to_s.gsub(version.release.to_s, "") if version.prerelease?
- "~> #{segments[0..seg_end_index].join(".")}#{prerelease_suffix}"
+ "#{version_prefix}#{segments[0..seg_end_index].join(".")}#{prerelease_suffix}"
+ end
+
+ def version_prefix
+ if @options[:strict]
+ "= "
+ elsif @options[:optimistic]
+ ">= "
+ else
+ "~> "
+ end
end
def build_gem_lines(conservative_versioning)
diff --git a/lib/bundler/installer.rb b/lib/bundler/installer.rb
index 33f5d62844..b934c38b94 100644
--- a/lib/bundler/installer.rb
+++ b/lib/bundler/installer.rb
@@ -21,7 +21,7 @@ module Bundler
# For more information see the #run method on this class.
def self.install(root, definition, options = {})
installer = new(root, definition)
- Plugin.hook("before-install-all", definition.dependencies)
+ Plugin.hook(Plugin::Events::GEM_BEFORE_INSTALL_ALL, definition.dependencies)
installer.run(options)
installer
end
diff --git a/lib/bundler/plugin.rb b/lib/bundler/plugin.rb
index 127f1f64c0..422d4acfbc 100644
--- a/lib/bundler/plugin.rb
+++ b/lib/bundler/plugin.rb
@@ -5,6 +5,7 @@ require "bundler/plugin/api"
module Bundler
module Plugin
autoload :DSL, "bundler/plugin/dsl"
+ autoload :Events, "bundler/plugin/events"
autoload :Index, "bundler/plugin/index"
autoload :Installer, "bundler/plugin/installer"
autoload :SourceList, "bundler/plugin/source_list"
@@ -175,6 +176,9 @@ module Bundler
# To be called via the API to register a hooks and corresponding block that
# will be called to handle the hook
def add_hook(event, &block)
+ unless Events.defined_event?(event)
+ raise ArgumentError, "Event '#{event}' not defined in Bundler::Plugin::Events"
+ end
@hooks_by_event[event.to_s] << block
end
@@ -186,6 +190,9 @@ module Bundler
# @param [String] event
def hook(event, *args, &arg_blk)
return unless Bundler.feature_flag.plugins?
+ unless Events.defined_event?(event)
+ raise ArgumentError, "Event '#{event}' not defined in Bundler::Plugin::Events"
+ end
plugins = index.hook_plugins(event)
return unless plugins.any?
diff --git a/lib/bundler/plugin/events.rb b/lib/bundler/plugin/events.rb
new file mode 100644
index 0000000000..26bd59e5cf
--- /dev/null
+++ b/lib/bundler/plugin/events.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+module Bundler
+ module Plugin
+ module Events
+ def self.define(const, event)
+ const = const.to_sym.freeze
+ if const_defined?(const) && const_get(const) != event
+ raise ArgumentError, "Attempting to reassign #{const} to a different value"
+ end
+ const_set(const, event) unless const_defined?(const)
+ @events ||= {}
+ @events[event] = const
+ end
+ private_class_method :define
+
+ def self.reset
+ @events.each_value do |const|
+ remove_const(const)
+ end
+ @events = nil
+ end
+ private_class_method :reset
+
+ # Check if an event has been defined
+ # @param event [String] An event to check
+ # @return [Boolean] A boolean indicating if the event has been defined
+ def self.defined_event?(event)
+ @events ||= {}
+ @events.key?(event)
+ end
+
+ # @!parse
+ # # A hook called before any gems install
+ # GEM_BEFORE_INSTALL_ALL = "before-install-all"
+ define :GEM_BEFORE_INSTALL_ALL, "before-install-all"
+ end
+ end
+end
diff --git a/lib/bundler/templates/newgem/travis.yml.tt b/lib/bundler/templates/newgem/travis.yml.tt
index fe0761cc23..7a3381a889 100644
--- a/lib/bundler/templates/newgem/travis.yml.tt
+++ b/lib/bundler/templates/newgem/travis.yml.tt
@@ -1,5 +1,7 @@
+---
sudo: false
language: ruby
+cache: bundler
rvm:
- <%= RUBY_VERSION %>
before_install: gem install bundler -v <%= Bundler::VERSION %>
diff --git a/man/bundle-add.ronn b/man/bundle-add.ronn
index f0f9b54d8f..1e2d732ec6 100644
--- a/man/bundle-add.ronn
+++ b/man/bundle-add.ronn
@@ -3,10 +3,10 @@ bundle-add(1) -- Add gem to the Gemfile and run bundle install
## SYNOPSIS
-`bundle add` <GEM_NAME> [--group=GROUP] [--version=VERSION] [--source=SOURCE]
+`bundle add` <GEM_NAME> [--group=GROUP] [--version=VERSION] [--source=SOURCE] [--skip-install] [--strict] [--optimistic]
## DESCRIPTION
-Adds the named gem to the Gemfile and run `bundle install`.
+Adds the named gem to the Gemfile and run `bundle install`. `bundle install` can be avoided by using the flag `--skip-install`.
Example:
@@ -16,6 +16,8 @@ bundle add rails --version "< 3.0, > 1.1"
bundle add rails --version "~> 5.0.0" --source "https://gems.example.com" --group "development"
+bundle add rails --skip-install
+
bundle add rails --group "development, test"
## OPTIONS
@@ -27,3 +29,12 @@ bundle add rails --group "development, test"
* `--source`, , `-s`:
Specify the source for the added gem.
+
+* `--skip-install`:
+ Adds the gem to the Gemfile but does not install it.
+
+* `--optimistic`:
+ Adds optimistic declaration of version
+
+* `--strict`:
+ Adds strict declaration of version
diff --git a/man/bundle-binstubs.ronn b/man/bundle-binstubs.ronn
index 550c0f6d66..c1ae0988cd 100644
--- a/man/bundle-binstubs.ronn
+++ b/man/bundle-binstubs.ronn
@@ -40,4 +40,4 @@ Calling binstubs with [GEM [GEM]] will create binstubs for all given gems.
## BUNDLE INSTALL --BINSTUBS
To create binstubs for all the gems in the bundle you can use the `--binstubs`
-flag in [bundle install(1)][bundle-install(1)].
+flag in [bundle install(1)](bundle-install.1.html).
diff --git a/man/bundle-config.ronn b/man/bundle-config.ronn
index 74f562fedf..15f78937dd 100644
--- a/man/bundle-config.ronn
+++ b/man/bundle-config.ronn
@@ -102,11 +102,11 @@ After running this command, every time bundler needs to install the
Configuration keys in bundler have two forms: the canonical form and the
environment variable form.
-For instance, passing the `--without` flag to [bundle install(1)][bundle-install(1)]
+For instance, passing the `--without` flag to [bundle install(1)](bundle-install.1.html)
prevents Bundler from installing certain groups specified in the Gemfile(5). Bundler
persists this value in `app/.bundle/config` so that calls to `Bundler.setup`
do not try to find gems from the `Gemfile` that you didn't install. Additionally,
-subsequent calls to [bundle install(1)][bundle-install(1)] remember this setting
+subsequent calls to [bundle install(1)](bundle-install.1.html) remember this setting
and skip those groups.
The canonical form of this configuration is `"without"`. To convert the canonical
@@ -120,7 +120,7 @@ the environment variable `BUNDLE_LOCAL__RACK`.
## LIST OF AVAILABLE KEYS
The following is a list of all configuration keys and their purpose. You can
-learn more about their operation in [bundle install(1)][bundle-install(1)].
+learn more about their operation in [bundle install(1)](bundle-install.1.html).
* `allow_bundler_dependency_conflicts` (`BUNDLE_ALLOW_BUNDLER_DEPENDENCY_CONFLICTS`):
Allow resolving to specifications that have dependencies on `bundler` that
@@ -285,7 +285,7 @@ learn more about their operation in [bundle install(1)][bundle-install(1)].
A `:`-separated list of groups whose gems bundler should not install.
In general, you should set these settings per-application by using the applicable
-flag to the [bundle install(1)][bundle-install(1)] or [bundle package(1)][bundle-package(1)] command.
+flag to the [bundle install(1)](bundle-install.1.html) or [bundle package(1)](bundle-package.1.html) command.
You can set them globally either via environment variables or `bundle config`,
whichever is preferable for your setup. If you use both, environment variables
diff --git a/man/bundle-exec.ronn b/man/bundle-exec.ronn
index 7b63cc7b47..aa680f4c5d 100644
--- a/man/bundle-exec.ronn
+++ b/man/bundle-exec.ronn
@@ -12,7 +12,7 @@ This command executes the command, making all gems specified in the
Essentially, if you would normally have run something like
`rspec spec/my_spec.rb`, and you want to use the gems specified
-in the [`Gemfile(5)`][Gemfile(5)] and installed via [bundle install(1)][bundle-install(1)], you
+in the [`Gemfile(5)`][Gemfile(5)] and installed via [bundle install(1)](bundle-install.1.html), you
should run `bundle exec rspec spec/my_spec.rb`.
Note that `bundle exec` does not require that an executable is
@@ -27,7 +27,7 @@ available on your shell's `$PATH`.
## BUNDLE INSTALL --BINSTUBS
-If you use the `--binstubs` flag in [bundle install(1)][bundle-install(1)], Bundler will
+If you use the `--binstubs` flag in [bundle install(1)](bundle-install.1.html), Bundler will
automatically create a directory (which defaults to `app_root/bin`)
containing all of the executables available from gems in the bundle.
diff --git a/man/bundle-gem.ronn b/man/bundle-gem.ronn
index 0002f05c40..cf3d037df2 100644
--- a/man/bundle-gem.ronn
+++ b/man/bundle-gem.ronn
@@ -75,4 +75,4 @@ configuration file using the following names:
## SEE ALSO
-* [bundle config(1)][bundle-config(1)]
+* [bundle config(1)](bundle-config.1.html)
diff --git a/man/bundle-install.ronn b/man/bundle-install.ronn
index a4034bc506..0bfd29234a 100644
--- a/man/bundle-install.ronn
+++ b/man/bundle-install.ronn
@@ -375,7 +375,7 @@ which other gems in the Gemfile(5) still depend on, run
`Summary`: In general, after making a change to the Gemfile(5) , you
should first try to run `bundle install`, which will guarantee that no
other gem in the Gemfile(5) is impacted by the change. If that
-does not work, run [bundle update(1)][bundle-update(1)].
+does not work, run [bundle update(1)](bundle-update.1.html).
## SEE ALSO
diff --git a/man/bundle-lock.ronn b/man/bundle-lock.ronn
index 951194715f..3aa5920f5a 100644
--- a/man/bundle-lock.ronn
+++ b/man/bundle-lock.ronn
@@ -91,4 +91,4 @@ For a full explanation of gem platforms, see `gem help platform`.
## PATCH LEVEL OPTIONS
-See [bundle update(1)][bundle-update(1)] for details.
+See [bundle update(1)](bundle-update.1.html) for details.
diff --git a/man/bundle-outdated.ronn b/man/bundle-outdated.ronn
index 76baa3d755..8b05af1e52 100644
--- a/man/bundle-outdated.ronn
+++ b/man/bundle-outdated.ronn
@@ -69,7 +69,7 @@ are up to date, Bundler will exit with a status of 0. Otherwise, it will exit 1.
## PATCH LEVEL OPTIONS
-See [bundle update(1)][bundle-update(1)] for details.
+See [bundle update(1)](bundle-update.1.html) for details.
One difference between the patch level options in `bundle update` and here is the `--strict` option.
`--strict` was already an option on outdated before the patch level options were added. `--strict`
diff --git a/man/bundle-package.ronn b/man/bundle-package.ronn
index e2d83c092f..bc137374da 100644
--- a/man/bundle-package.ronn
+++ b/man/bundle-package.ronn
@@ -27,8 +27,8 @@ in your local bundler configuration.
## REMOTE FETCHING
-By default, if you run `bundle install(1)`][bundle-install(1)] after running
-[bundle package(1)][bundle-package(1)], bundler will still connect to `rubygems.org`
+By default, if you run `bundle install(1)`](bundle-install.1.html) after running
+[bundle package(1)](bundle-package.1.html), bundler will still connect to `rubygems.org`
to check whether a platform-specific gem exists for any of the gems
in `vendor/cache`.
@@ -66,7 +66,7 @@ machine and check in the gems. For instance, you can run
staging process, and check in the `vendor/cache` before
deploying to production.
-By default, [bundle package(1)][bundle-package(1)] fetches and also
+By default, [bundle package(1)](bundle-package.1.html) fetches and also
installs the gems to the default location. To package the
dependencies to `vendor/cache` without installing them to the
local install location, you can run `bundle package --no-install`.
diff --git a/man/bundle-update.ronn b/man/bundle-update.ronn
index 493986a7a4..2ad678f424 100644
--- a/man/bundle-update.ronn
+++ b/man/bundle-update.ronn
@@ -21,7 +21,7 @@ bundle-update(1) -- Update your gems to the latest available versions
Update the gems specified (all gems, if `--all` flag is used), ignoring
the previously installed gems specified in the `Gemfile.lock`. In
-general, you should use [bundle install(1)][bundle-install(1)] to install the same exact
+general, you should use [bundle install(1)](bundle-install.1.html) to install the same exact
gems and versions across machines.
You would use `bundle update` to explicitly update the version of a
@@ -95,7 +95,7 @@ Consider the following Gemfile(5):
gem "rails", "3.0.0.rc"
gem "nokogiri"
-When you run [bundle install(1)][bundle-install(1)] the first time, bundler will resolve
+When you run [bundle install(1)](bundle-install.1.html) the first time, bundler will resolve
all of the dependencies, all the way down, and install what you need:
Fetching gem metadata from https://rubygems.org/.........
@@ -132,11 +132,11 @@ all of the dependencies, all the way down, and install what you need:
As you can see, even though you have two gems in the Gemfile(5), your application
needs 26 different gems in order to run. Bundler remembers the exact versions
-it installed in `Gemfile.lock`. The next time you run [bundle install(1)][bundle-install(1)], bundler skips
+it installed in `Gemfile.lock`. The next time you run [bundle install(1)](bundle-install.1.html), bundler skips
the dependency resolution and installs the same gems as it installed last time.
After checking in the `Gemfile.lock` into version control and cloning it on another
-machine, running [bundle install(1)][bundle-install(1)] will _still_ install the gems that you installed
+machine, running [bundle install(1)](bundle-install.1.html) will _still_ install the gems that you installed
last time. You don't need to worry that a new release of `erubis` or `mail` changes
the gems you use.
@@ -196,12 +196,12 @@ update all dependencies of that gem, including those that are also dependencies
of another gem.
To prevent updating shared dependencies, prior to version 1.14 the only option
-was the `CONSERVATIVE UPDATING` behavior in [bundle install(1)][bundle-install(1)]:
+was the `CONSERVATIVE UPDATING` behavior in [bundle install(1)](bundle-install.1.html):
In this scenario, updating the `thin` version manually in the Gemfile(5),
-and then running [bundle install(1)][bundle-install(1)] will only update `daemons` and `eventmachine`,
+and then running [bundle install(1)](bundle-install.1.html) will only update `daemons` and `eventmachine`,
but not `rack`. For more information, see the `CONSERVATIVE UPDATING` section
-of [bundle install(1)][bundle-install(1)].
+of [bundle install(1)](bundle-install.1.html).
Starting with 1.14, specifying the `--conservative` option will also prevent shared
dependencies from being updated.
@@ -339,7 +339,7 @@ use the following workflow:
$ git add Gemfile.lock
-* If [bundle install(1)][bundle-install(1)] reports a conflict, manually update the specific
+* If [bundle install(1)](bundle-install.1.html) reports a conflict, manually update the specific
gems that you changed in the Gemfile(5)
$ bundle update rails thin
diff --git a/man/bundle-viz.ronn b/man/bundle-viz.ronn
index 762558c184..701df5415e 100644
--- a/man/bundle-viz.ronn
+++ b/man/bundle-viz.ronn
@@ -14,7 +14,7 @@ bundle-viz(1) -- Generates a visual dependency graph for your Gemfile
`viz` generates a PNG file of the current `Gemfile(5)` as a dependency graph.
`viz` requires the ruby-graphviz gem (and its dependencies).
-The associated gems must also be installed via [`bundle install(1)`][bundle-install(1)].
+The associated gems must also be installed via [`bundle install(1)`](bundle-install.1.html).
## OPTIONS
diff --git a/man/bundle.ronn b/man/bundle.ronn
index a3a651ba3c..c03201a30c 100644
--- a/man/bundle.ronn
+++ b/man/bundle.ronn
@@ -30,20 +30,20 @@ We divide `bundle` subcommands into primary commands and utilities:
## PRIMARY COMMANDS
-* [`bundle install(1)`][bundle-install(1)]:
+* [`bundle install(1)`](bundle-install.1.html):
Install the gems specified by the `Gemfile` or `Gemfile.lock`
-* [`bundle update(1)`][bundle-update(1)]:
+* [`bundle update(1)`](bundle-update.1.html):
Update dependencies to their latest versions
-* [`bundle package(1)`][bundle-package(1)]:
+* [`bundle package(1)`](bundle-package.1.html):
Package the .gem files required by your application into the
`vendor/cache` directory
-* [`bundle exec(1)`][bundle-exec(1)]:
+* [`bundle exec(1)`](bundle-exec.1.html):
Execute a script in the current bundle
-* [`bundle config(1)`][bundle-config(1)]:
+* [`bundle config(1)`](bundle-config.1.html):
Specify and read configuration options for Bundler
* `bundle help(1)`:
@@ -51,47 +51,47 @@ We divide `bundle` subcommands into primary commands and utilities:
## UTILITIES
-* [`bundle add(1)`][bundle-add(1)]:
+* [`bundle add(1)`](bundle-add.1.html):
Add the named gem to the Gemfile and run `bundle install`
-* [`bundle binstubs(1)`][bundle-binstubs(1)]:
+* [`bundle binstubs(1)`](bundle-binstubs.1.html):
Generate binstubs for executables in a gem
-* [`bundle check(1)`][bundle-check(1)]:
+* [`bundle check(1)`](bundle-check.1.html):
Determine whether the requirements for your application are installed
and available to Bundler
-* [`bundle show(1)`][bundle-show(1)]:
+* [`bundle show(1)`](bundle-show.1.html):
Show the source location of a particular gem in the bundle
-* [`bundle outdated(1)`][bundle-outdated(1)]:
+* [`bundle outdated(1)`](bundle-outdated.1.html):
Show all of the outdated gems in the current bundle
* `bundle console(1)`:
Start an IRB session in the current bundle
-* [`bundle open(1)`][bundle-open(1)]:
+* [`bundle open(1)`](bundle-open.1.html):
Open an installed gem in the editor
-* [`bundle lock(1)`][bundle-lock]:
+* [`bundle lock(1)`](bundle-lock.1.hmtl):
Generate a lockfile for your dependencies
-* [`bundle viz(1)`][bundle-viz(1)]:
+* [`bundle viz(1)`](bundle-viz.1.html):
Generate a visual representation of your dependencies
-* [`bundle init(1)`][bundle-init(1)]:
+* [`bundle init(1)`](bundle-init.1.html):
Generate a simple `Gemfile`, placed in the current directory
-* [`bundle gem(1)`][bundle-gem(1)]:
+* [`bundle gem(1)`](bundle-gem.1.html):
Create a simple gem, suitable for development with Bundler
-* [`bundle platform(1)`][bundle-platform(1)]:
+* [`bundle platform(1)`](bundle-platform.1.html):
Display platform compatibility information
-* [`bundle clean(1)`][bundle-clean(1)]:
+* [`bundle clean(1)`](bundle-clean.1.html):
Clean up unused gems in your Bundler directory
-* `bundle doctor(1)`:
+* [`bundle doctor(1)`](bundle-doctor.1.html):
Display warnings about common problems
## PLUGINS
diff --git a/man/gemfile.5.ronn b/man/gemfile.5.ronn
index 9f6bbce93a..5c7ba23b29 100644
--- a/man/gemfile.5.ronn
+++ b/man/gemfile.5.ronn
@@ -35,7 +35,7 @@ this warning, by using the [`:source` option](#SOURCE) or a
### CREDENTIALS
-Some gem sources require a username and password. Use [bundle config(1)][bundle-config(1)] to set
+Some gem sources require a username and password. Use [bundle config(1)](bundle-config.1.html) to set
the username and password for any of the sources that need it. The command must
be run once on each computer that will install the Gemfile, but this keeps the
credentials from being stored in plain text in version control.
@@ -228,7 +228,7 @@ As with groups, you can specify one or more platforms:
gem "ruby-debug", :platforms => :mri_18
gem "nokogiri", :platforms => [:mri_18, :jruby]
-All operations involving groups ([`bundle install`][bundle-install(1)], `Bundler.setup`,
+All operations involving groups ([`bundle install`](bundle-install.1.html), `Bundler.setup`,
`Bundler.require`) behave exactly the same as if any groups not
matching the current platform were explicitly excluded.
diff --git a/spec/bundler/plugin/events_spec.rb b/spec/bundler/plugin/events_spec.rb
new file mode 100644
index 0000000000..b09e915682
--- /dev/null
+++ b/spec/bundler/plugin/events_spec.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+RSpec.describe Bundler::Plugin::Events do
+ context "plugin events" do
+ describe "#define" do
+ it "raises when redefining a constant" do
+ expect do
+ Bundler::Plugin::Events.send(:define, :GEM_BEFORE_INSTALL_ALL, "another-value")
+ end.to raise_error(ArgumentError)
+ end
+
+ it "can define a new constant" do
+ Bundler::Plugin::Events.send(:define, :NEW_CONSTANT, "value")
+ expect(Bundler::Plugin::Events::NEW_CONSTANT).to eq("value")
+ end
+ end
+ end
+end
diff --git a/spec/bundler/plugin_spec.rb b/spec/bundler/plugin_spec.rb
index 68a7e32ad1..eaa0b80905 100644
--- a/spec/bundler/plugin_spec.rb
+++ b/spec/bundler/plugin_spec.rb
@@ -251,6 +251,16 @@ RSpec.describe Bundler::Plugin do
end
end
+ describe "#add_hook" do
+ it "raises an ArgumentError on an unregistered event" do
+ ran = false
+ expect do
+ Plugin.add_hook("unregistered-hook") { ran = true }
+ end.to raise_error(ArgumentError)
+ expect(ran).to be(false)
+ end
+ end
+
describe "#hook" do
before do
path = lib_path("foo-plugin")
@@ -258,7 +268,13 @@ RSpec.describe Bundler::Plugin do
s.write "plugins.rb", code
end
- allow(index).to receive(:hook_plugins).with(event).
+ Bundler::Plugin::Events.send(:reset)
+ Bundler::Plugin::Events.send(:define, :EVENT_1, "event-1")
+ Bundler::Plugin::Events.send(:define, :EVENT_2, "event-2")
+
+ allow(index).to receive(:hook_plugins).with(Bundler::Plugin::Events::EVENT_1).
+ and_return(["foo-plugin"])
+ allow(index).to receive(:hook_plugins).with(Bundler::Plugin::Events::EVENT_2).
and_return(["foo-plugin"])
allow(index).to receive(:plugin_path).with("foo-plugin").and_return(path)
allow(index).to receive(:load_paths).with("foo-plugin").and_return([])
@@ -268,11 +284,15 @@ RSpec.describe Bundler::Plugin do
Bundler::Plugin::API.hook("event-1") { puts "hook for event 1" }
RUBY
- let(:event) { "event-1" }
+ it "raises an ArgumentError on an unregistered event" do
+ expect do
+ Plugin.hook("unregistered-hook")
+ end.to raise_error(ArgumentError)
+ end
it "executes the hook" do
out = capture(:stdout) do
- Plugin.hook("event-1")
+ Plugin.hook(Bundler::Plugin::Events::EVENT_1)
end.strip
expect(out).to eq("hook for event 1")
@@ -280,17 +300,15 @@ RSpec.describe Bundler::Plugin do
context "single plugin declaring more than one hook" do
let(:code) { <<-RUBY }
- Bundler::Plugin::API.hook("event-1") {}
- Bundler::Plugin::API.hook("event-2") {}
+ Bundler::Plugin::API.hook(Bundler::Plugin::Events::EVENT_1) {}
+ Bundler::Plugin::API.hook(Bundler::Plugin::Events::EVENT_2) {}
puts "loaded"
RUBY
- let(:event) { /event-1|event-2/ }
-
it "evals plugins.rb once" do
out = capture(:stdout) do
- Plugin.hook("event-1")
- Plugin.hook("event-2")
+ Plugin.hook(Bundler::Plugin::Events::EVENT_1)
+ Plugin.hook(Bundler::Plugin::Events::EVENT_2)
end.strip
expect(out).to eq("loaded")
@@ -299,12 +317,12 @@ RSpec.describe Bundler::Plugin do
context "a block is passed" do
let(:code) { <<-RUBY }
- Bundler::Plugin::API.hook("#{event}") { |&blk| blk.call }
+ Bundler::Plugin::API.hook(Bundler::Plugin::Events::EVENT_1) { |&blk| blk.call }
RUBY
it "is passed to the hook" do
out = capture(:stdout) do
- Plugin.hook("event-1") { puts "win" }
+ Plugin.hook(Bundler::Plugin::Events::EVENT_1) { puts "win" }
end.strip
expect(out).to eq("win")
diff --git a/spec/commands/add_spec.rb b/spec/commands/add_spec.rb
index d1f2050aa0..bf3b4e1759 100644
--- a/spec/commands/add_spec.rb
+++ b/spec/commands/add_spec.rb
@@ -75,11 +75,21 @@ RSpec.describe "bundle add" do
describe "with --source" do
it "adds dependency with specified source" do
bundle "add 'foo' --source='file://#{gem_repo2}'"
+
expect(bundled_app("Gemfile").read).to match(%r{gem "foo", "~> 2.0", :source => "file:\/\/#{gem_repo2}"})
expect(the_bundle).to include_gems "foo 2.0"
end
end
+ describe "with --skip-install" do
+ it "adds gem to Gemfile but is not installed" do
+ bundle "add foo --skip-install --version=2.0"
+
+ expect(bundled_app("Gemfile").read).to match(/gem "foo", "= 2.0"/)
+ expect(the_bundle).to_not include_gems "foo 2.0"
+ end
+ end
+
it "using combination of short form options works like long form" do
bundle "add 'foo' -s='file://#{gem_repo2}' -g='development' -v='~>1.0'"
expect(bundled_app("Gemfile").read).to include %(gem "foo", "~> 1.0", :group => [:development], :source => "file://#{gem_repo2}")
@@ -106,4 +116,36 @@ RSpec.describe "bundle add" do
bundle "add 'baz' --source='file://does/not/exist'"
expect(out).to include("Could not fetch specs from file://does/not/exist/")
end
+
+ describe "with --optimistic" do
+ it "adds optimistic version" do
+ bundle! "add 'foo' --optimistic"
+ expect(bundled_app("Gemfile").read).to include %(gem "foo", ">= 2.0")
+ expect(the_bundle).to include_gems "foo 2.0"
+ end
+ end
+
+ describe "with --strict option" do
+ it "adds strict version" do
+ bundle! "add 'foo' --strict"
+ expect(bundled_app("Gemfile").read).to include %(gem "foo", "= 2.0")
+ expect(the_bundle).to include_gems "foo 2.0"
+ end
+ end
+
+ describe "with no option" do
+ it "adds pessimistic version" do
+ bundle! "add 'foo'"
+ expect(bundled_app("Gemfile").read).to include %(gem "foo", "~> 2.0")
+ expect(the_bundle).to include_gems "foo 2.0"
+ end
+ end
+
+ describe "with --optimistic and --strict" do
+ it "throws error" do
+ bundle "add 'foo' --strict --optimistic"
+
+ expect(out).to include("You can not specify `--strict` and `--optimistic` at the same time")
+ end
+ end
end