Reputation: 7295
We have a number of use cases where we'd like to be able to call cookiecutter and have the files and directories generated get put into the current working directory.
What is essentially desired.
$ cd path/to/repo
$ ls
a.txt
$ cookiecutter path/to/template
$ls
a.txt b.txt
What the result actually is
$ cd path/to/repo
$ ls
a.txt
$ cookiecutter path/to/template
$ls
a.txt
template/
b.txt
template/
cookiecutter.json
b.txt
But cookiecutter appears to require there to be a template root by default to avoid cookiecutter.exceptions.NonTemplatedInputDirException
.
template/
cookiecutter.json
{{cookiecutter.name}}
But then the template files are just nested in a subdirectory of the current working directory like shown above of course.
I keep seeing comments on GitHub saying basically "this is solved", but I can't seem to find documentation on how to use whatever feature was added to accommodate this use case.
Upvotes: 4
Views: 4159
Reputation: 951
Alternatively to the previous answer, which should work perfectly on linux/mac, here is a solution in pure python
hooks/post_gen_project.py
:
import os
import shutil
from pathlib import Path, PurePath
from tempfile import TemporaryDirectory
def _move_single_file(src_dir: PurePath, dst_dir: PurePath, file_name: str):
shutil.move(
str(src_dir.joinpath(file_name)),
dst_dir.joinpath(file_name),
copy_function=lambda x, y: shutil.copytree(
x, y, dirs_exist_ok=True, copy_function=shutil.copy2
),
)
def move_directory_contents(src: PurePath, dst: PurePath):
temp_dir = TemporaryDirectory()
temp_dir_path = Path(temp_dir.name)
directory_contents = os.listdir(src)
for item in directory_contents:
print(f"Moving {item} to {temp_dir_path}")
_move_single_file(src, temp_dir_path, item)
directory_contents.remove(src.name)
for item in directory_contents:
print(f"Moving {item} to {dst}")
_move_single_file(temp_dir_path, dst, item)
os.removedirs(src)
_move_single_file(temp_dir_path, dst, src.name)
if __name__ == "__main__":
if "{{ cookiecutter.use_current_directory }}".lower() == "y":
src = Path.cwd()
assert src.name == "{{ cookiecutter.project_slug }}"
move_directory_contents(src, src.parent)
and the cookiecutter.json
will need to have this line:
{
"use_current_directory": "y/n",
}
This should work on any OS and only requires the hooks/post_gen_project.py
Upvotes: 0
Reputation: 989
The issue is closed, but this doesn't mean it is solved.
The only way to do this is with post-generate hook moving the files out of your folder and deleting the folder.
If you are on a *NIX system, you can use the following simple script:
#!/bin/sh
mv * ..
rm -rfv ../{{ cookiecutter.project_name }}
Where cookiecutter.project_name
is your template folder.
Upvotes: 7