def renderProcessCommits(req, db, user): review_id = req.getParameter("review", filter=int) commit_ids = map(int, req.getParameter("commits").split(",")) review = dbutils.Review.fromId(db, review_id) all_commits = [ gitutils.Commit.fromId(db, review.repository, commit_id) for commit_id in commit_ids ] commitset = log.commitset.CommitSet(all_commits) heads = commitset.getHeads() tails = commitset.getTails() def process(): if len(heads) != 1: return "invalid commit-set; multiple heads" if len(tails) != 1: return "invalid commit-set; multiple tails" old_head = gitutils.Commit.fromSHA1(db, review.repository, tails.pop()) new_head = heads.pop() output = cStringIO.StringIO() extensions.role.processcommits.execute(db, user, review, all_commits, old_head, new_head, output) return output.getvalue() return page.utils.ResponseBody(process(), content_type="text/plain")
def renderProcessCommits(req, db, user): review_id = req.getParameter("review", filter=int) commit_ids = map(int, req.getParameter("commits").split(",")) review = dbutils.Review.fromId(db, review_id) all_commits = [gitutils.Commit.fromId(db, review.repository, commit_id) for commit_id in commit_ids] commitset = log.commitset.CommitSet(all_commits) heads = commitset.getHeads() tails = commitset.getTails() def process(): if len(heads) != 1: return "invalid commit-set; multiple heads" if len(tails) != 1: return "invalid commit-set; multiple tails" old_head = gitutils.Commit.fromSHA1(db, review.repository, tails.pop()) new_head = heads.pop() output = cStringIO.StringIO() extensions.role.processcommits.execute(db, user, review, all_commits, old_head, new_head, output) return output.getvalue() return page.utils.ResponseBody(process(), content_type="text/plain")
def containsCommit(self, db, commit, include_head_and_tails=False): import gitutils commit_id = None commit_sha1 = None if isinstance(commit, gitutils.Commit): if commit.id: commit_id = commit.id else: commit_sha1 = commit.sha1 elif isinstance(commit, str): commit_sha1 = self.repository.revparse(commit) commit = None elif isinstance(commit, int): commit_id = commit commit = None else: raise TypeError cursor = db.cursor() if commit_id is not None: cursor.execute("""SELECT 1 FROM reviewchangesets JOIN changesets ON (id=changeset) WHERE reviewchangesets.review=%s AND changesets.child=%s AND changesets.type!='conflicts'""", (self.id, commit_id)) else: cursor.execute("""SELECT 1 FROM reviewchangesets JOIN changesets ON (changesets.id=reviewchangesets.changeset) JOIN commits ON (commits.id=changesets.child) WHERE reviewchangesets.review=%s AND changesets.type!='conflicts' AND commits.sha1=%s""", (self.id, commit_sha1)) if cursor.fetchone() is not None: return True if include_head_and_tails: head_and_tails = set([self.branch.head]) commitset = self.getCommitSet(db) if commitset: head_and_tails |= commitset.getTails() if commit_sha1 is None: if commit is None: commit = gitutils.Commit.fromId(db, self.repository, commit_id) commit_sha1 = commit.sha1 if commit_sha1 in head_and_tails: return True return False
def execute(db, user, review, all_commits, old_head, new_head, output): cursor = db.cursor() installs = Extension.getInstalls(db, user) data = None for extension_id, version_id, version_sha1, is_universal in installs: handlers = [] extension = Extension.fromId(db, extension_id) if version_id is not None: cursor.execute("""SELECT script, function FROM extensionroles JOIN extensionprocesscommitsroles ON (role=id) WHERE version=%s ORDER BY id ASC""", (version_id,)) handlers.extend(cursor) if not handlers: continue extension_path = getExtensionInstallPath(version_sha1) manifest = Manifest.load(extension_path) else: manifest = Manifest.load(extension.getPath()) for role in manifest.roles: if isinstance(role, ProcessCommitsRole): handlers.append((role.script, role.function)) if not handlers: continue if data is None: commitset = log.commitset.CommitSet(all_commits) assert old_head is None or old_head in commitset.getTails() assert new_head in commitset.getHeads() assert len(commitset.getHeads()) == 1 tails = commitset.getFilteredTails(review.repository) if len(tails) == 1: tail = gitutils.Commit.fromSHA1(db, review.repository, tails.pop()) changeset_id = changeset.utils.createChangeset( db, user, review.repository, from_commit=tail, to_commit=new_head)[0].id changeset_arg = "repository.getChangeset(%d)" % changeset_id else: changeset_arg = "null" commits_arg = "[%s]" % ",".join( [("repository.getCommit(%d)" % commit.getId(db)) for commit in all_commits]) data = { "review_id": review.id, "changeset": changeset_arg, "commits": commits_arg } for script, function in handlers: class Error(Exception): pass def print_header(): header = "%s::%s()" % (script, function) print >>output, ("\n[%s] %s\n[%s] %s" % (extension.getName(), header, extension.getName(), "=" * len(header))) try: argv = """ (function () { var review = new critic.Review(%(review_id)d); var repository = review.repository; var changeset = %(changeset)s; var commitset = new critic.CommitSet(%(commits)s); return [review, changeset, commitset]; })() """ % data argv = re.sub("[ \n]+", " ", argv.strip()) try: stdout_data = executeProcess( manifest, "processcommits", script, function, extension_id, user.id, argv, configuration.extensions.SHORT_TIMEOUT) except ProcessTimeout: raise Error("Timeout after %d seconds." % configuration.extensions.SHORT_TIMEOUT) except ProcessError as error: if error.returncode < 0: raise Error("Process terminated by signal %d." % -error.returncode) else: raise Error("Process returned %d.\n%s" % (error.returncode, error.stderr)) if stdout_data.strip(): print_header() for line in stdout_data.splitlines(): print >>output, "[%s] %s" % (extension.getName(), line) except Error as error: print_header() print >>output, "[%s] Extension error: %s" % (extension.getName(), error.message)
def execute(db, user, review, all_commits, old_head, new_head, output): cursor = db.cursor() installs = Extension.getInstalls(db, user) data = None for extension_id, version_id, version_sha1, is_universal in installs: handlers = [] extension = Extension.fromId(db, extension_id) if version_id is not None: cursor.execute( """SELECT script, function FROM extensionroles JOIN extensionprocesscommitsroles ON (role=id) WHERE version=%s ORDER BY id ASC""", (version_id, )) handlers.extend(cursor) if not handlers: continue extension_path = getExtensionInstallPath(version_sha1) manifest = Manifest.load(extension_path) else: manifest = Manifest.load(extension.getPath()) for role in manifest.roles: if isinstance(role, ProcessCommitsRole): handlers.append((role.script, role.function)) if not handlers: continue if data is None: commitset = log.commitset.CommitSet(all_commits) assert old_head is None or old_head in commitset.getTails() assert new_head in commitset.getHeads() assert len(commitset.getHeads()) == 1 tails = commitset.getFilteredTails(review.repository) if len(tails) == 1: tail = gitutils.Commit.fromSHA1(db, review.repository, tails.pop()) changeset_id = changeset.utils.createChangeset( db, user, review.repository, from_commit=tail, to_commit=new_head)[0].id changeset_arg = "repository.getChangeset(%d)" % changeset_id else: changeset_arg = "null" commits_arg = "[%s]" % ",".join( [("repository.getCommit(%d)" % commit.getId(db)) for commit in all_commits]) data = { "review_id": review.id, "changeset": changeset_arg, "commits": commits_arg } for script, function in handlers: class Error(Exception): pass def print_header(): header = "%s::%s()" % (script, function) print >> output, ("\n[%s] %s\n[%s] %s" % (extension.getName(), header, extension.getName(), "=" * len(header))) try: argv = """ (function () { var review = new critic.Review(%(review_id)d); var repository = review.repository; var changeset = %(changeset)s; var commitset = new critic.CommitSet(%(commits)s); return [review, changeset, commitset]; })() """ % data argv = re.sub("[ \n]+", " ", argv.strip()) try: stdout_data = executeProcess( manifest, "processcommits", script, function, extension_id, user.id, argv, configuration.extensions.SHORT_TIMEOUT) except ProcessTimeout: raise Error("Timeout after %d seconds." % configuration.extensions.SHORT_TIMEOUT) except ProcessError as error: if error.returncode < 0: raise Error("Process terminated by signal %d." % -error.returncode) else: raise Error("Process returned %d.\n%s" % (error.returncode, error.stderr)) if stdout_data.strip(): print_header() for line in stdout_data.splitlines(): print >> output, "[%s] %s" % (extension.getName(), line) except Error as error: print_header() print >> output, "[%s] Extension error: %s" % ( extension.getName(), error.message)
def containsCommit(self, db, commit, include_head_and_tails=False, include_actual_log=False): import gitutils commit_id = None commit_sha1 = None if isinstance(commit, gitutils.Commit): commit_id = commit.id commit_sha1 = commit.sha1 elif isinstance(commit, str): commit_sha1 = self.repository.revparse(commit) commit = None elif isinstance(commit, int): commit_id = commit commit = None else: raise TypeError cursor = db.cursor() if commit_id is not None: cursor.execute( """SELECT 1 FROM reviewchangesets JOIN changesets ON (id=changeset) WHERE reviewchangesets.review=%s AND changesets.child=%s AND changesets.type!='conflicts'""", (self.id, commit_id)) else: cursor.execute( """SELECT 1 FROM reviewchangesets JOIN changesets ON (changesets.id=reviewchangesets.changeset) JOIN commits ON (commits.id=changesets.child) WHERE reviewchangesets.review=%s AND changesets.type!='conflicts' AND commits.sha1=%s""", (self.id, commit_sha1)) if cursor.fetchone() is not None: return True if include_head_and_tails: head_and_tails = set([self.branch.getHead(db)]) commitset = self.getCommitSet(db) if commitset: head_and_tails |= commitset.getTails() if commit_sha1 is None: if commit is None: commit = gitutils.Commit.fromId(db, self.repository, commit_id) commit_sha1 = commit.sha1 if commit_sha1 in head_and_tails: return True if include_actual_log: if commit_id is not None: cursor.execute( """SELECT 1 FROM reachable JOIN branches ON (branches.id=reachable.branch) JOIN reviews ON (reviews.branch=branches.id) WHERE reachable.commit=%s AND reviews.id=%s""", (commit_id, self.id)) else: cursor.execute( """SELECT 1 FROM commits JOIN reachable ON (reachable.commit=commits.id) JOIN branches ON (branches.id=reachable.branch) JOIN reviews ON (reviews.branch=branches.id) WHERE commits.sha1=%s AND reviews.id=%s""", (commit_sha1, self.id)) if cursor.fetchone() is not None: return True return False
def execute(db, user, review, all_commits, old_head, new_head, output): cursor = db.cursor() cursor.execute("""SELECT extensions.id, extensions.author, extensions.name, extensionversions.sha1, roles.script, roles.function FROM extensions JOIN extensionversions ON (extensionversions.extension=extensions.id) JOIN extensionroles_processcommits AS roles ON (roles.version=extensionversions.id) WHERE uid=%s AND filter IS NULL""", (user.id,)) rows = cursor.fetchall() if rows: commitset = log.commitset.CommitSet(all_commits) assert old_head is None or old_head in commitset.getTails() assert new_head in commitset.getHeads() assert len(commitset.getHeads()) == 1 tails = commitset.getFilteredTails(review.repository) if len(tails) == 1: tail = gitutils.Commit.fromSHA1(db, review.repository, tails.pop()) changeset_id = changeset.utils.createChangeset(db, user, review.repository, from_commit=tail, to_commit=new_head)[0].id changeset_arg = "repository.getChangeset(%d)" % changeset_id db.commit() else: changeset_arg = "null" commits = "[%s]" % ",".join([("repository.getCommit(%d)" % commit.getId(db)) for commit in all_commits]) data = { "review_id": review.id, "changeset": changeset_arg, "commits": commits } for extension_id, author_id, extension_name, sha1, script, function in rows: author = dbutils.User.fromId(db, author_id) if sha1 is None: extension_path = getExtensionPath(author.name, extension_name) else: extension_path = getExtensionInstallPath(sha1) class Error(Exception): pass def print_header(): header = "%s::%s()" % (script, function) print >>output, "\n[%s] %s\n[%s] %s" % (extension_name, header, extension_name, "=" * len(header)) try: try: manifest = Manifest.load(extension_path) except ManifestError, error: raise Error("Invalid MANIFEST:\n%s" % error.message) for role in manifest.roles: if isinstance(role, ProcessCommitsRole) and role.script == script and role.function == function: break else: continue argv = """ (function () { var review = new critic.Review(%(review_id)d); var repository = review.repository; var changeset = %(changeset)s; var commitset = new critic.CommitSet(%(commits)s); return [review, changeset, commitset]; })() """ % data argv = re.sub("[ \n]+", " ", argv.strip()) try: stdout_data = executeProcess(manifest, role, extension_id, user.id, argv, configuration.extensions.SHORT_TIMEOUT) except ProcessTimeout: raise Error("Timeout after %d seconds." % configuration.extensions.SHORT_TIMEOUT) except ProcessError, error: if error.returncode < 0: if -error.returncode == signal.SIGXCPU: raise Error("CPU time limit (5 seconds) exceeded.") else: raise Error("Process terminated by signal %d." % -error.returncode) else: raise Error("Process returned %d.\n%s" % (error.returncode, error.stderr)) if stdout_data.strip(): print_header() for line in stdout_data.splitlines(): print >>output, "[%s] %s" % (extension_name, line) except Error, error: print_header() print >>output, "[%s] Extension error: %s" % (extension_name, error.message)