Skip to content

Latest commit

 

History

History
227 lines (165 loc) · 5.96 KB

PRE_CORE_MIGRATION.md

File metadata and controls

227 lines (165 loc) · 5.96 KB

Migrating to @oclif/core from deprecated libraries

Migrating to @oclif/core from the deprecated oclif libraries (@oclif/config, @oclif/command, @oclif/error, @oclif/parser) is relatively straight forward.

Update Imports

Replace imports from the old libraries with @oclif/core. For example,

import Help from '@oclif/plugin-help';
import {Topic} from '@oclif/config';
import {Command, Flags} from '@oclif/command'

With this import:

import {Command, Flags, Topic, Help} from '@oclif/core';

Update Command Args

We updated the Command.args to more closely resemble flags

Before

import { Command } from '@oclif/core'

export default MyCommand extends Command {
  static args = [{name: arg1, description: 'an argument', required: true}]

  public async run(): Promise<void> {
    const {args} = await this.parse(MyCommand) // args is useless {[name: string]: any}
  }
}

After

import { Command, Args } from '@oclif/core'

export default MyCommand extends Command {
  static args = {
    arg1: Args.string({description: 'an argument', required: true})
  }

  public async run(): Promise<void> {
    const {args} = await this.parse(MyCommand) // args is { arg1: string }
  }
}

These are the available Args:

  • string
  • integer
  • boolean
  • url
  • file
  • directory
  • custom

Update your bin scripts

@oclif/core now supports separate bin scripts for production and development.

You can copy these new bin scripts directly from our example repository.

Add main to your package.json

We recommend that all oclif plugins specify the main field in their package.json so that we can begin working on supporting Yarn v2.

{
  "main": "lib/index.js"
}

All plugins will be required to have this field in the next major version of @oclif/core.

Restore -h, -v, and version

@oclif/config automatically added -h as a short flag for --help, -v as a short flag for --version, and version as an alias for --version.

@oclif/core removes these so you can now use those flags for whatever you want! However, we've added a way to restore that functionality if you want to keep it.

Simply add the additionalHelpFlags and additionalVersionFlags properties to the oclif section of your package.json:

{
  "oclif": {
    "additionalHelpFlags": ["-h"],
    "additionalVersionFlags": ["-v"]
  }
}

To get the version command, install @oclif/plugin-version into your CLI:

{
  "dependencies": {
    "@oclif/plugin-version": "^3"
  },
  "oclif": {
    "plugins": [
      "@oclif/plugin-version"
    ]
  }
}

Configure the topicSeparator

By default, the topicSeparator is set to a colon (:) to maintain backwards compatibility with existing CLIs. If you prefer, you can now set it to a space.

For colons:

{
  "oclif": {
    "topicSeparator": ":"
  }
}

For spaces:

{
  "oclif": {
    "topicSeparator": " "
  }
}

NOTE: Using colons always works, even if you set the topicSeparator to spaces. This means that you can enable spaces in your CLI without introducing a breaking change to your users.

Update this.parse to await this.parse

The parse method on Command is now asynchronous (more here). So you'll now need to await any calls to this.parse:

const { args, flags } = this.parse(MyCommand) => const { args, flags } = await this.parse(MyCommand)

Update default property on flag definitions

The default property on flag definitions is now asynchronous. So you'll now need to await those.

Example:

import {Command, Flags} from '@oclif/core'
import {readFile} from 'fs/promises'

function getTeam(): Promise<string> {
  return readFile('team.txt', 'utf-8')
}

export const team = Flags.build({
  char: 't',
  description: 'team to use',
  default: () => getTeam(),
})

export class MyCLI extends Command {
  static flags = {
    team: team(),
  }

  async run() {
    const {flags} = this.parse(MyCLI)
    if (flags.team) console.log(`--team is ${flags.team}`)
  }
}

Replace cli-ux library with ux

The cli-ux library has also been moved into @oclif/core in order to break a complex circular dependency between the two projects.

All the exports that were available from cli-ux are now available under the ux namespace, with the exception of the cli export which was identical to the ux export.

Old:

import { cli } from 'cli-ux`

cli.log('hello world')
cli.action.start('doing things')
cli.action.stop()

New:

import { ux } from '@oclif/core`

ux.log('hello world')
ux.action.start('doing things')
ux.action.stop()

Single command CLIs

Single command CLIs now are configured in a different way. To ensure your migrated CLI work as before, you have to add the following to your oclif configuration in the package.json:

"oclif": {
  "default": ".",
  "commands": "./lib"
}

Where ./lib points to the folder in which your tsconfig.json is configured to output to (if you are using TypeScript), and your single command CLI entrypoint index.(ts|js) is located.