Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1""" 

2@file 

3@brief Various function to clean files. 

4""" 

5from __future__ import print_function 

6import os 

7import re 

8 

9 

10def clean_exts(folder=".", fLOG=print, exts=None, fclean=None): 

11 """ 

12 Cleans files in a folder and subfolders with a given extensions. 

13 

14 @param folder folder to clean 

15 @param fLOG logging function 

16 @param exts extensions to clean 

17 @param fclean if not None, ``fclean(name) -> True`` to clean 

18 @return list of removed files 

19 

20 If *exts* is None, it will be replaced by 

21 ``{".pyd", ".so", ".o", ".def", ".obj"}``. 

22 """ 

23 if exts is None: 

24 exts = {".pyd", ".so", ".o", ".def", ".obj"} 

25 rem = [] 

26 for root, _, files in os.walk(folder): 

27 for f in files: 

28 ext = os.path.splitext(f)[-1] 

29 if (ext in exts and "exe.win" not in root and "site-packages" not in root and 

30 "_venv" not in root): # pragma: no cover 

31 filename = os.path.join(root, f) 

32 if fclean is not None and not fclean(filename): 

33 continue 

34 fLOG("[clean_exts] removing ", filename) 

35 os.remove(filename) 

36 rem.append(filename) 

37 return rem 

38 

39 

40def clean_files(folder=".", posreg='.*[.]((py)|(rst))$', 

41 negreg=".*[.]git/.*", op="CR", fLOG=print): 

42 """ 

43 Cleans ``\\r`` in files a folder and subfolders with a given extensions. 

44 Backslashes are replaces by ``/``. The regular expressions 

45 applies on the relative path starting from *folder*. 

46 

47 :param folder: folder to clean 

48 :param posreg: regular expression to select files to process 

49 :param negreg: regular expression to skip files to process 

50 :param op: kind of cleaning to do, options are CR, CRB, pep8, 

51 see below for more details 

52 :param fLOG: logging function 

53 :return: list of processed files 

54 

55 The following cleaning are available: 

56 

57 * ``'CR'``: replaces ``'\\r\\n'`` by ``'\\n'`` 

58 * ``'CRB'``: replaces end of lines ``'\\n'`` by ``'\\r\\n'`` 

59 * ``'pep8'``: applies :epkg:`pep8` convention 

60 """ 

61 def clean_file_cr(name): 

62 with open(name, "rb") as f: 

63 content = f.read() 

64 new_content = content.replace(b"\r\n", b"\n") 

65 if new_content != content: 

66 with open(name, "wb") as f: 

67 f.write(new_content) 

68 return True 

69 return False 

70 

71 def clean_file_cr_back(name): 

72 with open(name, "rb") as f: 

73 lines = f.read().split(b'\n') 

74 new_lines = [] 

75 changes = False 

76 for li in lines: 

77 if not li.endswith(b'\r'): 

78 new_lines.append(li + b'\r') 

79 changes = True 

80 else: 

81 new_lines.append(li) 

82 if changes: 

83 with open(name, "wb") as f: 

84 f.write(b'\n'.join(new_lines)) 

85 return changes 

86 

87 if op == 'CR': 

88 clean_file = clean_file_cr 

89 elif op == 'CRB': 

90 clean_file = clean_file_cr_back 

91 elif op == 'pep8': 

92 from .code_helper import remove_extra_spaces_and_pep8 

93 clean_file = remove_extra_spaces_and_pep8 

94 else: 

95 raise ValueError("Unknown cleaning '{0}'.".format(op)) 

96 

97 if posreg and isinstance(posreg, str): 

98 posreg = re.compile(posreg) 

99 if negreg and isinstance(negreg, str): 

100 negreg = re.compile(negreg) 

101 

102 res = [] 

103 for root, _, files in os.walk(folder): 

104 for f in files: 

105 full = os.path.join(root, f) 

106 rel = os.path.relpath(full, folder) 

107 fn = rel.replace("\\", "/") 

108 if posreg is None or posreg.search(fn): 

109 if negreg is None or not negreg.search(fn): 

110 r = clean_file(full) 

111 if r and fLOG: 

112 fLOG("[clean_files] processed '{0}'".format(fn)) 

113 res.append(rel) 

114 return res