App

Overview

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.

Create

    
    slatekit new cli -name="SampleCLI" -package="mycompany.apps"
    


Goals


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


Status

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



Install

    repositories {
        // other repositories
        maven { url  "http://dl.bintray.com/codehelixinc/slatekit" }
    }

    dependencies {
        // other dependencies ...

        compile 'com.slatekit:slatekit-cli:1.0.0'
    }

Back to top



Sources

Jar slatekit.cli.jar
Package slatekit.cli
Sources slatekit-cli
Example Example_CLI.kt
Version
License
Requires See build.gradle for more info.

Back to top



Example

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()
    }

Back to top



Concepts


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

Back to top



Guide


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

Back to top



Inputs

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"
Back to features Back to top


Reserved

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
Back to features Back to top


Args

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")
Back to features Back to top


Requests

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"))

        // ...
    }
Back to features Back to top


Execute

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"
                ))
    }
Back to features Back to top


Responses

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"
                ))
Back to features Back to top


Startup

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
    )
Back to features Back to top


API

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()
Back to features Back to top


From file

Back to features Back to top


Scripts

Back to features Back to top



Back to top