code.cestus.io/tools/fabricator@v0.4.3/README.adoc (about) 1 = Fabricator 2 3 4 is a plugin enabled command line interface for the fabricator framework 5 6 == Goal 7 To allow a seamless migration from custom tools to a shared framework we will standardize the configuration DSL, but allow seperate plugins to provide the functionality. This will allow different users to have distinct implementations for code generation and other commands. 8 9 === Extend fabricator with plugins 10 This mechanic is highly inspired by the plugin mechanism of kubectl so most examples you find for that tool will be relevant for fabricator. 11 12 === Installing fabricator plugins 13 A plugin is a standalone executable file, whose name begins with `fabricator-`. To install a plugin, move its executable file to anywhere on your PATH. 14 Alternatively you can also add a search location with the --plugin-path flag or by setting the FABRICATOR_PLUGIN_PATH environment variable. If the `--plugin-path` flag is not set the current directory is added to the search locations by default 15 16 === Discovering plugins 17 `fabricator` provides a command `fabricator plugin list` that searches your path for valid plugin executables. 18 Executing this command causes a traversal of all files in your PATH. Any files that are executable, and begin with `fabricator-` will show up in the order in which they are present in your PATH in this command's output. A warning will be included for any files beginning with `fabricator-`` that are not executable. A warning will also be included for any valid plugin files that overlap each other's name. 19 20 ==== Limitations 21 It is not possible to create plugins that overwrite existing `fabricator` commands. For example, creating a plugin `fabricator-version` will cause that plugin to never be executed, as the existing `fabricator version` command will always take precedence over it. Due to this limitation, it is also not possible to use plugins to add new subcommands to existing `fabricator` commands. 22 `fabricator plugin list` shows warnings for any valid plugins that attempt to do this. 23 24 == Writing fabricator plugins 25 26 You can write a plugin in any programming language or script that allows you to write command-line commands. 27 28 There is no plugin installation or pre-loading required. Plugin executables receive the inherited environment from the `fabricator` binary. A plugin determines which command path it wishes to implement based on its name. For example, a plugin named `fabricator-foo` provides a command `fabricator foo`. You must install the plugin executable somewhere in your PATH. 29 30 === Example plugin 31 32 [source, bash] 33 ---- 34 #!/bin/bash 35 36 # optional argument handling 37 if [[ "$1" == "version" ]] 38 then 39 echo "1.0.0" 40 exit 0 41 fi 42 43 # optional argument handling 44 if [[ "$1" == "path" ]] 45 then 46 echo "$PATH" 47 exit 0 48 fi 49 50 echo "I am a plugin named fabricator-foo" 51 ---- 52 53 === Using a plugin 54 To use a plugin, make the plugin executable: 55 56 [source, bash] 57 ---- 58 sudo chmod +x ./kubectl-foo 59 ---- 60 61 you may now invoke your plugin as a `fabricator` command 62 [source, bash] 63 ---- 64 fabricator foo 65 ---- 66 67 ---- 68 I am a plugin named fabricator foo 69 ---- 70 All args and flags are passed as-is to the executable 71 [source, bash] 72 ---- 73 kubectl foo version 74 ---- 75 76 ---- 77 1.0.0 78 ---- 79 80 == Naming a plugin 81 82 As seen in the example above, a plugin determines the command path that it will implement based on its filename. Every sub-command in the command path that a plugin targets, is separated by a dash (-). For example, a plugin that wishes to be invoked whenever the command `fabricator foo bar baz` is invoked by the user, would have the filename of `fabricator-foo-bar-baz`. 83 84 == Flags and argument handling 85 fabricator plugins must parse and validate all of the arguments passed to them. 86 87 Here are some additional cases where users invoke your plugin while providing additional flags and arguments. This builds upon the `fabricator-foo-bar-baz` plugin from the scenario above. 88 89 If you run `fabricator foo bar baz arg1 --flag=value arg2`, fabricator's plugin mechanism will first try to find the plugin with the longest possible name, which in this case would be `fabricator-foo-bar-baz-arg1`. Upon not finding that plugin, fabricator then treats the last dash-separated value as an argument (`arg1` in this case), and attempts to find the next longest possible name, `fabricator-foo-bar-baz`. Upon having found a plugin with this name, fabricator then invokes that plugin, passing all args and flags after the plugin's name as arguments to the plugin process. 90 91 So in this case the `fabricator-foo-bar-baz` plugin would receive `arg1` as the first argument.