123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- 'use strict'
- const glob = require('glob')
- const CUSTOM = ['']
- const BOOLEAN = false
- const options = {
- start: {
- '--port': CUSTOM,
- '--auto-watch': BOOLEAN,
- '--no-auto-watch': BOOLEAN,
- '--log-level': ['disable', 'debug', 'info', 'warn', 'error'],
- '--colors': BOOLEAN,
- '--no-colors': BOOLEAN,
- '--reporters': ['dots', 'progress'],
- '--no-reporters': BOOLEAN,
- '--browsers': ['Chrome', 'ChromeHeadless', 'ChromeCanary', 'Firefox', 'PhantomJS', 'Safari', 'Opera'],
- '--no-browsers': BOOLEAN,
- '--single-run': BOOLEAN,
- '--no-single-run': BOOLEAN,
- '--help': BOOLEAN
- },
- init: {
- '--log-level': ['disable', 'debug', 'info', 'warn', 'error'],
- '--colors': BOOLEAN,
- '--no-colors': BOOLEAN,
- '--help': BOOLEAN
- },
- run: {
- '--no-refresh': BOOLEAN,
- '--port': CUSTOM,
- '--help': BOOLEAN
- }
- }
- function opositeWord (word) {
- if (word.startsWith('-')) {
- return word.startsWith('--no-') ? `--${word.slice(5)}` : `--no-${word.slice(2)}`
- } else {
- return null
- }
- }
- function sendCompletion (possibleWords, env) {
- const regexp = new RegExp('^' + env.last)
- possibleWords
- .filter((word) => regexp.test(word) && !env.words.includes(word) && !env.words.includes(opositeWord(word)))
- .forEach((word) => {
- console.log(word)
- })
- }
- function sendCompletionFiles (env) {
- glob(env.last + '*', { mark: true, nocase: true }, (err, files) => {
- if (err) return console.error(err)
- if (files.length === 1 && files[0].endsWith('/')) {
- sendCompletionFiles({ last: files[0] })
- } else {
- console.log(files.join('\n'))
- }
- })
- }
- function complete (env) {
- if (env.count === 1) {
- return sendCompletion(env.words[0].startsWith('-') ? ['--help', '--version'] : Object.keys(options), env)
- } else if (env.count === 2 && !env.words[1].startsWith('-')) {
- return sendCompletionFiles(env)
- }
- const cmdOptions = options[env.words[0]]
- if (cmdOptions) {
- if (cmdOptions[env.prev] === CUSTOM && env.last) {
- console.log(env.last)
- } else {
- return sendCompletion(cmdOptions[env.prev] || Object.keys(cmdOptions), env)
- }
- }
- }
- function completion () {
- if (process.argv[3] === '--') {
- return complete({
- words: process.argv.slice(5),
- count: parseInt(process.env.COMP_CWORD, 10),
- last: process.argv[process.argv.length - 1],
- prev: process.argv[process.argv.length - 2]
- })
- }
- // just print out the karma-completion.sh
- const fs = require('graceful-fs')
- const path = require('path')
- fs.readFile(path.resolve(__dirname, '../scripts/karma-completion.sh'), 'utf8', function (err, data) {
- if (err) return console.error(err)
- process.stdout.write(data)
- process.stdout.on('error', function (error) {
- // Darwin is a real dick sometimes.
- //
- // This is necessary because the "source" or "." program in
- // bash on OS X closes its file argument before reading
- // from it, meaning that you get exactly 1 write, which will
- // work most of the time, and will always raise an EPIPE.
- //
- // Really, one should not be tossing away EPIPE errors, or any
- // errors, so casually. But, without this, `. <(karma completion)`
- // can never ever work on OS X.
- if (error.errno === 'EPIPE') {
- error = null
- }
- })
- })
- }
- // PUBLIC API
- exports.completion = completion
- // for testing
- exports.opositeWord = opositeWord
- exports.sendCompletion = sendCompletion
- exports.complete = complete
|