Module continuous_delivery_scripts.spdx_report.spdx_summary
Summary generators.
Functions
def generate_file_based_on_template(output_dir: pathlib.Path,
template_name: str,
template_args: dict,
suffix: str | None = None) ‑> None-
Expand source code
def generate_file_based_on_template( output_dir: Path, template_name: str, template_args: dict, suffix: Optional[str] = None, ) -> None: """Write file based on template and arguments.""" logger.info("Loading template '%s'.", template_name) template = _get_jinja2_env().get_template(template_name) filename = Path(template_name.rsplit(".", 1)[0]) if suffix: filename = Path( "{0}_{2}{1}".format( *( str(filename.name), str(filename.suffix), str(suffix.replace(".", "_").replace("-", "_")), ) ) ) output_filename = output_dir.joinpath(filename) rendered = template.render(**template_args) logger.info("Writing to '%s'.", output_filename) output_filename.write_text(rendered, encoding="utf8")Write file based on template and arguments.
Classes
class SummaryGenerator (project_package: SpdxPackage,
dependencies_documents: List[SpdxPackage],
missing_dependencies: List[str] | None = None,
licence_assessments: Dict[str, LicenceAssessmentResult] | None = None)-
Expand source code
class SummaryGenerator: """Licensing summary generator.""" def __init__( self, project_package: SpdxPackage, dependencies_documents: List[SpdxPackage], missing_dependencies: Optional[List[str]] = None, licence_assessments: Optional[Dict[str, LicenceAssessmentResult]] = None, ) -> None: """Initialiser.""" self.project = project_package self.all_packages = list(dependencies_documents) self.all_packages.append(self.project) self.missing_dependencies = sorted(set(missing_dependencies or [])) if licence_assessments is None: assessor = LicenceAssessor(LicenceAssessmentPolicy.from_config()) licence_assessments = { dependency.name: assessor.assess( project_package.main_licence, dependency.licence, dependency.name, dependency.version, project_package.metadata.has_unknown_licence, dependency.metadata.has_unknown_licence or dependency.main_licence == UNKNOWN_LICENCE.identifier, get_package_manual_licence(dependency.name), ) for dependency in dependencies_documents } self.licence_assessments = licence_assessments self._template_arguments: Optional[dict] = None def _generate_template_arguments(self) -> Dict[str, Any]: arguments: Dict[str, Any] = dict() global_compliance, description_list = self._generate_packages_description() compliance_points = ( [ "The project and all assessed dependencies meet the configured licence policy, " "including any documented manual reviews.", ] if global_compliance else [ "The project or one or more dependencies do not meet the configured licence policy.", "Review the package results below for details.", ] ) arguments["project"] = { "name": self.project.name, "licence": self.project.main_licence, "licence_href": _project_licence_href(), "accepted_licences": _configured_licence_policy(), "compliance": global_compliance, "compliance_points": compliance_points, "compliance_details": " ".join( [f"The project is licensed under the {self.project.main_licence} licence.", *compliance_points] ), } arguments["packages"] = description_list arguments["licence_assessment_counts"] = { status.value: sum(result.status is status for result in self.licence_assessments.values()) for status in LicenceAssessment } arguments["missing_dependencies"] = self.missing_dependencies arguments["unknown_licences"] = sorted( p.name for p in self.all_packages if p.metadata.has_unknown_licence or p.main_licence == UNKNOWN_LICENCE.identifier ) arguments["unreviewed_licences"] = [ name for name in arguments["unknown_licences"] if not get_package_manual_check(name)[1] ] arguments["undocumented_exemptions"] = sorted( p.name for p in self.all_packages if get_package_manual_check(p.name)[0] and not get_package_manual_check(p.name)[1] ) arguments["project"]["complete"] = not ( self.missing_dependencies or arguments["unreviewed_licences"] or arguments["undocumented_exemptions"] ) if not arguments["project"]["complete"]: compliance_points = [ "The licence audit is incomplete.", "Review missing dependencies, unknown licences and undocumented exemptions before using this report.", ] arguments["project"]["compliance_points"] = compliance_points arguments["project"]["compliance_details"] = " ".join( [f"The project is licensed under the {self.project.main_licence} licence.", *compliance_points] ) arguments["render_time"] = datetime.datetime.now() return arguments def _generate_packages_description(self) -> Tuple[bool, dict]: description_list = dict() global_compliance = True for p in self.all_packages: main_licence_valid = p.is_main_licence_accepted actual_licence_valid = p.is_licence_accepted package_manually_checked, manual_check_details = get_package_manual_check(p.name) is_licence_compliant = main_licence_valid and actual_licence_valid is_compliant = is_licence_compliant or package_manually_checked if not is_compliant: global_compliance = False description_list[p.name] = self._generate_description_for_one_package( is_compliant, is_licence_compliant, package_manually_checked, manual_check_details, p, ) return global_compliance, description_list def _generate_description_for_one_package( self, is_compliant: bool, is_licence_compliant: bool, package_manually_checked: bool, manual_check_details: Optional[str], p: SpdxPackage, ) -> dict: description = { "name": p.name, "anchor": f"package-{generate_uuid_based_on_str(p.name)}", "is_dependency": p.is_dependency, "url": p.url, "licence": p.licence, "version": p.version, "licence_source": p.metadata.licence_source, "declared_licence": p.metadata.declared_licence, "licence_classifiers": p.metadata.licence_classifiers, "licence_candidates": p.metadata.licence_candidates, "licence_evidence": p.metadata.licence_evidence, "manual_check": {"checked": package_manually_checked, "reason": manual_check_details or ""}, "is_compliant": is_compliant, "mark_as_problematic": not is_licence_compliant, "licence_compliance_details": ( "Automatic licence assessment meets the configured policy." if is_licence_compliant else ( "Automatic licence assessment does not meet the configured policy; " f"accepted after manual review: {manual_check_details or 'no reason recorded'}." if package_manually_checked else "Automatic licence assessment does not meet the configured policy." ) ), } if p.is_dependency: description["licence_assessment"] = self.licence_assessments[p.name].as_report() return description @property def template_arguments(self) -> dict: """Gets template arguments.""" if not self._template_arguments: self._template_arguments = self._generate_template_arguments() return self._template_arguments def generate_summary(self, dir: Path) -> None: """Generates a licensing summary into the specified directory. Args: dir: output directory """ for t in JINJA_TEMPLATES: generate_file_based_on_template(dir, t, self.template_arguments) arguments = dict(self.template_arguments) arguments["render_time"] = arguments["render_time"].isoformat() dir.joinpath("third_party_IP_report.json").write_text( json.dumps(arguments, indent=2, sort_keys=True) + "\n", encoding="utf8" ) _link_report_from_index(dir)Licensing summary generator.
Initialiser.
Instance variables
prop template_arguments : dict-
Expand source code
@property def template_arguments(self) -> dict: """Gets template arguments.""" if not self._template_arguments: self._template_arguments = self._generate_template_arguments() return self._template_argumentsGets template arguments.
Methods
def generate_summary(self, dir: pathlib.Path) ‑> None-
Expand source code
def generate_summary(self, dir: Path) -> None: """Generates a licensing summary into the specified directory. Args: dir: output directory """ for t in JINJA_TEMPLATES: generate_file_based_on_template(dir, t, self.template_arguments) arguments = dict(self.template_arguments) arguments["render_time"] = arguments["render_time"].isoformat() dir.joinpath("third_party_IP_report.json").write_text( json.dumps(arguments, indent=2, sort_keys=True) + "\n", encoding="utf8" ) _link_report_from_index(dir)Generates a licensing summary into the specified directory.
- Args
- -----=
dir- output directory