From 0a0caacfa54dd086b87e31f5e806e5f21d5ffc3f Mon Sep 17 00:00:00 2001 From: Enguerrand de Ribaucourt Date: Mon, 12 Aug 2024 14:28:29 +0200 Subject: recipetool: create_npm: reuse license utils create_npm.py duplicated the logic for matching licenses from files and also finding them. This patch refactors the code to reuse the license utils. This will make the code more maintainable and also align both behaviors. For instance, some licenses weren't matched properly because the duplicate logic did not support the difference in format in the md5 tables for COMMON_LICENSE_DIR and licenses.csv. This is also faster since the license files were being read twice. The result is slightly more accurate since the utils have better implementations, and I was able to reuse the logic for the root PN package, as well as the base LICENSE variable. I chose to extract generate_common_licenses_chksums into create.py since it can be considered a general utility function to allow other recipetool creators to refer to COMMON_LICENSE_DIR files. I updated the wording in the code when appropriate. v3: - added commit - this replaces the commit that added all the COMMON_LICENSE_DIR md5 to licenses.csv (From OE-Core rev: 7bc18bed63b94689890bcde63402d7cc1cedffa9) Signed-off-by: Enguerrand de Ribaucourt Signed-off-by: Alexandre Belloni Signed-off-by: Richard Purdie --- scripts/lib/recipetool/create_npm.py | 92 +++++++++++------------------------- 1 file changed, 28 insertions(+), 64 deletions(-) (limited to 'scripts/lib/recipetool/create_npm.py') diff --git a/scripts/lib/recipetool/create_npm.py b/scripts/lib/recipetool/create_npm.py index 78dc248f31..3363a0e7ee 100644 --- a/scripts/lib/recipetool/create_npm.py +++ b/scripts/lib/recipetool/create_npm.py @@ -16,8 +16,7 @@ from bb.fetch2.npm import NpmEnvironment from bb.fetch2.npm import npm_package from bb.fetch2.npmsw import foreach_dependencies from recipetool.create import RecipeHandler -from recipetool.create import get_license_md5sums -from recipetool.create import find_licenses +from recipetool.create import match_licenses, find_license_files, generate_common_licenses_chksums from recipetool.create import split_pkg_licenses logger = logging.getLogger('recipetool') @@ -112,51 +111,53 @@ class NpmRecipeHandler(RecipeHandler): """Return the extra license files and the list of packages""" licfiles = [] packages = {} - # Licenses from package.json point to COMMON_LICENSE_DIR so we need - # to associate them explicitely for split_pkg_licenses() + # Licenses from package.json will point to COMMON_LICENSE_DIR so we need + # to associate them explicitely to packages for split_pkg_licenses() fallback_licenses = dict() - # Handle the parent package - packages["${PN}"] = "" - - def _licfiles_append_fallback_package_files(destdir): - """Append package.json files as fallback to license files if a license files is missing""" + def _find_package_licenses(destdir): + """Either find license files, or use package.json metadata""" def _get_licenses_from_package_json(package_json): with open(os.path.join(srctree, package_json), "r") as f: data = json.load(f) if "license" in data: licenses = data["license"].split(" ") licenses = [license.strip("()") for license in licenses if license != "OR" and license != "AND"] - return ["${COMMON_LICENSE_DIR}/" + license for license in licenses], licenses + return [], licenses else: return [package_json], None - fallback = True basedir = os.path.join(srctree, destdir) - for fn in os.listdir(basedir): - upper = fn.upper() - if upper.startswith("COPYING") or "LICENCE" in upper or "LICENSE" in upper: - fallback = False - if fallback: + licfiles = find_license_files(basedir) + if len(licfiles) > 0: + return licfiles, None + else: + # A license wasn't found in the package directory, so we'll use the package.json metadata pkg_json = os.path.join(basedir, "package.json") return _get_licenses_from_package_json(pkg_json) - return [], None + + def _get_package_licenses(destdir, package): + (package_licfiles, package_licenses) = _find_package_licenses(destdir) + if package_licfiles: + licfiles.extend(package_licfiles) + else: + fallback_licenses[package] = package_licenses # Handle the dependencies def _handle_dependency(name, params, destdir): deptree = destdir.split('node_modules/') suffix = "-".join([npm_package(dep) for dep in deptree]) packages["${PN}" + suffix] = destdir - (fallback_licfiles, common_lics) = _licfiles_append_fallback_package_files(destdir) - licfiles.extend(fallback_licfiles) - if common_lics: - fallback_licenses["${PN}" + suffix] = common_lics + _get_package_licenses(destdir, "${PN}" + suffix) with open(shrinkwrap_file, "r") as f: shrinkwrap = json.load(f) - foreach_dependencies(shrinkwrap, _handle_dependency, dev) + # Handle the parent package + packages["${PN}"] = "" + _get_package_licenses(srctree, "${PN}") + return licfiles, packages, fallback_licenses # Handle the peer dependencies @@ -279,48 +280,11 @@ class NpmRecipeHandler(RecipeHandler): bb.note("Handling licences ...") (licfiles, packages, fallback_licenses) = self._handle_licenses(srctree, shrinkwrap_file, dev) - - def _guess_odd_license(licfiles): - import bb - - md5sums = get_license_md5sums(d, linenumbers=True) - - def _resolve_licfile(srctree, licfile): - match = re.search(r'\$\{COMMON_LICENSE_DIR\}/(.+)$', licfile) - if match: - license = match.group(1) - commonlicdir = d.getVar('COMMON_LICENSE_DIR') - return os.path.join(commonlicdir, license) - - return os.path.join(srctree, licfile) - - chksums = [] - licenses = [] - md5value = None - for licfile in licfiles: - f = _resolve_licfile(srctree, licfile) - try: - md5value = bb.utils.md5_file(f) - except FileNotFoundError: - logger.info("Could not determine license for '%s'" % licfile) - (license, beginline, endline, md5) = md5sums.get(md5value, - (None, "", "", "")) - if not license: - license = "Unknown" - logger.info("Please add the following line for '%s' to a " - "'lib/recipetool/licenses.csv' and replace `Unknown`, " - "`X`, `Y` and `MD5` with the license, begin line, " - "end line and partial MD5 checksum:\n" \ - "%s,Unknown,X,Y,MD5" % (licfile, md5value)) - chksums.append("file://%s%s%s;md5=%s" % (licfile, - ";beginline=%s" % (beginline) if beginline else "", - ";endline=%s" % (endline) if endline else "", - md5 if md5 else md5value)) - licenses.append((license, licfile, md5value)) - return (licenses, chksums, fallback_licenses) - - (licenses, extravalues["LIC_FILES_CHKSUM"], fallback_licenses) = _guess_odd_license(licfiles) - split_pkg_licenses([*licenses, *find_licenses(srctree, d)], packages, lines_after, fallback_licenses) + licvalues = match_licenses(licfiles, srctree, d) + split_pkg_licenses(licvalues, packages, lines_after, fallback_licenses) + fallback_licenses_flat = [license for sublist in fallback_licenses.values() for license in sublist] + extravalues["LIC_FILES_CHKSUM"] = generate_common_licenses_chksums(fallback_licenses_flat, d) + extravalues["LICENSE"] = fallback_licenses_flat classes.append("npm") handled.append("buildsystem") -- cgit v1.2.3-54-g00ecf