@gunshi/docs 0.27.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -0
- package/package.json +52 -0
- package/src/guide/advanced/advanced-lazy-loading.md +312 -0
- package/src/guide/advanced/command-hooks.md +469 -0
- package/src/guide/advanced/context-extensions.md +545 -0
- package/src/guide/advanced/custom-rendering.md +945 -0
- package/src/guide/advanced/docs-gen.md +594 -0
- package/src/guide/advanced/internationalization.md +677 -0
- package/src/guide/advanced/type-system.md +561 -0
- package/src/guide/essentials/auto-usage.md +281 -0
- package/src/guide/essentials/composable.md +332 -0
- package/src/guide/essentials/declarative.md +724 -0
- package/src/guide/essentials/getting-started.md +252 -0
- package/src/guide/essentials/lazy-async.md +408 -0
- package/src/guide/essentials/plugin-system.md +472 -0
- package/src/guide/essentials/type-safe.md +154 -0
- package/src/guide/introduction/setup.md +68 -0
- package/src/guide/introduction/what-is-gunshi.md +68 -0
- package/src/guide/plugin/decorators.md +545 -0
- package/src/guide/plugin/dependencies.md +519 -0
- package/src/guide/plugin/extensions.md +317 -0
- package/src/guide/plugin/getting-started.md +298 -0
- package/src/guide/plugin/guidelines.md +940 -0
- package/src/guide/plugin/introduction.md +294 -0
- package/src/guide/plugin/lifecycle.md +432 -0
- package/src/guide/plugin/list.md +37 -0
- package/src/guide/plugin/testing.md +843 -0
- package/src/guide/plugin/type-system.md +529 -0
- package/src/index.md +44 -0
- package/src/release/v0.27.md +722 -0
- package/src/showcase.md +11 -0
|
@@ -0,0 +1,594 @@
|
|
|
1
|
+
# Documentation Generation
|
|
2
|
+
|
|
3
|
+
Gunshi provides a powerful feature for automatically generating documentation for your CLI applications.
|
|
4
|
+
|
|
5
|
+
This guide explains how to use the `generate` function to generate documentation programmatically.
|
|
6
|
+
|
|
7
|
+
## Using the `generate` Function
|
|
8
|
+
|
|
9
|
+
The following example demonstrates how to use the `generate` function to programmatically capture usage information for a command and save it to a documentation file:
|
|
10
|
+
|
|
11
|
+
```ts [cli.ts]
|
|
12
|
+
import { define } from 'gunshi'
|
|
13
|
+
import { generate } from 'gunshi/generator'
|
|
14
|
+
import { promises as fs } from 'node:fs'
|
|
15
|
+
|
|
16
|
+
import type { Command } from 'gunshi'
|
|
17
|
+
|
|
18
|
+
// Define your command
|
|
19
|
+
const command = define({
|
|
20
|
+
name: 'my-command',
|
|
21
|
+
description: 'A sample command',
|
|
22
|
+
args: {
|
|
23
|
+
input: {
|
|
24
|
+
type: 'string',
|
|
25
|
+
short: 'i',
|
|
26
|
+
description: 'Input file'
|
|
27
|
+
},
|
|
28
|
+
output: {
|
|
29
|
+
type: 'string',
|
|
30
|
+
short: 'o',
|
|
31
|
+
description: 'Output file'
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// ... and define `run`
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
// Generate documentation
|
|
38
|
+
async function main() {
|
|
39
|
+
// Generate the usage information
|
|
40
|
+
const usageText: string = await generate(null, command, {
|
|
41
|
+
name: 'my-cli',
|
|
42
|
+
version: '1.0.0',
|
|
43
|
+
description: 'My CLI tool'
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
// Now you can use the usage text to generate documentation
|
|
47
|
+
await fs.writeFile('docs/cli-usage.md', `# CLI Usage\n\n\`\`\`sh\n${usageText}\n\`\`\``, 'utf8')
|
|
48
|
+
|
|
49
|
+
console.log('Documentation generated successfully!')
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Generate!
|
|
53
|
+
await main()
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
<!-- eslint-disable markdown/no-missing-label-refs -->
|
|
57
|
+
|
|
58
|
+
> [!TIP]
|
|
59
|
+
> The example fully code is [here](https://github.com/kazupon/gunshi/tree/main/playground/advanced/docs-gen/basic).
|
|
60
|
+
|
|
61
|
+
<!-- eslint-enable markdown/no-missing-label-refs -->
|
|
62
|
+
|
|
63
|
+
The `generate` function programmatically captures usage information for your CLI commands and returns it as a string.
|
|
64
|
+
|
|
65
|
+
This allows you to generate documentation files, create API documentation, or integrate usage information into your build process.
|
|
66
|
+
|
|
67
|
+
Unlike the `cli` function which executes commands and prints output to the console, `generate` is designed specifically for documentation generation:
|
|
68
|
+
|
|
69
|
+
- **Silent Mode**: Internally sets `usageSilent: true` to capture output as a string rather than printing to console. When this flag is set, the internal `ctx.log` function is replaced with a no-op function, preventing console output while still returning the generated usage text
|
|
70
|
+
- **No Execution**: Only generates usage text without running command logic
|
|
71
|
+
- **Return Value**: Returns the generated usage text as a string (or empty string if generation fails)
|
|
72
|
+
|
|
73
|
+
The `generate` function takes three parameters:
|
|
74
|
+
|
|
75
|
+
- `command` (string | null): The sub-command name to generate documentation for. Pass `null` when generating documentation for the entry command or when you don't have sub-commands
|
|
76
|
+
- `entry` (Command | LazyCommand): The command object containing the command definition, or a lazy command that will be loaded to get the command
|
|
77
|
+
- `opts` (CliOptions): Optional configuration including:
|
|
78
|
+
- `name`: The CLI program name
|
|
79
|
+
- `version`: Version string to display
|
|
80
|
+
- `description`: Program description
|
|
81
|
+
- `subCommands`: Map of sub-commands (if applicable)
|
|
82
|
+
- `renderHeader`, `renderUsage`: Custom renderer functions
|
|
83
|
+
- **Note**: The `usageSilent` option is automatically set to `true` internally, so any value you provide will be overridden
|
|
84
|
+
|
|
85
|
+
Returns a Promise that resolves to the generated usage text as a string.
|
|
86
|
+
|
|
87
|
+
If no usage is generated (e.g., when renderUsage is not defined), returns an empty string.
|
|
88
|
+
|
|
89
|
+
## Generating Documentation for Multiple Commands
|
|
90
|
+
|
|
91
|
+
When your CLI has sub-commands, you can iterate through them to generate comprehensive documentation.
|
|
92
|
+
|
|
93
|
+
Here's how to generate documentation for each command separately:
|
|
94
|
+
|
|
95
|
+
```ts [cli.ts]
|
|
96
|
+
import { define } from 'gunshi'
|
|
97
|
+
import { generate } from 'gunshi/generator'
|
|
98
|
+
import { promises as fs } from 'node:fs'
|
|
99
|
+
|
|
100
|
+
import type { Command, CliOptions } from 'gunshi'
|
|
101
|
+
|
|
102
|
+
// Define your commands
|
|
103
|
+
const createCommand = define({
|
|
104
|
+
name: 'create',
|
|
105
|
+
description: 'Create a new resource',
|
|
106
|
+
args: {
|
|
107
|
+
name: {
|
|
108
|
+
type: 'string',
|
|
109
|
+
short: 'n',
|
|
110
|
+
required: true,
|
|
111
|
+
description: 'Name of the resource'
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// ... and define `run`
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
const listCommand = define({
|
|
118
|
+
name: 'list',
|
|
119
|
+
description: 'List all resources',
|
|
120
|
+
args: {
|
|
121
|
+
format: {
|
|
122
|
+
type: 'string',
|
|
123
|
+
short: 'f',
|
|
124
|
+
description: 'Output format (json, table)'
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// ... and define `run`
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
// Create a Map of sub-commands
|
|
131
|
+
const subCommands = {
|
|
132
|
+
create: createCommand,
|
|
133
|
+
list: listCommand
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Define the main command
|
|
137
|
+
const mainCommand = define({
|
|
138
|
+
name: 'manage',
|
|
139
|
+
description: 'Manage resources'
|
|
140
|
+
// ... and define `run`
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
// Generate documentation for all commands
|
|
144
|
+
async function main() {
|
|
145
|
+
const cliOptions: CliOptions = {
|
|
146
|
+
name: 'my-cli',
|
|
147
|
+
version: '1.0.0',
|
|
148
|
+
description: 'My CLI tool',
|
|
149
|
+
subCommands
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Generate main help
|
|
153
|
+
const mainUsage = await generate(null, mainCommand, cliOptions)
|
|
154
|
+
await fs.writeFile('docs/cli-main.md', `# CLI Usage\n\n\`\`\`sh\n${mainUsage}\n\`\`\``, 'utf8')
|
|
155
|
+
|
|
156
|
+
// Generate help for each sub-command
|
|
157
|
+
for (const name of Object.keys(subCommands)) {
|
|
158
|
+
const commandUsage = await generate(name, mainCommand, cliOptions)
|
|
159
|
+
await fs.writeFile(
|
|
160
|
+
`docs/cli-${name}.md`,
|
|
161
|
+
`# ${name.charAt(0).toUpperCase() + name.slice(1)} Command\n\n\`\`\`sh\n${commandUsage}\n\`\`\``,
|
|
162
|
+
'utf8'
|
|
163
|
+
)
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
console.log('All documentation generated successfully!')
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Generate!
|
|
170
|
+
await main()
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
<!-- eslint-disable markdown/no-missing-label-refs -->
|
|
174
|
+
|
|
175
|
+
> [!TIP]
|
|
176
|
+
> The example fully code is [here](https://github.com/kazupon/gunshi/tree/main/playground/advanced/docs-gen/sub-command).
|
|
177
|
+
|
|
178
|
+
<!-- eslint-enable markdown/no-missing-label-refs -->
|
|
179
|
+
|
|
180
|
+
## Creating Rich Documentation
|
|
181
|
+
|
|
182
|
+
You can combine the generated usage information with additional content to create rich documentation:
|
|
183
|
+
|
|
184
|
+
```ts
|
|
185
|
+
import { define } from 'gunshi'
|
|
186
|
+
import { generate } from 'gunshi/generator'
|
|
187
|
+
import { promises as fs } from 'node:fs'
|
|
188
|
+
|
|
189
|
+
// Generate rich documentation
|
|
190
|
+
async function main() {
|
|
191
|
+
const command = define({
|
|
192
|
+
name: 'data-processor',
|
|
193
|
+
description: 'Process data files',
|
|
194
|
+
args: {
|
|
195
|
+
input: {
|
|
196
|
+
type: 'string',
|
|
197
|
+
short: 'i',
|
|
198
|
+
required: true,
|
|
199
|
+
description: 'Input file path'
|
|
200
|
+
},
|
|
201
|
+
format: {
|
|
202
|
+
type: 'string',
|
|
203
|
+
short: 'f',
|
|
204
|
+
description: 'Output format (json, csv, xml)'
|
|
205
|
+
},
|
|
206
|
+
output: {
|
|
207
|
+
type: 'string',
|
|
208
|
+
short: 'o',
|
|
209
|
+
description: 'Output file path'
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
// ... and define `run`
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
// Generate the usage information
|
|
216
|
+
const usageText = await generate(null, command, {
|
|
217
|
+
name: 'data-processor',
|
|
218
|
+
version: '1.0.0',
|
|
219
|
+
description: 'A data processing utility'
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
// Create rich documentation
|
|
223
|
+
const documentation = `
|
|
224
|
+
# Data Processor CLI
|
|
225
|
+
|
|
226
|
+
A command-line utility for processing data files in various formats.
|
|
227
|
+
|
|
228
|
+
## Installation
|
|
229
|
+
|
|
230
|
+
\`\`\`sh
|
|
231
|
+
npm install -g data-processor
|
|
232
|
+
\`\`\`
|
|
233
|
+
|
|
234
|
+
## Usage
|
|
235
|
+
|
|
236
|
+
\`\`\`sh
|
|
237
|
+
${usageText}
|
|
238
|
+
\`\`\`
|
|
239
|
+
|
|
240
|
+
## Examples
|
|
241
|
+
|
|
242
|
+
### Convert a CSV file to JSON
|
|
243
|
+
|
|
244
|
+
\`\`\`sh
|
|
245
|
+
data-processor --input data.csv --format json --output data.json
|
|
246
|
+
\`\`\`
|
|
247
|
+
|
|
248
|
+
### Process a file and print to stdout
|
|
249
|
+
|
|
250
|
+
\`\`\`sh
|
|
251
|
+
data-processor --input data.csv
|
|
252
|
+
\`\`\`
|
|
253
|
+
|
|
254
|
+
## Advanced Usage
|
|
255
|
+
|
|
256
|
+
For more complex scenarios, you can:
|
|
257
|
+
|
|
258
|
+
1. Chain commands with pipes
|
|
259
|
+
2. Use glob patterns for batch processing
|
|
260
|
+
3. Configure processing with a config file
|
|
261
|
+
|
|
262
|
+
## API Reference
|
|
263
|
+
|
|
264
|
+
The CLI is built on top of the data-processor library, which you can also use programmatically.
|
|
265
|
+
`
|
|
266
|
+
|
|
267
|
+
await fs.writeFile('docs/data-processor.md', documentation, 'utf8')
|
|
268
|
+
console.log('Rich documentation generated successfully!')
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Generate!
|
|
272
|
+
await main()
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
<!-- eslint-disable markdown/no-missing-label-refs -->
|
|
276
|
+
|
|
277
|
+
> [!TIP]
|
|
278
|
+
> The example fully code is [here](https://github.com/kazupon/gunshi/tree/main/playground/advanced/docs-gen/rich).
|
|
279
|
+
|
|
280
|
+
<!-- eslint-enable markdown/no-missing-label-refs -->
|
|
281
|
+
|
|
282
|
+
## Automating Documentation Generation
|
|
283
|
+
|
|
284
|
+
You can automate documentation generation as part of your build process:
|
|
285
|
+
|
|
286
|
+
<!-- eslint-disable markdown/no-missing-label-refs -->
|
|
287
|
+
|
|
288
|
+
> [!NOTE]
|
|
289
|
+
> The following example uses Node.js-specific `__dirname` approach. For cross-runtime compatibility:
|
|
290
|
+
>
|
|
291
|
+
> - **Deno**: Use `import.meta.dirname` or `fromFileUrl(import.meta.url)`
|
|
292
|
+
> - **Bun**: Use `import.meta.dir` or Node.js-compatible approach
|
|
293
|
+
|
|
294
|
+
<!-- eslint-enable markdown/no-missing-label-refs -->
|
|
295
|
+
|
|
296
|
+
```ts [scripts/generate-docs.ts]
|
|
297
|
+
import { generate } from 'gunshi/generator'
|
|
298
|
+
import { promises as fs } from 'node:fs'
|
|
299
|
+
import { fileURLToPath } from 'node:url'
|
|
300
|
+
import path from 'node:path'
|
|
301
|
+
|
|
302
|
+
import type { Command, CliOptions } from 'gunshi'
|
|
303
|
+
|
|
304
|
+
// Get the directory of the current module
|
|
305
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
306
|
+
const rootDir = path.resolve(__dirname, '..')
|
|
307
|
+
const docsDir = path.join(rootDir, 'docs')
|
|
308
|
+
|
|
309
|
+
// Import your commands
|
|
310
|
+
import { mainCommand, subCommands } from '../src/commands.ts'
|
|
311
|
+
|
|
312
|
+
async function main() {
|
|
313
|
+
const cliOptions: CliOptions = {
|
|
314
|
+
name: 'my-cli',
|
|
315
|
+
version: '1.0.0',
|
|
316
|
+
description: 'My CLI tool',
|
|
317
|
+
subCommands
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// Generate main help
|
|
321
|
+
const mainUsage = await generate(null, mainCommand, cliOptions)
|
|
322
|
+
|
|
323
|
+
// Create the CLI reference page
|
|
324
|
+
const cliReference = `# CLI Reference
|
|
325
|
+
|
|
326
|
+
## Main Command
|
|
327
|
+
|
|
328
|
+
\`\`\`sh
|
|
329
|
+
${mainUsage}
|
|
330
|
+
\`\`\`
|
|
331
|
+
|
|
332
|
+
## Sub-commands
|
|
333
|
+
|
|
334
|
+
`
|
|
335
|
+
|
|
336
|
+
// Add each sub-command
|
|
337
|
+
let fullReference = cliReference
|
|
338
|
+
for (const name of Object.keys(subCommands)) {
|
|
339
|
+
const commandUsage = await generate(name, mainCommand, cliOptions)
|
|
340
|
+
fullReference += `### ${name.charAt(0).toUpperCase() + name.slice(1)}
|
|
341
|
+
|
|
342
|
+
\`\`\`sh
|
|
343
|
+
${commandUsage}
|
|
344
|
+
\`\`\`
|
|
345
|
+
|
|
346
|
+
`
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// Write the documentation
|
|
350
|
+
await fs.writeFile(path.join(docsDir, 'cli-reference.md'), fullReference, 'utf8')
|
|
351
|
+
console.log('Documentation generated successfully!')
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// Generate!
|
|
355
|
+
await main()
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
Then add a script to your `package.json`:
|
|
359
|
+
|
|
360
|
+
```json [package.json]
|
|
361
|
+
{
|
|
362
|
+
"scripts": {
|
|
363
|
+
"docs:generate": "tsx scripts/generate-docs.ts",
|
|
364
|
+
"docs:build": "npm run docs:generate && vitepress build docs"
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
## Generating Unix Man Pages
|
|
370
|
+
|
|
371
|
+
Unix man pages (short for "manual pages") are a traditional form of documentation for command-line tools on Unix-like operating systems.
|
|
372
|
+
|
|
373
|
+
You can use Gunshi's `generate` function to generate man pages for your CLI applications.
|
|
374
|
+
|
|
375
|
+
### Introduction to Man Pages
|
|
376
|
+
|
|
377
|
+
Man pages are the standard documentation format for Unix and Unix-like systems.
|
|
378
|
+
|
|
379
|
+
They provide comprehensive documentation directly accessible from the command line using the `man` command.
|
|
380
|
+
|
|
381
|
+
Man pages follow a specific structure with numbered sections (1 for user commands, 2 for system calls, etc.) and standardized formatting conventions.
|
|
382
|
+
|
|
383
|
+
The most common format for man pages is roff (runoff), though modern tools allow you to write documentation in simpler formats like Markdown and convert them to roff.
|
|
384
|
+
|
|
385
|
+
### Generating Man Pages with Gunshi
|
|
386
|
+
|
|
387
|
+
The following example demonstrates how to generate Unix man page documentation using Gunshi's `generate` function with a custom renderer.
|
|
388
|
+
|
|
389
|
+
The custom renderer (`renderManPageUsage`) creates markdown output that can be converted to the man page format (roff) using tools like `marked-man`.
|
|
390
|
+
|
|
391
|
+
The renderer function structures the output according to standard man page sections:
|
|
392
|
+
|
|
393
|
+
- **NAME**: Command name and brief description
|
|
394
|
+
- **SYNOPSIS**: Command syntax overview
|
|
395
|
+
- **DESCRIPTION**: Detailed command description
|
|
396
|
+
- **OPTIONS**: Available command-line options with descriptions
|
|
397
|
+
- **EXAMPLES**: Usage examples (references the command's help)
|
|
398
|
+
- **AUTHOR**: Author information
|
|
399
|
+
- **SEE ALSO**: Related documentation and resources
|
|
400
|
+
|
|
401
|
+
This approach allows you to maintain man pages alongside your CLI code, ensuring they stay synchronized:
|
|
402
|
+
|
|
403
|
+
```ts [cli.ts]
|
|
404
|
+
import { define } from 'gunshi'
|
|
405
|
+
import { generate } from 'gunshi/generator'
|
|
406
|
+
import { execFileSync } from 'node:child_process'
|
|
407
|
+
import { promises as fs } from 'node:fs'
|
|
408
|
+
import path from 'node:path'
|
|
409
|
+
|
|
410
|
+
import type { CommandContext } from 'gunshi'
|
|
411
|
+
|
|
412
|
+
// Define custom usage renderer that outputs markdown convertible to man page format (roff) using marked-man
|
|
413
|
+
function renderManPageUsage(ctx: CommandContext) {
|
|
414
|
+
const lines: string[] = []
|
|
415
|
+
|
|
416
|
+
// NAME
|
|
417
|
+
lines.push(`# ${ctx.name}(1) -- ${ctx.description || 'CLI tool'}`, '')
|
|
418
|
+
|
|
419
|
+
// SYNOPSIS
|
|
420
|
+
lines.push('## SYNOPSIS')
|
|
421
|
+
lines.push(`${ctx.env.name} <OPTIONS>`, '')
|
|
422
|
+
|
|
423
|
+
// DESCRIPTION
|
|
424
|
+
lines.push('## DESCRIPTION')
|
|
425
|
+
lines.push(ctx.description || '', '')
|
|
426
|
+
|
|
427
|
+
// OPTIONS
|
|
428
|
+
lines.push('## OPTIONS')
|
|
429
|
+
for (const [name, schema] of Object.entries(ctx.args)) {
|
|
430
|
+
const options = [`\`--${name}\``]
|
|
431
|
+
if (schema.short) {
|
|
432
|
+
options.unshift(`\`-${schema.short}\``)
|
|
433
|
+
}
|
|
434
|
+
let value = ''
|
|
435
|
+
if (schema.type !== 'boolean') {
|
|
436
|
+
value = schema.default ? `[${name}]` : `<${name}>`
|
|
437
|
+
}
|
|
438
|
+
lines.push(`- ${options.join(', ')}${value ? ` ${value}` : ''}`)
|
|
439
|
+
lines.push(` ${schema.description || ''}`)
|
|
440
|
+
lines.push('')
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// EXAMPLES
|
|
444
|
+
lines.push('## EXAMPLES')
|
|
445
|
+
lines.push('See command `--help` for examples', '')
|
|
446
|
+
|
|
447
|
+
// AUTHOR
|
|
448
|
+
lines.push('## AUTHOR')
|
|
449
|
+
lines.push('Created by yours', '')
|
|
450
|
+
|
|
451
|
+
// SEE ALSO
|
|
452
|
+
lines.push('## SEE ALSO')
|
|
453
|
+
lines.push('- man: `man my-tool`', '')
|
|
454
|
+
lines.push('- website: https://my-tools.com/references/cli', '')
|
|
455
|
+
lines.push('- repository: https://github.com/your-username/my-tool', '')
|
|
456
|
+
|
|
457
|
+
return Promise.resolve(lines.join('\n'))
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
async function main() {
|
|
461
|
+
const command = define({
|
|
462
|
+
name: 'my-tool',
|
|
463
|
+
description: 'A utility for processing data',
|
|
464
|
+
args: {
|
|
465
|
+
input: {
|
|
466
|
+
type: 'string',
|
|
467
|
+
short: 'i',
|
|
468
|
+
required: true,
|
|
469
|
+
description: 'Input file path'
|
|
470
|
+
},
|
|
471
|
+
output: {
|
|
472
|
+
type: 'string',
|
|
473
|
+
short: 'o',
|
|
474
|
+
description: 'Output file path (defaults to stdout)'
|
|
475
|
+
},
|
|
476
|
+
format: {
|
|
477
|
+
type: 'string',
|
|
478
|
+
short: 'f',
|
|
479
|
+
description: 'Output format (json, yaml, xml)'
|
|
480
|
+
},
|
|
481
|
+
verbose: {
|
|
482
|
+
type: 'boolean',
|
|
483
|
+
short: 'V',
|
|
484
|
+
description: 'Enable verbose output'
|
|
485
|
+
}
|
|
486
|
+
},
|
|
487
|
+
examples: `1. Process a file and output to stdout
|
|
488
|
+
$ my-tool --input data.csv
|
|
489
|
+
|
|
490
|
+
2. Process a file and save to a specific format
|
|
491
|
+
$ my-tool --input data.csv --output result.yaml --format yaml
|
|
492
|
+
|
|
493
|
+
3. Enable verbose output
|
|
494
|
+
$ my-tool --input data.csv --verbose`
|
|
495
|
+
// ... and define `run`
|
|
496
|
+
})
|
|
497
|
+
|
|
498
|
+
// Generate the usage with custom renderer
|
|
499
|
+
const usageText = await generate(null, command, {
|
|
500
|
+
name: 'my-tool',
|
|
501
|
+
version: '1.0.0',
|
|
502
|
+
description: 'A utility for processing data',
|
|
503
|
+
renderHeader: null, // no display header on console
|
|
504
|
+
renderUsage: renderManPageUsage // set custom usage renderer
|
|
505
|
+
})
|
|
506
|
+
|
|
507
|
+
// Prerequisites: Install marked-man for converting markdown to man page format
|
|
508
|
+
// npm install -g marked-man
|
|
509
|
+
// or add it to your project: npm install --save-dev marked-man
|
|
510
|
+
|
|
511
|
+
// Write the markdown file
|
|
512
|
+
const mdFile = path.join(process.cwd(), 'my-tool.1.md')
|
|
513
|
+
await fs.writeFile(mdFile, usageText, 'utf8')
|
|
514
|
+
|
|
515
|
+
// Convert markdown to man page format using marked-man
|
|
516
|
+
try {
|
|
517
|
+
execFileSync('marked-man', ['--input', mdFile, '--output', 'my-tool.1'])
|
|
518
|
+
console.log('Man page generated successfully: my-tool.1')
|
|
519
|
+
} catch (error) {
|
|
520
|
+
console.error('Error generating man page:', (error as Error).message)
|
|
521
|
+
console.log('Make sure marked-man is installed: npm install -g marked-man')
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
// Generate!
|
|
526
|
+
await main()
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
<!-- eslint-disable markdown/no-missing-label-refs -->
|
|
530
|
+
|
|
531
|
+
> [!TIP]
|
|
532
|
+
> The example fully code is [here](https://github.com/kazupon/gunshi/tree/main/playground/advanced/docs-gen/man)
|
|
533
|
+
|
|
534
|
+
<!-- eslint-enable markdown/no-missing-label-refs -->
|
|
535
|
+
|
|
536
|
+
### Installing Man Pages
|
|
537
|
+
|
|
538
|
+
Once you've generated a man page, you can install it on Unix-like systems:
|
|
539
|
+
|
|
540
|
+
1. **Local installation** (for development):
|
|
541
|
+
|
|
542
|
+
```sh
|
|
543
|
+
# Copy to your local man pages directory
|
|
544
|
+
cp my-tool.1 ~/.local/share/man/man1/
|
|
545
|
+
# Update the man database
|
|
546
|
+
mandb
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
2. **System-wide installation** (for packages):
|
|
550
|
+
|
|
551
|
+
```sh
|
|
552
|
+
# Copy to the system man pages directory (requires sudo)
|
|
553
|
+
sudo cp my-tool.1 /usr/local/share/man/man1/
|
|
554
|
+
# Update the man database
|
|
555
|
+
sudo mandb
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
3. **Package installation** (for npm packages):
|
|
559
|
+
Add this to your `package.json`:
|
|
560
|
+
```json [package.json]
|
|
561
|
+
{
|
|
562
|
+
"man": ["./man/my-tool.1"]
|
|
563
|
+
}
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
### Viewing Man Pages
|
|
567
|
+
|
|
568
|
+
After installation, users can view your man page using:
|
|
569
|
+
|
|
570
|
+
```sh
|
|
571
|
+
man my-tool
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
With the man page generation complete, let's look at broader guidelines for maintaining and generating documentation effectively.
|
|
575
|
+
|
|
576
|
+
## Documentation Generation Guidelines
|
|
577
|
+
|
|
578
|
+
When working with Gunshi's documentation generation features, consider these important guidelines:
|
|
579
|
+
|
|
580
|
+
### Keeping Documentation Current
|
|
581
|
+
|
|
582
|
+
Automating documentation generation as part of your build process ensures that your documentation stays synchronized with your code. This approach prevents documentation drift and maintains consistency across your project.
|
|
583
|
+
|
|
584
|
+
### Enhancing Generated Content
|
|
585
|
+
|
|
586
|
+
The auto-generated usage information provides a solid foundation, but combining it with hand-written examples and detailed explanations creates more valuable documentation. Consider adding context-specific examples that demonstrate real-world use cases.
|
|
587
|
+
|
|
588
|
+
### Leveraging Custom Renderers
|
|
589
|
+
|
|
590
|
+
For projects requiring specific documentation formats or styling, custom renderers provide fine-grained control over the output. See [Custom Rendering](./custom-rendering.md) for implementation details.
|
|
591
|
+
|
|
592
|
+
### Documentation Testing
|
|
593
|
+
|
|
594
|
+
Including documentation tests in your test suite verifies that the generated documentation accurately reflects your CLI's behavior. This practice helps catch discrepancies between implementation and documentation early in the development process.
|