I am trying to loop over all items in a Python cookiecutter json list and run a bash command based on each item.
Setup
I have the following cookiecutter.json:
{
    "directory_name": "df-sharp",
    "servers": ["db", "web"],
    "myweb_provisioner": "webck"
}
I have {{cookiecutter.myweb_provisioner}}.sh, which contains this jinja2 code:
{% for server in cookiecutter.servers %}
mkdir -p ~/myproj/host_types/{{ server }}
{% endfor %}
Problem
When I run cookiecutter create-server-tree, I get the following:
Select servers:
1 - db
2 - web
Choose from 1, 2 [1]: 2
and the contents in webck.sh are:
mkdir -p ~/myproj/host_types/w
mkdir -p ~/myproj/host_types/e
mkdir -p ~/myproj/host_types/b
The Select menu should not appear. I do not want to choose between the 2 elements in the list. I want to loop over them and construct 2 bash commands - one command per element. I am trying to loop over the list like shown here or here.
What I want
This is what I want: cookiecutter create-server-tree should produce webck.sh which contains the following:
mkdir -p ~/myproj/host_types/db
mkdir -p ~/myproj/host_types/web
How can I iterate over the servers list and use each of the list elements (instead of one character at a time)?
It turns out that I was using the wrong terminology. If the value in a key-value pair is a plain list, then cookiecutter calls that value (list) as providing "Multiple Choice options". So if I put in a plain list as the value for the key "servers", then I should expect to get the list of choices that I got above:
Select servers:
1 - db
2 - web
Choose from 1, 2 [1]: 2
What I needed was a nested dictionary as the value for the key servers, like they show here - it is called Dictionary Variables. To use this to answer my question, I changed my cookiecutter.json file to this:
{
    "directory_name": "df-sharp",
    "servers": {"server_list": ["db", "web"],
                "server_ips: ["123", "456"]"
               },
    "myweb_provisioner": "webck"
}
and then I used jinja2 as shown below:
{% for server in cookiecutter.servers.server_list %}
mkdir -p ~/myproj/host_types/{{ server }}
{% endfor %}
and this gave me what I wanted.
However, I had to use cookiecutter create-server-tree --no-input(link). This is because I have not been able to suppress only the prompt for a dictionary variable. I would have wanted this:
directory_name[df-sharp]: 
myweb_provisioner[webck]: 
and some way of specifying the key servers as a default argument. Actually, they have a default option here. It would be something like this and requires using their API:
cookiecutter('create-server-tree/',
             no_input=True,
             extra_context={"servers": {"server_list":['db','web'],
                                        "server_ips": ["123", "456"]
                                       }
                           }
            )
However, how should a user incorporate this extra_content={...} argument into an actual cookiecutter project and refer to "server_list" in jinja2 templated script? I don't know.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With