licomp-toolkit 0.6.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- licomp_toolkit/__init__.py +0 -0
- licomp_toolkit/__main__.py +322 -0
- licomp_toolkit/config.py +40 -0
- licomp_toolkit/data/reply_schema.json +305 -0
- licomp_toolkit/display_compatibility.py +21 -0
- licomp_toolkit/exception.py +11 -0
- licomp_toolkit/expr_parser.py +139 -0
- licomp_toolkit/format.py +362 -0
- licomp_toolkit/lic_expr.py +325 -0
- licomp_toolkit/license_policy.py +564 -0
- licomp_toolkit/return_codes.py +12 -0
- licomp_toolkit/schema_checker.py +67 -0
- licomp_toolkit/suggester.py +162 -0
- licomp_toolkit/toolkit.py +504 -0
- licomp_toolkit/utils.py +81 -0
- licomp_toolkit-0.6.3.dist-info/METADATA +164 -0
- licomp_toolkit-0.6.3.dist-info/RECORD +21 -0
- licomp_toolkit-0.6.3.dist-info/WHEEL +5 -0
- licomp_toolkit-0.6.3.dist-info/entry_points.txt +2 -0
- licomp_toolkit-0.6.3.dist-info/licenses/LICENSES/GPL-3.0-or-later.txt +232 -0
- licomp_toolkit-0.6.3.dist-info/top_level.txt +1 -0
|
File without changes
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
#!/bin/env python3
|
|
2
|
+
|
|
3
|
+
# SPDX-FileCopyrightText: 2024 Henrik Sandklef
|
|
4
|
+
#
|
|
5
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
6
|
+
|
|
7
|
+
import json
|
|
8
|
+
from json.decoder import JSONDecodeError
|
|
9
|
+
import logging
|
|
10
|
+
import sys
|
|
11
|
+
|
|
12
|
+
from licomp.interface import LicompException
|
|
13
|
+
|
|
14
|
+
from licomp_toolkit.return_codes import LicompToolkitReturnCodes
|
|
15
|
+
from licomp_toolkit.toolkit import LicompToolkit
|
|
16
|
+
from licomp_toolkit.toolkit import ExpressionExpressionChecker
|
|
17
|
+
from licomp_toolkit.format import LicompToolkitFormatter
|
|
18
|
+
from licomp_toolkit.config import cli_name
|
|
19
|
+
from licomp_toolkit.config import description
|
|
20
|
+
from licomp_toolkit.config import module_name
|
|
21
|
+
from licomp_toolkit.config import licomp_toolkit_file_version
|
|
22
|
+
from licomp_toolkit.config import epilog
|
|
23
|
+
from licomp_toolkit.schema_checker import LicompToolkitSchemaChecker
|
|
24
|
+
from licomp_toolkit.suggester import OutboundSuggester
|
|
25
|
+
from licomp_toolkit.display_compatibility import DisplayCompatibility
|
|
26
|
+
from licomp_toolkit.utils import resources_to_use
|
|
27
|
+
from licomp_toolkit.utils import default_resources
|
|
28
|
+
from licomp_toolkit.license_policy import LicensePolicyHandler
|
|
29
|
+
|
|
30
|
+
from licomp.main_base import LicompParser
|
|
31
|
+
from licomp.interface import UseCase
|
|
32
|
+
from licomp.interface import Provisioning
|
|
33
|
+
from licomp.return_codes import ReturnCodes
|
|
34
|
+
from licomp.return_codes import compatibility_status_to_returncode
|
|
35
|
+
|
|
36
|
+
from flame.license_db import FossLicenses
|
|
37
|
+
from flame.exception import FlameException
|
|
38
|
+
|
|
39
|
+
class LicompToolkitParser(LicompParser):
|
|
40
|
+
|
|
41
|
+
def __init__(self, name, description, epilog, default_usecase, default_provisioning):
|
|
42
|
+
self.licomp_toolkit = LicompToolkit()
|
|
43
|
+
LicompParser.__init__(self, self.licomp_toolkit, name, description, epilog, default_usecase, default_provisioning)
|
|
44
|
+
self.flame = FossLicenses()
|
|
45
|
+
|
|
46
|
+
def __normalize_license(self, lic_name):
|
|
47
|
+
return self.flame.expression_license(lic_name, update_dual=False)['identified_license']
|
|
48
|
+
|
|
49
|
+
def validate(self, args):
|
|
50
|
+
LicompToolkitSchemaChecker().validate_file(args.file_name, deep=True)
|
|
51
|
+
return None, ReturnCodes.LICOMP_OK.value, None
|
|
52
|
+
|
|
53
|
+
def _read_report_file(self, report_file):
|
|
54
|
+
try:
|
|
55
|
+
with open(report_file) as fp:
|
|
56
|
+
report = json.load(fp)
|
|
57
|
+
meta = report['meta']
|
|
58
|
+
meta_OK = meta['tool'] == module_name
|
|
59
|
+
meta_OK = meta['file_version'] == licomp_toolkit_file_version
|
|
60
|
+
file_OK = meta['file'] == 'verification'
|
|
61
|
+
if not (meta_OK and file_OK):
|
|
62
|
+
err_msg = f'File "{report_file}" not in Licomp Toolkit\'s license policy format.'
|
|
63
|
+
err_code = LicompToolkitReturnCodes.LICOMP_TOOLKIT_INVALID_FILE.value
|
|
64
|
+
return None, err_code, err_msg
|
|
65
|
+
return report, ReturnCodes.LICOMP_OK.value, None
|
|
66
|
+
except (FileNotFoundError, JSONDecodeError):
|
|
67
|
+
err_msg = f'File "{report_file}" not found or not in JSON format'
|
|
68
|
+
err_code = LicompToolkitReturnCodes.LICOMP_TOOLKIT_INVALID_FILE.value
|
|
69
|
+
return None, err_code, err_msg
|
|
70
|
+
except (KeyError):
|
|
71
|
+
err_msg = f'File "{report_file}" not in Licomp Toolkit\'s license policy format.'
|
|
72
|
+
err_code = LicompToolkitReturnCodes.LICOMP_TOOLKIT_INVALID_FILE.value
|
|
73
|
+
return None, err_code, err_msg
|
|
74
|
+
|
|
75
|
+
def apply_license_policy(self, args):
|
|
76
|
+
report, err_code, err_msg = self._read_report_file(args.report_file)
|
|
77
|
+
if err_code != ReturnCodes.LICOMP_OK.value:
|
|
78
|
+
return None, err_code, err_msg
|
|
79
|
+
if args.resources:
|
|
80
|
+
logging.warning(f'User specified resources are ignored. Using the resources as specified in the report file ("{args.report_file}").')
|
|
81
|
+
resources = report['resources']
|
|
82
|
+
usecase = report['usecase']
|
|
83
|
+
provisioning = report['provisioning']
|
|
84
|
+
lph = LicensePolicyHandler(policy_file=args.license_policy_file,
|
|
85
|
+
resources=resources,
|
|
86
|
+
usecase=usecase,
|
|
87
|
+
provisioning=provisioning)
|
|
88
|
+
policy_report = lph.apply_policy(report, ignore_missing=True)
|
|
89
|
+
ret_code = compatibility_status_to_returncode(policy_report['compatibility'])
|
|
90
|
+
formatter = LicompToolkitFormatter.formatter(self.args.output_format)
|
|
91
|
+
formatted_report = formatter.format_policy_report(report, verbose=args.verbose)
|
|
92
|
+
return formatted_report, ret_code, False
|
|
93
|
+
|
|
94
|
+
def verify(self, args):
|
|
95
|
+
formatter = LicompToolkitFormatter.formatter(self.args.output_format)
|
|
96
|
+
try:
|
|
97
|
+
if args.no_verbose:
|
|
98
|
+
detailed_report = False
|
|
99
|
+
else:
|
|
100
|
+
detailed_report = True
|
|
101
|
+
|
|
102
|
+
resources, unsupported = resources_to_use(args)
|
|
103
|
+
if unsupported:
|
|
104
|
+
return f'Resource(s) {", ".join(unsupported)} is/are not supported', ReturnCodes.LICOMP_UNSUPPORTED_RESOURCE.value, True
|
|
105
|
+
expr_checker = ExpressionExpressionChecker()
|
|
106
|
+
compatibilities = expr_checker.check_compatibility(self.__normalize_license(args.out_license),
|
|
107
|
+
self.__normalize_license(args.in_license),
|
|
108
|
+
args.usecase,
|
|
109
|
+
args.provisioning,
|
|
110
|
+
resources=resources,
|
|
111
|
+
detailed_report=detailed_report)
|
|
112
|
+
|
|
113
|
+
ret_code = compatibility_status_to_returncode(compatibilities['compatibility'])
|
|
114
|
+
if args.apply_license_policy:
|
|
115
|
+
if args.license_policy_file:
|
|
116
|
+
lph = LicensePolicyHandler(policy_file=args.license_policy_file)
|
|
117
|
+
else:
|
|
118
|
+
resources, unsupported = resources_to_use(args)
|
|
119
|
+
if unsupported:
|
|
120
|
+
return f'Resource(s) {", ".join(unsupported)} is/are not supported', ReturnCodes.LICOMP_UNSUPPORTED_RESOURCE.value, True
|
|
121
|
+
lph = LicensePolicyHandler(resources=resources,
|
|
122
|
+
usecase=args.usecase,
|
|
123
|
+
provisioning=args.provisioning)
|
|
124
|
+
policy_report = lph.apply_policy(compatibilities)
|
|
125
|
+
return formatter.format_policy_report(policy_report, verbose=args.verbose), ret_code, False
|
|
126
|
+
else:
|
|
127
|
+
return formatter.format_compatibilities(compatibilities, verbose=args.verbose), ret_code, False
|
|
128
|
+
except LicompException as e:
|
|
129
|
+
return e, e.return_code.value, True
|
|
130
|
+
except FlameException as e:
|
|
131
|
+
return f'Illegal or missing license(s) supplied. Original message: {e}', ReturnCodes.LICOMP_ILLEGAL_LICENSE.value, True
|
|
132
|
+
|
|
133
|
+
def supported_licenses(self, args):
|
|
134
|
+
licenses = self.licomp_toolkit.supported_licenses()
|
|
135
|
+
formatter = LicompToolkitFormatter.formatter(args.output_format)
|
|
136
|
+
return formatter.format_licomp_resources(licenses), ReturnCodes.LICOMP_OK.value, None
|
|
137
|
+
|
|
138
|
+
def supported_usecases(self, args):
|
|
139
|
+
usecases = self.licomp_toolkit.supported_usecases()
|
|
140
|
+
usecase_names = [UseCase.usecase_to_string(x) for x in usecases]
|
|
141
|
+
return usecase_names, ReturnCodes.LICOMP_OK.value, None
|
|
142
|
+
|
|
143
|
+
def supported_provisionings(self, args):
|
|
144
|
+
provisionings = self.licomp_toolkit.supported_provisionings()
|
|
145
|
+
provisioning_names = [Provisioning.provisioning_to_string(x) for x in provisionings]
|
|
146
|
+
provisioning_names = list(provisioning_names)
|
|
147
|
+
provisioning_names.sort()
|
|
148
|
+
return provisioning_names, ReturnCodes.LICOMP_OK.value, None
|
|
149
|
+
|
|
150
|
+
def simplify(self, args):
|
|
151
|
+
formatter = LicompToolkitFormatter.formatter(args.output_format)
|
|
152
|
+
normalized = self.__normalize_license(' ' .join(args.license))
|
|
153
|
+
simplified = self.licomp_toolkit.simplify(normalized)
|
|
154
|
+
return formatter.format_licomp_licenses(simplified), ReturnCodes.LICOMP_OK.value, None
|
|
155
|
+
|
|
156
|
+
def supported_resources(self, args):
|
|
157
|
+
formatter = LicompToolkitFormatter.formatter(args.output_format)
|
|
158
|
+
return formatter.format_licomp_resources(self.licomp_toolkit.licomp_resources_long()), ReturnCodes.LICOMP_OK.value, False
|
|
159
|
+
|
|
160
|
+
def _supports_helper(self, key, value, output_format):
|
|
161
|
+
licomp_resources = [x for x in self.licomp_toolkit.licomp_resources_long() if value in x[key]]
|
|
162
|
+
formatter = LicompToolkitFormatter.formatter(output_format)
|
|
163
|
+
return formatter.format_licomp_resources(licomp_resources)
|
|
164
|
+
|
|
165
|
+
def supports_license(self, args):
|
|
166
|
+
lic = args.license
|
|
167
|
+
if lic not in self.licomp_toolkit.supported_licenses():
|
|
168
|
+
return None, ReturnCodes.LICOMP_UNSUPPORTED_LICENSE.value, f'License "{args.license}" not supported.'
|
|
169
|
+
return self._supports_helper('licenses', lic, args.output_format), ReturnCodes.LICOMP_OK.value, None
|
|
170
|
+
|
|
171
|
+
def supports_usecase(self, args):
|
|
172
|
+
usecase = args.usecase
|
|
173
|
+
if usecase not in [UseCase.usecase_to_string(x) for x in self.licomp_toolkit.supported_usecases()]:
|
|
174
|
+
return None, ReturnCodes.LICOMP_UNSUPPORTED_USECASE.value, f'Use case "{args.usecase}" not supported. Supported use cases: {self.supported_usecases(args)[0]}'
|
|
175
|
+
return self._supports_helper('usecases', usecase, args.output_format), ReturnCodes.LICOMP_OK.value, None
|
|
176
|
+
|
|
177
|
+
def supports_provisioning(self, args):
|
|
178
|
+
provisioning = args.provisioning
|
|
179
|
+
if provisioning not in [Provisioning.provisioning_to_string(x) for x in self.licomp_toolkit.supported_provisionings()]:
|
|
180
|
+
return None, ReturnCodes.LICOMP_UNSUPPORTED_PROVISIONING.value, f'Provisioning "{args.provisioning}" not supported. Supported provisionings: {self.supported_provisionings(args)[0]}'
|
|
181
|
+
return self._supports_helper('provisionings', provisioning, args.output_format), ReturnCodes.LICOMP_OK.value, None
|
|
182
|
+
|
|
183
|
+
def outbound_candidate(self, args):
|
|
184
|
+
suggester = OutboundSuggester()
|
|
185
|
+
licenses_to_check = None
|
|
186
|
+
if args.all_licenses:
|
|
187
|
+
licenses_to_check = self.licomp_toolkit.supported_licenses()
|
|
188
|
+
|
|
189
|
+
resources, unsupported = resources_to_use(args)
|
|
190
|
+
if unsupported:
|
|
191
|
+
return f'Resource(s) {", ".join(unsupported)} is/are not supported', ReturnCodes.LICOMP_UNSUPPORTED_RESOURCE.value, True
|
|
192
|
+
candidates = suggester.compat_licenses(args.license_expression,
|
|
193
|
+
args.usecase,
|
|
194
|
+
args.provisioning,
|
|
195
|
+
licenses_to_check,
|
|
196
|
+
resources)
|
|
197
|
+
if args.least_compatible:
|
|
198
|
+
candidates.reverse()
|
|
199
|
+
|
|
200
|
+
formatter = LicompToolkitFormatter.formatter(args.output_format)
|
|
201
|
+
|
|
202
|
+
return formatter.format_licomp_licenses(candidates), ReturnCodes.LICOMP_OK.value, None
|
|
203
|
+
|
|
204
|
+
def display_compatibility(self, args):
|
|
205
|
+
display_compat = DisplayCompatibility(self.licomp_toolkit)
|
|
206
|
+
resources, unsupported = resources_to_use(args)
|
|
207
|
+
if unsupported:
|
|
208
|
+
return f'Resource(s) {", ".join(unsupported)} is/are not supported', ReturnCodes.LICOMP_UNSUPPORTED_RESOURCE.value, True
|
|
209
|
+
compats = display_compat.display_compatibility(args.licenses,
|
|
210
|
+
UseCase.string_to_usecase(args.usecase),
|
|
211
|
+
Provisioning.string_to_provisioning(args.provisioning),
|
|
212
|
+
resources)
|
|
213
|
+
formatter = LicompToolkitFormatter.formatter(args.output_format)
|
|
214
|
+
formatted = formatter.format_display_compatibilities(compats,
|
|
215
|
+
{'discard_unsupported': args.discard_unsupported_licenses})
|
|
216
|
+
return formatted, ReturnCodes.LICOMP_OK.value, None
|
|
217
|
+
|
|
218
|
+
def versions(self, args):
|
|
219
|
+
formatter = LicompToolkitFormatter.formatter(args.output_format)
|
|
220
|
+
return formatter.format_licomp_versions(self.licomp_toolkit.versions()), ReturnCodes.LICOMP_OK.value, False
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
def _working_return_code(return_code):
|
|
224
|
+
return return_code >= 0 and return_code < LicompToolkitReturnCodes.LICOMP_TOOLKIT_LAST_ERROR_CODE.value
|
|
225
|
+
|
|
226
|
+
def main():
|
|
227
|
+
logging.debug("Licomp Toolkit")
|
|
228
|
+
|
|
229
|
+
lct_parser = LicompToolkitParser(cli_name,
|
|
230
|
+
description,
|
|
231
|
+
epilog,
|
|
232
|
+
UseCase.LIBRARY,
|
|
233
|
+
Provisioning.BIN_DIST)
|
|
234
|
+
|
|
235
|
+
parser = lct_parser.parser
|
|
236
|
+
subparsers = lct_parser.sub_parsers()
|
|
237
|
+
|
|
238
|
+
parser.add_argument('-r', '--resources',
|
|
239
|
+
type=str,
|
|
240
|
+
action='append',
|
|
241
|
+
help=f'use specified licomp resource. For a list use the commands \'supported-resources\'. Use \'all\' to use all. Default: {", ".join(default_resources())}',
|
|
242
|
+
default=[])
|
|
243
|
+
|
|
244
|
+
parser.add_argument('-nv', '--no-verbose',
|
|
245
|
+
action='store_true',
|
|
246
|
+
help='keep compatibility report as short as possible',
|
|
247
|
+
default=[])
|
|
248
|
+
|
|
249
|
+
parser_v = subparsers.choices['verify']
|
|
250
|
+
parser_v.add_argument("--apply-license-policy", action='store_true', help='Apply license policy', default=False)
|
|
251
|
+
parser_v.add_argument("--license-policy-file", type=str, help='License policy file. Defaults to use default license policy.', default=None)
|
|
252
|
+
|
|
253
|
+
# Commands
|
|
254
|
+
parser_si = subparsers.add_parser('simplify', help='Normalize and simplify a license expression')
|
|
255
|
+
parser_si.set_defaults(which="simplify", func=lct_parser.simplify)
|
|
256
|
+
parser_si.add_argument("license", type=str, nargs="+", help='License expression to simplify')
|
|
257
|
+
|
|
258
|
+
parser_sr = subparsers.add_parser('supported-resources', help='List all supported Licomp resources')
|
|
259
|
+
parser_sr.set_defaults(which="supported_resources", func=lct_parser.supported_resources)
|
|
260
|
+
|
|
261
|
+
parser_sl = subparsers.add_parser('supports-license', help='List the Licomp resources supporting the license')
|
|
262
|
+
parser_sl.set_defaults(which="supports_license", func=lct_parser.supports_license)
|
|
263
|
+
parser_sl.add_argument("license")
|
|
264
|
+
|
|
265
|
+
parser_su = subparsers.add_parser('supports-usecase', help='List the Licomp resources supporting the usecase')
|
|
266
|
+
parser_su.set_defaults(which="supports_usecase", func=lct_parser.supports_usecase)
|
|
267
|
+
parser_su.add_argument("usecase")
|
|
268
|
+
|
|
269
|
+
parser_sp = subparsers.add_parser('supports-provisioning', help='List the Licomp resources supporting the provisioning')
|
|
270
|
+
parser_sp.set_defaults(which="supports_provisioning", func=lct_parser.supports_provisioning)
|
|
271
|
+
parser_sp.add_argument("provisioning")
|
|
272
|
+
|
|
273
|
+
parser_dc = subparsers.add_parser('display-compatibility', help='Display the compatibility between the supplied licenses')
|
|
274
|
+
parser_dc.set_defaults(which="display_compatibility", func=lct_parser.display_compatibility)
|
|
275
|
+
parser_dc.add_argument("licenses",
|
|
276
|
+
type=str,
|
|
277
|
+
nargs='+',
|
|
278
|
+
default=[])
|
|
279
|
+
parser_dc.add_argument('-dul', '--discard-unsupported-licenses',
|
|
280
|
+
action='store_true',
|
|
281
|
+
help='Discard unsupported licenses from the output',
|
|
282
|
+
default=False)
|
|
283
|
+
|
|
284
|
+
parser_ob = subparsers.add_parser('outbound-candidate', help='Identify outbound candidates to a license expression')
|
|
285
|
+
parser_ob.set_defaults(which='outbound_candidate', func=lct_parser.outbound_candidate)
|
|
286
|
+
parser_ob.add_argument("license_expression")
|
|
287
|
+
parser_ob.add_argument('-al', '--all-licenses',
|
|
288
|
+
action='store_true',
|
|
289
|
+
help='Use all known licenses to identify outbound candidates',
|
|
290
|
+
default=False)
|
|
291
|
+
parser_ob.add_argument('-lc', '--least-compatible',
|
|
292
|
+
action='store_true',
|
|
293
|
+
help='Sort the license according to least compatibility (i.e. from restrictive to permissive. Default is to list permissive to restrictive.',
|
|
294
|
+
default=False)
|
|
295
|
+
|
|
296
|
+
# Command: list versions (of all toolkit and licomp resources)
|
|
297
|
+
parser_sr = subparsers.add_parser('versions', help='Output version of licomp-toolkit and all the licomp resources')
|
|
298
|
+
parser_sr.set_defaults(which="versions", func=lct_parser.versions)
|
|
299
|
+
|
|
300
|
+
# Command: apply policy
|
|
301
|
+
parser_sr = subparsers.add_parser('apply-license-policy', help='')
|
|
302
|
+
parser_sr.set_defaults(which="apply_license_policy", func=lct_parser.apply_license_policy)
|
|
303
|
+
parser_sr.add_argument('--license-policy-file', '-lpf', type=str, help='License policy file', default=None)
|
|
304
|
+
parser_sr.add_argument("report_file", type=str)
|
|
305
|
+
|
|
306
|
+
res, code, err, func = lct_parser.run_noexit()
|
|
307
|
+
if _working_return_code(code):
|
|
308
|
+
if res:
|
|
309
|
+
print(res)
|
|
310
|
+
else:
|
|
311
|
+
if err:
|
|
312
|
+
print(err, file=sys.stderr)
|
|
313
|
+
else:
|
|
314
|
+
pass
|
|
315
|
+
else:
|
|
316
|
+
print(res, file=sys.stderr)
|
|
317
|
+
|
|
318
|
+
return code
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
if __name__ == '__main__':
|
|
322
|
+
sys.exit(main())
|
licomp_toolkit/config.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2024 Henrik Sandklef
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
|
+
|
|
5
|
+
licomp_toolkit_version = '0.6.3'
|
|
6
|
+
my_supported_api_version = '0.5'
|
|
7
|
+
licomp_toolkit_file_version = '0.5'
|
|
8
|
+
|
|
9
|
+
cli_name = 'licomp-toolkit'
|
|
10
|
+
module_name = 'licomp_toolkit'
|
|
11
|
+
|
|
12
|
+
disclaimer = 'This software and the data come with no guarantee. For more information read the disclaimers from the individual compatibility resources, and contact a lawyer to make sure your software is compliant.'
|
|
13
|
+
|
|
14
|
+
description = """
|
|
15
|
+
Simple command line tool to check compatibility between two licenses, given context
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
epilog = """
|
|
19
|
+
|
|
20
|
+
AUTHOR
|
|
21
|
+
Henrik Sandklef
|
|
22
|
+
|
|
23
|
+
PROJECT SITE
|
|
24
|
+
https://codeberg.org/software-compliance-org/licomp-toolkit
|
|
25
|
+
|
|
26
|
+
PYPI SITE
|
|
27
|
+
https://pypi.org/project/licomp-toolkit/
|
|
28
|
+
|
|
29
|
+
REPORTING BUGS
|
|
30
|
+
File a ticket at https://codeberg.org/software-compliance-org/licomp-toolkit/issues
|
|
31
|
+
|
|
32
|
+
COPYRIGHT
|
|
33
|
+
Copyright (c) 2024 Henrik Sandklef<hesa@sandklef.com>.
|
|
34
|
+
License GPL-3.0-or-later
|
|
35
|
+
|
|
36
|
+
ATTRIBUTION
|
|
37
|
+
licomp-toolkit is using various Licomp resources. Use the command supported-resources to list them.
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
"""
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema" : "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id" : "",
|
|
4
|
+
"title" : "Licomp Toolkit Reply",
|
|
5
|
+
"type" : "object",
|
|
6
|
+
"properties" : {
|
|
7
|
+
"meta": {
|
|
8
|
+
"type" : "object",
|
|
9
|
+
"properties" : {
|
|
10
|
+
"status" : {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"description" : ""
|
|
13
|
+
},
|
|
14
|
+
"tool" : {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"description" : ""
|
|
17
|
+
},
|
|
18
|
+
"file_version" : {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"description" : ""
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"compatibility_report": {
|
|
25
|
+
"type" : "object",
|
|
26
|
+
"$ref": "#/$defs/compatibility_object"
|
|
27
|
+
},
|
|
28
|
+
"outbound" : {
|
|
29
|
+
"$ref": "#/$defs/license",
|
|
30
|
+
"description" : "The outbound license expression."
|
|
31
|
+
},
|
|
32
|
+
"inbound" : {
|
|
33
|
+
"$ref": "#/$defs/license",
|
|
34
|
+
"description" : "The inbound license expression."
|
|
35
|
+
},
|
|
36
|
+
"usecase" : {
|
|
37
|
+
"type" : "string",
|
|
38
|
+
"enum": ["library", "compiler", "snippet", "tool", "test"],
|
|
39
|
+
"description" : "Usecase for the compatibility check, e.g. library (as in using the inbound licensed component as a library)"
|
|
40
|
+
},
|
|
41
|
+
"provisioning" : {
|
|
42
|
+
"type" : "string",
|
|
43
|
+
"enum": ["source-code-distribution", "binary-distribution", "local-use", "provide-service", "provide-webui"],
|
|
44
|
+
"description" : "The way the component is provided to the user for the compatibility check, e.g. binary-distribution"
|
|
45
|
+
},
|
|
46
|
+
"modification" : {
|
|
47
|
+
"type" : "string",
|
|
48
|
+
"description" : "Has the component been modified. Currently not used/implemented.",
|
|
49
|
+
"enum": [ "unmodified", "modified"]
|
|
50
|
+
},
|
|
51
|
+
"resources": {
|
|
52
|
+
"description": "Which resources are available, regardless of context",
|
|
53
|
+
"type": "array",
|
|
54
|
+
"items": {
|
|
55
|
+
"type" : "string"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"available_resources": {
|
|
59
|
+
"description": "Which resources are available given the context",
|
|
60
|
+
"type": "array",
|
|
61
|
+
"items": {
|
|
62
|
+
"type" : "string"
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
"unavailable_resources": {
|
|
66
|
+
"description": "Which resources are not available given the context",
|
|
67
|
+
"type": "array",
|
|
68
|
+
"items": {
|
|
69
|
+
"type": "object",
|
|
70
|
+
"properties": {
|
|
71
|
+
"resource": {
|
|
72
|
+
"type": "string",
|
|
73
|
+
"description": "The resource name"
|
|
74
|
+
},
|
|
75
|
+
"reasons": {
|
|
76
|
+
"type": "string",
|
|
77
|
+
"description": "The reason the resource is not available" }
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"compatibility" : {
|
|
82
|
+
"$ref": "#/$defs/compatibility",
|
|
83
|
+
"description" : "The inbound license expression."
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
"required" : [ "compatibility_report", "compatibility", "outbound", "inbound" , "usecase", "resources", "unavailable_resources", "available_resources" ],
|
|
87
|
+
"additionalProperties" : false,
|
|
88
|
+
"$defs": {
|
|
89
|
+
"compatibility_object": {
|
|
90
|
+
"type" : "object",
|
|
91
|
+
"oneOf": [
|
|
92
|
+
{
|
|
93
|
+
"properties": {
|
|
94
|
+
"compatibility": {
|
|
95
|
+
"$ref": "#/$defs/compatibility",
|
|
96
|
+
"description" : "The inbound license expression."
|
|
97
|
+
},
|
|
98
|
+
"compatibility_check": {
|
|
99
|
+
"$ref": "#/$defs/compatibility_check"
|
|
100
|
+
},
|
|
101
|
+
"check_class": {
|
|
102
|
+
"type": "string",
|
|
103
|
+
"description": "Names the class/function used to determine. For development purposes"
|
|
104
|
+
},
|
|
105
|
+
"inbound_license": {
|
|
106
|
+
"$ref": "#/$defs/license",
|
|
107
|
+
"description" : "The inbound license expression."
|
|
108
|
+
},
|
|
109
|
+
"outbound_license": {
|
|
110
|
+
"$ref": "#/$defs/license",
|
|
111
|
+
"description" : "The outbound license expression."
|
|
112
|
+
},
|
|
113
|
+
"compatibility_details": {
|
|
114
|
+
"oneOf": [
|
|
115
|
+
{
|
|
116
|
+
"type": "object",
|
|
117
|
+
"properties": {
|
|
118
|
+
"compatibilities": {
|
|
119
|
+
"type": "array",
|
|
120
|
+
"items": {
|
|
121
|
+
"$ref": "#/$defs/licomp_object"
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"type": "null"
|
|
128
|
+
}
|
|
129
|
+
]
|
|
130
|
+
},
|
|
131
|
+
"compatibility_object": {
|
|
132
|
+
"type" : "object",
|
|
133
|
+
"anyOf": [
|
|
134
|
+
{
|
|
135
|
+
"$ref": "#/$defs/compatibility_object"
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"properties": {}
|
|
139
|
+
}
|
|
140
|
+
]
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
"required": [ "compatibility", "compatibility_check", "inbound_license" , "outbound_license", "compatibility_object", "compatibility_details"],
|
|
144
|
+
"additionalProperties" : false
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"properties": {
|
|
148
|
+
"compatibility" : {
|
|
149
|
+
"$ref": "#/$defs/compatibility",
|
|
150
|
+
"description" : "The inbound license expression."
|
|
151
|
+
},
|
|
152
|
+
"compatibility_check": {
|
|
153
|
+
"$ref": "#/$defs/compatibility_check"
|
|
154
|
+
},
|
|
155
|
+
"check_class": {
|
|
156
|
+
"type": "string",
|
|
157
|
+
"description": "Names the class/function used to determine. For development purposes"
|
|
158
|
+
},
|
|
159
|
+
"inbound_license": {
|
|
160
|
+
"$ref": "#/$defs/license",
|
|
161
|
+
"description" : "The inbound license expression."
|
|
162
|
+
},
|
|
163
|
+
"outbound_license": {
|
|
164
|
+
"$ref": "#/$defs/license",
|
|
165
|
+
"description" : "The inbound license expression."
|
|
166
|
+
},
|
|
167
|
+
"compatibility_details": {
|
|
168
|
+
"type": "null"
|
|
169
|
+
},
|
|
170
|
+
"operator": {
|
|
171
|
+
"enum": [ "AND", "OR" ],
|
|
172
|
+
"description" : "The logical operator between two license expressions."
|
|
173
|
+
},
|
|
174
|
+
"operands": {
|
|
175
|
+
"type": "array",
|
|
176
|
+
"items": {
|
|
177
|
+
"compatibility_object": {
|
|
178
|
+
"type" : "object",
|
|
179
|
+
"$ref": "#/$defs/compatibility_object"
|
|
180
|
+
},
|
|
181
|
+
"compatibility": { "type": "string" }
|
|
182
|
+
},
|
|
183
|
+
"description": "The operands for the operator. The operands can be either a license or an operator."
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
"required": [ "compatibility", "compatibility_check", "inbound_license" , "outbound_license" , "operator", "operands" ],
|
|
187
|
+
"additionalProperties" : false
|
|
188
|
+
}
|
|
189
|
+
]
|
|
190
|
+
},
|
|
191
|
+
"compatibility" : {
|
|
192
|
+
"type" : "string",
|
|
193
|
+
"enum": [ "yes", "no", "depends", "unknown", "unsupported", "mixed", null],
|
|
194
|
+
"description" : "The compatbility between the Outbound and Inbound license expressions"
|
|
195
|
+
},
|
|
196
|
+
"license" : {
|
|
197
|
+
"type" : "string",
|
|
198
|
+
"minLength": 1
|
|
199
|
+
},
|
|
200
|
+
"compatibility_check": {
|
|
201
|
+
"type": "string",
|
|
202
|
+
"enum": [
|
|
203
|
+
"outbound-expression -> inbound-expression",
|
|
204
|
+
"outbound-expression -> inbound-license",
|
|
205
|
+
"outbound-license -> inbound-expression",
|
|
206
|
+
"outbound-license -> inbound-license"
|
|
207
|
+
],
|
|
208
|
+
"description" : "A text describing if outbound license or expression is checked for compatiblility against inbound license or expression."
|
|
209
|
+
},
|
|
210
|
+
"licomp_object": {
|
|
211
|
+
"type" : "object",
|
|
212
|
+
"properties" : {
|
|
213
|
+
"status" : {
|
|
214
|
+
"enum": [ "failure", "success" ],
|
|
215
|
+
"description" : "Overall status indicating if the compatibility check succeeded."
|
|
216
|
+
},
|
|
217
|
+
"status_details" : {
|
|
218
|
+
"type" : "object",
|
|
219
|
+
"properties" : {
|
|
220
|
+
"provisioning_status": {
|
|
221
|
+
"enum": [ "failure", "success" ],
|
|
222
|
+
"description" : "Status indicating if the provisioning is supported."
|
|
223
|
+
},
|
|
224
|
+
"usecase_status": {
|
|
225
|
+
"enum": [ "failure", "success" ],
|
|
226
|
+
"description" : "Status indicating if the usecase is supported."
|
|
227
|
+
},
|
|
228
|
+
"license_supported_status": {
|
|
229
|
+
"enum": [ "failure", "success" ],
|
|
230
|
+
"description" : "Status indicating if the licenses are supported."
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
"outbound" : {
|
|
235
|
+
"type" : "string",
|
|
236
|
+
"minLength": 1,
|
|
237
|
+
"description" : "The outbound license"
|
|
238
|
+
},
|
|
239
|
+
"inbound" : {
|
|
240
|
+
"type" : "string",
|
|
241
|
+
"minLength": 1,
|
|
242
|
+
"description" : "The inbound license"
|
|
243
|
+
},
|
|
244
|
+
"usecase" : {
|
|
245
|
+
"type" : "string",
|
|
246
|
+
"enum": ["library", "compiler", "snippet", "tool", "test"],
|
|
247
|
+
"description" : "Usecase for the compatibility check, e.g. library (as in using the inbound licensed component as a library)"
|
|
248
|
+
},
|
|
249
|
+
"provisioning" : {
|
|
250
|
+
"type" : "string",
|
|
251
|
+
"enum": ["source-code-distribution", "binary-distribution", "local-use", "provide-service", "provide-webui"],
|
|
252
|
+
"description" : "The way the component is provided to the user for the compatibility check, e.g. binary-distribution"
|
|
253
|
+
},
|
|
254
|
+
"modification" : {
|
|
255
|
+
"type" : "string",
|
|
256
|
+
"description" : "Has the component been modified. Currently not used/implemented.",
|
|
257
|
+
"enum": [ "unmodified", "modified"]
|
|
258
|
+
},
|
|
259
|
+
"compatibility_status" : {
|
|
260
|
+
"enum": [ "yes", "no", "depends", "unknown", "unsupported", null],
|
|
261
|
+
"description" : "The compatbility between the Outbound and Inbound license expressions"
|
|
262
|
+
},
|
|
263
|
+
"explanation" : {
|
|
264
|
+
"type" : "array" ,
|
|
265
|
+
"items": {
|
|
266
|
+
"type" : "string"
|
|
267
|
+
},
|
|
268
|
+
"description" : "A list of texts describing the compatiblity, e.g. how the compatibility was determined"
|
|
269
|
+
},
|
|
270
|
+
"api_version" : {
|
|
271
|
+
"type" : "string",
|
|
272
|
+
"pattern": "^[0-9].[0-9](.[0-9]){0,1}$",
|
|
273
|
+
"description" : "The api version of the program providing the reply"
|
|
274
|
+
},
|
|
275
|
+
"resource_name" : {
|
|
276
|
+
"type" : "string",
|
|
277
|
+
"minLength": 1,
|
|
278
|
+
"description" : "The name of the program providing the reply, e.g. licomp-osadl"
|
|
279
|
+
},
|
|
280
|
+
"resource_version" : {
|
|
281
|
+
"type" : "string",
|
|
282
|
+
"pattern": "^[0-9].[0-9](.[0-9]){0,1}$",
|
|
283
|
+
"description" : "The versions of the program providing the reply, e.g. licomp-osadl"
|
|
284
|
+
},
|
|
285
|
+
"resource_disclaimer" : {
|
|
286
|
+
"type" : "string",
|
|
287
|
+
"minLength": 10,
|
|
288
|
+
"description" : "A disclaimer of the program providing the reply."
|
|
289
|
+
},
|
|
290
|
+
"data_url" : {
|
|
291
|
+
"type" : "string",
|
|
292
|
+
"minLength": 10,
|
|
293
|
+
"description" : "A URL pointing to the data used to provide the resulting compatibility."
|
|
294
|
+
},
|
|
295
|
+
"resource_url" : {
|
|
296
|
+
"type" : "string",
|
|
297
|
+
"minLength": 10,
|
|
298
|
+
"description" : "A URL pointing to the project page (or similar) for the program providing the resulting compatibility."
|
|
299
|
+
}
|
|
300
|
+
},
|
|
301
|
+
"required" : [ "status", "status_details", "outbound", "inbound", "usecase", "provisioning", "modification", "compatibility_status", "explanation", "api_version", "resource_name", "resource_version", "resource_disclaimer", "data_url", "resource_url"],
|
|
302
|
+
"additionalProperties" : false
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|