lib/rim/upload_module_helper.rb in esr-rim-1.4.0 vs lib/rim/upload_module_helper.rb in esr-rim-1.4.2
- old
+ new
@@ -1,162 +1,163 @@
-require 'rim/module_helper'
-require 'rim/rim_info'
-require 'rim/file_helper'
-require 'rim/dirty_check'
-require 'rim/status_builder'
-require 'tempfile'
-
-module RIM
-
-class UploadModuleHelper < ModuleHelper
-
- def initialize(workspace_root, module_info, review, logger)
- super(workspace_root, module_info, logger)
- @review = review
- end
-
- # do the module uploads for revisions given by sha
- def upload(parent, sha1s)
- upload_module_changes(parent, sha1s)
- end
-
-private
-
- # upload the content of the module
- def upload_module_changes(parent_sha1, sha1s)
- remote_path = fetch_module
- # search for the first revision that is not
- tmp_git_path = clone_or_fetch_repository(remote_path, module_tmp_git_path(@remote_path))
- RIM::git_session(tmp_git_path) do |dest|
- local_branch = nil
- remote_branch = nil
- infos = nil
- if @module_info.subdir
- dest_path = File.join([tmp_git_path] + @module_info.subdir.split("/"))
- else
- dest_path = tmp_git_path
- end
- RIM::git_session(@ws_root) do |src|
- infos = get_branches_and_revision_infos(src, dest, parent_sha1, sha1s)
- if infos.branches.size == 1
- remote_branch = infos.branches[0]
- if dest.has_remote_branch?(remote_branch)
- infos.rev_infos.each do |rev_info|
- local_branch = create_update_branch(dest, infos.parent_sha1, rev_info.src_sha1) if !local_branch
- copy_revision_files(
- src,
- rev_info.src_sha1,
- dest_path,
- rev_info.rim_info.ignores
- )
- commit_changes(dest, local_branch, rev_info.src_sha1, rev_info.message)
- end
- else
- raise RimException.new("The target revision '#{@module_info.target_revision}' of module #{@module_info.local_path} is not a branch. No push can be performed.")
- end
- elsif infos.branches.size > 1
- raise RimException.new("There are commits for module #{@module_info.local_path} on multiple target revisions (#{infos.branches.join(", ")}).")
- end
- end
- # Finally we're done. Push the changes
- if local_branch && dest.rev_sha1(local_branch) != infos.parent_sha1
- push_branch = @review && @module_info.remote_branch_format && !@module_info.remote_branch_format.empty? \
- ? @module_info.remote_branch_format % remote_branch : remote_branch
- dest.execute("git push #{@remote_url} #{local_branch}:#{push_branch}")
- dest.execute("git checkout --detach #{local_branch}")
- dest.execute("git branch -D #{local_branch}")
- @logger.info("Commited changes for module #{@module_info.local_path} to remote branch #{push_branch}.")
- else
- @logger.info("No changes to module #{@module_info.local_path}.")
- end
- end
- end
-
- # search backwards for all revision infos
- def get_branches_and_revision_infos(src_session, dest_session, parent_sha1, sha1s)
- infos = []
- branches = []
- dest_parent_sha1 = nil
- (sha1s.size() - 1).step(0, -1) do |i|
- info = get_revision_info(src_session, dest_session, sha1s[i])
- if !info.dest_sha1 && info.rim_info.target_revision
- infos.unshift(info)
- branches.push(info.rim_info.target_revision) if !branches.include?(info.rim_info.target_revision)
- else
- dest_parent_sha1 = info.dest_sha1
- break
- end
- end
- dest_parent_sha1 = get_riminfo_for_revision(src_session, parent_sha1).revision_sha1 if !dest_parent_sha1
- dest_parent_sha1 = infos.first.rim_info.revision_sha1 if !dest_parent_sha1 && !infos.empty?
- return Struct.new(:branches, :parent_sha1, :rev_infos).new(branches, dest_parent_sha1, infos)
- end
-
- RevisionInfo = Struct.new(:dest_sha1, :src_sha1, :rim_info, :message)
-
- # collect infos for a revision
- def get_revision_info(src_session, dest_session, src_sha1)
- module_status = StatusBuilder.new.rev_module_status(src_session, src_sha1, @module_info.local_path)
- rim_info = get_riminfo_for_revision(src_session, src_sha1)
- dest_sha1 = dest_session.rev_sha1("rim-#{src_sha1}")
- msg = src_session.execute("git show -s --format=%B #{src_sha1}")
- RevisionInfo.new(module_status && module_status.dirty? ? dest_sha1 : rim_info.revision_sha1, src_sha1, rim_info, msg)
- end
-
- # commit changes to session
- def commit_changes(session, branch, sha1, msg)
- if session.status.lines.any?
- # add before commit because the path can be below a not yet added path
- session.execute("git add --all")
- msg_file = Tempfile.new('message')
- begin
- msg_file << msg
- msg_file.close
- session.execute("git commit -F #{msg_file.path}")
- ensure
- msg_file.close(true)
- end
- # create tag
- session.execute("git tag rim-#{sha1} refs/heads/#{branch}")
- end
- end
-
- # get target revision for this module for workspace revision
- def get_riminfo_for_revision(session, sha1)
- session.execute("git show #{sha1}:#{File.join(@module_info.local_path, RimInfo::InfoFileName)}") do |out, e|
- return RimInfo.from_s(!e ? out : "")
- end
- end
-
- # create update branch for given revision
- def create_update_branch(session, dest_sha1, src_sha1)
- branch = "rim/#{src_sha1}"
- session.execute("git checkout -B #{branch} #{dest_sha1}")
- branch
- end
-
- # copy files from given source revision into destination dir
- def copy_revision_files(src_session, src_sha1, dest_dir, ignores)
- Dir.mktmpdir do |tmp_dir|
- src_session.execute("git archive --format tar #{src_sha1} #{@module_info.local_path} | tar -x -C #{tmp_dir}")
- tmp_module_dir = File.join(tmp_dir, @module_info.local_path)
- files = FileHelper.find_matching_files(tmp_module_dir, false, "/**/*", File::FNM_DOTMATCH)
- files.delete(".")
- files.delete("..")
- files.delete(RimInfo::InfoFileName)
- files -= FileHelper.find_matching_files(tmp_module_dir, false, ignores)
- # have source files now. Now clear destination folder and copy
- prepare_empty_folder(dest_dir, ".git/**/*")
- files.each do |f|
- src_path = File.join(tmp_module_dir, f)
- if File.file?(src_path)
- path = File.join(dest_dir, f)
- FileUtils.mkdir_p(File.dirname(path))
- FileUtils.cp(src_path, path)
- end
- end
- end
- end
-
-end
-
-end
+require 'rim/module_helper'
+require 'rim/rim_info'
+require 'rim/file_helper'
+require 'rim/dirty_check'
+require 'rim/status_builder'
+require 'tempfile'
+
+module RIM
+
+class UploadModuleHelper < ModuleHelper
+
+ def initialize(workspace_root, module_info, review, logger)
+ super(workspace_root, module_info, logger)
+ @review = review
+ end
+
+ # do the module uploads for revisions given by sha
+ def upload(parent, sha1s)
+ upload_module_changes(parent, sha1s)
+ end
+
+private
+
+ # upload the content of the module
+ def upload_module_changes(parent_sha1, sha1s)
+ remote_path = fetch_module
+ # search for the first revision that is not
+ tmp_git_path = clone_or_fetch_repository(remote_path, module_tmp_git_path(@remote_path))
+ RIM::git_session(tmp_git_path) do |dest|
+ local_branch = nil
+ remote_branch = nil
+ infos = nil
+ if @module_info.subdir
+ dest_path = File.join([tmp_git_path] + @module_info.subdir.split("/"))
+ else
+ dest_path = tmp_git_path
+ end
+ RIM::git_session(@ws_root) do |src|
+ infos = get_branches_and_revision_infos(src, dest, parent_sha1, sha1s)
+ if infos.branches.size == 1
+ remote_branch = infos.branches[0]
+ if dest.has_remote_branch?(remote_branch)
+ infos.rev_infos.each do |rev_info|
+ local_branch = create_update_branch(dest, infos.parent_sha1, rev_info.src_sha1) if !local_branch
+ copy_revision_files(
+ src,
+ rev_info.src_sha1,
+ dest_path,
+ rev_info.rim_info.ignores
+ )
+ commit_changes(dest, local_branch, rev_info.src_sha1, rev_info.message)
+ end
+ else
+ raise RimException.new("The target revision '#{@module_info.target_revision}' of module #{@module_info.local_path} is not a branch. No push can be performed.")
+ end
+ elsif infos.branches.size > 1
+ raise RimException.new("There are commits for module #{@module_info.local_path} on multiple target revisions (#{infos.branches.join(", ")}).")
+ end
+ end
+ # Finally we're done. Push the changes
+ if local_branch && dest.rev_sha1(local_branch) != infos.parent_sha1
+ push_branch = @review && @module_info.remote_branch_format && !@module_info.remote_branch_format.empty? \
+ ? @module_info.remote_branch_format % remote_branch : remote_branch
+ dest.execute("git push #{@remote_url} #{local_branch}:#{push_branch}")
+ dest.execute("git checkout --detach #{local_branch}")
+ dest.execute("git branch -D #{local_branch}")
+ @logger.info("Commited changes for module #{@module_info.local_path} to remote branch #{push_branch}.")
+ else
+ @logger.info("No changes to module #{@module_info.local_path}.")
+ end
+ end
+ end
+
+ # search backwards for all revision infos
+ def get_branches_and_revision_infos(src_session, dest_session, parent_sha1, sha1s)
+ infos = []
+ branches = []
+ dest_parent_sha1 = nil
+ (sha1s.size() - 1).step(0, -1) do |i|
+ info = get_revision_info(src_session, dest_session, sha1s[i])
+ if !info.dest_sha1 && info.rim_info.target_revision
+ infos.unshift(info)
+ branches.push(info.rim_info.target_revision) if !branches.include?(info.rim_info.target_revision)
+ else
+ dest_parent_sha1 = info.dest_sha1
+ break
+ end
+ end
+ dest_parent_sha1 = get_riminfo_for_revision(src_session, parent_sha1).revision_sha1 if !dest_parent_sha1
+ dest_parent_sha1 = infos.first.rim_info.revision_sha1 if !dest_parent_sha1 && !infos.empty?
+ return Struct.new(:branches, :parent_sha1, :rev_infos).new(branches, dest_parent_sha1, infos)
+ end
+
+ RevisionInfo = Struct.new(:dest_sha1, :src_sha1, :rim_info, :message)
+
+ # collect infos for a revision
+ def get_revision_info(src_session, dest_session, src_sha1)
+ module_status = StatusBuilder.new.rev_module_status(src_session, src_sha1, @module_info.local_path)
+ rim_info = get_riminfo_for_revision(src_session, src_sha1)
+ dest_sha1 = dest_session.rev_sha1("rim-#{src_sha1}")
+ msg = src_session.execute("git show -s --format=%B #{src_sha1}")
+ RevisionInfo.new(module_status && module_status.dirty? ? dest_sha1 : rim_info.revision_sha1, src_sha1, rim_info, msg)
+ end
+
+ # commit changes to session
+ def commit_changes(session, branch, sha1, msg)
+ if session.status.lines.any?
+ # add before commit because the path can be below a not yet added path
+ session.execute("git add --all")
+ msg_file = Tempfile.new('message')
+ begin
+ msg_file << msg
+ msg_file.close
+ session.execute("git commit -F #{msg_file.path}")
+ ensure
+ msg_file.close(true)
+ end
+ # create tag
+ session.execute("git tag rim-#{sha1} refs/heads/#{branch}")
+ end
+ end
+
+ # get target revision for this module for workspace revision
+ def get_riminfo_for_revision(session, sha1)
+ session.execute("git show #{sha1}:#{File.join(@module_info.local_path, RimInfo::InfoFileName)}") do |out, e|
+ return RimInfo.from_s(!e ? out : "")
+ end
+ end
+
+ # create update branch for given revision
+ def create_update_branch(session, dest_sha1, src_sha1)
+ branch = "rim/#{src_sha1}"
+ session.execute("git checkout -B #{branch} #{dest_sha1}")
+ branch
+ end
+
+ # copy files from given source revision into destination dir
+ def copy_revision_files(src_session, src_sha1, dest_dir, ignores)
+ Dir.mktmpdir do |tmp_dir|
+ tmp_dir = Dir.glob(tmp_dir)[0]
+ src_session.execute("git archive --format tar #{src_sha1} #{@module_info.local_path} | tar -C #{tmp_dir} -xf -")
+ tmp_module_dir = File.join(tmp_dir, @module_info.local_path)
+ files = FileHelper.find_matching_files(tmp_module_dir, false, "/**/*", File::FNM_DOTMATCH)
+ files.delete(".")
+ files.delete("..")
+ files.delete(RimInfo::InfoFileName)
+ files -= FileHelper.find_matching_files(tmp_module_dir, false, ignores)
+ # have source files now. Now clear destination folder and copy
+ prepare_empty_folder(dest_dir, ".git/**/*")
+ files.each do |f|
+ src_path = File.join(tmp_module_dir, f)
+ if File.file?(src_path)
+ path = File.join(dest_dir, f)
+ FileUtils.mkdir_p(File.dirname(path))
+ FileUtils.cp(src_path, path)
+ end
+ end
+ end
+ end
+
+end
+
+end