1#!/usr/bin/env python3
2
3import argparse
4import glob
5import pathlib
6
7from importlib.machinery import PathFinder
8from importlib.metadata import DistributionFinder
9
10from installer import install
11from installer._core import _process_WHEEL_file
12from installer.destinations import SchemeDictionaryDestination
13from installer.sources import WheelFile
14
15
16def clean(source, destination):
17    scheme = _process_WHEEL_file(source)
18    scheme_path = destination.scheme_dict[scheme]
19    context = DistributionFinder.Context(
20        name=source.distribution,
21        path=[scheme_path],
22    )
23    for path in PathFinder.find_distributions(context=context):
24        # path.files is either an iterable, or None
25        if path.files is None:
26            continue
27        for file in path.files:
28            file_path = pathlib.Path(file.locate())
29            if file_path.exists():
30                file_path.unlink()
31
32
33def main():
34    """Entry point for CLI."""
35    ap = argparse.ArgumentParser("python pyinstaller.py")
36    ap.add_argument("wheel_file", help="Path to a .whl file to install")
37
38    ap.add_argument(
39        "--interpreter", required=True, help="Interpreter path to be used in scripts"
40    )
41    ap.add_argument(
42        "--script-kind",
43        required=True,
44        choices=["posix", "win-ia32", "win-amd64", "win-arm", "win-arm64"],
45        help="Kind of launcher to create for each script",
46    )
47
48    dest_args = ap.add_argument_group("Destination directories")
49    dest_args.add_argument(
50        "--purelib",
51        required=True,
52        help="Directory for platform-independent Python modules",
53    )
54    dest_args.add_argument(
55        "--platlib",
56        help="Directory for platform-dependent Python modules (same as purelib "
57        "if not specified)",
58    )
59    dest_args.add_argument(
60        "--headers", required=True, help="Directory for C header files"
61    )
62    dest_args.add_argument(
63        "--scripts", required=True, help="Directory for executable scripts"
64    )
65    dest_args.add_argument(
66        "--data", required=True, help="Directory for external data files"
67    )
68    args = ap.parse_args()
69
70    destination = SchemeDictionaryDestination(
71        {
72            "purelib": args.purelib,
73            "platlib": args.platlib if args.platlib is not None else args.purelib,
74            "headers": args.headers,
75            "scripts": args.scripts,
76            "data": args.data,
77        },
78        interpreter=args.interpreter,
79        script_kind=args.script_kind,
80    )
81
82    with WheelFile.open(glob.glob(args.wheel_file)[0]) as source:
83        clean(source, destination)
84        install(
85            source=source,
86            destination=destination,
87            additional_metadata={},
88        )
89
90
91if __name__ == "__main__":
92    main()
93