Easily create CLIs using OCLIF
Case Study: Adobe I/O CLI

Shazron Abdullah

  • Sr. Computer Scientist
  • Adobe I/O Developer Tools
  • Open Source Contributor
    • Apache Cordova
    • Adobe PhoneGap
    • Apache OpenWhisk
    • ios-sim, ios-deploy

Adobe I/O CLI

  • we wrote our own
  • based on TJ Holowaychuk's `commander`
  • we added extensibility with a plugin system
  • then OCLIF was released (March 2018)...

The Open CLI Framework

  • written by Heroku, a PaaS (acquired by Salesforce)
  • the basis of Heroku CLI
  • open source! MIT-License
  • node.js based (TypeScript/JavaScript)
  • automatic doc generation
  • extensible! where it is most powerful
  • convention over configuration
  • oclif.io

OCLIF Extensibility

OCLIF Features

  • cli-ux
    • tree - formats data in a tree
    • action - shows a spinner
    • table - format data in columns
    • open - open in browser
  •  node-notifier for cross-platform OS notifications
  • listr for complex workflows like checklists

OCLIF Convention over Configuration

  • $ my-cli giphy:random
  • $ my-cli giphy:search 'cats'
  • $ my-cli giphy:trending --size=10
  • $ my-cli giphy

 

src
└── commands
    └── giphy
        ├── index.js
        ├── random.js
        ├── search.js
        ├── translate.js
        ├── trending.js
        └── upload.js

What's with the colon (:) ?

  • i.e. $ my-cli giphy:random
  • oclif philosophy:
    •  It helps the user know which arguments are the command and which are arguments to that command
  • ​harder to get adoption from hardened cli users
    • we solved it in aio-cli, with our custom changes to support space-separated commands

 

Example Command

const { Command, flags } = require('@oclif/command')

class RandomCommand extends Command {
  async run () {
    const { flags, args } = this.parse(RandomCommand)
    this.log(`args: ${JSON.stringify(args)}`)
    this.log(`flags: ${JSON.stringify(flags)}`)
    // TODO: call the Giphy API and get the first random gif
  }
}

RandomCommand.description = 'Grabs a random gif from giphy'

RandomCommand.args = [
  { 
    name: 'tag', 
    description: 'filters results by the specified tag',
    required: false
  }
]

RandomCommand.flags = {
  rating: flags.string({ 
      char: 'r', 
      description: 'filters results by specified rating', 
      default: 'g',
      options: [ 'y', 'g', 'pg', 'pg-13', 'r' ]
  })
}

module.exports = RandomCommand

Demo

# ##############################################
# NOTE: Every PLUGIN is also a stand-alone CLI!
# ##############################################

$ ./bin/run giphy:random --help
Grabs a random gif from giphy

USAGE
  $ my-cli giphy:random [TAG]

ARGUMENTS
  TAG  filters results by the specified tag

OPTIONS
  -r, --rating=y|g|pg|pg-13|r  [default: g] filters results by specified rating

Distribution

  • npm registry
  • Windows Installer
  • macOS Installer
  • Ubuntu/Debian packages
  • Snap packages (snapcraft.io)

 

Adobe I/O CLI

  • currently has three plugins included:
    • @adobe/aio-cli-plugin-config
    • @adobe/aio-cli-plugin-jwt-auth
    • @adobe/aio-cli-plugin-console
  • works with Adobe I/O Runtime
    • helps list and select Runtime integrations
    • aio-cli-plugin-runtime plugin to replace the `wsk` cli for OpenWhisk 
  • had its debut at Adobe Summit 2019 
  • your plugin? let us help you!

 

Contact, Links

  • twitter: shazron


Thank you!