bundle_update_interactive 0.7.0 → 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +30 -0
- data/lib/bundle_update_interactive/bundler_commands.rb +7 -0
- data/lib/bundle_update_interactive/changelog_locator.rb +2 -1
- data/lib/bundle_update_interactive/cli/multi_select.rb +3 -1
- data/lib/bundle_update_interactive/cli/options.rb +12 -0
- data/lib/bundle_update_interactive/cli.rb +17 -14
- data/lib/bundle_update_interactive/latest/gem_requirement.rb +62 -0
- data/lib/bundle_update_interactive/latest/gemfile_editor.rb +68 -0
- data/lib/bundle_update_interactive/latest/updater.rb +41 -0
- data/lib/bundle_update_interactive/outdated_gem.rb +6 -2
- data/lib/bundle_update_interactive/report.rb +2 -11
- data/lib/bundle_update_interactive/string_helper.rb +12 -0
- data/lib/bundle_update_interactive/{reporter.rb → updater.rb} +28 -13
- data/lib/bundle_update_interactive/version.rb +1 -1
- data/lib/bundle_update_interactive.rb +6 -14
- metadata +22 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '092dad2541b41d82be0c6d26b8dc6a4b72c9555fcef8743919849f8b57b67a24'
|
4
|
+
data.tar.gz: b73e37e2d76480af7fbbbc22a2d8957f5a364bdacdefd2c9122830895c9de929
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e4dcf48f02f99ee78f8a08e23d0168846c344f0ff7d6c6d5c29c34c6cbf690e16ad2465a299bbf9a2dd8a349f8960737a14ba3d96fbc66864a857ddfabb0736d
|
7
|
+
data.tar.gz: 9789ed423ff5c6a30d2410e873af33126268825dd3571252d087149ab28154d55de04f5027ceb2fcc3ade3bdc04d6f877b55a7e0084ed4d73edc4dac50a2d12e
|
data/README.md
CHANGED
@@ -12,6 +12,7 @@
|
|
12
12
|
---
|
13
13
|
|
14
14
|
- [Quick start](#quick-start)
|
15
|
+
- [Options](#options)
|
15
16
|
- [Features](#features)
|
16
17
|
- [Prior art](#prior-art)
|
17
18
|
- [Support](#support)
|
@@ -39,6 +40,11 @@ Or the shorthand:
|
|
39
40
|
bundle ui
|
40
41
|
```
|
41
42
|
|
43
|
+
## Options
|
44
|
+
|
45
|
+
- `--latest` [modifies the Gemfile if necessary to allow the latest gem versions](#allow-latest-versions)
|
46
|
+
- `-D` / `--exclusively=GROUP` [limits updatable gems by Gemfile groups](#limit-impact-by-gemfile-groups)
|
47
|
+
|
42
48
|
## Features
|
43
49
|
|
44
50
|
### Semver highlighting
|
@@ -69,6 +75,30 @@ When a newer version of a gem is available, but updating is not allowed due to a
|
|
69
75
|
|
70
76
|
<img src="images/held-back.png" alt="Screenshot of rails and selenium-webdriver gems held back due to Gemfile requirements" width="717" />
|
71
77
|
|
78
|
+
To allow updates for gems that would normally be held back, use the `--latest` option (explained in the next section).
|
79
|
+
|
80
|
+
### Allow latest versions
|
81
|
+
|
82
|
+
Normally `update-interactive` only makes changes to your Gemfile.lock. It honors the version restrictions ("pins") in your Gemfile and will not update your Gemfile.lock to have versions that are not allowed. However with the `--latest` flag, update-interactive can update the version pins in your Gemfile as well. Consider the following Gemfile:
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
gem "rails", "~> 7.1.0"
|
86
|
+
```
|
87
|
+
|
88
|
+
Normally running `bundle update-interactive` will report that Rails is held back and therefore cannot be updated to the latest version. However, if you pass the `--latest` option like this:
|
89
|
+
|
90
|
+
```
|
91
|
+
bundle update-interactive --latest
|
92
|
+
```
|
93
|
+
|
94
|
+
Now Rails will be allowed to update. If you select to update Rails to the latest version (e.g. 7.2.0), `update-interactive` will modify the version requirement in your Gemfile to look like this:
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
gem "rails", "~> 7.2.0"
|
98
|
+
```
|
99
|
+
|
100
|
+
In other words, it works similarly to `yarn upgrade-interactive --latest`.
|
101
|
+
|
72
102
|
### Changelogs
|
73
103
|
|
74
104
|
`bundle update-interactive` will do its best to find an appropriate changelog for each gem.
|
@@ -10,6 +10,13 @@ module BundleUpdateInteractive
|
|
10
10
|
system "#{bundle_bin.shellescape} update --conservative #{gems.flatten.map(&:shellescape).join(' ')}"
|
11
11
|
end
|
12
12
|
|
13
|
+
def lock
|
14
|
+
success = system "#{bundle_bin.shellescape} lock"
|
15
|
+
raise "bundle lock command failed" unless success
|
16
|
+
|
17
|
+
true
|
18
|
+
end
|
19
|
+
|
13
20
|
def read_updated_lockfile(*gems)
|
14
21
|
command = ["#{bundle_bin.shellescape} lock --print"]
|
15
22
|
command << "--conservative" if gems.any?
|
@@ -31,7 +31,8 @@ module BundleUpdateInteractive
|
|
31
31
|
return "https://github.com/#{changelog_path}" if changelog_path
|
32
32
|
|
33
33
|
releases_url = "https://github.com/#{path}/releases"
|
34
|
-
|
34
|
+
response = HTTP.get(releases_url)
|
35
|
+
releases_url if response.success? && response.body.include?("v#{version}")
|
35
36
|
end
|
36
37
|
|
37
38
|
private
|
@@ -7,6 +7,8 @@ require "tty/screen"
|
|
7
7
|
|
8
8
|
class BundleUpdateInteractive::CLI
|
9
9
|
class MultiSelect
|
10
|
+
extend BundleUpdateInteractive::StringHelper
|
11
|
+
|
10
12
|
class List < TTY::Prompt::MultiList
|
11
13
|
def initialize(prompt, **options)
|
12
14
|
@opener = options.delete(:opener)
|
@@ -47,7 +49,7 @@ class BundleUpdateInteractive::CLI
|
|
47
49
|
|
48
50
|
def self.prompt_for_gems_to_update(outdated_gems, prompt: nil)
|
49
51
|
table = Table.updatable(outdated_gems)
|
50
|
-
title = "#{outdated_gems.length}
|
52
|
+
title = "#{pluralize(outdated_gems.length, 'gem')} can be updated."
|
51
53
|
opener = lambda do |gem|
|
52
54
|
url = outdated_gems[gem].changelog_uri
|
53
55
|
Launchy.open(url) unless url.nil?
|
@@ -48,6 +48,9 @@ module BundleUpdateInteractive
|
|
48
48
|
Show updates for development and test gems only, leaving production gems untouched.
|
49
49
|
#{pastel.green('bundle update-interactive')} #{pastel.yellow('-D')}
|
50
50
|
|
51
|
+
Allow the latest gem versions, ignoring Gemfile pins. May modify the Gemfile.
|
52
|
+
#{pastel.green('bundle update-interactive')} #{pastel.yellow('--latest')}
|
53
|
+
|
51
54
|
HELP
|
52
55
|
end
|
53
56
|
|
@@ -61,6 +64,9 @@ module BundleUpdateInteractive
|
|
61
64
|
OptionParser.new do |parser|
|
62
65
|
parser.summary_indent = " "
|
63
66
|
parser.summary_width = 24
|
67
|
+
parser.on("--latest", "Modify the Gemfile to allow the latest gem versions") do
|
68
|
+
options.latest = true
|
69
|
+
end
|
64
70
|
parser.on(
|
65
71
|
"--exclusively=GROUP",
|
66
72
|
"Update gems exclusively belonging to the specified Gemfile GROUP(s)"
|
@@ -84,9 +90,15 @@ module BundleUpdateInteractive
|
|
84
90
|
end
|
85
91
|
|
86
92
|
attr_accessor :exclusively
|
93
|
+
attr_writer :latest
|
87
94
|
|
88
95
|
def initialize
|
89
96
|
@exclusively = []
|
97
|
+
@latest = false
|
98
|
+
end
|
99
|
+
|
100
|
+
def latest?
|
101
|
+
@latest
|
90
102
|
end
|
91
103
|
end
|
92
104
|
end
|
@@ -4,14 +4,9 @@ require "bundler"
|
|
4
4
|
|
5
5
|
module BundleUpdateInteractive
|
6
6
|
class CLI
|
7
|
-
autoload :MultiSelect, "bundle_update_interactive/cli/multi_select"
|
8
|
-
autoload :Options, "bundle_update_interactive/cli/options"
|
9
|
-
autoload :Row, "bundle_update_interactive/cli/row"
|
10
|
-
autoload :Table, "bundle_update_interactive/cli/table"
|
11
|
-
|
12
7
|
def run(argv: ARGV) # rubocop:disable Metrics/AbcSize
|
13
8
|
options = Options.parse(argv)
|
14
|
-
report = generate_report(options)
|
9
|
+
report, updater = generate_report(options)
|
15
10
|
|
16
11
|
puts_legend_and_withheld_gems(report) unless report.empty?
|
17
12
|
puts("No gems to update.").then { return } if report.updatable_gems.empty?
|
@@ -22,13 +17,18 @@ module BundleUpdateInteractive
|
|
22
17
|
puts "Updating the following gems."
|
23
18
|
puts Table.updatable(selected_gems).render
|
24
19
|
puts
|
25
|
-
|
20
|
+
updater.apply_updates(*selected_gems.keys)
|
21
|
+
puts_gemfile_modified_notice if updater.modified_gemfile?
|
26
22
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
27
23
|
handle_exception(e)
|
28
24
|
end
|
29
25
|
|
30
26
|
private
|
31
27
|
|
28
|
+
def puts_gemfile_modified_notice
|
29
|
+
puts BundleUpdateInteractive.pastel.yellow("Your Gemfile was changed to accommodate the latest gem versions.")
|
30
|
+
end
|
31
|
+
|
32
32
|
def puts_legend_and_withheld_gems(report)
|
33
33
|
puts
|
34
34
|
puts legend
|
@@ -54,14 +54,17 @@ module BundleUpdateInteractive
|
|
54
54
|
|
55
55
|
def generate_report(options)
|
56
56
|
whisper "Resolving latest gem versions..."
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
report.
|
57
|
+
updater_class = options.latest? ? Latest::Updater : Updater
|
58
|
+
updater = updater_class.new(groups: options.exclusively)
|
59
|
+
|
60
|
+
report = updater.generate_report
|
61
|
+
unless report.empty?
|
62
|
+
whisper "Checking for security vulnerabilities..."
|
63
|
+
report.scan_for_vulnerabilities!
|
64
|
+
progress "Finding changelogs", report.all_gems.values, &:changelog_uri
|
65
|
+
end
|
62
66
|
|
63
|
-
|
64
|
-
report
|
67
|
+
[report, updater]
|
65
68
|
end
|
66
69
|
|
67
70
|
def whisper(message)
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BundleUpdateInteractive
|
4
|
+
module Latest
|
5
|
+
class GemRequirement
|
6
|
+
def self.parse(version)
|
7
|
+
return version if version.is_a?(GemRequirement)
|
8
|
+
|
9
|
+
_, operator, number = version.strip.match(/^([^\d\s]*)\s*(.+)/).to_a
|
10
|
+
operator = nil if operator.empty?
|
11
|
+
|
12
|
+
new(parts: number.split("."), operator: operator, parsed_from: version)
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :parts, :operator
|
16
|
+
|
17
|
+
def initialize(parts:, operator: nil, parsed_from: nil)
|
18
|
+
@parts = parts
|
19
|
+
@operator = operator
|
20
|
+
@parsed_from = parsed_from
|
21
|
+
end
|
22
|
+
|
23
|
+
def exact?
|
24
|
+
operator.nil?
|
25
|
+
end
|
26
|
+
|
27
|
+
def relax
|
28
|
+
return self if %w[!= > >=].include?(operator)
|
29
|
+
return self.class.parse(">= 0") if %w[< <=].include?(operator)
|
30
|
+
|
31
|
+
self.class.new(parts: parts, operator: ">=")
|
32
|
+
end
|
33
|
+
|
34
|
+
def shift(new_version) # rubocop:disable Metrics/AbcSize
|
35
|
+
return self.class.parse(new_version) if exact?
|
36
|
+
return self if Gem::Requirement.new(to_s).satisfied_by?(Gem::Version.new(new_version))
|
37
|
+
return self.class.new(parts: self.class.parse(new_version).parts, operator: "<=") if %w[< <=].include?(operator)
|
38
|
+
|
39
|
+
new_slice = self.class.parse(new_version).slice(parts.length)
|
40
|
+
self.class.new(parts: new_slice.parts, operator: "~>")
|
41
|
+
end
|
42
|
+
|
43
|
+
def slice(amount)
|
44
|
+
self.class.new(parts: parts[0, amount], operator: operator)
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_s
|
48
|
+
parsed_from || [operator, parts.join(".")].compact.join(" ")
|
49
|
+
end
|
50
|
+
|
51
|
+
def ==(other)
|
52
|
+
return false unless other.is_a?(GemRequirement)
|
53
|
+
|
54
|
+
to_s == other.to_s
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
attr_reader :parsed_from
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BundleUpdateInteractive
|
4
|
+
module Latest
|
5
|
+
class GemfileEditor
|
6
|
+
def initialize(gemfile_path: "Gemfile", lockfile_path: "Gemfile.lock")
|
7
|
+
@gemfile_path = gemfile_path
|
8
|
+
@lockfile_path = lockfile_path
|
9
|
+
end
|
10
|
+
|
11
|
+
def with_relaxed_gemfile
|
12
|
+
original, modified = modify_gemfile { |_, requirement| requirement.relax }
|
13
|
+
yield
|
14
|
+
ensure
|
15
|
+
File.write(gemfile_path, original) if original && original != modified
|
16
|
+
end
|
17
|
+
|
18
|
+
def shift_gemfile
|
19
|
+
lockfile = Lockfile.parse(File.read(lockfile_path))
|
20
|
+
original, modified = modify_gemfile do |name, requirement|
|
21
|
+
lockfile_entry = lockfile[name]
|
22
|
+
requirement.shift(lockfile_entry.version.to_s) if lockfile_entry
|
23
|
+
end
|
24
|
+
original != modified
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
attr_reader :gemfile_path, :lockfile_path
|
30
|
+
|
31
|
+
def modify_gemfile(&block)
|
32
|
+
original_contents = File.read(gemfile_path)
|
33
|
+
new_contents = original_contents.dup
|
34
|
+
|
35
|
+
find_rewritable_gem_names(original_contents).each do |name|
|
36
|
+
rewrite_contents(name, new_contents, &block)
|
37
|
+
end
|
38
|
+
|
39
|
+
File.write(gemfile_path, new_contents) unless new_contents == original_contents
|
40
|
+
[original_contents, new_contents]
|
41
|
+
end
|
42
|
+
|
43
|
+
def find_rewritable_gem_names(contents)
|
44
|
+
Gemfile.parse(gemfile_path).dependencies.filter_map do |dep|
|
45
|
+
gem_name = dep.name
|
46
|
+
gem_name if gem_declaration_with_requirement_re(gem_name).match?(contents)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def rewrite_contents(gem_name, contents)
|
51
|
+
found = contents.sub!(gem_declaration_with_requirement_re(gem_name)) do |match|
|
52
|
+
version = Regexp.last_match[1]
|
53
|
+
match[Regexp.last_match.regexp, 1] = yield(gem_name, GemRequirement.parse(version)).to_s
|
54
|
+
match
|
55
|
+
end
|
56
|
+
raise "Can't rewrite version for #{gem_name}" unless found
|
57
|
+
end
|
58
|
+
|
59
|
+
def gem_declaration_re(gem_name)
|
60
|
+
/^\s*gem\s+["']#{Regexp.escape(gem_name)}["']/
|
61
|
+
end
|
62
|
+
|
63
|
+
def gem_declaration_with_requirement_re(gem_name)
|
64
|
+
/#{gem_declaration_re(gem_name)},\s*["']([^'"]+)["']/
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Extends the default Updater class to allow updating to the latest gem versions.
|
4
|
+
# Does this by using GemfileEditor to relax the Gemfile requirements before
|
5
|
+
# `find_updatable_gems` and `apply_updates` are called.
|
6
|
+
module BundleUpdateInteractive
|
7
|
+
module Latest
|
8
|
+
class Updater < BundleUpdateInteractive::Updater
|
9
|
+
def initialize(editor: GemfileEditor.new, **kwargs)
|
10
|
+
super(**kwargs)
|
11
|
+
@modified_gemfile = false
|
12
|
+
@editor = editor
|
13
|
+
end
|
14
|
+
|
15
|
+
def apply_updates(*, **)
|
16
|
+
result = editor.with_relaxed_gemfile { super }
|
17
|
+
@modified_gemfile = editor.shift_gemfile
|
18
|
+
BundlerCommands.lock
|
19
|
+
result
|
20
|
+
end
|
21
|
+
|
22
|
+
def modified_gemfile?
|
23
|
+
@modified_gemfile
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
attr_reader :editor
|
29
|
+
|
30
|
+
def find_updatable_gems
|
31
|
+
editor.with_relaxed_gemfile { super }
|
32
|
+
end
|
33
|
+
|
34
|
+
# Overrides the default Updater implementation.
|
35
|
+
# When updating the latest gems, by definition nothing is withheld, so we can skip this.
|
36
|
+
def find_withheld_gems(**)
|
37
|
+
{}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -38,8 +38,8 @@ module BundleUpdateInteractive
|
|
38
38
|
@changelog_uri =
|
39
39
|
if (diff_url = build_git_diff_url)
|
40
40
|
diff_url
|
41
|
-
elsif rubygems_source?
|
42
|
-
|
41
|
+
elsif (found_uri = rubygems_source? && locate_changelog_uri)
|
42
|
+
found_uri
|
43
43
|
else
|
44
44
|
begin
|
45
45
|
Gem::Specification.find_by_name(name)&.homepage
|
@@ -57,6 +57,10 @@ module BundleUpdateInteractive
|
|
57
57
|
|
58
58
|
attr_reader :changelog_locator
|
59
59
|
|
60
|
+
def locate_changelog_uri
|
61
|
+
changelog_locator.find_changelog_uri(name: name, version: updated_version.to_s)
|
62
|
+
end
|
63
|
+
|
60
64
|
def build_git_diff_url
|
61
65
|
return nil unless git_version_changed?
|
62
66
|
|
@@ -23,11 +23,6 @@ module BundleUpdateInteractive
|
|
23
23
|
@all_gems ||= withheld_gems.merge(updatable_gems)
|
24
24
|
end
|
25
25
|
|
26
|
-
def expand_gems_with_exact_dependencies(*gem_names)
|
27
|
-
gem_names.flatten!
|
28
|
-
gem_names.flat_map { |name| [name, *current_lockfile[name].exact_dependencies] }.uniq
|
29
|
-
end
|
30
|
-
|
31
26
|
def scan_for_vulnerabilities!
|
32
27
|
return false if all_gems.empty?
|
33
28
|
|
@@ -36,16 +31,12 @@ module BundleUpdateInteractive
|
|
36
31
|
vulnerable_gem_names = Set.new(audit_report.vulnerable_gems.map(&:name))
|
37
32
|
|
38
33
|
all_gems.each do |name, gem|
|
39
|
-
|
34
|
+
exact_deps = current_lockfile && current_lockfile[name].exact_dependencies
|
35
|
+
gem.vulnerable = (vulnerable_gem_names & [name, *Array(exact_deps)]).any?
|
40
36
|
end
|
41
37
|
true
|
42
38
|
end
|
43
39
|
|
44
|
-
def bundle_update!(*gem_names)
|
45
|
-
expanded_names = expand_gems_with_exact_dependencies(*gem_names)
|
46
|
-
BundlerCommands.update_gems_conservatively(*expanded_names)
|
47
|
-
end
|
48
|
-
|
49
40
|
private
|
50
41
|
|
51
42
|
attr_reader :current_lockfile
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# lib/bundle_update_interactive/string_helper.rb
|
4
|
+
module BundleUpdateInteractive
|
5
|
+
module StringHelper
|
6
|
+
def pluralize(count, singular, plural=nil)
|
7
|
+
plural ||= "#{singular}s"
|
8
|
+
"#{count} #{count == 1 ? singular : plural}"
|
9
|
+
end
|
10
|
+
module_function :pluralize
|
11
|
+
end
|
12
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module BundleUpdateInteractive
|
4
|
-
class
|
4
|
+
class Updater
|
5
5
|
def initialize(groups: [])
|
6
6
|
@gemfile = Gemfile.parse
|
7
7
|
@current_lockfile = Lockfile.parse
|
@@ -15,6 +15,16 @@ module BundleUpdateInteractive
|
|
15
15
|
Report.new(current_lockfile: current_lockfile, updatable_gems: updatable_gems, withheld_gems: withheld_gems)
|
16
16
|
end
|
17
17
|
|
18
|
+
def apply_updates(*gem_names)
|
19
|
+
expanded_names = expand_gems_with_exact_dependencies(*gem_names)
|
20
|
+
BundlerCommands.update_gems_conservatively(*expanded_names)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Overridden by Latest::Updater subclass
|
24
|
+
def modified_gemfile?
|
25
|
+
false
|
26
|
+
end
|
27
|
+
|
18
28
|
private
|
19
29
|
|
20
30
|
attr_reader :gemfile, :current_lockfile, :candidate_gems
|
@@ -33,6 +43,20 @@ module BundleUpdateInteractive
|
|
33
43
|
end
|
34
44
|
end
|
35
45
|
|
46
|
+
def find_withheld_gems(exclude: [])
|
47
|
+
possibly_withheld = gemfile.dependencies.filter_map do |dep|
|
48
|
+
dep.name if dep.should_include? && !dep.requirement.none? # rubocop:disable Style/InverseMethods
|
49
|
+
end
|
50
|
+
possibly_withheld -= exclude
|
51
|
+
possibly_withheld &= candidate_gems unless candidate_gems.nil?
|
52
|
+
|
53
|
+
return {} if possibly_withheld.empty?
|
54
|
+
|
55
|
+
BundlerCommands.parse_outdated(*possibly_withheld).to_h do |name, newest|
|
56
|
+
[name, build_outdated_gem(name, newest, nil)]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
36
60
|
def build_outdated_gem(name, updated_version, updated_git_version)
|
37
61
|
current_lockfile_entry = current_lockfile[name]
|
38
62
|
|
@@ -49,18 +73,9 @@ module BundleUpdateInteractive
|
|
49
73
|
)
|
50
74
|
end
|
51
75
|
|
52
|
-
def
|
53
|
-
|
54
|
-
|
55
|
-
end
|
56
|
-
possibly_withheld -= exclude
|
57
|
-
possibly_withheld &= candidate_gems unless candidate_gems.nil?
|
58
|
-
|
59
|
-
return {} if possibly_withheld.empty?
|
60
|
-
|
61
|
-
BundlerCommands.parse_outdated(*possibly_withheld).to_h do |name, newest|
|
62
|
-
[name, build_outdated_gem(name, newest, nil)]
|
63
|
-
end
|
76
|
+
def expand_gems_with_exact_dependencies(*gem_names)
|
77
|
+
gem_names.flatten!
|
78
|
+
gem_names.flat_map { |name| [name, *current_lockfile[name].exact_dependencies] }.uniq
|
64
79
|
end
|
65
80
|
end
|
66
81
|
end
|
@@ -2,21 +2,13 @@
|
|
2
2
|
|
3
3
|
require "pastel"
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
autoload :Gemfile, "bundle_update_interactive/gemfile"
|
11
|
-
autoload :HTTP, "bundle_update_interactive/http"
|
12
|
-
autoload :Lockfile, "bundle_update_interactive/lockfile"
|
13
|
-
autoload :LockfileEntry, "bundle_update_interactive/lockfile_entry"
|
14
|
-
autoload :OutdatedGem, "bundle_update_interactive/outdated_gem"
|
15
|
-
autoload :Report, "bundle_update_interactive/report"
|
16
|
-
autoload :Reporter, "bundle_update_interactive/reporter"
|
17
|
-
autoload :SemverChange, "bundle_update_interactive/semver_change"
|
18
|
-
autoload :VERSION, "bundle_update_interactive/version"
|
5
|
+
require "zeitwerk"
|
6
|
+
loader = Zeitwerk::Loader.for_gem
|
7
|
+
loader.inflector.inflect "cli" => "CLI"
|
8
|
+
loader.inflector.inflect "http" => "HTTP"
|
9
|
+
loader.setup
|
19
10
|
|
11
|
+
module BundleUpdateInteractive
|
20
12
|
class << self
|
21
13
|
attr_accessor :pastel
|
22
14
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bundle_update_interactive
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Brictson
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-09-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: 0.8.2
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: zeitwerk
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '2.6'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '2.6'
|
97
111
|
description:
|
98
112
|
email:
|
99
113
|
- opensource@mattbrictson.com
|
@@ -118,12 +132,16 @@ files:
|
|
118
132
|
- lib/bundle_update_interactive/error.rb
|
119
133
|
- lib/bundle_update_interactive/gemfile.rb
|
120
134
|
- lib/bundle_update_interactive/http.rb
|
135
|
+
- lib/bundle_update_interactive/latest/gem_requirement.rb
|
136
|
+
- lib/bundle_update_interactive/latest/gemfile_editor.rb
|
137
|
+
- lib/bundle_update_interactive/latest/updater.rb
|
121
138
|
- lib/bundle_update_interactive/lockfile.rb
|
122
139
|
- lib/bundle_update_interactive/lockfile_entry.rb
|
123
140
|
- lib/bundle_update_interactive/outdated_gem.rb
|
124
141
|
- lib/bundle_update_interactive/report.rb
|
125
|
-
- lib/bundle_update_interactive/reporter.rb
|
126
142
|
- lib/bundle_update_interactive/semver_change.rb
|
143
|
+
- lib/bundle_update_interactive/string_helper.rb
|
144
|
+
- lib/bundle_update_interactive/updater.rb
|
127
145
|
- lib/bundle_update_interactive/version.rb
|
128
146
|
homepage: https://github.com/mattbrictson/bundle_update_interactive
|
129
147
|
licenses:
|
@@ -149,7 +167,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
149
167
|
- !ruby/object:Gem::Version
|
150
168
|
version: '0'
|
151
169
|
requirements: []
|
152
|
-
rubygems_version: 3.5.
|
170
|
+
rubygems_version: 3.5.18
|
153
171
|
signing_key:
|
154
172
|
specification_version: 4
|
155
173
|
summary: Adds an update-interactive command to Bundler
|