目标

下面我们演示如何在模块test-party中新建一个Cli命令,命令名全称为:test-party:default:demo

1. 定义Cli命令

src/suite-vendor/test-party/modules/test-party/backend/src/config/cli/command/default.demo.js

  1. 1module.exports = app => {
  2. 2 return {
  3. 3 bean: 'default.demo',
  4. 4 resource: {
  5. 5 atomStaticKey: 'cliDefaultDemo',
  6. 6 },
  7. 7 info: {
  8. 8 version: '4.0.0',
  9. 9 title: 'Cli Demo',
  10. 10 },
  11. 11 options: {
  12. 12 username: {
  13. 13 description: 'Your username',
  14. 14 alias: 'u',
  15. 15 type: 'string',
  16. 16 },
  17. 17 ...
  18. 18 },
  19. 19 groups: {
  20. 20 default: {
  21. 21 description: 'Your basic info',
  22. 22 condition: {
  23. 23 expression: null,
  24. 24 },
  25. 25 questions: {
  26. 26 username: {
  27. 27 type: 'input',
  28. 28 message: 'Your username',
  29. 29 },
  30. 30 ...
  31. 31 },
  32. 32 },
  33. 33 teacher: { ... },
  34. 34 student: { ... },
  35. 35 },
  36. 36 };
  37. 37};
名称 说明
bean 执行命令的bean组件
resource.atomStaticKey 与Cli命令绑定的资源Key,通过资源Key可以分配Open Auth访问权限
info 命令的version和title
options 命令支持的可选参数
groups 通过命令行收集用户输入信息的表单集,可以配置多个
groups.default 缺省表单
groups.default.description 表单描述,在进行收集之前打印到控制台
groups.default.condition 动态条件表达式。如果指定了表达式,就会进行运算求值,结果为真才使用此表单
groups.default.questions 表单字段清单,配置格式请参阅:enquirer

src/suite-vendor/test-party/modules/test-party/backend/src/config/cli/commands.js

  1. 1const defaultDemo = require('./command/default.demo.js');
  2. 2
  3. 3module.exports = app => {
  4. 4 const commands = {
  5. 5 default: {
  6. 6 demo: defaultDemo(app),
  7. 7 },
  8. 8 };
  9. 9 return commands;
  10. 10};
名称 说明
commands.default 将此Cli命令归入default分组

src/suite-vendor/test-party/modules/test-party/backend/src/meta.js

  1. 1// cli commands
  2. 2const cliCommands = require('./config/cli/commands.js')(app);
  3. 3...
  4. 4 cli: {
  5. 5 commands: cliCommands,
  6. 6 },
  7. 7...

2. 定义资源

src/suite-vendor/test-party/modules/test-party/backend/src/config/static/resources.js

  1. 1module.exports = app => {
  2. 2 const moduleInfo = app.meta.mockUtil.parseInfoFromPackage(__dirname);
  3. 3 const resources = [
  4. 4 // function
  5. 5 {
  6. 6 atomName: 'Cli Demo',
  7. 7 atomStaticKey: 'cliDefaultDemo',
  8. 8 atomRevision: 1,
  9. 9 atomCategoryId: 'a-base:function.Cli',
  10. 10 resourceType: 'a-base:function',
  11. 11 resourceConfig: null,
  12. 12 resourceRoles: 'template.system,RoleScopeCliDevelopment',
  13. 13 },
  14. 14 ...
  15. 15 ];
  16. 16 return resources;
  17. 17};
名称 说明
atomStaticKey 系统自动添加模块名称前缀,生成test-party:cliDefaultDemo
atomCategoryId 资源归属目录。资源类型全称a-base:function作为一级目录
resourceType 资源类型全称
resourceRoles 资源授权对象
  • 对于Cli命令而言,至少需要指定两个角色:

    • 首先,要解决哪些角色可以访问此资源的问题:这里是template.system

    • 其次,要解决哪些开放认证范围可以使用此资源的问题:这里是RoleScopeCliDevelopment

src/suite-vendor/test-party/modules/test-party/backend/src/meta.js

  1. 1// static
  2. 2const staticResources = require('./config/static/resources.js')(app);
  3. 3...
  4. 4 statics: {
  5. 5 'a-base.resource': {
  6. 6 items: staticResources,
  7. 7 },
  8. 8 },
  9. 9...

3. 定义Bean组件

src/suite-vendor/test-party/modules/test-party/backend/src/bean/cli.default.demo.js

  1. 1module.exports = ctx => {
  2. 2 class Cli extends ctx.app.meta.CliBase(ctx) {
  3. 3 async meta({ user }) {
  4. 4 const meta = await super.meta({ user });
  5. 5 return meta;
  6. 6 }
  7. 7 async execute({ user }) {
  8. 8 // super
  9. 9 await super.execute({ user });
  10. 10 // chalk
  11. 11 let text = this.helper.chalk.keyword('orange')('chalk test');
  12. 12 await this.console.log({ text });
  13. 13 // boxen
  14. 14 text = this.helper.boxen({ text: 'boxen test' });
  15. 15 await this.console.log({ text });
  16. 16 // table
  17. 17 const table = this.helper.newTable({
  18. 18 head: ['Name', 'Sex'],
  19. 19 colWidths: [20, 20],
  20. 20 });
  21. 21 table.push(['Tom', 'M']);
  22. 22 table.push(['Jane', 'F']);
  23. 23 await this.console.log({ text: 'table test' });
  24. 24 await this.console.log({ text: table.toString() });
  25. 25 // level one
  26. 26 await this._levelOne({ progressNo: 0 });
  27. 27 }
  28. 28 ...
  29. 29 }
  30. 30
  31. 31 return Cli;
  32. 32};
  • Cli命令继承自基类ctx.app.meta.CliBase

  • Cli命令只需实现两个方法:

    • meta:提供Cli命令的元数据,前端会使用此元数据完成所有的表单信息收集工作

    • execute:执行具体的命令逻辑

4. 注册Bean组件

src/suite-vendor/test-party/modules/test-party/backend/src/beans.js

  1. 1const cliDefaultDemo = require('./bean/cli.default.demo.js');
  2. 2...
  3. 3module.exports = app => {
  4. 4 const beans = {
  5. 5 // cli
  6. 6 'cli.default.demo': {
  7. 7 mode: 'ctx',
  8. 8 bean: cliDefaultDemo,
  9. 9 },
  10. 10 };
  11. 11};