Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom ADR templates #40

Open
lbenezriravin opened this issue Dec 12, 2024 · 2 comments
Open

Custom ADR templates #40

lbenezriravin opened this issue Dec 12, 2024 · 2 comments

Comments

@lbenezriravin
Copy link
Contributor

lbenezriravin commented Dec 12, 2024

Possibly related to #26

I'd like a feature (and I'm happy to implement!) that allows me to use a custom template when creating new ADRs. I want to discuss here/get approval for some ideas before going off the deep end though.

Motivation

My team has many projects and contexts in which we use ADRs, for some of which we like to include extra sections in our decisions. For example, when documenting team style standards, we want each record to have a section defining specs for CI automation that enforces it. It's annoying (and easy to forget) to manually add this section every time I create a new ADR.

Specification

  • New ADR generation should look for a template in a location relative to .adr-dir
  • If a template isn't found, default to the existing behavior -- this feature should be backwards-compatible
  • A custom template can be specified at runtime to override the default location

Implementation in other projects

npryce/adr-tools (essentially the reference implementation) kind of has this feature inasmuch as you can consider sed a templating engine:
https://github.com/npryce/adr-tools/blob/b3279baf9be2207d1a4f4bbd608fd0b591c72aee/src/adr-new#L108

It looks for a template in templates/template.md and replaces a few choice keywords. Obviously we can improve the templating logic here but I think this location for custom templates makes sense as a default for compatibility's sake.

Implementation details

The biggest issue with this feature is that the templating engine currently in use explicitly calls this out as not supported. Instead of hacking around the current tool, I propose that we switch to a more powerful engine such as handlebars or minijinja. I don't have a particularly strong opinion on which specific crate to use but I think that if we're opening up templates to users, having it based on popular engines (such as handlebars or jinja2) is a good thing.

My next big question is how powerful this feature should be. adr-tools allows for a couple specific builtin keywords and nothing else. I'm leaning towards keeping this type of restriction for two reasons:

  1. It keeps this feature contained. We can always add more power later if we want.
  2. I personally don't need that and don't see anyone calling for it. I don't want to overengineer anything crazy without a real usecase.

Less importantly, do we want to add a config file for adrs to allow users to override the default template location? I lean towards no for mostly the same reasons as above -- we can add it later and I don't want to overcomplicate a simple tool right now.

Finally, I'm happy to address #26 while I'm here, and I think it'll be much easier to do with a more full-featured templater.

Let me know what you think! I'd love to submit a PR soon if we agree on the spec.

@joshrotenberg
Copy link
Owner

Pretty much agree with everything here. I've used handlebars in the past, but both look like workable options. If you have experience with them both I'd love to know what would motivate choosing one or the other, but I think they both have more than enough functionality for the feature.

Also agree with holding off on adding new (and possibly user defined?) template items. Not against that as a feature but it should possibly be added after this to keep the changes smaller.

As far as config goes, some options:

  1. Support an actual configuration file with https://crates.io/crates/config, TOML would be my preference. In addition to template file location, could also support explicit config of where ADRs go and maybe some stuff around .adr-dir, editor, etc. Not necessarily "hard" but probably requires the most actual implementation.

  2. Support environment variables with cli args to override, so like ADRS_TEMPLATE_DIR can be set or specified with --template-dir for new and init. This actually should be possible already with clap (see https://docs.rs/clap/latest/clap/_features/index.html#optional-features). Pretty easy, enable the feature in Cargo.toml:

clap = { version = "4.5.1", features = ["derive", "env"] }

and then top level so it's shared across commands:

// main.rs
#[derive(Parser)]
#[command(version, about, long_about = None )]
#[command(propagate_version = true)]
struct Cli {
    #[arg(default_value = "foo", env = "ADRS_TEMPLATE_DIR", short, long)]
    template_directory: Option<String>,
    #[command(subcommand)]
    command: Commands,
}
  1. Hard code a directory and you just put your templates where we say you put your templates.

Personally I like 2 the best. 1. Seems excessive, 3. seems inflexible. 2 or 3 would be reasonable to add with a custom template PR, 1 would probably be better as a separate implementation.

@lbenezriravin
Copy link
Contributor Author

That all looks good to me. I agree environment vars with cli override makes the most sense right now. I'll take a stab at this over the next few days.

I personally have more experience with jinja than handlebars, but as you said I don't think we'll be coming close to using features where the difference really matters. I'll try out handlebars, the two projects are comparably active and it's always good to learn a new tool.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants