File inkscape-split-extensions-extra.py of Package inkscape

#!/usr/bin/env python3
# List all files, that depend on base_extra_modules, explicitly or implicitly.
import os
import pathlib
import re
import sys

# Search all .py files that are imported by mentioned modules.
def make_deplist(inx_list, module_list):
    modules = set()
    inx_regex = re.compile(rf">(.+)\.py</(dependency|command)>")

    for entry in inx_list:
        with open(os.path.join(".", entry), encoding="utf-8") as file:
            for line in file:
                match = inx_regex.search(line)
                if (match and match.group(1)
                    and match.group(1) not in module_list):
                    modules.add(match.group(1))

    for module in module_list.union(modules):
        name = os.path.join(".", f"{module}.py")
        if os.path.isfile(name):
            with open(name, encoding="utf-8") as file:
                for line in file:
                    match = re.match(r"from (.+) import", line)
                    if not match:
                        match = re.match(r"import ([^#]+).*? *", line)

                    if match and match.group(1):
                        needle = re.sub(r"as .+", "", match.group(1)).strip()

                        if (needle not in module_list.union(modules)
                            and os.path.isfile(f"{needle}.py")):
                            modules.add(needle)

    return modules

if __name__ == "__main__":
    work_dir = pathlib.Path(os.getcwd())
    os.chdir(sys.argv[1])
    prefix = sys.argv[2]

    base_extra_modules = set(["lxml", "numpy", "scour", "xml"])
    extra_modules = set()

    prev_modules = base_extra_modules
    while True:
        prev_module_regex = rf"({'|'.join(map(re.escape, prev_modules))})"
        import_regex = re.compile(rf"(import|from).* {prev_module_regex}")

        next_modules = set()

        # Search all .py files importing one of the mentioned modules.
        for entry in pathlib.Path(".").glob("**/*.py"):
            with entry.open(encoding="utf-8") as file:
                for line in file:
                    if import_regex.search(line):
                        name = str(entry.as_posix())

                        module = name.split(os.sep, 1)[0]
                        if module.endswith(".py"):
                            module = entry.stem
                        if module not in next_modules:
                            next_modules.add(module)

        prev_modules = next_modules
        if extra_modules.issuperset(prev_modules):
            break
        extra_modules.update(prev_modules)


    std_inx = set()
    extra_inx = set()

    # We have a complete list of .py files dependent on base_extra_modules.
    # Now we need a list of .inx module descriptors.
    inx_regex = re.compile(rf'({"|".join(map(re.escape, extra_modules))})\.py')

    for entry in pathlib.Path(".").iterdir():
        if entry.is_file() and entry.suffix == ".inx":
            with entry.open(encoding="utf-8") as file:
                for line in file:
                    if inx_regex.search(line):
                        extra_inx.add(entry.name)

            # inx files that do not belong in extra_inx.
            if entry.name not in extra_inx:
                std_inx.add(entry.name)


    # Now create list of .py files that should belong in the std package.
    std_modules = make_deplist(std_inx, set())

    # Now create list of .py files that are required by extra modules
    # (If no std module needs it, then they will belong in the extra package).
    extradep_modules = make_deplist(extra_inx, extra_modules)


    # And now verify everything and generate final list.
    exclusion_regex = re.compile(r"^(cdr|fig|.*gimp|scribus)")

    std_list = work_dir / "inkscape.lst"
    extra_list = work_dir / "inkscape-extensions-extra.lst"

    with std_list.open("w", encoding="utf-8") as file:
        for inx in std_inx:
            if not exclusion_regex.match(inx):
                print(f"{prefix}{inx}", file=file)
    with extra_list.open("w", encoding="utf-8") as file:
        for inx in extra_inx:
            if not exclusion_regex.match(inx):
                print(f"{prefix}{inx}", file=file)


    with std_list.open("a", encoding="utf-8") as std_file, extra_list.open("a", encoding="utf-8") as extra_file:
        for entry in pathlib.Path(".").iterdir():
            if entry.is_file() and entry.suffix == ".py":
                name = str(entry.as_posix())
                if exclusion_regex.match(name):
                    pass
                elif entry.is_file() and entry.stem in extra_modules:
                    print(f"{prefix}{entry.name}", file=extra_file)
                elif entry.is_file() and entry.stem in std_modules:
                    print(f"{prefix}{entry.name}", file=std_file)
                elif entry.is_file() and entry.stem in extradep_modules:
                    print(f"{prefix}{entry.name}", file=extra_file)
                else:
                    print(f"ERROR: Undecided file {name}", file=sys.stderr)
            elif entry.is_dir():
                if entry.name in extra_modules:
                    print(f"{prefix}{entry.name}/", file=extra_file)
                elif entry.name in std_modules:
                    print(f"{prefix}{entry.name}/", file=std_file)
                elif entry.name in extradep_modules:
                    print(f"{prefix}{entry.name}/", file=extra_file)
openSUSE Build Service is sponsored by