Skip to content

Commit

Permalink
build(doc): Provide utility to update README.md srgn --help output
Browse files Browse the repository at this point in the history
Could be extended to ALL output but that is much harder
  • Loading branch information
alexpovel committed Nov 6, 2024
1 parent bdd183c commit 2ce5a19
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 2 deletions.
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ binary needed), making it platform-independent. The downside is that custom pars
used. This has known warts. Those warts have workarounds:
- the README contains the full output of `srgn --help`, which is also tested against.
**This is whitespace-sensitive**, so there is trailing whitespace. Removing it fails
tests.
Run [`./scripts/update-readme.py`](./scripts/update-readme.py) to update this README
section automatically if you updated it.
- the tests contain [**hard-coded names of CLI
options**](https://github.com/alexpovel/srgn/blob/8ff54ee53ac0a53cdc4791b069648ee4511c7b94/tests/readme.rs#L494-L521).
This is necessary as otherwise it'd be unclear if a string `--foo` should be a flag
Expand Down
67 changes: 67 additions & 0 deletions scripts/update-readme.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/usr/bin/env python3

import argparse
import re
import subprocess
from difflib import unified_diff
from pathlib import Path

ENCODING = "utf8"


def diff(a: str, b: str, filename: Path) -> str:
res = "\n".join(
unified_diff(
a.splitlines(),
b.splitlines(),
fromfile=str(filename),
tofile=str(filename),
)
)
return res


def update_markdown_file(file: Path) -> None:
content = file.read_text(encoding=ENCODING)
print(f"Got contents of {file}, {len(content)} long")
pattern = re.compile(
pattern=r"(?<=```console\n\$ srgn --help\n)(.*?)(?=```$)",
flags=re.DOTALL | re.MULTILINE,
)
args = ["cargo", "run", "--", "--help"]
result = subprocess.run(
args=args,
capture_output=True,
text=True,
check=True,
)
print(f"Successfully ran command: {args}")

match_ = re.search(pattern, content)
assert match_ is not None, "Bad regex/README"
print(f"Match at: {match_}")

new_content = re.sub(pattern, result.stdout, content)

print("Got new file contents. Diff:")
print(diff(content, new_content, filename=file))
input("Press Enter to confirm and write to file, CTRL+C to abort...")
file.write_text(new_content, encoding=ENCODING)
print("Wrote new file contents.")


def main():
parser = argparse.ArgumentParser(
description="Update Markdown console code blocks with actual command output"
)
parser.add_argument("file", help="Path to the Markdown file to process")
args = parser.parse_args()

file = Path(args.file)
update_markdown_file(file)
print(f"Successfully updated {file}")
print("Done")


if __name__ == "__main__":
main()
16 changes: 16 additions & 0 deletions tests/readme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -818,6 +818,8 @@ mod tests {

#[test]
fn test_readme_code_blocks() {
let _helper = TestHinter;

let snippets = get_readme_snippets();
let pipes = get_readme_program_pipes(&snippets);

Expand Down Expand Up @@ -949,4 +951,18 @@ mod tests {

res
}

struct TestHinter;

impl Drop for TestHinter {
fn drop(&mut self) {
if std::thread::panicking() {
println!("\n==============================================");
println!("💡 README test failed!");
println!("Did you update the `srgn --help` output?");
println!("If no, run `./scripts/update-readme.py README.md` and try again.");
println!("==============================================\n");
}
}
}
}

0 comments on commit 2ce5a19

Please sign in to comment.