Git Product home page Git Product logo

cac's People

Contributors

0xflotus avatar antfu avatar auxves avatar chocolateboy avatar dependabot[bot] avatar egoist avatar falstack avatar fengzilong avatar fzn0x avatar guifromrio avatar hcysunyang avatar jkzing avatar joseph-galindo avatar justjavac avatar kandros avatar meteorlxy avatar mister-hope avatar mitolog avatar niftylettuce avatar paambaati avatar ulivz avatar yinm avatar yunyoujun avatar yuta1024 avatar zaaack avatar zce avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cac's Issues

Alias resolving appears to be broken

If multi-character option alias ends with a character that is used as a single-character alias for another option args will be parsed incorrectly and the value will be assigned to that single-character option

Example:

const cac = require('cac');

const cli = cac({ bin: 'package-name' });

cli
  .command('*', { desc: 'Example' }, (input, opts) => {
    console.log(opts);
  })
  .option('option', {
    alias: 'o', type: 'string',
    default: 'option-default',
  })
  .option('anotheroption', {
    alias: 'ao', type: 'string',
    default: 'another-option-default',
  });

cli.parse();

If I then execute it I get:

$ node ./cli.js -ao provided-ao-value
{ version: false,
  v: false,
  help: false,
  h: false,
  a: true,
  o: 'provided-ao-value',
  option: 'provided-ao-value',
  anotheroption: 'another-option-default',
  ao: 'another-option-default',
  '--': [] }

expected

{ ...
  o: 'option-default',
  option: 'option-default',
  anotheroption: 'provided-ao-value',
  ao: 'provided-ao-value',
  '--': [] }

I would have assumed that multi-character aliases aren't supported, but poi has some, so it looks like it should be.

Cac version 4.4.4

feat: allow non-array types

Issue Type

  • Bug Report
  • Feature Request
  • Other

Expected

I'd like to be able to just specify a type (eg. String), without making it an array String (eg. [String])

I'd like to be able to do:

const cli = cac('cli')
	.option('--size <size>', 'Size', {
		type: String,
	})

and get the parsed options:

{ '--': [], size: '16' }

Actual

Instead, I currently must do

const cli = cac('cli')
	.option('--size <size>', 'Size', {
		type: [String],
	})

and get the parsed options:

{ '--': [], size: ['16'] }

as communicated by the type:

type?: any[]

Possible Solutions

Info

  • CAC version: 6.7.2
  • Reproduction link:

firstArgs

8401c77

this.firstArg = this.firstArgs.startsWith('-') ? null : this.firstArgs;
                                   ^

TypeError: Cannot read property 'startsWith' of undefined

Looks like firstArgs never defined.

It's impossible to get type definitions working because of EventEmitter

I have spent the best of the last three hours trying innovative ways to make my VSCode understand the typing definitions in this TypeScript program from my client deno cli app. Alas, I have failed.

My attempt consisted of trying to leverage deno compiler options to add types like this:

// @deno-types="https://raw.githubusercontent.com/firstdoit/cac/master/mod.d.ts"
export { cac } from 'https://raw.githubusercontent.com/firstdoit/cac/master/mod.js'

And then to generate said mod.d.ts from the types/* directory.

It's apparently impossible, because you inline EventEmitter (#66) but all "dts generation tools" I tried were unable to inline the events library.

Tools I tried to create a single dts:
https://github.com/Swatinem/rollup-plugin-dts
https://github.com/timocov/dts-bundle-generator

You can take a look at my commits if it helps:
guifromrio@44e763c
guifromrio@4637d6b

I'm giving up on cac for now, since apparently deno is really at a stage when it's best to only import .ts, deno-native libs directly. :(

Types: export CAC class

Issue Type

  • Bug Report
  • Feature Request
  • Other

Export the CAC class please, we need it while writing with typescript.

Ability to customize subcommand help output

Issue Type

  • Bug Report
  • Feature Request
  • Other

Expected

$ command subcommand --help

Subcommand is used to... <---- this would be nice to be able to add

Usage:
  $ command subcommand

Options:
  -v, --version  Display version number
  -h, --help     Display this message

Actual

$ command subcommand --help

Usage:
  $ command subcommand

Options:
  -v, --version  Display version number
  -h, --help     Display this message

Possible Solutions

Add per command options to customize output to user.

cli.command('subcommand', 'description here')
    .help(`
          ${this.description}
          ${chalk.yellow(...)}
          ...
     `)

Info

  • CAC version: 6.5.1

When we have field `choices` of `option`, we have to give flag one precise value

When we have field choices of option, we have to give flag one precise value.

const cac = require('../')

const cli = cac()

cli.command('a', {
  desc: 'command a',
}).option('foo', {
  desc: 'foo is a flag for command a'.
  type: "string",
  default: "aa", 
  choices: ["aa", "bb", "cc"]
})

We have to give the value to flag of foo. like that:

$ cli a
# error msg
The value of flag "foo" should be one of: "aa","bb","cc"
$ cli a --foo aa
# pass

Publish TypeScript source for Deno

Currently you have to manually type cac in Deno using // deno-types="https://unpkg.com/cac/mod.d.ts". I think we can actually get rid of all the Node.js dependencies and publish TypeScript source code so you can directly use it in Deno.

Plugin for required options

const requiredOptions = require('cac-required-options')

cli.option('foo', {
  required: true,
  desc: 'this is foo'
})

const someCommand = cli.command('some', 'this is some command')

someCommand.option('bar', {
  required: true,
  desc: 'this is bar'
})

cli.use(requiredOptions())

Array types

Issue Type

  • Bug Report
  • Feature Request
  • Other

Expected

cli.option('--externals <external>', 'Add externals (can be used for multiple times)', {
  type: [String]
})
--externals foo
# options: { externals: ['foo'] }

--externals foo --externals bar
# options: { externals: ['foo', 'bar'] }

Actual

--externals foo
# options: { externals: 'foo' }

--externals foo --externals bar
# options: { externals: ['foo', 'bar'] }

Re: #24

Solution

Add a type option to cli.option and command.option methods.

Required option not working as expected

Issue Type

  • Bug Report
  • Feature Request
  • Other

Expected

cli
  .command('create [dir]')
  .option('--template <template>')

If I didn't pass the template, it should throw an error like๏ผšoption "template" value is missing.

Actual

No error, continue to execute

Possible Solutions

Command.ts - checkOptionValue

Info

  • CAC version: 6.7.2

coerce option is never run

Issue Type

  • Bug Report
  • Feature Request
  • Other

Expected

The coerce option config to run/coerce the results to the returned options.

Actual

The coerce option doesn't seem to run.

Possible Solutions

It appears the coerce option is never run in cac source. cac should run the coerce option on options with a coerce option defined.

Info

Long hyphenated options aren't recognised as aliases

Issue Type

  • Bug Report

Keywords: options, alias, aliases, hyphen, kebab-case

Description

Long hyphenated options (e.g. --clear-screen) aren't recognised as aliases of short options (e.g. -c) or long non-hyphenated options (e.g. --clear).


Suppose you have a --clear-screen option (as in the README) which can also be called as --clear or -c:

cat ./test.js
const cli = require('cac')()
cli.option('-c, --clear, --clear-screen')
console.log(cli.parse().options)

If this command is called with -c or --clear (or --clearScreen), all three aliases are assigned the value, e.g.:

node ./test.js -c            # { '--': [], c: true, clear: true, clearScreen: true }
node ./test.js --clear       # { '--': [], c: true, clear: true, clearScreen: true }
node ./test.js --clearScreen # { '--': [], c: true, clear: true, clearScreen: true }

But if the command is called with the long hyphenated option, it's treated as an unknown option (the aliases are not assigned the value):

node ./test.js --clear-screen   # { '--': [], clearScreen: true }
node ./test.js --unknown-option # { '--': [], unknownOption: true }

Environment

CAC: 6.7.3
Node: v14.17.3
OS: Linux (Arch)

Show root help for wildcard command

If you have a wildcard command like:

cli.option('foo', desc)

const wildcard = cli.command('*', desc, handler)
wildcard.option('bar', desc)

And when you run cli.js --help it currently prints message that includes bar instead of foo. Which means you can never see root help!

We should actually make wildcard command show root help instead of command help, and force user to add an alias name to the wildcard command so that it's possible to get the help for your wildcard command too:

cli.option('foo', desc)

const wildcard = cli.command('*', { alias: 'hi', desc }, handler)
wildcard.option('bar', desc)

In this case, run cli.js --help for root help, run cli.js hi --help for the help of your wildcard command.

CAC doesn't works with Deno

Issue Type

  • Bug Report
  • Feature Request
  • Other

Expected

Works CAC with Deno.

Actual

Deno throws error.

error: Uncaught ImportPrefixMissing: relative import path "events" not prefixed with / or ./ or ../ Imported from "https://unpkg.com/[email protected]/mod.js"
โ–บ $deno$/dispatch_json.ts:40:11
    at DenoError ($deno$/errors.ts:20:5)
    at unwrapResponse ($deno$/dispatch_json.ts:40:11)
    at sendAsync ($deno$/dispatch_json.ts:91:10)

Possible Solutions

Deno does not have 'events' module but cac depends.
Also Deno cannnot import https://www.npmjs.com/package/events with such code.

cac/mod.js

Line 1 in cb367c9

import { EventEmitter } from 'events';

Info

  • CAC version: 6.5.3
  • Reproduction code:
import { cac } from 'https://unpkg.com/cac/mod.js'

cac not working with Deno 1.0.0

Issue Type

Deno recently removed the usage of window.location.pathname which now break the fix that was implemented in #70

  • Bug Report

Expected

cac working with Deno

Actual

Rising an exception

Possible Solutions

Replace deno && typeof window !== 'undefined' && window.location.pathname with import.meta.url

Info

  • CAC version: 6.5.8

[Feature Request] Pass exit code to `cli.outputHelp()`?

Issue Type

  • Bug Report
  • Feature Request
  • Other

Expected

  • That when I manually call cli.outputHelp(), that I can then set the exit code (e.g. to 1).

Actual

  • Calling cli.outputHelp() calls process.exit(0) for me.

Possible Solutions

  • Pass exit code to cli.outputHelp()
  • Stop calling process.exit(0) in cli.outputHelp() (breaking change, though)

Info

  • CAC version: 6.4.2
  • Reproduction link:

unknown command throws error

The most bare bone example I could come up with

$ node index someUnknownCommand
// index.js
require('cac')().parse()
/home/superuser/git/cac-test/node_modules/cac/dist/cac.js:171
    const commandText = chalk.magenta(this.opts.displayCommands ? '<command> ' : `${this.command.command.name} `);
                                                                                                 ^

TypeError: Cannot read property 'command' of undefined
    at Help.getHelp (/home/superuser/git/cac-test/node_modules/cac/dist/cac.js:171:98)
    at Help.output (/home/superuser/git/cac-test/node_modules/cac/dist/cac.js:207:31)
    at Cac.showHelp (/home/superuser/git/cac-test/node_modules/cac/dist/cac.js:378:10)
    at Object.<anonymous> (/home/superuser/git/cac-test/index.js:3:5)
    at Module._compile (module.js:662:30)
    at Object.Module._extensions..js (module.js:673:10)
    at Module.load (module.js:575:32)
    at tryModuleLoad (module.js:515:12)
    at Function.Module._load (module.js:507:3)
    at Function.Module.runMain (module.js:703:10)

The only way I could get rid of this error was by adding a matching command such as * or someUnknownCommand.

Tested in version 4.4.2, 4.4.1, 4.4.0 and 4.3.7.

Number out of precision.

I passed a number out of precision:

cli -n 1002822319600013312

got n = 1002822319600013300, a number

cli -n "1002822319600013312"

also got n = 1002822319600013300, a number

May be better to parse parameter as string first and auto convert to number if within precision. :)

alias() to support multiple aliases

Issue Type

  • Bug Report
  • Feature Request
  • Other

Expected

cli
  .command('format [...files]', 'Format files using Prettier')
  .example("format 'src/**/*.{js,ts,json}'")
  .alias(['fmt', 'fromat', 'foramt'])

  // or separate arguments
  .alias('fmt', 'fromat', 'foramt')

  .action(async (files) => {})

Actual

None.

[Bug Report] Multiple words negated options

Issue Type

  • Bug Report
  • Feature Request
  • Other

Steps to repro

// test.js
const cli = require('cac')();

cli.option('--no-aaa-bbb').option('--no-ccc');

const parsed = cli.parse();

console.log(JSON.stringify(parsed, null, 2));
$ node test.js
{
  "args": [],
  "options": {
    "--": [],
    "aaa-bbb": true,
    "ccc": true
  }
}

$ node test.js --no-aaa-bbb
{
  "args": [],
  "options": {
    "--": [],
    "aaa-bbb": true,
    "ccc": true,
    "aaaBbb": false
  }
}

$ node test.js --no-ccc
{
  "args": [],
  "options": {
    "--": [],
    "aaa-bbb": true,
    "ccc": false
  }
}

The "aaa-bbb": true is always there.

Info

  • CAC version: 6.5.3

Native ESM (Node 13+) Support

Issue Type

  • Bug Report
  • Feature Request
  • Other

Expected

ESM support so we can do this:

import cac from 'cac'

const cli = cac()

// ...

Actual

No ESM support for Node.js

Possible Solutions

Adding these fields to package.json

"type": "module",
"module: "...",
"exports": {
    ".": {
      "import": "./dist/index.js",
      "require": "./dist/index.cjs"
    },
    "./package.json": "./package.json",
    "./": "./"
  }

Note that CJS will still work as before, here's an example of such module: https://github.com/talentlessguy/es-mime-types

Because this project already uses Rollup, it will be very easy to add a module target.

Info

  • CAC version: 6.15.3

if needed, I can make a pull request

[feature] sub commands like 'git remote prune origin'

Issue Type

  • Bug Report
  • Feature Request
  • Other

There doesn't seem to be mention of this, so not sure if possible.

Example:

my-command remote rm origin

Maybe this is actually a feature request. I can change it if so.

Command is not found in deno - incorrect arguments argv handling

Issue Type

  • Bug Report
  • Feature Request
  • Other

Expected

A simple cac cli written in node with one command should find the command when called.

e.g.

Create a file cli.ts with contents:


const cli = cac('act')
cli
  .command('install [...apps]', 'Install apps')
  .action((apps: any, options: any) => {
    console.log('Wow! Deno cli!', apps, options)
  })

cli.parse()

Then run deno install cli cli.ts and finally cli install a

Expected behavior: the console.log should execute

Actual

Nothing happens! Because the library cannot find the command given incorrect argv handling.

If you call it with an extra argument, though it works:

cli whatever install a

Result: console.log is called.

Possible Solutions

I believe this happened because of this change: denoland/deno#2123 (comment)

Now, Deno.args only has the actual arguments.

This is the source of the problem:

export const processArgs = deno ? ['deno'].concat(Deno.args) : process.argv

In node, the argv process has two "useless" elements in the beginning: the node executable itself, and the path to the script which started execution:
https://nodejs.org/docs/latest/api/process.html#process_process_argv

And finally, here is where we "remove" those two useless args, but they're not useless for Deno! They are the args.

cac/src/CAC.ts

Line 178 in aa8f868

const parsed = this.mri(argv.slice(2), command)

There are some possible solutions. Simplest would be to add the "script path" to the processArgs variable, to be "backwards compatible" with node code. Do you want me to PR that, or do you see a better alternative?

Thanks for the great lib!

Info

Output examples in help

// global examples
cli.example(`{bin} init project-name --force`)

// command examples
const command = cli.command('build')
command.example('{bin} build src/index.js')

Expose CAC and Command classes to the public?

Issue Type

  • Bug Report
  • Feature Request
  • Other

Expected

To have access to the CAC class so can extend it easier.

Actual

Don't have.


Otherwise we are going oldschool

function Foo() {
  this.bar = 123;
}

Foo.prototype = Object.getPrototypeOf(cac());

const qux = new Foo()

console.log(qux.bar)
console.log(qux.command)
console.log(qux.parse)

How to array

There are no examples on how to supply an array. Have tried a bunch of different ways.

command --array ["/","/about"]                    

Remove `module.exports` in esm bundle

Issue Type

  • Bug Report
  • Feature Request
  • Other

Description

cac/src/index.ts

Lines 13 to 14 in 5060bd9

// @remove-for-deno
module.exports = cac

This should be removed in esm bundle for Node.js too.

Normally it won't cause issues, unless you're trying to bundle your CLI into a single js file.

Possible Solutions

Using a rollup plugin to remove it, could be added here: https://github.com/cacjs/cac/blob/master/rollup.config.js

Info

  • CAC version: 6.7.3
  • Reproduction link:

Allow options to be used before commands

I am looking to implement cac into DocPad. However, I need to be able to specify options before or after commands.

Here is an example source file:

'use strict'

const cli = require('cac')()

cli.option('opt', {
	type: 'boolean',
	desc: 'a boolean option'
})

cli.command('cmd', {
	desc: 'a command'
}, function (input, flags) {
	console.log('cmd:', { input, flags })
})

cli.command('*', {
	desc: 'show help'
}, function (input, flags) {
	cli.showHelp()
})

cli.parse()

And here is its output:

> node cac.js --opt cmd

  cac.js 6.81.0

  project description

  USAGE

    cac.js <command> [options]

  COMMANDS

    cmd  a command
    *    show help

  GLOBAL OPTIONS

    -v, --version  Display version                     [Type: boolean]
    -h, --help     Display help (You're already here)  [Type: boolean]
    --opt          a boolean option                    [Type: boolean]
> node cac.js cmd --opt
cmd: { input: [],
  flags:
   { version: false,
     v: false,
     help: false,
     h: false,
     opt: true,
     '--': [] } }

The former output should behave the same as the latter output.

4.0 roadmap

cac is going to be like commander.js more while keeping the good part of minimist.

Require

const cac = require('cac')
const cli = cac()
// ...
cli.parse()

Command

// cli.js
cli.command('init', 'description', (input, flags) => {})
// or omit the handler function to use an external file
cli.command('init', 'description')
// then we get the handler function by `require('./cli-init')`

Option

// cli.js
cli.option('w, watch', 'description')
// this will be included i top-level command's help
// eg: `node cli.js --help`

cli.option('w, watch', 'description', {command: 'init'})
// this will be included in subcommand `init`'s help
// eg: `node cli.js init --help`

Plugin system

const cli = require('cac')()

cli.use(updateNotifier)
cli.use(autoComplete)

cli.use(ensureOptions({
  command: 'init',
  options: ['name']
}))

Support addtional match for commands

cli.command('run', {
	desc: 'run a file',
	addtionalMatch(firstArg) {
		return /.+\..+/.test(firstArg)
	}
}, (input, flags) => {
	console.log('run file:', input[0])
})

Then followings will do the same thing:

./cli.js run index.js
./cli.js index.js

But not this one:

./cli.js foo

could I use default command(not the global one with name '@@global@@')?

Issue Type

  • Bug Report
  • Feature Request
  • Other

run code below:

cli.command('[...rest]', 'desc')
    .option('--out', 'desc')
    .action(...)

const parsed = cli.parse(['', '', './src', '--out', './lib'], { run: false});

console.log(parsed)

Expected

{
  "args": [
    "./src",
    "abc"
  ],
  "options": {
    "--": [],
    "out": "./lib"
  }
}

Actual

{
  "args": [
    "./src"
  ],
  "options": {
    "--": [],
    "out": true
  }
}

Possible Solutions

Info

  • CAC version: 6.7.x
  • Reproduction link:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.