コード例 #1
0
ファイル: createreview.py プロジェクト: Tigge/critic
    def process(self, db, user, repository_id, commit_ids, branch, summary,
                reviewfilters, recipientfilters, applyfilters, applyparentfilters,
                description=None, frombranch=None, trackedbranch=None):
        if not branch.startswith("r/"):
            raise OperationFailure(code="invalidbranch",
                                   title="Invalid review branch name",
                                   message="'%s' is not a valid review branch name; it must have a \"r/\" prefix." % branch)

        repository = gitutils.Repository.fromId(db, repository_id)
        commits = [gitutils.Commit.fromId(db, repository, commit_id) for commit_id in commit_ids]
        commitset = CommitSet(commits)

        reviewfilters = parseReviewFilters(db, reviewfilters)
        recipientfilters = parseRecipientFilters(db, recipientfilters)

        review = createReview(db, user, repository, commits, branch, summary, description,
                              from_branch_name=frombranch,
                              reviewfilters=reviewfilters,
                              recipientfilters=recipientfilters,
                              applyfilters=applyfilters,
                              applyparentfilters=applyparentfilters)

        extensions_output = StringIO()
        kwargs = {}

        if configuration.extensions.ENABLED:
            if executeProcessCommits(db, user, review, commits, None, commitset.getHeads().pop(), extensions_output):
                kwargs["extensions_output"] = extensions_output.getvalue().lstrip()

        if trackedbranch:
            cursor = db.cursor()
            cursor.execute("""INSERT INTO trackedbranches (repository, local_name, remote, remote_name, forced, delay)
                                   VALUES (%s, %s, %s, %s, false, '1 hour')
                                RETURNING id""",
                           (repository_id, branch, trackedbranch["remote"], trackedbranch["name"]))

            trackedbranch_id = cursor.fetchone()[0]

            cursor.execute("""INSERT INTO trackedbranchusers (branch, uid)
                                   VALUES (%s, %s)""",
                           (trackedbranch_id, user.id))

            db.commit()

            pid = int(open(configuration.services.BRANCHTRACKER["pidfile_path"]).read().strip())
            os.kill(pid, signal.SIGHUP)

        return OperationResult(review_id=review.id, **kwargs)
コード例 #2
0
    def process(self, db, user, repository, branch, summary, commit_ids=None,
                commit_sha1s=None, applyfilters=True, applyparentfilters=True,
                reviewfilters=None, recipientfilters=None, description=None,
                frombranch=None, trackedbranch=None):
        if not branch.startswith("r/"):
            raise OperationFailure(code="invalidbranch",
                                   title="Invalid review branch name",
                                   message="'%s' is not a valid review branch name; it must have a \"r/\" prefix." % branch)

        if reviewfilters is None:
            reviewfilters = []
        if recipientfilters is None:
            recipientfilters = {}

        components = branch.split("/")
        for index in range(1, len(components)):
            try:
                repository.revparse("refs/heads/%s" % "/".join(components[:index]))
            except gitutils.GitReferenceError:
                continue

            message = ("Cannot create branch with name<pre>%s</pre>since there is already a branch named<pre>%s</pre>in the repository." %
                       (htmlutils.htmlify(branch), htmlutils.htmlify("/".join(components[:index]))))
            raise OperationFailure(code="invalidbranch",
                                   title="Invalid review branch name",
                                   message=message,
                                   is_html=True)

        if commit_sha1s is not None:
            commits = [gitutils.Commit.fromSHA1(db, repository, commit_sha1) for commit_sha1 in commit_sha1s]
        elif commit_ids is not None:
            commits = [gitutils.Commit.fromId(db, repository, commit_id) for commit_id in commit_ids]
        else:
            commits = []

        commitset = CommitSet(commits)

        reviewfilters = parseReviewFilters(db, reviewfilters)
        recipientfilters = parseRecipientFilters(db, recipientfilters)

        review = createReview(db, user, repository, commits, branch, summary, description,
                              from_branch_name=frombranch,
                              reviewfilters=reviewfilters,
                              recipientfilters=recipientfilters,
                              applyfilters=applyfilters,
                              applyparentfilters=applyparentfilters)

        extensions_output = StringIO()
        kwargs = {}

        if configuration.extensions.ENABLED:
            if extensions.role.processcommits.execute(db, user, review, commits, None, commitset.getHeads().pop(), extensions_output):
                kwargs["extensions_output"] = extensions_output.getvalue().lstrip()

        if trackedbranch:
            cursor = db.cursor()

            cursor.execute("""SELECT 1
                                FROM knownremotes
                               WHERE url=%s
                                 AND pushing""",
                           (trackedbranch["remote"],))

            if cursor.fetchone():
                delay = "1 week"
            else:
                delay = "1 hour"

            cursor.execute("""INSERT INTO trackedbranches (repository, local_name, remote, remote_name, forced, delay)
                                   VALUES (%s, %s, %s, %s, false, %s)
                                RETURNING id""",
                           (repository.id, branch, trackedbranch["remote"], trackedbranch["name"], delay))

            trackedbranch_id = cursor.fetchone()[0]

            cursor.execute("""INSERT INTO trackedbranchusers (branch, uid)
                                   VALUES (%s, %s)""",
                           (trackedbranch_id, user.id))

            db.commit()

            pid = int(open(configuration.services.BRANCHTRACKER["pidfile_path"]).read().strip())
            os.kill(pid, signal.SIGHUP)

        return OperationResult(review_id=review.id, **kwargs)
コード例 #3
0
ファイル: index.py プロジェクト: Tigge/critic
def createBranch(user, repository, name, head):
    processCommits(repository.name, head)

    cursor = db.cursor()

    def commit_id(sha1):
        cursor.execute("SELECT id FROM commits WHERE sha1=%s", [sha1])
        return cursor.fetchone()[0]

    components = name.split("/")
    for index in range(1, len(components)):
        try: repository.revparse("refs/heads/%s" % "/".join(components[:index]))
        except: continue

        message = ("Cannot create branch with name '%s' since there is already a branch named '%s' in the repository." %
                   (name, "/".join(components[:index])))
        raise IndexException, textutils.reflow(message, line_length=80 - len("remote: "))

    if name.startswith("r/"):
        try:
            review_id = int(name[2:])

            cursor.execute("SELECT branches.name FROM reviews JOIN branches ON (branches.id=reviews.branch) WHERE reviews.id=%s", (review_id,))
            row = cursor.fetchone()

            message = "Refusing to create review named as a number."

            if row:
                message += "\nDid you mean to push to the branch '%s', perhaps?" % row[0]

            raise IndexException, message
        except ValueError:
            pass

        if user.getPreference(db, "review.createViaPush"):
            the_commit = gitutils.Commit.fromSHA1(db, repository, head, commit_id(head))
            all_commits = [the_commit]
            review = review_utils.createReview(db, user, repository, all_commits, name, the_commit.summary(), None, via_push=True)

            print "Submitted review: %s/r/%d" % (dbutils.getURLPrefix(db), review.id)

            if review.reviewers:
                print "  Reviewers:"
                for reviewer in review.reviewers:
                    print "    %s <%s>" % (reviewer.fullname, reviewer.email)

            if review.watchers:
                print "  Watchers:"
                for watcher in review.watchers:
                    print "    %s <%s>" % (watcher.fullname, watcher.email)

            if configuration.extensions.ENABLED:
                if extensions.executeProcessCommits(db, user, review, all_commits, None, the_commit, stdout):
                    print

            print "Thank you!"
            return True
        else:
            raise IndexException, "Refusing to create review; user preference 'review.createViaPush' is not enabled."

    sha1 = head
    base = None
    tail = None

    cursor.execute("""SELECT 1
                        FROM reachable
                        JOIN branches ON (branches.id=reachable.branch)
                        JOIN repositories ON (repositories.id=branches.repository)
                       WHERE repositories.id=%s
                       LIMIT 1""",
                   (repository.id,))

    if cursor.fetchone():
        def reachable(sha1):
            cursor.execute("""SELECT branches.id
                                FROM branches
                                JOIN reachable ON (reachable.branch=branches.id)
                                JOIN commits ON (commits.id=reachable.commit)
                               WHERE branches.repository=%s
                                 AND branches.type='normal'
                                 AND commits.sha1=%s
                            ORDER BY reachable.branch ASC
                               LIMIT 1""",
                           (repository.id, sha1))
            return cursor.fetchone()
    else:
        def reachable(sha1):
            return None

    commit_map = {}
    commit_list = []

    row = reachable(sha1)
    if row:
        # Head of branch is reachable from an existing branch.  Could be because
        # this branch is actually empty (just created with no "own" commits) or
        # it could have been merged into some other already existing branch.  We
        # can't tell, so we just record it as empty.

        base = row[0]
        tail = sha1
    else:
        stack = []

        while True:
            if sha1 not in commit_map:
                commit = gitutils.Commit.fromSHA1(db, repository, sha1)
                commit_map[sha1] = commit
                commit_list.append(commit)

                for sha1 in commit.parents:
                    if sha1 not in commit_map:
                        row = reachable(sha1)
                        if not row:
                            stack.append(sha1)
                        elif base is None:
                            base = row[0]
                            tail = sha1

                            base_chain = [base]

                            while True:
                                cursor.execute("SELECT base FROM branches WHERE id=%s", (base_chain[-1],))
                                next = cursor.fetchone()[0]
                                if next is None: break
                                else: base_chain.append(next)

                            def reachable(sha1):
                                cursor.execute("""SELECT 1
                                                    FROM reachable
                                                    JOIN commits ON (commits.id=reachable.commit)
                                                   WHERE reachable.branch=ANY (%s)
                                                     AND commits.sha1=%s""",
                                               (base_chain, sha1))
                                return cursor.fetchone()

            if stack: sha1 = stack.pop(0)
            else: break

        if len(commit_list) % 10000 > 1000:
            stdout.write("\n")
            stdout.flush()

    if not base:
        cursor.execute("INSERT INTO branches (repository, name, head) VALUES (%s, %s, %s) RETURNING id", (repository.id, name, commit_id(head)))
        branch_id = cursor.fetchone()[0]
    else:
        cursor.execute("INSERT INTO branches (repository, name, head, base, tail) VALUES (%s, %s, %s, %s, %s) RETURNING id", (repository.id, name, commit_id(head), base, commit_id(tail)))
        branch_id = cursor.fetchone()[0]

        cursor.execute("SELECT name FROM branches WHERE id=%s", [base])

        print "Added branch based on %s containing %d commit%s:" % (cursor.fetchone()[0], len(commit_list), "s" if len(commit_list) > 1 else "")
        print "  %s/log?repository=%d&branch=%s" % (dbutils.getURLPrefix(db), repository.id, name)
        if len(commit_list) > 1:
            print "To create a review of all %d commits:" % len(commit_list)
        else:
            print "To create a review of the commit:"
        print "  %s/createreview?repository=%d&branch=%s" % (dbutils.getURLPrefix(db), repository.id, name)

    reachable_values = [(branch_id, commit.sha1) for commit in commit_list]
    cursor.executemany("INSERT INTO reachable (branch, commit) SELECT %s, id FROM commits WHERE sha1=%s", reachable_values)

    if isinstance(user, str): user_name = user
    else: user_name = user.name

    if not repository.hasMainBranch() and user_name == configuration.base.SYSTEM_USER_NAME:
        cursor.execute("UPDATE repositories SET branch=%s WHERE id=%s", (branch_id, repository.id))
コード例 #4
0
    def process(self,
                db,
                user,
                repository,
                branch,
                summary,
                commit_ids=None,
                commit_sha1s=None,
                applyfilters=True,
                applyparentfilters=True,
                reviewfilters=None,
                recipientfilters=None,
                description=None,
                frombranch=None,
                trackedbranch=None):
        if not branch.startswith("r/"):
            raise OperationFailure(
                code="invalidbranch",
                title="Invalid review branch name",
                message=
                "'%s' is not a valid review branch name; it must have a \"r/\" prefix."
                % branch)

        if reviewfilters is None:
            reviewfilters = []
        if recipientfilters is None:
            recipientfilters = {}

        components = branch.split("/")
        for index in range(1, len(components)):
            try:
                repository.revparse("refs/heads/%s" %
                                    "/".join(components[:index]))
            except gitutils.GitReferenceError:
                continue

            message = (
                "Cannot create branch with name<pre>%s</pre>since there is already a branch named<pre>%s</pre>in the repository."
                % (htmlutils.htmlify(branch),
                   htmlutils.htmlify("/".join(components[:index]))))
            raise OperationFailure(code="invalidbranch",
                                   title="Invalid review branch name",
                                   message=message,
                                   is_html=True)

        if commit_sha1s is not None:
            commits = [
                gitutils.Commit.fromSHA1(db, repository, commit_sha1)
                for commit_sha1 in commit_sha1s
            ]
        elif commit_ids is not None:
            commits = [
                gitutils.Commit.fromId(db, repository, commit_id)
                for commit_id in commit_ids
            ]
        else:
            commits = []

        commitset = CommitSet(commits)

        reviewfilters = parseReviewFilters(db, reviewfilters)
        recipientfilters = parseRecipientFilters(db, recipientfilters)

        review = createReview(db,
                              user,
                              repository,
                              commits,
                              branch,
                              summary,
                              description,
                              from_branch_name=frombranch,
                              reviewfilters=reviewfilters,
                              recipientfilters=recipientfilters,
                              applyfilters=applyfilters,
                              applyparentfilters=applyparentfilters)

        extensions_output = StringIO()
        kwargs = {}

        if configuration.extensions.ENABLED:
            if extensions.role.processcommits.execute(
                    db, user, review, commits, None,
                    commitset.getHeads().pop(), extensions_output):
                kwargs["extensions_output"] = extensions_output.getvalue(
                ).lstrip()

        if trackedbranch:
            cursor = db.cursor()

            cursor.execute(
                """SELECT 1
                                FROM knownremotes
                               WHERE url=%s
                                 AND pushing""", (trackedbranch["remote"], ))

            if cursor.fetchone():
                delay = "1 week"
            else:
                delay = "1 hour"

            cursor.execute(
                """INSERT INTO trackedbranches (repository, local_name, remote, remote_name, forced, delay)
                                   VALUES (%s, %s, %s, %s, false, %s)
                                RETURNING id""",
                (repository.id, branch, trackedbranch["remote"],
                 trackedbranch["name"], delay))

            trackedbranch_id = cursor.fetchone()[0]
            kwargs["trackedbranch_id"] = trackedbranch_id

            cursor.execute(
                """INSERT INTO trackedbranchusers (branch, uid)
                                   VALUES (%s, %s)""",
                (trackedbranch_id, user.id))

            db.commit()

            pid = int(
                open(configuration.services.BRANCHTRACKER["pidfile_path"]).
                read().strip())
            os.kill(pid, signal.SIGHUP)

        return OperationResult(review_id=review.id, **kwargs)