11#!C:/miniconda/envs/plc-pre-commit/python.exe
22
33import argparse
4+
45from lxml import etree
56
67TAB_WIDTH = 2
8+ RETRIES = 5
79
810
9- def fix_file (filename , tab_width = TAB_WIDTH ):
11+ def fix_file (
12+ filename : str ,
13+ tab_width : int = TAB_WIDTH ,
14+ retries : int = RETRIES ,
15+ ) -> None :
16+ """
17+ Read a file, fix it, write the fix back to the file handle
18+ """
1019 # lxml throws encoding errors unless we work in binary mode
11- with open (filename , 'rb' ) as fd :
20+ with open (filename , "rb" ) as fd :
1221 original_xml = fd .read ()
22+ iter_xml = original_xml
23+
24+ for _ in range (retries ):
25+ new_xml = xml_once (
26+ original_xml = iter_xml ,
27+ tab_width = tab_width ,
28+ )
29+ if new_xml == iter_xml :
30+ break
31+ iter_xml = new_xml
32+
33+ if new_xml != original_xml :
34+ print (f"Fixing { filename } " )
35+ with open (filename , "wb" ) as fd :
36+ fd .write (new_xml )
1337
38+
39+ def xml_once (original_xml : str , tab_width : int ) -> str :
40+ """
41+ One iteration of the xml formatting.
42+
43+ This may need to run several times due to inconsistencies in lxml.
44+ """
1445 # lxml is the easiest cross-platform way to do this using pre-commit
1546 # xmllint is cross-platform but pre-commit does not help us set it up
1647 xml_parser = etree .XMLParser (remove_blank_text = True )
@@ -25,18 +56,15 @@ def fix_file(filename, tab_width=TAB_WIDTH):
2556 # lxml always outputs with unix line endings (LF)
2657 if b'\r \n ' in original_xml :
2758 new_xml = new_xml .replace (b'\n ' , b'\r \n ' )
28-
29- if new_xml != original_xml :
30- print (f'Fixing { filename } ' )
31- with open (filename , 'wb' ) as fd :
32- fd .write (new_xml )
59+ return new_xml
3360
3461
3562def main (args = None ):
3663 if args is None :
3764 parser = argparse .ArgumentParser ()
38- parser .add_argument ('filenames' , nargs = '*' )
39- parser .add_argument ('--tab-width' , type = int , default = TAB_WIDTH )
65+ parser .add_argument ("filenames" , nargs = "*" )
66+ parser .add_argument ("--tab-width" , type = int , default = TAB_WIDTH )
67+ parser .add_argument ("--retries" , type = int , default = RETRIES )
4068 args = parser .parse_args ()
4169 try :
4270 for filename in args .filenames :
0 commit comments