Skip to content

Commit aef0dda

Browse files
committed
Merge branch 'main' into mmg/gh-pages-deploy-action
2 parents 84c2e61 + 5767f81 commit aef0dda

6 files changed

Lines changed: 86 additions & 73 deletions

File tree

.all-contributorsrc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,15 @@
310310
"a11y",
311311
"code"
312312
]
313+
},
314+
{
315+
"login": "jamesbriant",
316+
"name": "James Briant",
317+
"avatar_url": "https://avatars.githubusercontent.com/u/6298711?v=4",
318+
"profile": "http://james.briant.co.uk",
319+
"contributions": [
320+
"bug"
321+
]
313322
}
314323
]
315324
}

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ uv pip install -e ".[dev]"
108108
<td align="center" valign="top" width="14.28%"><a href="https://www.ucl.ac.uk/advanced-research-computing/advanced-research-computing-centre"><img src="https://avatars.githubusercontent.com/u/24316371?v=4?s=100" width="100px;" alt="Kimberly Meechan"/><br /><sub><b>Kimberly Meechan</b></sub></a><br /><a href="#bug-K-Meech" title="Bug reports">🐛</a> <a href="#a11y-K-Meech" title="Accessibility">️️️️♿️</a> <a href="#review-K-Meech" title="Reviewed Pull Requests">👀</a></td>
109109
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jamesprime"><img src="https://avatars.githubusercontent.com/u/17751241?v=4?s=100" width="100px;" alt="James Prime"/><br /><sub><b>James Prime</b></sub></a><br /><a href="#a11y-jamesprime" title="Accessibility">️️️️♿️</a> <a href="#ideas-jamesprime" title="Ideas, Planning, & Feedback">🤔</a></td>
110110
<td align="center" valign="top" width="14.28%"><a href="https://github.com/cuteshaun"><img src="https://avatars.githubusercontent.com/u/28014041?v=4?s=100" width="100px;" alt="Andrii Tsapko"/><br /><sub><b>Andrii Tsapko</b></sub></a><br /><a href="#a11y-cuteshaun" title="Accessibility">️️️️♿️</a> <a href="#code-cuteshaun" title="Code">💻</a></td>
111+
<td align="center" valign="top" width="14.28%"><a href="http://james.briant.co.uk"><img src="https://avatars.githubusercontent.com/u/6298711?v=4?s=100" width="100px;" alt="James Briant"/><br /><sub><b>James Briant</b></sub></a><br /><a href="#bug-jamesbriant" title="Bug reports">🐛</a></td>
111112
</tr>
112113
</tbody>
113114
</table>

hooks/post_gen_project.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def main(initialise_git_repository: str, deploy_docs_to_github_pages: str) -> in
6666
'-d "{{cookiecutter.project_short_description}}" '
6767
"--public "
6868
"-r origin "
69-
"--source {{cookiecutter.project_slug}}\n"
69+
"--source {{cookiecutter.project_slug}}\n",
7070
)
7171
except FileNotFoundError:
7272
# GitHub CLI isn't installed
@@ -78,7 +78,7 @@ def main(initialise_git_repository: str, deploy_docs_to_github_pages: str) -> in
7878
"https://docs.github.com/en/get-started/quickstart/create-a-repo.\n\n"
7979
"Then run:\n\n"
8080
"git remote add origin [email protected]:"
81-
"{{cookiecutter.__repo_name}}.git\n"
81+
"{{cookiecutter.__repo_name}}.git\n",
8282
)
8383
except subprocess.CalledProcessError as e:
8484
# some other error
@@ -91,7 +91,7 @@ def main(initialise_git_repository: str, deploy_docs_to_github_pages: str) -> in
9191
"You will need to configure the repository to deploy a GitHub pages site "
9292
"using GitHub Actions by going to\n\n"
9393
"{{cookiecutter.__repo_url}}/settings/pages\n\n"
94-
"and under 'Build and deployment' selecting 'GitHub Actions' for 'Source'."
94+
"and under 'Build and deployment' selecting 'GitHub Actions' for 'Source'.",
9595
)
9696

9797
return _EXIT_SUCCESS
@@ -102,5 +102,5 @@ def main(initialise_git_repository: str, deploy_docs_to_github_pages: str) -> in
102102
main(
103103
"{{ cookiecutter.initialise_git_repository }}",
104104
"{{ cookiecutter.deploy_docs_to_github_pages }}",
105-
)
105+
),
106106
)

tests/conftest.py

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,50 @@
77
import pytest
88

99

10+
@pytest.fixture(scope="function") # noqa: PT003
11+
def default_config() -> dict[str, str]:
12+
"""
13+
Get the minimal default configuration for cutting a cookie in tests.
14+
15+
This is used if `generate_package` is called without arguments.
16+
"""
17+
return {
18+
"github_owner": "test-user",
19+
"project_short_description": "description",
20+
"project_name": "Cookiecutter Test",
21+
"project_slug": "cookiecutter-test",
22+
}
23+
24+
25+
@pytest.fixture(scope="function") # noqa: PT003
26+
def default_config_with(default_config: dict[str, str]) -> typing.Callable:
27+
"""Extend or modify the default configuration with one additional value."""
28+
29+
def _wrapped_with(**kwargs: str) -> dict[str, str]:
30+
return default_config | kwargs
31+
32+
return _wrapped_with
33+
34+
1035
def _generate_package(
1136
config: dict[str, str], path: pathlib.Path
12-
) -> subprocess.CompletedProcess[str]:
37+
) -> tuple[subprocess.CompletedProcess[str], pathlib.Path]:
1338
"""
1439
Generate a project from the cookiecutter template.
1540
16-
Arguments:
17-
---------
18-
config: dict
41+
Parameters
42+
----------
43+
config
1944
A dictionary with values for the cookiecutter template,
2045
as defined in the cookiecutter.json
21-
path: Path
46+
path
2247
Directory to create package in.
2348
49+
Returns
50+
-------
51+
subprocess.CompletedProcess, pathlib.Path
52+
The result of the cookiecutter command and the path to the generated package.
53+
2454
"""
2555
args = [f"{key}={val}" for key, val in config.items()]
2656
cmd = ["cookiecutter", ".", "--no-input", "--output-dir", f"{path}"]
@@ -30,10 +60,18 @@ def _generate_package(
3060
shell=False,
3161
capture_output=True,
3262
text=True,
33-
)
63+
), path / config["project_slug"]
3464

3565

3666
@pytest.fixture
37-
def generate_package() -> typing.Callable:
67+
def generate_package(
68+
default_config: dict[str, str], tmp_path: pathlib.Path
69+
) -> typing.Callable:
3870
"""Generate project from cookiecutter template."""
39-
return _generate_package
71+
72+
def _wrapped_with_tmp_path(
73+
config: dict[str, str] = default_config,
74+
) -> tuple[subprocess.CompletedProcess, pathlib.Path]:
75+
return _generate_package(config, tmp_path)
76+
77+
return _wrapped_with_tmp_path

tests/test_git_init.py

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,21 @@
11
"""Checks that the git repo initialisation works."""
22

3-
import pathlib
43
import subprocess
54
import typing
65

76
import pytest
87

98

10-
@pytest.mark.parametrize("initialise_git_repository", [True, False])
9+
@pytest.mark.parametrize("init", [True, False])
1110
def test_initialisation_of_git_repo(
12-
initialise_git_repository: bool, # noqa: FBT001
11+
init: bool, # noqa: FBT001
12+
default_config_with: typing.Callable,
1313
generate_package: typing.Callable,
14-
tmp_path: pathlib.Path,
1514
) -> None:
1615
"""Checks to see if git was correctly initialised if desired."""
17-
test_config = {
18-
"github_owner": "test-user",
19-
"project_short_description": "description",
20-
"project_name": "Cookiecutter Test",
21-
"initialise_git_repository": initialise_git_repository,
22-
}
2316
# Run cookiecutter with initialise_git_repository
24-
result = generate_package(config=test_config, path=tmp_path)
25-
26-
test_project_dir = tmp_path / "cookiecutter-test"
17+
config = default_config_with(initialise_git_repository=str(init))
18+
result, test_project_dir = generate_package(config=config)
2719

2820
# check if git is initialised
2921
git_status = subprocess.run( # noqa: S603
@@ -37,7 +29,7 @@ def test_initialisation_of_git_repo(
3729
text=True,
3830
)
3931

40-
if not initialise_git_repository:
32+
if not init:
4133
# should not have found git
4234
assert "fatal: not a git repository" in git_status.stderr
4335
return # nothing more to test
@@ -57,9 +49,9 @@ def test_initialisation_of_git_repo(
5749
)
5850
assert (
5951
"GitHub CLI detected, you can create a repo with the following:\n\n"
60-
f"gh repo create {test_config['github_owner']}/"
52+
f"gh repo create {config['github_owner']}/"
6153
f"cookiecutter-test -d "
62-
f'"{test_config["project_short_description"]}" --public -r '
54+
f'"{config["project_short_description"]}" --public -r '
6355
f"origin --source cookiecutter-test" in result.stdout
6456
)
6557
except FileNotFoundError:
@@ -69,11 +61,11 @@ def test_initialisation_of_git_repo(
6961
assert (
7062
"You now have a local git repository. To sync this to GitHub you "
7163
"need to create an empty GitHub repo with the name "
72-
f"{test_config['github_owner']}/"
64+
f"{config['github_owner']}/"
7365
f"cookiecutter-test - DO NOT SELECT ANY "
7466
"OTHER OPTION.\n\nSee this link for more detail "
7567
"https://docs.github.com/en/get-started/quickstart/create-a-repo"
7668
".\n\nThen run:\n\ngit remote add origin [email protected]:"
77-
f"{test_config['github_owner']}/"
69+
f"{config['github_owner']}/"
7870
f"cookiecutter-test.git" in result.stdout
7971
)

tests/test_package_generation.py

Lines changed: 16 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -36,26 +36,19 @@ def get_all_files_folders(root_path: pathlib.Path) -> set[pathlib.Path]:
3636

3737

3838
def test_package_generation(
39-
tmp_path: pathlib.Path,
39+
default_config_with: typing.Callable,
4040
generate_package: typing.Callable,
4141
) -> None:
4242
"""Test package generation."""
43-
test_config = {
44-
"github_owner": "test-user",
45-
"project_short_description": "description",
46-
"project_name": "Cookiecutter Test",
47-
# Not having a git repo makes it easier to check in/out reference
48-
# data files to the main python-tooling git repository
49-
"initialise_git_repository": False,
50-
}
51-
generate_package(config=test_config, path=tmp_path)
43+
# Not having a git repo makes it easier to check in/out reference
44+
# data files to the main python-tooling git repository
45+
config = default_config_with(initialise_git_repository="False")
46+
_, test_project_dir = generate_package(config=config)
5247

5348
expected_package_dir = (
5449
pathlib.Path(__file__).parent / "data" / "test_package_generation"
5550
)
56-
# Check project directory exists
57-
test_project_dir = tmp_path / "cookiecutter-test"
58-
assert test_project_dir.exists()
51+
assert test_project_dir.exists(), "Project directory does not exist."
5952

6053
actual_files = get_all_files_folders(test_project_dir)
6154
expected_files = get_all_files_folders(expected_package_dir)
@@ -78,7 +71,7 @@ def test_package_generation(
7871
f2.readlines(),
7972
fromfile=str(actual_file),
8073
tofile=str(expected_file),
81-
)
74+
),
8275
)
8376

8477
if diff:
@@ -94,18 +87,11 @@ def test_package_generation(
9487

9588

9689
def test_pip_installable(
97-
tmp_path: pathlib.Path,
9890
venv: pytest_venv.VirtualEnvironment,
9991
generate_package: typing.Callable,
10092
) -> None:
10193
"""Test generated package is pip installable."""
102-
test_config = {
103-
"github_owner": "test-user",
104-
"project_short_description": "description",
105-
"project_name": "Cookiecutter Test",
106-
}
107-
generate_package(config=test_config, path=tmp_path)
108-
test_project_dir = tmp_path / "cookiecutter-test"
94+
_, test_project_dir = generate_package()
10995
# Try to install package in virtual environment with pip
11096
pipinstall = subprocess.run( # noqa: S603
11197
[
@@ -124,46 +110,33 @@ def test_pip_installable(
124110
)
125111

126112

127-
@pytest.mark.parametrize("funder", ["", "STFC"])
113+
@pytest.mark.parametrize("funder", ["", "STFC", "UKRI", "Wellcome Trust"])
128114
def test_optional_funder(
129-
tmp_path: pathlib.Path, generate_package: typing.Callable, funder: str
115+
funder: str,
116+
default_config_with: typing.Callable,
117+
generate_package: typing.Callable,
130118
) -> None:
131119
"""Test specifying funder or not in package generation."""
132-
config = {
133-
"github_owner": "test-user",
134-
"project_short_description": "description",
135-
"project_name": "Cookiecutter Test",
136-
"funder": funder,
137-
}
138-
139-
generate_package(config, tmp_path)
120+
config = default_config_with(funder=funder)
121+
_, test_project_dir = generate_package(config)
140122

141-
test_project_dir = tmp_path / "cookiecutter-test"
142123
with (test_project_dir / "README.md").open() as f:
143124
readme_text = "".join(f.readlines())
144125

145126
if funder == "":
146127
assert "## Acknowledgements" not in readme_text
147128
else:
148129
assert (
149-
f"## Acknowledgements\n\nThis work was funded by {config['funder']}."
150-
in readme_text
130+
f"## Acknowledgements\n\nThis work was funded by {funder}." in readme_text
151131
), readme_text
152132

153133

154134
def test_docs_build(
155-
tmp_path: pathlib.Path,
156135
venv: pytest_venv.VirtualEnvironment,
157136
generate_package: typing.Callable,
158137
) -> None:
159138
"""Test documentation build from package created from template."""
160-
config = {
161-
"github_owner": "test-user",
162-
"project_short_description": "description",
163-
"project_name": "Cookiecutter Test",
164-
}
165-
generate_package(config, tmp_path)
166-
test_project_dir = tmp_path / "cookiecutter-test"
139+
_, test_project_dir = generate_package()
167140
venv.install("tox")
168141
tox_docs_process = subprocess.run( # noqa: S603
169142
[

0 commit comments

Comments
 (0)