135 lines
2.8 KiB
Text
135 lines
2.8 KiB
Text
|
#!/usr/bin/env python3
|
||
|
|
||
|
from subprocess import check_call
|
||
|
import argparse
|
||
|
import json
|
||
|
import os
|
||
|
import sys
|
||
|
|
||
|
|
||
|
ADR_TEMPLATE_MD = """
|
||
|
---
|
||
|
{{- $num := index .Site.Data.adrs.current "number" -}}
|
||
|
{{- $title := index .Site.Data.adrs.index $num "name" -}}
|
||
|
title: "{{ $num }}. {{ $title }}"
|
||
|
date: {{ .Date }}
|
||
|
draft: true
|
||
|
topics:
|
||
|
- ADR
|
||
|
---
|
||
|
# {{ $num }}. {{ $title }}
|
||
|
|
||
|
Date: {{ dateFormat "2006-01-02" .Date }}
|
||
|
|
||
|
## Status
|
||
|
|
||
|
DRAFT
|
||
|
|
||
|
## Context
|
||
|
|
||
|
The issue motivating this decision, and any context that influences or
|
||
|
constrains the decision.
|
||
|
|
||
|
## Decision
|
||
|
|
||
|
The change that we're proposing or have agreed to implement.
|
||
|
|
||
|
## Consequences
|
||
|
|
||
|
What becomes easier or more difficult to do and any risks introduced by the
|
||
|
change that will need to be mitigated
|
||
|
""".strip()
|
||
|
|
||
|
ADR_DATA_DIR = os.path.join("data", "adrs")
|
||
|
ADR_CONTENT_DIR = os.path.join("content", "adrs")
|
||
|
|
||
|
|
||
|
def ensure_adr_archetype():
|
||
|
adr_archetype = os.path.join("archetypes", "adrs.md")
|
||
|
|
||
|
if not os.path.exists(adr_archetype):
|
||
|
with open(adr_archetype, "w") as f:
|
||
|
f.write(ADR_TEMPLATE_MD)
|
||
|
|
||
|
|
||
|
def write_adr_json(data: dict):
|
||
|
with open(os.path.join(ADR_DATA_DIR, "index.json"), "w") as index:
|
||
|
json.dump(data, index)
|
||
|
|
||
|
|
||
|
def load_adr_json() -> dict:
|
||
|
with open(os.path.join(ADR_DATA_DIR, "index.json")) as index:
|
||
|
return json.load(index)
|
||
|
|
||
|
|
||
|
def ensure_adr_data():
|
||
|
if not os.path.exists(ADR_DATA_DIR):
|
||
|
os.makedirs(ADR_DATA_DIR)
|
||
|
|
||
|
if not os.path.exists(os.path.join(ADR_DATA_DIR, "index.json")):
|
||
|
write_adr_json({})
|
||
|
|
||
|
|
||
|
def get_adr_number() -> int:
|
||
|
adr_dir = os.path.join("content", "adrs")
|
||
|
if not os.path.isdir(adr_dir):
|
||
|
return 1
|
||
|
|
||
|
num = 0
|
||
|
|
||
|
items = [
|
||
|
adr_file
|
||
|
for adr_file in sorted(os.listdir(adr_dir))
|
||
|
if os.path.isfile(os.path.join(adr_dir, adr_file))
|
||
|
]
|
||
|
|
||
|
for i in items:
|
||
|
num = max(num, int(i.split(".", 2)[0]))
|
||
|
|
||
|
num += 1
|
||
|
|
||
|
return num
|
||
|
|
||
|
|
||
|
def write_current_adr_number(num: int):
|
||
|
data = {"number": f"{num:04}"}
|
||
|
|
||
|
with open(os.path.join(ADR_DATA_DIR, "current.json"), "w") as current:
|
||
|
json.dump(data, current)
|
||
|
|
||
|
|
||
|
def create_adr_file(num: int, name: str):
|
||
|
adr_filename = f"{num:04}. {name}.md".lower().replace(" ", "-")
|
||
|
|
||
|
write_current_adr_number(num)
|
||
|
|
||
|
adr_data = load_adr_json()
|
||
|
|
||
|
adr_data[f"{num:04}"] = {"name": name, "status": "DRAFT"}
|
||
|
|
||
|
write_adr_json(adr_data)
|
||
|
|
||
|
check_call(["hugo", "new", f"adrs/{adr_filename}"])
|
||
|
|
||
|
|
||
|
def main():
|
||
|
argp = argparse.ArgumentParser()
|
||
|
argp.add_argument("title", help="The title of your architectural decision record")
|
||
|
|
||
|
args = argp.parse_args()
|
||
|
|
||
|
ensure_adr_archetype()
|
||
|
ensure_adr_data()
|
||
|
|
||
|
adr_number = get_adr_number()
|
||
|
|
||
|
create_adr_file(adr_number, args.title)
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
if not os.path.isdir("archetypes"):
|
||
|
print("You need to run this in a hugo project with an archetypes directory")
|
||
|
sys.exit(1)
|
||
|
|
||
|
main()
|