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.
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())
@@ -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
+ }