lib/autobuild/importer.rb in autobuild-1.10.0.rc13 vs lib/autobuild/importer.rb in autobuild-1.10.0.rc14
- old
+ new
@@ -148,10 +148,11 @@
@options = options.dup
@options[:retry_count] = Integer(@options[:retry_count] || 0)
@repository_id = options[:repository_id] || "#{self.class.name}:#{object_id}"
@interactive = options[:interactive]
@source_id = options[:source_id] || @repository_id
+ @post_hooks = Array.new
end
# Returns a string that identifies the remote repository uniquely
#
# This can be used to check whether two importers are pointing to the same
@@ -234,24 +235,81 @@
if retry_count <= self.retry_count
retry_count
end
end
+ # A list of hooks that are called after a successful checkout or update
+ #
+ # They are added either at the instance level with {#add_post_hook} or
+ # globally for all importers of a given type with {Importer.add_post_hook}
+ attr_reader :post_hooks
+
+ # Define a post-import hook for all instances of this class
+ #
+ # @yieldparam [Importer] importer the importer that finished
+ # @yieldparam [Package] package the package we're acting on
+ # @see Importer#add_post_hook
+ def self.add_post_hook(&hook)
+ @post_hooks ||= Array.new
+ @post_hooks << hook
+ end
+
+ # Enumerate the post-import hooks defined for all instances of this class
+ def self.each_post_hook(&hook)
+ (@post_hooks || Array.new).each(&hook)
+ end
+
+ # @api private
+ #
+ # Call the post-import hooks added with {#add_post_hook}
+ def execute_post_hooks(package)
+ self.class.each_post_hook do |hook|
+ hook.call(self, package)
+ end
+ each_post_hook.each do |block|
+ block.call(self, package)
+ end
+ end
+
+ # Add a block that should be called when the import has successfully
+ # finished
+ #
+ # @yieldparam [Importer] importer the importer that finished
+ # @yieldparam [Package] package the package we're acting on
+ # @see Importer.add_post_hook
+ def add_post_hook(&hook)
+ post_hooks << hook
+ end
+
+ # Enumerate the post-import hooks for this importer
+ def each_post_hook(&hook)
+ return enum_for(__method__) if !block_given?
+
+ self.class.each_post_hook(&hook)
+ post_hooks.each(&hook)
+ end
+
def perform_update(package,only_local=false)
cur_patches = currently_applied_patches(package)
needed_patches = self.patches
if cur_patches.map(&:last) != needed_patches.map(&:last)
patch(package, [])
end
+ last_error = nil
retry_count = 0
package.progress_start "updating %s"
begin
update(package,only_local)
+ execute_post_hooks(package)
rescue Interrupt
- raise
+ if last_error
+ raise last_error
+ else raise
+ end
rescue ::Exception => original_error
+ last_error = 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
@@ -286,16 +344,21 @@
rescue Autobuild::Exception => e
fallback(e, package, :import, package)
end
def perform_checkout(package, options = Hash.new)
+ last_error = nil
package.progress_start "checking out %s", :done_message => 'checked out %s' do
retry_count = 0
begin
checkout(package, options)
+ execute_post_hooks(package)
rescue Interrupt
- raise
+ if last_error then raise last_error
+ else raise
+ end
rescue ::Exception => original_error
+ last_error = original_error
retry_count = update_retry_count(original_error, retry_count)
if !retry_count
raise
end
package.message "checkout of %s failed, deleting the source directory #{package.importdir} and retrying (#{retry_count}/#{self.retry_count})"