Giter Site home page Giter Site logo

parser's Introduction

@oclif/parser

This library has been replaced by @oclif/core and is no longer maintained

arg and flag parser for oclif

Version CircleCI Appveyor CI Known Vulnerabilities Downloads/week License

CLI flag parser.

Usage:

const CLI = require('cli-flags')

const {flags, args} = CLI.parse({
  flags: {
    'output-file': CLI.flags.string({char: 'o'}),
    force: CLI.flags.boolean({char: 'f'})
  },
  args: [
    {name: 'input', required: true}
  ]
})

if (flags.force) {
  console.log('--force was set')
}

if (flags['output-file']) {
  console.log(`output file is: ${flags['output-file']}`)
}

console.log(`input arg: ${args.input}`)

// $ node example.js -f myinput --output-file=myexample.txt
// --force was set
// output file is: myexample.txt
// input arg: myinput

parser's People

Contributors

bryanjswift avatar childish-sambino avatar cristiand391 avatar dependabot[bot] avatar elbandito avatar frangio avatar g-rath avatar greenkeeper[bot] avatar heroku-cli avatar idandrd avatar jdx avatar mdonnalley avatar merceyz avatar mshanemc avatar oclif-bot avatar quantumkid avatar rasphilco avatar rhwood avatar rodesp avatar shazron avatar svc-cli-bot avatar tbrannam avatar tstapleton 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

Watchers

 avatar  avatar

parser's Issues

Improve args typings

Hi,

When using const { args } = this.parse(Command), the type of args is any.

This makes it harder to maintain stability when passing those args around.

Is it possible to make it inherit the values from the property itself?

So if I have:

static args = [
  {
    name: 'someArg',
  }
];

The type of const { args } = this.parse(Command) will be { someArg: string }

Arguments that have custom parsers throw missing argument errors when the parsed value is falsy

In my project I have a simple command to delete an element by its index, but when the argument is "0" and is parsed to a number through a custom parser the validator fails due to a missing argument exception.

Example:

import { Command } from "@oclif/command";

export default class TestCommand extends Command {
	static description = "Throws a missing argument exception when the argument is 0";

	static args = [
		{
			name: "value",
			required: true,
			description: "A number",
			parse: (value: string): number => parseInt(value, 10)
		}
	];

	public async run(): Promise<void> {
		const { args } = this.parse(TestCommand);

		this.log(`Received: ${args.value}`);
	}
}

Running the command with the argument "0" it will throw an exception with saying it has a missing value even though it was provided while running it with the argument "1" will run the command successfuly.

It seems to be caused by this comparison:

if (!parse.output.argv[index]) {

Can't pass an empty string flag

Hi there,

I have an issue that faced in https://github.com/twilio-labs/plugin-serverless where present string flags without any value don't work.

For example, this doesn't work:

twilio serverless:start --inspect

This works however:

twilio serverless:start --inspect=""

The problem seems to be here because if nothing else is being passed the last value will be undefined. If something else is passed it will be turned into the value.

For now the workaround for me is to add an empty string to the back of argv but this doesn't seem to be a good solution.

Update: in fact this doesn't even work. The fix instead is a documentation one for now to mention to pass an empty string

Support forwarding arguments

When -- is present the rest is taken as arguments. I believe it should be possible to specify the behavior where these "rest" arguments should be distinguishable from other args in order to have "forwarding behavior".

For example cli --parameter 1 --bool arg1 arg2 -- --parameter 2 arg3 arg4 should distinguish arg1 and arg2 from --parameter 2 arg3 arg4.

An in-range update of @types/node is breaking the build 🚨

The devDependency @types/node was updated from 10.10.0 to 10.10.1.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

@types/node is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • βœ… ci/circleci: node-latest: Your tests passed on CircleCI! (Details).
  • βœ… ci/circleci: node-8: Your tests passed on CircleCI! (Details).
  • βœ… continuous-integration/appveyor/branch: AppVeyor build succeeded (Details).
  • βœ… codecov/project: No report found to compare against (Details).
  • βœ… codecov/patch: Coverage not affected. (Details).
  • ❌ Build: We could not find a valid build file. Please ensure that your repo contains a cloudbuild or a Dockerfile.

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Integer flag support

Hi! I would like integer flags. I imagine the code on my command would look something like this:

static flags = {
  port: flags.integer({
    char: 'p',
    description: 'port',
    default: 5001,
  }),
}

async run() {
  const { flags } = this.parse(Start)
  this.log(`x has started on port ${flags.port}`)
}

I did find reference to an integer here https://github.com/oclif/parser/blob/master/src/flags.ts#L70-L75 but I'm not sure how to use it. There is no type defined like so:

export type IIntegerFlag<T> = IFlagBase<T, integer> & {}

Error: Cannot find module 'tslib'

I packed my cli with oclif-dev pack:macos and installed the pkg on my own computer. Upon executing this error appeared:

Error: Cannot find module 'tslib'
    at Function.Module._resolveFilename (module.js:547:15)
    at Function.Module._load (module.js:474:25)
    at Module.require (module.js:596:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/usr/local/lib/stocli/node_modules/@oclif/parser/lib/index.js:4:17)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)

My oclif dependencies are:

"@oclif/command": "^1.4.34",
"@oclif/config": "^1.6.33",
"@oclif/errors": "^1.1.2",
"@oclif/plugin-help": "^2.0.5",

I am on typescrit 2.9.2 and node 8.x

After manually adding tslib to my project dependencies I could start my CLI, but

(node:19071) [MODULE_NOT_FOUND] Error Plugin: stocli: Cannot find module 'globby'
module: @oclif/[email protected]

appeared. That I fixed by installing globby.

Flag gets picked up in place of missing arg

I've got the following command:

class InitCommand extends Command {
  run() {
    const {flags, args} = this.parse(InitCommand);
    console.log('flags:', flags);
    console.log('args:', args);
  }
}

InitCommand.args = [
  {
    name: 'path',
    required: true,
    description:
      "Where to create the new app. If the directory doesn't exist, it will be created."
  }
];

And I invoke it with: ./bin/run init --blah

Expected Behavior

I would expect to see either (or both) of these errors:

  1. Error: Unexpected argument: --blah
  2. Error: Missing 1 required arg: path

Actual Behavior

--blah is picked up as an arg, not a flag. So at run time, the path is invalid and the command isn't in "blah" mode.

flags: {} 
args: { path: '--blah' }

Is this a bug or intended behavior? If the former, I'm happy to fix it.

Add correct type to Flag object

After some investigation, I found that most of all flags created using flag object has type option. Can you please put the correct type for each of the flag types. It can be useful for extending flag functionality.
With the current solution, you are not able to evaluate the type of flag. Thanks in advice πŸ‘Ό

Invoke arg parse function before checking options

Consider an arg definition like this:

  {
    name: 'something',
    required: true,
    parse: input => input.toUpperCase(),
    options: ['A', 'B'],
  }

Logically an input token of a should be acceptable here because the parse function is provided in order to coerce the lower case value into an upper case value.

This, however, does not work since the token is compared to the options before the parse function is invoked. While in this synthetic case this is easy enough to workaround, in more complex cases it would not be quite so easy.

default value typing question

I thought that by declaring the default attribute in a flag, it would set it to the type I put.
But it's <T | undefined> and it's a problem for me. Is it intentional?

IMO it should not be undefined since it's default.

export declare type IOptionFlag<T> = IFlagBase<T, string> & {
    type: 'option';
    helpValue?: string;
    default?: Default<T | undefined>;
    multiple: boolean;
    input: string[];
    options?: string[];
};
```

An in-range update of eslint-config-oclif is breaking the build 🚨

The devDependency eslint-config-oclif was updated from 3.0.0 to 3.1.0.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

eslint-config-oclif is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • βœ… ci/circleci: node-8: Your tests passed on CircleCI! (Details).
  • βœ… ci/circleci: node-latest: Your tests passed on CircleCI! (Details).
  • ❌ continuous-integration/appveyor/branch: AppVeyor build failed (Details).

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Why is the default value for flags.boolean undefined?

It seems that although the presence of a bool flag causes the parsed value to be true, the absence of a bool flag causes the parsed value to be undefined (unless default:false is explicitly set).

Wouldn't it make more sense for boolean flags to have a default-default value of false?

Enum flags can be incorrectly typed

It seems that the type of enum flags is incorrect.

One can define the following and it results in the parsed value having an incorrect type.

type Options = 'a' | 'b';
...
flags.enum<Options>({
  options: [ 'c' ],
})

If an argument that is required (with no default) is missing, the parser does not throw a RequiredArgsError error

Description:

When I have a required argument with no default, and I don't pass an argument, the CLI does not throw an error.

Expected result:

When I call the command (see demo.js below) with no arguments, it should show this error:

β€Ί   Error: Missing 1 required arg:
 β€Ί   name  Name of the project to create
 β€Ί   See more help with --help

Actual result:

When I call the command (see demo.js below) with no arguments, there is no error or exception, args is parsed properly, with the named argument value set as undefined.

demo.js

const {Command,flags} = require('@oclif/command')

class DemoCommand extends Command {
  async run() {
    const {flags,args} = this.parse(DemoCommand) // eslint-disable-line no-unused-vars
    this.log(`If this prints, all args are parsed. args.name: ${args.name}`)
  }
}

DemoCommand.description = `Create example project.`

DemoCommand.args = [
  {
    name: 'name',               // name of arg to show in help and reference with args[name]
    required: true,            // make the arg required with `required: true`
    description: 'Name of the project to create'// help description
  },
  {
    name: 'dir',               // name of arg to show in help and reference with args[name]
    required: false,            // make the arg required with `required: true`
    description: 'Parent directory of new project', // help description
    default:'.'
  }
]

DemoCommand.strict = true

DemoCommand.flags = {
  type: flags.string({
    description:'Demo source type',
    options: ['simple', 'full'],
    default:'simple'
  })
}

module.exports = DemoCommand

How to pass flag type to base class

This is mostly a Typescript question more than anything else with OClif itself. I want to create a BaseCommand and define some additional parameters. One such is a getter for flags. I cannot figure out how to set the type of it though so it's dynamic based on whatever the implemented class is:

export abstract class BaseCommand extends Command {
  protected flags: WhatToPutHere;

  async run() {
     this.flags = this.parse(this.constructor).flags;
  }
}

class MyCommand extends BaseCommand {
  static flags = {
    version: flags.string()
  }

  async run() {
    // I want to access this.flags.version
  }
}

`parse` does not execute with `flags.build#default`

(Please direct this question to a different repo if warranted).

Current implementation:
https://github.com/TracerBench/tracerbench/blob/c9b4a5457cfcd21af93dc96f7cd1221eedf6b269/packages/cli/src/helpers/flags.ts#L7-L13

Use-case:
We have certain instances where we want to type check and parse flag values differently depending on if a default config.json value is being consumed vs explicitly flagged within the CLI command directly. ie

CLI: COMMAND --markers foo,buzz
CONFIG.json: "markers": ["foo", "buzz"]
parse: m => {
// return do something with m under both scenarios
}

Is it possible to "force" parse to execute within the context of flags.build when a default value is set. Appears currently if a default flag value is set parse is never executed.

flags.build#parse will execute

export const foo = flags.build({
  description: `foo foo`,
  parse: f => {
    if (typeof f === 'string') {
       // do something
    }
  }
});

flags.build#parse will NOT execute

export const foo = flags.build({
  default: 'foo',
  description: `foo foo`,
  parse: f => {
    if (typeof f === 'string') {
         // do something
    }
  }
});

Example in README doesn't work

The example in the README was confusing since it starts with:

const CLI = require('cli-args');

Which I assume is vestigial.

Moving past that, trying to just C+P the example from the README, it fails with the following:

TypeError: Cannot read property 'context' of undefined

Here's a runkit notebook showing the error.

New version needs publishing for Yarn2?

Just testing out some Yarn2 support, bumped to the latest version but still getting the same error that's fixed in #71 and on master, just not been pushed to NPM.

I'm genuinely not sure how to work around this (very new to Yarn 2, personally), so thought I'd ask if a new version could be published to save me the hassle! Thanks heaps πŸ™

`deps.ts` breaks packaging with pkg

The FAQ says to use https://github.com/zeit/pkg for building single binaries but when attempting to run commands on the packaged binary I get an error that looks like

Error: Cannot find module './parse'
1) If you want to compile the package/file into executable, please pay attention to compilation warnings and specify a literal in 'require' call. 2) If you don't want to compile the package/file into executable and want to 'require' it from filesystem (likely plugin), specify an absolute path in 'require' call using process.cwd() or process.execPath.
    at Function.Module._resolveFilename (pkg/prelude/bootstrap.js:1269:46)
    at Module.require (pkg/prelude/bootstrap.js:1153:31)
    at fetch (/snapshot/ssmenv/node_modules/@oclif/parser/lib/deps.js:34:16)
    at Object.get parse [as parse] (/snapshot/ssmenv/node_modules/@oclif/parser/lib/deps.js:12:12)
    at Object.parse (/snapshot/ssmenv/node_modules/@oclif/parser/lib/index.js:20:36)
    at Main.parse (/snapshot/ssmenv/node_modules/@oclif/command/lib/command.js:64:41)

The distributed deps.js from @oclif/parser is the only place I can find this pattern. After changing the export in the distributed deps.js to look like:

exports.deps = {
  // local
  args: require('./args'),
  flags: require('./flags'),
  parse: require('./parse'),
  validate: require('./validate'),
  renderList: require('./list').renderList,
  errors: require('./errors'),
  chalk: require('chalk'),
};

I can no longer reproduce the in my testing.

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.