@magic/cli 0.0.32 → 0.0.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -2
- package/package.json +11 -9
- package/src/exec.mjs +5 -5
- package/src/execFile.mjs +28 -0
- package/src/help/argToHelp.mjs +11 -0
- package/src/help/findLongestString.mjs +9 -14
- package/src/help/index.mjs +1 -3
- package/src/index.mjs +4 -0
- package/src/parse/argv.mjs +5 -3
- package/src/parse/clean.mjs +14 -7
- package/src/parse/commands.mjs +44 -33
- package/src/parse/env.mjs +3 -1
- package/src/parse/required.mjs +5 -2
- package/src/spawn.mjs +2 -1
package/README.md
CHANGED
|
@@ -50,8 +50,9 @@ ecmascript modules only. no commonjs support.
|
|
|
50
50
|
### <a name="dependencies"></a>dependencies:
|
|
51
51
|
* [@magic/log](https://github.com/magic/log): console.log wrapper with loglevels
|
|
52
52
|
* [@magic/types](https://github.com/magic/types): type checking library
|
|
53
|
+
* [@magic/types](https://github.com/magic/cases): case checking library (CamelCase, snake_case, kebab-case)
|
|
53
54
|
|
|
54
|
-
@magic/log and @magic/types have no dependencies.
|
|
55
|
+
@magic/log, @magic/cases and @magic/types have no dependencies.
|
|
55
56
|
|
|
56
57
|
### <a name="install"></a>install
|
|
57
58
|
be in a node ecmascript module project.
|
|
@@ -434,5 +435,20 @@ update dependencies
|
|
|
434
435
|
##### 0.0.32
|
|
435
436
|
update dependencies
|
|
436
437
|
|
|
437
|
-
##### 0.0.33
|
|
438
|
+
##### 0.0.33
|
|
439
|
+
update dependencies
|
|
440
|
+
|
|
441
|
+
##### 0.0.34
|
|
442
|
+
update dependencies
|
|
443
|
+
|
|
444
|
+
##### 0.0.35
|
|
445
|
+
* parse now can get an opts object as third argument to overwrite child_process.exec options
|
|
446
|
+
* help.argToHelp now errors if the first argument is not an array, before errors only got triggered by falsy arg.
|
|
447
|
+
* exec now uses @magic/error for errors.
|
|
448
|
+
* exec does not trim() the result.
|
|
449
|
+
* findLongestString sorts by length and then alphabetically
|
|
450
|
+
* export execFile
|
|
451
|
+
* update dependencies
|
|
452
|
+
|
|
453
|
+
##### 0.0.36 - unreleased
|
|
438
454
|
...
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@magic/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.36",
|
|
4
4
|
"homepage": "https://magic.github.io/cli",
|
|
5
5
|
"description": "declarative command line interfaces with aliasing, commands and environment sanitization",
|
|
6
6
|
"scripts": {
|
|
@@ -32,19 +32,21 @@
|
|
|
32
32
|
"declarative"
|
|
33
33
|
],
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@magic/cases": "0.0.
|
|
36
|
-
"@magic/
|
|
37
|
-
"@magic/
|
|
35
|
+
"@magic/cases": "0.0.6",
|
|
36
|
+
"@magic/deep": "0.1.9",
|
|
37
|
+
"@magic/error": "0.0.11",
|
|
38
|
+
"@magic/log": "0.1.11",
|
|
39
|
+
"@magic/types": "0.1.17"
|
|
38
40
|
},
|
|
39
41
|
"devDependencies": {
|
|
40
42
|
"@magic-modules/git-badges": "0.0.11",
|
|
41
43
|
"@magic-modules/light-switch": "0.0.10",
|
|
42
44
|
"@magic-modules/no-spy": "0.0.6",
|
|
43
|
-
"@magic-modules/pre": "0.0.
|
|
44
|
-
"@magic-themes/docs": "0.0.
|
|
45
|
-
"@magic/core": "0.0.
|
|
46
|
-
"@magic/format": "0.0.
|
|
47
|
-
"@magic/test": "0.
|
|
45
|
+
"@magic-modules/pre": "0.0.11",
|
|
46
|
+
"@magic-themes/docs": "0.0.14",
|
|
47
|
+
"@magic/core": "0.0.133",
|
|
48
|
+
"@magic/format": "0.0.34",
|
|
49
|
+
"@magic/test": "0.2.0"
|
|
48
50
|
},
|
|
49
51
|
"author": "Wizards & Witches",
|
|
50
52
|
"license": "AGPL-3.0",
|
package/src/exec.mjs
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
import child_process from 'child_process'
|
|
2
2
|
|
|
3
|
+
import error from '@magic/error'
|
|
4
|
+
|
|
3
5
|
const libName = '@magic/cli.exec'
|
|
4
6
|
|
|
5
7
|
export const exec = (cmd, options = {}) =>
|
|
6
8
|
new Promise((resolve, reject) => {
|
|
7
9
|
child_process.exec(cmd, options, (err, stdout, stderr) => {
|
|
8
10
|
if (err) {
|
|
9
|
-
const e =
|
|
10
|
-
e.name = 'E_EXEC_ERR'
|
|
11
|
+
const e = error(err, 'E_EXEC_ERR')
|
|
11
12
|
reject(e)
|
|
12
13
|
return
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
if (stderr) {
|
|
16
|
-
const e = new Error(`${libName}: ${cmd} error: ${stderr}`)
|
|
17
|
-
e.name = 'E_EXEC_STDERR'
|
|
17
|
+
const e = error(new Error(`${libName}: ${cmd} error: ${stderr}`), 'E_EXEC_STDERR')
|
|
18
18
|
reject(e)
|
|
19
19
|
return
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
resolve(stdout
|
|
22
|
+
resolve(stdout)
|
|
23
23
|
})
|
|
24
24
|
})
|
package/src/execFile.mjs
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import child_process from 'child_process'
|
|
2
|
+
|
|
3
|
+
import error from '@magic/error'
|
|
4
|
+
|
|
5
|
+
const libName = '@magic/cli.execFile'
|
|
6
|
+
|
|
7
|
+
export const execFile = (p, args = [], opts = {}) =>
|
|
8
|
+
new Promise((resolve, reject) => {
|
|
9
|
+
child_process.execFile(
|
|
10
|
+
p,
|
|
11
|
+
args.filter(a => a),
|
|
12
|
+
opts,
|
|
13
|
+
(err, stdout, stderr) => {
|
|
14
|
+
if (err) {
|
|
15
|
+
const e = error(err, 'E_EXECFILE_ERR')
|
|
16
|
+
reject(err)
|
|
17
|
+
return
|
|
18
|
+
}
|
|
19
|
+
if (stderr) {
|
|
20
|
+
const e = error(new Error(`${libName}: ${cmd} error: ${stderr}`), 'E_EXECFILE_STDERR')
|
|
21
|
+
reject(e)
|
|
22
|
+
return
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
resolve(stdout)
|
|
26
|
+
},
|
|
27
|
+
)
|
|
28
|
+
})
|
package/src/help/argToHelp.mjs
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
import is from '@magic/types'
|
|
2
2
|
import log from '@magic/log'
|
|
3
|
+
import error from '@magic/error'
|
|
3
4
|
|
|
4
5
|
import { findLongestString } from './findLongestString.mjs'
|
|
5
6
|
|
|
7
|
+
const lib = '@magic/cli.help.argToHelp'
|
|
8
|
+
|
|
6
9
|
export const argToHelp = (arr, help = {}, defaults = {}) => {
|
|
10
|
+
if (!is.array(arr)) {
|
|
11
|
+
throw error(
|
|
12
|
+
`${lib} expects the first argument to be a non-empty array, received: ${arr}`,
|
|
13
|
+
'E_MISSING_ARGUMENT',
|
|
14
|
+
)
|
|
15
|
+
}
|
|
16
|
+
|
|
7
17
|
const longest = findLongestString(arr)
|
|
8
18
|
|
|
9
19
|
return arr
|
|
@@ -19,6 +29,7 @@ export const argToHelp = (arr, help = {}, defaults = {}) => {
|
|
|
19
29
|
let res = log.paint('yellow', name)
|
|
20
30
|
|
|
21
31
|
const dist = longest.length - name.length
|
|
32
|
+
|
|
22
33
|
const placeholder = Array(dist + 1).join(' ')
|
|
23
34
|
|
|
24
35
|
res += placeholder
|
|
@@ -1,20 +1,15 @@
|
|
|
1
|
-
import
|
|
1
|
+
import deep from '@magic/deep'
|
|
2
2
|
|
|
3
3
|
export const findLongestString = arr => {
|
|
4
|
-
|
|
5
|
-
if (is.array(a)) {
|
|
6
|
-
a = findLongestString(a)
|
|
7
|
-
}
|
|
8
|
-
if (is.array(b)) {
|
|
9
|
-
b = findLongestString(b)
|
|
10
|
-
}
|
|
4
|
+
arr = deep.flatten(arr)
|
|
11
5
|
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
const sorted = arr.sort((a, b) => {
|
|
7
|
+
if (a.length !== b.length) {
|
|
8
|
+
return b.length - a.length
|
|
9
|
+
}
|
|
14
10
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
11
|
+
return a > b ? 1 : -1
|
|
12
|
+
})
|
|
18
13
|
|
|
19
|
-
return
|
|
14
|
+
return sorted[0]
|
|
20
15
|
}
|
package/src/help/index.mjs
CHANGED
|
@@ -6,8 +6,6 @@ import { argToHelp } from './argToHelp.mjs'
|
|
|
6
6
|
|
|
7
7
|
export const maybeHelp = args => {
|
|
8
8
|
const { parsed } = args
|
|
9
|
-
const hasArgs = Object.values(parsed).some(a => Object.entries(a).length)
|
|
10
|
-
const flags = ['help', 'h', '-h', '--h', '--help']
|
|
11
9
|
const hasCommands = args.commands && Object.entries(args.commands).length > 0
|
|
12
10
|
const showCommandHelp = hasCommands && Object.keys(parsed.commands).length === 0
|
|
13
11
|
|
|
@@ -27,7 +25,7 @@ export const maybeHelp = args => {
|
|
|
27
25
|
const envHelp = envToHelp(env, help.env)
|
|
28
26
|
|
|
29
27
|
const name = help.name || '@magic/cli wrapped cli.'
|
|
30
|
-
const header =
|
|
28
|
+
const header = is.string(help) ? help : help.text
|
|
31
29
|
|
|
32
30
|
const helpArray = [
|
|
33
31
|
log.paint('green', name),
|
package/src/index.mjs
CHANGED
|
@@ -5,6 +5,7 @@ import { maybeHelp } from './help/index.mjs'
|
|
|
5
5
|
import { parse } from './parse/index.mjs'
|
|
6
6
|
|
|
7
7
|
import { exec as execute } from './exec.mjs'
|
|
8
|
+
import { execFile as executeFile } from './execFile.mjs'
|
|
8
9
|
import { spawn as spawner } from './spawn.mjs'
|
|
9
10
|
import { prompt as promptUser } from './prompt.mjs'
|
|
10
11
|
|
|
@@ -39,4 +40,7 @@ cli.exec = execute
|
|
|
39
40
|
export const prompt = promptUser
|
|
40
41
|
cli.prompt = promptUser
|
|
41
42
|
|
|
43
|
+
export const execFile = executeFile
|
|
44
|
+
cli.execFile = executeFile
|
|
45
|
+
|
|
42
46
|
export default cli
|
package/src/parse/argv.mjs
CHANGED
|
@@ -19,6 +19,7 @@ export const parseArgv = ({
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
if (arg.startsWith('-')) {
|
|
22
|
+
// this is a key
|
|
22
23
|
let argvArg
|
|
23
24
|
options.forEach(option => {
|
|
24
25
|
if (is.array(option)) {
|
|
@@ -37,6 +38,7 @@ export const parseArgv = ({
|
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
40
|
} else {
|
|
41
|
+
// this is a value
|
|
40
42
|
if (lastArg) {
|
|
41
43
|
argv[lastArg].push(arg)
|
|
42
44
|
}
|
|
@@ -62,14 +64,14 @@ export const parseArgv = ({
|
|
|
62
64
|
}
|
|
63
65
|
|
|
64
66
|
let argvPrepend = []
|
|
65
|
-
if (!
|
|
67
|
+
if (!is.array(prepend)) {
|
|
66
68
|
argvPrepend.push(prepend)
|
|
67
69
|
} else if (prepend.length) {
|
|
68
70
|
Object.entries(prepend).forEach(([k, v]) => {
|
|
69
71
|
argv[k] = v
|
|
70
72
|
|
|
71
73
|
argvPrepend.push(k)
|
|
72
|
-
if (!
|
|
74
|
+
if (!is.array(v)) {
|
|
73
75
|
argvPrepend.push(v)
|
|
74
76
|
} else {
|
|
75
77
|
argvPrepend = [...argvPrepend, ...v]
|
|
@@ -78,7 +80,7 @@ export const parseArgv = ({
|
|
|
78
80
|
}
|
|
79
81
|
|
|
80
82
|
let argvAppend = []
|
|
81
|
-
if (!
|
|
83
|
+
if (!is.array(append)) {
|
|
82
84
|
argvAppend.push(append)
|
|
83
85
|
} else if (append.length) {
|
|
84
86
|
Object.entries(append)
|
package/src/parse/clean.mjs
CHANGED
|
@@ -1,20 +1,27 @@
|
|
|
1
1
|
import is from '@magic/types'
|
|
2
2
|
import cases from '@magic/cases'
|
|
3
3
|
|
|
4
|
-
export const clean = (cli, props) => {
|
|
4
|
+
export const clean = (cli, props = {}) => {
|
|
5
5
|
if (is.empty(props.single)) {
|
|
6
6
|
return cli
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
props.single.map(s => {
|
|
10
|
-
if (cli.argv[s] && is.array(cli.argv[s])) {
|
|
11
|
-
cli.argv[s] = cli.argv[s].join(' ')
|
|
12
|
-
}
|
|
13
|
-
|
|
14
10
|
const c = cases.camel(s)
|
|
11
|
+
const def = props.default && (props.default[s] || props.default[c])
|
|
12
|
+
|
|
13
|
+
const a = cli.argv[s]
|
|
14
|
+
|
|
15
|
+
if (!is.empty(a)) {
|
|
16
|
+
const str = is.array(a) ? a.join(' ') : a
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
if (str) {
|
|
19
|
+
cli.argv[s] = str
|
|
20
|
+
cli.args[c] = str
|
|
21
|
+
}
|
|
22
|
+
} else if (def) {
|
|
23
|
+
cli.argv[s] = def
|
|
24
|
+
cli.args[c] = def
|
|
18
25
|
}
|
|
19
26
|
})
|
|
20
27
|
|
package/src/parse/commands.mjs
CHANGED
|
@@ -1,43 +1,54 @@
|
|
|
1
|
-
|
|
1
|
+
import log from '@magic/log'
|
|
2
|
+
import is from '@magic/types'
|
|
3
|
+
|
|
4
|
+
export const parseCommands = (props = {}) => {
|
|
5
|
+
const { commands = [], pure = false } = props
|
|
2
6
|
const { argv } = process
|
|
3
7
|
const runAll = argv.includes('all')
|
|
4
8
|
|
|
5
|
-
const cmds =
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
if (argv.includes(tasks)) {
|
|
11
|
-
idx = argv.indexOf(tasks)
|
|
12
|
-
key = tasks
|
|
13
|
-
} else if (runAll) {
|
|
14
|
-
key = tasks
|
|
15
|
-
}
|
|
16
|
-
} else {
|
|
17
|
-
if (!Array.isArray(tasks)) {
|
|
18
|
-
tasks = [tasks]
|
|
19
|
-
}
|
|
9
|
+
const cmds = Object.fromEntries(
|
|
10
|
+
commands
|
|
11
|
+
.map((tasks = []) => {
|
|
12
|
+
let key
|
|
13
|
+
let idx = -1
|
|
20
14
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
15
|
+
if (is.string(tasks)) {
|
|
16
|
+
if (argv.includes(tasks)) {
|
|
17
|
+
idx = argv.indexOf(tasks)
|
|
18
|
+
key = tasks
|
|
19
|
+
} else if (runAll) {
|
|
20
|
+
key = tasks
|
|
21
|
+
}
|
|
22
|
+
} else if (is.array(tasks)) {
|
|
23
|
+
if (runAll) {
|
|
24
|
+
key = tasks[0]
|
|
25
|
+
} else {
|
|
26
|
+
const idxArray = tasks
|
|
27
|
+
.filter(task => argv.includes(task))
|
|
28
|
+
.map(task => argv.indexOf(task))
|
|
25
29
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
idx = idxArray[0]
|
|
31
|
+
key = tasks[0]
|
|
32
|
+
}
|
|
33
|
+
} else {
|
|
34
|
+
log.error(
|
|
35
|
+
'E_UNEXPECTED_TASK',
|
|
36
|
+
`@magic/cli: got unexpected task type: ${typeof tasks}, can handle strings or arrays`,
|
|
37
|
+
)
|
|
38
|
+
}
|
|
30
39
|
|
|
31
|
-
|
|
32
|
-
|
|
40
|
+
if (idx > -1) {
|
|
41
|
+
if (!pure) {
|
|
42
|
+
argv[idx] = key
|
|
43
|
+
}
|
|
33
44
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
45
|
+
return [key, true]
|
|
46
|
+
} else if (runAll) {
|
|
47
|
+
return [key, true]
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
.filter(a => a),
|
|
51
|
+
)
|
|
41
52
|
|
|
42
53
|
return cmds
|
|
43
54
|
}
|
package/src/parse/env.mjs
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import is from '@magic/types'
|
|
2
|
+
|
|
1
3
|
export const parseEnv = ({ env = [], pure = false }) => {
|
|
2
4
|
const environment = []
|
|
3
5
|
|
|
4
6
|
// set env depending on env switches
|
|
5
7
|
env
|
|
6
8
|
.filter(([argv]) => {
|
|
7
|
-
if (!
|
|
9
|
+
if (!is.array(argv)) {
|
|
8
10
|
argv = [argv]
|
|
9
11
|
}
|
|
10
12
|
return argv.some(a => process.argv.includes(a))
|
package/src/parse/required.mjs
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import is from '@magic/types'
|
|
2
2
|
|
|
3
|
-
export const parseRequired = (
|
|
4
|
-
const {
|
|
3
|
+
export const parseRequired = (args = {}) => {
|
|
4
|
+
const {
|
|
5
|
+
parsed,
|
|
6
|
+
props: { required },
|
|
7
|
+
} = args
|
|
5
8
|
|
|
6
9
|
if (is.empty(required)) {
|
|
7
10
|
return []
|
package/src/spawn.mjs
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import child_process from 'child_process'
|
|
2
2
|
|
|
3
|
-
export const spawn = (cmd, args = []) => {
|
|
3
|
+
export const spawn = (cmd, args = [], opt = {}) => {
|
|
4
4
|
const opts = {
|
|
5
5
|
cwd: process.cwd(),
|
|
6
6
|
env: process.env,
|
|
7
7
|
stdio: 'inherit',
|
|
8
|
+
...opt,
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
return child_process.spawn(cmd, args, opts)
|