def apply(self, line, state): result = OperationResult(line, False) if not state.args.anticrap: return result #trimmed = stripComments(line) output = line self.strings = scanForStrings(line) slashmatch = regex['backslash'].finditer(line) dotmatch = regex['typedot'].finditer(line) for m in slashmatch: if checkIfInsideString(m.start('backslash'), self.strings): continue substitution = "." output = output[:m.start('backslash')] + substitution + output[m.end('backslash'):] for m in dotmatch: if checkIfInsideString(m.start('dot'), self.strings): continue substitution = "\\" output = output[:m.start('dot')] + substitution + output[m.end('dot'):] result.line = output return result
def process(self, db, user, username, password): if not user.isAnonymous(): if user.name == username: return OperationResult() else: return OperationResult(message="Already signed as '%s'!" % user.name) try: auth.checkPassword(db, username, password) except auth.NoSuchUser: return OperationResult(message="No such user!") except auth.WrongPassword: return OperationResult(message="Wrong password!") sid = base64.b64encode(hashlib.sha1(os.urandom(20)).digest()) cursor = db.cursor() cursor.execute("""INSERT INTO usersessions (key, uid) SELECT %s, id FROM users WHERE name=%s""", (sid, username)) db.commit() # Set 'sid' and 'has_sid' cookies. # # The 'has_sid' cookie is significant if the system is accessible over # both HTTP and HTTPS. In that case, the 'sid' cookie is set with the # "secure" flag, so is only sent over HTTPS. The 'has_sid' cookie is # then used to detect that an HTTP client would have sent a 'sid' cookie # if the request instead had been made over HTTPS, in which case we # redirect the client to HTTPS automatically. result = OperationResult() result.setCookie("sid", sid, secure=True) result.setCookie("has_sid", "1") return result
def apply(self, line, state): result = OperationResult(line, False) skip = False if not self.stack.isEmpty(): #print(str(state.row) + " : " + str(self.stack.arr)) if self.stack.contains(False): skip = True dirsearch = regex['directive'].search(line) if dirsearch: directive = dirsearch.group(1) identifier = dirsearch.group(2) if directive == "#ifdef" or directive == "#ifndef" and not skip: result.line = commentLine(result.line) if identifier == "": result.error = "Invalid " + directive return result if not identifier in state.macros: self.stack.push(directive == "#ifndef") result.line = handleCulledLine(result.line) return result self.stack.push(directive != "#ifndef") elif directive == "#else": result.line = commentLine(result.line) if self.stack.isEmpty(): result.error = "Unexpected #else" return result if self.stack.top() == True: self.stack.pop() self.stack.push(False) else: self.stack.pop() self.stack.push(True) elif directive == "#endif": result.line = commentLine(result.line) if self.stack.isEmpty(): result.error = "Unexpected #endif" return result self.stack.pop() if skip: result.line = handleCulledLine(result.line) return result
def apply(self, line, state): result = OperationResult(line, False) #trimmed = stripComments(line) output = line self.strings = scanForStrings(line) output = self.replaceAll(output, regex['comment_start'], 'REMSTART', 'comment_start') output = self.replaceAll(output, regex['comment_end'], 'REMEND', 'comment_end') result.line = output return result
def apply(self, line, state): result = OperationResult(line, False) # strings = [] # string start and end positions as StringPos instances trimmed = stripComments(line) output = line expanded_line = line # find the directive dirsearch = regex['directive'].search(trimmed) if dirsearch: directive = dirsearch.group(1) identifier = dirsearch.group(2) origline = output output = commentLine(line) if directive == "#define": macro = Macro(dirsearch, trimmed) if macro != None: state.macros[macro.name] = macro elif directive == "#undef": temp_macro = Macro(dirsearch, trimmed) if temp_macro.name in state.macros: del state.macros[temp_macro.name] else: warnings.add(state.row, "Trying to undefine a nonexistent macro " + temp_macro.name) elif directive == "#pragma": if state.args.verbose: print("pragma: " + identifier) state.args = handlePragma(identifier, state.args) elif directive == "#include": if state.args.filedir: self.handleInclude(state, trimmed, state.args.filedir) else: # we'll leave #ifdef, #ifndef and #else to the other operators output = origline else: if state.args.nomacros: return result visited = Stack() #for name in self.macros: output = expandAll(line, state.macros, visited, state) result.line = output return result
def apply(self, line, state): result = OperationResult(line, False) if not state.args.cull: return result trimmedLine = line.strip() words = trimmedLine.split() if (len(words) > 0): if (words[0].upper() == "REMSTART" or words[0].upper() == "REMEND"): self.inMultilineComment = not self.inMultilineComment result.discard = True return result if self.inMultilineComment: result.discard = True return result result.line = stripComments(line) stripped = result.line.strip() if stripped == "" or stripped == "\n" or stripped == "\r\n": result.discard = True if state.lastline: result.line = result.line.rstrip("\r\n") return result
def apply(self, line, state): result = OperationResult(line, False) if not state.args.dumb_debug: return result trimmed = stripComments(line) addition = ": " if isEmptyLine(trimmed): addition = "" if trimmed is not line: # there's a comment on this line #print("left: " + line[len(trimmed)-1:]) if isEmptyLine(trimmed): trimmed = line[:len(trimmed)-1] + self.macrostring + addition + line[len(trimmed)-1:] else: trimmed = self.macrostring + addition + line else: trimmed = self.macrostring + addition + line result.line = trimmed return result
def apply(self, line, state): result = OperationResult(line, False) if not state.args.minify: return result l = stripComments(line) strings = scanForStrings(l) commentStart = len(l) stringRegex = r'(("[^"]+")|(|[^"]*?)([^\s]*?))?' comments = r'(?P<comment>(|(\'|//)*$))' def string(s): if not s: return "" return s def replace(m, group): if checkIfInsideString(m.start(group), strings): return string(m.group(0)) return string(m.group(1)) + string(m.group(group)) ops = [] ops.append(Replacement(re.compile(r'' + stringRegex + '\s*(?P<op>[=+\-*/\><,\^]{1,2})\s*'), lambda m: replace(m, "op"))) ops.append(Replacement(re.compile(r'' + stringRegex + r'(?<=\D)(0)(?P<digit>\.\d+)'), lambda m: replace(m, "digit") )) #l = l.lstrip("\t") for o in ops: l = o.regex.sub(o.substitution, l) l = l.rstrip("\r\n") result.line = strInsert(result.line, 0, commentStart-1, l) return result
def setChainState(self, db, user, chain, old_state, new_state, new_last_commit=None): review = chain.review if chain.state != old_state: raise OperationError, "the comment chain's state is not '%s'" % old_state if new_state == "open" and review.state != "open": raise OperationError, "can't reopen comment chain in %s review" % review.state if chain.last_commit: old_last_commit = chain.last_commit.id if new_last_commit is None: new_last_commit = old_last_commit else: old_last_commit = new_last_commit = None cursor = db.cursor() if chain.state_is_draft: # The user is reverting a draft state change; just undo the draft # change. cursor.execute( """DELETE FROM commentchainchanges WHERE chain=%s AND uid=%s AND to_state IS NOT NULL""", (chain.id, user.id)) else: # Otherwise insert a new row into the commentchainchanges table. cursor.execute( """INSERT INTO commentchainchanges (review, uid, chain, from_state, to_state, from_last_commit, to_last_commit) VALUES (%s, %s, %s, %s, %s, %s, %s)""", (review.id, user.id, chain.id, old_state, new_state, old_last_commit, new_last_commit)) db.commit() return OperationResult(draft_status=review.getDraftStatus(db, user))
def process(self, db, user, service_name, lines=40): logfile_paths = { "manager": configuration.services.SERVICEMANAGER["logfile_path"] } for service in configuration.services.SERVICEMANAGER["services"]: logfile_paths[service["name"]] = service["logfile_path"] logfile_path = logfile_paths.get(service_name) if not logfile_path: raise OperationError("unknown service: %s" % service_name) try: logfile = open(logfile_path) except OSError as error: raise OperationError("failed to open logfile: %s" % error.message) return OperationResult(lines=logfile.read().splitlines()[-lines:])
def process(self, db, user, comment_id, new_text): comment = Comment.fromId(db, comment_id, user) if user != comment.user: raise OperationError("can't edit comment written by another user") if comment.state != "draft": raise OperationError("can't edit comment that has been submitted") if not new_text.strip(): raise OperationError("empty comment") cursor = db.cursor() cursor.execute("""UPDATE comments SET comment=%s, time=now() WHERE id=%s""", (new_text, comment.id)) db.commit() return OperationResult(draft_status=comment.chain.review.getDraftStatus(db, user))
def process(self, db, user, branch_id): cursor = db.cursor() cursor.execute( """SELECT previous, next FROM trackedbranches WHERE id=%s""", (branch_id, )) previous, next = cursor.fetchone() previous = calendar.timegm( previous.utctimetuple()) if previous else None next = calendar.timegm(next.utctimetuple()) if next else None cursor.execute( """SELECT time, from_sha1, to_sha1, hook_output, successful FROM trackedbranchlog WHERE branch=%s ORDER BY time ASC""", (branch_id, )) items = [] for update_time, from_sha1, to_sha1, hook_output, successful in cursor: items.append({ "time": calendar.timegm(update_time.utctimetuple()), "from_sha1": from_sha1, "to_sha1": to_sha1, "hook_output": hook_output, "successful": successful }) cursor.execute( """SELECT repository FROM trackedbranches WHERE id=%s""", (branch_id, )) repository = gitutils.Repository.fromId(db, cursor.fetchone()[0]) return OperationResult(previous=previous, next=next, items=items, repository={ "id": repository.id, "name": repository.name })
def process(self, db, user, review_id, new_head_sha1): review = dbutils.Review.fromId(db, review_id) old_head = review.branch.getHead(db) new_head = gitutils.Commit.fromSHA1(db, review.repository, new_head_sha1) mergebase = review.repository.mergebase([old_head, new_head]) sha1s = review.repository.revlist([new_head], [mergebase]) valid = True for sha1 in sha1s: commit = gitutils.Commit.fromSHA1(db, review.repository, sha1) if commit.tree == old_head.tree: break else: valid = False return OperationResult(valid=valid)
def process(self, db, user, filter_id): cursor = db.cursor() cursor.execute( """SELECT uid FROM filters WHERE id=%s""", (filter_id, )) row = cursor.fetchone() if row: if user.id != row[0]: Operation.requireAdministratorRole(db, user) cursor.execute( """DELETE FROM filters WHERE id=%s""", (filter_id, )) db.commit() return OperationResult()
def process(self, db, user, review): if review.branch.archived: raise OperationFailure( code="invalidstate", title="Branch already archived!", message="The review's branch has already been archived.") if review.state not in ("closed", "dropped"): raise OperationFailure( code="invalidstate", title="Invalid review state!", message=("The review must be closed or dropped to archive " "its branch.")) review.branch.archive(db) review.cancelScheduledBranchArchival(db) db.commit() return OperationResult()
def process(self, db, user, remote, pattern=None): if pattern: regexp = re.compile(pattern.replace("*", ".*")) else: regexp = None try: refs = gitutils.Repository.lsremote(remote, regexp=regexp) except gitutils.GitCommandError as error: if error.output.splitlines()[0].endswith( "does not appear to be a git repository"): raise OperationFailure( code="invalidremote", title="Invalid remote!", message= ("<code>%s</code> does not appear to be a valid Git repository." % htmlutils.htmlify(remote)), is_html=True) else: raise else: branches = dict([(ref[1], ref[0]) for ref in refs]) return OperationResult(branches=branches)
def process(self, db, user, filter_id): cursor = db.cursor() cursor.execute("SELECT review FROM reviewfilters WHERE id=%s", (filter_id, )) review_id = cursor.fetchone() if not review_id: raise OperationFailure( code="nosuchfilter", title="No such filter!", message=("Maybe the filter has been deleted since you " "loaded this page?")) cursor.execute("DELETE FROM reviewfilters WHERE id=%s", (filter_id, )) review = dbutils.Review.fromId(db, review_id) review.incrementSerial(db) db.commit() return OperationResult()
def process(self, db, user, values, review_id=None, changeset_ids=None): cursor = db.cursor() data = {} if "users" in values: cursor.execute("SELECT name, fullname FROM users WHERE status!='retired'") data["users"] = dict(cursor) if "paths" in values: if review_id is not None: cursor.execute("""SELECT files.path, SUM(reviewfiles.deleted), SUM(reviewfiles.inserted) FROM files JOIN reviewfiles ON (reviewfiles.file=files.id) WHERE reviewfiles.review=%s GROUP BY files.id""", (review_id,)) elif changeset_ids is not None: cursor.execute("""SELECT files.path, SUM(chunks.deleteCount), SUM(chunks.insertCount) FROM files JOIN chunks ON (chunks.file=files.id) WHERE chunks.changeset=ANY (%s) GROUP BY files.id""", (changeset_ids,)) else: raise OperationError("paths requested, but neither review_id nor changeset_ids given") paths = {} for filename, deleted, inserted in cursor: paths[filename] = (0, deleted, inserted) components = filename.split("/") for index in range(len(components) - 1, 0, -1): directory = "/".join(components[:index]) + "/" nfiles, current_deleted, current_inserted = paths.get(directory, (0, 0, 0)) paths[directory] = nfiles + 1, current_deleted + deleted, current_inserted + inserted data["paths"] = paths return OperationResult(**data)
def process(self, db, user, chain_id, new_type): chain = CommentChain.fromId(db, chain_id, user) review = chain.review if chain.type == new_type: raise OperationError("the comment chain's type is already '%s'" % new_type) elif new_type == "note" and chain.state in ("closed", "addressed"): raise OperationError( "can't convert resolved or addressed issue to a note") cursor = db.cursor() if chain.state == "draft": # The chain is still a draft; just change its type directly. cursor.execute( """UPDATE commentchains SET type=%s WHERE id=%s""", (new_type, chain.id)) elif chain.type_is_draft: # The user is reverting a draft chain type change; just undo the # draft change. cursor.execute( """DELETE FROM commentchainchanges WHERE chain=%s AND uid=%s AND to_type IS NOT NULL""", (chain.id, user.id)) else: # Otherwise insert a new row into the commentchainchanges table. cursor.execute( """INSERT INTO commentchainchanges (uid, chain, from_type, to_type) VALUES (%s, %s, %s, %s)""", (user.id, chain.id, chain.type, new_type)) db.commit() return OperationResult(draft_status=review.getDraftStatus(db, user))
def process(req, db, user, review_id, reviewed, changeset_ids, file_ids): review = dbutils.Review.fromId(db, review_id) cursor = db.cursor() # Revert any draft changes the user has for the specified files in # the specified changesets. cursor.execute( """DELETE FROM reviewfilechanges USING reviewfiles WHERE reviewfilechanges.uid=%s AND reviewfilechanges.state='draft' AND reviewfilechanges.file=reviewfiles.id AND reviewfiles.review=%s AND reviewfiles.changeset=ANY (%s) AND reviewfiles.file=ANY (%s)""", (user.id, review.id, changeset_ids, file_ids)) if reviewed: from_state, to_state = 'pending', 'reviewed' else: from_state, to_state = 'reviewed', 'pending' # Insert draft changes for every file whose state would be updated. cursor.execute( """INSERT INTO reviewfilechanges (file, uid, "from", "to") SELECT reviewfiles.id, reviewuserfiles.uid, reviewfiles.state, %s FROM reviewfiles JOIN reviewuserfiles ON (reviewuserfiles.file=reviewfiles.id AND reviewuserfiles.uid=%s) WHERE reviewfiles.review=%s AND reviewfiles.state=%s AND reviewfiles.changeset=ANY (%s) AND reviewfiles.file=ANY (%s)""", (to_state, user.id, review.id, from_state, changeset_ids, file_ids)) db.commit() return OperationResult(draft_status=review.getDraftStatus(db, user))
def process(self, db, user, repository, sha1): try: commit = gitutils.Commit.fromSHA1(db, repository, sha1) except gitutils.GitReferenceError: raise OperationFailure(code="invalidsha1", title="Invalid SHA-1", message="No such commit: %s in %s" % (sha1, repository.path)) suggestions = {} cursor = db.readonly_cursor() cursor.execute( """SELECT reviews.id FROM reviews WHERE reviews.summary=%s""", (commit.summary(), )) for review_id, in cursor: review = dbutils.Review.fromId(db, review_id) if review.state != 'dropped': suggestions[review_id] = review.getReviewState(db) return OperationResult(summary=commit.summary(), reviews=reviews)
def process(self, db, user, repository_name, path, user_id=None): if user_id is None: user_id = user.id repository = gitutils.Repository.fromName(db, repository_name) path = reviewing.filters.sanitizePath(path) cursor = db.cursor() cursor.execute( """SELECT path FROM filters WHERE repository=%s AND uid=%s""", ( repository.id, user_id, )) paths = set(filter_path for (filter_path, ) in cursor) paths.add(path) return OperationResult(paths=reviewing.filters.getMatchedFiles( repository, list(paths))[path])
def process(self, db, user, branch_id): cursor = db.cursor() if not user.hasRole(db, "administrator"): cursor.execute( """SELECT 1 FROM trackedbranchusers WHERE branch=%s AND uid=%s""", (branch_id, user.id)) if not cursor.fetchone(): raise OperationFailure(code="notallowed", title="Not allowed!", message="Operation not permitted.") cursor.execute( """DELETE FROM trackedbranches WHERE id=%s""", (branch_id, )) db.commit() return OperationResult()
def process(self, db, user, new_pw, subject=None, current_pw=None): if subject is None: subject = user cursor = db.cursor() if user != subject: Operation.requireRole(db, "administrator", user) elif current_pw is None: cursor.execute("SELECT password FROM users WHERE id=%s", (subject.id,)) if cursor.fetchone()[0] is not None: # This is mostly a sanity check; the only way to trigger this is # if the user has no password when he loads /home, sets a # password in another tab or using another browser, and then # tries to set (rather than change) the password using the old # stale /home. raise OperationFailure(code="wrongpassword", title="Wrong password!", message="No current password provided.") if current_pw is not None: try: auth.checkPassword(db, subject.name, current_pw) except auth.WrongPassword: raise OperationFailure(code="wrongpassword", title="Wrong password!", message="The provided current password is not correct.") if not new_pw: raise OperationFailure(code="emptypassword", title="Empty password!", message="Setting an empty password is not allowed.") cursor.execute("UPDATE users SET password=%s WHERE id=%s", (auth.hashPassword(new_pw), subject.id)) db.commit() return OperationResult()
def process(self, db, user, review_id): review = dbutils.Review.fromId(db, review_id) tails = review.getFilteredTails() if len(tails) > 1: raise OperationError("Multiple tail commits.") try: from customization.filtertags import getUpstreamPattern except ImportError: def getUpstreamTagPattern(review): pass tail = tails.pop() tags = review.branch.repository.run("tag", "-l", "--contains", tail, getUpstreamTagPattern(review) or "*").splitlines() cursor = db.cursor() upstreams = [] for tag in tags: cursor.execute("SELECT sha1 FROM tags WHERE repository=%s AND name=%s", (review.branch.repository.id, tag)) if cursor.fetchone()[0] != tail: upstreams.append(tag) return OperationResult(upstreams=upstreams)
class GetServiceLog(Operation): def __init__(self): Operation.__init__(self, {"service_name": str, "lines": Optional(int)}) def process(self, db, user, service_name, lines=40): logfile_paths = { "manager": configuration.services.SERVICEMANAGER["logfile_path"] } for service in configuration.services.SERVICEMANAGER["services"]: logfile_paths[service["name"]] = service["logfile_path"] logfile_path = logfile_paths.get(service_name) if not logfile_path: raise OperationError, "unknown service: %s" % service_name try: logfile = open(logfile_path) except OSError, error: raise OperationError, "failed to open logfile: %s" % error.message return OperationResult(lines=logfile.read().splitlines()[-lines:])
def process(self, db, user, chain_ids=None, review_ids=None): cursor = db.cursor() if chain_ids: cursor.execute("""DELETE FROM commentstoread USING comments WHERE commentstoread.uid=%s AND commentstoread.comment=comments.id AND comments.chain=ANY (%s)""", (user.id, chain_ids)) if review_ids: cursor.execute("""DELETE FROM commentstoread USING comments, commentchains WHERE commentstoread.uid=%s AND commentstoread.comment=comments.id AND comments.chain=commentchains.id AND commentchains.review=ANY (%s)""", (user.id, review_ids)) db.commit() return OperationResult()
def process(self, db, user, chain_ids=None, review_ids=None): cursor = db.cursor() if chain_ids: cursor.execute("""DELETE FROM commentstoread WHERE uid=%s AND comment IN (SELECT id FROM comments WHERE chain=ANY (%s))""", (user.id, chain_ids)) if review_ids: cursor.execute("""DELETE FROM commentstoread WHERE uid=%s AND comment IN (SELECT comments.id FROM comments JOIN commentchains ON (commentchains.id=comments.chain) WHERE commentchains.review=ANY (%s))""", (user.id, review_ids)) db.commit() return OperationResult()
def process(self, db, user, branch_id): cursor = db.cursor() if not user.hasRole(db, "administrator"): cursor.execute( """SELECT 1 FROM trackedbranchusers WHERE branch=%s AND uid=%s""", (branch_id, user.id)) if not cursor.fetchone(): raise OperationFailure(code="notallowed", title="Not allowed!", message="Operation not permitted.") review_state = getTrackedBranchReviewState(db, branch_id) if review_state is not None and review_state != "open": raise OperationFailure( code="reviewnotopen", title="The review is not open!", message= "You need to reopen the review before new commits can be added to it." ) cursor.execute( """UPDATE trackedbranches SET next=NULL WHERE id=%s""", (branch_id, )) db.commit() pid = int( open(configuration.services.BRANCHTRACKER["pidfile_path"]).read(). strip()) os.kill(pid, signal.SIGHUP) return OperationResult()
def process(self, db, user, comment_id): comment = Comment.fromId(db, comment_id, user) if user != comment.user: raise OperationError("can't delete comment written by another user") if comment.state != "draft": raise OperationError("can't delete comment that has been submitted") cursor = db.cursor() cursor.execute("""UPDATE comments SET state='deleted' WHERE id=%s""", (comment.id,)) if comment.chain.state == "draft": # If the comment chain was a draft, then delete it as well. cursor.execute("""UPDATE commentchains SET state='empty' WHERE id=%s""", (comment.chain.id,)) db.commit() return OperationResult(draft_status=comment.chain.review.getDraftStatus(db, user))
def process(self, db, user, values, review_id=None): cursor = db.cursor() data = {} if "users" in values: cursor.execute( "SELECT name, fullname FROM users WHERE status!='retired' ORDER BY name" ) data["users"] = dict(cursor) if review_id is not None: if "paths" in values: cursor.execute( """SELECT fullfilename(file), deleted, inserted FROM (SELECT file, SUM(deleted) AS deleted, SUM(inserted) AS inserted FROM reviewfiles WHERE review=%s GROUP BY file) AS files""", (review_id, )) paths = {} for filename, deleted, inserted in cursor: paths[filename] = (0, deleted, inserted) components = filename.split("/") for index in range(len(components) - 1, 0, -1): directory = "/".join(components[:index]) + "/" nfiles, current_deleted, current_inserted = paths.get( directory, (0, 0, 0)) paths[ directory] = nfiles + 1, current_deleted + deleted, current_inserted + inserted data["paths"] = paths return OperationResult(**data)
def process(self, db, user, review_id): review = dbutils.Review.fromId(db, review_id) tails = review.getFilteredTails() available = "both" if len(tails) == 1 else "inplace" return OperationResult(available=available)
def process(self, db, user, review_id, rebase_id): review = dbutils.Review.fromId(db, review_id) cursor = db.cursor() cursor.execute("SELECT old_head, new_head, new_upstream FROM reviewrebases WHERE id=%s", (rebase_id,)) old_head_id, new_head_id, new_upstream_id = cursor.fetchone() cursor.execute("SELECT commit FROM previousreachable WHERE rebase=%s", (rebase_id,)) reachable = [commit_id for (commit_id,) in cursor] if not reachable: # Fail if rebase was done before the 'previousreachable' table was # added, and we thus don't know what commits the branch contained # before the rebase. raise OperationError("Automatic revert not supported; rebase is pre-historic.") if review.branch.head.getId(db) != new_head_id: raise OperationError("Commits added to review after rebase; need to remove them first.") old_head = gitutils.Commit.fromId(db, review.repository, old_head_id) new_head = gitutils.Commit.fromId(db, review.repository, new_head_id) cursor.execute("DELETE FROM reachable WHERE branch=%s", (review.branch.id,)) cursor.executemany("INSERT INTO reachable (branch, commit) VALUES (%s, %s)", [(review.branch.id, commit_id) for commit_id in reachable]) if new_upstream_id: new_upstream = gitutils.Commit.fromId(db, review.repository, new_upstream_id) if len(old_head.parents) == 2 and old_head.parents[1] == new_upstream.sha1: # Equivalent merge commit was added; remove it too. # Reopen any issues marked as addressed by the merge commit. cursor.execute("""UPDATE commentchains SET state='open', addressed_by=NULL WHERE review=%s AND state='addressed' AND addressed_by=%s""", (review.id, old_head_id)) # Delete any mappings of issues (or notes) to lines in the merge # commit. cursor.execute("""DELETE FROM commentchainlines USING commentchains WHERE commentchains.review=%s AND commentchains.id=commentchainlines.chain AND commentchainlines.commit=%s""", (review.id, old_head_id)) # Delete the review changesets (and, via cascade, all related # assignments.) cursor.execute("""DELETE FROM reviewchangesets USING changesets WHERE reviewchangesets.review=%s AND reviewchangesets.changeset=changesets.id AND changesets.child=%s""", (review.id, old_head_id)) old_head = gitutils.Commit.fromSHA1(db, review.repository, old_head.parents[0]) old_head_id = old_head.getId(db) cursor.execute("UPDATE branches SET head=%s WHERE id=%s", (old_head_id, review.branch.id)) cursor.execute("DELETE FROM reviewrebases WHERE id=%s", (rebase_id,)) db.commit() review.repository.run("update-ref", "refs/heads/%s" % review.branch.name, old_head.sha1, new_head.sha1) return OperationResult()
def process(self, db, user, review_id): review = dbutils.Review.fromId(db, review_id) doCancelRebase(db, user, review) return OperationResult()
def process(self, db, user, review_id, new_upstream=None, branch=None): review = dbutils.Review.fromId(db, review_id) doPrepareRebase(db, user, review, new_upstream, branch) return OperationResult()
def apply(self, line, state): result = OperationResult(line, False) trimmed = stripComments(line) output = line expanded_line = line # find the directive dirsearch = regex['directive'].search(trimmed) if dirsearch: directive = dirsearch.group(1) identifier = dirsearch.group(2) output = commentLine(line) if directive == "#macro": if self.macro: warnings.add("Trying to define multiline macro %s inside other macro %s" % (identifier, self.macro.name)) return result self.macro = Macro(dirsearch, trimmed) self.payload = "" elif directive == "#endmacro": #print ("macro %s ends") % (self.macro.name) self.macro.payload = self.macro.payload.rstrip('\n') self.multimacros[self.macro.name] = self.macro self.macro = None # TODO this is basically duplicate of the above functionality, clean it up elif directive == "#lambda": if self.macro: warnings.add("Trying to define multiline lambda %s inside other macro %s" % (identifier, self.macro.name)) return result self.macro = Macro(dirsearch, trimmed) self.macro.oneliner = True self.payload = "" elif directive == "#endlambda": #print ("macro %s ends") % (self.macro.name) self.macro.payload = self.macro.payload.rstrip('\n') self.macro.payload = re.sub("\n+", r':', self.macro.payload) self.multimacros[self.macro.name] = self.macro self.macro = None elif directive == "#undef": temp_macro = Macro(dirsearch, trimmed) if temp_macro.name in self.multimacros: del self.multimacros[temp_macro.name] else: output = output else: if state.args.nomacros: return result # Expand collected macros only if not inside a multiline macro. if self.macro: line_trimmed = line if self.macro.oneliner: line_trimmed = line.lstrip(" ").lstrip("\t") self.macro.payload += line_trimmed output = commentLine(output) else: output = expandAll(line, self.multimacros, Stack(), state) result.line = output return result
def process(self, db, user, review_id, merge_sha1=None, new_head_sha1=None, new_upstream_sha1=None): review = dbutils.Review.fromId(db, review_id) if merge_sha1 is not None: merge = gitutils.Commit.fromSHA1(db, review.repository, merge_sha1) changesets = changeset_utils.createChangeset(db, user, review.repository, merge, conflicts=True, do_highlight=False) url = "/showcommit?repository=%d&sha1=%s&conflicts=yes" % ( review.repository.id, merge.sha1) else: upstreams = review.getCommitSet(db).getFilteredTails( review.repository) if len(upstreams) > 1: return OperationResult(rebase_supported=False) old_head = review.branch.getHead(db) old_upstream = gitutils.Commit.fromSHA1(db, review.repository, upstreams.pop()) new_head = gitutils.Commit.fromSHA1(db, review.repository, new_head_sha1) new_upstream = gitutils.Commit.fromSHA1(db, review.repository, new_upstream_sha1) replay = reviewing.rebase.replayRebase(db, review, user, old_head, old_upstream, new_head, new_upstream) changesets = changeset_utils.createChangeset(db, user, review.repository, from_commit=replay, to_commit=new_head, conflicts=True, do_highlight=False) url = "/showcommit?repository=%d&from=%s&to=%s&conflicts=yes" % ( review.repository.id, replay.sha1, new_head.sha1) has_changes = False has_conflicts = False for changed_file in changesets[0].files: changed_file.loadOldLines() file_has_conflicts = False for chunk in changed_file.chunks: lines = changed_file.getOldLines(chunk) for line in lines: if line.startswith("<<<<<<<"): has_conflicts = file_has_conflicts = True break if file_has_conflicts: break if not file_has_conflicts: has_changes = True return OperationResult(has_conflicts=has_conflicts, has_changes=has_changes, url=url)
def process(self, db, user, review_id, user_name, files): reviewer = dbutils.User.fromName(db, user_name) new_file_ids = set(files) cursor = db.cursor() cursor.execute("SELECT 1 FROM reviewusers WHERE review=%s AND uid=%s", (review_id, reviewer.id)) if not cursor.fetchone(): cursor.execute( "INSERT INTO reviewusers (review, uid) VALUES (%s, %s)", (review_id, reviewer.id)) current_file_ids = set() else: cursor.execute( "SELECT file FROM fullreviewuserfiles WHERE review=%s AND assignee=%s", (review_id, reviewer.id)) current_file_ids = set(file_id for (file_id, ) in cursor) delete_file_ids = current_file_ids - new_file_ids new_file_ids -= current_file_ids if delete_file_ids or new_file_ids: cursor.execute( "INSERT INTO reviewassignmentstransactions (review, assigner) VALUES (%s, %s) RETURNING id", (review_id, user.id)) transaction_id = cursor.fetchone()[0] if delete_file_ids: cursor.executemany( """INSERT INTO reviewassignmentchanges (transaction, file, uid, assigned) SELECT %s, reviewfiles.id, reviewuserfiles.uid, false FROM reviewfiles JOIN reviewuserfiles ON (reviewuserfiles.file=reviewfiles.id) WHERE reviewfiles.review=%s AND reviewfiles.file=%s AND reviewuserfiles.uid=%s""", itertools.izip(itertools.repeat(transaction_id), itertools.repeat(review_id), delete_file_ids, itertools.repeat(reviewer.id))) cursor.executemany( """DELETE FROM reviewuserfiles USING reviewfiles WHERE reviewuserfiles.file=reviewfiles.id AND reviewfiles.review=%s AND reviewfiles.file=%s AND reviewuserfiles.uid=%s""", itertools.izip(itertools.repeat(review_id), delete_file_ids, itertools.repeat(reviewer.id))) if new_file_ids: cursor.executemany( """INSERT INTO reviewuserfiles (file, uid) SELECT reviewfiles.id, %s FROM reviewfiles WHERE reviewfiles.review=%s AND reviewfiles.file=%s""", itertools.izip(itertools.repeat(reviewer.id), itertools.repeat(review_id), new_file_ids)) cursor.executemany( """INSERT INTO reviewassignmentchanges (transaction, file, uid, assigned) SELECT %s, reviewfiles.id, %s, true FROM reviewfiles WHERE reviewfiles.review=%s AND reviewfiles.file=%s""", itertools.izip(itertools.repeat(transaction_id), itertools.repeat(reviewer.id), itertools.repeat(review_id), new_file_ids)) if delete_file_ids or new_file_ids: cursor.execute("UPDATE reviews SET serial=serial+1 WHERE id=%s", (review_id, )) pending_mails = review.utils.generateMailsForAssignmentsTransaction( db, transaction_id) db.commit() mailutils.sendPendingMails(pending_mails) return OperationResult()
def process(self, db, user, review_id, origin, parent_id, child_id, file_id, offset, count): review = dbutils.Review.fromId(db, review_id) verdict, data = validateCommentChain(db, review, origin, parent_id, child_id, file_id, offset, count) return OperationResult(verdict=verdict, **data)