Пример #1
0
	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
Пример #2
0
    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
Пример #3
0
	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
Пример #4
0
	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
Пример #5
0
	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
Пример #6
0
	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
Пример #7
0
	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
Пример #8
0
	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
Пример #9
0
    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))
Пример #10
0
    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:])
Пример #11
0
    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))
Пример #12
0
    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
                               })
Пример #13
0
    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)
Пример #14
0
    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()
Пример #15
0
    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()
Пример #16
0
    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)
Пример #17
0
    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()
Пример #18
0
    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)
Пример #19
0
    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))
Пример #20
0
    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))
Пример #21
0
    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)
Пример #22
0
    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])
Пример #23
0
    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()
Пример #24
0
    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()
Пример #25
0
    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)
Пример #26
0
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:])
Пример #27
0
    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()
Пример #28
0
    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()
Пример #29
0
    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()
Пример #30
0
    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))
Пример #31
0
    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)
Пример #32
0
    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)
Пример #33
0
    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()
Пример #34
0
 def process(self, db, user, review_id):
     review = dbutils.Review.fromId(db, review_id)
     doCancelRebase(db, user, review)
     return OperationResult()
Пример #35
0
 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()
Пример #36
0
	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
Пример #37
0
    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)
Пример #38
0
    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()
Пример #39
0
 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)