packagelister.packagelister_cli

  1import argparse
  2
  3from pathier import Pathier
  4
  5from packagelister import scan
  6
  7""" These are packages whose name doesn't match their `pip install` name.
  8When `packagelister` is generating a requirements file, these substitutions will be made."""
  9
 10pipmappings = {"speech_recognition": "SpeechRecognition"}
 11
 12
 13def main():
 14    def get_args() -> argparse.Namespace:
 15        parser = argparse.ArgumentParser()
 16
 17        parser.add_argument(
 18            "project_path",
 19            nargs="?",
 20            type=str,
 21            default=None,
 22            help=""" The project directory path to scan. """,
 23        )
 24
 25        parser.add_argument(
 26            "-s",
 27            "--show_files",
 28            action="store_true",
 29            help=""" Show which files imported each of the packages. """,
 30        )
 31
 32        parser.add_argument(
 33            "-g",
 34            "--generate_requirements",
 35            action="store_true",
 36            help=""" Generate a requirements.txt file in --project_path. """,
 37        )
 38
 39        parser.add_argument(
 40            "-v",
 41            "--versions",
 42            type=str,
 43            default=None,
 44            choices=["==", "<", "<=", ">", ">=", "~="],
 45            help=""" When generating a requirements.txt file, include the versions of the packages using this relation.
 46            (You may need to put quotes around some of the options.)""",
 47        )
 48
 49        parser.add_argument(
 50            "-i",
 51            "--include_builtins",
 52            action="store_true",
 53            help=""" Include built in standard library modules. """,
 54        )
 55
 56        args = parser.parse_args()
 57
 58        if not args.project_path:
 59            args.project_path = Pathier.cwd()
 60        else:
 61            args.project_path = Pathier(args.project_path)
 62        if not args.project_path.is_absolute():
 63            args.project_path = args.project_path.absolute()
 64
 65        return args
 66
 67    args = get_args()
 68    packages = scan(args.project_path, args.include_builtins)
 69    if args.generate_requirements:
 70        req_path = args.project_path / "requirements.txt"
 71        requirements = "\n".join(
 72            f"{package}{args.versions}{packages[package]['version']}"
 73            if args.versions
 74            else f"{package}"
 75            if packages[package]["version"]
 76            else package
 77            for package in sorted(packages)
 78        )
 79        for mapping in pipmappings:
 80            requirements = requirements.replace(mapping, pipmappings[mapping])
 81        req_path.write_text(requirements)
 82    packages = {
 83        f"{package}=={packages[package]['version']}": packages[package]["files"]
 84        for package in sorted(packages)
 85    }
 86
 87    if args.show_files:
 88        longest_key = max(len(package) for package in packages)
 89        packages = [
 90            f"{package}{' '*(longest_key-len(package)+4)}{', '.join(str(Pathier(file).relative_to(args.project_path)) for file in packages[package])}"
 91            for package in packages
 92        ]
 93
 94    print(f"Packages used in {args.project_path.stem}:")
 95    print(
 96        *packages,
 97        sep="\n",
 98    )
 99
100
101if __name__ == "__main__":
102    main()
def main():
14def main():
15    def get_args() -> argparse.Namespace:
16        parser = argparse.ArgumentParser()
17
18        parser.add_argument(
19            "project_path",
20            nargs="?",
21            type=str,
22            default=None,
23            help=""" The project directory path to scan. """,
24        )
25
26        parser.add_argument(
27            "-s",
28            "--show_files",
29            action="store_true",
30            help=""" Show which files imported each of the packages. """,
31        )
32
33        parser.add_argument(
34            "-g",
35            "--generate_requirements",
36            action="store_true",
37            help=""" Generate a requirements.txt file in --project_path. """,
38        )
39
40        parser.add_argument(
41            "-v",
42            "--versions",
43            type=str,
44            default=None,
45            choices=["==", "<", "<=", ">", ">=", "~="],
46            help=""" When generating a requirements.txt file, include the versions of the packages using this relation.
47            (You may need to put quotes around some of the options.)""",
48        )
49
50        parser.add_argument(
51            "-i",
52            "--include_builtins",
53            action="store_true",
54            help=""" Include built in standard library modules. """,
55        )
56
57        args = parser.parse_args()
58
59        if not args.project_path:
60            args.project_path = Pathier.cwd()
61        else:
62            args.project_path = Pathier(args.project_path)
63        if not args.project_path.is_absolute():
64            args.project_path = args.project_path.absolute()
65
66        return args
67
68    args = get_args()
69    packages = scan(args.project_path, args.include_builtins)
70    if args.generate_requirements:
71        req_path = args.project_path / "requirements.txt"
72        requirements = "\n".join(
73            f"{package}{args.versions}{packages[package]['version']}"
74            if args.versions
75            else f"{package}"
76            if packages[package]["version"]
77            else package
78            for package in sorted(packages)
79        )
80        for mapping in pipmappings:
81            requirements = requirements.replace(mapping, pipmappings[mapping])
82        req_path.write_text(requirements)
83    packages = {
84        f"{package}=={packages[package]['version']}": packages[package]["files"]
85        for package in sorted(packages)
86    }
87
88    if args.show_files:
89        longest_key = max(len(package) for package in packages)
90        packages = [
91            f"{package}{' '*(longest_key-len(package)+4)}{', '.join(str(Pathier(file).relative_to(args.project_path)) for file in packages[package])}"
92            for package in packages
93        ]
94
95    print(f"Packages used in {args.project_path.stem}:")
96    print(
97        *packages,
98        sep="\n",
99    )