Coverage for .nox/test-3-12/lib/python3.12/site-packages/nskit/mixer/components/license_file.py: 0%
63 statements
« prev ^ index » next coverage.py v7.3.3, created at 2023-12-19 17:42 +0000
« prev ^ index » next coverage.py v7.3.3, created at 2023-12-19 17:42 +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
9from ghapi.all import GhApi
10from pydantic import Field
12from nskit.mixer.components.file import File
13from nskit.mixer.components.filesystem_object import TemplateStr
14from nskit.mixer.utilities import Resource
17class LicenseOptionsEnum(Enum):
18 """License Options for the license file.
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'
36 @classmethod
37 def contains(cls, value):
38 """Return True if `value` is in `cls`.
40 BACKPORT FROM PYTHON 3.12
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
55def get_license_filename(context: Optional[Dict[str, Any]] = None):
56 """Callable to set the default license file name."""
57 # Can't do in LicenseOptionsEnum pre 3.12
58 if LicenseOptionsEnum.contains(context.get('license', None)):
59 # Handle naming
60 license_name = LicenseOptionsEnum(context.get('license', None))
61 # COPYING
62 if license_name in [
63 LicenseOptionsEnum.AGPL_3_0,
64 LicenseOptionsEnum.GPL_2_0,
65 LicenseOptionsEnum.GPL_3_0,
66 ]:
67 name = 'COPYING'
68 # COPYING.LESSER
69 elif license_name in [
70 LicenseOptionsEnum.LGPL_2_1,
71 ]:
72 name = 'COPYING.LESSER'
73 # LICENSE
74 elif license_name in [
75 LicenseOptionsEnum.MIT,
76 LicenseOptionsEnum.Apache_2_0,
77 LicenseOptionsEnum.BSD_2_Clause,
78 LicenseOptionsEnum.BSD_3_Clause,
79 LicenseOptionsEnum.BSL_1_0,
80 LicenseOptionsEnum.CC0_1_0,
81 LicenseOptionsEnum.EPL_2_0,
82 LicenseOptionsEnum.MIT,
83 LicenseOptionsEnum.MPL_2_0
84 ]:
85 name = "LICENSE"
86 # UNLICENSE
87 elif license_name in [LicenseOptionsEnum.Unlicense]:
88 name = 'UNLICENSE'
89 return name
92@lru_cache()
93def _get_license_content(license: LicenseOptionsEnum):
94 # Cache results as a static method to make testing etc. better on rates/rate limiting
95 license_content = GhApi().licenses.get(license.value)
96 return license_content
99def get_license_content(context: Dict[str, Any]):
100 """Render the content of the license."""
101 # We implement some specifics based on the implementation instructions in Github licenses api get
102 # Can't do in LicenseOptionsEnum pre 3.12
103 if LicenseOptionsEnum.contains(context.get('license', None)):
104 license_name = LicenseOptionsEnum(context.get('license', None))
105 license_content = _get_license_content(license_name)
106 content = license_content.body
107 # [year] [fullname] to be replaced
108 if license_name in [
109 LicenseOptionsEnum.BSD_2_Clause,
110 LicenseOptionsEnum.BSD_3_Clause,
111 LicenseOptionsEnum.MIT,
112 ]:
113 content = content.replace('[year]', '{{license_year}}').replace('[fullname]', '{{name}} Developers')
114 context['license_year'] = context.get('license_year', date.today().year)
115 return content
118class LicenseFile(File):
119 """License File created by downloading from Github."""
121 name: Optional[Union[TemplateStr, str, Callable]] = Field(get_license_filename, validate_default=True, description='The name of the license file')
122 content: Union[Resource, str, bytes, Path, Callable] = Field(get_license_content, description='The file content')