Skip to content

Commit ac2fbab

Browse files
authored
Merge pull request #8610 from sylvestre/rm_uuhelp
Fix the doc generation and remove uuhelp_parser
2 parents 2455066 + 28dde64 commit ac2fbab

File tree

11 files changed

+189
-408
lines changed

11 files changed

+189
-408
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# spell-checker:ignore dtolnay libsystemd libattr libcap gsub
2+
3+
name: Check uudoc Documentation Generation
4+
5+
on:
6+
pull_request:
7+
paths:
8+
- 'src/bin/uudoc.rs'
9+
- 'src/uu/*/locales/en-US.ftl'
10+
- 'Cargo.toml'
11+
- '.github/workflows/documentation.yml'
12+
push:
13+
branches:
14+
- main
15+
paths:
16+
- 'src/bin/uudoc.rs'
17+
- 'src/uu/*/locales/en-US.ftl'
18+
- 'Cargo.toml'
19+
20+
jobs:
21+
check-doc:
22+
name: Verify uudoc generates correct documentation
23+
runs-on: ubuntu-latest
24+
25+
steps:
26+
- name: Checkout repository
27+
uses: actions/checkout@v4
28+
29+
- name: Install/setup prerequisites
30+
shell: bash
31+
run: sudo apt-get -y update ; sudo apt-get -y install libselinux1-dev libsystemd-dev libacl1-dev libattr1-dev libcap-dev
32+
33+
- name: Install Rust toolchain
34+
uses: dtolnay/rust-toolchain@stable
35+
36+
- name: Download tldr
37+
run: curl https://tldr.sh/assets/tldr.zip -o docs/tldr.zip
38+
39+
- name: Generate documentation
40+
run: cargo run --bin uudoc --all-features
41+
42+
- name: Get current version from Cargo.toml
43+
id: version
44+
run: |
45+
VERSION=$(awk '/\[workspace\.package\]/{flag=1; next} flag && /version = /{gsub(/.*= "/, ""); gsub(/".*/, ""); print; exit}' Cargo.toml)
46+
echo "version=$VERSION" >> $GITHUB_OUTPUT
47+
echo "Detected version: $VERSION"
48+
49+
- name: Check for --repeated option in uniq.md
50+
run: |
51+
if [ ! -f "docs/src/utils/uniq.md" ]; then
52+
echo "docs/src/utils/uniq.md does not exist"
53+
exit 1
54+
fi
55+
56+
if ! grep -q -- "--repeated" docs/src/utils/uniq.md; then
57+
echo "'--repeated' option not found in docs/src/utils/uniq.md"
58+
echo "Content of uniq.md:"
59+
head -50 docs/src/utils/uniq.md
60+
exit 1
61+
fi
62+
63+
- name: Check for correct version in ls.md
64+
run: |
65+
VERSION="${{ steps.version.outputs.version }}"
66+
67+
if [ ! -f "docs/src/utils/ls.md" ]; then
68+
echo "docs/src/utils/ls.md does not exist"
69+
exit 1
70+
fi
71+
72+
if ! grep -q "v(uutils coreutils) $VERSION" docs/src/utils/ls.md; then
73+
echo "Version '$VERSION' not found in docs/src/utils/ls.md"
74+
echo "Found version info:"
75+
grep "v(uutils coreutils)" docs/src/utils/ls.md || echo "No version info found"
76+
echo "Full version section:"
77+
grep -A2 -B2 "version" docs/src/utils/ls.md || echo "No version section found"
78+
exit 1
79+
fi
80+
81+
- name: Verify usage information is present
82+
run: |
83+
if [ ! -f "docs/src/utils/cat.md" ]; then
84+
echo "docs/src/utils/cat.md does not exist"
85+
exit 1
86+
fi
87+
88+
if ! grep -q "cat \[OPTION\].*\[FILE\]" docs/src/utils/cat.md; then
89+
echo "Usage information missing from cat.md"
90+
echo "Content around usage:"
91+
grep -A5 -B5 "cat" docs/src/utils/cat.md | head -20
92+
exit 1
93+
fi
94+
95+
- name: Verify help text is properly resolved
96+
run: |
97+
if [ ! -f "docs/src/utils/cat.md" ]; then
98+
echo "docs/src/utils/cat.md does not exist"
99+
exit 1
100+
fi
101+
102+
if grep -q "cat-help-" docs/src/utils/cat.md; then
103+
echo "Found unresolved Fluent keys in cat.md - help text not properly translated"
104+
echo "Unresolved Fluent keys found:"
105+
grep "cat-help-" docs/src/utils/cat.md
106+
exit 1
107+
fi
108+
109+
- name: Verify about text is present
110+
run: |
111+
if [ ! -f "docs/src/utils/cat.md" ]; then
112+
echo "docs/src/utils/cat.md does not exist"
113+
exit 1
114+
fi
115+
116+
if ! grep -q "Concatenate FILE(s)" docs/src/utils/cat.md; then
117+
echo "About text missing from cat.md"
118+
echo "Content of cat.md:"
119+
head -30 docs/src/utils/cat.md
120+
exit 1
121+
fi
122+
123+
- name: Verify tldr examples integration
124+
run: |
125+
if [ ! -f "docs/src/utils/cp.md" ]; then
126+
echo "docs/src/utils/cp.md does not exist"
127+
exit 1
128+
fi
129+
130+
if ! grep -q "The examples are provided by" docs/src/utils/cp.md; then
131+
echo "tldr examples integration missing from cp.md"
132+
echo "Expected to find 'The examples are provided by' text"
133+
echo "Content of cp.md:"
134+
tail -20 docs/src/utils/cp.md
135+
exit 1
136+
fi

Cargo.lock

Lines changed: 1 addition & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ expensive_tests = []
3333
# "test_risky_names" == enable tests that create problematic file names (would make a network share inaccessible to Windows, breaks SVN on Mac OS, etc.)
3434
test_risky_names = []
3535
# * only build `uudoc` when `--feature uudoc` is activated
36-
uudoc = ["zip", "dep:uuhelp_parser"]
36+
uudoc = ["zip", "dep:fluent-syntax"]
3737
## features
3838
## Optional feature for stdbuf
3939
# "feat_external_libstdbuf" == use an external libstdbuf.so for stdbuf instead of embedding it
@@ -282,7 +282,6 @@ members = [
282282
"src/uu/stdbuf/src/libstdbuf",
283283
"src/uucore",
284284
"src/uucore_procs",
285-
"src/uuhelp_parser",
286285
"tests/benches/factor",
287286
"tests/uutests",
288287
# "fuzz", # TODO
@@ -415,8 +414,8 @@ phf.workspace = true
415414
selinux = { workspace = true, optional = true }
416415
textwrap.workspace = true
417416
zip = { workspace = true, optional = true }
417+
fluent-syntax = { workspace = true, optional = true }
418418

419-
uuhelp_parser = { optional = true, version = "0.2.2", path = "src/uuhelp_parser" }
420419

421420
# * uutils
422421
uu_test = { optional = true, version = "0.2.2", package = "uu_test", path = "src/uu/test" }

src/bin/uudoc.rs

Lines changed: 47 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
// spell-checker:ignore tldr uuhelp
66

77
use clap::Command;
8+
use fluent_syntax::ast::{Entry, Message, Pattern};
9+
use fluent_syntax::parser;
810
use std::collections::HashMap;
911
use std::ffi::OsString;
1012
use std::fs::File;
@@ -140,7 +142,7 @@ fn main() -> io::Result<()> {
140142
}
141143
let p = format!("docs/src/utils/{name}.md");
142144

143-
let markdown = File::open(format!("src/uu/{name}/{name}.md"))
145+
let fluent = File::open(format!("src/uu/{name}/locales/en-US.ftl"))
144146
.and_then(|mut f: File| {
145147
let mut s = String::new();
146148
f.read_to_string(&mut s)?;
@@ -155,7 +157,7 @@ fn main() -> io::Result<()> {
155157
name,
156158
tldr_zip: &mut tldr_zip,
157159
utils_per_platform: &utils_per_platform,
158-
markdown,
160+
fluent,
159161
}
160162
.markdown()?;
161163
println!("Wrote to '{p}'");
@@ -173,7 +175,7 @@ struct MDWriter<'a, 'b> {
173175
name: &'a str,
174176
tldr_zip: &'b mut Option<ZipArchive<File>>,
175177
utils_per_platform: &'b HashMap<&'b str, Vec<String>>,
176-
markdown: Option<String>,
178+
fluent: Option<String>,
177179
}
178180

179181
impl MDWriter<'_, '_> {
@@ -189,6 +191,33 @@ impl MDWriter<'_, '_> {
189191
self.examples()
190192
}
191193

194+
/// Extract value for a Fluent key from the .ftl content
195+
fn extract_fluent_value(&self, key: &str) -> Option<String> {
196+
let content = self.fluent.as_ref()?;
197+
let resource = parser::parse(content.clone()).ok()?;
198+
199+
for entry in resource.body {
200+
if let Entry::Message(Message {
201+
id,
202+
value: Some(Pattern { elements }),
203+
..
204+
}) = entry
205+
{
206+
if id.name == key {
207+
// Simple text extraction - just concatenate text elements
208+
let mut result = String::new();
209+
for element in elements {
210+
if let fluent_syntax::ast::PatternElement::TextElement { value } = element {
211+
result.push_str(&value);
212+
}
213+
}
214+
return Some(result);
215+
}
216+
}
217+
}
218+
None
219+
}
220+
192221
/// # Errors
193222
/// Returns an error if the writer fails.
194223
fn additional(&mut self) -> io::Result<()> {
@@ -237,10 +266,7 @@ impl MDWriter<'_, '_> {
237266
/// # Errors
238267
/// Returns an error if the writer fails.
239268
fn usage(&mut self) -> io::Result<()> {
240-
if let Some(markdown) = &self.markdown {
241-
let usage = uuhelp_parser::parse_usage(markdown);
242-
let usage = usage.replace("{}", self.name);
243-
269+
if let Some(usage) = self.extract_fluent_value(&format!("{}-usage", self.name)) {
244270
writeln!(self.w, "\n```")?;
245271
writeln!(self.w, "{usage}")?;
246272
writeln!(self.w, "```")
@@ -252,8 +278,8 @@ impl MDWriter<'_, '_> {
252278
/// # Errors
253279
/// Returns an error if the writer fails.
254280
fn about(&mut self) -> io::Result<()> {
255-
if let Some(markdown) = &self.markdown {
256-
writeln!(self.w, "{}", uuhelp_parser::parse_about(markdown))
281+
if let Some(about) = self.extract_fluent_value(&format!("{}-about", self.name)) {
282+
writeln!(self.w, "{about}")
257283
} else {
258284
Ok(())
259285
}
@@ -262,13 +288,11 @@ impl MDWriter<'_, '_> {
262288
/// # Errors
263289
/// Returns an error if the writer fails.
264290
fn after_help(&mut self) -> io::Result<()> {
265-
if let Some(markdown) = &self.markdown {
266-
if let Some(after_help) = uuhelp_parser::parse_section("after help", markdown) {
267-
return writeln!(self.w, "\n\n{after_help}");
268-
}
291+
if let Some(after_help) = self.extract_fluent_value(&format!("{}-after-help", self.name)) {
292+
writeln!(self.w, "\n\n{after_help}")
293+
} else {
294+
Ok(())
269295
}
270-
271-
Ok(())
272296
}
273297

274298
/// # Errors
@@ -368,13 +392,17 @@ impl MDWriter<'_, '_> {
368392
write!(self.w, "</code>")?;
369393
}
370394
writeln!(self.w, "</dt>")?;
395+
let help_text = arg.get_help().unwrap_or_default().to_string();
396+
// Try to resolve Fluent key if it looks like one, otherwise use as-is
397+
let resolved_help = if help_text.starts_with(&format!("{}-help-", self.name)) {
398+
self.extract_fluent_value(&help_text).unwrap_or(help_text)
399+
} else {
400+
help_text
401+
};
371402
writeln!(
372403
self.w,
373404
"<dd>\n\n{}\n\n</dd>",
374-
arg.get_help()
375-
.unwrap_or_default()
376-
.to_string()
377-
.replace('\n', "<br />")
405+
resolved_help.replace('\n', "<br />")
378406
)?;
379407
}
380408
writeln!(self.w, "</dl>\n")

src/uucore_procs/Cargo.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# spell-checker:ignore uuhelp
21
[package]
32
name = "uucore_procs"
43
description = "uutils ~ 'uucore' proc-macros"
@@ -17,4 +16,3 @@ proc-macro = true
1716
[dependencies]
1817
proc-macro2 = "1.0.81"
1918
quote = "1.0.36"
20-
uuhelp_parser = { path = "../uuhelp_parser", version = "0.2.2" }

0 commit comments

Comments
 (0)