Skip to content

Commit 6f812a4

Browse files
authored
Support YAML/JSON arrays for add and remove inputs (#114)
* feat: support arrays as add/remove inputs re #95 * chore: add debug log for parsed input type
1 parent f11ed1f commit 6f812a4

File tree

4 files changed

+160
-59
lines changed

4 files changed

+160
-59
lines changed

lib/index.js

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

package-lock.json

Lines changed: 11 additions & 25 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,12 @@
3636
"dependencies": {
3737
"@actions/core": "^1.2.6",
3838
"axios": "^0.21.0",
39+
"js-yaml": "^3.14.0",
3940
"simple-git": "^2.27.0"
4041
},
4142
"devDependencies": {
43+
"@types/js-yaml": "^3.12.5",
4244
"@types/node": "^12.12.54",
43-
"@types/yamljs": "^0.2.31",
4445
"@typescript-eslint/eslint-plugin": "^2.34.0",
4546
"@typescript-eslint/parser": "^2.34.0",
4647
"@vercel/ncc": "^0.25.1",

src/main.ts

Lines changed: 146 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,22 @@ import {
99
import axios from 'axios'
1010
import path from 'path'
1111
import simpleGit, { Response } from 'simple-git'
12+
import YAML from 'js-yaml'
1213
import { getInput, Input, log, outputs, parseBool, setOutput } from './util'
1314

15+
type Input =
16+
| 'add'
17+
| 'author_name'
18+
| 'author_email'
19+
| 'branch'
20+
| 'cwd'
21+
| 'message'
22+
| 'pull_strategy'
23+
| 'push'
24+
| 'remove'
25+
| 'signoff'
26+
| 'tag'
27+
1428
const baseDir = path.join(process.cwd(), getInput('cwd') || '')
1529
const git = simpleGit({ baseDir })
1630
console.log(`Running in ${baseDir}`)
@@ -179,6 +193,27 @@ async function checkInputs() {
179193
throw new Error(
180194
"Both 'add' and 'remove' are empty, the action has nothing to do."
181195
)
196+
197+
if (getInput('add')) {
198+
const parsed = parseInputArray(getInput('add'))
199+
if (parsed.length == 1)
200+
info('Add input parsed as single string, running 1 git add command.')
201+
else if (parsed.length > 1)
202+
info(
203+
`Add input parsed as string array, running ${parsed.length} git add commands.`
204+
)
205+
else setFailed('Add input: array length < 1')
206+
}
207+
if (getInput('remove')) {
208+
const parsed = parseInputArray(getInput('remove'))
209+
if (parsed.length == 1)
210+
info('Remove input parsed as single string, running 1 git rm command.')
211+
else if (parsed.length > 1)
212+
info(
213+
`Remove input parsed as string array, running ${parsed.length} git rm commands.`
214+
)
215+
else setFailed('Remove input: array length < 1')
216+
}
182217
// #endregion
183218

184219
// #region author_name, author_email
@@ -290,44 +325,123 @@ async function checkInputs() {
290325
}
291326
// #endregion
292327
}
293-
function add({
294-
logWarning = true,
295-
ignoreErrors = false
296-
} = {}): Promise<void | Response<void>> | void {
297-
if (getInput('add'))
298-
return git
299-
.add(getInput('add').split(' '), (e: any, d?: any) =>
300-
log(ignoreErrors ? null : e, d)
301-
)
302-
.catch((e: Error) => {
303-
if (ignoreErrors) return
304-
if (
305-
e.message.includes('fatal: pathspec') &&
306-
e.message.includes('did not match any files')
328+
329+
function getInput(name: Input) {
330+
return getInputCore(name)
331+
}
332+
333+
function parseBool(value: any) {
334+
try {
335+
const parsed = JSON.parse(value)
336+
if (typeof parsed == 'boolean') return parsed
337+
} catch {}
338+
}
339+
340+
function log(err: any | Error, data?: any) {
341+
if (data) console.log(data)
342+
if (err) error(err)
343+
}
344+
345+
async function add({ logWarning = true, ignoreErrors = false } = {}): Promise<
346+
(void | Response<void>)[]
347+
> {
348+
const input = getInput('add')
349+
if (!input) return []
350+
351+
const parsed = parseInputArray(input)
352+
const res: (void | Response<void>)[] = []
353+
354+
for (const args of parsed) {
355+
res.push(
356+
// Push the result of every git command (which are executed in order) to the array
357+
// If any of them fails, the whole function will return a Promise rejection
358+
await git
359+
.add(args.split(' '), (err: any, data?: any) =>
360+
log(ignoreErrors ? null : err, data)
307361
)
308-
logWarning && warning('Add command did not match any file.')
309-
else throw e
310-
})
362+
.catch((e: Error) => {
363+
if (ignoreErrors) return
364+
if (
365+
e.message.includes('fatal: pathspec') &&
366+
e.message.includes('did not match any files') &&
367+
logWarning
368+
)
369+
warning(`Add command did not match any file:\n git add ${args}`)
370+
else throw e
371+
})
372+
)
373+
}
374+
375+
return res
311376
}
312377

313-
function remove({
378+
async function remove({
314379
logWarning = true,
315380
ignoreErrors = false
316-
} = {}): Promise<void | Response<void>> | void {
317-
if (getInput('remove'))
318-
return git
319-
.rm(getInput('remove').split(' '), (e: any, d?: any) =>
320-
log(ignoreErrors ? null : e, d)
321-
)
322-
.catch((e: Error) => {
323-
if (ignoreErrors) return
324-
if (
325-
e.message.includes('fatal: pathspec') &&
326-
e.message.includes('did not match any files')
381+
} = {}): Promise<(void | Response<void>)[]> {
382+
const input = getInput('remove')
383+
if (!input) return []
384+
385+
const parsed = parseInputArray(input)
386+
const res: (void | Response<void>)[] = []
387+
388+
for (const args of parsed) {
389+
res.push(
390+
// Push the result of every git command (which are executed in order) to the array
391+
// If any of them fails, the whole function will return a Promise rejection
392+
await git
393+
.rm(args.split(' '), (e: any, d?: any) =>
394+
log(ignoreErrors ? null : e, d)
327395
)
328-
logWarning && warning('Remove command did not match any file.')
329-
else throw e
330-
})
396+
.catch((e: Error) => {
397+
if (ignoreErrors) return
398+
if (
399+
e.message.includes('fatal: pathspec') &&
400+
e.message.includes('did not match any files')
401+
)
402+
logWarning &&
403+
warning(
404+
`Remove command did not match any file:\n git rm ${args}`
405+
)
406+
else throw e
407+
})
408+
)
409+
}
410+
411+
return res
412+
}
413+
414+
/**
415+
* Tries to parse a JSON array, then a YAML array.
416+
* If both fail, it returns an array containing the input value as its only element
417+
*/
418+
function parseInputArray(input: string): string[] {
419+
try {
420+
const json = JSON.parse(input)
421+
if (
422+
json &&
423+
Array.isArray(json) &&
424+
json.every((e) => typeof e == 'string')
425+
) {
426+
debug(`Input parsed as JSON array of length ${json.length}`)
427+
return json
428+
}
429+
} catch {}
430+
431+
try {
432+
const yaml = YAML.safeLoad(input)
433+
if (
434+
yaml &&
435+
Array.isArray(yaml) &&
436+
yaml.every((e) => typeof e == 'string')
437+
) {
438+
debug(`Input parsed as YAML array of length ${yaml.length}`)
439+
return yaml
440+
}
441+
} catch {}
442+
443+
debug('Input parsed as single string')
444+
return [input]
331445
}
332446

333447
function logOutputs() {

0 commit comments

Comments
 (0)