@magic/cli 0.0.31 → 0.0.35

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 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.
@@ -431,5 +432,23 @@ update dependencies
431
432
  * bump required node version to 14.15.4
432
433
  * update dependencies
433
434
 
434
- ##### 0.0.32 - unreleased
435
+ ##### 0.0.32
436
+ update dependencies
437
+
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
435
454
  ...
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magic/cli",
3
- "version": "0.0.31",
3
+ "version": "0.0.35",
4
4
  "homepage": "https://magic.github.io/cli",
5
5
  "description": "declarative command line interfaces with aliasing, commands and environment sanitization",
6
6
  "scripts": {
@@ -13,6 +13,7 @@
13
13
  "calls": "calls"
14
14
  },
15
15
  "main": "src/index.mjs",
16
+ "type": "module",
16
17
  "files": [
17
18
  "src"
18
19
  ],
@@ -31,19 +32,21 @@
31
32
  "declarative"
32
33
  ],
33
34
  "dependencies": {
34
- "@magic/cases": "0.0.4",
35
- "@magic/log": "0.1.8",
36
- "@magic/types": "0.1.14"
35
+ "@magic/cases": "0.0.5",
36
+ "@magic/deep": "0.1.8",
37
+ "@magic/error": "0.0.10",
38
+ "@magic/log": "0.1.10",
39
+ "@magic/types": "0.1.16"
37
40
  },
38
41
  "devDependencies": {
39
42
  "@magic-modules/git-badges": "0.0.11",
40
43
  "@magic-modules/light-switch": "0.0.10",
41
44
  "@magic-modules/no-spy": "0.0.6",
42
- "@magic-modules/pre": "0.0.10",
43
- "@magic-themes/docs": "0.0.12",
44
- "@magic/core": "0.0.101",
45
- "@magic/format": "0.0.20",
46
- "@magic/test": "0.1.59"
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"
47
50
  },
48
51
  "author": "Wizards & Witches",
49
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 = new Error(`${libName}: ${cmd} error: ${err.message}`)
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.trim())
22
+ resolve(stdout)
23
23
  })
24
24
  })
@@ -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
+ })
@@ -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 is from '@magic/types'
1
+ import deep from '@magic/deep'
2
2
 
3
3
  export const findLongestString = arr => {
4
- const longest = arr.sort((a, b) => {
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
- return a.length > b.length ? -1 : 1
13
- })[0]
6
+ const sorted = arr.sort((a, b) => {
7
+ if (a.length !== b.length) {
8
+ return b.length - a.length
9
+ }
14
10
 
15
- if (is.array(longest)) {
16
- return longest[0]
17
- }
11
+ return a > b ? 1 : -1
12
+ })
18
13
 
19
- return longest
14
+ return sorted[0]
20
15
  }
@@ -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 = typeof help === 'string' ? help : help.text
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
@@ -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 (!Array.isArray(prepend)) {
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 (!Array.isArray(v)) {
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 (!Array.isArray(append)) {
83
+ if (!is.array(append)) {
82
84
  argvAppend.push(append)
83
85
  } else if (append.length) {
84
86
  Object.entries(append)
@@ -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
- if (cli.args[c] && is.array(cli.args[c])) {
17
- cli.args[c] = cli.args[c].join(' ')
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
 
@@ -1,43 +1,54 @@
1
- export const parseCommands = ({ commands = [], pure = false }) => {
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
- commands.map((tasks = []) => {
7
- let key
8
- let idx = -1
9
- if (typeof tasks === 'string') {
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
- if (runAll) {
22
- key = tasks[0]
23
- } else {
24
- const idxArray = tasks.filter(task => argv.includes(task)).map(task => argv.indexOf(task))
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
- idx = idxArray[0]
27
- key = tasks[0]
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
- if (idx > -1) {
32
- cmds[key] = true
40
+ if (idx > -1) {
41
+ if (!pure) {
42
+ argv[idx] = key
43
+ }
33
44
 
34
- if (!pure) {
35
- argv[idx] = key
36
- }
37
- } else if (runAll) {
38
- cmds[key] = true
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 (!Array.isArray(argv)) {
9
+ if (!is.array(argv)) {
8
10
  argv = [argv]
9
11
  }
10
12
  return argv.some(a => process.argv.includes(a))
@@ -1,7 +1,10 @@
1
1
  import is from '@magic/types'
2
2
 
3
- export const parseRequired = ({ props, parsed }) => {
4
- const { options, required } = props
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)