#!/usr/bin/env python3 import os import sys import json import subprocess from datetime import datetime from hashlib import sha256 from tempfile import TemporaryDirectory from shutil import copyfile FILENAME = 'Platfile' LOCKFILE = FILENAME + '.lock' VERSION = '2.0' def initialize(dir: str): print('Initializing ', FILENAME) dir_modules = os.path.join(dir, '..', '..', 'Modules') path = os.path.join(dir, FILENAME) with open(path, 'w') as file: entries = os.listdir(dir_modules) for entry in entries: if os.path.isfile(os.path.join(dir_modules, entry, entry + '.yml')): file.write(entry + '\n') def generate(dir: str, generator: str): path = os.path.join(dir, FILENAME) with open(path) as file: modules = file.readlines() modules = set(m.strip() for m in modules if m.strip()) modules = sorted(modules) dir_modules = os.path.join(dir, '..', '..', 'Modules') print(f'Generating modules: {len(modules)}') generator = generator or os.path.join(dir, 'generate-platform') for module in modules: src_dir = os.path.join(dir_modules, module, 'src') with TemporaryDirectory() as tmpdir: subprocess.call([generator, module, '-o', tmpdir]) _merge_changes(tmpdir, src_dir) if os.path.exists(LOCKFILE): os.remove(LOCKFILE) def _merge_changes(src_dir: str, dst_dir: str): for file_name in os.listdir(src_dir): src_file = os.path.join(src_dir, file_name) src_hash = _hash_file(src_file) dst_file = os.path.join(dst_dir, file_name) if os.path.exists(dst_file): dst_hash = _hash_file(dst_file) if src_hash == dst_hash: return copyfile(src_file, dst_file) print('Updated file: ', file_name) def _hash_file(path: str): alg = sha256() with open(path, 'rb') as file: for line in file.readlines(): if line: alg.update(line) return alg.hexdigest() def main(): from argparse import ArgumentParser parser = ArgumentParser( prog='GeneratePlatforms', description='Automatic code generator' ) parser.add_argument('-i', '--init', action='store_true') parser.add_argument('-g', '--generator', type=str) args = parser.parse_args() dir = os.path.dirname(os.path.realpath(sys.argv[0])) if args.init: initialize(dir) else: generate(dir, args.generator) if __name__ == "__main__": main()