|  | #!/usr/bin/env python3 | 
|  | # -*- coding: utf-8 -*- | 
|  | # | 
|  | # Copyright (C) 2017-2020  The Project X-Ray Authors. | 
|  | # | 
|  | # Use of this source code is governed by a ISC-style | 
|  | # license that can be found in the LICENSE file or at | 
|  | # https://opensource.org/licenses/ISC | 
|  | # | 
|  | # SPDX-License-Identifier: ISC | 
|  |  | 
|  | import argparse | 
|  | import hashlib | 
|  | import os | 
|  | import parse as format_parser | 
|  | import subprocess | 
|  | import sys | 
|  |  | 
|  | """Module for generating the Info.md file found in the database directory.""" | 
|  |  | 
|  | info_md_header = """ | 
|  | # Details | 
|  |  | 
|  | Last updated on {human_date} ({iso8601_date}). | 
|  |  | 
|  | Created using [Project X-Ray](https://github.com/SymbiFlow/prjxray) version [{commit_hash_short}](https://github.com/SymbiFlow/prjxray/commit/{commit_hash_long}). | 
|  |  | 
|  | Latest commit was; | 
|  | ``` | 
|  | {commit_latest} | 
|  | ``` | 
|  |  | 
|  | """ | 
|  |  | 
|  | info_md_section = """ | 
|  |  | 
|  | ## Database for [{part_line}]({part_line}/) | 
|  |  | 
|  | ### Settings | 
|  |  | 
|  | Created using following [settings/{part_line}.sh (sha256: {settings_sha256})](https://github.com/SymbiFlow/prjxray/blob/{commit_hash_long}/settings/{part_line}.sh) | 
|  | ```shell | 
|  | {settings_contents} | 
|  | ``` | 
|  |  | 
|  | ### [Results]({part_line}/) | 
|  |  | 
|  | Results have checksums; | 
|  |  | 
|  | """ | 
|  |  | 
|  | info_md_file = " * [`{file_sha256}  ./{file_short_path}`](./{file_short_path})\n" | 
|  |  | 
|  |  | 
|  | def sha256(s): | 
|  | m = hashlib.sha256() | 
|  | m.update(s) | 
|  | return m.hexdigest() | 
|  |  | 
|  |  | 
|  | def sha256_file(p): | 
|  | return sha256(open(p, 'rb').read()) | 
|  |  | 
|  |  | 
|  | def run(c): | 
|  | o = subprocess.check_output(c, shell=True) | 
|  | return o.decode('utf-8').strip() | 
|  |  | 
|  |  | 
|  | def main(argv): | 
|  |  | 
|  | parser = argparse.ArgumentParser() | 
|  | parser.add_argument( | 
|  | '--keep', | 
|  | default=False, | 
|  | action="store_true", | 
|  | help="""\ | 
|  | Keep the existing commit information. | 
|  | """) | 
|  | args = parser.parse_args() | 
|  |  | 
|  | info_md_filename = os.path.join('database', 'Info.md') | 
|  | assert os.path.exists(info_md_filename), info_md_filename | 
|  |  | 
|  | info_md = [] | 
|  |  | 
|  | info_md.append(open('database/README.md').read()) | 
|  |  | 
|  | v = {} | 
|  | v['human_date'] = run('TZ=UTC date') | 
|  | v['iso8601_date'] = run('TZ=UTC date --iso-8601=seconds') | 
|  | if not args.keep: | 
|  | v['commit_latest'] = run('git log -1') | 
|  | v['commit_hash_short'] = run('git log -1 --pretty=%h') | 
|  | v['commit_hash_long'] = run('git log -1 --pretty=%H') | 
|  | else: | 
|  | with open(info_md_filename) as f: | 
|  | result = format_parser.parse( | 
|  | '{before}' + info_md_header + '{after}', f.read()) | 
|  | assert result | 
|  | assert result['human_date'] | 
|  | assert result['iso8601_date'] | 
|  | v['commit_latest'] = result['commit_latest'] | 
|  | v['commit_hash_short'] = result['commit_hash_short'] | 
|  | v['commit_hash_long'] = result['commit_hash_long'] | 
|  |  | 
|  | info_md.append(info_md_header.format(**v)) | 
|  |  | 
|  | for part_line in sorted(os.listdir('database')): | 
|  | if part_line.startswith('.'): | 
|  | continue | 
|  | part_path = os.path.join('database', part_line) | 
|  |  | 
|  | if not os.path.isdir(part_path): | 
|  | continue | 
|  |  | 
|  | files = list(os.listdir(part_path)) | 
|  | files.sort() | 
|  |  | 
|  | settings_path = os.path.join('settings', part_line + '.sh') | 
|  | settings_raw = open(settings_path, 'rb').read() | 
|  |  | 
|  | w = {} | 
|  | w['commit_hash_long'] = v['commit_hash_long'] | 
|  | w['part_line'] = part_line | 
|  | w['settings_contents'] = settings_raw.decode('utf-8') | 
|  | w['settings_sha256'] = sha256(settings_raw) | 
|  |  | 
|  | info_md.append(info_md_section.format(**w)) | 
|  |  | 
|  | files = [] | 
|  | for dirpath, dirnames, filenames in os.walk(part_path): | 
|  | for f in filenames: | 
|  | files.append(os.path.join(dirpath, f)) | 
|  |  | 
|  | files.sort() | 
|  | for p in files: | 
|  | x = {} | 
|  | x['file_real_path'] = './' + p | 
|  | x['file_short_path'] = os.path.join( | 
|  | part_line, os.path.relpath(p, part_path)) | 
|  | x['file_sha256'] = sha256_file(p) | 
|  | info_md.append(info_md_file.format(**x)) | 
|  |  | 
|  | with open(info_md_filename, 'w') as f: | 
|  | f.write("".join(info_md)) | 
|  |  | 
|  | return 0 | 
|  |  | 
|  |  | 
|  | if __name__ == "__main__": | 
|  | sys.exit(main(sys.argv)) |