Skip to content

Commit 11fc0a8

Browse files
authored
Custom templating solution (#5)
Template analysis notebook to apply to other projects.
1 parent 1bf6291 commit 11fc0a8

7 files changed

Lines changed: 86 additions & 35 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ __pycache__/*
44
*.egg-info
55
_data/*
66
site/_build/*
7+
site/_generated/*
78
site/content/_generated/*
89
# Ignore text version of issues table
910
top_issues_table.md

site/Makefile

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,36 @@ BUILDDIR = _build
1212
help:
1313
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
1414

15-
.PHONY: help Makefile
15+
_generated/numpy.md: analysis_template.md
16+
python tools/generate_from_template.py numpy
1617

17-
# Catch-all target: route all unknown targets to Sphinx using the new
18-
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19-
%: Makefile
20-
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
18+
_generated/scipy.md: analysis_template.md
19+
python tools/generate_from_template.py scipy
20+
21+
_generated/matplotlib.md: analysis_template.md
22+
python tools/generate_from_template.py matplotlib
23+
24+
_generated/pandas.md: analysis_template.md
25+
python tools/generate_from_template.py pandas
26+
27+
_generated/scikit-learn.md: analysis_template.md
28+
python tools/generate_from_template.py scikit-learn
29+
30+
_generated/scikit-image.md: analysis_template.md
31+
python tools/generate_from_template.py scikit-image
32+
33+
_generated/networkx.md: analysis_template.md
34+
python tools/generate_from_template.py networkx
35+
36+
html : _generated/numpy.md _generated/scipy.md _generated/matplotlib.md _generated/pandas.md _generated/scikit-learn.md _generated/scikit-image.md _generated/networkx.md
37+
$(SPHINXBUILD) -b html "$(SOURCEDIR)" "$(BUILDDIR)/html" $(SPHINXOPTS) $(O)
38+
39+
clean:
40+
rm -rf _build _generated
41+
42+
.PHONY: help clean
43+
44+
## Catch-all target: route all unknown targets to Sphinx using the new
45+
## "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
46+
#%: Makefile
47+
# @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ kernelspec:
1111
name: python3
1212
---
1313

14-
# NumPy Report
14+
# `{{ project }}`
1515

1616
```{code-cell} ipython3
1717
---
@@ -48,7 +48,7 @@ output_notebook()
4848

4949
%TODO improve handling of datetimes (super annoying)
5050

51-
A snapshot of the development on the NumPy project.
51+
A snapshot of the development on the {{ project }} project.
5252

5353
## Issues
5454

@@ -59,10 +59,10 @@ A snapshot of the development on the NumPy project.
5959
query_date = np.datetime64("2020-01-01 00:00:00")
6060
6161
# Load data
62-
with open("../_data/issues.json", "r") as fh:
62+
with open("../../devstats-data/{{ project }}_issues.json", "r") as fh:
6363
issues = [item["node"] for item in json.loads(fh.read())]
6464
65-
glue("query_date", str(query_date.astype("M8[D]")))
65+
glue("{{ project }}_query_date", str(query_date.astype("M8[D]")))
6666
```
6767

6868
### New issues
@@ -86,17 +86,17 @@ new_issue_lifetime = np.array(
8686
],
8787
).astype("m8[h]") # in hours
8888
89-
glue("num_new_issues", len(newly_created))
90-
glue("num_new_issues_closed", percent_val(len(new_issues_closed), len(newly_created)))
91-
glue("new_issue_median_lifetime", f"{np.median(new_issue_lifetime)}")
89+
glue("{{ project }}_num_new_issues", len(newly_created))
90+
glue("{{ project }}_num_new_issues_closed", percent_val(len(new_issues_closed), len(newly_created)))
91+
glue("{{ project }}_new_issue_median_lifetime", f"{np.median(new_issue_lifetime)}")
9292
```
9393

94-
{glue:text}`num_new_issues` new issues have been opened since
95-
{glue:text}`query_date`, of which {glue:text}`num_new_issues_closed` have been
94+
{glue:text}`{{ project }}_num_new_issues` new issues have been opened since
95+
{glue:text}`{{ project }}_query_date`, of which {glue:text}`{{ project }}_num_new_issues_closed` have been
9696
closed.
9797

9898
The median lifetime of new issues that were created and closed in this period
99-
is {glue:text}`new_issue_median_lifetime`.
99+
is {glue:text}`{{ project }}_new_issue_median_lifetime`.
100100

101101
% TODO: replace with bokeh or some other live-plot
102102
% TODO: for any remaining static/mpl plots, set default params for things
@@ -185,19 +185,19 @@ num_issues_commented_by_cutoff = np.array(
185185
# usually sits before it's at least commented on
186186
187187
glue(
188-
"num_new_issues_responded",
188+
"{{ project }}_num_new_issues_responded",
189189
percent_val(len(commented_issues), len(newly_created_day_old))
190190
)
191191
192-
glue("new_issues_at_least_1_day_old", len(newly_created_day_old))
193-
glue("median_response_time", f"{median_time_til_first_response:1.0f}")
192+
glue("{{ project }}_new_issues_at_least_1_day_old", len(newly_created_day_old))
193+
glue("{{ project }}_median_response_time", f"{median_time_til_first_response:1.0f}")
194194
```
195195

196-
Of the {glue:text}`new_issues_at_least_1_day_old` issues that are at least 24
197-
hours old, {glue:text}`num_new_issues_responded` of them have been commented
196+
Of the {glue:text}`{{ project }}_new_issues_at_least_1_day_old` issues that are at least 24
197+
hours old, {glue:text}`{{ project }}_num_new_issues_responded` of them have been commented
198198
on.
199199
The median time until an issue is first responded to is
200-
{glue:text}`median_response_time` hours.
200+
{glue:text}`{{ project }}_median_response_time` hours.
201201

202202
```{code-cell} ipython3
203203
---
@@ -257,7 +257,7 @@ first_commenter_tab.sort_values(
257257
tags: [hide-input]
258258
---
259259
260-
with open("../_data/prs.json", "r") as fh:
260+
with open("../../devstats-data/{{ project }}_prs.json", "r") as fh:
261261
prs = [item["node"] for item in json.loads(fh.read())]
262262
263263
### Filters
@@ -413,9 +413,9 @@ show(p)
413413

414414
### Where contributions come from
415415

416-
There have been a total of {glue:text}`num_merged_prs_with_known_authors`
417-
merged PRs[^only_active] submitted by {glue:text}`num_unique_authors_of_merged_prs`
418-
unique authors. {glue:text}`num_flyby` of these are "fly-by" PRs, i.e.
416+
There have been a total of {glue:text}`{{ project }}_num_merged_prs_with_known_authors`
417+
merged PRs[^only_active] submitted by {glue:text}`{{ project }}_num_unique_authors_of_merged_prs`
418+
unique authors. {glue:text}`{{ project }}_num_flyby` of these are "fly-by" PRs, i.e.
419419
PRs from users who have contributed to the project once (to-date).
420420

421421

@@ -436,9 +436,9 @@ num_merged_prs_per_author = np.array(
436436
437437
num_flybys = np.sum(num_merged_prs_per_author == 1)
438438
439-
glue("num_merged_prs_with_known_authors", len(merged_prs))
440-
glue("num_unique_authors_of_merged_prs", len(contributions_by_author))
441-
glue("num_flyby", percent_val(num_flybys, len(num_merged_prs_per_author)))
439+
glue("{{ project }}_num_merged_prs_with_known_authors", len(merged_prs))
440+
glue("{{ project }}_num_unique_authors_of_merged_prs", len(contributions_by_author))
441+
glue("{{ project }}_num_flyby", percent_val(num_flybys, len(num_merged_prs_per_author)))
442442
```
443443

444444
```{code-cell} ipython3
@@ -477,7 +477,7 @@ described as:
477477
478478
For this analysis, we will consider merged PRs as the metric for contribution.
479479
Considering all merged PRs over the lifetime of the project, the pony factor
480-
is: {glue:text}`pony_factor`.
480+
is: {glue:text}`{{ project }}_pony_factor`.
481481

482482
% TODO: pandas-ify to improve sorting
483483

@@ -510,7 +510,7 @@ ax.hlines(
510510
)
511511
ax.legend();
512512
513-
glue("pony_factor", pony_factor)
513+
glue("{{ project }}_pony_factor", pony_factor)
514514
```
515515

516516
% TODO: Add:

site/conf.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@
3737
# List of patterns, relative to source directory, that match files and
3838
# directories to ignore when looking for source files.
3939
# This pattern also affects html_static_path and html_extra_path.
40-
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
40+
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', "analysis_template.md"]
41+
execution_excludepatterns = ["analysis_template.md"]
4142

4243

4344
# -- Options for HTML output -------------------------------------------------

site/index.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@ This website tracks the recent development history of the Scientific Python
55
ecosystem.
66

77
```{toctree}
8-
---
9-
maxdepth: 1
10-
---
8+
:maxdepth: 1
9+
:hidden: true
1110
12-
numpy_timeseries
11+
project_reports
1312
```

site/project_reports.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Project Reports
2+
===============
3+
4+
```{toctree}
5+
:glob:
6+
:maxdepth: 1
7+
8+
_generated/*
9+
```
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import sys
2+
import os
3+
4+
if len(sys.argv) != 2:
5+
raise ValueError("CLI usage: python generate_from_template.py <project_name>")
6+
7+
project = sys.argv[1]
8+
9+
os.makedirs("_generated", exist_ok=True)
10+
11+
with open("analysis_template.md", "r") as fh:
12+
template = fh.read()
13+
with open(f"_generated/{project}.md", "w") as fh:
14+
fh.write(template.replace("{{ project }}", project))

0 commit comments

Comments
 (0)