Add an OS specific helper for replacing characters for file separators
From a discussion we had about creating a directory structure, it was proposed to use replace(".", "/") in a task script. As this is specific to unix like filesystems it would be nice to have a helper that is OS specific. On Windows it will be \ and on unix like OS' it'll be /.
The working example (unix specific) is
# task.sh.jinja
templates_dir=templates
src_dir=src/main/{{ package.replace(".", "/") }}
test_dir=src/test/{{ package.replace(".", "/") }}
mkdir -p "$src_dir"
mkdir -p "$test_dir"
A nice alternative, as proposed by @yajo & @pawamoy would be
# task.sh.jinja
templates_dir=templates
src_dir=src/main/{{ package.replace(".", copier_sep) }}
test_dir=src/test/{{ package.replace(".", copier_sep) }}
mkdir -p "$src_dir"
mkdir -p "$test_dir"
I don't think the distinction between Linux and Windows is relevant: indeed, the point of this issue is to provide a way to create directory structures without tasks, and the suggestion is to provide a context variable (for example copier_sep or os_sep) that is not a real OS separator (because they are not allowed in filenames), and that Copier will handle as if it was an actual separator. So in any case, users will use a single variable, whatever the OS is, and Copier will run Python's mkdir, where / works on all systems anyway.
I see. You were pushing to add a feature where we can do this as a task in copier.yml instead of in a shell script?
IIUC, what @yajo suggested is that Copier natively supports creating arbitrarily deep directories without tasks, yes, by allowing writers to use a copier_sep/os_sep constant in their filenames.
umm... this works for me. You can use forward slash on Windows, no problem. I just made a custom jinja extension with a global DIR_SEP='/' and Copier creates directory structure.
Oh, and I had to add one line to copier, as it doesn't create parent directories for rendered files. I'll prepare a patch
In the PR 6e06df7 there's a test for this behaviour. It passes sep: '/' as part of data
@yajo @pawamoy , Do you think Copier should provide a separator variable to facilitate this?
Yes definitely. And it makes sense that it doesn't need to be a special character, since filenames will use the variable and not the character (slash) itself :)
Yes definitely. And it makes sense that it doesn't need to be a special character, since filenames will use the variable and not the character (slash) itself :)
Introducing a global variable would break existing templates for anyone who already uses that name, regardless of what name we pick. So it would be a breaking change, unless there's a configuration variable: copier.yaml:
_separator_key: os_sep
WDYT?
I think the risk of clashing with the name of an answer in someone's template is very low, especially if we prefix it with an underscore. But I'll let @yajo decide :slightly_smiling_face:
I think the risk of clashing with the name of an answer in someone's template is very low, especially if we prefix it with an underscore. But I'll let @yajo decide 🙂
Ah, I didn't think of adding a prefixed variable. Yeah, that works.
In that case, how about exposing a subset of os as _os? I can think os.environ might be useful. Either way'd we have a "hook" for future os-specific extensions.
Ha, very interesting idea :thinking:
I can think
os.environmight be useful
There's https://pypi.org/project/jinja2-getenv-extension/ so we shouldn't need this.