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)
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)
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))
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)