3.1.0 • Published 1 year ago

@oishi/cli-core v3.1.0

Weekly downloads
-
License
ISC
Repository
github
Last release
1 year ago

@oishi/cli-core

说明

这是一个整合了 commander 和 inquirer,用作创建脚本的底层框架。

使用该框架创建的命令行工具,一份配置通行交互式命令行和命令式命令行。

API

CliCore

框架的核心壳,用来创建声明初始命令行。

如下,创建一个空壳子,框架会自动注入 helpversion 等指令。

import { CliCore } from "@oishi/cli-core";

const cli = new CliCore({
  name: "cli",
  description: "常用命令行合集",
  version: "0.0.1",
  commands: [],
});

cli.execute();

使用,cli -hcli --version 查看信息。

# 查看帮助
$ cli -h

Usage: cli [options]

常用命令行合集

Options:
  -V, --version      output the version number
  -i, --interactive  交互式命令行 (default: false)
  -h, --help         display help for command

interactive

框架会自动注入 interactive 选项,当运行 cli -i 时,框架将会自动生成交互式命令行。

CliCommand

子命令对象,用来创建命令行的子命令集。

如下,创建一个最简单的命令行,我们希望程序给我们打个招呼,使用 cli say xxx 调用。

import { CliCommand } from "@oishi/cli-core";

interface IArgs {
  name: string;
}

interface IOpts {}

const say = new CliCommand<IArgs, IOpts>({
  command: "say",
  description: "say hello",
  arguments: {
    name: { description: "请输入您的名称" },
  },
  options: {},
  action({ data, logger, helper }) {
    logger.info(`hello ${data.name}`);
  },
});

创建完 CliCommand 之后,加入到 CliCorecommands 中即可。

import { CliCore } from "@oishi/cli-core";

const cli = new CliCore({
  name: "cli",
  description: "常用命令行合集",
  version: "0.0.1",
  commands: [say],
});

cli.execute();

如下调用,命令行将会输入对应信息。

# 执行指令
$ cli say jsjzh
20XX-XX-XXTXX:XX:XX.XXXZ [cli] info: hello jsjzh

command

required

子命令的名称,必传,接受字符串,比如传入了 say,则可以使用 cli say 调用。

description

required

子命令的描述,必传,接受字符串,传入的讯息将在 cli say -h 时显示。

arguments

optional

interface IArguments {
  description: string;
  default?: any | [any, string];
  choices?: string[];
  optional?: boolean;
  multiple?: boolean;
}

子命令的参数,这个和下面的 options 有些不同,该处参数一般为必填,且不用带前缀说明。

例子如下。

...
arguments: {
  name: { description: "请输入您的名称" }
}
...

如下,只需要直接输入 xxx 即可。

$ cli say xxx

options

optional

interface IOptions {
  description: string;
  default?: any | [any, string];
  alias?: string;
  choices?: string[];
  optional?: boolean;
  multiple?: boolean;
}

子命令的参数,需要携带前缀说明。

如果同上面的 arguments 的例子一样,options 也想要一个 name 的参数,该如何写呢?

例子如下。

...
options: {
  name: { description: "请输入您的名称" }
}
...

如下,需要增加前缀 --name 才行。

$ cli say --name xxx

commands

optional

子命令的命令集,CliCommand 支持嵌套方式,且命令行的命中模式为优先匹配命令集,直接说有些难理解,请看如下的例子。

const child = new CliCommand({
  command: "child",
  description: "child",
  action({ data, logger, helper }) {
    logger.info(`child`);
  },
});

const parent = new CliCommand({
  command: "parent",
  commands: [child],
  description: "parent",
  arguments: {
    name: { description: "请输入您的名称" },
  },
  options: {},
  action({ data, logger, helper }) {
    logger.info(`hello ${data.name}`);
  },
});

如上,在 parent 接收一个 arguments 时,parent 还有一个 commands,那程序如果运行 cli parent child,程序将如何匹配?

答案是优先匹配子命令集,将 cli parent child 传入的 child 当做是子命令集的触发,也就是会输出 child

所以,即使 parent 的参数中有 arguments,但如果传入的 arguments 和其子命令集的 command 重复,将会命中子命令集的任务。

Arguments

arguments 的对象描述如下

interface IArguments {
  description: string;
  default?: any | [any, string];
  choices?: string[];
  optional?: boolean;
  multiple?: boolean;
}
  • default 表示默认值,当没有传入值时,框架会传入默认值。
  • choices 表示可以输入的值,交互式的呈现是 list or checkbox(若开启 multiple) 选择,命令式的呈现是对输入进行验证。
  • optional 表示该参数是否可选,默认参数都为必选。若配置为 true,则交互式会跳过生成该条交互命令。
  • multiplechoices 配合使用,表示多选,输入的值会以数组的形式传入。

Options

interface IOptions {
  description: string;
  default?: any | [any, string];
  alias?: string;
  choices?: string[];
  optional?: boolean;
  multiple?: boolean;
}
  • alias 表示短缀,如 --build 设置 aliasb,则可使用 -b 调用。
  • default 表示默认值,当没有传入值时,框架会传入默认值。
  • choices 表示可以输入的值,交互式的呈现是 list or checkbox(若开启 multiple) 选择,命令式的呈现是对输入进行验证。
  • optional 表示该参数是否可选,默认参数都为必选。若配置为 true,则交互式会跳过生成该条交互命令。
  • multiplechoices 配合使用,表示多选,输入的值会以数组的形式传入。

Logger

如下为日志的严重程度,error 为 0,是最大 P0 级错误日志。

enum levels {
  error = 0,
  warn = 1,
  info = 2,
  http = 3,
  verbose = 4,
  debug = 5,
  silly = 6,
}

CliCommandaction 中接收一个 logger 方法,该方法是包装的 winston,该日志工具会以天为维度,记录 warnerror 等级的内容到 ~/logs/oishi/${cli} 中,文件最大为 20mb,会以滑动窗口的方式滚动记录最近 14 天的日志。

...
action({ data, logger, helper }) {
  logger.warn(`hello ${data.name}`);
}
...

Helper

框架提供了几个常用的工具。

runPrompt

创建交互式命令行。

const prompt = helper.runPrompt();

prompt.addInput({ name: "name", message: "请输入你的名字" });

prompt.execute((answers) => {
  console.log(answers);
});

runCron

创建定时任务。

helper.runCron({
  cronTime: "* * * * * *",
  onTick() {
    console.log("hello wrold");
  },
});

runCmd

创建命令行运行工具。

const run = helper.runCmd();

run("echo hello world");

runTask

创建任务链,方便管理任务顺序。

await helper
  .runTask({ hasTip: true })
  .add({
    title: "切换 registry 至 npm 源",
    async task() {
      run("npm set registry=https://registry.npmjs.org/");
    },
  })
  .add({
    title: "执行项目构建和发布",
    async task() {
      run("npm run build");
      run("npm publish");
    },
  })
  .add({
    title: "切换 registry 至国内镜像",
    async task() {
      run("npm set registry=https://registry.npmmirror.com/");
    },
  })
  .run();

待办

  • choices 和 default 允许传入 name value 的方式
  • 类型转换有问题,因为命令行解析的结果都是字符串,无法通过 ts 传入值来修改获取值
  • 后续 logger 可能可以支持自定义 winston transports
  • 添加更多的 inquirer 的输入类型支持
  • 命令运行时互相调用
2.0.7

1 year ago

2.0.6

1 year ago

3.0.3

1 year ago

3.0.2

1 year ago

3.0.1

1 year ago

3.0.0

1 year ago

3.1.0

1 year ago

2.0.3

1 year ago

2.0.2

1 year ago

2.0.5

1 year ago

2.0.4

1 year ago

2.0.1

1 year ago

2.0.0

1 year ago

1.0.14

1 year ago

1.0.2

1 year ago

1.0.1

1 year ago

1.0.0

1 year ago

1.0.9

1 year ago

1.0.8

1 year ago

1.0.7

1 year ago

1.0.6

1 year ago

1.0.5

1 year ago

1.0.4

1 year ago

1.0.3

1 year ago

1.0.11

1 year ago

1.0.10

1 year ago

1.0.13

1 year ago

1.0.12

1 year ago

0.0.51

3 years ago

0.0.50

4 years ago

0.0.49

4 years ago

0.0.48

4 years ago

0.0.47

4 years ago

0.0.46

4 years ago

0.0.45

4 years ago

0.0.44

4 years ago

0.0.43

4 years ago

0.0.42

4 years ago

0.0.40

4 years ago

0.0.41

4 years ago

0.0.38

4 years ago

0.0.39

4 years ago

0.0.36

4 years ago

0.0.36-3

4 years ago

0.0.36-2

4 years ago

0.0.36-1

4 years ago

0.0.36-0

4 years ago

0.0.35

4 years ago

0.0.33

4 years ago

0.0.32

4 years ago

0.0.31

4 years ago

0.0.24

4 years ago

0.0.25

4 years ago

0.0.26

4 years ago

0.0.27

4 years ago

0.0.28

4 years ago

0.0.21

4 years ago

0.0.22

4 years ago

0.0.23

4 years ago

0.0.20

4 years ago

0.0.19

4 years ago

0.0.17

4 years ago

0.0.18

4 years ago

0.0.16

4 years ago

0.0.15

4 years ago

0.0.13

4 years ago

0.0.12

4 years ago

0.0.11

4 years ago

0.0.10

4 years ago

0.0.9

4 years ago

0.0.5

4 years ago

0.0.4

4 years ago

0.0.6

4 years ago

0.0.3

4 years ago

0.0.2

4 years ago

0.0.1

4 years ago