Class: Gem::Repackager

Inherits:
Object
  • Object
show all
Defined in:
lib/gem_repackager.rb,
lib/gem_repackager/version.rb

Overview

Repackages one or more installed gems back into a .gem file

When a gem is installed, the file is split into multiple directories. The gemspec is placed in the specifications directory, the executables are placed in the bin directory, and the rest of the code is placed in a named directory within the gems directory.

Gem::Repackager repackages gems back into .gem file(s), either individually or a directory at a time.

packager = Gem::Repackager.new '/opt/ruby/gems'
packager.package_all '~/gems'

spec = packager.load_spec 'activemodel', '3.2.8'
packager.package_gem spec

Gem::Repackager requires a path to the gems directory of the desired Ruby installation in order to detect specs and properly recombine all the parts of a gem. It defaults to the current working directory.

Constant Summary collapse

VERSION =
'0.1.0'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(gem_dir = '.') ⇒ Repackager

Returns a new instance of Repackager.



30
31
32
# File 'lib/gem_repackager.rb', line 30

def initialize gem_dir = '.'
  @gem_dir = gem_dir
end

Instance Attribute Details

#gem_dirObject (readonly)

Returns the value of attribute gem_dir.



28
29
30
# File 'lib/gem_repackager.rb', line 28

def gem_dir
  @gem_dir
end

#gems_builtObject (readonly)

Returns the value of attribute gems_built.



28
29
30
# File 'lib/gem_repackager.rb', line 28

def gems_built
  @gems_built
end

#gems_failedObject (readonly)

Returns the value of attribute gems_failed.



28
29
30
# File 'lib/gem_repackager.rb', line 28

def gems_failed
  @gems_failed
end

Instance Method Details

#enter_gem_directory(gem) ⇒ Object

Enters specific gem’s directory within gems dir

Parameters:

  • name (String)

    of the gem



89
90
91
# File 'lib/gem_repackager.rb', line 89

def enter_gem_directory gem
  FileUtils.cd "#{@gem_dir}/gems/#{gem}"
end

#load_spec(options = {}) ⇒ Gem::Specification

Enters gems directory and loads the .gemspec

Parameters:

  • filename (String)

    (.gemspec) of gem

Returns:

  • (Gem::Specification)

    parsed .gemspec



76
77
78
79
80
81
82
83
84
# File 'lib/gem_repackager.rb', line 76

def load_spec options = {}
  if options[:filename]
    filename = options[:filename]
  elsif options[:name] && options[:version]
    filename = "#{@gem_dir}/specifications/#{options[:name]}-#{options[:version]}.gemspec"
  end

  Gem::Specification.load filename
end

#package_all(destination = gem_dir) ⇒ Array

Builds all gems and moves to determined directory

Parameters:

  • Destination (String)

    of built gems. Defaults to gem directory

Returns:

  • (Array)

    List of all gems built successfully



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/gem_repackager.rb', line 38

def package_all destination = gem_dir
  @gems_built = []
  @gems_failed = []

  Dir["#{@gem_dir}/specifications/*.gemspec"].each do |spec_filename|
    spec = load_spec filename: spec_filename
    gem = package_gem spec

    if gem
      @gems_built.push gem
      FileUtils.mv gem, destination
    else
      @gems_failed.push spec_filename
    end
  end

  @gems_built
end

#package_gem(spec) ⇒ String?

Packages gem from Gem::Specification. If successful, returns the filename of the gem packaged. If unsuccessul, returns nil.

Parameters:

  • Gemspec (Gem::Specification)

    to build

Returns:

  • (String, nil)

    Filename of gem built, or nil



62
63
64
65
66
67
68
69
70
# File 'lib/gem_repackager.rb', line 62

def package_gem spec
  enter_gem_directory spec.file_name.sub(/\.gem/,'')
  symlink_bin
  Gem::Builder.new(spec).build
rescue Gem::InvalidSpecificationException
  return nil
ensure
  unlink_bin
end

#reset_warningsObject

Resets warnings to before their silenced state

See Also:



125
126
127
128
129
# File 'lib/gem_repackager.rb', line 125

def reset_warnings
  Gem.configuration.verbose = @verbose
  Gem::UserInteraction.send :alias_method, :silent_alert_warning, :alert_warning
  Gem::UserInteraction.send :alias_method, :alert_warning, :loud_alert_warning
end

#silence_warningsObject

Silences warning generated by validating and packaging gems

When validating a gemspec before building, a slew of warnings and success notifications are spewed into the console without an easy way to silence the verbosity. This shuts off the warnings and build success output in a reversible fashion



115
116
117
118
119
120
# File 'lib/gem_repackager.rb', line 115

def silence_warnings
  @verbose = Gem.configuration.verbose
  Gem.configuration.verbose = false # SILENCE
  Gem::UserInteraction.send :alias_method, :loud_alert_warning, :alert_warning
  Gem::UserInteraction.send :alias_method, :alert_warning, :silent_alert_warning
end

Symlink the bin directory to the gem directory. This is due to the decomposed nature of installed gems compared to the original conjoined structure of the gem before packaging.

See Also:



98
99
100
# File 'lib/gem_repackager.rb', line 98

def symlink_bin
  FileUtils.ln_sf('../../bin', 'bin')
end

Removes the symlink to the bin directory.

See Also:



105
106
107
# File 'lib/gem_repackager.rb', line 105

def unlink_bin
  FileUtils.rm_f('bin')
end