| #!/usr/bin/env python3 |
| |
| import datetime |
| import os |
| import pprint |
| import shutil |
| import subprocess |
| import sys |
| import tempfile |
| import time |
| |
| from library_submodules import * |
| |
| |
| __dir__ = os.path.dirname(__file__) |
| |
| #author = "Tim 'mithro' Ansell <tansell@google.com>" |
| author = 'Kevin Kelley <kevin.kelley@skywatertechnology.com>' |
| |
| |
| def lib_src(src_lib_dir, l, v): |
| return os.path.join(src_lib_dir, l, 'v{}.{}.{}'.format(*v)) |
| |
| |
| def header(l, s, *args, **kw): |
| s1 = s.format(*args, **kw) |
| s2 = l*len(s1) |
| return '{}\n{}\n'.format(s1, s2) |
| |
| |
| message_template = """\ |
| Significant improvements to primitives {library} version {version}. |
| |
| This commit contains major improvements to all files by regenerating |
| from original data, improving consistency and automated cross checking |
| of data. |
| |
| These improvements should drastically reduce customer confusion when |
| using the library and further reduce future possibility for human errors to |
| creep into designs. |
| |
| Notable improvements include; |
| |
| * A large number of files have been regenerated from original source |
| data (compared to previous hand created versions). |
| |
| * Catalog and other library aggregations are now automatically |
| generated from library contents (compared to previous hand created |
| versions). |
| |
| * Significant improvements to documentation for all cells and models, |
| including producing graphical representations, verified metadata and |
| descriptions. |
| |
| * Names have been cross referenced between file types (such as |
| simulation, layout, schematic and timing) and now verified to match. |
| |
| * Names have been improved to fix a standard format across all supported |
| libraries and PDK contents. |
| |
| * Significant improvements to the contents of text files through improving |
| consistent style that has been automatically checked. |
| |
| * Simplified spice files for usage with open tools. |
| |
| * Too many numerous other changes to list here. |
| |
| Signed-off-by: Kevin Kelley <kevin.kelley@skywatertechnology.com> |
| """ |
| |
| |
| def main(args): |
| assert len(args) == 2 |
| |
| src_dir = os.path.abspath(args.pop(0)) |
| out_dir = os.path.abspath(args.pop(0)) |
| |
| assert os.path.exists(src_dir), src_dir |
| src_lib_dir = os.path.join(src_dir, "skywater-pdk", "libraries") |
| assert os.path.exists(src_lib_dir), src_lib_dir |
| |
| lib_versions = {} |
| for l in libraries.keys(): |
| lib_dir = os.path.join(src_lib_dir, l) |
| assert os.path.exists(lib_dir), lib_dir |
| versions = [tuple(int(x) for x in v[1:].split('.')) for v in os.listdir(lib_dir) if v.startswith('v')] |
| versions.sort() |
| lib_versions[l] = tuple(versions) |
| print(l, versions) |
| for v in versions: |
| ov = out_v(v, versions) |
| libv_dir = lib_src(src_lib_dir, l, v) |
| assert os.path.exists(libv_dir), libv_dir |
| print(' ', v, ov, libv_dir) |
| |
| print() |
| print() |
| assert os.path.exists(out_dir), out_dir |
| git_clone_dir = os.path.join(out_dir, "skywater-pdk") |
| if os.path.exists(git_clone_dir): |
| print("Removing old directory.") |
| print('='*75, flush=True) |
| run('rm -rf {}'.format(git_clone_dir)) |
| print('='*75, flush=True) |
| |
| os.makedirs(git_clone_dir) |
| |
| for l in libraries.keys(): |
| git_out_dir = os.path.join(git_clone_dir, l) |
| assert not os.path.exists(git_out_dir), git_out_dir |
| print() |
| print() |
| print('Doing update on', l) |
| print('='*75, flush=True) |
| print() |
| print('Cloning initial repo') |
| print('-'*20, flush=True) |
| git_reference = os.path.abspath(os.path.expanduser('~/gob/foss-eda-tools/skywater-pdk-libs-{0}/.git'.format(l))) |
| assert os.path.exists(git_reference), git_reference |
| git('clone --reference {1} https://foss-eda-tools.googlesource.com/skywater-pdk/libs/{0}.git'.format(l, git_reference), git_clone_dir) |
| assert os.path.exists(os.path.join(git_out_dir, ".git")), "Git directory was not created in:"+git_out_dir |
| git('fetch origin', git_out_dir) |
| git('fetch origin --tags', git_out_dir) |
| print('-'*20, flush=True) |
| versions = lib_versions[l] |
| for i, v in enumerate(versions): |
| src_dir = lib_src(src_lib_dir, l, v)+'/' |
| assert os.path.exists(src_dir), src_dir |
| |
| pv = previous_v(v, versions) |
| ov = out_v(v, versions) |
| |
| v_branch = "branch-{}.{}.{}".format(*ov) |
| v_tag = "v{}.{}.{}".format(*ov) |
| |
| print() |
| print("Was:", pv, "Now creating", (v_branch, v_tag), "in", git_out_dir, "from", src_dir) |
| print('-'*20, flush=True) |
| |
| # Get us back to a very clean tree. |
| git('reset --hard HEAD', git_out_dir) |
| git('clean -f', git_out_dir) |
| git('clean -x -f', git_out_dir) |
| |
| # Checkout the right branch |
| git('branch {}'.format(v_branch), git_out_dir) |
| git('checkout {}'.format(v_branch), git_out_dir) |
| git('branch old-{0} {0}'.format(v_branch), git_out_dir) |
| |
| diff_pos = 'branch-{}.{}.{}'.format(*pv) |
| if pv != (0, 0, 0): |
| git('merge {} --no-ff --no-commit --strategy=ours'.format(diff_pos), git_out_dir) |
| else: |
| diff_pos = 'HEAD' |
| |
| # Update the contents |
| run('rm -rf {}/*'.format(git_out_dir)) |
| run(f'cp -arT {src_dir} {git_out_dir}/') |
| #files = subprocess.check_output(f'find {src_dir} -name *.svg', shell=True, cwd=src_dir) |
| #files = files.decode('utf-8') |
| #for f in files.splitlines(): |
| # f = f.replace(src_dir, '') |
| # run(f'cp -arT {src_dir}/{f} {git_out_dir}/{f}') |
| if not os.path.exists(os.path.join(git_out_dir, "LICENSE")): |
| git('checkout HEAD LICENSE', git_out_dir) |
| if not os.path.exists(os.path.join(git_out_dir, "README.rst")): |
| git('checkout HEAD README.rst', git_out_dir) |
| git('add -A', git_out_dir) |
| |
| # Report if anything has changed. |
| git('status', git_out_dir) |
| git('diff {} --stat=200'.format(diff_pos), git_out_dir) |
| #diff_out = os.path.abspath(os.path.join(git_clone_dir, '{}-v{}.{}.{}_to_{}.patch'.format(l, *pv, v_tag))) |
| #git('diff {} > {} '.format(diff_pos, diff_out), git_out_dir) |
| |
| #diff_changes = os.path.abspath(os.path.join(git_clone_dir, '{}-{}-changes.patch'.format(l, v_tag))) |
| #git('diff HEAD > {} '.format(diff_changes), git_out_dir) |
| diff_changes = os.path.abspath(os.path.join(git_clone_dir, '{}-{}-changes.stat'.format(l, v_tag))) |
| git('diff HEAD --stat=200 > {} '.format(diff_changes), git_out_dir) |
| with tempfile.NamedTemporaryFile('w') as f: |
| f.write(message_template.format(library=l, version=v_tag[1:])) |
| f.flush() |
| git("commit --author='{}' --signoff --allow-empty --file={}".format(author, f.name), git_out_dir) |
| |
| #git('tag --delete {}'.format(v_tag), git_out_dir) |
| git('tag -a {} -m"Adding version {} for sky130_fd_pr"'.format(v_tag, v_tag), git_out_dir) |
| |
| git('branch -D master', git_out_dir) |
| git('branch master', git_out_dir) |
| |
| print('='*75, flush=True) |
| |
| |
| |
| if __name__ == "__main__": |
| sys.exit(main(sys.argv[1:])) |