diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/python/qmk/cli/cformat.py | 65 | ||||
| -rw-r--r-- | lib/python/qmk/path.py | 14 | ||||
| -rw-r--r-- | lib/python/qmk/tests/test_cli_commands.py | 3 |
3 files changed, 58 insertions, 24 deletions
diff --git a/lib/python/qmk/cli/cformat.py b/lib/python/qmk/cli/cformat.py index de55218ae..7e3a91dcf 100644 --- a/lib/python/qmk/cli/cformat.py +++ b/lib/python/qmk/cli/cformat.py | |||
| @@ -1,16 +1,14 @@ | |||
| 1 | """Format C code according to QMK's style. | 1 | """Format C code according to QMK's style. |
| 2 | """ | 2 | """ |
| 3 | import os | ||
| 4 | import subprocess | 3 | import subprocess |
| 5 | from shutil import which | 4 | from shutil import which |
| 6 | 5 | ||
| 7 | from milc import cli | 6 | from milc import cli |
| 7 | import qmk.path | ||
| 8 | 8 | ||
| 9 | 9 | ||
| 10 | @cli.argument('files', nargs='*', arg_only=True, help='Filename(s) to format.') | 10 | def cformat_run(files, all_files): |
| 11 | @cli.subcommand("Format C code according to QMK's style.") | 11 | """Spawn clang-format subprocess with proper arguments |
| 12 | def cformat(cli): | ||
| 13 | """Format C code according to QMK's style. | ||
| 14 | """ | 12 | """ |
| 15 | # Determine which version of clang-format to use | 13 | # Determine which version of clang-format to use |
| 16 | clang_format = ['clang-format', '-i'] | 14 | clang_format = ['clang-format', '-i'] |
| @@ -19,27 +17,48 @@ def cformat(cli): | |||
| 19 | if which(binary): | 17 | if which(binary): |
| 20 | clang_format[0] = binary | 18 | clang_format[0] = binary |
| 21 | break | 19 | break |
| 22 | |||
| 23 | # Find the list of files to format | ||
| 24 | if cli.args.files: | ||
| 25 | cli.args.files = [os.path.join(os.environ['ORIG_CWD'], file) for file in cli.args.files] | ||
| 26 | else: | ||
| 27 | ignores = ['tmk_core/protocol/usb_hid', 'quantum/template'] | ||
| 28 | for dir in ['drivers', 'quantum', 'tests', 'tmk_core']: | ||
| 29 | for dirpath, dirnames, filenames in os.walk(dir): | ||
| 30 | if any(i in dirpath for i in ignores): | ||
| 31 | dirnames.clear() | ||
| 32 | continue | ||
| 33 | |||
| 34 | for name in filenames: | ||
| 35 | if name.endswith(('.c', '.h', '.cpp')): | ||
| 36 | cli.args.files.append(os.path.join(dirpath, name)) | ||
| 37 | |||
| 38 | # Run clang-format on the files we've found | ||
| 39 | try: | 20 | try: |
| 40 | subprocess.run(clang_format + cli.args.files, check=True) | 21 | if not files: |
| 22 | cli.log.warn('No changes detected. Use "qmk cformat -a" to format all files') | ||
| 23 | return False | ||
| 24 | if files and all_files: | ||
| 25 | cli.log.warning('Filenames passed with -a, only formatting: %s', ','.join(cli.args.files)) | ||
| 26 | # 3.6+: Can remove the str casting, python will cast implicitly | ||
| 27 | subprocess.run(clang_format + [str(file) for file in files], check=True) | ||
| 41 | cli.log.info('Successfully formatted the C code.') | 28 | cli.log.info('Successfully formatted the C code.') |
| 42 | 29 | ||
| 43 | except subprocess.CalledProcessError: | 30 | except subprocess.CalledProcessError: |
| 44 | cli.log.error('Error formatting C code!') | 31 | cli.log.error('Error formatting C code!') |
| 45 | return False | 32 | return False |
| 33 | |||
| 34 | |||
| 35 | @cli.argument('-a', '--all-files', arg_only=True, action='store_true', help='Format all core files.') | ||
| 36 | @cli.argument('-b', '--base-branch', default='origin/master', help='Branch to compare to diffs to.') | ||
| 37 | @cli.argument('files', nargs='*', arg_only=True, help='Filename(s) to format.') | ||
| 38 | @cli.subcommand("Format C code according to QMK's style.") | ||
| 39 | def cformat(cli): | ||
| 40 | """Format C code according to QMK's style. | ||
| 41 | """ | ||
| 42 | # Empty array for files | ||
| 43 | files = [] | ||
| 44 | # Core directories for formatting | ||
| 45 | core_dirs = ['drivers', 'quantum', 'tests', 'tmk_core'] | ||
| 46 | ignores = ['tmk_core/protocol/usb_hid', 'quantum/template'] | ||
| 47 | # Find the list of files to format | ||
| 48 | if cli.args.files: | ||
| 49 | files.extend(qmk.path.normpath(file) for file in cli.args.files) | ||
| 50 | # If -a is specified | ||
| 51 | elif cli.args.all_files: | ||
| 52 | all_files = qmk.path.c_source_files(core_dirs) | ||
| 53 | # The following statement checks each file to see if the file path is in the ignored directories. | ||
| 54 | files.extend(file for file in all_files if not any(i in str(file) for i in ignores)) | ||
| 55 | # No files specified & no -a flag | ||
| 56 | else: | ||
| 57 | base_args = ['git', 'diff', '--name-only', cli.args.base_branch] | ||
| 58 | out = subprocess.run(base_args + core_dirs, check=True, stdout=subprocess.PIPE) | ||
| 59 | changed_files = filter(None, out.stdout.decode('UTF-8').split('\n')) | ||
| 60 | filtered_files = [qmk.path.normpath(file) for file in changed_files if not any(i in file for i in ignores)] | ||
| 61 | files.extend(file for file in filtered_files if file.exists() and file.suffix in ['.c', '.h', '.cpp']) | ||
| 62 | |||
| 63 | # Run clang-format on the files we've found | ||
| 64 | cformat_run(files, cli.args.all_files) | ||
diff --git a/lib/python/qmk/path.py b/lib/python/qmk/path.py index d16928afb..bfaa43924 100644 --- a/lib/python/qmk/path.py +++ b/lib/python/qmk/path.py | |||
| @@ -68,3 +68,17 @@ def normpath(path): | |||
| 68 | return Path(path) | 68 | return Path(path) |
| 69 | 69 | ||
| 70 | return Path(os.environ['ORIG_CWD']) / path | 70 | return Path(os.environ['ORIG_CWD']) / path |
| 71 | |||
| 72 | |||
| 73 | def c_source_files(dir_names): | ||
| 74 | """Returns a list of all *.c, *.h, and *.cpp files for a given list of directories | ||
| 75 | |||
| 76 | Args: | ||
| 77 | |||
| 78 | dir_names | ||
| 79 | List of directories, relative pathing starts at qmk's cwd | ||
| 80 | """ | ||
| 81 | files = [] | ||
| 82 | for dir in dir_names: | ||
| 83 | files.extend(file for file in Path(dir).glob('**/*') if file.suffix in ['.c', '.h', '.cpp']) | ||
| 84 | return files | ||
diff --git a/lib/python/qmk/tests/test_cli_commands.py b/lib/python/qmk/tests/test_cli_commands.py index bb77952fa..a2595eb78 100644 --- a/lib/python/qmk/tests/test_cli_commands.py +++ b/lib/python/qmk/tests/test_cli_commands.py | |||
| @@ -7,7 +7,8 @@ def check_subcommand(command, *args): | |||
| 7 | 7 | ||
| 8 | 8 | ||
| 9 | def test_cformat(): | 9 | def test_cformat(): |
| 10 | assert check_subcommand('cformat', 'tmk_core/common/keyboard.c').returncode == 0 | 10 | result = check_subcommand('cformat', 'quantum/matrix.c') |
| 11 | assert result.returncode == 0 | ||
| 11 | 12 | ||
| 12 | 13 | ||
| 13 | def test_compile(): | 14 | def test_compile(): |
