bundler-patch 0.9.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 96da032d4f30feda0e83bb1869df9e962846bd7c
4
- data.tar.gz: 8b73a7082fa6190b406d6204666118717d2328ac
3
+ metadata.gz: db13e486dca6bfc05d93f62cf35c04e8635ba49d
4
+ data.tar.gz: 9bc70139fc23c0411919e2c14405ee508ca10527
5
5
  SHA512:
6
- metadata.gz: 3d0fd0304763dbec00ce7cb8ea9bb60103733527627d470f00526bc2868c4f154cc6ac185dcbc59f198a1f579c3c9a1ea33616c374fceaeec5aa070460b85a53
7
- data.tar.gz: ee72e66cea4c8c44b5e3392ca091fc858fbe7929f795a31210d3af92c3bdfd132351739bde6cdc39286c215c4d3e07020fbc9a261ca79136a644cd12e81e3b7f
6
+ metadata.gz: b48d69a664d17906a3f38b2c1b235124e0c52e015e71afec2030a7a5cc88d9171737f33a34244655456aea0798abe95812dc75422b984739a1e1827dae454024
7
+ data.tar.gz: 848c2620c837d61da57080be7d5a982c068af6c82c35685eb8edd43243dfee1e917ec6941315497285d2e6aa6b95eeeae9835c7e8d33ce745b0cd744b675cf74
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.2.4
1
+ 2.3.1
data/.travis.yml CHANGED
@@ -5,12 +5,16 @@ before_install:
5
5
  - gem install bundler -v $BUNDLER_TEST_VERSION
6
6
  - bundle --version
7
7
 
8
+ script: bundle exec rake test:all
9
+
8
10
  matrix:
9
11
  include:
10
12
  - rvm: 2.1.10
11
13
  env: BUNDLER_TEST_VERSION=1.12.5
12
14
  - rvm: 2.2.5
13
15
  env: BUNDLER_TEST_VERSION=1.12.5
16
+ - rvm: 2.3.1
17
+ env: BUNDLER_TEST_VERSION=1.9.10
14
18
  - rvm: 2.3.1
15
19
  env: BUNDLER_TEST_VERSION=1.10.5
16
20
  - rvm: 2.3.1
@@ -18,4 +22,4 @@ matrix:
18
22
  - rvm: 2.3.1
19
23
  env: BUNDLER_TEST_VERSION=1.12.5
20
24
  - rvm: 2.3.1
21
- env: BUNDLER_TEST_VERSION=1.13.0.rc.1
25
+ env: BUNDLER_TEST_VERSION=1.13.0.rc.2
data/BUNDLER.md ADDED
@@ -0,0 +1,154 @@
1
+ # Conservative Bundle Updates
2
+
3
+ Starting with 1.13.0.rc.2, a subset of bundler-patch behavior was ported to Bundler itself.
4
+ The plan is to leave it undocumented and unsupported in 1.13 to give it a chance to
5
+ be used and flush out bugs and iron out some design decisions.
6
+
7
+ Part of that work before 1.14 (or maybe a later version) will be to properly document
8
+ `bundle update` as well as the [Conservative Updating](http://bundler.io/v1.12/man/bundle-install.1.html#CONSERVATIVE-UPDATING)
9
+ section of `bundle install`, but right now we need a placeholder document showing the new
10
+ stuff so folks know how to use it.
11
+
12
+ This is largely copy/pasta of the bundler-patch [README](README.md).
13
+
14
+ ## Usage
15
+
16
+ The default `bundle update` behavior remains untouched. Use of the new `--patch`
17
+ or `--minor` options will invoke the new conservative update behavior.
18
+
19
+ "Conservative" means it will sort all available versions to prefer the
20
+ latest releases from the current version, then the latest minor releases and
21
+ then the latest major releases.
22
+
23
+ "Prefer" means that no available versions are removed from consideration, to
24
+ help ensure a suitable dependency graph can be reconciled. This does mean some
25
+ gems cannot be upgraded or may be upgraded to unexpected versions. NOTE: There is
26
+ a `--strict` option which _will_ remove versions from consideration, see below.
27
+
28
+ Gem requirements as defined in the Gemfile will still define what versions are available.
29
+ The new conservative behavior controls the preference order of those versions.
30
+
31
+ For example, if gem 'foo' is locked at 1.0.2, with no gem requirement defined
32
+ in the Gemfile, and versions 1.0.3, 1.0.4, 1.1.0, 1.1.1, 2.0.0 all exist, the
33
+ default order of preference will be "1.0.4, 1.0.3, 1.0.2, 1.1.1, 1.1.0,
34
+ 2.0.0".
35
+
36
+ In the same example, if gem 'foo' has a requirement of '~> 1.0', version 2.0.0
37
+ will be removed from consideration as always.
38
+
39
+ With no gem names provided on the command line, all gems will be unlocked and
40
+ open for updating.
41
+
42
+ $ bundle update --patch
43
+
44
+ A list of gem names can be passed to restrict to just those gems.
45
+
46
+ $ bundle update --patch foo bar
47
+
48
+ * `--patch` option will give preference for release/patch versions, then minor,
49
+ then major.
50
+
51
+ * `--minor` option will give preference for minor versions over
52
+ release versions, then major versions.
53
+
54
+ * `--major` option will give preference for major versions over
55
+ minor or release versions. This is the default behavior currently, so this
56
+ flag is cosmetic for now. Bundler 2.0 will likely make `--patch` the default
57
+ behavior.
58
+
59
+ * `--strict` option will actually remove from consideration
60
+ versions outside either the current release (or minor version if `--minor`
61
+ specified). This increases the chances of Bundler being unable to
62
+ reconcile the dependency graph and in some cases could even raise a
63
+ `VersionConflict`.
64
+
65
+ ## Examples
66
+
67
+ ### Single Gem
68
+
69
+ | Requirements| Locked | Available | Option | Result |
70
+ |-------------|---------|----------------------------------|----------|--------|
71
+ | foo | 1.4.3 | 1.4.4, 1.4.5, 1.5.0, 1.5.1 1.6.0 | --patch | 1.4.5 |
72
+ | foo | 1.4.3 | 1.4.4, 1.4.5, 1.5.0, 1.5.1 1.6.0 | --minor | 1.5.1 |
73
+ | foo | 1.4.3 | 1.4.4, 1.4.5, 1.5.0, 1.5.1 1.6.0 | --major | 1.6.0 |
74
+
75
+ ### Two Gems
76
+
77
+ Given the following gem specifications:
78
+
79
+ - foo 1.4.3, requires: ~> bar 2.0
80
+ - foo 1.4.4, requires: ~> bar 2.0
81
+ - foo 1.4.5, requires: ~> bar 2.1
82
+ - foo 1.5.0, requires: ~> bar 2.1
83
+ - foo 1.5.1, requires: ~> bar 3.0
84
+ - bar with versions 2.0.3, 2.0.4, 2.1.0, 2.1.1, 3.0.0
85
+
86
+ Gemfile:
87
+
88
+ gem 'foo'
89
+
90
+ Gemfile.lock:
91
+
92
+ foo (1.4.3)
93
+ bar (~> 2.0)
94
+ bar (2.0.3)
95
+
96
+ | # | Command Line | Result |
97
+ |---|--------------------------------|---------------------------|
98
+ | 1 | bundle update --patch | 'foo 1.4.5', 'bar 2.1.1' |
99
+ | 2 | bundle update --patch foo | 'foo 1.4.4', 'bar 2.0.3' |
100
+ | 3 | bundle update --minor | 'foo 1.5.1', 'bar 3.0.0' |
101
+ | 4 | bundle update --minor --strict | 'foo 1.5.0', 'bar 2.1.1' |
102
+ | 5 | bundle update --patch --strict | 'foo 1.4.4', 'bar 2.0.4' |
103
+
104
+ In case 1, `bar` is upgraded to 2.1.1, a minor version increase, because the
105
+ dependency from `foo` 1.4.5 required it.
106
+
107
+ In case 2, only `foo` is unlocked, so `foo` can only go to 1.4.4 to maintain
108
+ the dependency to `bar`.
109
+
110
+ In case 3, `bar` goes up a whole major release, because a minor increase is
111
+ preferred now for `foo`, and when it goes to 1.5.1, it requires 3.0.0 of
112
+ `bar`.
113
+
114
+ In case 4, `foo` is preferred up to a 1.5.x, but 1.5.1 won't work because the
115
+ `--strict` flag removes `bar` 3.0.0 from consideration since it's a major
116
+ increment.
117
+
118
+ In case 5, both `foo` and `bar` have any minor or major increments removed
119
+ from consideration because of the `--strict` flag, so the most they can
120
+ move is up to 1.4.4 and 2.0.4.
121
+
122
+
123
+ ### Troubleshooting
124
+
125
+ First, make sure the current `bundle` command itself runs to completion on its
126
+ own without any problems.
127
+
128
+ The most frequent problems with this tool involve expectations around what
129
+ gems should or shouldn't be upgraded. This can quickly get complicated as even
130
+ a small dependency tree can involve many moving parts, and Bundler works hard
131
+ to find a combination that satisfies all of the dependencies and requirements.
132
+
133
+ NOTE: the requirements in the Gemfile trump anything else. The most control
134
+ you have is by modifying those in the Gemfile, in some circumstances it may be
135
+ better to pin your versions to what you need instead of trying to diagnose why
136
+ Bundler isn't calculating the versions you expect with a broader requirement.
137
+ If there is an incompatibility, pinning to desired versions can also aide in
138
+ debugging dependency conflicts.
139
+
140
+ You can get a (very verbose) look into how Bundler's resolution algorithm is
141
+ working by setting the `DEBUG_RESOLVER` environment variable. While it can be
142
+ tricky to dig through, it should explain how it came to the conclusions it
143
+ came to.
144
+
145
+ In particular, grep for 'Unwinding for conflict' in the debug output to
146
+ isolate some key issues that may be preventing the outcome you expect.
147
+
148
+ To get additional Bundler debugging output, enable the `DEBUG` env variable.
149
+ This will include all of the details of the downloading the full dependency
150
+ data from remote sources.
151
+
152
+ At the end of all of this though, again, the requirements in the Gemfile
153
+ trump anything else, and the most control you have is by modifying those
154
+ in the Gemfile.
data/README.md CHANGED
@@ -8,7 +8,9 @@ current version, over the latest minor releases or the latest major releases.
8
8
  This is somewhat opposite from `bundle update` which prefers newest/major
9
9
  versions first.
10
10
 
11
- Works with Bundler 1.10.x and higher.
11
+ Works with Bundler 1.9 and higher. Starting with Bundler 1.13, much of the
12
+ core behavior in `bundler-patch` has been ported to Bundler itself. Read
13
+ [BUNDLER.md](BUNDLER.md) for more information.
12
14
 
13
15
  [![Build Status](https://travis-ci.org/livingsocial/bundler-patch.svg?branch=master)](https://travis-ci.org/livingsocial/bundler-patch)
14
16
 
@@ -32,17 +34,10 @@ made.
32
34
  latest releases from the current version, then the latest minor releases and
33
35
  then the latest major releases.
34
36
 
35
- Gem requirements as defined in the Gemfile will restrict the available version
36
- options.
37
-
38
- For example, if gem 'foo' is locked at 1.0.2, with no gem requirement defined
39
- in the Gemfile, and versions 1.0.3, 1.0.4, 1.1.0, 1.1.1, 2.0.0 all exist, the
40
- default order of preference will be "1.0.4, 1.0.3, 1.0.2, 1.1.1, 1.1.0,
41
- 2.0.0".
42
-
43
37
  "Prefer" means that no available versions are removed from consideration*, to
44
38
  help ensure a suitable dependency graph can be reconciled. This does mean some
45
- gems cannot be upgraded or will be upgraded to unexpected versions.
39
+ gems cannot be upgraded or may be upgraded to unexpected versions. NOTE: There is
40
+ a `--strict_updates` option which _will_ remove versions from consideration, see below.
46
41
 
47
42
  _*That's a white-lie. bundler-patch will actually remove from consideration
48
43
  any versions older than the currently locked version, which `bundle update`
@@ -50,6 +45,17 @@ will not do. It's not common, but it is possible for `bundle update` to
50
45
  regress a gem to an older version, if necessary to reconcile the dependency
51
46
  graph._
52
47
 
48
+ Gem requirements as defined in the Gemfile will still define what versions are available.
49
+ The new conservative behavior controls the preference order of those versions.
50
+
51
+ For example, if gem 'foo' is locked at 1.0.2, with no gem requirement defined
52
+ in the Gemfile, and versions 1.0.3, 1.0.4, 1.1.0, 1.1.1, 2.0.0 all exist, the
53
+ default order of preference will be "1.0.4, 1.0.3, 1.0.2, 1.1.1, 1.1.0,
54
+ 2.0.0".
55
+
56
+ In the same example, if gem 'foo' has a requirement of '~> 1.0', version 2.0.0
57
+ will be removed from consideration as always.
58
+
53
59
  With no gem names provided on the command line, all gems will be unlocked and
54
60
  open for updating. A list of gem names can be passed to restrict to just those
55
61
  gems.
@@ -84,7 +90,7 @@ in the Gemfile on vulnerable gems to ensure they can be upgraded.
84
90
  The rules for updating vulnerable gems are almost identical to the general
85
91
  `bundler-patch` behavior described above, and abide by the same options (`-m`,
86
92
  `-p`, and `-s`) though there are some tweaks to encourage getting to at least
87
- a patched version of the gem. Keep in mind Bundler may choose unexpected
93
+ a patched version of the gem. Keep in mind Bundler may still choose unexpected
88
94
  versions in order to satisfy the dependency graph.
89
95
 
90
96
  * `-v/--vulnerable_gems_only` option will automatically restrict the gems
@@ -170,29 +176,40 @@ gems should or shouldn't be upgraded. This can quickly get complicated as even
170
176
  a small dependency tree can involve many moving parts, and Bundler works hard
171
177
  to find a combination that satisfies all of the dependencies and requirements.
172
178
 
179
+ NOTE: the requirements in the Gemfile trump anything else. The most control
180
+ you have is by modifying those in the Gemfile, in some circumstances it may be
181
+ better to pin your versions to what you need instead of trying to diagnose why
182
+ Bundler isn't calculating the versions you expect with a broader requirement.
183
+ If there is an incompatibility, pinning to desired versions can also aide in
184
+ debugging dependency conflicts.
185
+
173
186
  You can get a (very verbose) look into how Bundler's resolution algorithm is
174
187
  working by setting the `DEBUG_RESOLVER` environment variable. While it can be
175
188
  tricky to dig through, it should explain how it came to the conclusions it
176
189
  came to.
177
190
 
191
+ In particular, grep for 'Unwinding for conflict' in the debug output to
192
+ isolate some key issues that may be preventing the outcome you expect.
193
+
178
194
  Adding to the usual Bundler complexity, `bundler-patch` is injecting its own
179
195
  logic to the resolution process to achieve its goals. If there's a bug
180
196
  involved, it's almost certainly in the `bundler-patch` code as Bundler has
181
197
  been around a long time and has thorough testing and real world experience.
182
198
 
183
- In particular, grep for 'Unwinding for conflict' in the debug output to
184
- isolate some key issues that may be preventing the outcome you expect.
199
+ When used with versions of Bundler prior to 1.13, `bundler-patch` can dump
200
+ its own debug output, potentially helpful, with `DEBUG_PATCH_RESOLVER`.
185
201
 
186
- `bundler-patch` can dump its own debug output, potentially helpful, with
187
- `DEBUG_PATCH_RESOLVER`.
202
+ (When used with version 1.13+ of Bundler, `bundler-patch` only adds some
203
+ additional sorting behavior, the result of which will be included in the
204
+ `DEBUG_RESOLVER` output and `DEBUG_PATCH_RESOLVER` is not used).
188
205
 
189
206
  To get additional Bundler debugging output, enable the `DEBUG` env variable.
190
207
  This will include all of the details of the downloading the full dependency
191
208
  data from remote sources.
192
209
 
193
- At the end of all of this though, the requirements in the Gemfile trump
194
- anything else, and the most control you have is by modifying those in the
195
- Gemfile.
210
+ At the end of all of this though, again, the requirements in the Gemfile
211
+ trump anything else, and the most control you have is by modifying those
212
+ in the Gemfile.
196
213
 
197
214
 
198
215
  ## Development
@@ -19,12 +19,12 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = ['bundler-patch']
20
20
  spec.require_paths = ['lib']
21
21
 
22
- spec.add_dependency 'bundler-advise', '~> 1.0', '>= 1.0.3'
22
+ spec.add_dependency 'bundler-advise', '~> 1.1', '>= 1.1.2'
23
23
  spec.add_dependency 'slop', '~> 3.0'
24
- spec.add_dependency 'bundler', '~> 1.10'
24
+ spec.add_dependency 'bundler', '~> 1.7'
25
25
 
26
26
  spec.add_development_dependency 'bundler-fixture', '~> 1.3'
27
27
  spec.add_development_dependency 'pry'
28
28
  spec.add_development_dependency 'rake', '~> 10.0'
29
- spec.add_development_dependency 'rspec'
29
+ spec.add_development_dependency 'rspec', '~> 3.5'
30
30
  end
@@ -1,3 +1,5 @@
1
+ require 'bundler'
2
+ require 'bundler/vendor/thor/lib/thor'
1
3
  require 'bundler/advise'
2
4
  require 'slop'
3
5
 
@@ -16,26 +16,37 @@ module Bundler::Patch
16
16
  else
17
17
  # Run a resolve against the locally available gems
18
18
  base = last_resolve.is_a?(Bundler::SpecSet) ? Bundler::SpecSet.new(last_resolve) : []
19
- resolver = ConservativeResolver.new(index, source_requirements, base)
20
- locked_specs = if @unlocking && @locked_specs.length == 0
21
- # Have to grab these again. Default behavior is to not store any
22
- # locked_specs if updating all gems, because behavior is the same
23
- # with no lockfile OR lockfile but update them all. In our case,
24
- # we need to know the locked versions for conservative comparison.
25
- locked = Bundler::LockfileParser.new(@lockfile_contents)
26
- Bundler::SpecSet.new(locked.specs)
27
- else
28
- @locked_specs
29
- end
30
-
31
- resolver.gems_to_update = @gems_to_update
32
- resolver.locked_specs = locked_specs
33
- resolver.strict = @strict
34
- resolver.minor_preferred = @minor_preferred
35
- resolver.prefer_minimal = @prefer_minimal
19
+ if Gem::Version.new(Bundler::VERSION) >= Gem::Version.new('1.13.0.rc.2')
20
+ require 'bundler/patch/gem_version_patch_promoter'
21
+
22
+ gvpp = Bundler::Patch::GemVersionPatchPromoter.new(@gem_version_promoter.locked_specs, @gem_version_promoter.unlock_gems)
23
+ gvpp.level = @minor_preferred ? :minor : :patch
24
+ gvpp.strict = @strict
25
+ gvpp.minimal = @prefer_minimal
26
+ gvpp.gems_to_update = @gems_to_update
27
+ resolver = Bundler::Resolver.new(index, source_requirements, base, nil, gvpp, additional_base_requirements_for_resolve)
28
+ else
29
+ resolver = ConservativeResolver.new(index, source_requirements, base)
30
+ locked_specs = if @unlocking && @locked_specs.length == 0
31
+ # Have to grab these again. Default behavior is to not store any
32
+ # locked_specs if updating all gems, because behavior is the same
33
+ # with no lockfile OR lockfile but update them all. In our case,
34
+ # we need to know the locked versions for conservative comparison.
35
+ locked = Bundler::LockfileParser.new(@lockfile_contents)
36
+ Bundler::SpecSet.new(locked.specs)
37
+ else
38
+ @locked_specs
39
+ end
40
+
41
+ resolver.gems_to_update = @gems_to_update
42
+ resolver.locked_specs = locked_specs
43
+ resolver.strict = @strict
44
+ resolver.minor_preferred = @minor_preferred
45
+ resolver.prefer_minimal = @prefer_minimal
46
+ end
47
+
36
48
  result = resolver.start(expanded_dependencies)
37
49
  spec_set = Bundler::SpecSet.new(result)
38
-
39
50
  last_resolve.merge spec_set
40
51
  end
41
52
  end
@@ -3,11 +3,10 @@ module Bundler::Patch
3
3
  attr_accessor :locked_specs, :gems_to_update, :strict, :minor_preferred, :prefer_minimal
4
4
 
5
5
  def initialize(index, source_requirements, base)
6
- # hack for 1.10 and 1.11+ support
7
6
  case Bundler::Resolver.instance_method(:initialize).arity
8
- when 3
7
+ when 3 # 1.9 1.10
9
8
  super(index, source_requirements, base)
10
- when 4
9
+ when 4 # 1.11 1.12
11
10
  super(index, source_requirements, base, nil)
12
11
  end
13
12
  end
@@ -74,48 +73,81 @@ module Bundler::Patch
74
73
  # reminder: sort still filters anything older than locked version
75
74
  def sort_specs(specs, locked_spec)
76
75
  return specs unless locked_spec
77
- gem_name = locked_spec.name
78
- locked_version = locked_spec.version
76
+ @gem_name = locked_spec.name
77
+ @locked_version = locked_spec.version
79
78
 
80
- filtered = specs.select { |s| s.first.version >= locked_version }
79
+ filtered = specs.select { |s| s.first.version >= @locked_version }
81
80
 
82
- filtered.sort do |a, b|
83
- a_ver = a.first.version
84
- b_ver = b.first.version
85
- gem_patch = @gems_to_update.gem_patch_for(gem_name)
86
- new_version = gem_patch ? gem_patch.new_version : nil
81
+ @gem_patch = @gems_to_update.gem_patch_for(@gem_name)
82
+ @new_version = @gem_patch ? @gem_patch.new_version : nil
83
+
84
+ result = filtered.sort do |a, b|
85
+ @a_ver = a.first.version
86
+ @b_ver = b.first.version
87
87
  case
88
- when a_ver.segments[0] != b_ver.segments[0]
89
- b_ver <=> a_ver
90
- when !@minor_preferred && (a_ver.segments[1] != b_ver.segments[1])
91
- b_ver <=> a_ver
92
- when @prefer_minimal && !@gems_to_update.unlocking_gem?(gem_name)
93
- b_ver <=> a_ver
94
- when @prefer_minimal && @gems_to_update.unlocking_gem?(gem_name) &&
95
- (![a_ver, b_ver].include?(locked_version) &&
96
- (!new_version || (new_version && a_ver >= new_version && b_ver >= new_version)))
97
- b_ver <=> a_ver
98
- else
99
- a_ver <=> b_ver
100
- end
101
- end.tap do |result|
102
- if @gems_to_update.unlocking_gem?(gem_name)
103
- gem_patch = @gems_to_update.gem_patch_for(gem_name)
104
- if gem_patch && gem_patch.new_version && @prefer_minimal
105
- move_version_to_end(specs, gem_patch.new_version, result)
106
- end
88
+ when segments_do_not_match(:major)
89
+ @b_ver <=> @a_ver
90
+ when !@minor_preferred && segments_do_not_match(:minor)
91
+ @b_ver <=> @a_ver
92
+ when @prefer_minimal && !unlocking_gem?
93
+ @b_ver <=> @a_ver
94
+ when @prefer_minimal && unlocking_gem? &&
95
+ (neither_version_matches(@locked_version) &&
96
+ (!@new_version || both_versions_gt_or_equal_to_version(@new_version)))
97
+ @b_ver <=> @a_ver
107
98
  else
108
- move_version_to_end(specs, locked_version, result)
99
+ @a_ver <=> @b_ver
109
100
  end
110
101
  end
102
+ post_sort(result)
111
103
  end
112
104
 
113
- def move_version_to_end(specs, version, result)
114
- spec_group = specs.detect { |s| s.first.version.to_s == version.to_s }
115
- if spec_group
116
- result.reject! { |s| s.first.version.to_s === version.to_s }
117
- result << spec_group
105
+ def post_sort(result)
106
+ unless unlocking_gem?
107
+ result = move_version_to_end(result, @locked_version)
108
+ end
109
+
110
+ if @new_version && unlocking_gem? && segments_match(:major, @new_version, @locked_version)
111
+ if @prefer_minimal || (!@prefer_minimal && (result.last.first.version < @new_version))
112
+ result = move_version_to_end(result, @new_version)
113
+ end
118
114
  end
115
+
116
+ result
117
+ end
118
+
119
+ def unlocking_gem?
120
+ @gems_to_update.unlocking_gem?(@gem_name)
121
+ end
122
+
123
+ def either_version_older_than_locked(locked_version)
124
+ @a_ver < locked_version || @b_ver < locked_version
125
+ end
126
+
127
+ def segments_match(level, a_ver=@a_ver, b_ver=@b_ver)
128
+ !segments_do_not_match(level, a_ver, b_ver)
129
+ end
130
+
131
+ def segments_do_not_match(level, a_ver=@a_ver, b_ver=@b_ver)
132
+ index = [:major, :minor].index(level)
133
+ a_ver.segments[index] != b_ver.segments[index]
134
+ end
135
+
136
+ def neither_version_matches(match_version)
137
+ !one_version_matches(match_version)
138
+ end
139
+
140
+ def one_version_matches(match_version)
141
+ [@a_ver, @b_ver].include?(match_version)
142
+ end
143
+
144
+ def both_versions_gt_or_equal_to_version(version)
145
+ version && @a_ver >= version && @b_ver >= version
146
+ end
147
+
148
+ def move_version_to_end(result, version)
149
+ move, keep = result.partition { |s| s.first.version.to_s == version.to_s }
150
+ keep.concat(move)
119
151
  end
120
152
  end
121
153
  end
@@ -0,0 +1,75 @@
1
+ module Bundler::Patch
2
+ class GemVersionPatchPromoter < Bundler::GemVersionPromoter
3
+ attr_accessor :minimal, :gems_to_update
4
+
5
+ private
6
+
7
+ def sort_dep_specs(spec_groups, locked_spec)
8
+ result = super(spec_groups, locked_spec)
9
+ return result unless locked_spec
10
+
11
+ @gem_name = locked_spec.name
12
+ @locked_version = locked_spec.version
13
+ gem_patch = @gems_to_update.gem_patch_for(@gem_name)
14
+ @new_version = gem_patch ? gem_patch.new_version : nil
15
+
16
+ return result unless @minimal || @new_version
17
+
18
+ # STDERR.puts "during sort_versions: #{debug_format_result(spec_groups.first.first.name, result).inspect}" if ENV["DEBUG_RESOLVER"]
19
+
20
+ # Custom sort_by-ish behavior to minimize index calls.
21
+ result = result.map { |a| [result.index(a), a] }.sort do |(a_index, a), (b_index, b)|
22
+ @a_ver = a.version
23
+ @b_ver = b.version
24
+ case
25
+ when @minimal && unlocking_gem? &&
26
+ (neither_version_matches(@locked_version) &&
27
+ (!@new_version || both_versions_gt_or_equal_to_version(@new_version)))
28
+ @b_ver <=> @a_ver
29
+ else
30
+ a_index <=> b_index # no change in current ordering
31
+ end
32
+ end.map { |a| a.last }
33
+
34
+ post_sort(result)
35
+ end
36
+
37
+ def unlocking_gem?
38
+ @gems_to_update.unlocking_gem?(@gem_name)
39
+ end
40
+
41
+ def one_version_matches(match_version)
42
+ [@a_ver, @b_ver].include?(match_version)
43
+ end
44
+
45
+ def neither_version_matches(match_version)
46
+ !one_version_matches(match_version)
47
+ end
48
+
49
+ def both_versions_gt_or_equal_to_version(version)
50
+ version && @a_ver >= version && @b_ver >= version
51
+ end
52
+
53
+ # Sorting won't work properly for some specific arrangements to the end of the list because not
54
+ # all versions are compared in quicksort and the result isn't deterministic.
55
+ def post_sort(result)
56
+ result = super(result)
57
+
58
+ if @new_version && unlocking_gem? && segments_match(:major, @new_version, @locked_version)
59
+ if @minimal || (!@minimal && result.last.version < @new_version)
60
+ # This handles two cases:
61
+ # - minimal doesn't want to go past requested new_version
62
+ # - new_version is up a minor rev but level is :patch
63
+ result = move_version_to_end(result, @new_version)
64
+ end
65
+ end
66
+
67
+ result
68
+ end
69
+
70
+ def segments_match(level, a_ver, b_ver)
71
+ index = [:major, :minor].index(level)
72
+ a_ver.segments[index] == b_ver.segments[index]
73
+ end
74
+ end
75
+ end
@@ -78,7 +78,7 @@ module Bundler::Patch
78
78
 
79
79
  def requirements_args_regexp
80
80
  ops = Gem::Requirement::OPS.keys.join "|"
81
- re = /(\s*['\"]\s*(#{ops})?\s*#{Gem::Version::VERSION_PATTERN}\s*['"],*)+/
81
+ /(\s*['\"]\s*(#{ops})?\s*#{Gem::Version::VERSION_PATTERN}\s*['"],*)+/
82
82
  end
83
83
 
84
84
  # See Bundler::Dsl for reference
@@ -1,9 +1,12 @@
1
1
  module Bundler::Patch
2
2
  class RubyVersion < UpdateSpec
3
+ RUBY_VERSION_LINE_REGEXPS = [/ruby\s+["'](.*)['"]/]
4
+
3
5
  def self.files
4
6
  {
5
7
  '.ruby-version' => [/.*/],
6
- 'Gemfile' => [/ruby\s+["'](.*)['"]/]
8
+ 'Gemfile' => RUBY_VERSION_LINE_REGEXPS,
9
+ 'gems.rb' => RUBY_VERSION_LINE_REGEXPS,
7
10
  }
8
11
  end
9
12
 
@@ -71,15 +71,3 @@ module Bundler::Patch
71
71
  end
72
72
  end
73
73
  end
74
-
75
- # def prep_git_checkout(spec)
76
- # Dir.chdir(spec.target_dir) do
77
- # status_first_line = `git status`.split("\n").first
78
- # raise "Not on master: #{status_first_line}" unless status_first_line == '# On branch master'
79
- #
80
- # raise 'Uncommitted files' unless `git status --porcelain`.chomp.empty?
81
- #
82
- # verbose_puts `git pull`
83
- # end
84
- # end
85
-
@@ -1,5 +1,5 @@
1
1
  module Bundler
2
2
  module Patch
3
- VERSION = '0.9.0'
3
+ VERSION = '0.10.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bundler-patch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - chrismo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-02 00:00:00.000000000 Z
11
+ date: 2016-08-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler-advise
@@ -16,20 +16,20 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.0'
19
+ version: '1.1'
20
20
  - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: 1.0.3
22
+ version: 1.1.2
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - "~>"
28
28
  - !ruby/object:Gem::Version
29
- version: '1.0'
29
+ version: '1.1'
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
- version: 1.0.3
32
+ version: 1.1.2
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: slop
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -50,14 +50,14 @@ dependencies:
50
50
  requirements:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
- version: '1.10'
53
+ version: '1.7'
54
54
  type: :runtime
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
58
  - - "~>"
59
59
  - !ruby/object:Gem::Version
60
- version: '1.10'
60
+ version: '1.7'
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: bundler-fixture
63
63
  requirement: !ruby/object:Gem::Requirement
@@ -104,16 +104,16 @@ dependencies:
104
104
  name: rspec
105
105
  requirement: !ruby/object:Gem::Requirement
106
106
  requirements:
107
- - - ">="
107
+ - - "~>"
108
108
  - !ruby/object:Gem::Version
109
- version: '0'
109
+ version: '3.5'
110
110
  type: :development
111
111
  prerelease: false
112
112
  version_requirements: !ruby/object:Gem::Requirement
113
113
  requirements:
114
- - - ">="
114
+ - - "~>"
115
115
  - !ruby/object:Gem::Version
116
- version: '0'
116
+ version: '3.5'
117
117
  description:
118
118
  email:
119
119
  - chrismo@clabs.org
@@ -126,6 +126,7 @@ files:
126
126
  - ".rspec"
127
127
  - ".ruby-version"
128
128
  - ".travis.yml"
129
+ - BUNDLER.md
129
130
  - Gemfile
130
131
  - LICENSE.txt
131
132
  - README.md
@@ -139,6 +140,7 @@ files:
139
140
  - lib/bundler/patch/cli.rb
140
141
  - lib/bundler/patch/conservative_definition.rb
141
142
  - lib/bundler/patch/conservative_resolver.rb
143
+ - lib/bundler/patch/gem_version_patch_promoter.rb
142
144
  - lib/bundler/patch/gemfile.rb
143
145
  - lib/bundler/patch/gems_to_patch_reconciler.rb
144
146
  - lib/bundler/patch/ruby_version.rb
@@ -164,7 +166,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
164
166
  version: '0'
165
167
  requirements: []
166
168
  rubyforge_project:
167
- rubygems_version: 2.4.5.1
169
+ rubygems_version: 2.6.4
168
170
  signing_key:
169
171
  specification_version: 4
170
172
  summary: Conservative bundler updates