unjs / citty

🌆 Elegant CLI Builder
Other
729 stars 23 forks source link

Support detecting args that is specified but with no values #142

Open hyf0 opened 4 months ago

hyf0 commented 4 months ago

Describe the feature

Generally I have to using customized args parser to write tje following code. I was hope that citty could support the requirement said in the title, since it already use mir under the hood.

import process from 'node:process'
import parseArgs from 'mri'
import { defineCommand, runMain, showUsage } from 'citty'
import { ensureConfig, logger } from './utils.js'
import { bundle } from './commands/bundle.js'
import {
  version,
  description,
} from '../../package.json' assert { type: 'json' }
import { DEFAULT_CONFIG_FILENAME } from './constants.js'

interface ParsedArgs {
  config?: string | true
  c?: string | true
  // `citty` intercept the help option, so we don't need to deal with it
  // help?: boolean
  // h?: boolean
}

const main = defineCommand({
  meta: {
    name: 'rolldown',
    version,
    description,
  },
  args: {
    config: {
      type: 'string',
      alias: 'c',
      description:
        'Use this config file (if argument is used but value is unspecified, defaults to `rolldown.config.js`)',
    },
    help: {
      type: 'boolean',
      alias: 'h',
      description: 'Show this help message',
    },
  },
  async run(_ctx) {
    // FIXME: `citty` doesn't support detecting if an argument is unspecified
    const parsedArgs = parseArgs<ParsedArgs>(process.argv.slice(2))
    let argConfig = parsedArgs.c || parsedArgs.config
    if (argConfig) {
      // If config is specified, we will ignore other arguments and bundle with the specified config
      if (argConfig == true) {
        argConfig = DEFAULT_CONFIG_FILENAME
      }
      await bundle(argConfig)
      return
    }

    showUsage(main)
  },
})

runMain(main)

Additional information