132 lines
5.4 KiB
Python
132 lines
5.4 KiB
Python
#!/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.xlsx.
|
|
|
|
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.xlsx to the SKILL
|
|
repo (and, per the workflow, the same change flows to the library repo copies).
|
|
"""
|
|
import argparse, datetime, os
|
|
import openpyxl
|
|
from copy import copy
|
|
from openpyxl.styles import Font, PatternFill, Border, Side, Alignment
|
|
from common import (TEMPLATE_XLSX, CHANGELOG_XLSX, CHANGELOG_HEADERS,
|
|
bump_versions, resolve_operator)
|
|
|
|
GREEN = "B6D7A8"; GRAY = "BFBFBF"
|
|
|
|
|
|
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 _thin():
|
|
s = Side(style="thin", color=GRAY)
|
|
return Border(left=s, right=s, top=s, bottom=s)
|
|
|
|
|
|
def _new_changelog_book():
|
|
"""Create the changelog workbook with a styled header row."""
|
|
wb = openpyxl.Workbook()
|
|
ws = wb.active
|
|
ws.title = "Changelog"
|
|
for c, h in enumerate(CHANGELOG_HEADERS, start=1):
|
|
cell = ws.cell(1, c, h)
|
|
cell.font = Font(name="Calibri", bold=True)
|
|
cell.fill = PatternFill("solid", fgColor=GREEN)
|
|
cell.border = _thin()
|
|
cell.alignment = Alignment(horizontal="center", vertical="center")
|
|
for col, w in zip("ABCDEF", (18, 10, 14, 16, 50, 22)):
|
|
ws.column_dimensions[col].width = w
|
|
ws.freeze_panes = "A2"
|
|
return wb
|
|
|
|
|
|
def write_changelog(typeid, added, old, new, desc, by="", when=None):
|
|
"""Append one row to the Excel changelog for a typeid's template/version change.
|
|
Columns: Date | Typeid | Skill Version | Template Version | Description | By. The version
|
|
columns show the NEW versions; Description is the note (or the added params); By is who
|
|
made the change (the operator)."""
|
|
when = when or datetime.datetime.now()
|
|
detail = desc or ("Added parameter(s): " + ", ".join(added))
|
|
if os.path.exists(CHANGELOG_XLSX):
|
|
wb = openpyxl.load_workbook(CHANGELOG_XLSX)
|
|
ws = wb["Changelog"] if "Changelog" in wb.sheetnames else wb.active
|
|
else:
|
|
wb = _new_changelog_book()
|
|
ws = wb.active
|
|
row = [when.strftime("%Y-%m-%d %H:%M"), typeid,
|
|
f"v{new['skill_version']}", f"v{new['template_version']}", detail, by or ""]
|
|
r = ws.max_row + 1
|
|
for c, v in enumerate(row, start=1):
|
|
cell = ws.cell(r, c, v)
|
|
cell.border = _thin()
|
|
cell.alignment = Alignment(vertical="center",
|
|
wrap_text=(c == 5), horizontal="left")
|
|
wb.save(CHANGELOG_XLSX)
|
|
return CHANGELOG_XLSX
|
|
|
|
|
|
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("--by", default="", help="who made this change (name); recorded in the 'By' "
|
|
"column. If omitted, the operator identity is resolved automatically.")
|
|
ap.add_argument("--template", default=TEMPLATE_XLSX)
|
|
a = ap.parse_args()
|
|
|
|
by = a.by or (resolve_operator()[0] or "")
|
|
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, by=by)
|
|
print(f"Added to {a.typeid}: {', '.join(added)}" + (f" (by {by})" if by else ""))
|
|
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.xlsx to the SKILL repo.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|