lib/autobuild/importer.rb in autobuild-1.8.3 vs lib/autobuild/importer.rb in autobuild-1.9.0.b1

- old
+ new

@@ -51,12 +51,12 @@ attr_accessor :remote_commits # An array of strings that represent commits that are in the local # repository and not in the remote one (would be pushed by an update) attr_accessor :local_commits - def initialize - @status = -1 + def initialize(status = -1) + @status = status @uncommitted_code = false @remote_commits = Array.new @local_commits = Array.new end end @@ -139,10 +139,22 @@ patches.map do |path, level| [path, level, File.read(path)] end end + def update_retry_count(original_error, retry_count) + if !original_error.respond_to?(:retry?) || + !original_error.retry? + return + end + + retry_count += 1 + if retry_count <= self.retry_count + retry_count + end + 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, []) @@ -174,14 +186,12 @@ rescue ::Exception raise original_error end end - retry_count += 1 - if retry_count > self.retry_count - raise - end + retry_count = update_retry_count(original_error, retry_count) + raise if !retry_count package.message "update failed in #{package.importdir}, retrying (#{retry_count}/#{self.retry_count})" retry ensure package.progress_done "updated %s" end @@ -199,13 +209,13 @@ retry_count = 0 begin checkout(package) rescue Interrupt raise - rescue ::Exception - retry_count += 1 - if retry_count > self.retry_count + rescue ::Exception => 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})" FileUtils.rm_rf package.importdir retry @@ -223,26 +233,56 @@ rescue Autobuild::Exception => e FileUtils.rm_rf package.importdir fallback(e, package, :import, package) end - # Performs the import of +package+ - def import(package,only_local = false) + # Imports the given package + # + # The importer will checkout or update code in package.importdir. No update + # will be done if {update?} returns false. + # + # @raises ConfigException if package.importdir exists and is not a directory + # + # @option options [Boolean] :only_local (false) if true, will only perform + # actions that do not require network access. Importers that do not + # support this mode will simply do nothing + # @option options [Boolean] :reset (false) if true, the importer's + # configuration is interpreted as a hard state in which it should put the + # working copy. Otherwise, it tries to update the local repository with + # the remote information. For instance, a git importer for which a commit + # ID is given will, in this mode, reset the repository to the requested ID + # (if that does not involve losing commits). Otherwise, it will only + # ensure that the requested commit ID is present in the current HEAD. + def import(package, options = Hash.new) + # Backward compatibility + if !options.kind_of?(Hash) + options = !!options + Autoproj.warn "calling #import with a boolean as second argument is deprecated, switch to the named argument interface instead" + Autoproj.warn " e.g. call import(package, only_local: #{options})" + Autoproj.warn " #{caller(1).first}" + options = Hash[only_local: !!options] + end + + options = Kernel.validate_options options, + only_local: false, + reset: false, + checkout_only: false + importdir = package.importdir if File.directory?(importdir) package.isolate_errors(false) do - if package.update? - perform_update(package,only_local) + if !options[:checkout_only] && package.update? + perform_update(package, options) else if Autobuild.verbose package.message "%s: not updating" end return end end - elsif File.exists?(importdir) + elsif File.exist?(importdir) raise ConfigException.new(package, 'import'), "#{importdir} exists but is not a directory" else perform_checkout(package) end end @@ -273,42 +313,41 @@ def patchlist(package) File.join(patchdir(package), "list") end def call_patch(package, reverse, file, patch_level) - patch = Autobuild.tool('patch') - Dir.chdir(package.importdir) do - Subprocess.run(package, :patch, patch, "-p#{patch_level}", (reverse ? '-R' : nil), '--forward', :input => file) - end + package.run(:patch, Autobuild.tool('patch'), + "-p#{patch_level}", (reverse ? '-R' : nil), '--forward', input: file, + working_directory: package.importdir) end def apply(package, path, patch_level = 0); call_patch(package, false, path, patch_level) end def unapply(package, path, patch_level = 0); call_patch(package, true, path, patch_level) end - def parse_patch_list(patches_file) + def parse_patch_list(package, patches_file) File.readlines(patches_file).map do |line| line = line.rstrip if line =~ /^(.*)\s+(\d+)$/ - path = $1 + path = File.expand_path($1, package.srcdir) level = Integer($2) else - path = line + path = File.expand_path(line, package.srcdir) level = 0 end [path, level, File.read(path)] end end def currently_applied_patches(package) patches_file = patchlist(package) - if File.exists?(patches_file) - return parse_patch_list(patches_file) + if File.exist?(patches_file) + return parse_patch_list(package, patches_file) end patches_file = File.join(package.importdir, "patches-autobuild-stamp") - if File.exists?(patches_file) - cur_patches = parse_patch_list(patches_file) + if File.exist?(patches_file) + cur_patches = parse_patch_list(package, patches_file) save_patch_state(package, cur_patches) FileUtils.rm_f patches_file return currently_applied_patches(package) end @@ -317,11 +356,13 @@ def patch(package, patches = self.patches) # Get the list of already applied patches cur_patches = currently_applied_patches(package) - if cur_patches.map(&:last) == patches.map(&:last) + cur_patches_state = cur_patches.map { |_, level, content| [level, content] } + patches_state = patches.map { |_, level, content| [level, content] } + if cur_patches_state == patches_state return false end # Do not be smart, remove all already applied patches # and then apply the new ones @@ -340,13 +381,13 @@ p, level, _ = *p unapply(package, p, level) cur_patches.pop end - patches.to_a.each do |p, level, content| - apply(package, p, level) - cur_patches << [p, level, content] + patches.to_a.each do |new_patch, new_patch_level, content| + apply(package, new_patch, new_patch_level) + cur_patches << [new_patch, new_patch_level, content] end ensure save_patch_state(package, cur_patches) end @@ -355,17 +396,21 @@ def save_patch_state(package, cur_patches) patch_dir = patchdir(package) FileUtils.mkdir_p patch_dir cur_patches = cur_patches.each_with_index.map do |(path, level, content), idx| - path = File.join(patch_dir, idx.to_s) - File.open(path, 'w') do |patch_io| - patch_io.write content + path = File.join(patch_dir, idx.to_s) + File.open(path, 'w') do |patch_io| + patch_io.write content + end + [path, level] end - [path, level] - end File.open(patchlist(package), 'w') do |f| - f.write(cur_patches.map { |p, l| "#{p} #{l}" }.join("\n")) + patch_state = cur_patches.map do |path, level| + path = Pathname.new(path).relative_path_from( Pathname.new(package.srcdir) ).to_s + "#{path} #{level}" + end + f.write(patch_state.join("\n")) end end def supports_relocation?; false end end