github.com/criteo/command-launcher@v0.0.0-20230407142452-fb616f546e98/gh-pages/content/en/docs/overview/manifest.md (about) 1 --- 2 title: "Manifest.mf specification" 3 description: "Specification of manifest.mf file" 4 lead: "Specification of manifest.mf file" 5 date: 2022-10-02T19:02:32+02:00 6 lastmod: 2022-10-02T19:02:32+02:00 7 draft: false 8 images: [] 9 menu: 10 docs: 11 parent: "overview" 12 identifier: "manifest-c4f5d2abc378574f57d70f0ab85d24fb" 13 weight: 240 14 toc: true 15 --- 16 17 18 ## What is a manifest.mf file? 19 20 A manifest.mf file is a file located at the root of your command launcher package. It describes the commands packaged in the zip file. When cola installs a package, it reads the manifest file and registers the commands in the manifest file. 21 22 ## Format of manifest.mf 23 24 manifest.mf is in JSON or YAML format. It contains 3 fields: 25 26 - pkgName: a unique name of your package 27 - version: the version of your package 28 - cmds: a list of command definition, see command definition section 29 30 Here is an example 31 32 ```json 33 { 34 "pkgName": "hotfix", 35 "version": "1.0.0-44231", 36 "cmds": [ ... ] 37 } 38 ``` 39 40 ## Command Definition 41 42 > Command launcher is implemented with [cobra](https://github.com/spf13/cobra). It follows the same command concepts: 43 > 44 > Commands represent actions, Args are things and Flags are modifiers for those actions. 45 > 46 > The best applications read like sentences when used, and as a result, users intuitively know how to interact with them. 47 > 48 > The pattern to follow is APPNAME VERB NOUN --ADJECTIVE or APPNAME COMMAND ARG --FLAG. 49 > 50 > Each package contains multiple command definitions. You can specify following definition for your command: 51 52 ### Command properties list 53 54 | Property | Required | Description | 55 |--------------------|--------------------|------------------------------------------------------------------------------------------------------| 56 | name | yes | the name of your command | 57 | type | yes | the type of the command, `group` or `executable` | 58 | group | no | the group of your command belongs to, default, command launcher root | 59 | short | yes | a short description of your command, it will be display in auto-complete options | 60 | long | no | a long description of your command | 61 | argsUsage | no | custom the one line usage in help | 62 | examples | no | a list of example entries | 63 | executable | yes for executable | the executable to call when executing your command | 64 | args | no | the argument list to pass to the executable, command launcher arguments will be appended to the list | 65 | validArgs | no | the static list of options for auto-complete the arguments | 66 | validArgsCmd | no | array of string, command to run to get the dynamic auto-complete options for arguments | 67 | requiredFlags | no | the static list of options for the command flags (deprecated in 1.9) | 68 | flags | no | the flag list (available in 1.9+) | 69 | exclusiveFlags | no | group of exclusive flags (available in 1.9+) | 70 | groupFlags | no | group of grouped flags, which must be presented together (available in 1.9+) | 71 | checkFlags | no | whether check the flags defined in manifest before calling the command, default false | 72 | requestedResources | no | the resources that the command requested, ex, USERNAME, PASSWORD | 73 74 ## Command properties 75 76 ### name 77 78 The name of the command. A user uses the group and the name of the command to run it: 79 80 ```shell 81 cola {group} {name} 82 ``` 83 84 You must make sure your command's group and name combination is unique 85 86 ### type 87 88 There are three types of commands: `group`, `executable`, or `system` 89 90 An `executable` type of command is meant to be executed. You must fill the `executable` and `args` fields of an executable command. 91 92 A `group` type of command is used to group executable commands. 93 94 A `system` type of command is an executable command which extends the built-in command-launcher functions. More details see [system package](../system-package) 95 96 ### group 97 98 The group of your command. A user uses the group and the name of your command to run it: 99 100 ```shell 101 cola {group} {name} 102 ``` 103 104 You must make sure your command's group and name combination is unique 105 106 To registry a command at the root level of command launcher, set `group` to empty string. 107 108 > Note: command launcher only supports one level of group, the "group" field of a "group" type command is ignored. 109 110 **Example** 111 112 ```json 113 { 114 ... 115 "cmds": [ 116 { 117 "name": "infra", 118 "type": "group" 119 }, 120 { 121 "name": "reintall", 122 "type": "executable", 123 "group": "infra", 124 "executable": "{{.PackageDir}}/bin/reinstall", 125 "args": [] 126 } 127 ... 128 ] 129 } 130 ``` 131 132 The above manifest snippet registered a command: `cola infra reinstall`, when triggered, it will execute the `reinstall` binary located in the package's bin folder 133 134 ### short 135 136 The short description of the command. It is mostly used as the description in auto-complete options and the list of command in help output. Please keep it in a single line. 137 138 ### long 139 140 The long description of the command. In case your command doesn't support "-h" or "--help" flags, command launcher will generate one help command for you, and render your long description in the output. 141 142 ### argsUsage 143 144 Custom the one-line usage message. By default, command launcher will generate a one-line usage in the format of: 145 146 ```text 147 Usage: 148 APP_NAME group command_name [flags] 149 ``` 150 151 For some commands that accept multiple types of arguments, it would be nice to have a usage that show the different argument names and their orders. For example, for a command that accepts the 1st argument as country, and 2nd argument as city name, we can custom the usage message with following manifest: 152 153 ```json 154 { 155 ... 156 "cmds": [ 157 { 158 "name": "get-city-population", 159 "type": "executable", 160 "executable": "{{.PackageDir}}/bin/get-city-population.sh", 161 "args": [], 162 "argsUsage": "country city" 163 } 164 ... 165 ] 166 } 167 ``` 168 169 The help message looks like: 170 171 ```text 172 Usage: 173 cola get-city-population country city [flags] 174 ``` 175 176 ### examples 177 178 You can add examples to your command's help message. The `examples` property defines a list of examples for your command. Each example contains two fields: `scenario` and `command`: 179 180 - **scenario**, describes the use case. 181 - **cmd**, demonstrates the command to apply for the particular use case. 182 183 For example: 184 185 ```json 186 { 187 ... 188 "cmds": [ 189 { 190 "name": "get-city-population", 191 "type": "executable", 192 "executable": "{{.PackageDir}}/bin/get-city-population.sh", 193 "args": [], 194 "argsUsage": "country city" 195 "examples": [ 196 { 197 "scenario": "get the city population of Paris, France", 198 "cmd": "get-city-population France Paris" 199 } 200 ] 201 } 202 ... 203 ] 204 } 205 ``` 206 207 The help message looks like: 208 209 ```text 210 ... 211 212 Usage: 213 cola get-city-population country city [flags] 214 215 Example: 216 # get the city population of Paris, France 217 get-city-population France Paris 218 219 ... 220 ``` 221 222 ### executable 223 224 The executable to call when your command is trigger from command launcher. You can inject predefined variables in the executable location string. More detail about the variables see [Manifest Variables](./VARIABLE.md) 225 226 **Example** 227 228 ```json 229 { 230 ... 231 "cmds": [ 232 { 233 "executable": "{{.PackageDir}}/bin/my-binary{{.Extension}}" 234 } 235 ] 236 } 237 ``` 238 239 ### args 240 241 The arguments that to be appended to the executable when the command is triggered. The other arguments passed from command launcher will be appeneded after these arguments that are defined in `args` field. 242 243 **Example** 244 245 ```json 246 { 247 ... 248 "cmds": [ 249 { 250 "name": "crawler", 251 "type": "executable", 252 "group": "", 253 "executable": "java", 254 "args": [ "-jar", "{{.PackageDir}}/bin/crawler.jar"] 255 } 256 ] 257 } 258 ``` 259 260 When we call this command from command launcher: 261 262 ```shell 263 cola crawler --url https://example.com 264 ``` 265 266 It executes following command: 267 268 ```shell 269 java -jar {{package path}}/bin/crawler.jar --url https://example.com 270 ``` 271 272 Note: you can use variables in `args` fields as well. See [Variables](./VARIABLE.md) 273 274 ### validArgs 275 276 A static list of the arguments for auto-complete. 277 278 **Example** 279 280 ```json 281 { 282 "cmds": [ 283 { 284 "name": "population", 285 "type": "executable", 286 "group": "city", 287 "executable": "get-city-population", 288 "args": [], 289 "validArgs": [ 290 "paris", 291 "rome", 292 "london" 293 ] 294 } 295 ] 296 } 297 ``` 298 299 Once you have configured auto-complete for command launcher, the command described above will have auto-complete for its arguments. 300 301 When you type: `[cola] city population [TAB]`, your shell will prompt options: `paris`, `rome`, and `london` 302 303 ### validArgsCmd 304 305 A command to execute to get the dynamic list of arguments. 306 307 **Example** 308 309 ```json 310 { 311 "cmds": [ 312 { 313 "name": "population", 314 "type": "executable", 315 "group": "city", 316 "executable": "{{.PackageDir}}/bin/get-city-population", 317 "args": [], 318 "validArgsCmd": [ 319 "{{.PackageDir}}/bin/population-cities.sh", 320 "-H", 321 ] 322 } 323 ] 324 } 325 ``` 326 327 When you type `[cola] city poplution [TAB]`, command launcher will run the command specified in this field, and append all existing flags/arguments to the `validArgsCmd`. 328 329 More details see: [Auto-Complete](./AUTO_COMPLETE.md) 330 331 ### flags 332 333 > Available in 1.9+ 334 335 Define flags (options) of the command. Each flags could have the following properties 336 337 | Property | Required | Description | 338 |-----------|----------|-----------------------------------------------------------------------------------------------------| 339 | name | yes | flag name | 340 | short | no | flag short name, usually one letter | 341 | desc | no | flag description | 342 | type | no | flag type, default "string", currently support "string" and bool" | 343 | default | no | flag default value, only available for string type, bool flag's default is always false | 344 | required | no | boolean, is the flag required, default false | 345 | values | no | list of values for the flag for Auto-Complete. Available in 1.10.0+ | 346 | valuesCmd | no | list of string. The command to call to get available values for auto-complete. Available in 1.10.0+ | 347 348 **Example** 349 350 ```json 351 { 352 "cmds": [ 353 { 354 "name": "population", 355 "type": "executable", 356 "group": "city", 357 "executable": "get-city-population", 358 "args": [], 359 "validArgs": [ 360 "paris", 361 "rome", 362 "london" 363 ], 364 "flags": [ 365 { 366 "name": "human", 367 "short": "H", 368 "desc": "return the human readabe format", 369 "type": "bool" 370 } 371 ] 372 } 373 ] 374 } 375 ``` 376 377 ### exclusiveFlags 378 379 > Available in 1.9+ 380 381 Declare two or more flags are mutually exclusive. For example, a flag `json` that outputs JSON format will be exclusive to the flag `text`, which outputs in plain text format. 382 383 **Example** 384 385 ```json 386 { 387 "cmds": [ 388 { 389 "name": "population", 390 "type": "executable", 391 "group": "city", 392 "executable": "get-city-population", 393 "args": [], 394 "validArgs": [ 395 "paris", 396 "rome", 397 "london" 398 ], 399 "flags": [ 400 { 401 "name": "human", 402 "short": "H", 403 "desc": "return the human readabe format", 404 "type": "bool" 405 }, 406 { 407 "name": "json", 408 "short": "j", 409 "desc": "return the JSON format", 410 "type": "bool" 411 } 412 ], 413 "exclusiveFlags": [ 414 [ "human", "json" ] 415 ] 416 } 417 ] 418 } 419 ``` 420 421 ### groupFlags 422 423 > Available in 1.9+ 424 425 Ensure that two or more flags are presented at the same time. 426 427 **Example** 428 429 ```json 430 { 431 "cmds": [ 432 { 433 "name": "population", 434 "type": "executable", 435 "group": "city", 436 "executable": "get-city-population", 437 "args": [], 438 "flags": [ 439 { 440 "name": "country", 441 "short": "c", 442 "desc": "country name", 443 "required": true 444 }, 445 { 446 "name": "city", 447 "short": "t", 448 "desc": "city name" 449 } 450 ], 451 "groupFlags": [ 452 [ "country", "city" ] 453 ] 454 } 455 ] 456 } 457 ``` 458 459 ### requiredFlags 460 461 > Deprecated in 1.9, see [flags](./#flags) property 462 463 The static list of flags for your command 464 465 **Example** 466 467 ```json 468 { 469 "cmds": [ 470 { 471 "name": "population", 472 "type": "executable", 473 "group": "city", 474 "executable": "get-city-population", 475 "args": [], 476 "validArgs": [ 477 "paris", 478 "rome", 479 "london" 480 ], 481 "requiredFlags": [ 482 "human\t H\t return the human readable format", 483 ] 484 } 485 ] 486 } 487 ``` 488 489 It declares a `--human` flags with a short form: `-H` 490 491 The flag definition string uses `\t` to separate different fields. A complete fields can be found in the following table 492 493 | field position | field name | field description | 494 |----------------|--------------------|---------------------------------------------------------------------------------------------------| 495 | 1 | flag full name | the full name of the flags, usually in format of x-y-z, note: no need to include `--` in the name | 496 | 2 | flag short name | optional, the short name (one letter) for the flag | 497 | 3 | flag description | optional, the description of the flag name | 498 | 4 | flag type | optional, the flag type, one of string and bool. Default: string | 499 | 5 | flag default value | optional, the default value if not specified | 500 501 Beside the complete form, it is also possible to have a short form: 502 503 1. only the full name: ex. "user-name" 504 2. full name + description: ex. "user-name\t the user name" 505 3. full name + short name + description: ex. "user-name\t u\t the user name" 506 507 ### checkFlags 508 509 Whether parse and check flags before execute the command. Default: false. 510 511 The `requiredFlags` (deprecated in 1.9), `flags`, `validArgs` and `validArgsCmd` are mainly used for auto completion. Command launcher will not parse the flag and arguments by default, it will simply pass through them to the callee command. In other words, in this case, it is the callee command's responsibility to parse the flags and arguments. This works fine when the command is implemented with languages that has advanced command line supports, like golang. 512 513 For some cases, arguments parsing is difficult or has less support, for example, implementing the command in shell script. Enable `checkFlags` will allow command launcher to parse the arguments and catch errors. Further more, command launcher will pass the parsed flags and arguments to the callee command through environment variables: 514 515 - For flags: `COLA_FLAG_[FLAG_NAME]` ('-' is replaced with '_'). Example: flag `--user-name` is passed through environment variable `COLA_FLAG_USER_NAME` 516 517 - For arguments: `COLA_ARG_[INDEX]` where the index starts from 1. Example: command `cola get-city-population France Paris` will get environment variable `COLA_ARG_1=France` and `COLA_ARG_2=Paris`. An additional environment variable `COLA_NARGS` (available in 1.9+) is available as well to get the number of arguments. 518 519 > Even checkFlags is set to `true`, command launcher will still pass through the original arguments to the callee command as well, in addition, to the original arguments, parsed flags and arguments are passed to the callee as environment variables. 520 521 Another behavior change is that once `checkFlags` is enabled, the `-h` and `--help` flags are handled by command launcher. The original behavior is managed by the callee command itself. 522 523 ### requestedResources 524 525 Under the user consent, command launcher can pass several resources to the callee command, for example, the user credential collected and stored securely by the built-in `login` command. The `requestedResources` is used to request such resources. Command launcher will prompt user consent for the first time, and pass requested resources value to the callee command through environment variable. More detail see: [Manage resources](../resources) 526 527 The following snippet requests to access the user name and password resources. 528 529 ```json 530 { 531 "cmds": [ 532 { 533 "name": "population", 534 "type": "executable", 535 "group": "city", 536 "executable": "get-city-population", 537 "args": [], 538 "requestedResources": [ "USERNAME", "PASSWORD" ] 539 } 540 ] 541 } 542 ``` 543 544 ## System commands 545 546 Besides the [system command](../system-package/#system-commands) defined in a [system package](../system-package). You can define package level system command as a lifecycle hook. 547 548 ### \_\_setup\_\_ 549 550 When a package is installed, sometimes it requires some setups to make it work properly. For example, a command written in javascript could require a `npm install` to install all its dependencies. You can define a system command `__setup__` in your package as a normal command, with type `system`, it will be called when the package is installed. (You can disable this behavior, by turning the configuration `enable_package_setup_hook` to `false`). You can also manually trigger it through the built-in command: `cola package setup` 551 552 > Make sure the setup hook is idempotent, when a new version is installed the setup hook will be called again. 553 554 **Example** 555 556 ```yaml 557 pkgName: package-demo 558 version: 1.0.0 559 cmds: 560 - name: __setup__ 561 type: system 562 executable: "{{.PackageDir}}/hooks/setup-hook" 563 args: [ "predefined-arg1", "predefined-arg2" ] 564 - name: other-commands 565 type: executable 566 executable: "{{.PackageDir}}/scripts/other-cmd.sh" 567 ```