class Packtory::Packer

Constants

BUNDLE_BUNDLER_SETUP_FILE
BUNDLE_EXTENSIONS_PATH
BUNDLE_PACKTORY_TOOLS_PATH
BUNDLE_TARGET_PATH
DEFAULT_BIN_PATH

Attributes

gemfile[R]
gemspec_file[R]
opts[R]

Public Class Methods

new(opts = { }) click to toggle source
# File lib/packtory/packer.rb, line 26
def initialize(opts = { })
  @opts = Packtory.config.merge(opts)

  unless @opts[:gemfile].nil?
    @gemfile = Pathname.new(@opts[:gemfile])
  else
    @gemfile = nil
  end

  if @opts[:gemspec].nil?
    @gemspec_file = find_default_gemspec_file
  else
    @gemspec_file = @opts[:gemspec]
  end

  if @gemfile.nil?
    @gemfile = autogenerate_clean_gemfile
  end

  @files = nil

  self
end
silence_warnings() { || ... } click to toggle source
# File lib/packtory/packer.rb, line 14
def self.silence_warnings
  original_verbosity = $VERBOSE
  $VERBOSE = nil
  ret = yield
  $VERBOSE = original_verbosity
  ret
end

Public Instance Methods

add_bin_files(files, target_prefix_path, package_path = nil) click to toggle source
# File lib/packtory/packer.rb, line 505
def add_bin_files(files, target_prefix_path, package_path = nil)
  bin_path = @opts[:bin_path] || DEFAULT_BIN_PATH

  if @opts[:binstub].nil?
    unless gemspec.nil? || gemspec.executables.nil? || gemspec.executables.empty?
      @opts[:binstub] = { }

      gemspec.executables.each do |exec_fname|
        @opts[:binstub][exec_fname] = File.join(bin_path, exec_fname)
      end
    end
  end

  @opts[:binstub].each do |binstub_fname, binstub_file|
    src_binstub_file = create_binstub(binstub_fname, target_prefix_path)
    files[src_binstub_file] = binstub_file
  end unless @opts[:binstub].nil?

  files
end
add_ruby_build_dependencies!() click to toggle source
# File lib/packtory/packer.rb, line 305
def add_ruby_build_dependencies!
  unless @opts[:dependencies].include?('ruby-dev')
    @opts[:dependencies]['ruby-dev'] = @opts[:dependencies]['ruby']
  end

  unless @opts[:dependencies].include?('ruby-build')
    @opts[:dependencies]['ruby-build'] = @opts[:dependencies]['ruby']
  end

  @opts[:dependencies]
end
after_install_script_path() click to toggle source
# File lib/packtory/packer.rb, line 535
def after_install_script_path
  ftarget_path, _ = path_to_gathered_file(@files, Packtory.after_install_script_path)
  ftarget_path
end
architecture() click to toggle source
# File lib/packtory/packer.rb, line 241
def architecture
  @opts[:architecture]
end
author() click to toggle source
# File lib/packtory/packer.rb, line 222
def author
  gemspec.authors.join(', ')
end
autogenerate_clean_gemfile() click to toggle source
# File lib/packtory/packer.rb, line 152
    def autogenerate_clean_gemfile
      FileUtils.mkpath(working_path)

      gemfile_path = File.join(working_path, 'Gemfile')
      File.open(gemfile_path, 'w') do |f|
        gemfile_content = <<GEMFILE
source 'http://rubygems.org'
gemspec :path => '%s', :name => '%s'
GEMFILE

        gemfile_content = gemfile_content % [ File.dirname(@gemspec_file),
                                              File.basename(@gemspec_file, '.gemspec') ]
        f.write(gemfile_content)
      end

      Pathname.new(gemfile_path)
    end
build_file_map(target_prefix_path, package_path = nil) click to toggle source
# File lib/packtory/packer.rb, line 495
def build_file_map(target_prefix_path, package_path = nil)
  files = { }

  source_path = File.join(package_working_path, package_name, '/')
  target_path = (package_path || target_prefix_path) % package_name
  files[source_path] = target_path

  files
end
bundle_gems() click to toggle source
# File lib/packtory/packer.rb, line 255
def bundle_gems
  bgems = { }

  specs = bundler_definition.specs_for([ :default ])
  specs.each do |spec|
    next if gemspec.nil? || spec.name == gemspec.name

    if spec.name == 'bundler'
      if detect_bundler_include
        spec = @bundler_spec
      else
        next
      end
    end

    orig_spec = spec
    if spec.is_a?(Bundler::EndpointSpecification)
      rs = spec.instance_variable_get(:@remote_specification)
      if rs
        spec = rs
      elsif spec._local_specification
        spec = spec._local_specification
      end
    end

    bhash = { }

    bhash[:orig_spec] = orig_spec
    bhash[:spec] = spec
    bhash[:gem_path] = spec.full_gem_path

    bhash[:files] = Dir.glob(File.join(spec.full_gem_path, '**/*')).inject([ ]) { |a, f|
      unless File.directory?(f)
        a << f.gsub('%s/' % spec.full_gem_path, '')
      end

      a
    }.uniq

    bhash[:require_paths] = spec.full_require_paths.collect { |path|
      path.include?(bhash[:gem_path]) ?
        path.gsub(bhash[:gem_path], '') : nil
    }.compact.uniq

    bgems[spec.name] = bhash
  end

  bgems
end
bundle_working_path() click to toggle source
# File lib/packtory/packer.rb, line 194
def bundle_working_path
  @opts[:bundle_working_path] || File.join(working_path, 'bundle')
end
bundler_definition() click to toggle source
# File lib/packtory/packer.rb, line 72
def bundler_definition
  if defined?(@bundle_def)
    @bundle_def
  else
    ENV['BUNDLE_GEMFILE'] = @gemfile.to_s

    install_opts = { }
    install_opts[:with] = [ :default ]
    install_opts[:without] = [ :development, :test, :documentation ]
    install_opts[:path] = bundle_working_path
    install_opts[:retry] = 3
    install_opts[:jobs] = 3

    # in case, we are called multiple times
    Bundler.reset!

    if @opts[:bundler_silent]
      Bundler.ui = Bundler::UI::Silent.new
    else
      Bundler.ui = Bundler::UI::Shell.new
      Bundler.ui.info 'Bundling with: %s' % @gemfile.to_s
    end

    if @opts[:bundler_local]
      install_opts[:local] = true
    end

    self.class.silence_warnings do
      Bundler.settings.temporary(install_opts) do
        @bundle_def = ::Bundler.definition
        @bundle_def.validate_runtime!
      end

      Bundler.settings.temporary({ :no_install => true }.merge(install_opts)) do
        Bundler::Installer.install(Bundler.root, @bundle_def, install_opts)
      end
    end

    rubygems_dir = Bundler.rubygems.gem_dir
    FileUtils.mkpath(File.join(rubygems_dir, 'specifications'))

    cached_gems = { }
    @bundle_def.specs.each do |spec|
      next unless spec.source.is_a?(Bundler::Source::Rubygems)
      cached_gems[spec.name] = spec.source.send(:cached_gem, spec)
    end

    if detect_bundler_include
      bundler_source = Bundler::Source::Rubygems.new('remotes' => 'https://rubygems.org')

      @bundler_spec =
        Bundler::RemoteSpecification.new('bundler', Bundler::VERSION,
                                         Gem::Platform::RUBY, bundler_source.fetchers.first)

      @bundler_spec.remote = Bundler::Source::Rubygems::Remote.new(bundler_source.remotes.first)

      bundler_source.send(:fetch_gem, @bundler_spec)
      cached_gems['bundler'] = bundler_source.send(:cached_gem, @bundler_spec)
    end

    cached_gems.each do |gem_name, cached_gem|
      installer = Gem::Installer.at(cached_gem, :path => rubygems_dir)
      installer.extract_files
      installer.write_spec
    end

    @bundle_def
  end
end
create_binstub(binstub_fname, target_prefix_path) click to toggle source
# File lib/packtory/packer.rb, line 461
    def create_binstub(binstub_fname, target_prefix_path)
      binstub_code = <<CODE
#!/usr/bin/ruby

ENV['RUBY_PATH'] = '/usr/bin/ruby'

package_prefix = %s
require File.join(package_prefix, '%s')
load File.join(package_prefix, '%s')
CODE

      src_bin_path = File.join(package_working_path, 'bin', binstub_fname)
      FileUtils.mkpath(File.dirname(src_bin_path))

      if @opts[:install_prefix_as_code]
        target_path = @opts[:install_prefix_as_code] % package_name
      else
        target_path = '"%s"' % (target_prefix_path % package_name)
      end

      bundler_setup_path = File.join(BUNDLE_TARGET_PATH, BUNDLE_BUNDLER_SETUP_FILE)

      bindir_name = gemspec.nil? ? 'bin' : gemspec.bindir
      actual_bin_path = File.join(bindir_name, binstub_fname)

      File.open(src_bin_path, 'w') do |f|
        f.write(binstub_code % [ target_path, bundler_setup_path, actual_bin_path ])
      end

      FileUtils.chmod(0755, src_bin_path)

      src_bin_path
    end
description() click to toggle source
# File lib/packtory/packer.rb, line 214
def description
  gemspec.description.strip
end
detect_bundler_include() click to toggle source
# File lib/packtory/packer.rb, line 245
def detect_bundler_include
  if @opts[:bundler_include]
    true
  elsif !gemspec.dependencies.detect { |d| d.name == 'bundler' }.nil?
    true
  else
    false
  end
end
find_default_gemspec_file() click to toggle source
# File lib/packtory/packer.rb, line 50
def find_default_gemspec_file
  files = [ ]
  try_paths = [ ]

  unless @gemfile.nil?
    try_paths << @gemfile.untaint.expand_path.parent.to_s
  end

  try_paths << root_path

  try_paths.detect do |tpath|
    files.concat(Dir.glob(File.join(tpath, '{,*}.gemspec')))
    files.count > 0
  end

  unless files.empty?
    File.expand_path(files.first)
  else
    nil
  end
end
for_each_bundle_gems() { |gem_name, bhash, rpaths| ... } click to toggle source
# File lib/packtory/packer.rb, line 361
def for_each_bundle_gems(&block)
  bgems = bundle_gems
  bgems.each do |gem_name, bhash|
    src_paths = bhash[:require_paths]
    if src_paths.count > 0
      rpaths = src_paths.dup
    else
      rpaths = [ '/lib' ]
    end

    yield(gem_name, bhash, rpaths)
  end
end
gather_files() click to toggle source
# File lib/packtory/packer.rb, line 375
def gather_files
  prefix_path = File.join(package_working_path, package_name)

  if File.exists?(prefix_path)
    FileUtils.rm_r(prefix_path)
  end

  FileUtils.mkpath(prefix_path)

  files = gather_files_for_package
  files.each do |fsrc, ftarget|
    if fsrc =~ /^\//
      fsrc_path = fsrc
    else
      fsrc_path = File.join(root_path, fsrc)
    end

    ftarget_path, tvalues = path_to_gathered_file(files, fsrc)

    FileUtils.mkpath(File.dirname(ftarget_path))
    FileUtils.cp_r(fsrc_path, ftarget_path)

    if ftarget.is_a?(Hash)
      tf = TemplateFile.new(self, ftarget_path, tvalues)
      tf.evaluate!
    end

    ftarget_path
  end

  files
end
gather_files_for_package() click to toggle source
# File lib/packtory/packer.rb, line 317
def gather_files_for_package
  files = { }

  unless gemspec.nil?
    (gemspec.files - gemspec.test_files).each do |fname|
      next if File.directory?(fname)
      fname = fname.gsub('%s/' % gemspec.full_gem_path, '')
      files[fname] = fname
    end
  end

  bgems = bundle_gems
  bgems.each do |gem_name, bhash|
    bhash[:files].each do |file|
      src_full_path = File.join(bhash[:gem_path], file)
      files[src_full_path] = File.join(BUNDLE_TARGET_PATH, gem_name, file)
    end

    unless bhash[:spec].extensions.empty?
      add_ruby_build_dependencies!
      files[bhash[:orig_spec].loaded_from] = File.join(BUNDLE_EXTENSIONS_PATH, '%s.gemspec' % gem_name)
    end
  end

  files = gather_packtory_tools_for_package(files)
  files[Packtory.bundler_setup_path] = { :target_path => File.join(BUNDLE_TARGET_PATH, BUNDLE_BUNDLER_SETUP_FILE) }

  files
end
gather_packtory_tools_for_package(files) click to toggle source
# File lib/packtory/packer.rb, line 347
def gather_packtory_tools_for_package(files)
  target_tools_path = File.join(BUNDLE_PACKTORY_TOOLS_PATH)

  gem_build_extensions_path = Packtory.gem_build_extensions_path
  files[gem_build_extensions_path] = File.join(target_tools_path, File.basename(gem_build_extensions_path))

  after_install_script_path = Packtory.after_install_script_path
  files[after_install_script_path] = { :target_path => File.join(target_tools_path,
                                                                 File.basename(after_install_script_path)),
                                       :values => { 'pg_PACKAGE_PATH' => '$(dirname "$this_dir")' } }

  files
end
gemspec() click to toggle source
# File lib/packtory/packer.rb, line 142
def gemspec
  if defined?(@spec)
    @spec
  elsif !@gemspec_file.nil?
    @spec = Gem::Specification.load(@gemspec_file)
  else
    @spec = nil
  end
end
homepage() click to toggle source
# File lib/packtory/packer.rb, line 218
def homepage
  gemspec.homepage
end
license() click to toggle source
# File lib/packtory/packer.rb, line 226
def license
  gemspec.license
end
maintainer() click to toggle source
# File lib/packtory/packer.rb, line 230
def maintainer
  case gemspec.email
  when Array
    gemspec.email.first
  when String
    gemspec.email
  else
    nil
  end
end
package_name() click to toggle source
# File lib/packtory/packer.rb, line 202
def package_name
  if @opts[:package_name].nil?
    gemspec.name
  else
    @opts[:package_name]
  end
end
package_working_path() click to toggle source
# File lib/packtory/packer.rb, line 198
def package_working_path
  File.join(working_path, 'package')
end
path_to_gathered_file(files, fkey) click to toggle source
# File lib/packtory/packer.rb, line 408
def path_to_gathered_file(files, fkey)
  prefix_path = File.join(package_working_path, package_name)

  ftarget = files[fkey]
  ftarget_path = nil
  tvalues = nil

  case ftarget
  when String
    ftarget_path = File.join(prefix_path, ftarget)
  when Hash
    ftarget_path = File.join(prefix_path, ftarget[:target_path])
    tvalues = ftarget[:values]
  end

  [ ftarget_path, tvalues ]
end
pkg_path() click to toggle source
# File lib/packtory/packer.rb, line 178
def pkg_path
  if @opts[:pkg_path].nil?
    File.join(root_path, 'pkg')
  else
    @opts[:pkg_path]
  end
end
prepare_files(target_prefix_path, package_path = nil) click to toggle source
# File lib/packtory/packer.rb, line 526
def prepare_files(target_prefix_path, package_path = nil)
  @files = gather_files

  sfiles_map = build_file_map(target_prefix_path, package_path)
  sfiles_map = add_bin_files(sfiles_map, target_prefix_path, package_path)

  sfiles_map
end
root_path() click to toggle source
# File lib/packtory/packer.rb, line 170
def root_path
  if @opts[:path].nil?
    File.expand_path('./')
  else
    @opts[:path]
  end
end
template_scripts_values() click to toggle source
# File lib/packtory/packer.rb, line 540
def template_scripts_values
  { }
end
version() click to toggle source
# File lib/packtory/packer.rb, line 210
def version
  gemspec.version
end
working_path() click to toggle source
# File lib/packtory/packer.rb, line 186
def working_path
  if @opts[:working_path].nil?
    File.join(root_path, 'tmp/packtory_wp')
  else
    @opts[:working_path]
  end
end