diff --git a/common/src/common-utils.ts b/common/src/common-utils.ts index 666e289..4de9d53 100644 --- a/common/src/common-utils.ts +++ b/common/src/common-utils.ts @@ -1,4 +1,6 @@ +import { setOutput } from '@actions/core'; import { getExecOutput } from '@actions/exec' +import { stringifyForShell } from './serialization-utils'; export async function execCommand(command: string): Promise { const { stdout, stderr, exitCode } = await getExecOutput(command) @@ -9,3 +11,9 @@ export async function execCommand(command: string): Promise { return stdout.trim() } + +export function setOutputs(values: Record): void { + for (const [key, value] of Object.entries(values)) { + setOutput(key, stringifyForShell(value)); + } +} diff --git a/common/src/constants.ts b/common/src/constants.ts index 6ac0bc3..4f591af 100644 --- a/common/src/constants.ts +++ b/common/src/constants.ts @@ -1,7 +1,6 @@ export const inputs = { GH_TOKEN: 'gh-token', - OUTPUT: 'output', PATHS: 'paths', } as const; diff --git a/common/src/path-utils.test.ts b/common/src/path-utils.test.ts index 1a0a07d..bc8c9e5 100644 --- a/common/src/path-utils.test.ts +++ b/common/src/path-utils.test.ts @@ -1,4 +1,4 @@ -import { filterPaths } from "./path-utils"; +import { filterPaths, normalizePatterns } from "./path-utils"; describe('path utils', () => { @@ -9,6 +9,11 @@ describe('path utils', () => { patterns: [], expected: [] }, + { + paths: ['a.ts', 'a.js', 'b.md'], + patterns: [], + expected: ['a.ts', 'a.js', 'b.md'] + }, { paths: ['a.ts', 'a.js', 'b.md'], patterns: ['b*.*'], @@ -89,4 +94,18 @@ describe('path utils', () => { expect(filterPaths(paths, patterns)).toEqual(expected); }); }); + + describe('normalizePatterns', () => { + test.each([ + { patterns: undefined, expected: undefined }, + { patterns: [ ], expected: undefined }, + { patterns: [ undefined ], expected: undefined }, + { patterns: [ '' ], expected: undefined }, + { patterns: [ '', undefined ], expected: undefined }, + { patterns: ['a'], expected: ['a'] }, + { patterns: ['', 'a', undefined ], expected: ['a'] }, + ])('basic cases [%#]', ({ patterns, expected }) => { + expect(normalizePatterns(patterns)).toEqual(expected); + }); + }); }); diff --git a/common/src/path-utils.ts b/common/src/path-utils.ts index 4ee432a..6a4b7cd 100644 --- a/common/src/path-utils.ts +++ b/common/src/path-utils.ts @@ -24,11 +24,23 @@ function filterPathsImpl( paths: string[], patterns: string[], ): string[] { - return paths.filter(path => { - return patterns.reduce((prevResult, pattern) => { - return pattern.startsWith(NEGATION) - ? prevResult && !match(path, pattern.substring(1)) - : prevResult || match(path, pattern); - }, false); - }); + const normalizedPatterns = normalizePatterns(patterns); + return normalizedPatterns === undefined + ? paths + : paths.filter(path => testPath(path, normalizedPatterns)); +} + +export function normalizePatterns(patterns?: (string | undefined)[]): string[] | undefined { + if(!patterns) return undefined; + + const notEmptyPatterns = patterns.filter(p => p != undefined && p.length > 0); + return (notEmptyPatterns.length > 0 ? notEmptyPatterns : undefined) as ReturnType; +} + +export function testPath(path: string, patterns: string[]): boolean { + return patterns.reduce((prevResult, pattern) => { + return pattern.startsWith(NEGATION) + ? prevResult && !match(path, pattern.substring(1)) + : prevResult || match(path, pattern); + }, false); } diff --git a/common/src/pr-utils.ts b/common/src/pr-utils.ts index 968a0fc..9231545 100644 --- a/common/src/pr-utils.ts +++ b/common/src/pr-utils.ts @@ -1,6 +1,7 @@ -import * as core from '@actions/core' -import { context, getOctokit } from '@actions/github' +import * as core from '@actions/core'; +import { context, getOctokit } from '@actions/github'; +import { components } from '@octokit/openapi-types'; import { execCommand } from './common-utils'; export async function getPrRevisionRange(): Promise<{ @@ -42,14 +43,19 @@ function normalizeCommit(commit: string) { return commit === '0000000000000000000000000000000000000000' ? 'HEAD^' : commit; } -export async function getChangedFiles(token: string): Promise { +interface ChangedFile { + path: string; + status: components['schemas']['diff-entry']['status']; +} + +export async function getChangedFiles(token: string): Promise { return getChangedFilesImpl(token).then((files) => { core.info(`${files.length} changed files: ${JSON.stringify(files, undefined, 2)}`) return files; }); } -async function getChangedFilesImpl(token: string): Promise { +async function getChangedFilesImpl(token: string): Promise { try { const octokit = getOctokit(token); @@ -58,13 +64,13 @@ async function getChangedFilesImpl(token: string): Promise { return []; } - const files = await octokit.paginate(octokit.rest.pulls.listFiles, { + const entries = await octokit.paginate(octokit.rest.pulls.listFiles, { owner: context.repo.owner, repo: context.repo.repo, pull_number: context.payload.pull_request.number, }); - return files.map(file => file.filename); + return entries.map(({ filename, status }) => ({ path: filename, status })); } catch (error) { core.setFailed(`Getting changed files failed with error: ${error}`); return []; diff --git a/common/src/serialization-utils.test.ts b/common/src/serialization-utils.test.ts new file mode 100644 index 0000000..8baa218 --- /dev/null +++ b/common/src/serialization-utils.test.ts @@ -0,0 +1,23 @@ +import { stringifyForShell } from "./serialization-utils"; + +describe('action utils', () => { + + describe(stringifyForShell.name, () => { + test.each([ + { value: 123, expected: '123' }, + { value: 'abc', expected: 'abc' }, + ])('scalar cases [%#]', ({ value, expected }) => { + expect(stringifyForShell(value)).toEqual(expected); + }); + }); + + describe(stringifyForShell.name, () => { + test.each([ + { value: [123, 456], expected: '123 456' }, + { value: ['abc', 'def'], expected: '\'abc\' \'def\'' }, + ])('array values [%#]', ({ value, expected }) => { + expect(stringifyForShell(value)).toEqual(expected); + }); + }); + +}); diff --git a/common/src/serialization-utils.ts b/common/src/serialization-utils.ts new file mode 100644 index 0000000..3903c65 --- /dev/null +++ b/common/src/serialization-utils.ts @@ -0,0 +1,35 @@ +function stringifyArrayItem(item: unknown): string { + switch (typeof item) { + case 'number': + return item.toString(); + + case 'string': + return `'${item}'`; + + default: + return JSON.stringify(item); + } +} + +export function stringifyForShell(value: unknown): string { + + switch (typeof value) { + + case 'string': + return value; + + case 'object': + if (Array.isArray(value)) { + return value.map(stringifyArrayItem).join(' '); + } + + if (value === null) { + return ''; + } + + return value.toString(); + + default: + return JSON.stringify(value); + } +} \ No newline at end of file diff --git a/get-changed-files/action.yml b/get-changed-files/action.yml index 0eb1700..886f910 100644 --- a/get-changed-files/action.yml +++ b/get-changed-files/action.yml @@ -11,15 +11,16 @@ inputs: description: Semicolon separated globs required: false - output: - description: Output file path - required: true - - runs: using: node16 main: dist/index.js outputs: - result: - description: A file with the list of files in JSON format + count: + description: The count of all files changed in the PR + files: + description: Space-separated list of all files changed in the PR + json: + description: | + Full output in JSON format. + 'Schema: { files: { path: string; status: string; } []; count: number; }' diff --git a/get-changed-files/dist/index.js b/get-changed-files/dist/index.js index 35296ac..7196793 100644 --- a/get-changed-files/dist/index.js +++ b/get-changed-files/dist/index.js @@ -16,8 +16,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.execCommand = void 0; +exports.setOutputs = exports.execCommand = void 0; +const core_1 = __nccwpck_require__(5316); const exec_1 = __nccwpck_require__(110); +const serialization_utils_1 = __nccwpck_require__(9091); function execCommand(command) { return __awaiter(this, void 0, void 0, function* () { const { stdout, stderr, exitCode } = yield (0, exec_1.getExecOutput)(command); @@ -28,6 +30,12 @@ function execCommand(command) { }); } exports.execCommand = execCommand; +function setOutputs(values) { + for (const [key, value] of Object.entries(values)) { + (0, core_1.setOutput)(key, (0, serialization_utils_1.stringifyForShell)(value)); + } +} +exports.setOutputs = setOutputs; /***/ }), @@ -41,7 +49,6 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.outputs = exports.inputs = void 0; exports.inputs = { GH_TOKEN: 'gh-token', - OUTPUT: 'output', PATHS: 'paths', }; exports.outputs = { @@ -126,7 +133,7 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.filterPaths = void 0; +exports.testPath = exports.normalizePatterns = exports.filterPaths = void 0; const core = __importStar(__nccwpck_require__(5316)); const minimatch_1 = __nccwpck_require__(148); const NEGATION = '!'; @@ -144,14 +151,26 @@ function filterPaths(paths, patterns) { } exports.filterPaths = filterPaths; function filterPathsImpl(paths, patterns) { - return paths.filter(path => { - return patterns.reduce((prevResult, pattern) => { - return pattern.startsWith(NEGATION) - ? prevResult && !match(path, pattern.substring(1)) - : prevResult || match(path, pattern); - }, false); - }); + const normalizedPatterns = normalizePatterns(patterns); + return normalizedPatterns === undefined + ? paths + : paths.filter(path => testPath(path, normalizedPatterns)); +} +function normalizePatterns(patterns) { + if (!patterns) + return undefined; + const notEmptyPatterns = patterns.filter(p => p != undefined && p.length > 0); + return (notEmptyPatterns.length > 0 ? notEmptyPatterns : undefined); } +exports.normalizePatterns = normalizePatterns; +function testPath(path, patterns) { + return patterns.reduce((prevResult, pattern) => { + return pattern.startsWith(NEGATION) + ? prevResult && !match(path, pattern.substring(1)) + : prevResult || match(path, pattern); + }, false); +} +exports.testPath = testPath; /***/ }), @@ -249,12 +268,12 @@ function getChangedFilesImpl(token) { core.setFailed('Getting changed files only works on pull request events.'); return []; } - const files = yield octokit.paginate(octokit.rest.pulls.listFiles, { + const entries = yield octokit.paginate(octokit.rest.pulls.listFiles, { owner: github_1.context.repo.owner, repo: github_1.context.repo.repo, pull_number: github_1.context.payload.pull_request.number, }); - return files.map(file => file.filename); + return entries.map(({ filename, status }) => ({ path: filename, status })); } catch (error) { core.setFailed(`Getting changed files failed with error: ${error}`); @@ -264,6 +283,44 @@ function getChangedFilesImpl(token) { } +/***/ }), + +/***/ 9091: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.stringifyForShell = void 0; +function stringifyArrayItem(item) { + switch (typeof item) { + case 'number': + return item.toString(); + case 'string': + return `'${item}'`; + default: + return JSON.stringify(item); + } +} +function stringifyForShell(value) { + switch (typeof value) { + case 'string': + return value; + case 'object': + if (Array.isArray(value)) { + return value.map(stringifyArrayItem).join(' '); + } + if (value === null) { + return ''; + } + return value.toString(); + default: + return JSON.stringify(value); + } +} +exports.stringifyForShell = stringifyForShell; + + /***/ }), /***/ 2013: @@ -514,20 +571,26 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", ({ value: true })); -const fs = __importStar(__nccwpck_require__(7147)); const core = __importStar(__nccwpck_require__(5316)); const common_1 = __nccwpck_require__(9145); function run() { return __awaiter(this, void 0, void 0, function* () { try { - const pathPatterns = core.getInput(common_1.inputs.PATHS).split(';'); + const patterns = (0, common_1.normalizePatterns)(core.getInput(common_1.inputs.PATHS).split(';')); const token = core.getInput(common_1.inputs.GH_TOKEN, { required: true }); - const output = core.getInput(common_1.inputs.OUTPUT, { required: true }); - console.log('patterns: ' + JSON.stringify(pathPatterns, undefined, 2)); + console.log('patterns: ' + JSON.stringify(patterns, undefined, 2)); const changedFiles = yield (0, common_1.getChangedFiles)(token); - const filteredFiles = (0, common_1.filterPaths)(changedFiles, pathPatterns); - (0, common_1.ensureDir)(output); - fs.writeFileSync(output, JSON.stringify(filteredFiles.map(filename => ({ filename })), undefined, 2)); + const filteredFiles = patterns === undefined + ? changedFiles + : changedFiles.filter(({ path }) => (0, common_1.testPath)(path, patterns)); + (0, common_1.setOutputs)({ + json: JSON.stringify({ + files: filteredFiles, + count: filteredFiles.length, + }), + files: filteredFiles.map(e => e.path), + count: filteredFiles.length, + }); } catch (error) { if (error instanceof Error) { diff --git a/get-changed-files/src/main.ts b/get-changed-files/src/main.ts index d832f2a..8b28f80 100644 --- a/get-changed-files/src/main.ts +++ b/get-changed-files/src/main.ts @@ -1,22 +1,34 @@ -import * as fs from 'fs'; import * as core from '@actions/core'; -import { inputs, filterPaths, getChangedFiles, ensureDir } from 'common'; +import { + inputs, + getChangedFiles, + setOutputs, + testPath, + normalizePatterns, +} from 'common'; async function run(): Promise { try { - const pathPatterns = core.getInput(inputs.PATHS).split(';'); + const patterns = normalizePatterns(core.getInput(inputs.PATHS).split(';')); const token = core.getInput(inputs.GH_TOKEN, { required: true }); - const output = core.getInput(inputs.OUTPUT, { required: true }); - console.log('patterns: ' + JSON.stringify(pathPatterns, undefined, 2)); + console.log('patterns: ' + JSON.stringify(patterns, undefined, 2)); const changedFiles = await getChangedFiles(token); - const filteredFiles = filterPaths(changedFiles, pathPatterns); + const filteredFiles = patterns === undefined + ? changedFiles + : changedFiles.filter(({ path }) => testPath(path, patterns)); - ensureDir(output); - fs.writeFileSync(output, JSON.stringify(filteredFiles.map(filename => ({ filename })), undefined, 2)); + setOutputs({ + json: JSON.stringify({ + files: filteredFiles, + count: filteredFiles.length, + }), + files: filteredFiles.map(e => e.path), + count: filteredFiles.length, + }); } catch (error) { if (error instanceof Error) { core.setFailed(error.message) diff --git a/pr-filter/dist/index.js b/pr-filter/dist/index.js index 1791f1f..89e3ade 100644 --- a/pr-filter/dist/index.js +++ b/pr-filter/dist/index.js @@ -16,8 +16,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.execCommand = void 0; +exports.setOutputs = exports.execCommand = void 0; +const core_1 = __nccwpck_require__(5316); const exec_1 = __nccwpck_require__(110); +const serialization_utils_1 = __nccwpck_require__(9091); function execCommand(command) { return __awaiter(this, void 0, void 0, function* () { const { stdout, stderr, exitCode } = yield (0, exec_1.getExecOutput)(command); @@ -28,6 +30,12 @@ function execCommand(command) { }); } exports.execCommand = execCommand; +function setOutputs(values) { + for (const [key, value] of Object.entries(values)) { + (0, core_1.setOutput)(key, (0, serialization_utils_1.stringifyForShell)(value)); + } +} +exports.setOutputs = setOutputs; /***/ }), @@ -41,7 +49,6 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.outputs = exports.inputs = void 0; exports.inputs = { GH_TOKEN: 'gh-token', - OUTPUT: 'output', PATHS: 'paths', }; exports.outputs = { @@ -126,7 +133,7 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.filterPaths = void 0; +exports.testPath = exports.normalizePatterns = exports.filterPaths = void 0; const core = __importStar(__nccwpck_require__(5316)); const minimatch_1 = __nccwpck_require__(148); const NEGATION = '!'; @@ -144,14 +151,26 @@ function filterPaths(paths, patterns) { } exports.filterPaths = filterPaths; function filterPathsImpl(paths, patterns) { - return paths.filter(path => { - return patterns.reduce((prevResult, pattern) => { - return pattern.startsWith(NEGATION) - ? prevResult && !match(path, pattern.substring(1)) - : prevResult || match(path, pattern); - }, false); - }); + const normalizedPatterns = normalizePatterns(patterns); + return normalizedPatterns === undefined + ? paths + : paths.filter(path => testPath(path, normalizedPatterns)); +} +function normalizePatterns(patterns) { + if (!patterns) + return undefined; + const notEmptyPatterns = patterns.filter(p => p != undefined && p.length > 0); + return (notEmptyPatterns.length > 0 ? notEmptyPatterns : undefined); +} +exports.normalizePatterns = normalizePatterns; +function testPath(path, patterns) { + return patterns.reduce((prevResult, pattern) => { + return pattern.startsWith(NEGATION) + ? prevResult && !match(path, pattern.substring(1)) + : prevResult || match(path, pattern); + }, false); } +exports.testPath = testPath; /***/ }), @@ -249,12 +268,12 @@ function getChangedFilesImpl(token) { core.setFailed('Getting changed files only works on pull request events.'); return []; } - const files = yield octokit.paginate(octokit.rest.pulls.listFiles, { + const entries = yield octokit.paginate(octokit.rest.pulls.listFiles, { owner: github_1.context.repo.owner, repo: github_1.context.repo.repo, pull_number: github_1.context.payload.pull_request.number, }); - return files.map(file => file.filename); + return entries.map(({ filename, status }) => ({ path: filename, status })); } catch (error) { core.setFailed(`Getting changed files failed with error: ${error}`); @@ -264,6 +283,44 @@ function getChangedFilesImpl(token) { } +/***/ }), + +/***/ 9091: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.stringifyForShell = void 0; +function stringifyArrayItem(item) { + switch (typeof item) { + case 'number': + return item.toString(); + case 'string': + return `'${item}'`; + default: + return JSON.stringify(item); + } +} +function stringifyForShell(value) { + switch (typeof value) { + case 'string': + return value; + case 'object': + if (Array.isArray(value)) { + return value.map(stringifyArrayItem).join(' '); + } + if (value === null) { + return ''; + } + return value.toString(); + default: + return JSON.stringify(value); + } +} +exports.stringifyForShell = stringifyForShell; + + /***/ }), /***/ 2013: @@ -33659,7 +33716,7 @@ function run() { try { const pathPatterns = core.getInput(common_1.inputs.PATHS).split(';'); const token = core.getInput(common_1.inputs.GH_TOKEN, { required: true }); - const changedFiles = yield (0, common_1.getChangedFiles)(token); + const changedFiles = (yield (0, common_1.getChangedFiles)(token)).map(e => e.path); const filteredFiles = (0, common_1.filterPaths)(changedFiles, pathPatterns); core.setOutput(common_1.outputs.RESULT, filteredFiles.length > 0); } diff --git a/pr-filter/src/main.ts b/pr-filter/src/main.ts index ed82a12..1b68463 100644 --- a/pr-filter/src/main.ts +++ b/pr-filter/src/main.ts @@ -7,7 +7,7 @@ async function run(): Promise { const pathPatterns = core.getInput(inputs.PATHS).split(';'); const token = core.getInput(inputs.GH_TOKEN, { required: true }); - const changedFiles = await getChangedFiles(token); + const changedFiles = (await getChangedFiles(token)).map(e => e.path); const filteredFiles = filterPaths(changedFiles, pathPatterns); core.setOutput(outputs.RESULT, filteredFiles.length > 0); diff --git a/verify-version-change/dist/index.js b/verify-version-change/dist/index.js index 0da1e5a..bb18ed7 100644 --- a/verify-version-change/dist/index.js +++ b/verify-version-change/dist/index.js @@ -16,8 +16,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.execCommand = void 0; +exports.setOutputs = exports.execCommand = void 0; +const core_1 = __nccwpck_require__(5316); const exec_1 = __nccwpck_require__(110); +const serialization_utils_1 = __nccwpck_require__(9091); function execCommand(command) { return __awaiter(this, void 0, void 0, function* () { const { stdout, stderr, exitCode } = yield (0, exec_1.getExecOutput)(command); @@ -28,6 +30,12 @@ function execCommand(command) { }); } exports.execCommand = execCommand; +function setOutputs(values) { + for (const [key, value] of Object.entries(values)) { + (0, core_1.setOutput)(key, (0, serialization_utils_1.stringifyForShell)(value)); + } +} +exports.setOutputs = setOutputs; /***/ }), @@ -41,7 +49,6 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.outputs = exports.inputs = void 0; exports.inputs = { GH_TOKEN: 'gh-token', - OUTPUT: 'output', PATHS: 'paths', }; exports.outputs = { @@ -126,7 +133,7 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.filterPaths = void 0; +exports.testPath = exports.normalizePatterns = exports.filterPaths = void 0; const core = __importStar(__nccwpck_require__(5316)); const minimatch_1 = __nccwpck_require__(148); const NEGATION = '!'; @@ -144,14 +151,26 @@ function filterPaths(paths, patterns) { } exports.filterPaths = filterPaths; function filterPathsImpl(paths, patterns) { - return paths.filter(path => { - return patterns.reduce((prevResult, pattern) => { - return pattern.startsWith(NEGATION) - ? prevResult && !match(path, pattern.substring(1)) - : prevResult || match(path, pattern); - }, false); - }); + const normalizedPatterns = normalizePatterns(patterns); + return normalizedPatterns === undefined + ? paths + : paths.filter(path => testPath(path, normalizedPatterns)); +} +function normalizePatterns(patterns) { + if (!patterns) + return undefined; + const notEmptyPatterns = patterns.filter(p => p != undefined && p.length > 0); + return (notEmptyPatterns.length > 0 ? notEmptyPatterns : undefined); } +exports.normalizePatterns = normalizePatterns; +function testPath(path, patterns) { + return patterns.reduce((prevResult, pattern) => { + return pattern.startsWith(NEGATION) + ? prevResult && !match(path, pattern.substring(1)) + : prevResult || match(path, pattern); + }, false); +} +exports.testPath = testPath; /***/ }), @@ -249,12 +268,12 @@ function getChangedFilesImpl(token) { core.setFailed('Getting changed files only works on pull request events.'); return []; } - const files = yield octokit.paginate(octokit.rest.pulls.listFiles, { + const entries = yield octokit.paginate(octokit.rest.pulls.listFiles, { owner: github_1.context.repo.owner, repo: github_1.context.repo.repo, pull_number: github_1.context.payload.pull_request.number, }); - return files.map(file => file.filename); + return entries.map(({ filename, status }) => ({ path: filename, status })); } catch (error) { core.setFailed(`Getting changed files failed with error: ${error}`); @@ -264,6 +283,44 @@ function getChangedFilesImpl(token) { } +/***/ }), + +/***/ 9091: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.stringifyForShell = void 0; +function stringifyArrayItem(item) { + switch (typeof item) { + case 'number': + return item.toString(); + case 'string': + return `'${item}'`; + default: + return JSON.stringify(item); + } +} +function stringifyForShell(value) { + switch (typeof value) { + case 'string': + return value; + case 'object': + if (Array.isArray(value)) { + return value.map(stringifyArrayItem).join(' '); + } + if (value === null) { + return ''; + } + return value.toString(); + default: + return JSON.stringify(value); + } +} +exports.stringifyForShell = stringifyForShell; + + /***/ }), /***/ 2013: