gem-repair 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: b7cc3c257647d2c9fc203ea0c429a4ff4962bdf333af226a103042777d636ef8
4
+ data.tar.gz: f3a0b102dc4b3c4c2de7ffd1f089eb34b8f0cb6edd09d0c1c5d203aa65865277
5
+ SHA512:
6
+ metadata.gz: b152ae8bab08597374d9c2d9fd078866e0e755d817bab48f4abae03de05baac0a0b561c45b08190524dca7eafdf00d8c4967c165dd755b9d7c71f8e64890f040
7
+ data.tar.gz: 9bacb491ae4cdf206828dabf9dfc0f261b49d32a804d3b299b77b7431bb4f37af24d227b1df367137a84d42e01fb8a312f8a819f56cf74c46a664741574c4d45
data/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # gem-repair
2
+
3
+ A RubyGems plugin to repair gems with missing extensions.
4
+
5
+ ## Installation
6
+
7
+ Build and install the gem locally:
8
+
9
+ ```sh
10
+ gem build gem-repair.gemspec
11
+ gem install ./gem-repair-0.1.0.gem
12
+ ```
13
+
14
+ Or, if you are managing it within a Bundler context, add it to your Gemfile:
15
+
16
+ ```ruby
17
+ gem 'gem-repair', path: './labs/gem-repair' # Adjust path as necessary
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ After installation, the `gem repair` command will be available:
23
+
24
+ ```sh
25
+ gem repair
26
+ ```
27
+
28
+ You can also specify the number of parallel threads to use:
29
+
30
+ ```sh
31
+ gem repair -j 8 # Use 8 threads
32
+ gem repair --jobs 2 # Use 2 threads
33
+ ```
34
+
35
+ This command will:
36
+ 1. Find all installed gems that are missing their compiled C extensions.
37
+ 2. Attempt to reinstall these gems using multiple threads.
38
+
39
+ ## Development
40
+
41
+ After checking out the repo, run `bundle install` to install dependencies. Then, you can run `rake test` to run the tests (though no tests are set up in this initial version).
42
+
43
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `gem-repair.gemspec`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [a configured gem server](https://rubygems.org).
44
+
45
+ ## Contributing
46
+
47
+ Bug reports and pull requests are welcome on GitHub at https://github.com/hsbt/hsbt. # TODO: Update if you have a different repo
48
+
49
+ ## License
50
+
51
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,99 @@
1
+ require 'rubygems/command'
2
+ require 'rubygems/installer'
3
+
4
+
5
+ class Gem::Commands::RepairCommand < Gem::Command
6
+ def initialize
7
+ super 'repair', 'Repairs gems with missing extensions by reinstalling them'
8
+
9
+ add_option('-j', '--jobs JOBS', Integer,
10
+ 'Number of parallel threads to use (default: 4)') do |value, options|
11
+ options[:jobs] = value
12
+ end
13
+ end
14
+
15
+ def arguments # :nodoc:
16
+ ""
17
+ end
18
+
19
+ def description # :nodoc:
20
+ <<-EOF
21
+ The repair command finds all installed gems that are missing their compiled
22
+ extensions and attempts to reinstall them. This can be useful after upgrading
23
+ Ruby or changing system libraries.
24
+
25
+ Use -j to specify the number of parallel threads (default: 4).
26
+ EOF
27
+ end
28
+
29
+ def usage # :nodoc:
30
+ "#{program_name} [options]"
31
+ end
32
+
33
+ def execute
34
+ say "Searching for gems with missing extensions..."
35
+
36
+ specs = Gem::Specification.select do |spec|
37
+ spec.platform == RUBY_ENGINE && spec.respond_to?(:missing_extensions?) && spec.missing_extensions?
38
+ end
39
+
40
+ specs = specs.group_by { |s| [s.name, s.version] }.map do |_, gems|
41
+ non_default_specs = gems.select { |s| !s.default_gem? }
42
+ if non_default_specs.empty?
43
+ gems
44
+ else
45
+ non_default_specs
46
+ end
47
+ end.flatten(1).shuffle
48
+
49
+ if specs.empty?
50
+ say "No gems found with missing extensions."
51
+ return
52
+ end
53
+
54
+ say "Found #{specs.count} gem(s) to repair: #{specs.map(&:full_name).join(', ')}"
55
+
56
+ queue = Queue.new
57
+ specs.each { |spec| queue << spec }
58
+
59
+ threads = []
60
+ # Get number of threads from -j option, default to 4
61
+ num_threads = options[:jobs] || 4
62
+
63
+ say "Repairing gems using #{num_threads} parallel threads..."
64
+
65
+ num_threads.times do
66
+ threads << Thread.new do
67
+ while !queue.empty? && (spec = queue.pop(true) rescue nil)
68
+ begin
69
+ say "Repairing #{spec.full_name}..."
70
+ # Ensure spec.base_dir is correct and writable
71
+ # The installer might need specific options, ensure they are correctly set up
72
+ installer_options = {
73
+ wrappers: true,
74
+ force: true, # Reinstall even if it appears installed
75
+ install_dir: spec.base_dir, # Install into the same location
76
+ env_shebang: true,
77
+ build_args: spec.build_args,
78
+ # Add other options as needed, e.g., :user_install => false if installing to system gems
79
+ # ignore_dependencies: true # Usually good for a restore/pristine operation
80
+ }
81
+
82
+ # Use spec.cache_file if available and valid, otherwise the installer might re-download
83
+ # Forcing a specific installer might be needed if default behavior isn't right
84
+ installer = Gem::Installer.at(spec.cache_file, installer_options)
85
+ installer.install
86
+ say "Successfully repaired #{spec.full_name} to #{spec.base_dir}"
87
+ rescue Gem::Ext::BuildError, Gem::Package::FormatError, Gem::InstallError, Zlib::BufError, NameError => e
88
+ alert_error "Failed to repair #{spec.full_name}: #{e.message}\n Backtrace: #{e.backtrace.join("\n ")}"
89
+ rescue => e
90
+ alert_error "An unexpected error occurred while repairing #{spec.full_name}: #{e.message}\n Backtrace: #{e.backtrace.join("\n ")}"
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ threads.each(&:join)
97
+ say "Gem repair process complete."
98
+ end
99
+ end
@@ -0,0 +1,4 @@
1
+ require 'rubygems/command_manager'
2
+ require 'rubygems/commands/repair_command'
3
+
4
+ Gem::CommandManager.instance.register_command :repair
metadata ADDED
@@ -0,0 +1,43 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gem-repair
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Hiroshi SHIBATA
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies: []
12
+ description: A RubyGems plugin that finds and reinstalls gems with missing compiled
13
+ extensions.
14
+ email:
15
+ - hsbt@ruby-lang.org
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - README.md
21
+ - lib/rubygems/commands/repair_command.rb
22
+ - lib/rubygems_plugin.rb
23
+ homepage: https://github.com/hsbt/gem-repair
24
+ licenses: []
25
+ metadata: {}
26
+ rdoc_options: []
27
+ require_paths:
28
+ - lib
29
+ required_ruby_version: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 2.7.0
34
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ requirements: []
40
+ rubygems_version: 3.6.7
41
+ specification_version: 4
42
+ summary: RubyGems plugin to repair gems with missing extensions.
43
+ test_files: []