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

pkgxdev / pkgx / 6605283511

22 Oct 2023 05:39PM UTC coverage: 97.311% (-0.5%) from 97.833%
6605283511

push

github

mxcl
Have command not found handler sync

Sync is quick if they have done it recently. Let’s see how this feels.

Rationale: We add new pkgs all the time.

389 of 408 branches covered (0.0%)

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

2 existing lines in 1 file now uncovered.

1384 of 1414 relevant lines covered (97.88%)

137.82 hits per line

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

92.78
/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'
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 'install':
48✔
68
  case 'run':
48✔
69
    mode = input[0]
56✔
70
    it.next()  // consume the subcommand
56✔
71
  }
48✔
72

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

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

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

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

169

170
//////////////////////// utils
2✔
171

172
function parse(arg: string): ['+', string] | ['--', string] | ['-', string] | [undefined, string] {
97✔
173
  switch (arg[0]) {
97✔
174
  case '+': {
219✔
175
    const content = arg.slice(1)
122✔
176
    if (!content) throw new UsageError(arg)
122✔
177
    return ['+', content]
580✔
178
  }
145✔
179
  case '-':
97✔
180
    if (arg[1] == '-') {
149✔
181
      return ['--', arg.slice(2)]
788✔
182
    } else {
149✔
183
      const content = arg.slice(1)
153✔
184
      if (!content) throw new UsageError(arg)
153✔
185
      return ['-', content]
620✔
186
    }
155✔
187
  default:
97✔
188
    return [undefined, arg]
460✔
189
  }
97✔
190
}
97✔
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