Skip to content

Instantly share code, notes, and snippets.

@ExpHP
Created September 14, 2017 00:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ExpHP/7049ff4728227d7883d3fb5d7a2cc1d7 to your computer and use it in GitHub Desktop.
Save ExpHP/7049ff4728227d7883d3fb5d7a2cc1d7 to your computer and use it in GitHub Desktop.
cargo-deps.py
#!/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