You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ko...@apache.org on 2022/01/20 14:07:53 UTC

[couchdb] 01/02: Forward port erlfmt improvements from #3837

This is an automated email from the ASF dual-hosted git repository.

kocolosk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit fca5a2e0db6208ebe17ffb8717791ac406032796
Author: Adam Kocoloski <ko...@apache.org>
AuthorDate: Tue Jan 18 22:47:31 2022 -0500

    Forward port erlfmt improvements from #3837
    
    Credit to @nickva for the original improvements. The main branch is
    already Erlang 21+ so the minimum version check is less essential, but
    the performance improvements are greatly appreciated!
---
 dev/format_all.py   | 11 ++++++++---
 dev/format_check.py | 49 ++++++++++++++++++-------------------------------
 dev/format_lib.py   | 33 +++++++++++++++++++++++----------
 3 files changed, 49 insertions(+), 44 deletions(-)

diff --git a/dev/format_all.py b/dev/format_all.py
index 067fc79..1927fb5 100644
--- a/dev/format_all.py
+++ b/dev/format_all.py
@@ -18,13 +18,18 @@ USAGE: ERLFMT_PATH=<path_to_erlfmt> python3 dev/format_all.py
 """
 
 import os
+import sys
 import subprocess
 
-from format_lib import get_source_paths
+from format_lib import get_source_paths, get_erlang_version
 
 if __name__ == "__main__":
-    for item in get_source_paths():
+    if get_erlang_version() < 21:
+        print("Erlang version is < 21. Skipping format check")
+        sys.exit(0)
+
+    for path in get_source_paths():
         subprocess.run(
-            [os.environ["ERLFMT_PATH"], "-w", item["raw_path"]],
+            [os.environ["ERLFMT_PATH"], "-w", path],
             stdout=subprocess.PIPE,
         )
diff --git a/dev/format_check.py b/dev/format_check.py
index 6b46588..cbb0126 100644
--- a/dev/format_check.py
+++ b/dev/format_check.py
@@ -21,41 +21,28 @@ import os
 import subprocess
 import sys
 
-from format_lib import get_source_paths
+from format_lib import get_source_paths, get_erlang_version
 
-FILTERED_LINES = [
-    "Checking formatting...",
-    "[warn] Code style issues found in the above file(s). Forgot to run erlfmt?",
-    "",
-]
 
 if __name__ == "__main__":
-    failed_checks = 0
-    for item in get_source_paths():
+    if get_erlang_version() < 21:
+        print("Erlang version is < 21. Skipping format check")
+        sys.exit(0)
+
+    exit_code = 0
+
+    for path in get_source_paths():
         run_result = subprocess.run(
-            [
-                os.environ["ERLFMT_PATH"],
-                "-c",
-                "--verbose",
-                # We have some long lines and erlfmt doesn't forcefully wrap
-                # them all. We should decrease this over time
-                "--print-width=167",
-                item["raw_path"],
-            ],
+            [os.environ["ERLFMT_PATH"], "-c", path],
             stdout=subprocess.PIPE,
             stderr=subprocess.PIPE,
         )
-        if run_result.returncode != 0:
-            # erlfmt sometimes returns a non-zero status code with no
-            # actual errors. This is a workaround
-            stderr_lines = [
-                line
-                for line in run_result.stderr.decode("utf-8").split("\n")
-                if line not in FILTERED_LINES
-                and not line.startswith("Formatting ")
-                and not line.startswith("[warn] ")
-            ]
-            if len(stderr_lines) > 0:
-                print("\n".join(stderr_lines), file=sys.stderr)
-                failed_checks += 1
-    sys.exit(failed_checks)
+        rc = run_result.returncode
+        if rc != 0:
+            print("\n %s error for %s" % (rc, path))
+            stderr_lines = run_result.stderr.decode("utf-8").split("\n")
+            for line in stderr_lines:
+                print("  > %s" % line, file=sys.stderr)
+            exit_code = 1
+
+    sys.exit(exit_code)
diff --git a/dev/format_lib.py b/dev/format_lib.py
index 563ef8d..3db0057 100644
--- a/dev/format_lib.py
+++ b/dev/format_lib.py
@@ -20,22 +20,35 @@ import pathlib
 import subprocess
 
 
+def get_erlang_version():
+    args = [
+        "erl",
+        "-eval",
+        "io:put_chars(erlang:system_info(otp_release)), halt().",
+        "-noshell",
+    ]
+    res = subprocess.run(args, stdout=subprocess.PIPE, check=True)
+    str_version = res.stdout.decode("utf-8").strip().strip('"')
+    return int(str_version)
+
+
+# Generate source paths as "directory/*.erl" wildcard patterns
+# those can be directly consumed by erlfmt and processed in parallel
+#
 def get_source_paths():
+    curdir = None
     for item in (
         subprocess.run(
-            ["git", "ls-files"],
+            ["git", "ls-files", "--", "*.erl"],
             stdout=subprocess.PIPE,
             stderr=subprocess.PIPE,
         )
         .stdout.decode("utf-8")
         .split("\n")
     ):
-        item_path = pathlib.Path(item)
-        if item_path.suffix != ".erl":
-            continue
-
-        result_dict = {
-            "raw_path": item,
-            "item_path": item_path,
-        }
-        yield result_dict
+        path = pathlib.Path(item)
+        if path.parent != curdir:
+            yield str(path.parent.joinpath("*.erl"))
+            curdir = path.parent
+    if curdir is not None:
+        yield str(curdir.joinpath("*.erl"))