TheCodedProf | 3021937 | 2023-06-11 14:15:30 -0400 | [diff] [blame^] | 1 | import sys |
| 2 | import os |
| 3 | import json |
| 4 | |
| 5 | node_modules = sys.argv[1] |
| 6 | bin_dir = sys.argv[2] |
| 7 | |
| 8 | def collect_packages_in(_node_modules, packages: set[str] | None = None): |
| 9 | _packages: set[str] = packages or set() |
| 10 | for path in os.listdir(_node_modules): |
| 11 | if not os.path.isdir(os.path.join(_node_modules, path)) or os.path.join(_node_modules, path) in _packages: |
| 12 | continue |
| 13 | |
| 14 | _packages.add(os.path.join(_node_modules, path)) |
| 15 | if os.path.exists(os.path.join(_node_modules, path, "node_modules")): |
| 16 | collect_packages_in(os.path.join(_node_modules, path, "node_modules"), _packages) |
| 17 | return _packages |
| 18 | |
| 19 | def get_binaries_in(package): |
| 20 | package_json = os.path.join(package, "package.json") |
| 21 | if not os.path.exists(package_json): |
| 22 | return [] |
| 23 | |
| 24 | with open(package_json) as f: |
| 25 | package_json_contents = json.load(f) |
| 26 | |
| 27 | if "bin" not in package_json_contents: |
| 28 | return [] |
| 29 | |
| 30 | if type(package_json_contents["bin"]) == str: |
| 31 | return [[os.path.basename(package_json_contents["name"]), os.path.join(package, package_json_contents["bin"])]] |
| 32 | |
| 33 | return [[name, os.path.join(package, bin)] for name, bin in package_json_contents["bin"].items()] |
| 34 | |
| 35 | def main(): |
| 36 | packages = collect_packages_in(node_modules) |
| 37 | binaries = [] |
| 38 | for package in packages: |
| 39 | binaries += get_binaries_in(package) |
| 40 | |
| 41 | os.makedirs(bin_dir, exist_ok=True) |
| 42 | |
| 43 | for binary in binaries: |
| 44 | if os.path.exists(os.path.join(bin_dir, binary[0])): |
| 45 | os.remove(os.path.join(bin_dir, binary[0])) |
| 46 | |
| 47 | os.symlink(os.path.realpath(binary[1]), os.path.join(bin_dir, binary[0])) |
| 48 | |
| 49 | if __name__ == "__main__": |
| 50 | main() |