git-file-tidy: add support for ".nolint" supression files

This patch allows to exclude subdirectories from linting by adding a
".nolint" file, and also passes "-quiet" to clang-tidy when not running
w/ "--verbose".

LE-277 #comment git-file-tidy: add support for ".nolint" supression files

Change-Id: I35a41046f9fa91cc86a178e4deb91dfb1857f959
diff --git a/git-file-tidy b/git-file-tidy
index 7e9e246..52d587d 100755
--- a/git-file-tidy
+++ b/git-file-tidy
@@ -30,6 +30,20 @@
 NINJA_TOOL = os.path.join(paths.BUILDTOOLS_ROOT, "ninja")
 
 
+def find_ancestor_with(filepath, relpath):
+    """Returns the lowest ancestor of |filepath| that contains |relpath|."""
+    cur_dir_path = os.path.abspath(os.path.dirname(filepath))
+    while True:
+        if os.path.exists(os.path.join(cur_dir_path, relpath)):
+            return cur_dir_path
+
+        next_dir_path = os.path.dirname(cur_dir_path)
+        if next_dir_path != cur_dir_path:
+            cur_dir_path = next_dir_path
+        else:
+            return None
+
+
 def get_out_dir(args):
     if os.environ.get("FUCHSIA_BUILD_DIR"):
         return os.environ.get("FUCHSIA_BUILD_DIR")
@@ -69,18 +83,33 @@
     # generate the compilation database
     generate_db(out_dir)
 
-    # Find the files to be formatted.
+    # Find the files to be checked.
     if args.all:
         files = git_utils.get_all_files()
     else:
         files = git_utils.get_diff_files()
 
+    filtered_files = []
+    for file_path in files:
+        # Skip deleted files.
+        if not os.path.isfile(file_path):
+            if args.verbose:
+                print "skipping " + file_path + " (deleted)"
+            continue
+
+        # Skip files with parent directories containing .nolint
+        if find_ancestor_with(file_path, ".nolint"):
+            if args.verbose:
+                print "skipping " + file_path + " (.nolint)"
+            continue
+        filtered_files.append(file_path)
+
     if args.verbose:
         print
-        print "Files to be formatted:"
-        for file in files:
+        print "Files to be checked:"
+        for file in filtered_files:
             print " - " + file
-        if not files:
+        if not filtered_files:
             print " (no files)"
         print
 
@@ -99,13 +128,7 @@
 
     jobs = set()
 
-    for file_path in files:
-        # Skip deleted files.
-        if not os.path.isfile(file_path):
-            if args.verbose:
-                print "skipping " + file_path + " (deleted)"
-            continue
-
+    for file_path in filtered_files:
         _, extension = os.path.splitext(file_path)
         if extension == ".cc":
             relpath = os.path.relpath(file_path)
@@ -114,6 +137,8 @@
                 cmd.append("-checks=" + args.checks)
             if args.fix:
                 cmd.append("-fix")
+            if not args.verbose:
+                cmd.append("-quiet")
 
             if args.verbose:
                 print "checking " + file_path + ": " + str(cmd)