Created
September 14, 2017 00:16
-
-
Save ExpHP/7049ff4728227d7883d3fb5d7a2cc1d7 to your computer and use it in GitHub Desktop.
cargo-deps.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import os | |
import sys | |
# Prints cargo deps (each name-version pair), gathered recursively. | |
# I couldn't find anything that does this in cargo. | |
def main(): | |
import argparse | |
p = argparse.ArgumentParser( | |
description='Lists name and version for all dependencies of a crate,' | |
' gathered recursively') | |
p.add_argument('DIR', nargs='?', default='.', | |
help='crate root directory (with Cargo.toml)') | |
p.add_argument('--all', '-a', action='store_true', | |
help='include build- and dev-dependencies') | |
p.add_argument('--format', default='{name} {version}', | |
help='format string. [Default: "{name} {version}"]') | |
args = p.parse_args() | |
fmt = args.format | |
os.chdir(args.DIR) | |
for name, version in collect_cargo_deps(p, args.all): | |
print(fmt.format(name=name, version=version)) | |
def collect_cargo_deps(p, do_all): | |
from subprocess import check_output, CalledProcessError | |
import shutil | |
if not shutil.which('cargo-list'): | |
p.error('Cannot find cargo-list. \n' | |
'Please install cargo-edit: \n' | |
' cargo install cargo-edit\n' | |
'and make sure that .cargo/bin is in your PATH.') | |
def inner(*extra): | |
# cargo-list has no recursive option, but we can screenscrape --tree | |
def run(*args): | |
try: return check_output(args, universal_newlines=True) | |
except CalledProcessError as e: | |
sys.exit(1) | |
out = run('cargo', 'list', '--tree') | |
if do_all: | |
out += '\n' + run('cargo', 'list', '--tree', '--build') | |
out += '\n' + run('cargo', 'list', '--tree', '--dev') | |
lines = out.split('\n') | |
lines = [x.strip() for x in lines] | |
lines = [x for x in lines if x] | |
for line in lines: | |
*_, name, version = line.split() | |
assert version[0] == '(' | |
assert version[-1] == ')' | |
version = version[1:-1] | |
yield (name, version) | |
# note: multiple versions may be produced for any crate, | |
# but we don't want any (name,version) pair to appear twice | |
return sorted(set(inner())) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment