Skip to content
This repository was archived by the owner on Jul 29, 2024. It is now read-only.

Commit b8feede

Browse files
Multiple Changes (docker image creation template, MIT license, cookiecutter prompts) (#5)
2 parents 09a7c78 + 077892f commit b8feede

File tree

6 files changed

+208
-0
lines changed

6 files changed

+208
-0
lines changed

src/PopulateCookiecutterPrompts.py

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# ----------------------------------------------------------------------
2+
# |
3+
# | Copyright (c) 2024 Scientific Software Engineering Center at Georgia Tech
4+
# | Distributed under the MIT License.
5+
# |
6+
# ----------------------------------------------------------------------
7+
"""Populates multiline cookiecutter.json __prompts__ values."""
8+
9+
import re
10+
import sys
11+
import textwrap
12+
13+
from pathlib import Path
14+
from typing import Match
15+
16+
import rtyaml
17+
18+
from dbrownell_Common import PathEx
19+
from dbrownell_Common import TextwrapEx
20+
21+
22+
# ----------------------------------------------------------------------
23+
# | Calculate Directories
24+
directories: list[Path] = []
25+
26+
for child in PathEx.EnsureDir(Path(__file__).parent / "PythonProjectBootstrapper").iterdir():
27+
if child.is_dir():
28+
directories.append(child)
29+
30+
31+
# ----------------------------------------------------------------------
32+
# | Process Content
33+
for directory in directories:
34+
# Read the yaml content
35+
yaml_filename = directory / "cookiecutter_prompts.yaml"
36+
if not yaml_filename.is_file():
37+
continue
38+
39+
with yaml_filename.open() as f:
40+
yaml_content = rtyaml.load(f)
41+
42+
# Read the json content
43+
json_filename = directory / "cookiecutter.json"
44+
assert json_filename.is_file(), json_filename
45+
46+
with json_filename.open() as f:
47+
json_content = f.read()
48+
49+
# Replace the content
50+
# ----------------------------------------------------------------------
51+
def Replace(
52+
match: Match,
53+
) -> str:
54+
return TextwrapEx.Indent(
55+
textwrap.dedent(
56+
"""\
57+
"__prompts__": {{
58+
{content}
59+
}}{trailing_comma}
60+
""",
61+
).format(
62+
content=TextwrapEx.Indent(
63+
",\n".join(
64+
'"{}": "{}"'.format(
65+
key,
66+
"\n\n{}{}".format(value, "\n\n" if "\n" in value else "")
67+
.replace("\n", "\\n")
68+
.replace('"', '\\"'),
69+
)
70+
for key, value in yaml_content.items()
71+
),
72+
4,
73+
),
74+
trailing_comma=match.group("trailing_comma") or "",
75+
),
76+
match.group("initial_whitespace"),
77+
)
78+
79+
# ----------------------------------------------------------------------
80+
81+
new_content = re.sub(
82+
r"""(?#
83+
initial whitespace )^(?P<initial_whitespace>[ \t]+)(?#
84+
begin section )[\"']__prompts__[\"']: {\r?\n(?#
85+
<content> ).+?(?#
86+
end section )(?P=initial_whitespace)}(?#
87+
trailing comma )(?P<trailing_comma>,)?\r?\n(?#
88+
)""",
89+
Replace,
90+
json_content,
91+
flags=re.MULTILINE | re.DOTALL,
92+
)
93+
94+
# Write the content (if necessary)
95+
if new_content != json_content:
96+
with json_filename.open("w") as f:
97+
f.write(new_content)
98+
99+
sys.stdout.write(f"New content has been written to '{json_filename}'.\n")
100+
else:
101+
sys.stdout.write(f"'{json_filename}' was not modified.\n")

src/PythonProjectBootstrapper/python_project/cookiecutter.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,19 @@
2323

2424
"__empty_dir": "",
2525

26+
"__prompts_warning__": "The values in the __prompts__ section were produced by running `../../PopulateCookiecutterPrompts.py` and will be overwritten the next time that script is run. To modify prompt values, make changes in `cookiecutter_prompts.yaml` and run that script.",
27+
2628
"__prompts__": {
29+
"name": "\n\nPlease enter your name.\n\nThis value will be used in:\n - The copyright header for source files\n - Metadata for the generated python package\n - Metadata for the generated python binary\n\n",
30+
"email": "\n\nPlease enter your email address.\n\nThis value will be used in:\n - Metadata for the generated python package\n - Metadata for the generated python binary\n\n",
31+
"project_description": "\n\nPlease enter a short description of your project (less than 100 characters).\n\nThis value will be used in:\n - Metadata for the generated python package\n - Metadata for the generated python binary\n\n",
32+
"license": "\n\nPlease enter the license you would like to use for your project. https://choosealicense.com/ is a\ngood resource that helps you choose the best license for your project.\n\nThis value will be used in:\n - Population of the License.txt file (or equivalent)\n - The copyright header for source files\n - Metadata for the generated python package\n - Metadata for the generated python binary\n - Metadata for the generated docker image (if applicable)\n\n",
33+
"gist_id": "\n\nPlease enter the GitHub gist id for use with this project.\n\nGitHub defines a gist as \"a simple way to share snippets and pastes with others.\" The generated\npython project will use a gist to store information dynamically generated during the build (for\nexample code coverage information) that can be retrieved at a later time (for example, to display\na code coverage badge in the project's README.md file).\n\nTo create a gist:\n 1. Go to https://gist.github.com/\n 2. Enter the following values in their respective fields:\n\n Gist description...: Gist used by GitHub Action workflows to store and retrieve dynamic information (oftentimes used to create and display badges).\n Filename including extension...: README.md\n File contents: Gist used by GitHub Action workflows to store and retrieve dynamic information (oftentimes used to create and display badges).\n\n 3. Click the \"Create secret gist\" button\n 4. Copy the gist id (this will be the hex string at the end of the url associated with the gist\n that was just created). It will look something like:\n\n https://gist.github.com/<github username>/4c10281ff1abc26cafcb9a5f9a8a443e\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n This is the gist id\n\n",
34+
"github_url": "\n\nPlease enter the GitHub URL. The default value should be used unless you are running on an GitHub\nEnterprise instance.\n\n https://github.com/username/projectname\n ^^^^^^^^^^^^^^^^^^\n This is the GitHub URL\n\n",
35+
"github_username": "\n\nPlease enter your GitHub username.\n\n https://github.com/username/projectname\n ^^^^^^^^\n This is the GitHub username\n\n",
36+
"github_project_name": "\n\nPlease enter the name of your GitHub project that corresponds to the output directory.\n\n https://github.com/username/projectname\n ^^^^^^^^^^^\n This is the GitHub project name\n\n",
37+
"pypi_project_name": "\n\nPlease enter the name of your project as it will appear on PyPI (https://pypi.org). This\nname cannot be associated with any other project on PyPI.\n\n",
38+
"create_docker_image": "\n\nWould you like the GitHub Action workflows to create docker images of the development environment?\nThese images can be used to produce exact results across different commits made to the repository\nover time (which is especially valuable when writing scientific software).\n\n"
2739
},
2840

2941
"_extensions": ["local_extensions.pypi_string"]
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Values in this file will overwrite values in `cookiecutter.json` when `../../PopulateCookiecutterPrompts.py` is run.
2+
3+
name: |-
4+
Please enter your name.
5+
6+
This value will be used in:
7+
- The copyright header for source files
8+
- Metadata for the generated python package
9+
- Metadata for the generated python binary
10+
11+
email: |-
12+
Please enter your email address.
13+
14+
This value will be used in:
15+
- Metadata for the generated python package
16+
- Metadata for the generated python binary
17+
18+
project_description: |-
19+
Please enter a short description of your project (less than 100 characters).
20+
21+
This value will be used in:
22+
- Metadata for the generated python package
23+
- Metadata for the generated python binary
24+
25+
license: |-
26+
Please enter the license you would like to use for your project. https://choosealicense.com/ is a
27+
good resource that helps you choose the best license for your project.
28+
29+
This value will be used in:
30+
- Population of the License.txt file (or equivalent)
31+
- The copyright header for source files
32+
- Metadata for the generated python package
33+
- Metadata for the generated python binary
34+
- Metadata for the generated docker image (if applicable)
35+
36+
gist_id: |-
37+
Please enter the GitHub gist id for use with this project.
38+
39+
GitHub defines a gist as "a simple way to share snippets and pastes with others." The generated
40+
python project will use a gist to store information dynamically generated during the build (for
41+
example code coverage information) that can be retrieved at a later time (for example, to display
42+
a code coverage badge in the project's README.md file).
43+
44+
To create a gist:
45+
1. Go to https://gist.github.com/
46+
2. Enter the following values in their respective fields:
47+
48+
Gist description...: Gist used by GitHub Action workflows to store and retrieve dynamic information (oftentimes used to create and display badges).
49+
Filename including extension...: README.md
50+
File contents: Gist used by GitHub Action workflows to store and retrieve dynamic information (oftentimes used to create and display badges).
51+
52+
3. Click the "Create secret gist" button
53+
4. Copy the gist id (this will be the hex string at the end of the url associated with the gist
54+
that was just created). It will look something like:
55+
56+
https://gist.github.com/<github username>/4c10281ff1abc26cafcb9a5f9a8a443e
57+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
58+
This is the gist id
59+
60+
github_url: |-
61+
Please enter the GitHub URL. The default value should be used unless you are running on an GitHub
62+
Enterprise instance.
63+
64+
https://github.com/username/projectname
65+
^^^^^^^^^^^^^^^^^^
66+
This is the GitHub URL
67+
68+
github_username: |-
69+
Please enter your GitHub username.
70+
71+
https://github.com/username/projectname
72+
^^^^^^^^
73+
This is the GitHub username
74+
75+
github_project_name: |-
76+
Please enter the name of your GitHub project that corresponds to the output directory.
77+
78+
https://github.com/username/projectname
79+
^^^^^^^^^^^
80+
This is the GitHub project name
81+
82+
pypi_project_name: |-
83+
Please enter the name of your project as it will appear on PyPI (https://pypi.org). This
84+
name cannot be associated with any other project on PyPI.
85+
86+
create_docker_image: |-
87+
Would you like the GitHub Action workflows to create docker images of the development environment?
88+
These images can be used to produce exact results across different commits made to the repository
89+
over time (which is especially valuable when writing scientific software).

src/PythonProjectBootstrapper/python_project/hooks/pre_gen_project.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
# ----------------------------------------------------------------------
77
errors: list[str] = []
88

9+
# BugBug: Ensure that the dir has a .git directory
10+
911
# fmt: off
1012
if "{{ cookiecutter.name }}".startswith("<") and "{{ cookiecutter.name }}".endswith(">"):
1113
errors.append('name ("{{ cookiecutter.name }}")')

src/PythonProjectBootstrapper/python_project/{{ cookiecutter.__empty_dir }}/.github/workflows/standard.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ jobs:
187187
python_version: {% raw %}${{ matrix.python_version }}{% endraw %}
188188
name_suffix: {% raw %}-${{ matrix.python_version }}{% endraw %}
189189
bootstrap_args: ""
190+
docker_description: "{{ cookiecutter.pypi_project_name }} - {% raw %}${{ matrix.python_version }}{% endraw %}"
191+
push_image_as_package: true
190192
{% endif %}
191193

192194
# ----------------------------------------------------------------------

src/PythonProjectBootstrapper/python_project/{{ cookiecutter.__empty_dir }}/Licenses/MIT_LICENSE.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
MIT LICENSE
2+
13
Copyright (c) {% now 'utc', '%Y' %} {{ cookiecutter.name }}
24

35
Permission is hereby granted, free of charge, to any person obtaining a copy

0 commit comments

Comments
 (0)