You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@impala.apache.org by ta...@apache.org on 2018/07/31 06:48:29 UTC
[3/5] impala git commit: IMPALA-7317: add scripts to post flake8
comments
IMPALA-7317: add scripts to post flake8 comments
The script is used by a new jenkins job gerrit-auto-critic
to post comments on code reviews.
Testing:
This patch deliberately contains some flake8 violations so
that gerrit-auto-critic will flag them.
Change-Id: I7d348ea4944f829a407bd7b2939654f272736170
Reviewed-on: http://gerrit.cloudera.org:8080/11054
Reviewed-by: Impala Public Jenkins <im...@cloudera.com>
Reviewed-by: Michael Brown <mi...@cloudera.com>
Tested-by: Impala Public Jenkins <im...@cloudera.com>
Project: http://git-wip-us.apache.org/repos/asf/impala/repo
Commit: http://git-wip-us.apache.org/repos/asf/impala/commit/47b46067
Tree: http://git-wip-us.apache.org/repos/asf/impala/tree/47b46067
Diff: http://git-wip-us.apache.org/repos/asf/impala/diff/47b46067
Branch: refs/heads/master
Commit: 47b4606742287361b8c3751b4db77ab5b3508783
Parents: 240fde6
Author: Tim Armstrong <ta...@cloudera.com>
Authored: Wed Jul 25 23:38:21 2018 -0700
Committer: Impala Public Jenkins <im...@cloudera.com>
Committed: Tue Jul 31 02:30:54 2018 +0000
----------------------------------------------------------------------
bin/jenkins/critique-gerrit-review.py | 130 +++++++++++++++++++++++++++++
1 file changed, 130 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/impala/blob/47b46067/bin/jenkins/critique-gerrit-review.py
----------------------------------------------------------------------
diff --git a/bin/jenkins/critique-gerrit-review.py b/bin/jenkins/critique-gerrit-review.py
new file mode 100755
index 0000000..3311793
--- /dev/null
+++ b/bin/jenkins/critique-gerrit-review.py
@@ -0,0 +1,130 @@
+#!/usr/bin/python
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# Usage: critique-gerrit-review.py <git commit>
+#
+# This script is meant to run on an jenkins.impala.io build slave and post back comments
+# to a code review. It does not need to run on all supported platforms so we use system
+# python instead of the full Impala virtualenv.
+#
+# This script runs in the context of a source checkout. It posts comments for issues
+# introduced between HEAD^ and HEAD. It picks up metadata from environment variables
+# set by the jenkins gerrit trigger: GERRIT_CHANGE_NUMBER, GERRIT_PATCHSET_NUMBER, etc.
+#
+# It uses the gerrit ssh interface to post the review, connecting as
+# impala-public-jenkins.
+# Ref: https://gerrit-review.googlesource.com/Documentation/cmd-review.html
+#
+# Dependencies:
+# ssh, pip, virtualenv
+#
+# TODO: generalise to other warnings
+# * Lines too long and trailing whitespace
+# * clang-tidy
+
+from collections import defaultdict
+import json
+import os
+from os import environ
+import os.path
+import re
+from subprocess import check_call, Popen, PIPE
+import sys
+import virtualenv
+
+FLAKE8_VERSION = "3.5.0"
+FLAKE8_DIFF_VERSION = "0.2.2"
+
+VENV_PATH = "gerrit_critic_venv"
+VENV_BIN = os.path.join(VENV_PATH, "bin")
+PIP_PATH = os.path.join(VENV_BIN, "pip")
+FLAKE8_DIFF_PATH = os.path.join(VENV_BIN, "flake8-diff")
+
+
+def setup_virtualenv():
+ """Set up virtualenv with flake8-diff."""
+ virtualenv.create_environment(VENV_PATH)
+ check_call([PIP_PATH, "install",
+ "flake8=={0}".format(FLAKE8_VERSION),
+ "flake8-diff=={0}".format(FLAKE8_DIFF_VERSION)])
+
+
+def get_flake8_comments(revision):
+ """Get flake8 warnings for code changes made in the git commit 'revision'.
+ Returns a dict with file path as keys and a list of CommentInput objects. See
+ https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#review-input
+ for information on the format."""
+ comments = defaultdict(lambda: [])
+ # flake8 needs to be on the path.
+ flake8_env = os.environ.copy()
+ flake8_env["PATH"] = "{0}:{1}".format(VENV_BIN, flake8_env["PATH"])
+
+ base_revision = "{0}^".format(revision)
+ flake8_diff_proc = Popen(
+ [FLAKE8_DIFF_PATH, "--standard-flake8-output", "--color", "off", base_revision,
+ revision],
+ stdin=PIPE, stdout=PIPE, stderr=PIPE, env=flake8_env)
+ stdout, stderr = flake8_diff_proc.communicate()
+ # Ignore the return code since it will be non-zero if any violations are found. We want
+ # to continue in that case. Instead check stderr for any errors.
+ if stderr:
+ raise Exception("Did not expect flake8-diff to write to stderr:\n{0}".format(stderr))
+
+ # Match output lines like:
+ # bin/jenkins/flake8-gerrit-review.py:25:1: F401 'json' imported but unused
+ VIOLATION_RE = re.compile(r"^([^:]*):([0-9]*):([0-9]*): (.*)$")
+
+ for line in stdout.splitlines():
+ match = VIOLATION_RE.match(line)
+ if not match:
+ raise Exception("Pattern did not match line:\n{0}".format(line))
+ file, line, col, details = match.groups()
+ line = int(line)
+ col = int(col)
+ comments_for_file = comments[file]
+ comment = {"message": "flake8: {0}".format(details)}
+ # Heuristic: if the error is on the first column, assume it applies to the whole line.
+ if col == 1:
+ comment["line"] = line
+ else:
+ comment["range"] = {"start_line": line, "end_line": line,
+ "start_character": col - 1, "end_character": col}
+ comments_for_file.append(comment)
+ return comments
+
+
+def post_review_to_gerrit(review_input):
+ """Post a review to the gerrit patchset. 'review_input' is a ReviewInput JSON object
+ containing the review comments. The gerrit change and patchset are picked up from
+ environment variables set by the gerrit jenkins trigger."""
+ change_num = environ["GERRIT_CHANGE_NUMBER"]
+ patch_num = environ["GERRIT_PATCHSET_NUMBER"]
+ proc = Popen(["ssh", "-p", environ["GERRIT_PORT"],
+ "impala-public-jenkins@" + environ["GERRIT_HOST"], "gerrit", "review",
+ "--project", environ["GERRIT_PROJECT"], "--json",
+ "{0},{1}".format(change_num, patch_num)], stdin=PIPE)
+ proc.communicate(json.dumps(review_input))
+ if proc.returncode != 0:
+ raise Exception("Error posting review to gerrit.")
+
+
+if __name__ == "__main__":
+ setup_virtualenv()
+ review_input = {"comments": get_flake8_comments(sys.argv[1])}
+ print json.dumps(review_input, indent=True)
+ post_review_to_gerrit(review_input)