cac

授权协议 MIT License
开发语言 JavaScript
所属分类 应用工具、 终端/远程登录
软件类型 开源软件
地区 不详
投 递 者 郏实
操作系统 跨平台
开源组织
适用人群 未知
 软件概览

2017-07-26 9 27 05

Introduction

Command And Conquer is a JavaScript library for building CLI apps.

Features

  • Super light-weight: No dependency, just a single file.
  • Easy to learn. There're only 4 APIs you need to learn for building simple CLIs: cli.option cli.version cli.help cli.parse.
  • Yet so powerful. Enable features like default command, git-like subcommands, validation for required arguments and options, variadic arguments, dot-nested options, automated help message generation and so on.
  • Developer friendly. Written in TypeScript.

Table of Contents

Install

yarn add cac

Usage

Simple Parsing

Use CAC as simple argument parser:

// examples/basic-usage.js
const cli = require('cac')()

cli.option('--type <type>', 'Choose a project type', {
  default: 'node'
})

const parsed = cli.parse()

console.log(JSON.stringify(parsed, null, 2))

2018-11-26 12 28 03

Display Help Message and Version

// examples/help.js
const cli = require('cac')()

cli.option('--type [type]', 'Choose a project type', {
  default: 'node'
})
cli.option('--name <name>', 'Provide your name')

cli.command('lint [...files]', 'Lint files').action((files, options) => {
  console.log(files, options)
})

// Display help message when `-h` or `--help` appears
cli.help()
// Display version number when `-v` or `--version` appears
// It's also used in help message
cli.version('0.0.0')

cli.parse()

2018-11-25 8 21 14

Command-specific Options

You can attach options to a command.

const cli = require('cac')()

cli
  .command('rm <dir>', 'Remove a dir')
  .option('-r, --recursive', 'Remove recursively')
  .action((dir, options) => {
    console.log('remove ' + dir + (options.recursive ? ' recursively' : ''))
  })

cli.help()

cli.parse()

A command's options are validated when the command is used. Any unknown options will be reported as an error. However, if an action-based command does not define an action, then the options are not validated. If you really want to use unknown options, use command.allowUnknownOptions.

command options

Dash in option names

Options in kebab-case should be referenced in camelCase in your code:

cli
  .command('dev', 'Start dev server')
  .option('--clear-screen', 'Clear screen')
  .action(options => {
    console.log(options.clearScreen)
  })

In fact --clear-screen and --clearScreen are both mapped to options.clearScreen.

Brackets

When using brackets in command name, angled brackets indicate required command arguments, while square bracket indicate optional arguments.

When using brackets in option name, angled brackets indicate that a string / number value is required, while square bracket indicate that the value can also be true.

const cli = require('cac')()

cli
  .command('deploy <folder>', 'Deploy a folder to AWS')
  .option('--scale [level]', 'Scaling level')
  .action((folder, options) => {
    // ...
  })

cli
  .command('build [project]', 'Build a project')
  .option('--out <dir>', 'Output directory')
  .action((folder, options) => {
    // ...
  })

cli.parse()

Negated Options

To allow an option whose value is false, you need to manually specify a negated option:

cli
  .command('build [project]', 'Build a project')
  .option('--no-config', 'Disable config file')
  .option('--config <path>', 'Use a custom config file')

This will let CAC set the default value of config to true, and you can use --no-config flag to set it to false.

Variadic Arguments

The last argument of a command can be variadic, and only the last argument. To make an argument variadic you have to add ... to the start of argument name, just like the rest operator in JavaScript. Here is an example:

const cli = require('cac')()

cli
  .command('build <entry> [...otherFiles]', 'Build your app')
  .option('--foo', 'Foo option')
  .action((entry, otherFiles, options) => {
    console.log(entry)
    console.log(otherFiles)
    console.log(options)
  })

cli.help()

cli.parse()

2018-11-25 8 25 30

Dot-nested Options

Dot-nested options will be merged into a single option.

const cli = require('cac')()

cli
  .command('build', 'desc')
  .option('--env <env>', 'Set envs')
  .example('--env.API_SECRET xxx')
  .action(options => {
    console.log(options)
  })

cli.help()

cli.parse()

2018-11-25 9 37 53

Default Command

Register a command that will be used when no other command is matched.

const cli = require('cac')()

cli
  // Simply omit the command name, just brackets
  .command('[...files]', 'Build files')
  .option('--minimize', 'Minimize output')
  .action((files, options) => {
    console.log(files)
    console.log(options.minimize)
  })

cli.parse()

Supply an array as option value

node cli.js --include project-a
# The parsed options will be:
# { include: 'project-a' }

node cli.js --include project-a --include project-b
# The parsed options will be:
# { include: ['project-a', 'project-b'] }

Error Handling

To handle command errors globally:

try {
  // Parse CLI args without running the command
  cli.parse(process.argv, { run: false })
  // Run the command yourself
  // You only need `await` when your command action returns a Promise
  await cli.runMatchedCommand()
} catch (error) {
  // Handle error here..
  // e.g.
  // console.error(error.stack)
  // process.exit(1)
}

With TypeScript

First you need @types/node to be installed as a dev dependency in your project:

yarn add @types/node --dev

Then everything just works out of the box:

const { cac } = require('cac')
// OR ES modules
import { cac } from 'cac'

With Deno

import { cac } from 'https://unpkg.com/cac/mod.ts'

const cli = cac('my-program')

Projects Using CAC

Projects that use CAC:

  • VuePress: �� Minimalistic Vue-powered static site generator.
  • SAO: ⚔️ Futuristic scaffolding tool.
  • DocPad: �� Powerful Static Site Generator.
  • Poi: ⚡️ Delightful web development.
  • bili: �� Schweizer Armeemesser for bundling JavaScript libraries.
  • Lad: �� Lad scaffolds a Koa webapp and API framework for Node.js.
  • Lass: ���� Scaffold a modern package boilerplate for Node.js.
  • Foy: �� A lightweight and modern task runner and build tool for general purpose.
  • Vuese: �� One-stop solution for vue component documentation.
  • NUT: �� A framework born for microfrontends
  • Feel free to add yours here...

References

�� Check out the generated docs from source code if you want a more in-depth API references.

Below is a brief overview.

CLI Instance

CLI instance is created by invoking the cac function:

const cac = require('cac')
const cli = cac()

cac(name?)

Create a CLI instance, optionally specify the program name which will be used to display in help and version message. When not set we use the basename of argv[1].

cli.command(name, description, config?)

  • Type: (name: string, description: string) => Command

Create a command instance.

The option also accepts a third argument config for additional command config:

  • config.allowUnknownOptions: boolean Allow unknown options in this command.
  • config.ignoreOptionDefaultValue: boolean Don't use the options's default value in parsed options, only display them in help message.

cli.option(name, description, config?)

  • Type: (name: string, description: string, config?: OptionConfig) => CLI

Add a global option.

The option also accepts a third argument config for additional option config:

  • config.default: Default value for the option.
  • config.type: any[] When set to [], the option value returns an array type. You can also use a conversion function such as [String], which will invoke the option value with String.

cli.parse(argv?)

  • Type: (argv = process.argv) => ParsedArgv
interface ParsedArgv {
  args: string[]
  options: {
    [k: string]: any
  }
}

When this method is called, cli.rawArgs cli.args cli.options cli.matchedCommand will also be available.

cli.version(version, customFlags?)

  • Type: (version: string, customFlags = '-v, --version') => CLI

Output version number when -v, --version flag appears.

cli.help(callback?)

  • Type: (callback?: HelpCallback) => CLI

Output help message when -h, --help flag appears.

Optional callback allows post-processing of help text before it is displayed:

type HelpCallback = (sections: HelpSection[]) => void

interface HelpSection {
  title?: string
  body: string
}

cli.outputHelp()

  • Type: () => CLI

Output help message.

cli.usage(text)

  • Type: (text: string) => CLI

Add a global usage text. This is not used by sub-commands.

Command Instance

Command instance is created by invoking the cli.command method:

const command = cli.command('build [...files]', 'Build given files')

command.option()

Basically the same as cli.option but this adds the option to specific command.

command.action(callback)

  • Type: (callback: ActionCallback) => Command

Use a callback function as the command action when the command matches user inputs.

type ActionCallback = (
  // Parsed CLI args
  // The last arg will be an array if it's a variadic argument
  ...args: string | string[] | number | number[]
  // Parsed CLI options
  options: Options
) => any

interface Options {
  [k: string]: any
}

command.alias(name)

  • Type: (name: string) => Command

Add an alias name to this command, the name here can't contain brackets.

command.allowUnknownOptions()

  • Type: () => Command

Allow unknown options in this command, by default CAC will log an error when unknown options are used.

command.example(example)

  • Type: (example: CommandExample) => Command

Add an example which will be displayed at the end of help message.

type CommandExample = ((name: string) => string) | string

command.usage(text)

  • Type: (text: string) => Command

Add a usage text for this command.

Events

Listen to commands:

// Listen to the `foo` command
cli.on('command:foo', () => {
  // Do something
})

// Listen to the default command
cli.on('command:!', () => {
  // Do something
})

// Listen to unknown commands
cli.on('command:*', () => {
  console.error('Invalid command: %s', cli.args.join(' '))
  process.exit(1)
})

FAQ

How is the name written and pronounced?

CAC, or cac, pronounced C-A-C.

This project is dedicated to our lovely C.C. sama. Maybe CAC stands for C&C as well :P

Why not use Commander.js?

CAC is very similar to Commander.js, while the latter does not support dot nested options, i.e. something like --env.API_SECRET foo. Besides, you can't use unknown options in Commander.js either.

And maybe more...

Basically I made CAC to fulfill my own needs for building CLI apps like Poi, SAO and all my CLI apps. It's small, simple but powerful :P

Contributing

  1. Fork it!
  2. Create your feature branch: git checkout -b my-new-feature
  3. Commit your changes: git commit -am 'Add some feature'
  4. Push to the branch: git push origin my-new-feature
  5. Submit a pull request :D

Author

CAC © EGOIST, Released under the MIT License.
Authored and maintained by egoist with help from contributors (list).

Website · GitHub @egoist · Twitter @_egoistlily

  • 相关文献 —12.—JL.日IJ 面 成组技术与计算机技术紧密结合是现代成组技术(GT)发展的重要标志之一。编码是将有关设计、制造和管理方面的信息数字化,以便使用计算机检索、分析和处理生产中应用的火量信息。所以,编码是实现计算机辅助GT的重要基础。重 庆 大 学 学 报 为了对零件有关生产信息作较详细的描述,现代编码系统正向着多码位方向发展。在此情况下,用手工编码工作繁锁、出错率高及效率低的弊端将

  • CAC介绍 是一个JavaScript库,用于构建应用的CLI。 超轻量级:没有依赖关系,只有一个文件。 简单易学: 构建简单的CLI只需学习4种API :cli.option cli.version cli.help cli.parse。 功能抢到: 例如默认命令,类似git的子命令,对所需参数和选项进行验证,可变参数,点嵌套选项,自动帮助消息生成等功能。 开发人员友好: 用TypeScript

  • 你说的对,IEEE check过应该就没啥问题了。毕竟这个会提交终稿时要粘贴check的回复邮件。我说的是组委会写的话。也存在有人上传了有误的版本的可能,因为我们上传和check都是分开进行的,不像有的会议提交是逐一点击下一步的,版本是唯一的。比如说我们这个会,我的论文就check了好几次才通过,为了防止混淆,我给每个测试版本都加了日期做标记。。。当然,这些毕竟小概率事件,就你最开始的问题,我依旧

 相关资料
  • 问题内容: cacerts和密钥库之间有什么区别? 如果我使用在这些链接中找到的定义cacerts和keystore,则它们似乎是证书的集合,但是是在(Java)分布式系统的上下文中。SSL连接期间使用哪一个进行身份验证?两者还是只是其中之一,还是交替? 问题答案: “ cacerts”是一个信任库。信任库用于验证对等方。密钥库用于验证您的身份。

  • 问题内容: 我是spring批注的新手,我想创建一个示例示例,该示例显示在spring 3.1中使用 @Cacheable批注 是否有人指导创建此示例? 问题答案: 希望下面的链接可能会对你有所帮助...... 一个示例应用程序。 还可以查看Spring的缓存抽象文档和spring源博客文章。

  • 问题内容: 我正在研究部分应用程序的使用情况,但是我只能找到有关使用专有sun实现或Oracle特定实现的信息。 sun的实现不受支持,并且可能会发生变化。如果将来我想将其部署到非Sun虚拟机上,使用此方法也可能会导致问题,最后,它在构建日志中留下了无法抑制的警告,可以掩盖其他警告。 我是否可以与我的应用程序一起部署一个开源替代实现,该实现在多个数据库之间都能很好地工作?至少支持MySQL的东西。

  • 问题内容: 我正在使用Spring 3.1,并且想使用新的缓存功能。然后,我尝试: 但是我没有找到配置自定义KeyGenerator的方法。任何想法? 问题答案: 好的,我只是找到一种方法来做… 如您所见,我使用AnnotationDrivenCacheBeanDefinitionParser,将配置放入xml中,并且可以::完成! 编辑: 对于Spring> 3.2,可以使用实现CachingC

  • 问题内容: 直到今天,我一直在处理查询结果。但是,今天我读了关于小和,我意识到,他们可以为我的目的更好。虽然在所有示例中我都读到哪里并称为对象,但是当我在代码中亲自尝试时,我意识到它们是接口,并且在示例中它们使用了这些接口的某些实现。 现在我的问题是我在哪里可以找到这些实现,并且有什么正式的东西吗? 我需要下载它们还是JDK附带了它们? 问题答案: 这些实现是JRE特定的。Oracle(Sun)J

  • 问题内容: 我尝试使用MapMaker / CacheBuilder进行缓存,但是我不了解如何正确处理空值。 如果方法createExpensiveGraph返回空值,则抛出NullpointerException。我不明白为什么ComputingConcurrentHashMap抛出NPE而不是仅返回空值。 如何正确处理呢?只是捕获NPE并返回null即可?我想念什么吗? 问题答案: Guava

  • 问题内容: 我有一个类似的问题,但有时可以。描述的错误仅偶尔发生一次。 我正在使用spring 3.2.5和ehcache 2.6.5。 异常跟踪: 我的缓存代码如下: 当发生这种情况时 :当我配置了一个jenkins来构建并自动部署到tomcat7时/当我使用maven在Eclipse WS中构建并部署到tomcat7时。 当它完美运行时 :一次失败后,如果我仅用一些空格编辑MailFilter

  • 问题内容: 我在Spring(3.1)中使用以下@Cacheable: Spring: Maven: 要缓存的方法: las,当我调试代码时,我看到即使param1和param2相同(即未使用cahce),也多次调用了该缓存方法。 有任何想法吗? 问题答案: 密钥显示不正确- 您可能是说- 此外,如果在没有调试信息的情况下完成编译,则param1,param2参数名称将对表达式求值器不可用。相反,