Class: Gem::Commands::RebuildCommand

Inherits:
Gem::Command show all
Includes:
GemspecHelpers
Defined in:
lib/rubygems/commands/rebuild_command.rb

Constant Summary collapse

DATE_FORMAT =
"%Y-%m-%d %H:%M:%S.%N Z"

Instance Attribute Summary

Attributes inherited from Gem::Command

#command, #defaults, #options, #program_name, #summary

Instance Method Summary collapse

Methods included from GemspecHelpers

#find_gemspec

Methods inherited from Gem::Command

add_common_option, #add_extra_args, #add_option, add_specific_extra_args, #begins?, build_args, build_args=, #check_deprecated_options, common_options, #defaults_str, #deprecate_option, #deprecated?, extra_args, extra_args=, #extract_gem_name_and_version, #get_all_gem_names, #get_all_gem_names_and_versions, #get_one_gem_name, #get_one_optional_argument, #handle_options, #handles?, #invoke, #invoke_with_build_args, #merge_options, #remove_option, #show_help, #show_lookup_failure, specific_extra_args, specific_extra_args_hash, #when_invoked

Methods included from UserInteraction

#alert, #alert_error, #alert_warning, #ask, #ask_for_password, #ask_yes_no, #choose_from_list, #say, #terminate_interaction, #verbose

Methods included from DefaultUserInteraction

ui, #ui, ui=, #ui=, use_ui, #use_ui

Methods included from Text

#clean_text, #format_text, #levenshtein_distance, #min3, #truncate_text

Constructor Details

#initializeRebuildCommand

Returns a new instance of RebuildCommand.



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/rubygems/commands/rebuild_command.rb', line 15

def initialize
  super "rebuild", "Attempt to reproduce a build of a gem."

  add_option "--diff", "If the files don't match, compare them using diffoscope." do |_value, options|
    options[:diff] = true
  end

  add_option "--force", "Skip validation of the spec." do |_value, options|
    options[:force] = true
  end

  add_option "--strict", "Consider warnings as errors when validating the spec." do |_value, options|
    options[:strict] = true
  end

  add_option "--source GEM_SOURCE", "Specify the source to download the gem from." do |value, options|
    options[:source] = value
  end

  add_option "--original GEM_FILE", "Specify a local file to compare against (instead of downloading it)." do |value, options|
    options[:original_gem_file] = value
  end

  add_option "--gemspec GEMSPEC_FILE", "Specify the name of the gemspec file." do |value, options|
    options[:gemspec_file] = value
  end

  add_option "-C PATH", "Run as if gem build was started in <PATH> instead of the current working directory." do |value, options|
    options[:build_path] = value
  end
end

Instance Method Details

#argumentsObject

:nodoc:



47
48
49
50
# File 'lib/rubygems/commands/rebuild_command.rb', line 47

def arguments # :nodoc:
  "GEM_NAME      gem name on gem server\n" \
  "GEM_VERSION   gem version you are attempting to rebuild"
end

#descriptionObject

:nodoc:



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/rubygems/commands/rebuild_command.rb', line 52

def description # :nodoc:
  <<-EOF
The rebuild command allows you to (attempt to) reproduce a build of a gem
from a ruby gemspec.

This command assumes the gemspec can be built with the `gem build` command.
If you use any of `gem build`, `rake build`, or`rake release` in the
build/release process for a gem, it is a potential candidate.

You will need to match the RubyGems version used, since this is included in
the Gem metadata.

If the gem includes lockfiles (e.g. Gemfile.lock) and similar, it will
require more effort to reproduce a build. For example, it might require
more precisely matched versions of Ruby and/or Bundler to be used.
  EOF
end

#executeObject



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/rubygems/commands/rebuild_command.rb', line 74

def execute
  gem_name, gem_version = get_gem_name_and_version

  old_dir, new_dir = prep_dirs

  gem_filename = "#{gem_name}-#{gem_version}.gem"
  old_file = File.join(old_dir, gem_filename)
  new_file = File.join(new_dir, gem_filename)

  if options[:original_gem_file]
    FileUtils.copy_file(options[:original_gem_file], old_file)
  else
    download_gem(gem_name, gem_version, old_file)
  end

  rg_version = rubygems_version(old_file)
  unless rg_version == Gem::VERSION
    alert_error <<-EOF
You need to use the same RubyGems version #{gem_name} v#{gem_version} was built with.

#{gem_name} v#{gem_version} was built using RubyGems v#{rg_version}.
Gem files include the version of RubyGems used to build them.
This means in order to reproduce #{gem_filename}, you must also use RubyGems v#{rg_version}.

You're using RubyGems v#{Gem::VERSION}.

Please install RubyGems v#{rg_version} and try again.
    EOF
    terminate_interaction 1
  end

  source_date_epoch = get_timestamp(old_file).to_s

  if build_path = options[:build_path]
    Dir.chdir(build_path) { build_gem(gem_name, source_date_epoch, new_file) }
  else
    build_gem(gem_name, source_date_epoch, new_file)
  end

  compare(source_date_epoch, old_file, new_file)
end

#usageObject

:nodoc:



70
71
72
# File 'lib/rubygems/commands/rebuild_command.rb', line 70

def usage # :nodoc:
  "#{program_name} GEM_NAME GEM_VERSION"
end