@@ -9,8 +9,22 @@ import {
99import axios from 'axios'
1010import path from 'path'
1111import simpleGit , { Response } from 'simple-git'
12+ import YAML from 'js-yaml'
1213import { 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+
1428const baseDir = path . join ( process . cwd ( ) , getInput ( 'cwd' ) || '' )
1529const git = simpleGit ( { baseDir } )
1630console . 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
333447function logOutputs ( ) {
0 commit comments