Class: Gemvault::CLI::Commands::Doctor

Inherits:
Gemvault::CLI::Command show all
Defined in:
lib/gemvault/cli/commands/doctor.rb

Overview

Recovers from wrecked bundler plugin state. Two wrecks are repaired:

A bundler plugin index entry whose stored path no longer exists. Bundler records absolute paths in .bundle/plugin/index for path-installed plugins. Moving or renaming the source directory leaves an invalid path behind -- Bundler::Plugin.load_plugin warns "The following plugin paths don't exist: ..." and silently returns, leaving @sources nil. The next source X, type: :vault crashes inside Bundler::SourceList#add_plugin_source with NoMethodError on nil. Uninstalling clears the broken entry.

A ghost specification: an installation record whose gem directory is gone (see Gemvault::GhostSpecification). Bundler's plugin installer trusts the record and validates plugins.rb against the missing directory instead of the copy it just installed, so every bundle install fails with MalformattedPlugin (issue #23). Removing the record lets the reinstall see the machine as it is.

Re-running bundle install afterwards triggers Bundler to reinstall the plugin against whatever the current Gemfile declares. Run this from the project directory.

A project whose Gemfile is inline has no Gemfile to reinstall from, and keeps its plugins in a root Bundler will not consult unless told to. Both are handled below.

The repair is transactional. bundle install does more than reinstall the plugin, and that extra work can fail on its own; the index the uninstall clears is snapshotted first and put back when the reinstall never happened, so a failed run leaves the machine as found rather than with no plugin at all (issue #27). Every failure is one line on stderr and exit 1 (issue #24).

Constant Summary collapse

PLUGIN =
"bundler-source-vault".freeze
OWNED_GEMS =
%w[gemvault bundler-source-vault].freeze
PERMISSION_HINT =
"(re-run with permissions for that gem home, e.g. sudo gemvault doctor)".freeze

Instance Method Summary collapse

Instance Method Details

#runObject



51
52
53
54
55
56
57
58
59
60
61
# File 'lib/gemvault/cli/commands/doctor.rb', line 51

def run
  begin
    remove_ghost_specifications
  rescue SystemCallError => e
    print_error("#{e.message} #{PERMISSION_HINT}")
    exit(1)
  end
  saved = index.snapshot
  uninstall_plugin
  reinstall_or_explain(saved)
end