• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pkgxdev / pkgx / 6655045313

26 Oct 2023 01:46PM UTC coverage: 96.431% (-0.5%) from 96.892%
6655045313

push

github

Max Howell
pkgx uninstall

397 of 426 branches covered (0.0%)

2 of 2 new or added lines in 1 file covered. (100.0%)

4 existing lines in 1 file now uncovered.

1386 of 1423 relevant lines covered (97.4%)

137.03 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.93
/src/parse-args.ts
1
import { UsageError } from "./utils/error.ts"
2✔
2
import { Path, utils } from "pkgx"
2✔
3
const { flatmap } = utils
2✔
4

5
type Pkgs = {
6
  plus: string[]
7
  minus: string[]
8
}
9

10
export type Args = {
11
  flags: Flags
12
} & (
13
  {
14
    mode: 'x' | 'run'
15
    args: string[]
16
    unknown: string[]
17
    pkgs: Pkgs
18
  } | {
19
    mode: 'internal.use'
20
    pkgs: Pkgs
21
  } | {
22
    mode: 'env'
23
    pkgs: {
24
      plus: string[]
25
      minus: string[]
26
    }
27
  } | {
28
    mode: 'shellcode' | 'version' | 'help'
29
  } | {
30
    mode: 'integrate' | 'deintegrate'
31
    dryrun: boolean
32
  } | {
33
    mode: 'provider' | 'shell-completion'
34
    args: string[]
35
  } | {
36
    mode: 'internal.activate'
37
    dir: Path
38
  } | {
39
    mode: 'install' | 'uninstall'
40
    args: string[]
41
  }
42
)
43

44
interface Flags {
45
  sync: boolean
46
  update: boolean
47
  verbosity?: number
48
  keepGoing: boolean
49
}
50

51
export default function(input: string[]): Args {
2✔
52
  const it = input[Symbol.iterator]()
48✔
53
  const pkgs: Pkgs = { plus: [], minus: [] }
192✔
54
  const args: string[] = []
48✔
55
  const unknown: string[] = []
48✔
56
  const flags: Flags = {
48✔
57
    sync: false,
48✔
58
    update: false,
48✔
59
    keepGoing: false
48✔
60
  }
48✔
61
  let mode: string | undefined
48✔
62
  let dryrun: boolean | undefined
48✔
63

64
  switch (input[0]) {
48✔
65
  case 'deintegrate':
48✔
66
  case 'integrate':
48✔
67
  case 'uninstall':
48✔
68
  case 'install':
48✔
69
  case 'run':
48✔
70
    mode = input[0]
56✔
71
    it.next()  // consume the subcommand
56✔
72
  }
48✔
73

74
  for (const arg of it) {
48✔
75
    const [type, content] = parse(arg)
144✔
76

77
    switch (type) {
144✔
78
    case '+':
144✔
79
      pkgs.plus.push(content)
168✔
80
      break
168✔
81
    case '-':
144✔
82
      pkgs.minus.push(content)
146✔
83
      break
146✔
84
    case '--':
144✔
85
      switch (content) {
192✔
86
      case 'sync':
192✔
87
        flags.sync = true
194✔
88
        break
194✔
89
      case 'update':
192✔
90
        flags.update = true
194✔
91
        break
194✔
UNCOV
92
      case 'provides':
×
93
        if (mode) throw new UsageError({msg: 'multiple modes specified'})
×
94
        console.error("%cdeprecated: %cuse pkgx --provider instead", 'color: red', 'color: initial')
×
95
        mode = 'provider'
×
96
        break
×
97
      case 'shellcode':
192✔
98
      case 'integrate':
192✔
99
      case 'internal.activate':
192✔
100
      case 'help':
192✔
101
      case 'version':
192✔
102
      case 'provider':
192✔
103
      case 'shell-completion':
192✔
104
      case 'internal.use':
192✔
105
        if (mode) throw new UsageError({msg: 'multiple modes specified'})
664✔
106
        mode = content
232✔
107
        break
232✔
108
      case 'silent':
192✔
109
        flags.verbosity = -2
194✔
110
        break
194✔
111
      case 'quiet':
192✔
112
        flags.verbosity = -1
194✔
113
        break
194✔
114
      case 'dry-run':
192✔
115
        dryrun = true
196✔
116
        break
196✔
UNCOV
117
      case 'keep-going':
×
118
        flags.keepGoing = true
×
119
        break
×
120
      case '':
192✔
121
        // empty the main loop iterator
194✔
122
        for (const arg of it) unknown.push(arg)
194✔
123
        break
194✔
124
      default: {
394✔
125
        const match = content.match(/^verbose(=-?\d+)?$/)
202✔
126
        if (match) {
202✔
127
          flags.verbosity = flatmap(match[1], n => parseInt(n.slice(1))!) ?? 1
210✔
128
        } else {
202✔
129
          throw new UsageError(arg)
204✔
130
        }
204✔
131
      }}
394✔
132
      break
230✔
133
    default:
144✔
134
      /// unrecognized args means the start of the runner args
162✔
135
      args.push(arg)
162✔
136
      for (const arg of it) args.push(arg)
162✔
137
    }
162✔
138
  }
162✔
139

140
  if (dryrun !== undefined && !(mode == 'integrate' || mode == 'deintegrate')) {
48✔
141
    throw new UsageError({msg: '--dry-run cannot be specified with this mode'})
150✔
142
  }
50✔
143

144
  switch (mode) {
78✔
145
  case undefined:
48✔
146
    if (args.length + unknown.length) {
64✔
147
      return { mode: 'x', flags, pkgs, args, unknown }
490✔
148
    } else {
64✔
149
      return { mode: 'env', flags, pkgs }
370✔
150
    }
74✔
151
  case 'internal.use':
48✔
152
    return { mode, flags, pkgs }
250✔
153
  case 'provider':
48✔
154
  case 'shell-completion':
48✔
155
    return { mode, flags, args }
250✔
156
  case 'internal.activate':
48✔
157
    return { mode, flags, dir: new Path(args[0]) }
250✔
158
  case 'install':
48✔
159
  case 'uninstall':
48✔
160
    return { mode, flags, args }
250✔
161
  case 'integrate':
48✔
162
  case 'deintegrate':
48✔
163
    dryrun ??= false
54✔
164
    return { mode, dryrun, flags }
270✔
UNCOV
165
  default:
×
UNCOV
166
    // deno-lint-ignore no-explicit-any
×
167
    return { mode: mode as any, flags }
×
168
  }
48✔
169
}
48✔
170

171

172
//////////////////////// utils
2✔
173

174
function parse(arg: string): ['+', string] | ['--', string] | ['-', string] | [undefined, string] {
98✔
175
  switch (arg[0]) {
98✔
176
  case '+': {
222✔
177
    const content = arg.slice(1)
124✔
178
    if (!content) throw new UsageError(arg)
124✔
179
    return ['+', content]
592✔
180
  }
148✔
181
  case '-':
98✔
182
    if (arg[1] == '-') {
150✔
183
      return ['--', arg.slice(2)]
792✔
184
    } else {
150✔
185
      const content = arg.slice(1)
154✔
186
      if (!content) throw new UsageError(arg)
154✔
187
      return ['-', content]
624✔
188
    }
156✔
189
  default:
98✔
190
    return [undefined, arg]
464✔
191
  }
98✔
192
}
98✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc