gvf 0.1.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.
Files changed (5) hide show
  1. checksums.yaml +7 -0
  2. data/exe/gvf +53 -0
  3. data/lib/gvf/gemfile_updater.rb +37 -0
  4. data/lib/gvf.rb +20 -0
  5. metadata +46 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 31dd7935b10f8a57ee5ebf22a6032b1c66d0de5777b0729269ad1345fc4d7cb8
4
+ data.tar.gz: 9837ccc6201190c83daf46fd64fc623ecff262522674969d380b20a65969212e
5
+ SHA512:
6
+ metadata.gz: 176d75cb80372c71514a54f6feeb606a50e3e13fd68ac76b94e271b7508dc28b5c2a6f0d45473f7bf14ea627ea478ab3d4be892e34952402888d2edb9ddd464b
7
+ data.tar.gz: 9560f2056b5a8f536415fac3816a46487b2ad30c640ffd58deade93ce5b3b0805006f3bca7cec416809d678cda574b27be130c8dca3510627d426678ee181ecb
data/exe/gvf ADDED
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "optparse"
4
+ require_relative "../lib/gvf"
5
+
6
+ options = { constraint: "minor", yes: false }
7
+
8
+ parser = OptionParser.new do |opts|
9
+ opts.banner = "Usage: gvf [options] [Gemfile [Gemfile.lock]]"
10
+
11
+ opts.on("-c", "--version-constraint CONSTRAINT", %w[minor patch],
12
+ "Version constraint ('minor' or 'patch') (default: minor)") do |c|
13
+ options[:constraint] = c
14
+ end
15
+
16
+ opts.on("-y", "--yes", "Skip confirmation prompt") do
17
+ options[:yes] = true
18
+ end
19
+
20
+ opts.on("-v", "--version", "Print version and exit") do
21
+ puts GVF::VERSION
22
+ exit
23
+ end
24
+
25
+ opts.on("-h", "--help", "Show this message") do
26
+ puts opts
27
+ exit
28
+ end
29
+ end
30
+
31
+ parser.parse!
32
+
33
+ gemfile = ARGV[0] || "Gemfile"
34
+ lockfile = ARGV[1] || "Gemfile.lock"
35
+
36
+ puts "pinning gem versions from:"
37
+ puts " #{lockfile} -> #{gemfile}"
38
+
39
+ unless options.delete(:yes)
40
+ print "\ncontinue? [y/N] "
41
+ unless $stdin.gets.to_s.strip.downcase == "y"
42
+ puts "aborted"
43
+ exit 1
44
+ end
45
+ end
46
+
47
+ begin
48
+ count = GVF.run(gemfile_path: gemfile, lockfile_path: lockfile, **options)
49
+ puts "updated #{count} gem(s)"
50
+ rescue => e
51
+ warn "error: #{e.message}"
52
+ exit 1
53
+ end
@@ -0,0 +1,37 @@
1
+ module GVF
2
+ module GemfileUpdater
3
+ # Returns [updated_content, count_of_changes]
4
+ def self.update(gemfile_path, versions, constraint: "minor")
5
+ content = File.read(gemfile_path)
6
+ count = 0
7
+
8
+ updated = content.gsub(/^([ \t]*gem[ \t]+['"]([^'"]+)['"])([^#\n]*)/) do
9
+ indent_and_name = $1
10
+ name = $2
11
+ rest = $3
12
+
13
+ version = versions[name]
14
+ unless version
15
+ next $& # no match in lockfile, leave unchanged
16
+ end
17
+
18
+ # Strip version constraint strings (e.g. "~> 1.0", ">= 0.18", "< 2.0")
19
+ # and keep everything else (require:, group:, platforms:, etc.)
20
+ options = rest.gsub(/,?[ \t]*["'][ \t]*(?:~>|>=|<=|!=|[><]=?|=)[ \t]*\d[^'"]*["']/, "")
21
+
22
+ count += 1
23
+ "#{indent_and_name}, \"#{format_constraint(version, constraint)}\"#{options}"
24
+ end
25
+
26
+ [updated, count]
27
+ end
28
+
29
+ def self.format_constraint(version, constraint)
30
+ parts = version.split(".")
31
+ case constraint
32
+ when "minor" then "~> #{parts[0..1].join(".")}"
33
+ when "patch" then "~> #{parts[0..2].join(".")}"
34
+ end
35
+ end
36
+ end
37
+ end
data/lib/gvf.rb ADDED
@@ -0,0 +1,20 @@
1
+ require "bundler"
2
+ require_relative "gvf/gemfile_updater"
3
+
4
+ module GVF
5
+ VERSION = "0.1.0"
6
+
7
+ def self.run(gemfile_path: "Gemfile", lockfile_path: "Gemfile.lock", constraint: "minor")
8
+ raise "Gemfile not found: #{gemfile_path}" unless File.exist?(gemfile_path)
9
+ raise "Gemfile.lock not found: #{lockfile_path}" unless File.exist?(lockfile_path)
10
+ raise "Invalid constraint '#{constraint}': must be 'minor' or 'patch'" unless %w[minor patch].include?(constraint)
11
+
12
+ parser = Bundler::LockfileParser.new(File.read(lockfile_path))
13
+ versions = parser.specs.each_with_object({}) { |spec, h| h[spec.name] = spec.version.to_s }
14
+
15
+ updated, count = GemfileUpdater.update(gemfile_path, versions, constraint: constraint)
16
+
17
+ File.write(gemfile_path, updated)
18
+ count
19
+ end
20
+ end
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gvf
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - kinduff
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2026-03-21 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email:
15
+ executables:
16
+ - gvf
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - exe/gvf
21
+ - lib/gvf.rb
22
+ - lib/gvf/gemfile_updater.rb
23
+ homepage: https://github.com/kinduff/gvf
24
+ licenses:
25
+ - MIT
26
+ metadata: {}
27
+ post_install_message:
28
+ rdoc_options: []
29
+ require_paths:
30
+ - lib
31
+ required_ruby_version: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ requirements: []
42
+ rubygems_version: 3.4.19
43
+ signing_key:
44
+ specification_version: 4
45
+ summary: gemfile version fixer
46
+ test_files: []