def async_comment_to_pr(data): ''' commit comment rewrite to pr ''' type_ = data.get('type') if type_ not in ('commit_comment', 'commit_linecomment'): return comment = data.get('comment') ref = comment.get('ref') author = comment.get('author') content = comment.get('content') proj_id = comment.get('project_id') comment_uid = comment.get('comment_uid') proj = CodeDoubanProject.get(proj_id) prs = proj.open_family_pulls anchor = comment_uid for pr in prs: if ref in pr.get_commits_shas(): content = COMMENT_TEMPLATE.format(content=content, domain=DOMAIN, proj=proj.name, sha=ref, anchor=anchor) ticket = Ticket.get_by_projectid_and_ticketnumber( pr.to_proj.id, pr.ticket_id) ticket.add_comment(content, author)
def __init__(self, project_id, ticket_number, hl_description): self.ticket = Ticket.get_by_projectid_and_ticketnumber( project_id, ticket_number) self.ticket_project = CodeDoubanProject.get(self.ticket.project_id) self.author = User(self.ticket.author) self.ticket_url = self.ticket.url self.hl_description = hl_description if hl_description \ else self.ticket.description
def new(self, request): user = request.user if not user: raise AccessError from_proj = self.project from_ref = request.get_form_var('head_ref', from_proj.default_branch) parent_proj = from_proj.get_forked_from() to_proj = request.get_form_var('base_repo') if to_proj: to_proj = CodeDoubanProject.get_by_name(to_proj) elif parent_proj: to_proj = parent_proj else: to_proj = from_proj if not to_proj: raise TraversalError("The PR's upstream project is not existed") to_ref = request.get_form_var('base_ref', to_proj.default_branch) if from_proj != to_proj: # Allow to create PR to a different project only if user has push perm # ~~A bit weird, maybe should be separate perms # ~~If from and to projects are the same, we should be in online edit mode if not from_proj.has_push_perm(user.name): raise AccessError( "Need push permission to add a PR on another project") pullreq = PullRequest.open(from_proj, from_ref, to_proj, to_ref) family = from_proj.get_fork_network() from_branches = from_proj.repo.branches to_branches = to_proj.repo.branches from_commit = pullreq.from_commit to_commit = pullreq.to_commit if not pullreq.can_pull: raise TraversalError( "The PR's head_ref or base_ref is not existed") highlighted_projects = filter(None, [from_proj, parent_proj]) commits = pullreq.commits n_commits = len(commits) n_authors = len(set(c.author.username for c in commits)) ticket_title, ticket_desc = self._choose_default_PR_title_and_description( commits) # noqa # get diff diff = pullreq.get_diff(rename_detection=True) n_files = diff.length grouped_commits = groupby(commits, lambda c: c.author_time.date()) prs = PullRequest.get_by_from_and_to(from_proj.id, from_ref, to_proj.id, to_ref) open_pullreqs = [] for pr in prs: t = Ticket.get_by_projectid_and_ticketnumber( to_proj.id, pr.ticket_id) if t and t.closed is None: open_pullreqs.append(pr) guideline_url = get_project_guidelines(to_proj) teams = Team.get_all_team_uids() return st('/pull/new.html', **locals())
def new(self, request): user = request.user if not user: raise AccessError from_proj = self.project from_ref = request.get_form_var('head_ref', from_proj.default_branch) parent_proj = from_proj.get_forked_from() to_proj = request.get_form_var('base_repo') if to_proj: to_proj = CodeDoubanProject.get_by_name(to_proj) elif parent_proj: to_proj = parent_proj else: to_proj = from_proj if not to_proj: raise TraversalError("The PR's upstream project is not existed") to_ref = request.get_form_var('base_ref', to_proj.default_branch) if from_proj != to_proj: # Allow to create PR to a different project only if user has push perm # ~~A bit weird, maybe should be separate perms # ~~If from and to projects are the same, we should be in online edit mode if not from_proj.has_push_perm(user.name): raise AccessError( "Need push permission to add a PR on another project") pullreq = PullRequest.open(from_proj, from_ref, to_proj, to_ref) family = from_proj.get_fork_network() from_branches = from_proj.repo.branches to_branches = to_proj.repo.branches from_commit = pullreq.from_commit to_commit = pullreq.to_commit if not pullreq.can_pull: raise TraversalError( "The PR's head_ref or base_ref is not existed") highlighted_projects = filter(None, [from_proj, parent_proj]) commits = pullreq.commits n_commits = len(commits) n_authors = len(set(c.author.username for c in commits)) ticket_title, ticket_desc = self._choose_default_PR_title_and_description(commits) # noqa # get diff diff = pullreq.get_diff(rename_detection=True) n_files = diff.length grouped_commits = groupby(commits, lambda c: c.author_time.date()) prs = PullRequest.get_by_from_and_to( from_proj.id, from_ref, to_proj.id, to_ref) open_pullreqs = [] for pr in prs: t = Ticket.get_by_projectid_and_ticketnumber( to_proj.id, pr.ticket_id) if t and t.closed is None: open_pullreqs.append(pr) guideline_url = get_project_guidelines(to_proj) teams = Team.get_all_team_uids() return st('/pull/new.html', **locals())
def __init__(self, request, proj_name, ticket_id): self.proj_name = proj_name self.ticket_id = ticket_id self.project = CodeDoubanProject.get_by_name(self.proj_name) if not self.project: raise TraversalError() self.ticket = Ticket.get_by_projectid_and_ticketnumber( self.project.id, self.ticket_id) if not self.ticket: raise TraversalError()
def __init__(self, proj_name, ticket_id): self.proj_name = proj_name self.ticket_id = ticket_id self.project = CodeDoubanProject.get_by_name(proj_name) self.ticket = Ticket.get_by_projectid_and_ticketnumber( self.project.id, self.ticket_id) self.pullreq = PullRequest.get_by_proj_and_ticket( self.project.id, self.ticket_id) try: self.all_commits = self.pullreq.commits except Exception: self.all_commits = self.pullreq.get_merged_commits()
def __init__(self, project_id, ticket_id): self.project_id = project_id self.ticket_id = ticket_id self.ticket = Ticket.get_by_projectid_and_ticketnumber( self.project_id, self.ticket_id) if not self.ticket: raise NotFoundError('pull') self.pullreq = PullRequest.get_by_proj_and_ticket( self.project_id, self.ticket.ticket_number)
def __init__(self, project_id, ticket_id): self.project_id = project_id self.ticket_id = ticket_id self.ticket = Ticket.get_by_projectid_and_ticketnumber(self.project_id, self.ticket_id) if not self.ticket: raise NotFoundError('pull') self.pullreq = PullRequest.get_by_proj_and_ticket( self.project_id, self.ticket.ticket_number)
def get_by_repo_and_pull(cls, project_name, pull_number): project = CodeDoubanProject.get_by_name(project_name) ticket = Ticket.get_by_projectid_and_ticketnumber(project.id, pull_number) def get_id_by_repo_and_pull(proj_id, ticket_id): rs = store.execute("select id from pullreq " "where to_project=%s and ticket_id=%s", (proj_id, ticket_id)) return rs[0][0] if rs else '' id_ = get_id_by_repo_and_pull(project.id, ticket.ticket_id) return cls.get(id_)
def _get_pr_by_uid(uid): pr = {} # uid: pullrequest-project-ticketid-status if uid and uid.startswith('pullrequest'): fields = uid.split('-') if len(fields) != 4: return pr _, project_name, ticket_number, status = fields project = CodeDoubanProject.get_by_name(project_name) ticket = Ticket.get_by_projectid_and_ticketnumber(project.id, ticket_number) pr = _get_pr_by_project_and_ticket(project, ticket) return pr
def _save_merged(self, operator, from_sha, to_sha, merge_commit_sha): self.merged = "%s..%s" % (from_sha, to_sha) self.save() merged_time = datetime.now() self.merge_by = operator self.merge_time = merged_time.strftime('%Y-%m-%d %H:%M:%S') # FIXME: pullreq without ticket_id? if self.ticket_id: ticket = Ticket.get_by_projectid_and_ticketnumber( self.to_proj.id, self.ticket_id) if ticket: # add commits to ticket ticket.add_commits(merge_commit_sha, operator) TicketNode.add_merge(ticket.id, operator, merged_time)
def test_ticket(self): title = 'test title' desc = 'test desc' author = 'testuser' p1_t1 = Ticket.add(self.proj1.id, title, desc, author) pullreq1 = PullRequest.open(self.proj1_fork, 'master', self.proj1, 'master') pullreq1 = pullreq1.insert(p1_t1.ticket_number) assert p1_t1.ticket_id == 1 assert p1_t1.title == title assert p1_t1.description == desc assert p1_t1.author == author p2_t1 = Ticket.add(self.proj2.id, title, desc, author) pullreq2 = PullRequest.open(self.proj2_fork, 'master', self.proj2, 'master') pullreq2 = pullreq2.insert(p2_t1.ticket_number) assert p2_t1.ticket_id == 1 ticket = Ticket.get_by_projectid_and_ticketnumber( self.proj1.id, p1_t1.ticket_id) assert ticket.id == p1_t1.id ticket = Ticket.get_by_projectid_and_ticketnumber( self.proj2.id, p2_t1.ticket_id) assert ticket.id == p2_t1.id
def test_ticket(self): title = 'test title' desc = 'test desc' author = 'testuser' p1_t1 = Ticket.add(self.proj1.id, title, desc, author) pullreq1 = PullRequest.open( self.proj1_fork, 'master', self.proj1, 'master') pullreq1 = pullreq1.insert(p1_t1.ticket_number) assert p1_t1.ticket_id == 1 assert p1_t1.title == title assert p1_t1.description == desc assert p1_t1.author == author p2_t1 = Ticket.add(self.proj2.id, title, desc, author) pullreq2 = PullRequest.open( self.proj2_fork, 'master', self.proj2, 'master') pullreq2 = pullreq2.insert(p2_t1.ticket_number) assert p2_t1.ticket_id == 1 ticket = Ticket.get_by_projectid_and_ticketnumber( self.proj1.id, p1_t1.ticket_id) assert ticket.id == p1_t1.id ticket = Ticket.get_by_projectid_and_ticketnumber( self.proj2.id, p2_t1.ticket_id) assert ticket.id == p2_t1.id
def as_dict(self): if not (self.ticket_id and self.to_proj): return None ticket = Ticket.get_by_projectid_and_ticketnumber( self.to_proj.id, self.ticket_id) if not ticket: return None d = {} d['url'] = "%s/api/%s/pull/%s" % (DOMAIN, self.to_proj.name, self.ticket_id) d['html_url'] = "%s/%s/pull/%s/" % (DOMAIN, self.to_proj.name, self.ticket_id) d['number'] = self.ticket_id # or ticket_id as name is better? d['title'] = ticket.title d['description'] = ticket.description d['merged'] = self.merged and True or False d['created_at'] = ticket.time.strftime('%Y-%m-%dT%H:%M:%S') if ticket.closed: d['closed_at'] = ticket.closed.strftime('%Y-%m-%dT%H:%M:%S') d['state'] = 'closed' else: d['closed_at'] = None d['state'] = 'open' if d['merged']: # No merged time recored, use closed_at instead d['merged_at'] = d['closed_at'] else: d['merged_at'] = None d['author'] = {} d['author']['login'] = ticket.author d['ticket_id'] = self.ticket_id d['from_proj'] = self.from_proj and self.from_proj.name or '' d['to_proj'] = self.to_proj and self.to_proj.name or '' d['to_proj_id'] = self.to_proj and self.to_proj.id or -1 d['creator'] = ticket.author d['base'] = self._base_repo_as_dict() d['head'] = self._head_repo_as_dict() commits = self.get_commits_by_status(d['state']) d['commit_id'] = [c.sha for c in commits] return d
def as_dict(self): if not (self.ticket_id and self.to_proj): return None ticket = Ticket.get_by_projectid_and_ticketnumber( self.to_proj.id, self.ticket_id) if not ticket: return None d = {} d['url'] = "%s/api/%s/pull/%s" % ( DOMAIN, self.to_proj.name, self.ticket_id) d['html_url'] = "%s/%s/pull/%s/" % ( DOMAIN, self.to_proj.name, self.ticket_id) d['number'] = self.ticket_id # or ticket_id as name is better? d['title'] = ticket.title d['description'] = ticket.description d['merged'] = self.merged and True or False d['created_at'] = ticket.time.strftime('%Y-%m-%dT%H:%M:%S') if ticket.closed: d['closed_at'] = ticket.closed.strftime('%Y-%m-%dT%H:%M:%S') d['state'] = 'closed' else: d['closed_at'] = None d['state'] = 'open' if d['merged']: # No merged time recored, use closed_at instead d['merged_at'] = d['closed_at'] else: d['merged_at'] = None d['author'] = {} d['author']['login'] = ticket.author d['ticket_id'] = self.ticket_id d['from_proj'] = self.from_proj and self.from_proj.name or '' d['to_proj'] = self.to_proj and self.to_proj.name or '' d['to_proj_id'] = self.to_proj and self.to_proj.id or -1 d['creator'] = ticket.author d['base'] = self._base_repo_as_dict() d['head'] = self._head_repo_as_dict() commits = self.get_commits_by_status(d['state']) d['commit_id'] = [c.sha for c in commits] return d
def _get_code_review_by_uid(uid): code_review = {} if uid and uid.startswith('newcodereview'): fields = uid.split('-') if len(fields) != 4: return code_review _, project_name, ticket_number, comment_id = fields project = CodeDoubanProject.get_by_name(project_name) ticket = Ticket.get_by_projectid_and_ticketnumber(project.id, ticket_number) pr = _get_pr_by_project_and_ticket(project, ticket) comment = Comment.get(comment_id) # FIXME: comment type code_review = dict( id=comment_id, type='comment', pr=pr, ) return code_review
def _q_lookup(self, request, pullid): if request.get_path().find('newpull') > 0: return request.redirect(request.get_path().replace( 'newpull', 'pull')) if pullid.count('.') == 1: pullid, diff_type = pullid.split('.') pr = PullRequest.get_by_proj_and_ticket(self.project.id, pullid) resp = request.response resp.set_header("Content-Type", "text/plain") if diff_type == 'patch' and pr: text = pr.get_format_patch() return text.encode('utf-8') elif diff_type == 'diff' and pr: text = pr.get_diff_tree() return text else: raise TraversalError if pullid.isdigit(): ticket = Ticket.get_by_projectid_and_ticketnumber( self.project.id, pullid) if ticket: return TicketUI(self.proj_name, pullid) raise TraversalError
def ticket(self): if not self.ticket_id: return None ticket = Ticket.get_by_projectid_and_ticketnumber(self.to_proj.id, self.ticket_id) return ticket
def ticket(self): if not self.ticket_id: return None ticket = Ticket.get_by_projectid_and_ticketnumber( self.to_proj.id, self.ticket_id) return ticket