bundle_update_interactive 0.9.1 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f45b67dd4da1f56e5bad0b154acfb7dce40b4f518eb1cf9c1101302ec3ee71f4
4
- data.tar.gz: 9d763c27460be163b2dc6eaa818e770e81448244bcd0c2c94dee368b148d4a1d
3
+ metadata.gz: 45766051bc33bd9e477c7e1cf57bb78352732be6c0683c173330a46b6ede55bd
4
+ data.tar.gz: 40308582e58bd8b027be213c38fd7bdbb375a8b25a5272f30ec0cde2f1e741b9
5
5
  SHA512:
6
- metadata.gz: 5bf17f343e90aa16f244c470ad9f58590702d61f610e9ac6bb4623990b997f103ea52448433f8c5273880b3f110e467c72c841fa25274c9770e21805c3ce403a
7
- data.tar.gz: 248b8e8b066fa56574297c76ce25eab8bbd6b14e10ca1a8d83444679a82dae76ae7117775fa6df9753a1c847a337d2c4730270d87ec55c33186e249e9d002a02
6
+ metadata.gz: b826b2cd41a7e31c2e875f5d6c5333ddba6df10931bcc6eacdc191e078be51b6bb65d993a3371e587de0825306ddbad383925b45729c62d3dc3a0e8b2bb56316
7
+ data.tar.gz: '08a986946005d949e9a53c460ea00e338dc71512b11ba7c4ab72f9b31e31291b009cb9da175c35ece600624d8499f6b509080da0731d2cabac9525b7d5bb6c63'
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2024 Matt Brictson
3
+ Copyright (c) 2025 Matt Brictson
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -44,6 +44,7 @@ bundle ui
44
44
 
45
45
  - `--commit` [applies each gem update in a discrete git commit](#git-commits)
46
46
  - `--latest` [modifies the Gemfile if necessary to allow the latest gem versions](#allow-latest-versions)
47
+ - `--only-explicit` [updates Gemfile gems only (excluding indirect dependencies)](#exclude-indirect-dependencies)
47
48
  - `-D` / `--exclusively=GROUP` [limits updatable gems by Gemfile groups](#limit-impact-by-gemfile-groups)
48
49
 
49
50
  ## Features
@@ -145,6 +146,16 @@ https://github.com/rails/rails/compare/5a8d894...77dfa65
145
146
 
146
147
  This feature currently works for GitHub, GitLab, and Bitbucket repos.
147
148
 
149
+ ### Exclude indirect dependencies
150
+
151
+ Just like with `bundle outdated`, you can pass `--only-explicit` to limit updates to only gems that are explicitly listed in the Gemfile.
152
+
153
+ ```sh
154
+ bundle update-interactive --only-explicit
155
+ ```
156
+
157
+ This will omit indirect dependencies from the list of gems that can be updated.
158
+
148
159
  ### Limit impact by Gemfile groups
149
160
 
150
161
  The effects of `bundle update-interactive` can be limited to one or more Gemfile groups using the `--exclusively` option:
@@ -71,6 +71,9 @@ module BundleUpdateInteractive
71
71
  parser.on("--latest", "Modify the Gemfile to allow the latest gem versions") do
72
72
  options.latest = true
73
73
  end
74
+ parser.on("--only-explicit", "Update Gemfile gems only (no indirect dependencies)") do
75
+ options.only_explicit = true
76
+ end
74
77
  parser.on(
75
78
  "--exclusively=GROUP",
76
79
  "Update gems exclusively belonging to the specified Gemfile GROUP(s)"
@@ -94,12 +97,13 @@ module BundleUpdateInteractive
94
97
  end
95
98
 
96
99
  attr_accessor :exclusively
97
- attr_writer :commit, :latest
100
+ attr_writer :commit, :latest, :only_explicit
98
101
 
99
102
  def initialize
100
103
  @exclusively = []
101
104
  @commit = false
102
105
  @latest = false
106
+ @only_explicit = false
103
107
  end
104
108
 
105
109
  def commit?
@@ -109,6 +113,10 @@ module BundleUpdateInteractive
109
113
  def latest?
110
114
  @latest
111
115
  end
116
+
117
+ def only_explicit?
118
+ @only_explicit
119
+ end
112
120
  end
113
121
  end
114
122
  end
@@ -47,7 +47,7 @@ module BundleUpdateInteractive
47
47
  end
48
48
 
49
49
  def gem_names
50
- rows.keys
50
+ rows.keys.sort
51
51
  end
52
52
 
53
53
  def render_header
@@ -61,7 +61,7 @@ module BundleUpdateInteractive
61
61
 
62
62
  def render
63
63
  lines = [render_header]
64
- rows.keys.sort.each { |name| lines << render_gem(name) }
64
+ gem_names.each { |name| lines << render_gem(name) }
65
65
  lines.join("\n")
66
66
  end
67
67
 
@@ -61,18 +61,25 @@ module BundleUpdateInteractive
61
61
  def generate_report(options)
62
62
  whisper "Resolving latest gem versions..."
63
63
  updater_class = options.latest? ? Latest::Updater : Updater
64
- updater = updater_class.new(groups: options.exclusively)
64
+ updater = updater_class.new(groups: options.exclusively, only_explicit: options.only_explicit?)
65
65
 
66
66
  report = updater.generate_report
67
- unless report.empty?
68
- whisper "Checking for security vulnerabilities..."
69
- report.scan_for_vulnerabilities!
70
- progress "Finding changelogs", report.all_gems.values, &:changelog_uri
71
- end
67
+ populate_vulnerabilities_and_changelogs_concurrently(report) unless report.empty?
72
68
 
73
69
  [report, updater]
74
70
  end
75
71
 
72
+ def populate_vulnerabilities_and_changelogs_concurrently(report)
73
+ pool = ThreadPool.new(max_threads: 25)
74
+ whisper "Checking for security vulnerabilities..."
75
+ scan_promise = pool.future(report, &:scan_for_vulnerabilities!)
76
+ changelog_promises = report.all_gems.map do |_, outdated_gem|
77
+ pool.future(outdated_gem, &:changelog_uri)
78
+ end
79
+ progress "Finding changelogs", changelog_promises, &:value!
80
+ scan_promise.value!
81
+ end
82
+
76
83
  def whisper(message)
77
84
  $stderr.puts(message)
78
85
  end
@@ -22,5 +22,9 @@ module BundleUpdateInteractive
22
22
  def dependencies
23
23
  @dependencies.values
24
24
  end
25
+
26
+ def gem_names
27
+ dependencies.map(&:name)
28
+ end
25
29
  end
26
30
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "concurrent"
4
+
5
+ module BundleUpdateInteractive
6
+ class ThreadPool
7
+ include Concurrent::Promises::FactoryMethods
8
+
9
+ def initialize(max_threads:)
10
+ @executor = Concurrent::ThreadPoolExecutor.new(
11
+ min_threads: 0,
12
+ max_threads: max_threads,
13
+ max_queue: 0
14
+ )
15
+ end
16
+
17
+ def default_executor
18
+ @executor
19
+ end
20
+ end
21
+ end
@@ -2,7 +2,8 @@
2
2
 
3
3
  module BundleUpdateInteractive
4
4
  class Updater
5
- def initialize(groups: [])
5
+ def initialize(groups: [], only_explicit: false)
6
+ @only_explicit = only_explicit
6
7
  @gemfile = Gemfile.parse
7
8
  @current_lockfile = Lockfile.parse
8
9
  @candidate_gems = current_lockfile.gems_exclusively_installed_by(gemfile: gemfile, groups: groups) if groups.any?
@@ -32,12 +33,14 @@ module BundleUpdateInteractive
32
33
 
33
34
  private
34
35
 
35
- attr_reader :gemfile, :current_lockfile, :candidate_gems
36
+ attr_reader :gemfile, :current_lockfile, :candidate_gems, :only_explicit
36
37
 
37
38
  def find_updatable_gems
38
39
  return {} if candidate_gems && candidate_gems.empty?
39
40
 
40
- build_outdated_gems(BundlerCommands.read_updated_lockfile(*Array(candidate_gems)))
41
+ updatable = build_outdated_gems(BundlerCommands.read_updated_lockfile(*Array(candidate_gems)))
42
+ updatable = updatable.slice(*gemfile.gem_names) if only_explicit
43
+ updatable
41
44
  end
42
45
 
43
46
  def build_outdated_gems(lockfile_contents)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BundleUpdateInteractive
4
- VERSION = "0.9.1"
4
+ VERSION = "0.11.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bundle_update_interactive
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Brictson
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2024-11-24 00:00:00.000000000 Z
10
+ date: 2025-01-04 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: bundler
@@ -38,6 +37,20 @@ dependencies:
38
37
  - - ">="
39
38
  - !ruby/object:Gem::Version
40
39
  version: 0.9.1
40
+ - !ruby/object:Gem::Dependency
41
+ name: concurrent-ruby
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 1.3.4
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 1.3.4
41
54
  - !ruby/object:Gem::Dependency
42
55
  name: launchy
43
56
  requirement: !ruby/object:Gem::Requirement
@@ -108,7 +121,6 @@ dependencies:
108
121
  - - "~>"
109
122
  - !ruby/object:Gem::Version
110
123
  version: '2.6'
111
- description:
112
124
  email:
113
125
  - opensource@mattbrictson.com
114
126
  executables:
@@ -142,6 +154,7 @@ files:
142
154
  - lib/bundle_update_interactive/report.rb
143
155
  - lib/bundle_update_interactive/semver_change.rb
144
156
  - lib/bundle_update_interactive/string_helper.rb
157
+ - lib/bundle_update_interactive/thread_pool.rb
145
158
  - lib/bundle_update_interactive/updater.rb
146
159
  - lib/bundle_update_interactive/version.rb
147
160
  homepage: https://github.com/mattbrictson/bundle_update_interactive
@@ -153,7 +166,6 @@ metadata:
153
166
  source_code_uri: https://github.com/mattbrictson/bundle_update_interactive
154
167
  homepage_uri: https://github.com/mattbrictson/bundle_update_interactive
155
168
  rubygems_mfa_required: 'true'
156
- post_install_message:
157
169
  rdoc_options: []
158
170
  require_paths:
159
171
  - lib
@@ -168,8 +180,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
168
180
  - !ruby/object:Gem::Version
169
181
  version: '0'
170
182
  requirements: []
171
- rubygems_version: 3.5.23
172
- signing_key:
183
+ rubygems_version: 3.6.2
173
184
  specification_version: 4
174
185
  summary: Adds an update-interactive command to Bundler
175
186
  test_files: []