11"""Main functions for controlling the template creation."""
22from pathlib import Path
3+ from shutil import which
34from typing import Any , Dict
45
56from cookiecutter .main import cookiecutter
67
78from .config import CookiecutterConfig , CookiecutterJson
8- from .utils import TempDir , copy_template
9+ from .utils import TempDir , copy_template , run_cmd
10+
11+
12+ def check_prerequisites ():
13+ needed = ["git" , "python" , "pip" , "poetry" ]
14+ for prg in needed :
15+ if not which (prg ):
16+ print (f"Program '{ prg } ' was not found in your environment, cannot proceed!" )
17+ exit (1 )
18+
19+
20+ def strip_yaml_header (file_contents : str ):
21+ """Given text file contents, remove YAML header bounded by '---' lines."""
22+ content = file_contents .splitlines ()
23+ startidx = 1
24+ if content and content [0 ] == "---" :
25+ startidx += 1
26+ while not content [startidx - 1 ].startswith ("---" ):
27+ startidx += 1
28+ return "\n " .join (content [startidx :])
29+
30+
31+ def create_gl_issue_template_from_gh (proj_root : Path ):
32+ """Given project path, create GitLab issue templates from GitHub ones."""
33+ gh_templates = proj_root / ".github" / "ISSUE_TEMPLATE"
34+ gl_templates = proj_root / ".gitlab" / "issue_templates"
35+
36+ gl_templates .mkdir (parents = True , exist_ok = True )
37+ for file in gh_templates .glob ("*" ):
38+ with open (gl_templates / file .name , "w" ) as f :
39+ f .write (strip_yaml_header (open (file ).read ()))
40+
41+
42+ def remove_unneeded_code (proj_root : Path , conf : CookiecutterConfig ):
43+ """Remove code examples the user did not wish to have in the project."""
44+ pkg = conf .fair_python_cookiecutter .project_package ()
45+ to_remove = []
46+ if not conf .fair_python_cookiecutter .init_cli :
47+ to_remove += [
48+ (proj_root / "src" / pkg / "cli.py" ),
49+ (proj_root / "tests" / "test_cli.py" ),
50+ ]
51+ if not conf .fair_python_cookiecutter .init_api :
52+ to_remove += [
53+ (proj_root / "src" / pkg / "api.py" ),
54+ (proj_root / "tests" / "test_api.py" ),
55+ ]
56+ for file in to_remove :
57+ if file .is_file ():
58+ file .unlink ()
59+
60+
61+ def download_licenses (proj_root : Path , conf : CookiecutterConfig ):
62+ """Download all needed licenses and create main LICENSE file."""
63+ # only install reuse/pipx if it is not found
64+ reuse_cmd = "reuse --suppress-deprecation download --all"
65+ if not which ("reuse" ):
66+ reuse_cmd = "pipx run " + reuse_cmd
67+ if not which ("pipx" ):
68+ run_cmd ("poetry run pip install pipx" , cwd = proj_root )
69+ reuse_cmd = "poetry run " + reuse_cmd
70+ # download licenses
71+ print (reuse_cmd , "root:" , proj_root )
72+ run_cmd (reuse_cmd , cwd = proj_root )
73+ # copy main license over from resulting licenses directory
74+ license_name = conf .fair_python_cookiecutter .project_license
75+ license = Path (proj_root ) / "LICENSE"
76+ license .write_text ((proj_root / "LICENSES" / f"{ license_name } .txt" ).read_text ())
77+
78+
79+ def finalize_repository (proj_root : Path , conf : CookiecutterConfig ):
80+ """Finalize instantiated repository based on configuration."""
81+ # remove unneeded and create needed files
82+ create_gl_issue_template_from_gh (proj_root )
83+ remove_unneeded_code (proj_root , conf )
84+ download_licenses (proj_root , conf )
985
1086
1187def create_repository (
@@ -19,6 +95,7 @@ def create_repository(
1995 cc_json = CookiecutterJson .from_config (conf )
2096 cc_args = cc_args or {}
2197
98+ check_prerequisites ()
2299 with TempDir (keep = keep_on_fail ) as tmp_root :
23100 copy_template (tmp_root , cookiecutter_json = cc_json )
24101 cookiecutter (
@@ -30,4 +107,6 @@ def create_repository(
30107 ** cc_args ,
31108 )
32109 repo_dir = output_dir / cc_json .project_slug
110+ finalize_repository (repo_dir , conf )
111+
33112 return repo_dir
0 commit comments