Пример #1
0
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)
Пример #2
0
 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
Пример #3
0
    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())
Пример #4
0
    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())
Пример #5
0
 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()
Пример #6
0
 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()
Пример #7
0
 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()
Пример #8
0
    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)
Пример #9
0
 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()
Пример #10
0
    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)
Пример #11
0
    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_)
Пример #12
0
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
Пример #13
0
 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)
Пример #14
0
 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)
Пример #15
0
 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
Пример #16
0
 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
Пример #17
0
    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
Пример #18
0
    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
Пример #19
0
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
Пример #20
0
    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
Пример #21
0
    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
Пример #22
0
 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
Пример #23
0
 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