add a bbclass to disutils3 that generates a fallback setup.py in case
there is no setup.py available in the source dir, but a setup.cfg.

Use the mapping provided by
https://setuptools.pypa.io/en/latest/userguide/declarative_config.html
to translate the most essential items to legacy setuptools.setup
dictitonary.

Signed-off-by: Konrad Weihmann <kweihm...@outlook.com>
---
 meta/classes/distutils3-legacy.bbclass | 112 +++++++++++++++++++++++++
 meta/classes/distutils3.bbclass        |   1 +
 2 files changed, 113 insertions(+)
 create mode 100644 meta/classes/distutils3-legacy.bbclass

diff --git a/meta/classes/distutils3-legacy.bbclass 
b/meta/classes/distutils3-legacy.bbclass
new file mode 100644
index 0000000000..266d30138f
--- /dev/null
+++ b/meta/classes/distutils3-legacy.bbclass
@@ -0,0 +1,112 @@
+# Helper to create a trimmed down setup.py from information found in
+# setup.cfg, in case there is no setup.py shipped with the sources
+
+# this functionality can be safely removed once the pypa community
+# comes up with a safe replacement for the functionality found in 
distutils3.bbclass
+
+def distutils_legacy_package_name(d):
+    # use pypi name or fall back to BPN
+    return d.getVar("PYPI_PACKAGE") or d.getVar('BPN').replace('python-', 
'').replace('python3-', '')
+
+DISTUTILS_LEGACY_VERSION ?= "${PV}"
+DISTUTILS_LEGACY_NAME ?= "${@distutils_legacy_package_name(d)}"
+
+python do_create_setup_py_legacy() {
+    import os 
+
+    if os.path.exists(os.path.join(d.getVar("DISTUTILS_SETUP_PATH"), 
"setup.py")):
+        return
+
+    from configparser import ConfigParser, NoOptionError, NoSectionError, 
ParsingError
+    import re
+
+    config = ConfigParser()
+    try:
+        config.read(os.path.join(d.getVar("DISTUTILS_SETUP_PATH"), 
"setup.cfg"))
+    except FileNotFoundError:
+        return
+
+    def _strip(x):
+        return re.sub(r"\s|\t|\n", "", x)
+
+    def get_section(section):
+        try:
+            return dict(config.items(section=section))
+        except (NoSectionError, ParsingError):
+            return None
+
+    def get_option(section, option):
+        try:
+            return config.get(section=section, option=option)
+        except (NoOptionError, NoSectionError, ParsingError):
+            return None
+
+    def extract_bool(section, option, default):
+        _option = get_option(section, option)
+        if _option is None:
+            return default
+        return bool(_strip(_option))
+
+    def extract_str(section, option, default):
+        _option = get_option(section, option)
+        if _option is None:
+            return default
+        return _strip(_option)
+
+    def extract_dict_vallist(section, default, delim=""):
+        _section = get_section(section)
+        if _section is None:
+            return default
+        return {_strip(k): [_strip(x) for x in re.split(delim, v)] if delim 
else [ _strip(v) ] for k, v in _section.items()}
+
+    def extract_dict(section, default):
+        _section = get_section(section)
+        if _section is None:
+            return default
+        return {_strip(k): _strip(v) for k, v in _section.items()}
+
+    def extract_list(section, option, default, delim):
+        _option = get_option(section, option)
+        if _option is None:
+            return default
+        bb.warn("%s:%s -> %s" % (section, option, _option))
+        _listitems = re.split(delim, _option) if delim else [_option]
+        return [_strip(x) for x in _listitems]
+
+    def quote(x):
+        return '"%s"' % x
+
+    _pkginfo = {
+        "entry_points": extract_dict_vallist("options.entry_points", {}),
+        "include_package_data": extract_bool("options", 
"include_package_data", False),
+        "name": quote(extract_str("options", "name", 
d.getVar("DISTUTILS_LEGACY_NAME"))),
+        "package_data": extract_dict_vallist("options.package_data", {}, 
r"\s+|,"),
+        "packages": extract_list("options", "packages", [], ""),
+        "version": quote(d.getVar("DISTUTILS_LEGACY_VERSION")),
+        "zip_safe": extract_bool("options", "zip_safe", False),
+        "install_requires": extract_list("options", "install_requires", [], 
r"\t+|\n+"),
+        "python_requires": quote(extract_str("options", "python_requires", 
">0.0")),
+        "package_dir": extract_dict("package_dir", {}),
+        "py_modules": extract_list("options", "py_modules", [], r"\s+|,"),
+    }
+
+    # In case packages is using :find module
+    # we need to look for top level directories containing a __init__.py
+    if _pkginfo["packages"] == ["find:"]:
+        # top level search dir can be adjusted by options.packages.find option
+        _path = extract_str("options.packages.find", "where", "")
+        _pkginfo["packages"] = set(x.name for x in os.scandir(os.path.join(
+            d.getVar("DISTUTILS_SETUP_PATH"), _path)) if os.path.isdir(x) and 
os.path.exists(os.path.join(x, "__init__.py")))
+
+    with open(os.path.join(d.getVar("DISTUTILS_SETUP_PATH"), "setup.py"), "w") 
as o:
+        o.write("import setuptools\n")
+        o.write("setuptools.setup(\n")
+        for k, v in _pkginfo.items():
+            o.write("%s = %s,\n" % (str(k), str(v)))
+        o.write(")")
+
+    
+}
+
+do_create_setup_py_legacy[doc] = "Create a fallback version of legacy setup.py 
if not existing"
+addtask do_create_setup_py_legacy before do_configure after do_patch 
do_prepare_recipe_sysroot
diff --git a/meta/classes/distutils3.bbclass b/meta/classes/distutils3.bbclass
index be645d37bd..f26f0d5184 100644
--- a/meta/classes/distutils3.bbclass
+++ b/meta/classes/distutils3.bbclass
@@ -1,4 +1,5 @@
 inherit distutils3-base
+inherit distutils3-legacy
 
 B = "${WORKDIR}/build"
 distutils_do_configure[cleandirs] = "${B}"
-- 
2.25.1

-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#158741): 
https://lists.openembedded.org/g/openembedded-core/message/158741
Mute This Topic: https://lists.openembedded.org/mt/87289428/21656
Group Owner: openembedded-core+ow...@lists.openembedded.org
Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub 
[arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to