AFAIK this is not possible with cookiecutter if the number of accounts is not fixed in advance. But you can achieve the same effect with a hook. Something like this: (n.b. untested)
├── project
│ ├── {{ client_name }}
│ │ ├── account_name
│ │ │ │── some-folder
│ │ │ ├── account_name.py
| |-- hooks
| | |-- post_gen_project.py
# post_gen_project.py
# runs from the *generated* project
from pathlib import Path
from shutil import copy, rmtree
accounts = [x.strip() for x in {{ accounts }}.split(",")] # cookiecutter will render this for you
client_name = {{ client_name }}
src = Path(client_name)
for account in accounts:
copy(src / "account_name", src/account)
fn = src/ f"account/account_name.py"
fn.rename(fn.with_name(f"{account}.py"))
rmtree(src)
If you have lots of this to do, you might be better off just writing a deploy script yourself and avoiding cookiecutter.
I am assuming that your accounts are entered ,
separated: I can't remember if there's any way to get a raw list type in cookiecutter.
Yet another option is to use nested cookiecutters---specifically, calling a cookiecutter for account
from the post_gen hook, in a loop until the user no longer wants to add accounts. Something like this (again untested, provided as a starting point):
├── project
│ ├── {{ client_name }}
│ │ ├── account_template
| | | |-- {{ account_name }}
│ | │ │ │── some-folder
│ | │ │ ├── {{ account_name }}.py
| |-- hooks
| | |-- post_gen_project.py
# cookiecutter_project.json
...
"_copy_without_render": ["account_template/"]
This gets our inner cookiecutter deployed where we want it without rendering it. Then in the inner cookiecutter:
# account_template/cookiecutter.json
{ "account_name": "default account", "client_name": "default client"}
And then finally, in the outer cookiecutter's hook:
# hooks/post_gen_project.py
from shutil import rmtree
from cookiecutter.main import cookiecutter
client_name = {{ client_name }}
cont = True
while cont:
account_name = input("Enter account name: ")
cookiecutter(
"template_account",
no_input=True,
extra_content=dict(
account_name=account_name,
client_name=client_name
)
)
cont = not input("Press enter to continue").strip()
rmtree("template_account")
If the number of accounts is fixed in advance it's easy---just name one set account1
, the next account2
and so on.
References:
https://cookiecutter.readthedocs.io/en/1.7.3/advanced/hooks.html
https://cookiecutter.readthedocs.io/en/1.7.3/advanced/suppressing_prompts.html#suppressing-command-line-prompts