chore: use cog for quick README updates (#2428)
* chore: use cog for quick README updates Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com> * refactor: rename scripts Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com> --------- Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
This commit is contained in:
+6
-11
@@ -62,20 +62,15 @@ repos:
|
|||||||
name: Disallow improper capitalization
|
name: Disallow improper capitalization
|
||||||
language: pygrep
|
language: pygrep
|
||||||
entry: PyBind|Numpy|Cmake|Github|PyTest
|
entry: PyBind|Numpy|Cmake|Github|PyTest
|
||||||
types:
|
types: [markdown]
|
||||||
- markdown
|
|
||||||
exclude: ^docs/working-examples\.md$ # Autogenerated
|
exclude: ^docs/working-examples\.md$ # Autogenerated
|
||||||
- id: update-readme-changelog
|
- id: cog
|
||||||
name: Update README changelog
|
name: Cog the README
|
||||||
language: python
|
language: python
|
||||||
entry: bin/update_readme_changelog.py
|
|
||||||
files: ^docs/changelog.md$
|
|
||||||
- id: update-readme-options-table
|
|
||||||
name: Update README options table
|
|
||||||
language: python
|
|
||||||
entry: bin/update_readme_options_table.py --force
|
|
||||||
files: ^docs/options.md$
|
|
||||||
pass_filenames: false
|
pass_filenames: false
|
||||||
|
entry: cog -c -P -r -I ./bin README.md
|
||||||
|
files: '^(README\.md|docs/changelog\.md|docs/options\.md|bin/readme.*)$'
|
||||||
|
additional_dependencies: [cogapp]
|
||||||
|
|
||||||
- repo: https://github.com/codespell-project/codespell
|
- repo: https://github.com/codespell-project/codespell
|
||||||
rev: v2.4.1
|
rev: v2.4.1
|
||||||
|
|||||||
@@ -124,8 +124,10 @@ The following diagram summarises the steps that cibuildwheel takes on each platf
|
|||||||
|
|
||||||
<sup>Explore an interactive version of this diagram [in the docs](https://cibuildwheel.pypa.io/en/stable/#how-it-works).</sup>
|
<sup>Explore an interactive version of this diagram [in the docs](https://cibuildwheel.pypa.io/en/stable/#how-it-works).</sup>
|
||||||
|
|
||||||
<!-- START bin/update_readme_options_table.py -->
|
|
||||||
<!-- This table is auto-generated from docs/options.md by bin/update_readme_options_table.py -->
|
<!--[[[cog from readme_options_table import get_table; print(get_table()) ]]]-->
|
||||||
|
|
||||||
|
<!-- This table is auto-generated from docs/options.md by bin/readme_options_table.py -->
|
||||||
|
|
||||||
| | Option | Description |
|
| | Option | Description |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
@@ -159,7 +161,8 @@ The following diagram summarises the steps that cibuildwheel takes on each platf
|
|||||||
| | [`debug-traceback`](https://cibuildwheel.pypa.io/en/stable/options/#debug-traceback) | Print full traceback when errors occur. |
|
| | [`debug-traceback`](https://cibuildwheel.pypa.io/en/stable/options/#debug-traceback) | Print full traceback when errors occur. |
|
||||||
| | [`build-verbosity`](https://cibuildwheel.pypa.io/en/stable/options/#build-verbosity) | Increase/decrease the output of the build |
|
| | [`build-verbosity`](https://cibuildwheel.pypa.io/en/stable/options/#build-verbosity) | Increase/decrease the output of the build |
|
||||||
|
|
||||||
<!-- END bin/update_readme_options_table.py -->
|
|
||||||
|
<!--[[[end]]] (checksum: 4d6a8418630e9ed43251973d93798a1b) -->
|
||||||
|
|
||||||
These options can be specified in a pyproject.toml file, or as environment variables, see [configuration docs](https://cibuildwheel.pypa.io/en/latest/configuration/).
|
These options can be specified in a pyproject.toml file, or as environment variables, see [configuration docs](https://cibuildwheel.pypa.io/en/latest/configuration/).
|
||||||
|
|
||||||
@@ -222,9 +225,7 @@ This is similar to static linking, so it might have some license implications. C
|
|||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
<!-- START bin/update_readme_changelog.py -->
|
<!-- [[[cog from readme_changelog import mini_changelog; print(mini_changelog()) ]]] -->
|
||||||
|
|
||||||
<!-- this section was generated by bin/update_readme_changelog.py -- do not edit manually -->
|
|
||||||
|
|
||||||
### v3.0.0
|
### v3.0.0
|
||||||
|
|
||||||
@@ -278,7 +279,7 @@ _26 April 2025_
|
|||||||
|
|
||||||
- 🛠 Dependency updates, including Python 3.13.3 (#2371)
|
- 🛠 Dependency updates, including Python 3.13.3 (#2371)
|
||||||
|
|
||||||
<!-- END bin/update_readme_changelog.py -->
|
<!-- [[[end]]] (checksum: ccccc1a3fec30c19a762ec4575fbd18d) -->
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
Executable
+23
@@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import re
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
PROJECT_ROOT = Path(__file__).parent / ".."
|
||||||
|
CHANGELOG_FILE = PROJECT_ROOT / "docs" / "changelog.md"
|
||||||
|
|
||||||
|
# https://regexr.com/622ds
|
||||||
|
FIRST_5_CHANGELOG_ENTRIES_REGEX = re.compile(r"""(^###.*?(?=###)){5}""", re.DOTALL | re.MULTILINE)
|
||||||
|
|
||||||
|
|
||||||
|
def mini_changelog() -> str:
|
||||||
|
changelog_text = CHANGELOG_FILE.read_text()
|
||||||
|
|
||||||
|
mini_changelog_match = FIRST_5_CHANGELOG_ENTRIES_REGEX.search(changelog_text)
|
||||||
|
assert mini_changelog_match, "Failed to find the first few changelog entries"
|
||||||
|
|
||||||
|
return f"\n{mini_changelog_match.group(0).strip()}\n"
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print(mini_changelog())
|
||||||
@@ -1,13 +1,11 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import argparse
|
|
||||||
import dataclasses
|
import dataclasses
|
||||||
import re
|
import re
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Final
|
from typing import Final
|
||||||
|
|
||||||
DIR: Final[Path] = Path(__file__).parent.parent.resolve()
|
DIR: Final[Path] = Path(__file__).parent.parent.resolve()
|
||||||
README: Final[Path] = DIR / "README.md"
|
|
||||||
OPTIONS_MD: Final[Path] = DIR / "docs" / "options.md"
|
OPTIONS_MD: Final[Path] = DIR / "docs" / "options.md"
|
||||||
|
|
||||||
SECTION_HEADER_REGEX = re.compile(r"^## (?P<name>.*?)$", re.MULTILINE)
|
SECTION_HEADER_REGEX = re.compile(r"^## (?P<name>.*?)$", re.MULTILINE)
|
||||||
@@ -17,11 +15,6 @@ OPTION_HEADER_REGEX = re.compile(
|
|||||||
r"^### (?P<name>.*?){.*#(?P<id>\S+).*}\n+> ?(?P<desc>.*)$", re.MULTILINE
|
r"^### (?P<name>.*?){.*#(?P<id>\S+).*}\n+> ?(?P<desc>.*)$", re.MULTILINE
|
||||||
)
|
)
|
||||||
|
|
||||||
README_OPTIONS_TABLE_SECTION = re.compile(
|
|
||||||
r"""(?<=<!-- START bin\/update_readme_options_table.py -->\n).*(?=<!-- END bin\/update_readme_options_table.py -->)""",
|
|
||||||
re.DOTALL,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@dataclasses.dataclass(kw_only=True)
|
@dataclasses.dataclass(kw_only=True)
|
||||||
class Option:
|
class Option:
|
||||||
@@ -31,17 +24,7 @@ class Option:
|
|||||||
section: str
|
section: str
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def get_table() -> str:
|
||||||
parser = argparse.ArgumentParser(
|
|
||||||
description="Update the options table in the README from docs/options.md"
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"--force",
|
|
||||||
action="store_true",
|
|
||||||
help="Updates the README inplace, rather than printing to stdout.",
|
|
||||||
)
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
options_md = OPTIONS_MD.read_text(encoding="utf-8")
|
options_md = OPTIONS_MD.read_text(encoding="utf-8")
|
||||||
|
|
||||||
sections = SECTION_HEADER_REGEX.split(options_md)[1:]
|
sections = SECTION_HEADER_REGEX.split(options_md)[1:]
|
||||||
@@ -58,7 +41,7 @@ def main() -> None:
|
|||||||
)
|
)
|
||||||
options.append(option)
|
options.append(option)
|
||||||
|
|
||||||
table_md = "<!-- This table is auto-generated from docs/options.md by bin/update_readme_options_table.py -->\n\n"
|
table_md = "\n<!-- This table is auto-generated from docs/options.md by bin/readme_options_table.py -->\n\n"
|
||||||
table_md += "| | Option | Description |\n"
|
table_md += "| | Option | Description |\n"
|
||||||
table_md += "|---|---|---|\n"
|
table_md += "|---|---|---|\n"
|
||||||
last_section: str | None = None
|
last_section: str | None = None
|
||||||
@@ -78,21 +61,8 @@ def main() -> None:
|
|||||||
table_md += "| " + " | ".join(cells) + " |\n"
|
table_md += "| " + " | ".join(cells) + " |\n"
|
||||||
table_md += "\n"
|
table_md += "\n"
|
||||||
|
|
||||||
if not args.force:
|
return table_md
|
||||||
print(table_md)
|
|
||||||
return
|
|
||||||
|
|
||||||
readme_text = README.read_text(encoding="utf-8")
|
|
||||||
|
|
||||||
if not re.search(README_OPTIONS_TABLE_SECTION, readme_text):
|
|
||||||
msg = "Options section not found in README"
|
|
||||||
raise ValueError(msg)
|
|
||||||
|
|
||||||
readme_text = re.sub(README_OPTIONS_TABLE_SECTION, table_md, readme_text)
|
|
||||||
README.write_text(readme_text, encoding="utf-8")
|
|
||||||
|
|
||||||
print("Updated README with options table.")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
print(get_table())
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
PROJECT_ROOT = Path(__file__).parent / ".."
|
|
||||||
CHANGELOG_FILE = PROJECT_ROOT / "docs" / "changelog.md"
|
|
||||||
README_FILE = PROJECT_ROOT / "README.md"
|
|
||||||
|
|
||||||
# https://regexr.com/622ds
|
|
||||||
FIRST_5_CHANGELOG_ENTRIES_REGEX = re.compile(r"""(^###.*?(?=###)){5}""", re.DOTALL | re.MULTILINE)
|
|
||||||
|
|
||||||
# https://regexr.com/622e5
|
|
||||||
README_CHANGELOG_SECTION = re.compile(
|
|
||||||
r"""(?<=<!-- START bin\/update_readme_changelog.py -->\n).*(?=<!-- END bin\/update_readme_changelog.py -->)""",
|
|
||||||
re.DOTALL,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
|
||||||
changelog_text = CHANGELOG_FILE.read_text()
|
|
||||||
readme_text = README_FILE.read_text()
|
|
||||||
|
|
||||||
mini_changelog_match = FIRST_5_CHANGELOG_ENTRIES_REGEX.search(changelog_text)
|
|
||||||
assert mini_changelog_match, "Failed to find the first few changelog entries"
|
|
||||||
|
|
||||||
mini_changelog = "\n".join(
|
|
||||||
[
|
|
||||||
"",
|
|
||||||
"<!-- this section was generated by bin/update_readme_changelog.py -- do not edit manually -->",
|
|
||||||
"",
|
|
||||||
mini_changelog_match.group(0).strip(),
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
if not re.search(README_CHANGELOG_SECTION, readme_text):
|
|
||||||
sys.exit("Changelog section not found in README")
|
|
||||||
|
|
||||||
readme_text = re.sub(README_CHANGELOG_SECTION, mini_changelog, readme_text)
|
|
||||||
README_FILE.write_text(readme_text)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
Reference in New Issue
Block a user