mirror of
				https://github.com/esphome/esphome.git
				synced 2025-11-04 00:51:49 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			113 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			113 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/env python3
 | 
						|
 | 
						|
import argparse
 | 
						|
import multiprocessing
 | 
						|
import os
 | 
						|
import queue
 | 
						|
import re
 | 
						|
import subprocess
 | 
						|
import sys
 | 
						|
import threading
 | 
						|
 | 
						|
import click
 | 
						|
import colorama
 | 
						|
from helpers import filter_changed, get_binary, git_ls_files, print_error_for_file
 | 
						|
 | 
						|
 | 
						|
def run_format(executable, args, queue, lock, failed_files):
 | 
						|
    """Takes filenames out of queue and runs clang-format on them."""
 | 
						|
    while True:
 | 
						|
        path = queue.get()
 | 
						|
        invocation = [executable]
 | 
						|
        if args.inplace:
 | 
						|
            invocation.append("-i")
 | 
						|
        else:
 | 
						|
            invocation.extend(["--dry-run", "-Werror"])
 | 
						|
        invocation.append(path)
 | 
						|
 | 
						|
        proc = subprocess.run(invocation, capture_output=True, encoding="utf-8")
 | 
						|
        if proc.returncode != 0:
 | 
						|
            with lock:
 | 
						|
                print_error_for_file(path, proc.stderr)
 | 
						|
                failed_files.append(path)
 | 
						|
        queue.task_done()
 | 
						|
 | 
						|
 | 
						|
def progress_bar_show(value):
 | 
						|
    return value if value is not None else ""
 | 
						|
 | 
						|
 | 
						|
def main():
 | 
						|
    colorama.init()
 | 
						|
 | 
						|
    parser = argparse.ArgumentParser()
 | 
						|
    parser.add_argument(
 | 
						|
        "-j",
 | 
						|
        "--jobs",
 | 
						|
        type=int,
 | 
						|
        default=multiprocessing.cpu_count(),
 | 
						|
        help="number of format instances to be run in parallel.",
 | 
						|
    )
 | 
						|
    parser.add_argument(
 | 
						|
        "files", nargs="*", default=[], help="files to be processed (regex on path)"
 | 
						|
    )
 | 
						|
    parser.add_argument(
 | 
						|
        "-i", "--inplace", action="store_true", help="reformat files in-place"
 | 
						|
    )
 | 
						|
    parser.add_argument(
 | 
						|
        "-c", "--changed", action="store_true", help="only run on changed files"
 | 
						|
    )
 | 
						|
    args = parser.parse_args()
 | 
						|
 | 
						|
    files = []
 | 
						|
    for path in git_ls_files(["*.cpp", "*.h", "*.tcc"]):
 | 
						|
        files.append(os.path.relpath(path, os.getcwd()))
 | 
						|
 | 
						|
    if args.files:
 | 
						|
        # Match against files specified on command-line
 | 
						|
        file_name_re = re.compile("|".join(args.files))
 | 
						|
        files = [p for p in files if file_name_re.search(p)]
 | 
						|
 | 
						|
    if args.changed:
 | 
						|
        files = filter_changed(files)
 | 
						|
 | 
						|
    files.sort()
 | 
						|
 | 
						|
    failed_files = []
 | 
						|
    try:
 | 
						|
        executable = get_binary("clang-format", 13)
 | 
						|
        task_queue = queue.Queue(args.jobs)
 | 
						|
        lock = threading.Lock()
 | 
						|
        for _ in range(args.jobs):
 | 
						|
            t = threading.Thread(
 | 
						|
                target=run_format, args=(executable, args, task_queue, lock, failed_files)
 | 
						|
            )
 | 
						|
            t.daemon = True
 | 
						|
            t.start()
 | 
						|
 | 
						|
        # Fill the queue with files.
 | 
						|
        with click.progressbar(
 | 
						|
            files, width=30, file=sys.stderr, item_show_func=progress_bar_show
 | 
						|
        ) as bar:
 | 
						|
            for name in bar:
 | 
						|
                task_queue.put(name)
 | 
						|
 | 
						|
        # Wait for all threads to be done.
 | 
						|
        task_queue.join()
 | 
						|
 | 
						|
    except FileNotFoundError as ex:
 | 
						|
        return 1
 | 
						|
    except KeyboardInterrupt:
 | 
						|
        print()
 | 
						|
        print("Ctrl-C detected, goodbye.")
 | 
						|
        # Kill subprocesses (and ourselves!)
 | 
						|
        # No simple, clean alternative appears to be available.
 | 
						|
        os.kill(0, 9)
 | 
						|
        return 2    # Will not execute.
 | 
						|
 | 
						|
    return len(failed_files)
 | 
						|
 | 
						|
 | 
						|
if __name__ == "__main__":
 | 
						|
    sys.exit(main())
 |