Keats / kickstart

A scaffolding tool to get new projects up and running quickly
MIT License
354 stars 24 forks source link

Allow loading choices from API call #45

Open aexvir opened 3 years ago

aexvir commented 3 years ago

Nice project!

It actually seems to be doing some nice things that I wanted cookiecutter to do and I was developing on my own 😅️

What do you think about allowing to populate the choices option dynamically via some API call? My use case at the moment is that we already have existing resources that we'd like to make references to in templated files, like k8s definitions and vcs projects.

I imagine this being set up somewhat like this:

[[variables]]
name = "infra_repo"
default = "infra/default"
prompt = "Which infrastructure repository should this be linked to?"
choices =  [
    { endpoint = "https://gitlab.com/api/v4/groups/123/projects", headers = "Authorization: Bearer {{ token }}", values = "$.*.id", labels = "$.*.name" }
]

what kickstart would do in this case would be an API call to the endpoint, with the specified headers and will query the result using JSONPath for both values and labels and zip them together, showing the labels to the users but saving the value when the user accepts

I think that allowing to template headers from env vars or cli flag should be enough to support most auth methods, and for basic auth the credentials can be templated in the endpoint part

so headers should be optional

and labels as well, for when the info displayed to the user can be used also as value

choices can accept a list of this inline tables and make one request per configured endpoint, merging all the results in the end... not sure if this would be needed at some point, otherwise it can be limited to one only, or maybe moved outside of choices

either way... this is just a suggestion implementation, I'm more interested in if you'd be up for adding this feature to kickstart and if you'd be ok with getting and reviewing a contribution on this 🙂️

Keats commented 3 years ago

I think the concept is ok but I'm not sure about the implementation. Something like:

[[variables]]
name = "infra_repo"
default = "infra/default"
prompt = "Which infrastructure repository should this be linked to?"
# The line below will load all of vars listed and errors if not present
environment_variables = ["ACCESS_TOKEN"]
# and now how to load remote choices.... maybe a nested dict?
[remote_choices]
url = "blabla"
headers = []
names = "$...."
values = "$..."

Would that feature be something many people need though? Any other examples to make sure we don't do something too narrow (eg limiting to JSON path).

aexvir commented 3 years ago

oops... I somehow missed this notification, sorry 😕

regarding the implementation syntax... sure, it was just a suggestion I personally don't have a strong feeling against your suggestion but I found it simpler to be integrated within the current choices option, as it could technically also join results from the remote endpoint and explicit values, but I can see how that would add complexity

how much people would need this? to be honest... I don't know 😅️ in my opinion is a really powerful option as it could be used to make the templates more dynamic, without needing to duplicate or sync information when needing to refer to some external resources I have plenty of use cases on my own but can't give you any numbers I'm afraid

about supporting more than json path... that should be ok for most of the cases of REST APIs but if the feature is really popular and some people will want additional response processors that shouldn't be too hard to add, but I can't think of many other alternatives to this... maybe graphql?

Keats commented 3 years ago

GraphQL was what I was thinking of, although you can still use JSON path there anyway. Hopefully no one will want to handle XML or parse HTTP...

I personally don't have a strong feeling against your suggestion but I found it simpler to be integrated within the current choices options

What I don't like with this is that one row in the options you end up with many options which would be confusing imo. You could still have both remote_choices and choices and merge them