11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120 | def parse_context(config_file: str):
"""Render Context on demand, using cookiecutter.json and optional config file."""
from pathlib import Path
my_dir = Path(__file__).parent.absolute()
# use whatever way cookiecutter uses to render the cookiecutter.json
# cookie uses Jinja2
from jinja2 import Environment, FileSystemLoader
# render file
env = Environment(
loader=FileSystemLoader(str(my_dir / '..')),
extensions=['jinja2_time.TimeExtension'], # shipped with cookiecutter 1.7
# Issue: [B701:jinja2_autoescape_false] By default, jinja2 sets autoescape to False. Consider using autoescape=True or use the select_autoescape function to mitigate XSS vulnerabilities.
# Severity: High Confidence: High
# CWE: CWE-94 (https://cwe.mitre.org/data/definitions/94.html)
# More Info: https://bandit.readthedocs.io/en/1.7.7/plugins/b701_jinja2_autoescape_false.html
autoescape=True,
)
template = env.get_template('cookiecutter.json')
rendered = template.render({'cookiecutter': {}})
assert isinstance(rendered, str)
cook_json: t.Mapping[str, t.Any] = json.loads(rendered)
# in cookiecutter 1.7, a 'choice' variable is a json array
choices = {k: v for k, v in cook_json.items() if isinstance(v, list)}
if config_file:
from .user_config_proxy import get_user_config
data = get_user_config(config_file, default_config=False)
# data = load_yaml(config_file)
user_default_context = data['default_context']
_interpreters: t.Mapping[str, t.List[str]] = user_default_context.get(
'interpreters', '{}'
)
if isinstance(_interpreters, str):
logger.warning(
"Interpreters expected to be loaded in a python dict already. Got a string instead."
)
logger.info("Converting interpreters %s to a python dict", _interpreters)
_interpreters = json.loads(_interpreters)
user_interpreters = _interpreters
else:
user_default_context = {}
user_interpreters = cook_json['interpreters']
context_defaults = dict(
cook_json,
**{k: v for k, v in user_default_context.items()},
**{k: v[0] for k, v in choices.items() if k not in user_default_context},
)
from cookiecutter_python.handle.interactive_cli_pipeline import (
InteractiveDialogsPipeline,
)
pipe = InteractiveDialogsPipeline()
# assert choices['rtd_python_version'] == [], f"DEBUG: {choices['rtd_python_version']}"
res = pipe.process(
[
{
"project_name": context_defaults['project_name'],
"project_type": {
'default': context_defaults['project_type'],
'choices': choices['project_type'],
},
"full_name": context_defaults['full_name'],
"author_email": context_defaults['author_email'],
"github_username": context_defaults['github_username'],
"project_short_description": context_defaults['project_short_description'],
# "release_date": context_defaults['release_date'],
# "year": context_defaults['year'],
"version": context_defaults['version'],
"initialize_git_repo": {
'default': context_defaults['initialize_git_repo'],
'choices': choices['initialize_git_repo'],
},
"supported-interpreters": {
# 'default': context_defaults['initialize_git_repo'],
'choices': [
(choice, True)
for choice in user_interpreters.get(
'supported-interpreters',
["3.6", "3.7", "3.8", "3.9", "3.10", "3.11"],
)
],
},
"docs_builder": {
'default': context_defaults['docs_builder'],
'choices': choices['docs_builder'],
},
"rtd_python_version": {
'default': context_defaults['rtd_python_version'],
'choices': choices['rtd_python_version'],
},
"cicd": {
'default': context_defaults['cicd'],
'choices': choices['cicd'],
},
}
]
)
return res
|