This issue changes the Fn CLI to use a [verb][noun] structure, resulting in a more intuitive, human-readable approach that would bring a consistent feel to the CLI. It is a common pattern among other CLI's that developers may be using alongside Fn. (A more detailed analysis of the Fn CLI and other CLI's can be found here: CLI Analysis)
The Verb Noun matrix shows how many of the nouns are unrelated to a verb. Therefore these should be their own high-level commands along with all other verbs:
| verbs |
nouns |
| build |
app[s] |
| bump |
call[s] |
| call |
config |
| create |
context |
| delete |
lambda |
| deploy |
logs |
| get |
route[s] |
| help |
server |
| import |
|
| init |
|
| list |
|
| pull? |
|
| run |
|
| set |
|
| start |
|
| stop |
|
| test |
|
| update |
|
| use |
|
There is confusion about the use of apps/routes vs app/route (singular use of app/route/call/image). Looking back at Singular vs Plural the use of both plural and singular nouns are both valid:
~ $ fn create app/apps <app>
~ $ fn delete route/routes <app> </route>
When using 'fn get' and 'fn list', get is used to return a single object, specificly a function call, and list is used to return multiple apps/routes/calls etc. The command 'inspect' allows you to retrieve on or all apps/routes properties. However, this essentially performs the same as 'get' and will, therefore, be deprecated.
~ $ fn list apps
java-app
string-reverse-app
~ $ fn list routes java-app
/hello-java-function <dockerhub_username>/hello2:0.0.2 localhost:8080/r/java-app/hello-java-function
/test-route <dockerhub_username>/hello2:0.0.2 localhost:8080/r/java-app/test-route
~ $ fn list calls <app>
ID: 01C9RQPM7G47WG200000000000
App: java-app
Route: /hello-java-function
Created At: 2018-03-29T11:18:49.840Z
Started At: 2018-03-29T11:18:50.366Z
Completed At: 2018-03-29T11:18:50.367Z
Status: success
ID: 01C9RG0N7147WGA00000000000
App: java-app
Route: /test-route
Created At: 2018-03-29T09:04:29.921Z
Started At: 2018-03-29T09:04:30.432Z
Completed At: 2018-03-29T09:04:30.441Z
Status: success
All subcommands of 'fn images' exist as top-level commands, this makes the use of images redundant and will be removed:
~ $ fn images build/bump/call/deploy/push/run/test ...
~ $ fn build/bump/call/deploy/push/run/test ...
Logical Grouping of Verbs
Its common practice for other CLI's to logically group commands together within the help text, this makes it easier for developers to scan through a more structure help text.
| Management |
Development |
Server |
Other |
Removed |
| create |
build |
start |
help |
apps |
| delete |
bump |
stop |
version |
routes |
| get |
call |
stop |
|
inspect |
| list |
deploy |
|
|
calls |
| set |
import |
|
|
logs |
| update |
init |
|
|
images |
| run |
push |
|
|
|
|
test |
|
|
|
Help Text:
The result of fn help would be as follows:
Fn command line tool
ENVIRONMENT VARIABLES:
FN_API_URL - Fn server address
FN_REGISTRY - Docker registry to push images to, use username only to push to Docker Hub - [[registry.hub.docker.com/]USERNAME]
SERVER COMMANDS:
start start a functions server
stop stop a functions server
pull | update | upgrade ? pulls latest functions server
MANAGEMENT COMMANDS:
create, c create a new object
delete, d delete an object
get, g get information or properties for an object
list, l list all instances of an object
set, s set features or properties for an object
unset unset features or properties for an object
update, u update an object
DEVELOPMENT COMMANDS:
build build function version
bump bump function version
call call a remote function
deploy deploys a function to the functions server. (bumps, build, pushes and updates route)
import import an existing external function
init create a local func.yaml file
push push function to Docker Hub
run run a function locally
test run functions test if present
OTHER COMMANDS:
help shows a list of commands or help for one command
version displays server and cli versions
GLOBAL OPTIONS:
--verbose, -v use --verbose to enable verbose mode for debugging
--help, -h show help
--version print only the cli version
LEARN MORE:
https://github.com/fnproject/fn
Help Text for Commands/Verbs
create, c
COMMANDS:
app create a new app
context create a new context
route create a new route
EXAMPLE:
fn create app <app>
fn create context <context>
fn create route <app> </path>
delete, d
COMMANDS:
app delete an app
context delete a context
route delete a route
EXAMPLE:
fn delete app <app>
fn delete route <app> </path>
update, u
COMMANDS:
app create an app
route update a route
EXAMPLE:
fn update app <app>
fn update context <context> <args>
fn update route <app> </path>
get, g
COMMANDS:
app get a specified app
config get configuration for apps and routes
context get context
call get a specified call
logs get logs for a call
route get a specified route
EXAMPLE:
fn get app <app>
fn get route <app> </path>
fn get config app <app> <key>
fn get call <app> [<call-id> | last]
fn get logs <app> [<call-id> | last]
set, s
COMMANDS:
config set configuration for apps and routes
EXAMPLE:
fn set config app <app> <key> <value>
fn set config route <app> </path> <key> <value>
unset
COMMANDS:
config unset configuration for apps and routes
EXAMPLE:
fn unset config app <app> <key>
fn unset config route <app> </path> <key>
list, l
COMMANDS:
apps display all apps
routes display all routes for specific
calls display all calls
config display all configs for apps and routes
EXAMPLE:
fn list apps
fn list routes <app> (specific to an app)
fn list calls <app> (specific to an app)
fn list config <app>
fn list config <app> </path>
run
NAME:
fn run - run a function locally
USAGE:
fn run [command options] [arguments...]
OPTIONS:
--env value, -e value select environment variables to be sent to function
--link value select container links for the function
--method value http method for function
--format default format to use. default and `http` (hot) formats currently supported.
--runs runs for hot functions only, will call the function runs times in a row. (default: 0)
--memory value RAM to allocate for function, Units: MB (default: 0)
--no-cache Don't use Docker cache for the build
test
NAME:
fn test - run functions test if present
USAGE:
fn test [command options] [arguments...]
OPTIONS:
--remote value run tests against a remote fn server
call
EXAMPLE:
fn call <app> </path>
init
NAME:
fn init - create a local func.yaml file
USAGE:
fn init [command options] [FUNCTION_NAME]
DESCRIPTION:
Creates a func.yaml file in the current directory.
OPTIONS:
--name value name of the function. Defaults to directory name in lowercase.
--force overwrite existing func.yaml
--runtime value choose an existing runtime - dotnet, go, java8, java9, java, lambda-nodejs4.3, lambda-node-4, node, php, python, python3.6, ruby, rust, kotlin
--entrypoint value entrypoint is the command to run to start this function - equivalent to Dockerfile ENTRYPOINT.
--cmd value command to run to start this function - equivalent to Dockerfile CMD.
--version value set initial function version (default: "0.0.1")
--image value, -i value image name
--memory value, -m value memory in MiB (default: 0)
--type value, -t value route type - sync or async
--config value, -c value route configuration
--headers value route response headers
--format value, -f value hot container IO format - default or http
--timeout value route timeout (eg. 30) (default: 0)
--idle-timeout value route idle timeout (eg. 30) (default: 0)
deploy
NAME:
fn deploy - deploys a function to the functions server. (bumps, build, pushes and updates route)
USAGE:
fn deploy [command options] [arguments...]
OPTIONS:
--app value app name to deploy to
--verbose, -v verbose mode
--no-cache Don't use Docker cache for the build
--local, --skip-push does not push Docker built images onto Docker Hub - useful for local development.
--registry --registry username Sets the Docker owner for images and optionally the registry. This will be prefixed to your function name for pushing to Docker registries. eg: --registry username will set your Docker Hub owner. `--registry registry.hub.docker.com/username` will set the registry and owner.
--all app.yaml if in root directory containing app.yaml, this will deploy all functions
bump
NAME:
fn bump - bump function version
USAGE:
fn bump [command options] [arguments...]
OPTIONS:
--major bumps major version
--minor bumps minor version
--verbose, -v verbose mode
build
NAME:
fn build - build function version
USAGE:
fn build [command options] [arguments...]
OPTIONS:
-v verbose mode
--no-cache Don't use docker cache
push
NAME:
fn push - push function to Docker Hub
USAGE:
fn push [command options] [arguments...]
OPTIONS:
-v verbose mode
--registry --registry username Sets the Docker owner for images and optionally the registry. This will be prefixed to your function name for pushing to Docker registries. eg: --registry username will set your Docker Hub owner. `--registry registry.hub.docker.com/username` will set the registry and owner.
import
NAME:
fn import - import an existing external function
USAGE:
fn import [command] [command options] <arn> <region> <image/name>
COMMANDS:
lamba
OPTIONS:
--payload value Payload to pass to the function. This is usually a JSON object. (default: "{}")
--version value Version of the function to import. (default: "$LATEST")
--download-only Only download the function into a directory. Will not create a Docker image.
--config value function configuration
start
NAME:
fn start - start a functions server container
USAGE:
fn start [command] [command options] [arguments...]
OBJECTS:
server
OPTIONS:
--detach, -d Run container in background.
--env-file <value> Path to Fn server configuration file.
--log-level <value> --log-level debug to enable debugging
--port, -p <value> Specify the port on which to expose the running server image.
stop
NAME:
fn stop - stop a functions server
USAGE:
fn stop [command]
OBJECTS:
server
pull / upgrade
NAME:
fn [pull | upgrade] - pulls latest functions server
USAGE:
fn [pull | upgrade] [command]
COMMANDS:
server
version
NAME:
fn version - displays cli and server versions
USAGE:
fn version [arguments...]
help, h
EXAMPLE:
fn help
fn help create
fn help apps
Help Text for Objects/Nouns
app[s]
~ fn help [app | apps]
USAGE:
fn command [app | apps] [command options] <app>
COMMANDS:
create, c create a new app
update, u update an `app`
list, l list all apps
delete, d delete an app
call[s]
~ fn help [call | calls]
USAGE:
fn command [call | call] [command options] [argument...]
COMMANDS:
get, g get function call info per app
list, l list all calls for the specific app. Route is optional
route[s]
~ fn help [route | routes]
USAGE:
fn command [route | routes] [command options] <app> </path>
COMMANDS:
call call a route
list, l list routes for `app`
create, c create a route in an `app`
update, u update a route in an `app`
config operate a route configuration set
delete, d delete a route from `app`
config
~ fn help config
USAGE:
fn command config [app | route] [command options] [argument...]
COMMANDS:
set, s store a configuration key for this route
get, g get configuration key for this route
list, l list configuration key/value pairs for this route
unset, u remove a configuration key for this route
context[s]
~ fn help context
USAGE:
fn <command> context <context> [command options] [argument...]
COMMANDS:
create, c create a new context
delete, d delete context <context>
get, g display the details of a context
list, l list all contexts
update, u update a key/value pair in a context
use change the currently selected context
logs
~ fn help logs
USAGE:
fn command logs [command options] [argument...]
COMMANDS:
get, g get logs for a call. Must provide call_id or last to retrieve the most recent calls logs.
server
~ fn help server
USAGE:
fn command server [command options] [argument...]
COMMAND:
start start a function server
stop stop a function server
pull | upgrade ? pulls latest functions server
lambda
~ fn help lambda
USAGE:
fn command lambda [command options] [arguments...]
COMMANDS:
import import an existing function to an image, where the function code is downloaded to a directory in the current working directory that has the same name as the function.
Examples:
Developer user experience (initial):
~ $ fn init --runtime java <app>
~ $ fn run
~ $ fn create route <app> </path> --image <image>
~ $ fn list routes <app>
~ $ fn deploy --app <app>
~ $ fn call <app> </path>
~ $ fn list calls <app>
~ $ fn get calls <app> [<call-id> | last]
Trouble Shooting:
~ $ fn get logs <app> [<call-id> | last]
~ $ fn list calls <app>
~ $ fn get calls <app> [<call-id> | last]
Configuration Management Process
~ $ fn set app config <app> <key> <value>
~ $ fn set route config <app> </path> <key> <value>
~ $ fn get app config <app> </path> <key>
~ $ fn get route config <app> </path> <key>
~ $ fn unset app config <app> <key>
~ $ fn unset route config <app> </path> <key>
~ $ fn list apps config <app>
~ $ fn list routes config <app> </path>
Current Bugs
The global options, such as verbose, help and version should be non-positional. In order to enable verbose mode for debugging users must put --verbose/-v in a specific position:
~ $ fn --verbose deploy --app <app> --local ...
However, if --verbose is positioned anywhere else, it is not picked up:
~ $ fn deploy --verbose ...
~ $ fn deploy --app <app> --verbose ...
Users should be able to position the global options at any point after 'fn' within the command.
This issue changes the Fn CLI to use a [verb][noun] structure, resulting in a more intuitive, human-readable approach that would bring a consistent feel to the CLI. It is a common pattern among other CLI's that developers may be using alongside Fn. (A more detailed analysis of the Fn CLI and other CLI's can be found here: CLI Analysis)
The Verb Noun matrix shows how many of the nouns are unrelated to a verb. Therefore these should be their own high-level commands along with all other verbs:
There is confusion about the use of apps/routes vs app/route (singular use of
app/route/call/image). Looking back at Singular vs Plural the use of both plural and singular nouns are both valid:When using 'fn get' and 'fn list', get is used to return a single object, specificly a function call, and list is used to return multiple apps/routes/calls etc. The command 'inspect' allows you to retrieve on or all apps/routes properties. However, this essentially performs the same as 'get' and will, therefore, be deprecated.
All subcommands of 'fn images' exist as top-level commands, this makes the use of images redundant and will be removed:
Logical Grouping of Verbs
Its common practice for other CLI's to logically group commands together within the help text, this makes it easier for developers to scan through a more structure help text.
Help Text:
The result of
fn helpwould be as follows:Help Text for Commands/Verbs
create, c
delete, d
update, u
get, g
set, s
unset
list, l
run
test
call
init
deploy
bump
build
push
import
start
stop
pull / upgrade
version
help, h
Help Text for Objects/Nouns
app[s]
call[s]
route[s]
config
context[s]
logs
server
lambda
Examples:
Developer user experience (initial):
Trouble Shooting:
Configuration Management Process
Current Bugs
The global options, such as verbose, help and version should be non-positional. In order to enable verbose mode for debugging users must put --verbose/-v in a specific position:
However, if --verbose is positioned anywhere else, it is not picked up:
Users should be able to position the global options at any point after 'fn' within the command.