text.py 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. """Ensure text files have the proper line endings.
  2. """
  3. from subprocess import DEVNULL
  4. from milc import cli
  5. from qmk.path import normpath, is_relative_to
  6. from qmk.commands import get_chunks
  7. IGNORE_SUFFIXES = [
  8. 'hex',
  9. 'ico',
  10. 'jpeg',
  11. 'jpg',
  12. 'png',
  13. ]
  14. IGNORE_DIRS = [
  15. 'lib/fnv',
  16. 'lib/lib8tion',
  17. 'lib/usbhost',
  18. ]
  19. def _check_dos2unix():
  20. """Check for a 'valid' dos2unix executable
  21. """
  22. dos2unix = cli.run(['dos2unix', '--help'])
  23. return dos2unix.returncode == 0 and '--add-eol' in dos2unix.stdout
  24. def dos2unix_run(files):
  25. """Spawn multiple dos2unix subprocess avoiding too long commands on formatting everything
  26. """
  27. for chunk in get_chunks([normpath(file).as_posix() for file in files], 10):
  28. dos2unix = cli.run(['dos2unix', '--add-eol', *chunk])
  29. if dos2unix.returncode:
  30. cli.log.debug(dos2unix.stdout)
  31. cli.log.error(dos2unix.stderr)
  32. return False
  33. def filter_files(files):
  34. """Yield only files to be formatted and skip the rest
  35. """
  36. ret = []
  37. for file in map(normpath, filter(None, files)):
  38. if file.suffix[1:] in IGNORE_SUFFIXES:
  39. continue
  40. if not any(is_relative_to(file, i) for i in IGNORE_DIRS):
  41. ret.append(file)
  42. return ret
  43. @cli.argument('-b', '--base-branch', default='origin/master', help='Branch to compare to diffs to.')
  44. @cli.argument('-a', '--all-files', arg_only=True, action='store_true', help='Format all files.')
  45. @cli.argument('files', nargs='*', arg_only=True, type=normpath, help='Filename(s) to format.')
  46. @cli.subcommand("Ensure text files have the proper line endings.", hidden=True)
  47. def format_text(cli):
  48. """Ensure text files have the proper line endings.
  49. """
  50. if not _check_dos2unix():
  51. cli.log.error('Formatting requires an up-to-date version of "dos2unix"')
  52. return False
  53. # Find the list of files to format
  54. if cli.args.files:
  55. files = filter_files(cli.args.files)
  56. if not files:
  57. cli.log.error('No valid files in filelist: %s', ', '.join(map(str, cli.args.files)))
  58. return False
  59. if cli.args.all_files:
  60. cli.log.warning('Filenames passed with -a, only formatting: %s', ','.join(map(str, files)))
  61. elif cli.args.all_files:
  62. git_ls_cmd = ['git', 'ls-files']
  63. git_ls = cli.run(git_ls_cmd, stdin=DEVNULL)
  64. files = filter_files(git_ls.stdout.split('\n'))
  65. else:
  66. git_diff_cmd = ['git', 'diff', '--name-only', cli.args.base_branch]
  67. git_diff = cli.run(git_diff_cmd, stdin=DEVNULL)
  68. files = filter_files(git_diff.stdout.split('\n'))
  69. # Sanity check
  70. if not files:
  71. cli.log.error('No changed files detected. Use "qmk format-text -a" to format all files')
  72. return False
  73. return dos2unix_run(files)