v / vlib / cli
Raw file | 181 loc (173 sloc) | 3.77 KB | Latest commit hash 017ace6ea
1module cli
2
3import time
4
5fn man_flag() Flag {
6 return Flag{
7 flag: .bool
8 name: 'man'
9 description: 'Prints the auto-generated manpage.'
10 }
11}
12
13fn man_cmd() Command {
14 return Command{
15 name: 'man'
16 usage: '<subcommand>'
17 description: 'Prints the auto-generated manpage.'
18 execute: print_manpage_for_command
19 }
20}
21
22// print_manpage_for_command prints the manpage for the
23// command or subcommand in `man_cmd` to stdout
24pub fn print_manpage_for_command(man_cmd Command) ! {
25 if man_cmd.args.len > 0 {
26 mut cmd := man_cmd.parent
27 for arg in man_cmd.args {
28 mut found := false
29 for sub_cmd in cmd.commands {
30 if sub_cmd.name == arg {
31 cmd = unsafe { &sub_cmd }
32 found = true
33 break
34 }
35 }
36 if !found {
37 args := man_cmd.args.join(' ')
38 println('Invalid command: ${args}')
39 return
40 }
41 }
42 print(cmd.manpage())
43 } else {
44 if unsafe { man_cmd.parent != 0 } {
45 print(man_cmd.parent.manpage())
46 }
47 }
48}
49
50// manpage returns a `string` containing the mdoc(7) manpage for
51// this `Command`
52pub fn (cmd Command) manpage() string {
53 mut mdoc := '.Dd ${time.now().strftime('%B %d, %Y')}\n'
54 mdoc += '.Dt ${cmd.full_name().replace(' ', '-').to_upper()} 1\n'
55 mdoc += '.Os\n.Sh NAME\n.Nm ${cmd.full_name().replace(' ', '-')}\n.Nd ${cmd.description}\n'
56 mdoc += '.Sh SYNOPSIS\n'
57 mdoc += '.Nm ${cmd.root().name}\n'
58 if unsafe { cmd.parent != 0 } {
59 mut parents := []Command{}
60 if !cmd.parent.is_root() {
61 parents.prepend(cmd.parent)
62 for {
63 p := parents[0]
64 if p.parent.is_root() {
65 break
66 } else {
67 parents.prepend(p.parent)
68 }
69 }
70 for c in parents {
71 mdoc += '.Ar ${c.name}\n'
72 }
73 }
74 mdoc += '.Ar ${cmd.name}\n'
75 }
76 for flag in cmd.flags {
77 mdoc += '.Op'
78 if flag.abbrev != '' {
79 mdoc += ' Fl ${flag.abbrev}'
80 } else {
81 if cmd.posix_mode {
82 mdoc += ' Fl -${flag.name}'
83 } else {
84 mdoc += ' Fl ${flag.name}'
85 }
86 }
87 match flag.flag {
88 .int, .float, .int_array, .float_array { mdoc += ' Ar num' }
89 .string, .string_array { mdoc += ' Ar string' }
90 else {}
91 }
92 mdoc += '\n'
93 }
94 for i in 0 .. cmd.required_args {
95 mdoc += '.Ar arg${i}\n'
96 }
97 if cmd.commands.len > 0 {
98 mdoc += '.Nm ${cmd.root().name}\n'
99 if unsafe { cmd.parent != 0 } {
100 mut parents := []Command{}
101 if !cmd.parent.is_root() {
102 parents.prepend(cmd.parent)
103 for {
104 p := parents[0]
105 if p.parent.is_root() {
106 break
107 } else {
108 parents.prepend(p.parent)
109 }
110 }
111 for c in parents {
112 mdoc += '.Ar ${c.name}\n'
113 }
114 }
115 mdoc += '.Ar ${cmd.name}\n'
116 }
117 mdoc += '.Ar subcommand\n'
118 }
119
120 mdoc += '.Sh DESCRIPTION\n'
121 if cmd.man_description != '' {
122 mdoc += '${cmd.man_description}\n'
123 } else if cmd.description != '' {
124 mdoc += '${cmd.description}\n'
125 }
126 if cmd.flags.len > 0 {
127 mdoc += '.Pp\nThe options are as follows:\n'
128 mdoc += '.Bl -tag -width indent\n'
129 for flag in cmd.flags {
130 mdoc += '.It'
131 if flag.abbrev != '' {
132 mdoc += ' Fl ${flag.abbrev}'
133 }
134 if cmd.posix_mode {
135 mdoc += ' Fl -${flag.name}'
136 } else {
137 mdoc += ' Fl ${flag.name}'
138 }
139 mdoc += '\n'
140 if flag.description != '' {
141 mdoc += '${flag.description}\n'
142 }
143 }
144 mdoc += '.El\n'
145 }
146 if cmd.commands.len > 0 {
147 mdoc += '.Pp\nThe subcommands are as follows:\n'
148 mdoc += '.Bl -tag -width indent\n'
149 for c in cmd.commands {
150 mdoc += '.It Cm ${c.name}\n'
151 if c.description != '' {
152 mdoc += '${c.description}\n'
153 }
154 }
155 mdoc += '.El\n'
156 }
157
158 if cmd.commands.len > 0 {
159 mdoc += '.Sh SEE ALSO\n'
160 mut cmds := []string{}
161 if unsafe { cmd.parent != 0 } {
162 cmds << cmd.parent.full_name().replace(' ', '-')
163 }
164 for c in cmd.commands {
165 cmds << c.full_name().replace(' ', '-')
166 }
167 cmds.sort()
168 mut i := 1
169 for c in cmds {
170 mdoc += '.Xr ${c} 1'
171 if i == cmds.len {
172 mdoc += '\n'
173 } else {
174 mdoc += ' ,\n'
175 }
176 i++
177 }
178 }
179
180 return mdoc
181}