|
1 | 1 | /*! |
2 | 2 | # `Cargo BashMan` |
3 | | -
|
4 | | -`BashMan` is a Cargo plugin that helps you generate BASH completions and/or MAN pages for your Rust apps using metadata from your projects' `Cargo.toml` manifests. It pairs well with the (unaffiliated) [cargo-deb](https://github.com/mmstick/cargo-deb). |
5 | | -
|
6 | | -BASH completions are sub-command aware — one level deep — and avoid making duplicate suggestions. For example, if the line already has `-h`, it will not suggest `-h` or its long variant `--help`. |
7 | | -
|
8 | | -MAN pages are automatically populated with the primary sections — `NAME`, `DESCRIPTION`, `USAGE`, `SUBCOMMANDS`, `FLAGS`, `OPTIONS`, `ARGUMENTS` — and the top level page can be extended with additional arbitrary sections as needed. If subcommands are defined, additional pages for each are generated, showing their particular usage, flags, etc. |
9 | | -
|
10 | | -MAN pages are saved in both plain ("app.1") and Gzipped ("app.1.gz") states. Linux `man` can read either format, so just pick whichever you prefer for distribution purposes. (Though Gzip is smaller…) |
11 | | -
|
12 | | -**This software is a work-in-progress.** |
13 | | -
|
14 | | -Feel free to use it, but if something weird happens — or if you have ideas for improvement — please open an [issue](https://github.com/Blobfolio/bashman/issues)! |
15 | | -
|
16 | | -
|
17 | | -
|
18 | | -## Installation |
19 | | -
|
20 | | -This application is written in [Rust](https://www.rust-lang.org/) and can be installed using [Cargo](https://github.com/rust-lang/cargo). |
21 | | -
|
22 | | -For stable Rust (>= `1.51.0`), run: |
23 | | -```bash |
24 | | -RUSTFLAGS="-C link-arg=-s" cargo install \ |
25 | | - --git https://github.com/Blobfolio/bashman.git \ |
26 | | - --bin cargo-bashman \ |
27 | | - --target x86_64-unknown-linux-gnu |
28 | | -``` |
29 | | -
|
30 | | -Pre-built `.deb` packages are also added for each [release](https://github.com/Blobfolio/bashman/releases/latest). They should always work for the latest stable Debian and Ubuntu. |
31 | | -
|
32 | | -
|
33 | | -
|
34 | | -## Usage |
35 | | -
|
36 | | -`BashMan` pulls all the data it needs to compile BASH completions and MAN pages straight from the specified `Cargo.toml` file. Once your manifest is set, all you need to do is run: |
37 | | -
|
38 | | -```bash |
39 | | -cargo bashman [-m/--manifest-path] /path/to/Cargo.toml |
40 | | -``` |
41 | | -
|
42 | | -
|
43 | | -## CONFIGURATION |
44 | | -
|
45 | | -The binary name, version, and description are taken from the standard `Cargo.toml` fields. |
46 | | -
|
47 | | -For everything else, start by adding a section to your `Cargo.toml` manifest like: |
48 | | -
|
49 | | -```toml |
50 | | -[package.metadata.bashman] |
51 | | -name = "Cargo BashMan" |
52 | | -bash-dir = "../release/bash_completion.d" |
53 | | -man-dir = "../release/man1" |
54 | | -credits-dir = "../" |
55 | | -``` |
56 | | -
|
57 | | -| Key | Type | Description | Default | |
58 | | -| --- | ---- | ----------- | ------- | |
59 | | -| name | *string* | The proper name of your application. | If not provided, the binary name is used. | |
60 | | -| bash-dir | *directory* | The output directory for BASH completions. This can be an absolute path, or a path relative to the manifest. | If not provided, the manifest's parent directory is used. | |
61 | | -| credits-dir | *directory* | The output directory for the `CREDITS.md` dependency list. This can be an absolute path, or a path relative to the manifest. | If not provided, the manifest's parent directory is used. | |
62 | | -| man-dir | *directory* | The output directory for MAN page(s). This can be an absolute path, or a path relative to the manifest. | If not provided, the manifest's parent directory is used. | |
63 | | -| subcommands | *array* | An array of your app's subcommands, if any. | | |
64 | | -| switches | *array* | An array of your app's true/false flags, if any. | | |
65 | | -| options | *array* | An array of your app's key=value options, if any. | | |
66 | | -| arguments | *array* | An array of any trailing arguments expected by your app. | | |
67 | | -| sections | *array* | Arbitrary sections to append to the MAN page. | | |
68 | | -
|
69 | | -### SUBCOMMANDS |
70 | | -
|
71 | | -When adding subcommands, each entry requires the following fields: |
72 | | -
|
73 | | -| Key | Type | Description | Default | |
74 | | -| --- | ---- | ----------- | ------- | |
75 | | -| name | *string* | The proper name of the command. | If not provided, the `cmd` value will be used. | |
76 | | -| cmd | *string* | The subcommand. | | |
77 | | -| description | *string* | A description of what the subcommand does. | | |
78 | | -
|
79 | | -Subcommands can have their own switches, options, arguments. These are specified in the `switches`, `options`, and `arguments` sections respectively. Keep reading… |
80 | | -
|
81 | | -Example: |
82 | | -```toml |
83 | | -[[package.metadata.bashman.subcommands]] |
84 | | -name="Whale Talk" |
85 | | -cmd="whale" |
86 | | -description="Print an underwater message." |
87 | | -``` |
88 | | -
|
89 | | -### SWITCHES |
90 | | -
|
91 | | -A "switch" is a CLI flag that either is or isn't. It can be a short key, like `-h`, or a long key like `--help`, or both. The value is implicitly `true` if the flag is present, or `false` if not. |
92 | | -
|
93 | | -Switches have the following fields: |
94 | | -
|
95 | | -| Key | Type | Description | |
96 | | -| --- | ---- | ----------- | |
97 | | -| short | *string* | A short key, like `-h`. | |
98 | | -| long | *string* | A long key, like `--help`. | |
99 | | -| description | *string* | A description for the flag. | |
100 | | -| subcommands | *array* | If this switch applies to one or more subcommands, list the commands here. If a switch applies to the top-level app, omit this field, or include an empty `""` entry in the array. | |
101 | | -
|
102 | | -Example: |
103 | | -```toml |
104 | | -[[package.metadata.bashman.switches]] |
105 | | -short = "-V" |
106 | | -long = "--version" |
107 | | -description = "Print application version." |
108 | | -
|
109 | | -[[package.metadata.bashman.switches]] |
110 | | -short = "-h" |
111 | | -long = "--help" |
112 | | -description = "Print help information." |
113 | | -subcommands = [ "call", "text", "" ] |
114 | | -``` |
115 | | -
|
116 | | -### OPTIONS |
117 | | -
|
118 | | -An "option" is exactly like a "switch", except it takes a value. As such, they have a couple more fields: |
119 | | -
|
120 | | -| Key | Type | Description | |
121 | | -| --- | ---- | ----------- | |
122 | | -| short | *string* | A short key, like `-h`. | |
123 | | -| long | *string* | A long key, like `--help`. | |
124 | | -| description | *string* | A description for the flag. | |
125 | | -| label | *string* | A placeholder label for the value bit, like `<FILE>`. | |
126 | | -| path | *bool* | If `true`, the BASH completions will suggest files/directories as potential values. If `false`, no value suggestion will be hazarded. | |
127 | | -| subcommands | *array* | If this option applies to one or more subcommands, list the commands here. If an option applies to the top-level app, omit this field, or include an empty `""` entry in the array. | |
128 | | -
|
129 | | -Example: |
130 | | -```toml |
131 | | -[[package.metadata.bashman.options]] |
132 | | -short = "-m" |
133 | | -long = "--manifest-path" |
134 | | -description = "Path to the Cargo.toml file to use." |
135 | | -label = "<Cargo.toml>" |
136 | | -path = true |
137 | | -
|
138 | | -[[package.metadata.bashman.options]] |
139 | | -short = "-c" |
140 | | -long = "--color" |
141 | | -description = "Use this foreground color." |
142 | | -label = "<NUM>" |
143 | | -subcommands = [ "print", "echo" ] |
144 | | -``` |
145 | | -
|
146 | | -### ARGUMENTS |
147 | | -
|
148 | | -A trailing argument is what comes after everything else. |
149 | | -
|
150 | | -| Key | Type | Description | |
151 | | -| --- | ---- | ----------- | |
152 | | -| label | *string* | A placeholder label for the value bit, like `<FILE(s)…>`. | |
153 | | -| description | *string* | A description for the argument. | |
154 | | -| subcommands | *array* | If this argument applies to one or more subcommands, list the commands here. If it applies to the top-level app, omit this field, or include an empty `""` entry in the array. | |
155 | | -
|
156 | | -Example: |
157 | | -```toml |
158 | | -[[package.metadata.bashman.arguments]] |
159 | | -label = "<FILE(s)…>" |
160 | | -description = "Files and directories to search." |
161 | | -subcommands = [ "search" ] |
162 | | -``` |
163 | | -
|
164 | | -### SECTIONS |
165 | | -
|
166 | | -`BashMan` will automatically generate manual sections for: |
167 | | - * `NAME` |
168 | | - * `DESCRIPTION` |
169 | | - * `USAGE` |
170 | | - * `SUBCOMMANDS` (if any) |
171 | | - * `FLAGS` (i.e. "switches", if any) |
172 | | - * `OPTIONS` (if any) |
173 | | - * `ARGUMENTS` (if any) |
174 | | -
|
175 | | -If you would like to include other information (for the top-level MAN page), such as a list of sister software repositories, you can do so by adding sections with the following fields: |
176 | | -
|
177 | | -| Key | Type | Description | |
178 | | -| --- | ---- | ----------- | |
179 | | -| name | *string* | The section name, e.g. `RECIPES`. | |
180 | | -| inside | *bool* | If `true`, the section will be indented (like most sections are). | |
181 | | -| lines | *array* | An array of paragraph lines (strings) to append. Line breaks are forced between entries, but you could jam everything into one string to just have it wrap. | |
182 | | -| items | *array* | An array of key/value pairs to list in a manner similar to how arguments are presented. Each entry should be an array with exactly two string values, `[ "Label", "A description or whatever." ]` | |
183 | | -
|
184 | | -Generally speaking, you'll want either "lines" or "items" for a given section, but not both. |
185 | | -
|
186 | | -Example: |
187 | | -```toml |
188 | | -[[package.metadata.bashman.sections]] |
189 | | -name = "FILE TYPES" |
190 | | -inside = true |
191 | | -lines = [ |
192 | | - "This program will search for files with the following extensions:", |
193 | | - ".foo; .bar; .img", |
194 | | -] |
195 | | -
|
196 | | -[[package.metadata.bashman.sections]] |
197 | | -name = "CREDITS" |
198 | | -inside = true |
199 | | -items = [ |
200 | | - ["Bob", "https://bob.com"], |
201 | | - ["Alice", "https://github.com/Alice"], |
202 | | -] |
203 | | -``` |
204 | | -
|
205 | | -### ALL TOGETHER NOW |
206 | | -
|
207 | | -Taking `BashMan` as an example, the `Cargo.toml` will end up containing something like: |
208 | | -```toml |
209 | | -[package.metadata.bashman] |
210 | | -name = "Cargo BashMan" |
211 | | -bash-dir = "../release/bash_completion.d" |
212 | | -man-dir = "../release/man1" |
213 | | -
|
214 | | -[[package.metadata.bashman.switches]] |
215 | | -short = "-h" |
216 | | -long = "--help" |
217 | | -description = "Print help information." |
218 | | -
|
219 | | -[[package.metadata.bashman.switches]] |
220 | | -short = "-V" |
221 | | -long = "--version" |
222 | | -description = "Print application version." |
223 | | -
|
224 | | -[[package.metadata.bashman.options]] |
225 | | -short = "-m" |
226 | | -long = "--manifest-path" |
227 | | -description = "Path to the Cargo.toml file to use." |
228 | | -label = "<Cargo.toml>" |
229 | | -path = true |
230 | | -``` |
231 | 3 | */ |
232 | 4 |
|
233 | 5 | #![forbid(unsafe_code)] |
|
0 commit comments