示例#1
0
class AutoMaster: 

	def __init__(self):
		self.__git = GitEngine()
		self.__jira = JiraEngine()
		self.__note = NotifyEngine()
		self.__main_commiter = config.main_commiter
		self.__accept_branch = config.accept_branch

	def main(self):
		# run first phase
		self.__init_master_phase()
		issues = self.__get_jira_issues_phase()
		#debug second phase
		LOGGER.debug("Issues: %s" %issues)
		success_issues = []
		for (issue_key, issue_assignee) in issues:
			if self.__accept_issue_phase(issue_key, issue_assignee):
				LOGGER.debug("Accept issue: %s" % issue_key)
				success_issues.append(issue_key)
				if not config.is_bulk:
					break;
		LOGGER.debug("Success issues: %s" % success_issues)

		try:
			if success_issues:

				self.__git.push(config.repo_urls[self.__main_commiter], \
					self.__get_branches_name(MAIN_GIT)[1], \
					self.__accept_branch)

				for issue_key in success_issues:
					self.__jira.processWorkflow(issue_key, \
					config.jira_last_workflow)

		except GitEngineError:
			self.__note.notify(self.__main_commiter, "Push to server is Fail")
			LOGGER.error("Push is fail. Bulk = %s" % config.is_bulk)
		except:
			raise

		self.__send_notifications_phase()
		

	def __init_master_phase(self):
		LOGGER.debug("init phase")
		self.__get_changes(MAIN_GIT)

	def __get_jira_issues_phase(self):
		""" return list of tuples (issue key -> assignee) """
		return self.__jira.getIssuesKeyAndAssigneeByFilter(ACCEPT_TO_MASTER_FILTER)	

	def __accept_issue_phase(self, issue_key, issue_assignee):
		""" return true if task is accepted """
		LOGGER.debug("accept phase task: %s" % issue_key)
		holder_name = issue_assignee

		accept_branch = self.__get_changes(holder_name, issue_key)

		main_branch = self.__get_branches_name(MAIN_GIT)[1]		

		shas = self.__git.search(issue_key, main_branch, accept_branch)
		
		LOGGER.debug("Shas: %s" % shas)
	
		if not shas:
			self.__note.notify(holder_name, "Commits for task %s wasn't found in you default branch" % issue_key)
			LOGGER.error("Commits aren't found for task %s" % issue_key)
			return False
		# sort shas by commit time
		shas.sort(key = lambda commitInfo: int(commitInfo[1]))

		# checkout local master branch
		self.__git.checkout(main_branch)
					
		commit_count = 0
		try:

			for sha, commitTime in shas:
				self.__git.cherry_pick(sha)
				commit_count+=1

		except GitEngineError:
			# reset to master
			self.__git.reset("HEAD~%d" % commit_count, True)		
			self.__note.notify(holder_name, "Conflicts until cherry-pick of task %s" % issue_key)
			LOGGER.error("Cherry-pick conflict task %s" % issue_key)
			return False

		return True

	def __send_notifications_phase(self):
		LOGGER.debug("Send phase")
		self.__note.send()
	
	def __get_branches_name(self, holder_name, issue_key = None):
		""" return tuple of branches(remote,local) for holder"""
		checkout_point =  (holder_name, self.__get_branch(holder_name, issue_key)) 
		return ("%s/%s" % checkout_point, "%s_%s" % checkout_point)

	def __get_branch(self, holder_name, issue_key = None):
		branch_name = ""
		if issue_key is not None:
			branch_name = self.__jira.getFieldValue(issue_key, config.jira_branch_field)

		if branch_name == "":
			branch_name = config.def_branches[holder_name]

		return branch_name

	def __get_changes(self, holder_name, issue_key = None):
		self.__git.fetch(config.repo_urls[holder_name], holder_name)
		
		(remote_branch, local_branch) = self.__get_branches_name(holder_name, issue_key)
		try:
			self.__git.checkout(remote_branch, local_branch)
		except GitEngineError:	
			# It means that the branch exists
			# And we need to checkout the branch and reset it to fetched branch with --hard
			self.__git.checkout(local_branch)
			self.__git.reset(remote_branch, True)

		return local_branch