#!/usr/bin/env python3 import os import re import subprocess class CargoModifier: def __init__(self): self.depends = list() # noinspection PyShadowingNames def modify_file(self, path): temp = path + '.___' try: with open(path, 'r') as reader: with open(temp, 'w') as writer: self.modify_stream(reader, writer) os.remove(path) os.rename(temp, path) except BaseException as error: try: os.remove(temp) except OSError: pass raise error # chrono = "0.4.38" # clap = { version = "4.5.4", features = ["cargo"] } def modify_stream(self, reader, writer): target = None for line in reader: if re.search(r'^\[dependencies]$', line): print(line, end='', file=writer) target = '' elif match := re.search(r'^\[target\."(.+)"\.dependencies]$', line): print(line, end='', file=writer) target, = match.groups() elif target is not None: if match := re.search(r'^([\w-]+) = "\d+\.\d+\.\d+"$', line): library, = match.groups() self.depends.append((library, target, None)) elif match := re.search(r'^([\w-]+) = { version = "\d+\.\d+\.\d+", features = \["(\w+)"] }$', line): library, features = match.groups() self.depends.append((library, target, features)) elif re.search(r'^$', line): print(line, end='', file=writer) target = None else: raise RuntimeError(f'Unexpected line: {line.rstrip()}') else: print(line, end='', file=writer) def run_cargo(self): for library, target, features in self.depends: command = ['cargo', 'add', library] if target: command.extend(['--target', target]) if features: command.extend(['--features', features]) self.run_process(*command) @classmethod def run_process(cls, *args): process = subprocess.run(args) return process.returncode == 0 def run_main(): modifier = CargoModifier() modifier.modify_file('Cargo.toml') modifier.run_cargo() try: run_main() except (OSError, RuntimeError) as error: print(error) except KeyboardInterrupt: pass