Coverage for .nox/test-3-9/lib/python3.9/site-packages/nskit/mixer/components/license_file.py: 95%

63 statements  

« prev     ^ index     » next       coverage.py v7.4.2, created at 2024-02-25 17:38 +0000

1"""License file handler.""" 

2from datetime import date 

3from enum import Enum 

4from functools import lru_cache 

5from pathlib import Path 

6import sys 

7from typing import Any, Callable, Dict, Optional, Union 

8 

9from ghapi.all import GhApi 

10from pydantic import Field 

11 

12from nskit.mixer.components.file import File 

13from nskit.mixer.components.filesystem_object import TemplateStr 

14from nskit.mixer.utilities import Resource 

15 

16 

17class LicenseOptionsEnum(Enum): 

18 """License Options for the license file. 

19 

20 Built from Github API licenses.get_all_commonly_used. 

21 """ 

22 AGPL_3_0 = 'agpl-3.0' 

23 Apache_2_0 = 'apache-2.0' 

24 BSD_2_Clause = 'bsd-2-clause' 

25 BSD_3_Clause = 'bsd-3-clause' 

26 BSL_1_0 = 'bsl-1.0' 

27 CC0_1_0 = 'cc0-1.0' 

28 EPL_2_0 = 'epl-2.0' 

29 GPL_2_0 = 'gpl-2.0' 

30 GPL_3_0 = 'gpl-3.0' 

31 LGPL_2_1 = 'lgpl-2.1' 

32 MIT = 'mit' 

33 MPL_2_0 = 'mpl-2.0' 

34 Unlicense = 'unlicense' 

35 

36 @classmethod 

37 def contains(cls, value): 

38 """Return True if `value` is in `cls`. 

39 

40 BACKPORT FROM PYTHON 3.12 

41 

42 `value` is in `cls` if: 

43 1) `value` is a member of `cls`, or 

44 2) `value` is the value of one of the `cls`'s members. 

45 """ 

46 if sys.version_info.major <= 3 and sys.version_info.minor < 12: 

47 if isinstance(value, cls): 

48 return True 

49 try: 

50 return value in cls._value2member_map_ 

51 except TypeError: 

52 return value in cls._unhashable_values_ 

53 return value in cls 

54 

55 

56def get_license_filename(context: Optional[Dict[str, Any]] = None): 

57 """Callable to set the default license file name.""" 

58 # Can't do in LicenseOptionsEnum pre 3.12 

59 if LicenseOptionsEnum.contains(context.get('license', None)): 

60 # Handle naming 

61 license_name = LicenseOptionsEnum(context.get('license', None)) 

62 # COPYING 

63 if license_name in [ 

64 LicenseOptionsEnum.AGPL_3_0, 

65 LicenseOptionsEnum.GPL_2_0, 

66 LicenseOptionsEnum.GPL_3_0, 

67 ]: 

68 name = 'COPYING' 

69 # COPYING.LESSER 

70 elif license_name in [ 

71 LicenseOptionsEnum.LGPL_2_1, 

72 ]: 

73 name = 'COPYING.LESSER' 

74 # LICENSE 

75 elif license_name in [ 

76 LicenseOptionsEnum.MIT, 

77 LicenseOptionsEnum.Apache_2_0, 

78 LicenseOptionsEnum.BSD_2_Clause, 

79 LicenseOptionsEnum.BSD_3_Clause, 

80 LicenseOptionsEnum.BSL_1_0, 

81 LicenseOptionsEnum.CC0_1_0, 

82 LicenseOptionsEnum.EPL_2_0, 

83 LicenseOptionsEnum.MIT, 

84 LicenseOptionsEnum.MPL_2_0 

85 ]: 

86 name = "LICENSE" 

87 # UNLICENSE 

88 elif license_name in [LicenseOptionsEnum.Unlicense]: 

89 name = 'UNLICENSE' 

90 return name 

91 

92 

93@lru_cache() 

94def _get_license_content(license: LicenseOptionsEnum): 

95 # Cache results as a static method to make testing etc. better on rates/rate limiting 

96 license_content = GhApi().licenses.get(license.value) 

97 return license_content 

98 

99 

100def get_license_content(context: Dict[str, Any]): 

101 """Render the content of the license.""" 

102 # We implement some specifics based on the implementation instructions in Github licenses api get 

103 # Can't do in LicenseOptionsEnum pre 3.12 

104 if LicenseOptionsEnum.contains(context.get('license', None)): 

105 license_name = LicenseOptionsEnum(context.get('license', None)) 

106 license_content = _get_license_content(license_name) 

107 content = license_content.body 

108 # [year] [fullname] to be replaced 

109 if license_name in [ 

110 LicenseOptionsEnum.BSD_2_Clause, 

111 LicenseOptionsEnum.BSD_3_Clause, 

112 LicenseOptionsEnum.MIT, 

113 ]: 

114 content = content.replace('[year]', '{{license_year}}').replace('[fullname]', '{{repo.name}} Developers') 

115 context['license_year'] = context.get('license_year', date.today().year) 

116 return content 

117 

118 

119class LicenseFile(File): 

120 """License File created by downloading from Github.""" 

121 

122 name: Optional[Union[TemplateStr, str, Callable]] = Field(get_license_filename, validate_default=True, description='The name of the license file') 

123 content: Union[Resource, str, bytes, Path, Callable] = Field(get_license_content, description='The file content')