예제 #1
0
def _main():
    myauth = HTTPDigestAuth('account', 'password')
    rest = GerritRestAPI(url='http://code...', auth=myauth)

    try:
        """
        conditions
        """
        query = ["status:open"]
        query += ["owner:leon5209"]
        query += ["age:1week"]
        changes = rest.get("/changes/?q=%s" % "%20".join(query))
        logging.debug("there are %d changes", len(changes))
        """
        abandon
        """
        for change in changes:
            logging.debug("subject : %s ", change['subject'])
            logging.debug("change id : %s ", change['change_id'])

            # we don't kill draft
            if change['status'] == "DRAFT":
                logging.debug("skip, we dont abandon draft")
            else:
                logging.debug("commit out of date , abandon!")
                rest.post("/changes/" + change['change_id'] + "/abandon",
                          json={
                              "message":
                              "This Commit is out of date, auto abandon! "
                          })

    except RequestException as err:
        logging.error("Error: %s", str(err))
예제 #2
0
def _main():
    parser = optparse.OptionParser()
    parser.add_option('-g', '--gerrit-url', dest='gerrit_url',
                      metavar='URL',
                      default=None,
                      help='gerrit server URL')
    parser.add_option('-b', '--basic-auth', dest='basic_auth',
                      action='store_true',
                      help='(deprecated) use HTTP basic authentication instead'
                      ' of digest')
    parser.add_option('-d', '--digest-auth', dest='digest_auth',
                      action='store_true',
                      help='use HTTP digest authentication instead of basic')
    parser.add_option('-n', '--dry-run', dest='dry_run',
                      action='store_true',
                      help='enable dry-run mode: show stale changes but do '
                           'not abandon them')
    parser.add_option('-a', '--age', dest='age',
                      metavar='AGE',
                      default="6months",
                      help='age of change since last update '
                           '(default: %default)')
    parser.add_option('-m', '--message', dest='message',
                      metavar='STRING', default=None,
                      help='Custom message to append to abandon message')
    parser.add_option('--branch', dest='branches', metavar='BRANCH_NAME',
                      default=[], action='append',
                      help='Abandon changes only on the given branch')
    parser.add_option('--exclude-branch', dest='exclude_branches',
                      metavar='BRANCH_NAME',
                      default=[],
                      action='append',
                      help='Do not abandon changes on given branch')
    parser.add_option('--project', dest='projects', metavar='PROJECT_NAME',
                      default=[], action='append',
                      help='Abandon changes only on the given project')
    parser.add_option('--exclude-project', dest='exclude_projects',
                      metavar='PROJECT_NAME',
                      default=[],
                      action='append',
                      help='Do not abandon changes on given project')
    parser.add_option('--owner', dest='owner',
                      metavar='USERNAME',
                      default=None,
                      action='store',
                      help='Only abandon changes owned by the given user')
    parser.add_option('-v', '--verbose', dest='verbose',
                      action='store_true',
                      help='enable verbose (debug) logging')

    (options, _args) = parser.parse_args()

    level = logging.DEBUG if options.verbose else logging.INFO
    logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s',
                        level=level)

    if not options.gerrit_url:
        logging.error("Gerrit URL is required")
        return 1

    pattern = re.compile(r"^([\d]+)(month[s]?|year[s]?|week[s]?)")
    match = pattern.match(options.age)
    if not match:
        logging.error("Invalid age: %s", options.age)
        return 1
    message = "Abandoning after %s %s or more of inactivity." % \
        (match.group(1), match.group(2))

    if options.digest_auth:
        auth_type = HTTPDigestAuthFromNetrc
    else:
        auth_type = HTTPBasicAuthFromNetrc

    try:
        auth = auth_type(url=options.gerrit_url)
        gerrit = GerritRestAPI(url=options.gerrit_url, auth=auth)
    except Exception as e:
        logging.error(e)
        return 1

    logging.info(message)
    try:
        stale_changes = []
        offset = 0
        step = 500
        query_terms = ["status:new", "age:%s" % options.age]
        if options.branches:
            query_terms += ["branch:%s" % b for b in options.branches]
        elif options.exclude_branches:
            query_terms += ["-branch:%s" % b for b in options.exclude_branches]
        if options.projects:
            query_terms += ["project:%s" % p for p in options.projects]
        elif options.exclude_projects:
            query_terms = ["-project:%s" % p for p in options.exclude_projects]
        if options.owner:
            query_terms += ["owner:%s" % options.owner]
        query = "%20".join(query_terms)
        while True:
            q = query + "&n=%d&S=%d" % (step, offset)
            logging.debug("Query: %s", q)
            url = "/changes/?q=" + q
            result = gerrit.get(url)
            logging.debug("%d changes", len(result))
            if not result:
                break
            stale_changes += result
            last = result[-1]
            if "_more_changes" in last:
                logging.debug("More...")
                offset += step
            else:
                break
    except Exception as e:
        logging.error(e)
        return 1

    abandoned = 0
    errors = 0
    abandon_message = message
    if options.message:
        abandon_message += "\n\n" + options.message
    for change in stale_changes:
        number = change["_number"]
        try:
            owner = change["owner"]["name"]
        except:
            owner = "Unknown"
        subject = change["subject"]
        if len(subject) > 70:
            subject = subject[:65] + " [...]"
        change_id = change["id"]
        logging.info("%s (%s): %s", number, owner, subject)
        if options.dry_run:
            continue

        try:
            gerrit.post("/changes/" + change_id + "/abandon",
                        data='{"message" : "%s"}' % abandon_message)
            abandoned += 1
        except Exception as e:
            errors += 1
            logging.error(e)
    logging.info("Total %d stale open changes", len(stale_changes))
    if not options.dry_run:
        logging.info("Abandoned %d changes. %d errors.", abandoned, errors)
예제 #3
0
def _main():
    parser = optparse.OptionParser()
    parser.add_option('-g', '--gerrit-url', dest='gerrit_url',
                      metavar='URL',
                      default=None,
                      help='gerrit server URL')
    parser.add_option('-b', '--basic-auth', dest='basic_auth',
                      action='store_true',
                      help='use HTTP basic authentication instead of digest')
    parser.add_option('-n', '--dry-run', dest='dry_run',
                      action='store_true',
                      help='enable dry-run mode: show stale changes but do '
                           'not abandon them')
    parser.add_option('-a', '--age', dest='age',
                      metavar='AGE',
                      default="6months",
                      help='age of change since last update '
                           '(default: %default)')
    parser.add_option('-m', '--message', dest='message',
                      metavar='STRING', default=None,
                      help='Custom message to append to abandon message')
    parser.add_option('--branch', dest='branches', metavar='BRANCH_NAME',
                      default=[], action='append',
                      help='Abandon changes only on the given branch')
    parser.add_option('--exclude-branch', dest='exclude_branches',
                      metavar='BRANCH_NAME',
                      default=[],
                      action='append',
                      help='Do not abandon changes on given branch')
    parser.add_option('--project', dest='projects', metavar='PROJECT_NAME',
                      default=[], action='append',
                      help='Abandon changes only on the given project')
    parser.add_option('--exclude-project', dest='exclude_projects',
                      metavar='PROJECT_NAME',
                      default=[],
                      action='append',
                      help='Do not abandon changes on given project')
    parser.add_option('--owner', dest='owner',
                      metavar='USERNAME',
                      default=None,
                      action='store',
                      help='Only abandon changes owned by the given user')
    parser.add_option('-v', '--verbose', dest='verbose',
                      action='store_true',
                      help='enable verbose (debug) logging')

    (options, _args) = parser.parse_args()

    level = logging.DEBUG if options.verbose else logging.INFO
    logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s',
                        level=level)

    if not options.gerrit_url:
        logging.error("Gerrit URL is required")
        return 1

    pattern = re.compile(r"^([\d]+)(month[s]?|year[s]?|week[s]?)")
    match = pattern.match(options.age)
    if not match:
        logging.error("Invalid age: %s", options.age)
        return 1
    message = "Abandoning after %s %s or more of inactivity." % \
        (match.group(1), match.group(2))

    if options.basic_auth:
        auth_type = HTTPBasicAuthFromNetrc
    else:
        auth_type = HTTPDigestAuthFromNetrc

    try:
        auth = auth_type(url=options.gerrit_url)
        gerrit = GerritRestAPI(url=options.gerrit_url, auth=auth)
    except Exception as e:
        logging.error(e)
        return 1

    logging.info(message)
    try:
        stale_changes = []
        offset = 0
        step = 500
        query_terms = ["status:new", "age:%s" % options.age]
        if options.branches:
            query_terms += ["branch:%s" % b for b in options.branches]
        elif options.exclude_branches:
            query_terms += ["-branch:%s" % b for b in options.exclude_branches]
        if options.projects:
            query_terms += ["project:%s" % p for p in options.projects]
        elif options.exclude_projects:
            query_terms = ["-project:%s" % p for p in options.exclude_projects]
        if options.owner:
            query_terms += ["owner:%s" % options.owner]
        query = "%20".join(query_terms)
        while True:
            q = query + "&n=%d&S=%d" % (step, offset)
            logging.debug("Query: %s", q)
            url = "/changes/?q=" + q
            result = gerrit.get(url)
            logging.debug("%d changes", len(result))
            if not result:
                break
            stale_changes += result
            last = result[-1]
            if "_more_changes" in last:
                logging.debug("More...")
                offset += step
            else:
                break
    except Exception as e:
        logging.error(e)
        return 1

    abandoned = 0
    errors = 0
    abandon_message = message
    if options.message:
        abandon_message += "\n\n" + options.message
    for change in stale_changes:
        number = change["_number"]
        try:
            owner = change["owner"]["name"]
        except:
            owner = "Unknown"
        subject = change["subject"]
        if len(subject) > 70:
            subject = subject[:65] + " [...]"
        change_id = change["id"]
        logging.info("%s (%s): %s", number, owner, subject)
        if options.dry_run:
            continue

        try:
            gerrit.post("/changes/" + change_id + "/abandon",
                        data='{"message" : "%s"}' % abandon_message)
            abandoned += 1
        except Exception as e:
            errors += 1
            logging.error(e)
    logging.info("Total %d stale open changes", len(stale_changes))
    if not options.dry_run:
        logging.info("Abandoned %d changes. %d errors.", abandoned, errors)
예제 #4
0
def _main():
    descr = "Perform bulk operations on Gerrit"
    parser = argparse.ArgumentParser(
        description=descr, formatter_class=argparse.ArgumentDefaultsHelpFormatter
    )
    parser.add_argument(
        "-u",
        "--gerrit-url",
        dest="url",
        required=False,
        default="https://gerrit-review.googlesource.com",
        help="Gerrit URL",
    )
    parser.add_argument(
        "-q", "--query", dest="query", required=True, action="store", help="query"
    )
    parser.add_argument(
        "-o",
        "--option",
        dest="options",
        required=False,
        action="append",
        help="query options",
    )
    parser.add_argument(
        "-c",
        "--commands",
        dest="commands",
        required=False,
        action="store_true",
        help="how to fetch changes; appends -o " + REVISION + " -o " + COMMANDS,
    )
    parser.add_argument(
        "-a",
        "--approve",
        dest="approve",
        required=False,
        action="store_true",
        help="apply Code-Review+2 to changes",
    )
    parser.add_argument(
        "-v",
        "--verify",
        dest="verify",
        required=False,
        action="store_true",
        help="apply Verified+1 to changes",
    )
    parser.add_argument(
        "-s",
        "--submit",
        dest="submit",
        required=False,
        action="store_true",
        help="submit changes",
    )
    parser.add_argument(
        "-f",
        "--filter",
        dest="filter",
        required=False,
        help="filter changes by project prefix",
    )
    parser.add_argument(
        "-fs",
        "--subject",
        dest="subject",
        required=False,
        help="filter changes by subject prefix",
    )
    parser.add_argument(
        "--abandon",
        dest="abandon",
        required=False,
        action="store_true",
        help="abandon changes",
    )
    parser.add_argument(
        "--hashtag",
        dest="hashtags",
        required=False,
        action="append",
        help="add hashtags",
    )
    parser.add_argument(
        "-r",
        "--reviewer",
        dest="reviewers",
        required=False,
        action="append",
        help="add reviewers",
    )
    options = parser.parse_args()

    api = GerritRestAPI(url=options.url)
    query_terms = options.query.replace(" ", "%20")
    uri = "/changes/?q=" + query_terms
    query_options = [o.upper() for o in options.options] if options.options else []
    if options.commands:
        if REVISION not in query_options:
            query_options.append(REVISION)
        if COMMANDS not in query_options:
            query_options.append(COMMANDS)
    if query_options:
        uri += "".join(["&o=%s" % o for o in query_options])
    changes = api.get(uri)
    changes_count = len(changes)
    print("Found %d changes" % changes_count)
    if options.filter:
        changes = [c for c in changes if c["project"].startswith(options.filter)]
    if options.subject:
        changes = [c for c in changes if c["subject"].startswith(options.subject)]
    filtered_count = len(changes)
    if filtered_count < changes_count:
        print("Filtered out %d changes" % (changes_count - filtered_count))
    labels = {}
    review = {}
    if options.reviewers:
        review["reviewers"] = [{"reviewer": r} for r in options.reviewers]
    if options.verify:
        labels["Verified"] = 1
    if options.approve:
        labels["Code-Review"] = 2
    if labels:
        review["labels"] = labels
    for change in changes:
        print("%s : %s" % (change["project"], change["subject"]))
        try:
            if options.hashtags:
                hashtags = {"add": options.hashtags}
                api.post("/changes/%s/hashtags" % change["id"], json=hashtags)
            if options.abandon:
                api.post("/changes/%s/abandon" % change["id"])
                continue
            if review:
                api.post(
                    "/changes/%s/revisions/current/review" % change["id"], json=review
                )
            if options.submit:
                api.post("/changes/%s/submit" % change["id"])
        except Exception as e:
            print("Operation failed: %s" % e, file=sys.stderr)
    if options.commands:
        for change in changes:
            repo = change["project"].split("/")[-1]
            command = next(iter(change["revisions"].values()))["fetch"]["http"][
                "commands"
            ]["Checkout"]
            print("cd %s && %s && cd -" % (repo, command))
def _main():
    parser = optparse.OptionParser()
    parser.add_option(
        "-g",
        "--gerrit-url",
        dest="gerrit_url",
        metavar="URL",
        default=None,
        help="gerrit server URL",
    )
    parser.add_option(
        "-b",
        "--basic-auth",
        dest="basic_auth",
        action="store_true",
        help="(deprecated) use HTTP basic authentication instead of digest",
    )
    parser.add_option(
        "-d",
        "--digest-auth",
        dest="digest_auth",
        action="store_true",
        help="use HTTP digest authentication instead of basic",
    )
    parser.add_option(
        "-n",
        "--dry-run",
        dest="dry_run",
        action="store_true",
        help="enable dry-run mode: show stale changes but do not abandon them",
    )
    parser.add_option(
        "-t",
        "--test",
        dest="testmode",
        action="store_true",
        help="test mode: query changes with the `test-abandon` "
        "topic and ignore age option",
    )
    parser.add_option(
        "-a",
        "--age",
        dest="age",
        metavar="AGE",
        default="6months",
        help="age of change since last update in days, months"
        " or years (default: %default)",
    )
    parser.add_option(
        "-m",
        "--message",
        dest="message",
        metavar="STRING",
        default=None,
        help="custom message to append to abandon message",
    )
    parser.add_option(
        "--branch",
        dest="branches",
        metavar="BRANCH_NAME",
        default=[],
        action="append",
        help="abandon changes only on the given branch",
    )
    parser.add_option(
        "--exclude-branch",
        dest="exclude_branches",
        metavar="BRANCH_NAME",
        default=[],
        action="append",
        help="do not abandon changes on given branch",
    )
    parser.add_option(
        "--project",
        dest="projects",
        metavar="PROJECT_NAME",
        default=[],
        action="append",
        help="abandon changes only on the given project",
    )
    parser.add_option(
        "--exclude-project",
        dest="exclude_projects",
        metavar="PROJECT_NAME",
        default=[],
        action="append",
        help="do not abandon changes on given project",
    )
    parser.add_option(
        "--owner",
        dest="owner",
        metavar="USERNAME",
        default=None,
        action="store",
        help="only abandon changes owned by the given user",
    )
    parser.add_option(
        "--exclude-wip",
        dest="exclude_wip",
        action="store_true",
        help="Exclude changes that are Work-in-Progress",
    )
    parser.add_option(
        "-v",
        "--verbose",
        dest="verbose",
        action="store_true",
        help="enable verbose (debug) logging",
    )

    (options, _args) = parser.parse_args()

    level = logging.DEBUG if options.verbose else logging.INFO
    logging.basicConfig(format="%(asctime)s %(levelname)s %(message)s",
                        level=level)

    if not options.gerrit_url:
        logging.error("Gerrit URL is required")
        return 1

    if options.testmode:
        message = "Abandoning in test mode"
    else:
        pattern = re.compile(r"^([\d]+)(month[s]?|year[s]?|week[s]?)")
        match = pattern.match(options.age)
        if not match:
            logging.error("Invalid age: %s", options.age)
            return 1
        message = "Abandoning after %s %s or more of inactivity." % (
            match.group(1),
            match.group(2),
        )

    if options.digest_auth:
        auth_type = HTTPDigestAuthFromNetrc
    else:
        auth_type = HTTPBasicAuthFromNetrc

    try:
        auth = auth_type(url=options.gerrit_url)
        gerrit = GerritRestAPI(url=options.gerrit_url, auth=auth)
    except Exception as e:
        logging.error(e)
        return 1

    logging.info(message)
    try:
        stale_changes = []
        offset = 0
        step = 500
        if options.testmode:
            query_terms = ["status:new", "owner:self", "topic:test-abandon"]
        else:
            query_terms = ["status:new", "age:%s" % options.age]
        if options.exclude_wip:
            query_terms += ["-is:wip"]
        if options.branches:
            query_terms += ["branch:%s" % b for b in options.branches]
        elif options.exclude_branches:
            query_terms += ["-branch:%s" % b for b in options.exclude_branches]
        if options.projects:
            query_terms += ["project:%s" % p for p in options.projects]
        elif options.exclude_projects:
            query_terms = ["-project:%s" % p for p in options.exclude_projects]
        if options.owner and not options.testmode:
            query_terms += ["owner:%s" % options.owner]
        query = "%20".join(query_terms)
        while True:
            q = query + "&o=DETAILED_ACCOUNTS&n=%d&S=%d" % (step, offset)
            logging.debug("Query: %s", q)
            url = "/changes/?q=" + q
            result = gerrit.get(url)
            logging.debug("%d changes", len(result))
            if not result:
                break
            stale_changes += result
            last = result[-1]
            if "_more_changes" in last:
                logging.debug("More...")
                offset += step
            else:
                break
    except Exception as e:
        logging.error(e)
        return 1

    abandoned = 0
    errors = 0
    abandon_message = message
    if options.message:
        abandon_message += "\n\n" + options.message
    for change in stale_changes:
        number = change["_number"]
        project = ""
        if len(options.projects) != 1:
            project = "%s: " % change["project"]
        owner = ""
        if options.verbose:
            try:
                o = change["owner"]["name"]
            except KeyError:
                o = "Unknown"
            owner = " (%s)" % o
        subject = change["subject"]
        if len(subject) > 70:
            subject = subject[:65] + " [...]"
        change_id = change["id"]
        logging.info("%s%s: %s%s", number, owner, project, subject)
        if options.dry_run:
            continue

        try:
            gerrit.post(
                "/changes/" + change_id + "/abandon",
                json={"message": "%s" % abandon_message},
            )
            abandoned += 1
        except Exception as e:
            errors += 1
            logging.error(e)
    logging.info("Total %d stale open changes", len(stale_changes))
    if not options.dry_run:
        logging.info("Abandoned %d changes. %d errors.", abandoned, errors)