class Autobuild::Importer

Attributes

fallback_handlers[R]

The set of handlers registered by ::fallback

Public Class Methods

Autobuild::Importer.fallback { |package, importer| ... } click to toggle source

If called, registers the given block as a fallback mechanism for failing imports.

Fallbacks are tried in reverse order with the failing importer object as argument. The first valid importer object that has been returned will be used instead.

It is the responsibility of the fallback handler to make sure that it does not do infinite recursions and stuff like that.

# File lib/autobuild/importer.rb, line 21
def self.fallback(&block)
    @fallback_handlers.unshift(block)
end
new(options) click to toggle source

Creates a new Importer object. The options known to Importer are:

:patches

a list of patch to apply after import

More options are specific to each importer type.

# File lib/autobuild/importer.rb, line 68
def initialize(options)
    @options = options.dup
end

Public Instance Methods

fallback(error, package, *args, &block) click to toggle source

Tries to find a fallback importer because of the given error.

# File lib/autobuild/importer.rb, line 223
def fallback(error, package, *args, &block)
    Importer.fallback_handlers.each do |handler|
        fallback_importer = handler.call(package, self)
        if fallback_importer.kind_of?(Importer)
            begin
                return fallback_importer.send(*args, &block)
            rescue Exception
                raise error
            end
        end
    end
    raise error
end
import(package) click to toggle source

Performs the import of package

# File lib/autobuild/importer.rb, line 201
def import(package)
    srcdir = package.srcdir
    if File.directory?(srcdir)
        package.isolate_errors(false) do
            if Autobuild.do_update
                perform_update(package)
            else
                if Autobuild.verbose
                    package.message "%s: not updating"
                end
                return
            end
        end

    elsif File.exists?(srcdir)
        raise ConfigException.new(package, 'import'), "#{srcdir} exists but is not a directory"
    else
        perform_checkout(package)
    end
end
patches() click to toggle source
# File lib/autobuild/importer.rb, line 89
def patches
    patches =
        if @options[:patches].respond_to?(:to_ary)
            @options[:patches]
        elsif !@options[:patches]
            []
        else
            [[@options[:patches], 0]]
        end

    if patches.size == 2 && patches[0].respond_to?(:to_str) && patches[1].respond_to?(:to_int)
        patches = [patches]
    else
        patches.map do |obj|
            if obj.respond_to?(:to_str)
                [obj, 0]
            elsif obj.respond_to?(:to_ary)
                obj
            else
                raise Arguments, "wrong patch specification #{obj.inspect}"
                obj
            end
        end
    end
end
perform_checkout(package) click to toggle source
# File lib/autobuild/importer.rb, line 169
def perform_checkout(package)
    package.progress_start "checking out %s", :done_message => 'checked out %s' do
        retry_count = 0
        begin
            checkout(package)
        rescue Interrupt
            raise
        rescue ::Exception
            retry_count += 1
            if retry_count > self.retry_count
                raise
            end
            package.message "checkout of %s failed, deleting the source directory #{package.srcdir} and retrying (#{retry_count}/#{self.retry_count})"
            FileUtils.rm_rf package.srcdir
            retry
        end
    end

    patch(package)
    package.updated = true
rescue Interrupt
    raise
rescue ::Exception
    package.message "checkout of %s failed, deleting the source directory #{package.srcdir}"
    FileUtils.rm_rf package.srcdir
    raise
rescue Autobuild::Exception => e
    FileUtils.rm_rf package.srcdir
    fallback(e, package, :import, package)
end
perform_update(package) click to toggle source
# File lib/autobuild/importer.rb, line 115
def perform_update(package)
    cur_patches = currently_applied_patches(package)
    needed_patches = self.patches
    kept_patches = (cur_patches & needed_patches)
    if kept_patches != cur_patches
        patch(package, kept_patches)
    end

    retry_count = 0
    package.progress_start "updating %s"
    begin
        update(package)
    rescue Interrupt
        raise
    rescue ::Exception => original_error
        # If the package is patched, it might be that the update
        # failed because we needed to unpatch first. Try it out
        #
        # This assumes that importing data with conflict will
        # make the import fail, but not make the patch
        # un-appliable. Importers that do not follow this rule
        # will have to unpatch by themselves.
        cur_patches = currently_applied_patches(package)
        if !cur_patches.empty?
            package.progress_done
            package.message "update failed and some patches are applied, retrying after removing all patches first"
            begin
                patch(package, [])
                return perform_update(package)
            rescue Interrupt
                raise
            rescue ::Exception
                raise original_error
            end
        end

        retry_count += 1
        if retry_count > self.retry_count
            raise
        end
        package.message "update failed in #{package.srcdir}, retrying (#{retry_count}/#{self.retry_count})"
        retry
    ensure
        package.progress_done "updated %s"
    end

    patch(package)
    package.updated = true
rescue Interrupt
    raise
rescue Autobuild::Exception => e
    fallback(e, package, :import, package)
end
retry_count() click to toggle source

The number of times update / checkout should be retried before giving up. The default is 0 (do not retry)

Set either with retry_count= or by setting the :retry_count option when constructing this importer

# File lib/autobuild/importer.rb, line 77
def retry_count
    @options[:retry_count] || 0
end
retry_count=(count) click to toggle source

Sets the number of times update / checkout should be retried before giving up. 0 (the default) disables retrying.

See also retry_count

# File lib/autobuild/importer.rb, line 85
def retry_count=(count)
    @options[:retry_count] = count
end