| #!/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)) |