#!/usr/bin/env python3 """Add one or more new parameters to a single typeid's template sheet, bump that typeid's versions, and record the change in the global changelog. Versioning is **per typeid**: adding a parameter to (say) SCH means there's a new SCH template, so SCH's template_version bumps v1->v2, and on the back of that its skill_version bumps v1->v2 too. Only SCH moves; every other typeid keeps its versions. Those two numbers are what fill_templates later stamps into the SCH sheet's rows (columns B and C). The new column is appended at the END of the sheet (as requested), styled like the other headers. Then versions.json is bumped and one entry is written to CHANGELOG.md. python append_parameter.py --typeid SCH \ --param "Reverse Recovery Time(ns)" --param "Diode Capacitance(pF)" \ --desc "Added Trr and Cd for SMPS rectifier derating" After running, push the updated template.xlsx + versions.json + CHANGELOG.md to the SKILL repo (and, per the workflow, the same change flows to the components repo copies). """ import argparse, datetime, os import openpyxl from copy import copy from common import (TEMPLATE_XLSX, CHANGELOG_MD, bump_versions, load_taxonomy) def _style_header(new_cell, ref_cell): """Make an appended header look like the sheet's existing headers.""" for attr in ("font", "fill", "border", "alignment", "number_format"): try: setattr(new_cell, attr, copy(getattr(ref_cell, attr))) except Exception: pass def append_params(template_path, typeid, params): wb = openpyxl.load_workbook(template_path) if typeid not in wb.sheetnames: raise SystemExit(f"no sheet '{typeid}' in template; is it a valid typeid?") ws = wb[typeid] headers = [ws.cell(1, c).value for c in range(1, ws.max_column + 1)] added = [] for p in params: if p in headers: print(f" ! '{p}' already exists in {typeid} - skipping") continue col = ws.max_column + 1 cell = ws.cell(1, col, p) _style_header(cell, ws.cell(1, 1)) headers.append(p) added.append(p) if not added: raise SystemExit("nothing to add (all parameters already present)") wb.save(template_path) return added def write_changelog(typeid, added, old, new, desc, when=None): when = when or datetime.datetime.now() folder = (load_taxonomy().get(typeid) or {}).get("folder", "?") lines = [ f"## {when.strftime('%Y-%m-%d %H:%M')} - {typeid} ({folder})", f"- Template v{old['template_version']} -> v{new['template_version']}, " f"Skill v{old['skill_version']} -> v{new['skill_version']}", "- Added parameter(s): " + ", ".join(f'\"{p}\"' for p in added), ] if desc: lines.append(f"- Description: {desc}") entry = "\n".join(lines) + "\n\n" header = "# library-manager - template/version changelog\n\n" prior = "" if os.path.exists(CHANGELOG_MD): prior = open(CHANGELOG_MD, encoding="utf-8").read() if prior.startswith(header): prior = prior[len(header):] open(CHANGELOG_MD, "w", encoding="utf-8").write(header + entry + prior) # newest on top return CHANGELOG_MD def main(): ap = argparse.ArgumentParser() ap.add_argument("--typeid", required=True, help="e.g. SCH, MOS, LDO") ap.add_argument("--param", required=True, action="append", help="new column header; repeat for several") ap.add_argument("--desc", default="", help="what/why - goes in the changelog") ap.add_argument("--template", default=TEMPLATE_XLSX) a = ap.parse_args() added = append_params(a.template, a.typeid, a.param) old, new = bump_versions(a.typeid) cl = write_changelog(a.typeid, added, old, new, a.desc) print(f"Added to {a.typeid}: {', '.join(added)}") print(f"{a.typeid}: template v{old['template_version']}->v{new['template_version']}, " f"skill v{old['skill_version']}->v{new['skill_version']}") print(f"Changelog updated: {cl}") print("Now push template.xlsx + versions.json + CHANGELOG.md to the SKILL repo.") if __name__ == "__main__": main()