Coverage for .nox/test/lib/python3.12/site-packages/mkdocs_licenseinfo/get_licenses.py: 83%

89 statements  

« prev     ^ index     » next       coverage.py v7.3.4, created at 2023-12-27 09:44 +0000

1"""Get licenseinfo.""" 

2from __future__ import annotations 

3 

4from contextlib import ContextDecorator 

5from io import StringIO 

6import json 

7import os 

8from pathlib import Path 

9import sys 

10 

11import licensecheck 

12 

13 

14class UnclosableIO(StringIO): 

15 """StringIO object that cannot be closed.""" 

16 

17 def close(self): 

18 """Don't close it.""" 

19 pass 

20 

21 def force_close(self): 

22 """Force close it.""" 

23 super().close() 

24 

25 def __del__(self, *args, **kwargs): 

26 """Make sure it closes.""" 

27 self.force_close() 

28 super().__del__(*args, **kwargs) 

29 

30 

31class LicenseCheckArgs(ContextDecorator): 

32 """Context manager for setting licensecheck args.""" 

33 

34 def __init__( 

35 self, 

36 using='PEP631', 

37 format='json', 

38 ignore_packages=None, 

39 fail_packages=None, 

40 skip_packages=None, 

41 ignore_licenses=None, 

42 fail_licenses=None, 

43 output=None, 

44 path=None 

45 ): 

46 """Initialise the context manager. 

47 

48 Keyword Args: 

49 target_dir (Optional[Path]): the target directory 

50 """ 

51 self._original_args = None 

52 if output is None: 

53 output = UnclosableIO() 

54 self._output = output 

55 self._stdout = None 

56 self._using = using 

57 self._format = format 

58 if ignore_packages is None: 

59 ignore_packages = [] 

60 self._ignore_packages = ignore_packages 

61 if fail_packages is None: 

62 fail_packages = [] 

63 self._fail_packages = fail_packages 

64 if skip_packages is None: 

65 skip_packages = [] 

66 self._skip_packages = skip_packages 

67 if ignore_licenses is None: 

68 ignore_licenses = [] 

69 self._ignore_licenses = ignore_licenses 

70 if fail_licenses is None: 

71 fail_licenses = [] 

72 self._fail_licenses = fail_licenses 

73 self._original_path = None 

74 if path: 

75 path = Path(path) 

76 self._path = path 

77 

78 def __enter__(self): 

79 """Change to the set argv.""" 

80 self._original_args = sys.argv[:] 

81 new_args = [ 

82 'licensecheck', 

83 '-u', 

84 self._using, 

85 '--format', 

86 self._format] 

87 for package in self._ignore_packages: 

88 new_args.append('--ignore-packages') 

89 new_args.append(package) 

90 for package in self._fail_packages: 

91 new_args.append('--fail-packages') 

92 new_args.append(package) 

93 for package in self._skip_packages: 

94 new_args.append('--skip-dependencies') 

95 new_args.append(package) 

96 for package in self._ignore_licenses: 

97 new_args.append('--ignore-licenses') 

98 new_args.append(package) 

99 for package in self._fail_licenses: 

100 new_args.append('--fail-licenses') 

101 new_args.append(package) 

102 self._stdout = licensecheck.stdout 

103 licensecheck.stdout = self._output 

104 sys.argv = new_args 

105 if self._path: 

106 self._original_path = Path.cwd() 

107 os.chdir(str(self._path)) 

108 

109 def __exit__(self, exc_type, exc_val, exc_tb): # noqa: U100 

110 """Reset to the original argv.""" 

111 sys.argv = self._original_args[:] 

112 licensecheck.stdout = self._stdout 

113 if self._path: 

114 os.chdir(str(self._original_path)) 

115 # Handle SystemExit 

116 if isinstance(exc_val, SystemExit) and exc_val.code == 0: 

117 return True 

118 

119 

120def _split_licenses(package): 

121 package['licenses'] = [u.strip() for u in package['license'].split(';;')] 

122 

123 

124def get_licenses( 

125 using='PEP631', 

126 ignore_packages=None, 

127 fail_packages=None, 

128 skip_packages=None, 

129 ignore_licenses=None, 

130 fail_licenses=None, 

131 path=None 

132): 

133 """Get the licenses using licensecheck.""" 

134 output = UnclosableIO() 

135 if using is None: 

136 using = 'PEP631' 

137 with LicenseCheckArgs( 

138 using=using, 

139 format='json', 

140 ignore_packages=ignore_packages, 

141 fail_packages=fail_packages, 

142 skip_packages=skip_packages, 

143 ignore_licenses=ignore_licenses, 

144 fail_licenses=fail_licenses, 

145 output=output, 

146 path=path 

147 ): 

148 licensecheck.cli() 

149 result = json.loads(output.getvalue()) 

150 output.force_close() 

151 # Loop over the results and clean the licenses 

152 packages = result['packages'] 

153 for package in packages: 

154 _split_licenses(package) 

155 return packages