Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/bundler/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ def fund
method_option "path", type: :string, banner: "Specify a different path than the system default, namely, $BUNDLE_PATH or $GEM_HOME (removed)."
method_option "quiet", type: :boolean, banner: "Only output warnings and errors."
method_option "frozen", type: :boolean, banner: "Do not allow the Gemfile.lock to be updated after this bundle cache operation's install (removed)"
method_option "cooldown", type: :numeric, banner: "Only consider gem versions published at least N days ago. Use 0 to disable."
long_desc <<-D
The cache command will copy the .gem files for every gem in the bundle into the
directory ./vendor/cache. If you then check that directory into your source
Expand Down Expand Up @@ -643,6 +644,7 @@ def inject(*)
method_option "strict", type: :boolean, banner: "If updating, do not allow any gem to be updated past latest --patch | --minor | --major"
method_option "conservative", type: :boolean, banner: "If updating, use bundle install conservative update behavior and do not allow shared dependencies to be updated"
method_option "bundler", type: :string, lazy_default: "> 0.a", banner: "Update the locked version of bundler"
method_option "cooldown", type: :numeric, banner: "Only consider gem versions published at least N days ago. Use 0 to disable."
def lock
require_relative "cli/lock"
Lock.new(options).run
Expand Down
3 changes: 3 additions & 0 deletions lib/bundler/cli/lock.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ def run

check_for_conflicting_options

Bundler::CLI::Common.validate_cooldown!(options[:cooldown])
Bundler.settings.set_command_option_if_given :cooldown, options[:cooldown]

print = options[:print]
previous_output_stream = Bundler.ui.output_stream
Bundler.ui.output_stream = :stderr if print
Expand Down
3 changes: 3 additions & 0 deletions lib/bundler/man/bundle-cache.1
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ Include gems for all platforms present in the lockfile, not only the current one
\fB\-\-cache\-path=CACHE\-PATH\fR
Specify a different cache path than the default (vendor/cache)\.
.TP
\fB\-\-cooldown=<number>\fR
Only consider gem versions published at least \fInumber\fR days ago when resolving before caching\. Pass \fB0\fR to disable cooldown for this run, overriding any per\-source or global configuration\. See \fBcooldown\fR in bundle\-config(1)\.
.TP
\fB\-\-gemfile=GEMFILE\fR
Use the specified gemfile instead of Gemfile\.
.TP
Expand Down
6 changes: 6 additions & 0 deletions lib/bundler/man/bundle-cache.1.ronn
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ use the gems in the cache in preference to the ones on `rubygems.org`.
* `--cache-path=CACHE-PATH`:
Specify a different cache path than the default (vendor/cache).

* `--cooldown=<number>`:
Only consider gem versions published at least <number> days ago when
resolving before caching. Pass `0` to disable cooldown for this run,
overriding any per-source or global configuration. See `cooldown` in
bundle-config(1).

* `--gemfile=GEMFILE`:
Use the specified gemfile instead of Gemfile.

Expand Down
5 changes: 4 additions & 1 deletion lib/bundler/man/bundle-lock.1
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
.SH "NAME"
\fBbundle\-lock\fR \- Creates / Updates a lockfile without installing
.SH "SYNOPSIS"
\fBbundle lock\fR [\-\-update] [\-\-bundler[=BUNDLER]] [\-\-local] [\-\-print] [\-\-lockfile=PATH] [\-\-full\-index] [\-\-gemfile=GEMFILE] [\-\-add\-checksums] [\-\-add\-platform] [\-\-remove\-platform] [\-\-normalize\-platforms] [\-\-patch] [\-\-minor] [\-\-major] [\-\-pre] [\-\-strict] [\-\-conservative]
\fBbundle lock\fR [\-\-update] [\-\-bundler[=BUNDLER]] [\-\-local] [\-\-print] [\-\-lockfile=PATH] [\-\-full\-index] [\-\-gemfile=GEMFILE] [\-\-add\-checksums] [\-\-add\-platform] [\-\-remove\-platform] [\-\-normalize\-platforms] [\-\-patch] [\-\-minor] [\-\-major] [\-\-pre] [\-\-strict] [\-\-conservative] [\-\-cooldown=NUMBER]
.SH "DESCRIPTION"
Lock the gems specified in Gemfile\.
.SH "OPTIONS"
Expand Down Expand Up @@ -59,6 +59,9 @@ If updating, do not allow any gem to be updated past latest \-\-patch | \-\-mino
.TP
\fB\-\-conservative\fR
If updating, use bundle install conservative update behavior and do not allow shared dependencies to be updated\.
.TP
\fB\-\-cooldown=<number>\fR
Only consider gem versions published at least \fInumber\fR days ago when resolving\. Pass \fB0\fR to disable cooldown for this run, overriding any per\-source or global configuration\. See \fBcooldown\fR in bundle\-config(1)\.
.SH "UPDATING ALL GEMS"
If you run \fBbundle lock\fR with \fB\-\-update\fR option without list of gems, bundler will ignore any previously installed gems and resolve all dependencies again based on the latest versions of all gems available in the sources\.
.SH "UPDATING A LIST OF GEMS"
Expand Down
6 changes: 6 additions & 0 deletions lib/bundler/man/bundle-lock.1.ronn
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ bundle-lock(1) -- Creates / Updates a lockfile without installing
[--pre]
[--strict]
[--conservative]
[--cooldown=NUMBER]

## DESCRIPTION

Expand Down Expand Up @@ -84,6 +85,11 @@ Lock the gems specified in Gemfile.
* `--conservative`:
If updating, use bundle install conservative update behavior and do not allow shared dependencies to be updated.

* `--cooldown=<number>`:
Only consider gem versions published at least <number> days ago when
resolving. Pass `0` to disable cooldown for this run, overriding any
per-source or global configuration. See `cooldown` in bundle-config(1).

## UPDATING ALL GEMS

If you run `bundle lock` with `--update` option without list of gems, bundler will
Expand Down
92 changes: 92 additions & 0 deletions spec/install/cooldown_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,19 @@
build_gem "fresh_gem", "0.3.2" do |s|
s.date = now - (1 * 86_400)
end

# the generic build is outside the window, but a platform-specific
# build of the same version was pushed inside it
build_gem "late_platform", "1.0.0" do |s|
s.date = now - (30 * 86_400)
end
build_gem "late_platform", "2.0.0" do |s|
s.date = now - (30 * 86_400)
end
build_gem "late_platform", "2.0.0" do |s|
s.platform = "x86_64-linux"
s.date = now - (1 * 86_400)
end
end
end

Expand Down Expand Up @@ -712,6 +725,85 @@
expect(lockfile).not_to include("ripe_gem (2.0.0)")
end

it "excludes a version on every platform when a platform-specific build of it is inside the window" do
# Exclusion is keyed on [name, version] and deliberately ignores
# platform: otherwise pushing a fresh platform-specific build under an
# already-ripe version number would slip new code past the cooldown.
gemfile <<-G
source "https://gem.repo3"
gem "late_platform"
G

bundle "install --cooldown 7", artifice: "compact_index_cooldown"

expect(the_bundle).to include_gems("late_platform 1.0.0")
end

it "selects the version with a late platform-specific build when --cooldown 0 bypasses the filter" do
gemfile <<-G
source "https://gem.repo3"
gem "late_platform"
G

bundle "install --cooldown 0", artifice: "compact_index_cooldown"

# On x86_64-linux hosts this resolves to the platform-specific build, so
# assert on the lockfile instead of the installed platform.
expect(lockfile).to include("late_platform (2.0.0")
expect(lockfile).not_to include("late_platform (1.0.0)")
end

it "applies CLI --cooldown on bundle lock --update" do
gemfile <<-G
source "https://gem.repo3"
gem "ripe_gem"
G

lockfile <<-L
GEM
remote: https://gem.repo3/
specs:
ripe_gem (1.0.0)

PLATFORMS
#{lockfile_platforms}

DEPENDENCIES
ripe_gem

BUNDLED WITH
#{Bundler::VERSION}
L

bundle "lock --update --cooldown 7", artifice: "compact_index_cooldown"

expect(lockfile).to include("ripe_gem (1.0.0)")
expect(lockfile).not_to include("ripe_gem (2.0.0)")
end

it "rejects a negative --cooldown value on bundle lock" do
gemfile <<-G
source "https://gem.repo3"
gem "ripe_gem"
G

bundle "lock --cooldown=-7", artifice: "compact_index_cooldown", raise_on_error: false

expect(err).to match(/non-negative integer/)
end

it "applies CLI --cooldown on bundle cache" do
gemfile <<-G
source "https://gem.repo3"
gem "ripe_gem"
G

bundle "cache --cooldown 7", artifice: "compact_index_cooldown"

expect(the_bundle).to include_gems("ripe_gem 1.0.0")
expect(bundled_app("vendor/cache/ripe_gem-1.0.0.gem")).to exist
end

it "ignores cooldown and installs the locked version when frozen" do
# Frozen installs read the lockfile instead of resolving, so cooldown has
# no say. A version already locked inside the window must still install.
Expand Down