Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Track number of Sphinx build warnings #45

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
f4db75c
Track number of Sphinx build warnings
m-aciek Feb 1, 2025
84e0a79
Rename Sphinx outputdir, build is used to copy files for GH pages copy
m-aciek Feb 1, 2025
0761872
Copy over only PO files to avoid warnings on extra files
m-aciek Feb 1, 2025
e722116
Use locale format for Sphinx
m-aciek Feb 1, 2025
bd676c0
Don't override language builds
m-aciek Feb 1, 2025
add0365
Drop fresh-env flag from Sphinx build
m-aciek Feb 1, 2025
f97278d
Run update on main once an hour
m-aciek Feb 1, 2025
064faa2
Parallelize the main loop
m-aciek Feb 2, 2025
82d6f03
Rename issues to warnings
m-aciek Feb 2, 2025
6f565fe
Ignore generated warnings files
m-aciek Feb 2, 2025
562cc3d
Rename issues to warnings in style.css
m-aciek Feb 2, 2025
77acb8b
Skip build for zero completion
m-aciek Feb 2, 2025
b99fd95
Switch to ProcessPoolExecutor
m-aciek Feb 3, 2025
d515419
Use HTML base tag in head to specify default anchors target
m-aciek Feb 3, 2025
8d53770
Link to warnings if build triggered
m-aciek Feb 3, 2025
22f29ae
Merge branch 'main' into build-warnings
m-aciek Feb 4, 2025
c35c4b0
Fix merge
m-aciek Feb 5, 2025
f2fbac0
Merge branch 'main' into build-warnings
m-aciek Feb 5, 2025
03bf88d
Merge branch 'main' into build-warnings
m-aciek Feb 7, 2025
1b44f03
Remove unused import
m-aciek Feb 7, 2025
532b331
Separate pool managers for processes
m-aciek Feb 7, 2025
7d95f0b
Separate pool managers for processes
m-aciek Feb 7, 2025
caef691
Fix warnings link
m-aciek Feb 7, 2025
358ff67
Count warnings by keywords, not by lines
m-aciek Feb 10, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/update.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
on:
schedule:
- cron: '*/30 * * * *'
- cron: '17 * * * *'
push:
branches:
- 'main'
Expand All @@ -20,7 +20,7 @@ jobs:
- uses: actions/checkout@v4
- run: sudo apt-get install -y gettext
- run: uv run generate.py # generates "index.html"
- run: mkdir -p build && cp index.* style.css build
- run: mkdir -p build && cp index.* style.css warnings* build
- name: Deploy 🚀
if: github.event_name != 'pull_request'
uses: JamesIves/github-pages-deploy-action@v4
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
index.html
warnings-*.txt
37 changes: 37 additions & 0 deletions build_warnings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from pathlib import Path
from re import findall
from shutil import copyfile

import sphinx.cmd.build


def number(clones_dir: str, repo: str, language_code: str) -> int:
language_part, *locale = language_code.split('-')
if locale:
lang_with_locale = f'{language_part}_{locale[0].upper()}'
else:
lang_with_locale = language_part
locale_dir = Path(clones_dir, f'cpython/Doc/locales/{lang_with_locale}/LC_MESSAGES')
locale_dir.mkdir(parents=True)
for po_file in Path(clones_dir, repo).rglob('*.po'):
relative_path = po_file.relative_to(Path(clones_dir, repo))
target_file = locale_dir / relative_path
target_file.parent.mkdir(parents=True, exist_ok=True)
copyfile(po_file, target_file)
sphinx.cmd.build.main(
(
'--builder',
'html',
'--jobs',
'auto',
'--define',
f'language={language_code}',
'--verbose',
'--warning-file',
warning_file := f'{clones_dir}/warnings-{language_code}.txt',
f'{clones_dir}/cpython/Doc', # sourcedir
f'./sphinxbuild/{language_code}', # outputdir
)
)
copyfile(warning_file, f'warnings-{language_code}.txt')
return len(findall('ERROR|WARNING', Path(warning_file).read_text()))
24 changes: 16 additions & 8 deletions generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
# "jinja2",
# "requests",
# "docutils",
# "sphinx",
# "python-docs-theme",
# ]
# ///
import json
Expand All @@ -23,11 +25,12 @@
from jinja2 import Template
from urllib3 import PoolManager

import contribute
import build_warnings
import build_status
import contribute
from visitors import get_number_of_visitors
from completion import branches_from_devguide, get_completion, TranslatorsData
from repositories import get_languages_and_repos, Language
from repositories import Language, get_languages_and_repos

generation_time = datetime.now(timezone.utc)

Expand All @@ -48,15 +51,13 @@ def get_completion_progress() -> Iterator['LanguageProjectData']:
)
subprocess.run(['make', '-C', cpython_dir / 'Doc', 'venv'], check=True)
subprocess.run(['make', '-C', cpython_dir / 'Doc', 'gettext'], check=True)
languages_built = dict(build_status.get_languages(http := PoolManager()))

with concurrent.futures.ThreadPoolExecutor() as executor:
languages_built = dict(build_status.get_languages(PoolManager()))
with concurrent.futures.ProcessPoolExecutor() as executor:
return executor.map(
get_project_data,
*zip(*get_languages_and_repos(devguide_dir)),
itertools.repeat(languages_built),
itertools.repeat(clones_dir),
itertools.repeat(http),
)


Expand All @@ -65,16 +66,21 @@ def get_project_data(
repo: str | None,
languages_built: dict[str, bool],
clones_dir: str,
http: PoolManager,
) -> 'LanguageProjectData':
built = language.code in languages_built
if repo:
completion, translators_data, branch = get_completion(clones_dir, repo)
visitors_num = get_number_of_visitors(language.code, http) if built else 0
visitors_num = (
get_number_of_visitors(language.code, PoolManager()) if built else 0
)
warnings = (
build_warnings.number(clones_dir, repo, language.code) if completion else 0
)
else:
completion = 0.0
translators_data = TranslatorsData(0, False)
visitors_num = 0
warnings = 0
branch = None
return LanguageProjectData(
language,
Expand All @@ -83,6 +89,7 @@ def get_project_data(
completion,
translators_data,
visitors_num,
warnings,
built,
in_switcher=languages_built.get(language.code),
uses_platform=language.code in contribute.pulling_from_transifex,
Expand All @@ -98,6 +105,7 @@ class LanguageProjectData:
completion: float
translators: TranslatorsData
visitors: int
warnings: int
built: bool
in_switcher: bool | None
uses_platform: bool
Expand Down
2 changes: 1 addition & 1 deletion style.css
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ th {
.progress-bar.low + .progress-bar-outer-label {
display: inline-block;
}
td[data-label="visitors"], td[data-label="translators"] {
td[data-label="visitors"], td[data-label="translators"], td[data-label="warnings"] {
text-align: right;
}
td[data-label="completion"] {
Expand Down
20 changes: 13 additions & 7 deletions template.html.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<title>Python Docs Translation Dashboard</title>
<link rel="stylesheet" href="style.css">
<meta charset="UTF-8">
<base target="_blank">
</head>
<body>
<h1>Python Docs Translation Dashboard</h1>
Expand All @@ -12,8 +13,9 @@
<th>language</th>
<th>contribute</th>
<th>build</th>
<th>visitors*</th>
<th>visitors¹</th>
<th>translators</th>
<th>warnings²</th>
<th>completion</th>
</tr>
</thead>
Expand All @@ -22,31 +24,34 @@
<tr>
<td data-label="language">{{ project.language.name }} ({{ project.language.code }})</td>
<td data-label="contribute">
{% if project.contribution_link %}<a href="{{ project.contribution_link }}" target="_blank">{% endif %}
{% if project.contribution_link %}<a href="{{ project.contribution_link }}">{% endif %}
{% if project.uses_platform %}platform{% else %}repository{% endif %}
{% if project.contribution_link %}</a>{% endif %}
</td>
<td data-label="build">
{% if project.built %}
<a href="https://docs.python.org/{{ project.language.code }}/" target="_blank">✓{% if project.in_switcher %} in switcher{% endif %}</a>
<a href="https://docs.python.org/{{ project.language.code }}/">✓{% if project.in_switcher %} in switcher{% endif %}</a>
{% else %}
{% endif %}
</td>
<td data-label="visitors">
{% if project.built %}
<a href="https://plausible.io/docs.python.org?filters=((contains,page,(/{{ project.language.code }}/)))" target="_blank">
<a href="https://plausible.io/docs.python.org?filters=((contains,page,(/{{ project.language.code }}/)))">
{{ '{:,}'.format(project.visitors) }}
</a>
{% else %}
{{ '{:,}'.format(project.visitors) }}
{% endif %}
</td>
<td data-label="translators">
{% if project.translators.link %}<a href="{{ project.translators.link }}" target="_blank">{% endif %}
{% if project.translators.link %}<a href="{{ project.translators.link }}">{% endif %}
{{ project.translators.number }}
{% if project.translators.link %}</a>{% endif %}
</td>
<td data-label="warnings">
{% if project.completion %}<a href="warnings-{{ project.language.code }}.txt">{{ project.warnings }}</a>{% else %}{{ project.warnings }}{% endif %}
</td>
<td data-label="completion">
<div class="progress-bar" style="width: {{ project.completion }}%;">{{ "{:.2f}".format(project.completion) }}%</div>
<div class="progress-bar-outer-label">{{ "{:.2f}".format(project.completion) }}%</div>
Expand All @@ -55,8 +60,9 @@
{% endfor %}
</tbody>
</table>
<p>* sum of <a href="https://plausible.io/data-policy#how-we-count-unique-users-without-cookies" target="_blank">daily unique visitors</a> since 8 June 2024</p>
<p>For more information about translations, see the <a href="https://devguide.python.org/documentation/translating/" target="_blank">Python Developer’s Guide</a>.</p>
<p>¹ sum of <a href="https://plausible.io/data-policy#how-we-count-unique-users-without-cookies">daily unique visitors</a> since 8 June 2024</p>
<p>² number of Sphinx build process warnings</p>
<p>For more information about translations, see the <a href="https://devguide.python.org/documentation/translating/">Python Developer’s Guide</a>.</p>
<p>Last updated at {{ generation_time.strftime('%A, %-d %B %Y, %-H:%M:%S %Z') }} (in {{ duration // 60 }}:{{ "{:02}".format(duration % 60) }} minutes).</p>
</body>
<script>
Expand Down
Loading