fix(rust-docs): use [lib].name override + prefix bare-filename links#64
Conversation
Two issues from the first multi-package rustdoc run: 1. resq-bin fell through to the README stub even though it has a lib.rs. Cargo allows a custom [lib].name (resq-bin sets it to bin_explorer), which overrides the default snake_case of the package name. cargo-doc-md uses the lib name for output dirs. Parse [lib].name from each crate's Cargo.toml and use that for the rustdoc output lookup. 2. cargo-doc-md emits cross-references as bare relative paths (config.md, commands/audit.md) which Mintlify rejects as broken (28 links across 4 files). Add the same prefix-with-./ step the TypeScript template uses.
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request updates the Rust API documentation template to correctly handle custom library names defined in Cargo.toml and introduces a new step to prefix bare relative Markdown links with ./ for Mintlify compatibility. Feedback identifies several issues in the link prefixing Python script, including a greedy regex that fails on multiple links per line, a potential IndexError for empty link targets, and lack of support for links containing titles or trailing whitespace. Additionally, it is recommended to use explicit project lists instead of automated file discovery via rglob.
| link_re = re.compile(r'(?<!\!)\[([^\]]*)\]\(([^)]+)\)') | ||
|
|
||
| def is_qualified(target: str) -> bool: | ||
| t = target.strip().split(None, 1)[0] | ||
| if t.startswith(("./", "../", "/", "#")): | ||
| return True | ||
| if ":" in t.split("/", 1)[0]: | ||
| return True | ||
| return False | ||
|
|
||
| for f in pathlib.Path(".").rglob("*.md"): | ||
| text = f.read_text(encoding="utf-8") | ||
| def fix(m: re.Match) -> str: | ||
| label, target = m.group(1), m.group(2) | ||
| if is_qualified(target): | ||
| return m.group(0) | ||
| if not target.endswith(".md") and ".md#" not in target: | ||
| return m.group(0) | ||
| return f"[{label}](./{target})" | ||
| new = link_re.sub(fix, text) | ||
| if new != text: | ||
| f.write_text(new, encoding="utf-8") |
There was a problem hiding this comment.
The link prefixing logic has a few issues that could lead to incorrect documentation or script failures:
- Greedy Regex: The regex
([^)]+)for the link target is greedy. On lines with multiple links (e.g.,[a](b.md) and [c](d.md)), it will match from the first[to the last), causing the rewriter to fail or produce corrupted output. Using a non-greedy quantifier+?is necessary. - Potential IndexError: In
is_qualified,target.strip().split(None, 1)[0]will raise anIndexErrorif the link target is empty or contains only whitespace (e.g.,[]()). While rare in generated docs, the script should handle this gracefully. - Extension Check Robustness: The
fixfunction checkstarget.endswith(".md"). If a link includes a title (e.g.,[label](file.md "title")) or trailing whitespace, this check will fail, and the link won't be prefixed with./, leaving it broken in Mintlify. - Automated Discovery: The script uses
rglob("*.md")to discover files. Per repository guidelines, prefer explicit project lists over automated discovery in CI workflows if the repository structure contains duplicate project configurations (such as shadow copies) or if manual oversight of the public API surface is necessary to distinguish between public and internal components.
Note that these same patterns appear to be present in the TypeScript template as well.
link_re = re.compile(r'(?<!\!)\[([^\]]*)\]\(([^)]+?)\)')
def is_qualified(target: str) -> bool:
parts = target.strip().split(None, 1)
if not parts:
return True
t = parts[0]
if t.startswith(("./", "../", "/", "#")):
return True
if ":" in t.split("/", 1)[0]:
return True
return False
for f in pathlib.Path(".").rglob("*.md"):
text = f.read_text(encoding="utf-8")
def fix(m: re.Match) -> str:
label, target = m.group(1), m.group(2)
if is_qualified(target):
return m.group(0)
url_part = target.strip().split(None, 1)[0]
if not url_part.endswith(".md") and ".md#" not in url_part:
return m.group(0)
return f"[{label}](./{target})"
new = link_re.sub(fix, text)
if new != text:
f.write_text(new, encoding="utf-8")References
- Prefer explicit project lists over automated discovery (e.g., via grep) in CI workflows if the repository structure contains duplicate project configurations (such as shadow copies) or if manual oversight of the public API surface is necessary to distinguish between public and internal components.
Two issues caught from the first cargo-doc-md run (resq-software/docs#63):
1. resq-bin fell through to README stub
`resq-bin` has `lib.rs` but its `Cargo.toml` sets `[lib].name = "bin_explorer"`, overriding the default snake_case-of-package-name. `cargo-doc-md` uses the lib name for output dirs, so `target/doc-md/bin_explorer/` exists but my snake-case lookup checked `target/doc-md/resq_bin/` and missed it.
Parse `[lib].name` from each crate's `Cargo.toml` and use that for the rustdoc output lookup. Falls back to snake_case of the package name when not set.
2. cargo-doc-md emits bare-filename links
28 broken-link errors across 4 files: `config.md`, `commands/audit.md`, etc. Mintlify only resolves `./`, `../`, or absolute paths. Add the same Python-based prefix step the TypeScript template uses to add `./` to bare relative `.md` link targets.