takluyver / pynsist

Build Windows installers for Python applications
https://pynsist.readthedocs.io/
Other
883 stars 119 forks source link

Read dependencies from wheels #184

Open andreymal opened 4 years ago

andreymal commented 4 years ago

Wheels already have dependencies info in *.dist-info/METADATA. How about parse and download it automatically? Now my pypi_wheels list is monstrously long because pynsist does not download dependencies automatically, and it may break in the future when some dependencies change and I forget to update this list.

albertogomcas commented 1 year ago

I agree that maintaining transitive dependencies is a pain.

As a workaround, I made a small script that at least cuts through several hours of trial & error and leaves to you just fixing the packages without a wheel.

import glob
import os
import shutil
import subprocess

PACKAGE = "mypackage"
wheels_folder = "wheels"

if __name__ == "__main__":
    shutil.rmtree(wheels_folder)
    subprocess.call(f"pip wheel . -w {wheels_folder}") # key line here, make a wheel of your package, use pip to pull deps

    wheels = glob.glob(f"{wheels_folder}/*.whl")

    deps = {}

    with open(f"{wheels_folder}/wheel_list.txt", "wt+") as f:
        for wheel in wheels:
            print(os.path.basename(wheel))
            pkgname, version, *_ = os.path.basename(wheel).split("-")
            if pkgname != PACKAGE:
                f.write(f"{pkgname}=={version}\n")
            else:
                os.remove(wheel)

Out of this you get a folder with all wheels (including transitive deps), which you can just include with local_wheels=wheels/*.whl or alternatively a text file with the listed wheels which you can copy-paste into the pynsist config file (with a little more work you could fill a config template file instead). The only trick I needed is to skip the wheel of the mypackage itself.