The Slate Kit CLI is a Command Line Interface application that provides
pre-built functionality for you to integrate your own commands in an interactie manner. This CLI offers 2 distinct approaches to integration. The first approach allows you to handle the raw text supplied in the CLI yourself and is the most flexible. The second approach provides a more connected, automatic experience by exposing, validating, and executing inputs against Slate Kit Universal APIs. You can create a CLI app quickly using the Slate Kit command line executable with the command below.
slatekit new cli -name="SampleCLI" -package="mycompany.apps"
Goal | Description |
1. Pre-Built CLI | Support for raw text, parsing, looping, formats, param types |
2. Flexible Use | Handle raw requests or leverage existing integration |
3. API Support | Slate Kit APIs are accessible on Web or CLI |
This component is currently stable and there is a project generator for it.
A small future enhancement will add support for question and answer flow.
Back to top
repositories {
// other repositories
maven { url "http://dl.bintray.com/codehelixinc/slatekit" }
}
dependencies {
// other dependencies ...
compile 'com.slatekit:slatekit-cli:1.0.0'
}
Jar | slatekit.cli.jar |
Package | slatekit.cli |
Sources | slatekit-cli |
Example | Example_CLI.kt |
Version | |
License | |
Requires | See build.gradle for more info. |
You can create a custom CLI by extending the Slate Kit CLI component or the CliAPI component which integrates nicely with Slate Kit APIs
import kotlinx.coroutines.runBlocking
import slatekit.results.*
import slatekit.cli.CLI
import slatekit.cli.CliRequest
import slatekit.cli.CliSettings
import slatekit.cli.CliResponse
class AppCLI(settings: CliSettings, serializer:(Any?, ContentType) -> Content)
: CLI(settings, Info.none, Folders.default, serializer = serializer) {
/**
* Use case 3a : ( OPTIONAL ) do some stuff before running any commands
*/
override suspend fun init(): Try<Boolean> {
// You don't need to override this as the base method displays help info
context.help.showHelp()
context.writer.highlight("\thook: onShellStart - starting myapp command line interface")
return Success(true)
}
/**
* Use case 3b : ( OPTIONAL ) do some stuff before ending the shell this is called
*/
override suspend fun end(status: Status): Try<Boolean> {
context.writer.highlight("\thook: onShellEnd - ending myapp command line interface")
return Success(true)
}
/**
* Handle execution of the CLI Request
*/
override suspend fun executeRequest(request: CliRequest): Try<CliResponse<*>> {
// Access the arguments
val title = request.args.getString("title"))
val date = request.args.getString("date"))
// Do something with the request
val res = Success("Processed " + request.path)
// 4. Now return the response
return res
}
}
// Serialization for output ( using Slate Kit default )
val serializer = { item:Any?, type: ContentType -> Content.csv(slatekit.meta.Serialization.csv().serialize(item) )}
// Create with default settings
val cli = AppCLI(CliSettings(), serializer)
// Begin the REPL (Read, Eval, Print, Loop )
runBlocking {
cli.run()
}
Component | Description |
CLI | The main component managing the interaction |
CliRequest | Represents the command entered |
CliResponse | Represents the output of the operation |
CliApi | Extends the CLI by integrating it with Slate Kit APIs |
Command | Reserved commands like about, version, help, quit, exit, etc |
Input Param | Parameter starting with - representing data for a command |
Meta Param | Parameter starting with @ representing metadata for a command |
System Param | Parameter starting with $ representing an instruction for the CLI |
9. Reference | Reference to command originating from a file |
Name | Description | More |
1. Inputs | Handling text and inputs | more |
2. Reserved | List of reserved commands | more |
3. Args | How to convert raw text into parsed parameters | more |
4. Requests | Working with parsed commands as CLI Requests | more |
5. Execute | How to execute a request | more |
6. Responses | Working with parsed commands as CLI Requests | more |
7. Startup | Load a command at start up | more |
8. API | How to access APIs on the command line | more |
9. From file | Load a command from a file | more |
10. Scripts | Run a series of commands in batch mode | more |
You can customize the CLI so that you can handle a) raw text / lines, b)have the text parsed into arguments, or c) have the text be converted and called as an API request. All these are valid depending on your configuration.
# Handle any text yourself
:> some free form text
# Use a arguments style structure
:> -email="user1@abc.com" -betaUser=true -promoCode=referral
# Leverage use of Slate Kit Universal APIs by specifying the 3 part route
:> manage.movies.createSample -title="Dark Knight" -date="2013-07-18"
There are several built-in reserved commands. See Reserved.kt for more info
Text | Aliases | Purpose |
exit | quit | Exits the CLI |
version | n/a | Gets the current version of the CLI |
about | help, info | Gets help text about the CLI and how to use commands |
The raw text / line is parsed into command line args using the Args
# Leverage use of Slate Kit Universal APIs by specifying the 3 part route
:> manage.movies.createSample -title="Dark Knight" -date="2013-07-18"
args.getString("title")
args.getLocalDate("date")
The raw text line, after being parsed into command line arguments is converted into a CliRequest object which you can then use to execute your commands.
/**
* Handle execution of the CLI Request
*/
override suspend fun executeRequest(request: CliRequest): Try<CliResponse<*>> {
// 1. Here is where you can put in your code to handle the command.
println("running command")
// 2. You have access to all the command fields and arguments.
// NOTES:
// - The command is parsed into [slatekit.common.args.Args]
// - The Args component is put inside [slatekit.cli.CliRequest]
// This gets you the raw text/line
println("line : " + request.args.line)
// This returns the list of action names before arguments. e.g. ["manage", "movies", "createSample"]
println("parts : " + request.parts)
println("path : " + request.fullName)
// This is useful if leveraging the 3 part routing system for Slate Kit APIs
println("area : " + request.area)
println("api : " + request.name)
println("action : " + request.action)
// Access the arguments
println("arg # : " + request.args.size())
println("arg 1 : " + request.args.getString("title"))
// ...
}
To execute the command, you can override the executeRequest method
/**
* Handle execution of the CLI Request
*/
override suspend fun executeRequest(request: CliRequest): Try<CliResponse<*>> {
// Access the arguments
val title = request.args.getString("title"))
val date = request.args.getLocalDate("date"))
// Process...
// Return
return Success(
CliResponse(
request = request,
success = true,
code = Codes.SUCCESS.code,
meta = mapOf(),
value = "Sample Response",
msg = "Processed",
err = null,
tag = "tag-123"
))
}
You must return a CliResponse upon execution. This leverages the Slate Kit Result
return Success(
CliResponse(
request = request,
success = true,
code = Codes.SUCCESS.code,
meta = mapOf(),
value = "Sample Response",
msg = "Processed",
err = null,
tag = "tag-123"
))
You can have commands run during the start up of the CLI. This is accomplished by supplying a list of String text commands to the CLI during construction in the commands parameter.
open class CLI(
val settings: CliSettings,
val info: Info,
val folders: Folders?,
val callback: ((CLI, CliRequest) -> CliResponse<*>)? = null,
commands: List<String?>? = listOf(),
ioReader: ((Unit) -> String?)? = null,
ioWriter: ((CliOutput) -> Unit)? = null,
val serializer:(Any?, ContentType) -> Content
)
The most important and powerful feature of the CLI is integration with Slate Kit APIs. Refer to Sample for more info.
// 1. The API keys( DocApi, SetupApi are authenticated using an sample API key )
val keys = listOf(ApiKey( name ="cli", key = "abc", roles = "dev,qa,ops,admin"))
// 2. Authentication
val auth = Authenticator(keys)
// 3. Load all the Slate Kit Universal APIs
val apis = listOf(
slatekit.apis.core.Api(
klass = SampleApi::class,
singleton = SampleApi(ctx)
)
)
// 4. Makes the APIs accessible on the CLI runner
val cli = CliApi(
ctx = ctx,
auth = auth,
settings = CliSettings(enableLogging = true, enableOutput = true),
apiItems = apis,
metaTransform = {
listOf("api-key" to keys.first().key)
},
serializer = {item, type -> Content.csv(slatekit.meta.Serialization.csv().serialize(item))}
)
// 5. Run interactive mode
return cli.run()