fix recursive readings for subcommands that return identical help
This commit is contained in:
parent
ba9dda073d
commit
845ff03632
2 changed files with 103 additions and 5 deletions
40
bin/main.ml
40
bin/main.ml
|
|
@ -675,9 +675,18 @@ let help_resolve_par ?(timeout=200) ?(mandirs=[]) cmd rest name =
|
|||
| Error _ -> None
|
||||
| Ok r when r.entries = [] && r.subcommands = [] && r.positionals = [] -> None
|
||||
| Ok r ->
|
||||
let at_limit = depth >= 5 in
|
||||
let subs = if at_limit then [] else r.subcommands in
|
||||
Some (r, subs, []))
|
||||
let self_listed = match cmd_args with
|
||||
| [] -> false
|
||||
| _ ->
|
||||
let leaf = List.nth cmd_args (List.length cmd_args - 1) in
|
||||
List.exists (fun (sc : subcommand) -> sc.name = leaf) r.subcommands in
|
||||
if self_listed then
|
||||
Some ({ entries = []; subcommands = []; positionals = [];
|
||||
description = "" }, [], [])
|
||||
else
|
||||
let at_limit = depth >= 5 in
|
||||
let subs = if at_limit then [] else r.subcommands in
|
||||
Some (r, subs, []))
|
||||
else
|
||||
match parse_help text with
|
||||
| Error _ -> None
|
||||
|
|
@ -688,7 +697,13 @@ let help_resolve_par ?(timeout=200) ?(mandirs=[]) cmd rest name =
|
|||
| _ ->
|
||||
let leaf = List.nth cmd_args (List.length cmd_args - 1) in
|
||||
List.exists (fun (sc : subcommand) -> sc.name = leaf) r.subcommands in
|
||||
if self_listed then None
|
||||
if self_listed then
|
||||
(* the subcommand's --help returned the parent's help text
|
||||
* (it lists itself as a subcommand). cache a leaf stub so the
|
||||
* completer knows this is a leaf node, not a parent with
|
||||
* further subcommands. *)
|
||||
Some ({ entries = []; subcommands = []; positionals = [];
|
||||
description = "" }, [], [])
|
||||
else
|
||||
let at_limit = depth >= 5 in
|
||||
let subs = if at_limit then [] else r.subcommands in
|
||||
|
|
@ -871,7 +886,22 @@ let cmd_index bindirs mandirs ignorelist help_only dir =
|
|||
done_cmds := SSet.add sub_cmd !done_cmds;
|
||||
incr result_count
|
||||
end
|
||||
) subs
|
||||
) subs;
|
||||
(* for COMMANDS section subcommands (e.g. systemctl start/stop),
|
||||
* write leaf stubs so the completer treats them as leaf nodes
|
||||
* rather than falling back to the parent's flags/subcommands.
|
||||
* only when there are no clap-style sub-sections (subs = []),
|
||||
* meaning the subcommands came from the COMMANDS section.
|
||||
* deliberately not added to done_cmds — if a per-subcommand
|
||||
* manpage exists (e.g. docker-start.1), it will overwrite the stub. *)
|
||||
if subs = [] then
|
||||
List.iter (fun (sc : subcommand) ->
|
||||
let sub_cmd = cmd ^ " " ^ sc.name in
|
||||
if not (SSet.mem sub_cmd !done_cmds) then
|
||||
write_result ~dir ~source:"manpage" sub_cmd
|
||||
{ entries = []; subcommands = []; positionals = [];
|
||||
description = sc.desc }
|
||||
) result.subcommands
|
||||
) files
|
||||
end
|
||||
) command_sections
|
||||
|
|
|
|||
|
|
@ -436,6 +436,70 @@ Use \fB\-\-verbose\fR to see more.
|
|||
let verbose_lines = List.filter (fun l -> contains l "verbose") lines in
|
||||
check "only one verbose line" (List.length verbose_lines = 1)
|
||||
|
||||
let test_commands_section_subcommands () =
|
||||
Printf.printf "\n== COMMANDS section subcommand extraction ==\n";
|
||||
(* manpages like systemctl have a COMMANDS section with bold command names
|
||||
* inside .PP + .RS/.RE blocks. these should be extracted as subcommands
|
||||
* and treated as leaf nodes (no entries of their own). *)
|
||||
let groff = {|.SH OPTIONS
|
||||
.TP
|
||||
\fB\-\-user\fR
|
||||
Talk to the service manager of the calling user.
|
||||
.TP
|
||||
\fB\-\-system\fR
|
||||
Talk to the service manager of the system.
|
||||
.SH COMMANDS
|
||||
.PP
|
||||
\fBstart\fR \fIUNIT\fR\&...
|
||||
.RS 4
|
||||
Start (activate) one or more units.
|
||||
.RE
|
||||
.PP
|
||||
\fBstop\fR \fIUNIT\fR\&...
|
||||
.RS 4
|
||||
Stop (deactivate) one or more units.
|
||||
.RE
|
||||
.PP
|
||||
\fBreload\fR \fIUNIT\fR\&...
|
||||
.RS 4
|
||||
Asks all units to reload their configuration.
|
||||
.RE
|
||||
.SH SEE ALSO
|
||||
|} in
|
||||
let result = parse_manpage_string groff in
|
||||
check "has options entries" (List.length result.entries = 2);
|
||||
check "has subcommands" (List.length result.subcommands = 3);
|
||||
let sc_names = List.map (fun (sc : subcommand) -> sc.name) result.subcommands in
|
||||
check "has start" (List.mem "start" sc_names);
|
||||
check "has stop" (List.mem "stop" sc_names);
|
||||
check "has reload" (List.mem "reload" sc_names);
|
||||
(* verify subcommand descriptions are extracted *)
|
||||
let start_sc = List.find (fun (sc : subcommand) -> sc.name = "start") result.subcommands in
|
||||
check "start has desc" (String.length start_sc.desc > 0)
|
||||
|
||||
let test_self_listing_detection () =
|
||||
Printf.printf "\n== Self-listing subcommand detection ==\n";
|
||||
(* when a subcommand's --help shows the parent's help text,
|
||||
* the subcommand name appears in its own subcommand list.
|
||||
* the parser should detect this — tested via parse_help. *)
|
||||
let help_text = {|systemctl [OPTIONS...] COMMAND ...
|
||||
|
||||
Unit Commands:
|
||||
start UNIT... Start (activate) one or more units
|
||||
stop UNIT... Stop (deactivate) one or more units
|
||||
status [PATTERN...] Show runtime status
|
||||
|
||||
Options:
|
||||
--user Talk to the user service manager
|
||||
--system Talk to the system service manager
|
||||
|} in
|
||||
let r = parse help_text in
|
||||
let has_start = List.exists (fun (sc : subcommand) -> sc.name = "start") r.subcommands in
|
||||
check "detected start as subcommand" has_start;
|
||||
(* the self-listing logic (in main.ml) would check: is "start" in r.subcommands?
|
||||
* here we just verify the parser extracts it correctly. *)
|
||||
check "has entries too" (List.length r.entries >= 2)
|
||||
|
||||
let test_font_boundary_spacing () =
|
||||
Printf.printf "\n== Font boundary spacing ==\n";
|
||||
(* \fB--max-results\fR\fIcount\fR should become "--max-results count" *)
|
||||
|
|
@ -488,5 +552,9 @@ let () =
|
|||
test_dedup_manpage ();
|
||||
test_font_boundary_spacing ();
|
||||
|
||||
Printf.printf "\nRunning COMMANDS section tests...\n";
|
||||
test_commands_section_subcommands ();
|
||||
test_self_listing_detection ();
|
||||
|
||||
Printf.printf "\n=== Results: %d passed, %d failed ===\n" !passes !failures;
|
||||
if !failures > 0 then exit 1
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue