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