我们有很多用例,希望能够调用cookiecutter,并将生成的文件和目录放入当前工作目录中。
简单示例
本质上需要什么。
$ cd path/to/repo
$ ls
a.txt
$ cookiecutter path/to/template
$ls
a.txt b.txt
实际结果是什么
$ cd path/to/repo
$ ls
a.txt
$ cookiecutter path/to/template
$ls
a.txt
template/
b.txt
我尝试过的东西
- 你可以想象模板是这样的
template/
cookiecutter.json
b.txt
但是cookiecutter似乎默认情况下需要有一个模板根以避免cookiecutter.exceptions.NonTemplatedInputDirException
。
- 因此,添加一个包含模板文件的目录,并尝试将其输出到特定目录
template/
cookiecutter.json
{{cookiecutter.name}}
但是,模板文件只是嵌套在当前工作目录的子目录中,当然如上所示。
- 我也希望可以使用后生成挂钩将模板的输出文件移动到您想要的位置,但这似乎有点像黑客
我一直在GitHub上看到评论,基本上说";这就解决了";,但我似乎找不到关于如何使用为适应这个用例而添加的任何功能的文档。
- https://github.com/cookiecutter/cookiecutter/issues/1068
- https://github.com/cookiecutter/cookiecutter/issues/35
- https://github.com/cookiecutter/cookiecutter/issues/153
问题已经解决,但这并不意味着问题已经解决。
唯一的方法是使用后生成挂钩将文件从文件夹中移出并删除文件夹。
如果您在*NIX系统上,您可以使用以下简单脚本:
#!/bin/sh
mv * ..
rm -rfv ../{{ cookiecutter.project_name }}
其中cookiecutter.project_name
是您的模板文件夹。
除了前面的答案(应该在linux/mac上完美工作(之外,这里还有一个纯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)
并且CCD_ 4将需要具有以下行:
{
"use_current_directory": "y/n",
}
这应该适用于任何操作系统,并且只需要hooks/post_gen_project.py