All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/4] mutlilib: Handle WHITELIST_GPL-3.0 being unset
@ 2022-03-01 23:42 Richard Purdie
  2022-03-01 23:42 ` [PATCH 2/4] base/license: Rework INCOMPATIBLE_LICENSE variable handling Richard Purdie
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Richard Purdie @ 2022-03-01 23:42 UTC (permalink / raw)
  To: openembedded-core

The code doesn't work if the variable is unset, fix that.

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
---
 meta/classes/multilib.bbclass | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/meta/classes/multilib.bbclass b/meta/classes/multilib.bbclass
index ec2013198ce..1ad654f546d 100644
--- a/meta/classes/multilib.bbclass
+++ b/meta/classes/multilib.bbclass
@@ -77,9 +77,10 @@ python multilib_virtclass_handler () {
 
     # Expand WHITELIST_GPL-3.0 with multilib prefix
     pkgs = e.data.getVar("WHITELIST_GPL-3.0")
-    for pkg in pkgs.split():
-        pkgs += " " + variant + "-" + pkg
-    e.data.setVar("WHITELIST_GPL-3.0", pkgs)
+    if pkgs:
+        for pkg in pkgs.split():
+            pkgs += " " + variant + "-" + pkg
+        e.data.setVar("WHITELIST_GPL-3.0", pkgs)
 
     # DEFAULTTUNE can change TARGET_ARCH override so expand this now before update_data
     newtune = e.data.getVar("DEFAULTTUNE:" + "virtclass-multilib-" + variant, False)
-- 
2.32.0



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/4] base/license: Rework INCOMPATIBLE_LICENSE variable handling
  2022-03-01 23:42 [PATCH 1/4] mutlilib: Handle WHITELIST_GPL-3.0 being unset Richard Purdie
@ 2022-03-01 23:42 ` Richard Purdie
  2022-03-01 23:42 ` [PATCH 3/4] license/insane: Show warning for obsolete license usage Richard Purdie
  2022-03-01 23:42 ` [PATCH 4/4] license: Rework INCOMPATIBLE_LICENSE wildcard handling Richard Purdie
  2 siblings, 0 replies; 8+ messages in thread
From: Richard Purdie @ 2022-03-01 23:42 UTC (permalink / raw)
  To: openembedded-core; +Cc: Saul Wold, Saul Wold

From: Saul Wold <Saul.Wold@windriver.com>

This re-writes the INCOMPATIBLE_LICENSE checking code to replace
the WHITELIST_<lic> with
INCOMPATIBLE_LICENSE_EXCEPTIONS = '<pkg>:<lic> <pkg>:<lic> ...'

This initial change leaves most of the code structure in place,
but the code in base.bbclass needs to be re-written to make
the check more consistent around packages (PKGS) and not recipe
names (PN). This also is taking into account the changes for SPDX
licenses.

The aim is to provide a mode consistent variable where the variable
name is known and can easily be queried.

Signed-off-by: Saul Wold <saul.wold@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
---
 meta/classes/base.bbclass                     | 67 ++++++++-----------
 meta/classes/license_image.bbclass            | 33 ++++-----
 meta/classes/multilib.bbclass                 |  6 +-
 meta/conf/bitbake.conf                        | 11 +++
 meta/lib/oe/license.py                        |  5 ++
 .../oeqa/selftest/cases/incompatible_lic.py   |  4 +-
 6 files changed, 63 insertions(+), 63 deletions(-)

diff --git a/meta/classes/base.bbclass b/meta/classes/base.bbclass
index 27c1d6168d4..bfc7087a189 100644
--- a/meta/classes/base.bbclass
+++ b/meta/classes/base.bbclass
@@ -595,46 +595,35 @@ python () {
         if check_license and bad_licenses:
             bad_licenses = expand_wildcard_licenses(d, bad_licenses)
 
-            whitelist = []
-            for lic in bad_licenses:
-                spdx_license = return_spdx(d, lic)
-                whitelist.extend((d.getVar("WHITELIST_" + lic) or "").split())
-                if spdx_license:
-                    whitelist.extend((d.getVar("WHITELIST_" + spdx_license) or "").split())
-
-            if pn in whitelist:
-                '''
-                We need to track what we are whitelisting and why. If pn is
-                incompatible we need to be able to note that the image that
-                is created may infact contain incompatible licenses despite
-                INCOMPATIBLE_LICENSE being set.
-                '''
-                bb.note("Including %s as buildable despite it having an incompatible license because it has been whitelisted" % pn)
-            else:
-                pkgs = d.getVar('PACKAGES').split()
-                skipped_pkgs = {}
-                unskipped_pkgs = []
-                for pkg in pkgs:
-                    incompatible_lic = incompatible_license(d, bad_licenses, pkg)
-                    if incompatible_lic:
-                        skipped_pkgs[pkg] = incompatible_lic
-                    else:
-                        unskipped_pkgs.append(pkg)
-                if unskipped_pkgs:
-                    for pkg in skipped_pkgs:
-                        bb.debug(1, "Skipping the package %s at do_rootfs because of incompatible license(s): %s" % (pkg, ' '.join(skipped_pkgs[pkg])))
-                        d.setVar('_exclude_incompatible-' + pkg, ' '.join(skipped_pkgs[pkg]))
-                    for pkg in unskipped_pkgs:
-                        bb.debug(1, "Including the package %s" % pkg)
+            exceptions = (d.getVar("INCOMPATIBLE_LICENSE_EXCEPTIONS") or "").split()
+
+            pkgs = d.getVar('PACKAGES').split()
+            skipped_pkgs = {}
+            unskipped_pkgs = []
+            for pkg in pkgs:
+                remaining_bad_licenses = oe.license.apply_pkg_license_exception(pkg, bad_licenses, exceptions)
+
+                incompatible_lic = incompatible_license(d, remaining_bad_licenses, pkg)
+                if incompatible_lic:
+                    skipped_pkgs[pkg] = incompatible_lic
                 else:
-                    incompatible_lic = incompatible_license(d, bad_licenses)
-                    for pkg in skipped_pkgs:
-                        incompatible_lic += skipped_pkgs[pkg]
-                    incompatible_lic = sorted(list(set(incompatible_lic)))
-
-                    if incompatible_lic:
-                        bb.debug(1, "Skipping recipe %s because of incompatible license(s): %s" % (pn, ' '.join(incompatible_lic)))
-                        raise bb.parse.SkipRecipe("it has incompatible license(s): %s" % ' '.join(incompatible_lic))
+                    unskipped_pkgs.append(pkg)
+
+            if unskipped_pkgs:
+                for pkg in skipped_pkgs:
+                    bb.debug(1, "Skipping the package %s at do_rootfs because of incompatible license(s): %s" % (pkg, ' '.join(skipped_pkgs[pkg])))
+                    d.setVar('_exclude_incompatible-' + pkg, ' '.join(skipped_pkgs[pkg]))
+                for pkg in unskipped_pkgs:
+                    bb.debug(1, "Including the package %s" % pkg)
+            else:
+                incompatible_lic = incompatible_license(d, bad_licenses)
+                for pkg in skipped_pkgs:
+                    incompatible_lic += skipped_pkgs[pkg]
+                incompatible_lic = sorted(list(set(incompatible_lic)))
+
+                if incompatible_lic:
+                    bb.debug(1, "Skipping recipe %s because of incompatible license(s): %s" % (pn, ' '.join(incompatible_lic)))
+                    raise bb.parse.SkipRecipe("it has incompatible license(s): %s" % ' '.join(incompatible_lic))
 
     needsrcrev = False
     srcuri = d.getVar('SRC_URI')
diff --git a/meta/classes/license_image.bbclass b/meta/classes/license_image.bbclass
index bf70bee99bb..0a5ea0a2fbc 100644
--- a/meta/classes/license_image.bbclass
+++ b/meta/classes/license_image.bbclass
@@ -54,28 +54,23 @@ def write_license_files(d, license_manifest, pkg_dic, rootfs=True):
     bad_licenses = (d.getVar("INCOMPATIBLE_LICENSE") or "").split()
     bad_licenses = expand_wildcard_licenses(d, bad_licenses)
 
-    whitelist = []
-    for lic in bad_licenses:
-        whitelist.extend((d.getVar("WHITELIST_" + lic) or "").split())
-
+    exceptions = (d.getVar("INCOMPATIBLE_LICENSE_EXCEPTIONS") or "").split()
     with open(license_manifest, "w") as license_file:
         for pkg in sorted(pkg_dic):
-            if bad_licenses and pkg not in whitelist:
-                try:
-                    licenses = incompatible_pkg_license(d, bad_licenses, pkg_dic[pkg]["LICENSE"])
-                    if licenses:
-                        bb.fatal("Package %s cannot be installed into the image because it has incompatible license(s): %s" %(pkg, ' '.join(licenses)))
-                    (pkg_dic[pkg]["LICENSE"], pkg_dic[pkg]["LICENSES"]) = \
-                        oe.license.manifest_licenses(pkg_dic[pkg]["LICENSE"],
-                        bad_licenses, canonical_license, d)
-                except oe.license.LicenseError as exc:
-                    bb.fatal('%s: %s' % (d.getVar('P'), exc))
+            remaining_bad_licenses = oe.license.apply_pkg_license_exception(pkg, bad_licenses, exceptions)
+            incompatible_licenses = incompatible_pkg_license(d, remaining_bad_licenses, pkg_dic[pkg]["LICENSE"])
+            if incompatible_licenses:
+                bb.fatal("Package %s cannot be installed into the image because it has incompatible license(s): %s" %(pkg, ' '.join(incompatible_licenses)))
             else:
-                pkg_dic[pkg]["LICENSES"] = re.sub(r'[|&()*]', ' ', pkg_dic[pkg]["LICENSE"])
-                pkg_dic[pkg]["LICENSES"] = re.sub(r'  *', ' ', pkg_dic[pkg]["LICENSES"])
-                pkg_dic[pkg]["LICENSES"] = pkg_dic[pkg]["LICENSES"].split()
-                if pkg in whitelist:
-                    oe.qa.handle_error('license-incompatible', "Including %s with an incompatible license %s into the image, because it has been whitelisted." %(pkg, pkg_dic[pkg]["LICENSE"]), d)
+                incompatible_licenses = incompatible_pkg_license(d, bad_licenses, pkg_dic[pkg]["LICENSE"])
+                if incompatible_licenses:
+                    oe.qa.handle_error('license-incompatible', "Including %s with incompatible license(s) %s into the image, because it has been allowed by exception list." %(pkg, ' '.join(incompatible_licenses)), d)
+            try:
+                (pkg_dic[pkg]["LICENSE"], pkg_dic[pkg]["LICENSES"]) = \
+                    oe.license.manifest_licenses(pkg_dic[pkg]["LICENSE"],
+                    remaining_bad_licenses, canonical_license, d)
+            except oe.license.LicenseError as exc:
+                bb.fatal('%s: %s' % (d.getVar('P'), exc))
 
             if not "IMAGE_MANIFEST" in pkg_dic[pkg]:
                 # Rootfs manifest
diff --git a/meta/classes/multilib.bbclass b/meta/classes/multilib.bbclass
index 1ad654f546d..5859ca8d21e 100644
--- a/meta/classes/multilib.bbclass
+++ b/meta/classes/multilib.bbclass
@@ -75,12 +75,12 @@ python multilib_virtclass_handler () {
     e.data.setVar("PN", variant + "-" + e.data.getVar("PN", False))
     e.data.setVar("OVERRIDES", e.data.getVar("OVERRIDES", False) + override)
 
-    # Expand WHITELIST_GPL-3.0 with multilib prefix
-    pkgs = e.data.getVar("WHITELIST_GPL-3.0")
+    # Expand INCOMPATIBLE_LICENSE_EXCEPTIONS with multilib prefix
+    pkgs = e.data.getVar("INCOMPATIBLE_LICENSE_EXCEPTIONS")
     if pkgs:
         for pkg in pkgs.split():
             pkgs += " " + variant + "-" + pkg
-        e.data.setVar("WHITELIST_GPL-3.0", pkgs)
+        e.data.setVar("INCOMPATIBLE_LICENSE_EXCEPTIONS", pkgs)
 
     # DEFAULTTUNE can change TARGET_ARCH override so expand this now before update_data
     newtune = e.data.getVar("DEFAULTTUNE:" + "virtclass-multilib-" + variant, False)
diff --git a/meta/conf/bitbake.conf b/meta/conf/bitbake.conf
index 6fb7bfeb23c..7705415a4f5 100644
--- a/meta/conf/bitbake.conf
+++ b/meta/conf/bitbake.conf
@@ -110,6 +110,17 @@ BB_RENAMED_VARIABLES[INHERIT_BLACKLIST] = "is a deprecated variable and no longe
 BB_RENAMED_VARIABLES[TUNEABI_WHITELIST] = "is a deprecated variable and support has been removed"
 BB_RENAMED_VARIABLES[LICENSE_FLAGS_WHITELIST] = "LICENSE_FLAGS_ACCEPTED"
 
+BB_RENAMED_VARIABLES[WHITELIST_GPL-3.0-only] = "INCOMPATIBLE_LICENSE_EXCEPTIONS"
+BB_RENAMED_VARIABLES[WHITELIST_GPL-3.0-or-later] = "INCOMPATIBLE_LICENSE_EXCEPTIONS"
+BB_RENAMED_VARIABLES[WHITELIST_LGPL-3.0-only] = "INCOMPATIBLE_LICENSE_EXCEPTIONS"
+BB_RENAMED_VARIABLES[WHITELIST_LGPL-3.0-or-later] = "INCOMPATIBLE_LICENSE_EXCEPTIONS"
+
+# These are deprecated version and should be updated to approved names
+BB_RENAMED_VARIABLES[WHITELIST_GPL-3.0] = "is deprecated, convert to INCOMPATIBLE_LICENSE_EXCEPTIONS = '<pkg>:GPL-3.0-only'"
+BB_RENAMED_VARIABLES[WHITELIST_GPL-3.0+] = "is deprecated, convert to INCOMPATIBLE_LICENSE_EXCEPTIONS = '<pkg>:GPL-3.0-or-later'"
+BB_RENAMED_VARIABLES[WHITELIST_LGPL-3.0] = "is deprecated, convert to INCOMPATIBLE_LICENSE_EXCEPTIONS = '<pkg>:LGPL-3.0-only'"
+BB_RENAMED_VARIABLES[WHITELIST_LGPL-3.0+] = "is deprecated, convert to INCOMPATIBLE_LICENSE_EXCEPTIONS = '<pkg>:LGPL-3.0-or-later'"
+
 ##################################################################
 # Architecture-dependent build variables.
 ##################################################################
diff --git a/meta/lib/oe/license.py b/meta/lib/oe/license.py
index 8955cbdeb24..29412dfe46b 100644
--- a/meta/lib/oe/license.py
+++ b/meta/lib/oe/license.py
@@ -242,3 +242,8 @@ def list_licenses(licensestr):
     except SyntaxError as exc:
         raise LicenseSyntaxError(licensestr, exc)
     return visitor.licenses
+
+def apply_pkg_license_exception(pkg, bad_licenses, exceptions):
+    """Return remaining bad licenses after removing any package exceptions"""
+
+    return [lic for lic in bad_licenses if pkg + ':' + lic not in exceptions]
diff --git a/meta/lib/oeqa/selftest/cases/incompatible_lic.py b/meta/lib/oeqa/selftest/cases/incompatible_lic.py
index fd3b3f409e3..c68f920555f 100644
--- a/meta/lib/oeqa/selftest/cases/incompatible_lic.py
+++ b/meta/lib/oeqa/selftest/cases/incompatible_lic.py
@@ -110,8 +110,8 @@ INCOMPATIBLE_LICENSE:pn-core-image-minimal = "GPL-3.0 LGPL-3.0"
 
         bitbake('core-image-minimal')
 
-    def test_bash_whitelist(self):
-        self.write_config(self.default_config() + '\nWHITELIST_GPL-3.0:pn-core-image-minimal = "bash"')
+    def test_bash_license_exceptions(self):
+        self.write_config(self.default_config() + '\nINCOMPATIBLE_LICENSE_EXCEPTIONS:pn-core-image-minimal = "bash:GPL-3.0-or-later"')
 
         bitbake('core-image-minimal')
 
-- 
2.32.0



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/4] license/insane: Show warning for obsolete license usage
  2022-03-01 23:42 [PATCH 1/4] mutlilib: Handle WHITELIST_GPL-3.0 being unset Richard Purdie
  2022-03-01 23:42 ` [PATCH 2/4] base/license: Rework INCOMPATIBLE_LICENSE variable handling Richard Purdie
@ 2022-03-01 23:42 ` Richard Purdie
  2022-03-02 15:17   ` [OE-core] " Peter Kjellerstedt
  2022-03-01 23:42 ` [PATCH 4/4] license: Rework INCOMPATIBLE_LICENSE wildcard handling Richard Purdie
  2 siblings, 1 reply; 8+ messages in thread
From: Richard Purdie @ 2022-03-01 23:42 UTC (permalink / raw)
  To: openembedded-core

We want to use SPDX identifiers in LICENSE variables. There is now a
conversion script to make most of the translations. Add a list of
strings which have been replaced so we can show warnings to users
if they're still used anywhere.

Add checks to the package as insane check. This is currently a warning
by default but can be turned off or made an error as per the other standard
checks.

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
---
 meta/classes/base.bbclass   |  6 ++++++
 meta/classes/insane.bbclass | 31 ++++++++++++++++++++++---------
 meta/lib/oe/license.py      | 10 ++++++++++
 3 files changed, 38 insertions(+), 9 deletions(-)

diff --git a/meta/classes/base.bbclass b/meta/classes/base.bbclass
index bfc7087a189..b7869da3b38 100644
--- a/meta/classes/base.bbclass
+++ b/meta/classes/base.bbclass
@@ -597,6 +597,12 @@ python () {
 
             exceptions = (d.getVar("INCOMPATIBLE_LICENSE_EXCEPTIONS") or "").split()
 
+            for lic_exception in exceptions:
+                if ":" in lic_exception:
+                    lic_exception.split(":")[0]
+                if lic_exception in oe.license.obsolete_license_list():
+                    bb.fatal("Invalid license %s used in INCOMPATIBLE_LICENSE_EXCEPTIONS" % lic_exception)
+
             pkgs = d.getVar('PACKAGES').split()
             skipped_pkgs = {}
             unskipped_pkgs = []
diff --git a/meta/classes/insane.bbclass b/meta/classes/insane.bbclass
index 29b9b3d466a..3c8d49f13bd 100644
--- a/meta/classes/insane.bbclass
+++ b/meta/classes/insane.bbclass
@@ -27,7 +27,7 @@ WARN_QA ?= " libdir xorg-driver-abi \
             mime mime-xdg unlisted-pkg-lics unhandled-features-check \
             missing-update-alternatives native-last missing-ptest \
             license-exists license-no-generic license-syntax license-format \
-            license-incompatible license-file-missing \
+            license-incompatible license-file-missing obsolete-license \
             "
 ERROR_QA ?= "dev-so debug-deps dev-deps debug-files arch pkgconfig la \
             perms dep-cmp pkgvarcheck perm-config perm-line perm-link \
@@ -909,14 +909,19 @@ def package_qa_check_unlisted_pkg_lics(package, d, messages):
         return True
 
     recipe_lics_set = oe.license.list_licenses(d.getVar('LICENSE'))
-    unlisted = oe.license.list_licenses(pkg_lics) - recipe_lics_set
-    if not unlisted:
-        return True
-
-    oe.qa.add_message(messages, "unlisted-pkg-lics",
-                           "LICENSE:%s includes licenses (%s) that are not "
-                           "listed in LICENSE" % (package, ' '.join(unlisted)))
-    return False
+    package_lics = oe.license.list_licenses(pkg_lics)
+    unlisted = package_lics - recipe_lics_set
+    if unlisted:
+        oe.qa.add_message(messages, "unlisted-pkg-lics",
+                               "LICENSE:%s includes licenses (%s) that are not "
+                               "listed in LICENSE" % (package, ' '.join(unlisted)))
+        return False
+    obsolete = set(oe.license.obsolete_license_list()) & package_lics - recipe_lics_set
+    if obsolete:
+        oe.qa.add_message(messages, "obsolete-license",
+                               "LICENSE:%s includes obsolete licenses %s" % (package, ' '.join(obsolete)))
+        return False
+    return True
 
 QAPKGTEST[empty-dirs] = "package_qa_check_empty_dirs"
 def package_qa_check_empty_dirs(pkg, d, messages):
@@ -1012,6 +1017,14 @@ python do_package_qa () {
 
     bb.note("DO PACKAGE QA")
 
+    main_lic = d.getVar('LICENSE')
+
+    # Check for obsolete license references in main LICENSE (packages are checked below for any changes)
+    main_licenses = oe.license.list_licenses(d.getVar('LICENSE'))
+    obsolete = set(oe.license.obsolete_license_list()) & main_licenses
+    if obsolete:
+        oe.qa.handle_error("obsolete-license", "Recipe LICENSE includes obsolete licenses %s" % ' '.join(obsolete), d)
+
     bb.build.exec_func("read_subpackage_metadata", d)
 
     # Check non UTF-8 characters on recipe's metadata
diff --git a/meta/lib/oe/license.py b/meta/lib/oe/license.py
index 29412dfe46b..99cfa5f7339 100644
--- a/meta/lib/oe/license.py
+++ b/meta/lib/oe/license.py
@@ -14,6 +14,16 @@ def license_ok(license, dont_want_licenses):
             return False
     return True
 
+def obsolete_license_list():
+    return ["AGPL-3", "AGPL-3+", "AGPLv3", "AGPLv3+", "AGPLv3.0", "AGPLv3.0+", "AGPL-3.0", "AGPL-3.0+", "BSD-0-Clause",
+            "GPL-1", "GPL-1+", "GPLv1", "GPLv1+", "GPLv1.0", "GPLv1.0+", "GPL-1.0", "GPL-1.0+", "GPL-2", "GPL-2+", "GPLv2",
+            "GPLv2+", "GPLv2.0", "GPLv2.0+", "GPL-2.0", "GPL-2.0+", "GPL-3", "GPL-3+", "GPLv3", "GPLv3+", "GPLv3.0", "GPLv3.0+",
+            "GPL-3.0", "GPL-3.0+", "LGPLv2", "LGPLv2+", "LGPLv2.0", "LGPLv2.0+", "LGPL-2.0", "LGPL-2.0+", "LGPL2.1", "LGPL2.1+",
+            "LGPLv2.1", "LGPLv2.1+", "LGPL-2.1", "LGPL-2.1+", "LGPLv3", "LGPLv3+", "LGPL-3.0", "LGPL-3.0+", "MPL-1", "MPLv1",
+            "MPLv1.1", "MPLv2", "MIT-X", "MIT-style", "openssl", "PSF", "PSFv2", "Python-2", "Apachev2", "Apache-2", "Artisticv1",
+            "Artistic-1", "AFL-2", "AFL-1", "AFLv2", "AFLv1", "CDDLv1", "CDDL-1", "EPLv1.0", "FreeType", "Nauman",
+            "tcl", "vim", "SGIv1"]
+
 class LicenseError(Exception):
     pass
 
-- 
2.32.0



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 4/4] license: Rework INCOMPATIBLE_LICENSE wildcard handling
  2022-03-01 23:42 [PATCH 1/4] mutlilib: Handle WHITELIST_GPL-3.0 being unset Richard Purdie
  2022-03-01 23:42 ` [PATCH 2/4] base/license: Rework INCOMPATIBLE_LICENSE variable handling Richard Purdie
  2022-03-01 23:42 ` [PATCH 3/4] license/insane: Show warning for obsolete license usage Richard Purdie
@ 2022-03-01 23:42 ` Richard Purdie
  2022-03-02 15:09   ` [OE-core] " Peter Kjellerstedt
  2 siblings, 1 reply; 8+ messages in thread
From: Richard Purdie @ 2022-03-01 23:42 UTC (permalink / raw)
  To: openembedded-core

The current wildcard handling is badly documented and inconsistently
used and understood.

Forcing users to have to use "GPL-3.0-only GPL-3.0-or-later" whilst
explict is not very user friendly. Equally, using the current wildcards
is ambigious. This supports pre-defined expansions only and at least makes
it clear what GPL-3.0* means (it doesn't include the exception licenses).

This is hopefully an acceptable compromise between literal meaning and
having something usable.

Non-SPDX forms of license in this field have been dropped and errors are
shown for unsupported expansions and unsupported old style license terms.

Users need to carefully consider how to migrate to the new syntax but
the meaning should be well defined and clear from here forward.

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
---
 meta/classes/license.bbclass                  | 41 +++++----
 .../oeqa/selftest/cases/incompatible_lic.py   | 86 +++++++++++--------
 2 files changed, 70 insertions(+), 57 deletions(-)

diff --git a/meta/classes/license.bbclass b/meta/classes/license.bbclass
index 68c022248c8..cb1f46983ac 100644
--- a/meta/classes/license.bbclass
+++ b/meta/classes/license.bbclass
@@ -277,28 +277,27 @@ AVAILABLE_LICENSES := "${@' '.join(available_licenses(d))}"
 
 def expand_wildcard_licenses(d, wildcard_licenses):
     """
-    Return actual spdx format license names if wildcards are used. We expand
-    wildcards from SPDXLICENSEMAP flags and AVAILABLE_LICENSES.
+    There are some common wildcard values users may want to use. Support them
+    here.
     """
-    import fnmatch
-
-    licenses = wildcard_licenses[:]
-    spdxmapkeys = d.getVarFlags('SPDXLICENSEMAP').keys()
-    for wld_lic in wildcard_licenses:
-        spdxflags = fnmatch.filter(spdxmapkeys, wld_lic)
-        licenses += [d.getVarFlag('SPDXLICENSEMAP', flag) for flag in spdxflags]
-        # Assume that if we are passed "GPL-3.0" or "*GPL-3.0", then it means
-        # "-or-later" as well.
-        if not wld_lic.endswith(("-or-later", "-only", "*", "+")):
-            spdxflags = fnmatch.filter(spdxmapkeys, wld_lic + "+")
-            licenses += [d.getVarFlag('SPDXLICENSEMAP', flag) for flag in spdxflags]
-
-    spdx_lics = d.getVar('AVAILABLE_LICENSES').split()
-    for wld_lic in wildcard_licenses:
-        licenses += fnmatch.filter(spdx_lics, wld_lic)
-
-    licenses = list(set(licenses))
-    return licenses
+    licenses = set(wildcard_licenses)
+    mapping = {
+        "GPL-3.0*" : ["GPL-3.0-only", "GPL-3.0-or-later"],
+        "LGPL-3.0*" : ["LGPL-3.0-only", "LGPL-3.0-or-later"],
+    }
+    for k in mapping:
+        if k in wildcard_licenses:
+            licenses.remove(k)
+            for item in mapping[k]:
+                licenses.add(item)
+
+    for l in licenses:
+        if l in oe.license.obsolete_license_list():
+            bb.fatal("Error, %s is an obsolete license, please use an SPDX reference in INCOMPATIBLE_LICENSE" % l)
+        if "*" in l:
+            bb.fatal("Error, %s is an invalid license wildcard entry" % l)
+
+    return list(licenses)
 
 def incompatible_license_contains(license, truevalue, falsevalue, d):
     license = canonical_license(d, license)
diff --git a/meta/lib/oeqa/selftest/cases/incompatible_lic.py b/meta/lib/oeqa/selftest/cases/incompatible_lic.py
index c68f920555f..0794d46e6dd 100644
--- a/meta/lib/oeqa/selftest/cases/incompatible_lic.py
+++ b/meta/lib/oeqa/selftest/cases/incompatible_lic.py
@@ -1,10 +1,11 @@
 from oeqa.selftest.case import OESelftestTestCase
 from oeqa.utils.commands import bitbake
 
-class IncompatibleLicenseTests(OESelftestTestCase):
+class IncompatibleLicenseTestObsolete(OESelftestTestCase):
 
-    def lic_test(self, pn, pn_lic, lic):
-        error_msg = 'ERROR: Nothing PROVIDES \'%s\'\n%s was skipped: it has incompatible license(s): %s' % (pn, pn, pn_lic)
+    def lic_test(self, pn, pn_lic, lic, error_msg=None):
+        if not error_msg:
+            error_msg = 'ERROR: Nothing PROVIDES \'%s\'\n%s was skipped: it has incompatible license(s): %s' % (pn, pn, pn_lic)
 
         self.write_config("INCOMPATIBLE_LICENSE += \"%s\"" % (lic))
 
@@ -12,69 +13,82 @@ class IncompatibleLicenseTests(OESelftestTestCase):
         if error_msg not in result.output:
             raise AssertionError(result.output)
 
-    # Verify that a package with an SPDX license (from AVAILABLE_LICENSES)
-    # cannot be built when INCOMPATIBLE_LICENSE contains this SPDX license
-    def test_incompatible_spdx_license(self):
-        self.lic_test('incompatible-license', 'GPL-3.0-only', 'GPL-3.0-only')
-
     # Verify that a package with an SPDX license (from AVAILABLE_LICENSES)
     # cannot be built when INCOMPATIBLE_LICENSE contains an alias (in
     # SPDXLICENSEMAP) of this SPDX license
     def test_incompatible_alias_spdx_license(self):
-        self.lic_test('incompatible-license', 'GPL-3.0-only', 'GPLv3')
-
-    # Verify that a package with an SPDX license (from AVAILABLE_LICENSES)
-    # cannot be built when INCOMPATIBLE_LICENSE contains a wildcarded license
-    # matching this SPDX license
-    def test_incompatible_spdx_license_wildcard(self):
-        self.lic_test('incompatible-license', 'GPL-3.0-only', '*GPL-3.0-only')
+        self.lic_test('incompatible-license', 'GPL-3.0-only', 'GPLv3', "is an obsolete license, please use an SPDX reference in INCOMPATIBLE_LICENSE")
 
     # Verify that a package with an SPDX license (from AVAILABLE_LICENSES)
     # cannot be built when INCOMPATIBLE_LICENSE contains a wildcarded alias
     # license matching this SPDX license
     def test_incompatible_alias_spdx_license_wildcard(self):
-        self.lic_test('incompatible-license', 'GPL-3.0-only', '*GPLv3')
-
-    # Verify that a package with an alias (from SPDXLICENSEMAP) to an SPDX
-    # license cannot be built when INCOMPATIBLE_LICENSE contains this SPDX
-    # license
-    def test_incompatible_spdx_license_alias(self):
-        self.lic_test('incompatible-license-alias', 'GPL-3.0-only', 'GPL-3.0-only')
+        self.lic_test('incompatible-license', 'GPL-3.0-only', '*GPLv3', "*GPLv3 is an invalid license wildcard entry")
 
     # Verify that a package with an alias (from SPDXLICENSEMAP) to an SPDX
     # license cannot be built when INCOMPATIBLE_LICENSE contains this alias
     def test_incompatible_alias_spdx_license_alias(self):
-        self.lic_test('incompatible-license-alias', 'GPL-3.0-only', 'GPLv3')
+        self.lic_test('incompatible-license-alias', 'GPL-3.0-only', 'GPLv3', "is an obsolete license, please use an SPDX reference in INCOMPATIBLE_LICENSE")
 
     # Verify that a package with an alias (from SPDXLICENSEMAP) to an SPDX
     # license cannot be built when INCOMPATIBLE_LICENSE contains a wildcarded
     # license matching this SPDX license
     def test_incompatible_spdx_license_alias_wildcard(self):
-        self.lic_test('incompatible-license-alias', 'GPL-3.0-only', '*GPL-3.0')
+        self.lic_test('incompatible-license-alias', 'GPL-3.0-only', '*GPL-3.0', "*GPL-3.0 is an invalid license wildcard entry")
 
     # Verify that a package with an alias (from SPDXLICENSEMAP) to an SPDX
     # license cannot be built when INCOMPATIBLE_LICENSE contains a wildcarded
     # alias license matching the SPDX license
     def test_incompatible_alias_spdx_license_alias_wildcard(self):
-        self.lic_test('incompatible-license-alias', 'GPL-3.0-only', '*GPLv3')
+        self.lic_test('incompatible-license-alias', 'GPL-3.0-only', '*GPLv3', "*GPLv3 is an invalid license wildcard entry")
 
-    # Verify that a package with multiple SPDX licenses (from
-    # AVAILABLE_LICENSES) cannot be built when INCOMPATIBLE_LICENSE contains
-    # some of them
-    def test_incompatible_spdx_licenses(self):
-        self.lic_test('incompatible-licenses', 'GPL-3.0-only LGPL-3.0-only', 'GPL-3.0-only LGPL-3.0-only')
 
     # Verify that a package with multiple SPDX licenses (from
     # AVAILABLE_LICENSES) cannot be built when INCOMPATIBLE_LICENSE contains a
     # wildcard to some of them
     def test_incompatible_spdx_licenses_wildcard(self):
-        self.lic_test('incompatible-licenses', 'GPL-3.0-only LGPL-3.0-only', '*GPL-3.0-only')
+        self.lic_test('incompatible-licenses', 'GPL-3.0-only LGPL-3.0-only', '*GPL-3.0-only', "*GPL-3.0-only is an invalid license wildcard entry")
+
 
     # Verify that a package with multiple SPDX licenses (from
     # AVAILABLE_LICENSES) cannot be built when INCOMPATIBLE_LICENSE contains a
     # wildcard matching all licenses
     def test_incompatible_all_licenses_wildcard(self):
-        self.lic_test('incompatible-licenses', 'GPL-2.0-only GPL-3.0-only LGPL-3.0-only', '*')
+        self.lic_test('incompatible-licenses', 'GPL-2.0-only GPL-3.0-only LGPL-3.0-only', '*', "* is an invalid license wildcard entry")
+
+class IncompatibleLicenseTests(OESelftestTestCase):
+
+    def lic_test(self, pn, pn_lic, lic):
+        error_msg = 'ERROR: Nothing PROVIDES \'%s\'\n%s was skipped: it has incompatible license(s): %s' % (pn, pn, pn_lic)
+
+        self.write_config("INCOMPATIBLE_LICENSE += \"%s\"" % (lic))
+
+        result = bitbake('%s --dry-run' % (pn), ignore_status=True)
+        if error_msg not in result.output:
+            raise AssertionError(result.output)
+
+    # Verify that a package with an SPDX license (from AVAILABLE_LICENSES)
+    # cannot be built when INCOMPATIBLE_LICENSE contains this SPDX license
+    def test_incompatible_spdx_license(self):
+        self.lic_test('incompatible-license', 'GPL-3.0-only', 'GPL-3.0-only')
+
+    # Verify that a package with an SPDX license (from AVAILABLE_LICENSES)
+    # cannot be built when INCOMPATIBLE_LICENSE contains a wildcarded license
+    # matching this SPDX license
+    def test_incompatible_spdx_license_wildcard(self):
+        self.lic_test('incompatible-license', 'GPL-3.0-only', 'GPL-3.0*')
+
+    # Verify that a package with an alias (from SPDXLICENSEMAP) to an SPDX
+    # license cannot be built when INCOMPATIBLE_LICENSE contains this SPDX
+    # license
+    def test_incompatible_spdx_license_alias(self):
+        self.lic_test('incompatible-license-alias', 'GPL-3.0-only', 'GPL-3.0-only')
+
+    # Verify that a package with multiple SPDX licenses (from
+    # AVAILABLE_LICENSES) cannot be built when INCOMPATIBLE_LICENSE contains
+    # some of them
+    def test_incompatible_spdx_licenses(self):
+        self.lic_test('incompatible-licenses', 'GPL-3.0-only LGPL-3.0-only', 'GPL-3.0-only LGPL-3.0-only')
 
     # Verify that a package with a non-SPDX license (neither in
     # AVAILABLE_LICENSES nor in SPDXLICENSEMAP) cannot be built when
@@ -86,7 +100,7 @@ class IncompatibleLicensePerImageTests(OESelftestTestCase):
     def default_config(self):
         return """
 IMAGE_INSTALL:append = " bash"
-INCOMPATIBLE_LICENSE:pn-core-image-minimal = "GPL-3.0 LGPL-3.0"
+INCOMPATIBLE_LICENSE:pn-core-image-minimal = "GPL-3.0* LGPL-3.0*"
 """
 
     def test_bash_default(self):
@@ -118,15 +132,15 @@ INCOMPATIBLE_LICENSE:pn-core-image-minimal = "GPL-3.0 LGPL-3.0"
 class NoGPL3InImagesTests(OESelftestTestCase):
     def test_core_image_minimal(self):
         self.write_config("""
-INCOMPATIBLE_LICENSE:pn-core-image-minimal = "GPL-3.0 LGPL-3.0"
+INCOMPATIBLE_LICENSE:pn-core-image-minimal = "GPL-3.0* LGPL-3.0*"
 """)
         bitbake('core-image-minimal')
 
     def test_core_image_full_cmdline_weston(self):
         self.write_config("""
 INHERIT += "testimage"
-INCOMPATIBLE_LICENSE:pn-core-image-full-cmdline = "GPL-3.0 LGPL-3.0"
-INCOMPATIBLE_LICENSE:pn-core-image-weston = "GPL-3.0 LGPL-3.0"
+INCOMPATIBLE_LICENSE:pn-core-image-full-cmdline = "GPL-3.0* LGPL-3.0*"
+INCOMPATIBLE_LICENSE:pn-core-image-weston = "GPL-3.0* LGPL-3.0*"
 # Settings for full-cmdline
 RDEPENDS:packagegroup-core-full-cmdline-utils:remove = "bash bc coreutils cpio ed findutils gawk grep mc mc-fish mc-helpers mc-helpers-perl sed tar time"
 RDEPENDS:packagegroup-core-full-cmdline-dev-utils:remove = "diffutils m4 make patch"
-- 
2.32.0



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* RE: [OE-core] [PATCH 4/4] license: Rework INCOMPATIBLE_LICENSE wildcard handling
  2022-03-01 23:42 ` [PATCH 4/4] license: Rework INCOMPATIBLE_LICENSE wildcard handling Richard Purdie
@ 2022-03-02 15:09   ` Peter Kjellerstedt
  2022-03-02 15:34     ` Richard Purdie
  0 siblings, 1 reply; 8+ messages in thread
From: Peter Kjellerstedt @ 2022-03-02 15:09 UTC (permalink / raw)
  To: Richard Purdie, openembedded-core

> -----Original Message-----
> From: openembedded-core@lists.openembedded.org <openembedded-
> core@lists.openembedded.org> On Behalf Of Richard Purdie
> Sent: den 2 mars 2022 00:42
> To: openembedded-core@lists.openembedded.org
> Subject: [OE-core] [PATCH 4/4] license: Rework INCOMPATIBLE_LICENSE
> wildcard handling
> 
> The current wildcard handling is badly documented and inconsistently
> used and understood.
> 
> Forcing users to have to use "GPL-3.0-only GPL-3.0-or-later" whilst
> explict is not very user friendly. Equally, using the current wildcards
> is ambigious. This supports pre-defined expansions only and at least makes
> it clear what GPL-3.0* means (it doesn't include the exception licenses).
> 
> This is hopefully an acceptable compromise between literal meaning and
> having something usable.
> 
> Non-SPDX forms of license in this field have been dropped and errors are
> shown for unsupported expansions and unsupported old style license terms.
> 
> Users need to carefully consider how to migrate to the new syntax but
> the meaning should be well defined and clear from here forward.
> 
> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
> ---
>  meta/classes/license.bbclass                  | 41 +++++----
>  .../oeqa/selftest/cases/incompatible_lic.py   | 86 +++++++++++--------
>  2 files changed, 70 insertions(+), 57 deletions(-)
> 
> diff --git a/meta/classes/license.bbclass b/meta/classes/license.bbclass
> index 68c022248c8..cb1f46983ac 100644
> --- a/meta/classes/license.bbclass
> +++ b/meta/classes/license.bbclass
> @@ -277,28 +277,27 @@ AVAILABLE_LICENSES := "${@' '.join(available_licenses(d))}"
> 
>  def expand_wildcard_licenses(d, wildcard_licenses):
>      """
> -    Return actual spdx format license names if wildcards are used. We expand
> -    wildcards from SPDXLICENSEMAP flags and AVAILABLE_LICENSES.
> +    There are some common wildcard values users may want to use. Support them
> +    here.
>      """
> -    import fnmatch
> -
> -    licenses = wildcard_licenses[:]
> -    spdxmapkeys = d.getVarFlags('SPDXLICENSEMAP').keys()
> -    for wld_lic in wildcard_licenses:
> -        spdxflags = fnmatch.filter(spdxmapkeys, wld_lic)
> -        licenses += [d.getVarFlag('SPDXLICENSEMAP', flag) for flag in spdxflags]
> -        # Assume that if we are passed "GPL-3.0" or "*GPL-3.0", then it means
> -        # "-or-later" as well.
> -        if not wld_lic.endswith(("-or-later", "-only", "*", "+")):
> -            spdxflags = fnmatch.filter(spdxmapkeys, wld_lic + "+")
> -            licenses += [d.getVarFlag('SPDXLICENSEMAP', flag) for flag in spdxflags]
> -
> -    spdx_lics = d.getVar('AVAILABLE_LICENSES').split()
> -    for wld_lic in wildcard_licenses:
> -        licenses += fnmatch.filter(spdx_lics, wld_lic)
> -
> -    licenses = list(set(licenses))
> -    return licenses
> +    licenses = set(wildcard_licenses)
> +    mapping = {
> +        "GPL-3.0*" : ["GPL-3.0-only", "GPL-3.0-or-later"],
> +        "LGPL-3.0*" : ["LGPL-3.0-only", "LGPL-3.0-or-later"],

If you are adamant about using "*" in these shortcuts (which I 
still think is a mistake), then you should add these two as well:

        "AGPL-3.0*" : ["AGPL-3.0-only", "AGPL-3.0-or-later"],
        "*GPL-3.0*" : ["GPL-3.0-only", "GPL-3.0-or-later", "LGPL-3.0-only", "LGPL-3.0-or-later", "AGPL-3.0-only", "AGPL-3.0-or-later"],

I believe the last one is what most really want to do, i.e., 
exclude all GPL-3.0 variants.

//Peter


^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: [OE-core] [PATCH 3/4] license/insane: Show warning for obsolete license usage
  2022-03-01 23:42 ` [PATCH 3/4] license/insane: Show warning for obsolete license usage Richard Purdie
@ 2022-03-02 15:17   ` Peter Kjellerstedt
  2022-03-02 15:19     ` Richard Purdie
  0 siblings, 1 reply; 8+ messages in thread
From: Peter Kjellerstedt @ 2022-03-02 15:17 UTC (permalink / raw)
  To: Richard Purdie, openembedded-core

> -----Original Message-----
> From: openembedded-core@lists.openembedded.org <openembedded-core@lists.openembedded.org> On Behalf Of Richard Purdie
> Sent: den 2 mars 2022 00:42
> To: openembedded-core@lists.openembedded.org
> Subject: [OE-core] [PATCH 3/4] license/insane: Show warning for obsolete license usage
> 
> We want to use SPDX identifiers in LICENSE variables. There is now a
> conversion script to make most of the translations. Add a list of
> strings which have been replaced so we can show warnings to users
> if they're still used anywhere.
> 
> Add checks to the package as insane check. This is currently a warning
> by default but can be turned off or made an error as per the other standard
> checks.
> 
> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
> ---
>  meta/classes/base.bbclass   |  6 ++++++
>  meta/classes/insane.bbclass | 31 ++++++++++++++++++++++---------
>  meta/lib/oe/license.py      | 10 ++++++++++
>  3 files changed, 38 insertions(+), 9 deletions(-)
> 
> diff --git a/meta/classes/base.bbclass b/meta/classes/base.bbclass
> index bfc7087a189..b7869da3b38 100644
> --- a/meta/classes/base.bbclass
> +++ b/meta/classes/base.bbclass
> @@ -597,6 +597,12 @@ python () {
> 
>              exceptions = (d.getVar("INCOMPATIBLE_LICENSE_EXCEPTIONS") or "").split()
> 
> +            for lic_exception in exceptions:
> +                if ":" in lic_exception:
> +                    lic_exception.split(":")[0]
> +                if lic_exception in oe.license.obsolete_license_list():
> +                    bb.fatal("Invalid license %s used in INCOMPATIBLE_LICENSE_EXCEPTIONS" % lic_exception)
> +
>              pkgs = d.getVar('PACKAGES').split()
>              skipped_pkgs = {}
>              unskipped_pkgs = []
> diff --git a/meta/classes/insane.bbclass b/meta/classes/insane.bbclass
> index 29b9b3d466a..3c8d49f13bd 100644
> --- a/meta/classes/insane.bbclass
> +++ b/meta/classes/insane.bbclass
> @@ -27,7 +27,7 @@ WARN_QA ?= " libdir xorg-driver-abi \
>              mime mime-xdg unlisted-pkg-lics unhandled-features-check \
>              missing-update-alternatives native-last missing-ptest \
>              license-exists license-no-generic license-syntax license-format \
> -            license-incompatible license-file-missing \
> +            license-incompatible license-file-missing obsolete-license \
>              "
>  ERROR_QA ?= "dev-so debug-deps dev-deps debug-files arch pkgconfig la \
>              perms dep-cmp pkgvarcheck perm-config perm-line perm-link \
> @@ -909,14 +909,19 @@ def package_qa_check_unlisted_pkg_lics(package, d, messages):
>          return True
> 
>      recipe_lics_set = oe.license.list_licenses(d.getVar('LICENSE'))
> -    unlisted = oe.license.list_licenses(pkg_lics) - recipe_lics_set
> -    if not unlisted:
> -        return True
> -
> -    oe.qa.add_message(messages, "unlisted-pkg-lics",
> -                           "LICENSE:%s includes licenses (%s) that are not "
> -                           "listed in LICENSE" % (package, ' '.join(unlisted)))
> -    return False
> +    package_lics = oe.license.list_licenses(pkg_lics)
> +    unlisted = package_lics - recipe_lics_set
> +    if unlisted:
> +        oe.qa.add_message(messages, "unlisted-pkg-lics",
> +                               "LICENSE:%s includes licenses (%s) that are not "
> +                               "listed in LICENSE" % (package, ' '.join(unlisted)))
> +        return False
> +    obsolete = set(oe.license.obsolete_license_list()) & package_lics - recipe_lics_set
> +    if obsolete:
> +        oe.qa.add_message(messages, "obsolete-license",
> +                               "LICENSE:%s includes obsolete licenses %s" % (package, ' '.join(obsolete)))
> +        return False
> +    return True
> 
>  QAPKGTEST[empty-dirs] = "package_qa_check_empty_dirs"
>  def package_qa_check_empty_dirs(pkg, d, messages):
> @@ -1012,6 +1017,14 @@ python do_package_qa () {
> 
>      bb.note("DO PACKAGE QA")
> 
> +    main_lic = d.getVar('LICENSE')
> +
> +    # Check for obsolete license references in main LICENSE (packages are checked below for any changes)
> +    main_licenses = oe.license.list_licenses(d.getVar('LICENSE'))

The documentation for oe.license.list_licenses() says that it returns 
a list, but I assume that is not true or the code below would not work...

> +    obsolete = set(oe.license.obsolete_license_list()) & main_licenses
> +    if obsolete:
> +        oe.qa.handle_error("obsolete-license", "Recipe LICENSE includes obsolete licenses %s" % ' '.join(obsolete), d)
> +
>      bb.build.exec_func("read_subpackage_metadata", d)
> 
>      # Check non UTF-8 characters on recipe's metadata

//Peter



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [OE-core] [PATCH 3/4] license/insane: Show warning for obsolete license usage
  2022-03-02 15:17   ` [OE-core] " Peter Kjellerstedt
@ 2022-03-02 15:19     ` Richard Purdie
  0 siblings, 0 replies; 8+ messages in thread
From: Richard Purdie @ 2022-03-02 15:19 UTC (permalink / raw)
  To: Peter Kjellerstedt, openembedded-core

On Wed, 2022-03-02 at 15:17 +0000, Peter Kjellerstedt wrote:
> > +    main_lic = d.getVar('LICENSE')
> > +
> > +    # Check for obsolete license references in main LICENSE (packages are checked below for any changes)
> > +    main_licenses = oe.license.list_licenses(d.getVar('LICENSE'))
> 
> The documentation for oe.license.list_licenses() says that it returns 
> a list, but I assume that is not true or the code below would not work...
> 
> > +    obsolete = set(oe.license.obsolete_license_list()) & main_licenses
> > +    if obsolete:
> > +        oe.qa.handle_error("obsolete-license", "Recipe LICENSE includes obsolete licenses %s" % ' '.join(obsolete), d)
> > +
> >      bb.build.exec_func("read_subpackage_metadata", d)
> > 
> >      # Check non UTF-8 characters on recipe's metadata

It does return a set, not a list.

Cheers,

Richard



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [OE-core] [PATCH 4/4] license: Rework INCOMPATIBLE_LICENSE wildcard handling
  2022-03-02 15:09   ` [OE-core] " Peter Kjellerstedt
@ 2022-03-02 15:34     ` Richard Purdie
  0 siblings, 0 replies; 8+ messages in thread
From: Richard Purdie @ 2022-03-02 15:34 UTC (permalink / raw)
  To: Peter Kjellerstedt, openembedded-core

On Wed, 2022-03-02 at 15:09 +0000, Peter Kjellerstedt wrote:
> > -----Original Message-----
> > From: openembedded-core@lists.openembedded.org <openembedded-
> > core@lists.openembedded.org> On Behalf Of Richard Purdie
> > Sent: den 2 mars 2022 00:42
> > To: openembedded-core@lists.openembedded.org
> > Subject: [OE-core] [PATCH 4/4] license: Rework INCOMPATIBLE_LICENSE
> > wildcard handling
> > 
> > The current wildcard handling is badly documented and inconsistently
> > used and understood.
> > 
> > Forcing users to have to use "GPL-3.0-only GPL-3.0-or-later" whilst
> > explict is not very user friendly. Equally, using the current wildcards
> > is ambigious. This supports pre-defined expansions only and at least makes
> > it clear what GPL-3.0* means (it doesn't include the exception licenses).
> > 
> > This is hopefully an acceptable compromise between literal meaning and
> > having something usable.
> > 
> > Non-SPDX forms of license in this field have been dropped and errors are
> > shown for unsupported expansions and unsupported old style license terms.
> > 
> > Users need to carefully consider how to migrate to the new syntax but
> > the meaning should be well defined and clear from here forward.
> > 
> > Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
> > ---
> >  meta/classes/license.bbclass                  | 41 +++++----
> >  .../oeqa/selftest/cases/incompatible_lic.py   | 86 +++++++++++--------
> >  2 files changed, 70 insertions(+), 57 deletions(-)
> > 
> > diff --git a/meta/classes/license.bbclass b/meta/classes/license.bbclass
> > index 68c022248c8..cb1f46983ac 100644
> > --- a/meta/classes/license.bbclass
> > +++ b/meta/classes/license.bbclass
> > @@ -277,28 +277,27 @@ AVAILABLE_LICENSES := "${@'
> > '.join(available_licenses(d))}"
> > 
> >  def expand_wildcard_licenses(d, wildcard_licenses):
> >      """
> > -    Return actual spdx format license names if wildcards are used. We
> > expand
> > -    wildcards from SPDXLICENSEMAP flags and AVAILABLE_LICENSES.
> > +    There are some common wildcard values users may want to use. Support
> > them
> > +    here.
> >      """
> > -    import fnmatch
> > -
> > -    licenses = wildcard_licenses[:]
> > -    spdxmapkeys = d.getVarFlags('SPDXLICENSEMAP').keys()
> > -    for wld_lic in wildcard_licenses:
> > -        spdxflags = fnmatch.filter(spdxmapkeys, wld_lic)
> > -        licenses += [d.getVarFlag('SPDXLICENSEMAP', flag) for flag in
> > spdxflags]
> > -        # Assume that if we are passed "GPL-3.0" or "*GPL-3.0", then it
> > means
> > -        # "-or-later" as well.
> > -        if not wld_lic.endswith(("-or-later", "-only", "*", "+")):
> > -            spdxflags = fnmatch.filter(spdxmapkeys, wld_lic + "+")
> > -            licenses += [d.getVarFlag('SPDXLICENSEMAP', flag) for flag in
> > spdxflags]
> > -
> > -    spdx_lics = d.getVar('AVAILABLE_LICENSES').split()
> > -    for wld_lic in wildcard_licenses:
> > -        licenses += fnmatch.filter(spdx_lics, wld_lic)
> > -
> > -    licenses = list(set(licenses))
> > -    return licenses
> > +    licenses = set(wildcard_licenses)
> > +    mapping = {
> > +        "GPL-3.0*" : ["GPL-3.0-only", "GPL-3.0-or-later"],
> > +        "LGPL-3.0*" : ["LGPL-3.0-only", "LGPL-3.0-or-later"],
> 
> If you are adamant about using "*" in these shortcuts (which I 
> still think is a mistake), then you should add these two as well:
> 
>         "AGPL-3.0*" : ["AGPL-3.0-only", "AGPL-3.0-or-later"],
>         "*GPL-3.0*" : ["GPL-3.0-only", "GPL-3.0-or-later", "LGPL-3.0-only",
> "LGPL-3.0-or-later", "AGPL-3.0-only", "AGPL-3.0-or-later"],
> 
> I believe the last one is what most really want to do, i.e., 
> exclude all GPL-3.0 variants.

I don't think I've seen anything under the AGPL. I don't have a strong
preference for adding it here or not, I was tempted to wait for patches and see
if anyone needed it.

The idea is the wildcards added should remove the need for the latter as people
can say "GPL-3.0* LGPL-3.0*" which I think is manageable.

Cheers,

Richard




^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2022-03-02 15:34 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-01 23:42 [PATCH 1/4] mutlilib: Handle WHITELIST_GPL-3.0 being unset Richard Purdie
2022-03-01 23:42 ` [PATCH 2/4] base/license: Rework INCOMPATIBLE_LICENSE variable handling Richard Purdie
2022-03-01 23:42 ` [PATCH 3/4] license/insane: Show warning for obsolete license usage Richard Purdie
2022-03-02 15:17   ` [OE-core] " Peter Kjellerstedt
2022-03-02 15:19     ` Richard Purdie
2022-03-01 23:42 ` [PATCH 4/4] license: Rework INCOMPATIBLE_LICENSE wildcard handling Richard Purdie
2022-03-02 15:09   ` [OE-core] " Peter Kjellerstedt
2022-03-02 15:34     ` Richard Purdie

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.