From b0ffcf6388ef85793ac756514eb48df78a7287c7 Mon Sep 17 00:00:00 2001 From: Michael Kriese Date: Tue, 2 Jun 2020 17:36:32 +0200 Subject: [PATCH 1/2] chore: testing --- src/runner.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/runner.ts b/src/runner.ts index eff16ee6d..25c1254ce 100644 --- a/src/runner.ts +++ b/src/runner.ts @@ -18,6 +18,7 @@ export default async function run(): Promise { break; default: + log(chalk.yellow('args:'), chalk.grey(...process.argv)); log.error(chalk.red('Unknown command:'), cmd); break; } From e83daef62e21a9a51ebbee6b954d97c0fc7f0342 Mon Sep 17 00:00:00 2001 From: Michael Kriese Date: Wed, 3 Jun 2020 12:05:57 +0200 Subject: [PATCH 2/2] feat: local builder --- package.json | 8 ++- src/commands/docker/builder.ts | 13 ++--- src/runner.ts | 8 ++- src/util.ts | 63 +---------------------- src/utils/cli.ts | 74 ++++++++++++++++++++++++++++ src/utils/docker/buildx.ts | 10 +++- src/utils/env.ts | 8 +++ src/utils/fs.ts | 41 +++++++++++++++ test/commands/docker/builder.spec.ts | 44 +++++++++-------- test/util.spec.ts | 36 ++------------ test/utils/cli.spec.ts | 35 +++++++++++++ test/utils/env.spec.ts | 17 +++++++ test/utils/fs.spec.ts | 46 +++++++++++++++++ yarn.lock | 31 +++++++++++- 14 files changed, 309 insertions(+), 125 deletions(-) create mode 100644 src/utils/cli.ts create mode 100644 src/utils/env.ts create mode 100644 src/utils/fs.ts create mode 100644 test/utils/cli.spec.ts create mode 100644 test/utils/env.spec.ts create mode 100644 test/utils/fs.spec.ts diff --git a/package.json b/package.json index 5c1b973cb..202c05840 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "author": "Rhys Arkins ", "main": "dist/index.js", "engines": { - "node": " >=12.0.0", + "node": ">=12.0.0", "yarn": ">=1.22.0" }, "scripts": { @@ -26,17 +26,21 @@ "@actions/io": "1.0.2", "@sindresorhus/is": "3.1.2", "chalk": "4.1.0", + "commander": "5.1.0", "delay": "4.4.0", "find-up": "5.0.0", "got": "11.7.0", + "js-yaml": "3.14.0", "renovate": "23.39.0", "semver": "7.3.2", "strip-ansi": "6.0.0", - "www-authenticate": "0.6.2" + "www-authenticate": "0.6.2", + "yawn-yaml": "1.5.0" }, "devDependencies": { "@jest/globals": "26.4.2", "@types/jest": "26.0.14", + "@types/js-yaml": "3.12.4", "@types/node": "12.12.62", "@types/semver": "7.3.4", "@typescript-eslint/eslint-plugin": "4.3.0", diff --git a/src/commands/docker/builder.ts b/src/commands/docker/builder.ts index b16449cdb..faa477c4b 100644 --- a/src/commands/docker/builder.ts +++ b/src/commands/docker/builder.ts @@ -1,12 +1,13 @@ -import { getInput } from '@actions/core'; import is from '@sindresorhus/is'; import chalk from 'chalk'; import { ReleaseResult, getPkgReleases } from 'renovate/dist/datasource'; import { get as getVersioning } from 'renovate/dist/versioning'; -import { exec, getArg, isDryRun, readFile, readJson } from '../../util'; +import { exec, isDryRun } from '../../util'; +import { getArg } from '../../utils/cli'; import { build, publish } from '../../utils/docker'; import { init } from '../../utils/docker/buildx'; import { dockerDf, dockerPrune, dockerTag } from '../../utils/docker/common'; +import { readFile, readJson } from '../../utils/fs'; import log from '../../utils/logger'; import * as renovate from '../../utils/renovate'; @@ -291,7 +292,7 @@ async function readDockerConfig(cfg: ConfigFile): Promise { export async function run(): Promise { const dryRun = isDryRun(); - const configFile = getInput('config') || 'builder.json'; + const configFile = getArg('config') || 'builder.json'; const cfg = await readJson(configFile); @@ -301,7 +302,7 @@ export async function run(): Promise { // TODO: validation if (!is.string(cfg.image)) { - cfg.image = getInput('image', { required: true }); + cfg.image = getArg('image', { required: true }); } if (!is.string(cfg.buildArg)) { @@ -319,8 +320,8 @@ export async function run(): Promise { tagSuffix: getArg('tag-suffix') || undefined, ignoredVersions: cfg.ignoredVersions ?? [], dryRun, - lastOnly: getInput('last-only') == 'true', - buildOnly: getInput('build-only') == 'true', + lastOnly: getArg('last-only') == 'true', + buildOnly: getArg('build-only') == 'true', majorMinor: getArg('major-minor') !== 'false', prune: getArg('prune') === 'true', }; diff --git a/src/runner.ts b/src/runner.ts index 25c1254ce..dd65bc584 100644 --- a/src/runner.ts +++ b/src/runner.ts @@ -1,12 +1,16 @@ -import { getInput, setFailed } from '@actions/core'; +import { setFailed } from '@actions/core'; import chalk from 'chalk'; import { Commands } from './types'; +import { getArg, initCli, isCli } from './utils/cli'; import log from './utils/logger'; export default async function run(): Promise { try { log.info(chalk.blue('Renovate Docker Builder')); - const cmd = getInput('command') as Commands; + if (isCli()) { + await initCli(); + } + const cmd = getArg('command') as Commands; log.info(chalk.yellow('Executing:'), ` ${cmd}`); switch (cmd) { case Commands.DockerBuilder: diff --git a/src/util.ts b/src/util.ts index 1a6daf849..f6517d431 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,9 +1,7 @@ -import { promises as fs } from 'fs'; -import { join } from 'path'; import { endGroup, getInput, startGroup } from '@actions/core'; import { exec as _exec } from '@actions/exec'; import { ExecOptions as _ExecOptions } from '@actions/exec/lib/interfaces'; -import findUp = require('find-up'); +import { getEnv } from './utils/env'; import { ExecError, ExecResult } from './utils/types'; export type ExecOptions = _ExecOptions; @@ -41,15 +39,6 @@ export async function exec( return { code, stdout, stderr }; } -/** - * Get environment variable or empty string. - * Used for easy mocking. - * @param key variable name - */ -export function getEnv(key: string): string { - return process.env[key] ?? ''; -} - export function isCI(): boolean { return !!getEnv('CI'); } @@ -62,53 +51,3 @@ export function isDryRun(): boolean { export function getWorkspace(): string { return getEnv('GITHUB_WORKSPACE') || process.cwd(); } - -export async function readJson(file: string): Promise { - const path = join(getWorkspace(), file); - const res = (await import(path)) as T | { default: T }; - // istanbul ignore next - return 'default' in res ? res?.default : res; -} - -export async function readFile(file: string): Promise { - const path = join(getWorkspace(), file); - return await fs.readFile(path, 'utf8'); -} - -export const MultiArgsSplitRe = /\s*(?:[;,]|$)\s*/; - -export function getArg(name: string, opts?: { required?: boolean }): string; -export function getArg( - name: string, - opts?: { required?: boolean; multi: true } -): string[]; -export function getArg( - name: string, - opts?: { required?: boolean; multi?: boolean } -): string | string[]; -export function getArg( - name: string, - opts?: { required?: boolean; multi?: boolean } -): string | string[] { - const val = getInput(name, opts); - return opts?.multi ? val.split(MultiArgsSplitRe).filter(Boolean) : val; -} - -let _pkg: Promise; - -/** - * Resolve path for a file relative to renovate root directory (our package.json) - * @param file a file to resolve - */ -export async function resolveFile(file: string): Promise { - // eslint-disable-next-line @typescript-eslint/no-misused-promises - if (!_pkg) { - _pkg = findUp('package.json', { cwd: __dirname, type: 'file' }); - } - const pkg = await _pkg; - // istanbul ignore if - if (!pkg) { - throw new Error('Missing package.json'); - } - return join(pkg, '../', file); -} diff --git a/src/utils/cli.ts b/src/utils/cli.ts new file mode 100644 index 000000000..214c62137 --- /dev/null +++ b/src/utils/cli.ts @@ -0,0 +1,74 @@ +import { getInput as cli } from '@actions/core'; +import { Command } from 'commander'; +import { getEnv } from './env'; +import { readLocalYaml } from './fs'; + +export function isCli(): boolean { + return getEnv('GITHUB_ACTIONS') !== 'true'; +} + +export function getArgv(): string[] { + return process.argv; +} + +type Action = { + inputs: Record< + string, + { description: string; required: boolean; default: string } + >; +}; + +let _opts: Record = {}; + +async function parse(): Promise> { + const program = new Command() + .storeOptionsAsProperties(false) + .passCommandToAction(false) + .arguments(' [image]'); + + const action = await readLocalYaml('action.yml'); + + for (const name of Object.keys(action.inputs).filter( + (n) => !['command', 'image'].includes(n) + )) { + const val = action.inputs[name]; + + if (val.required === true) { + program.requiredOption(`--${name} `, val.description, val.default); + } else { + program.option(`--${name} `, val.description, val.default); + } + } + + return program.parse(getArgv()).opts(); +} + +export async function initCli(): Promise { + _opts = await parse(); +} + +export function getCliArg(name: string, required?: boolean): string { + if (!_opts[name] && required) { + throw Error(`Missing required argument ${name}`); + } + return _opts[name]; +} + +export const MultiArgsSplitRe = /\s*(?:[;,]|$)\s*/; + +export function getArg(name: string, opts?: { required?: boolean }): string; +export function getArg( + name: string, + opts?: { required?: boolean; multi: true } +): string[]; +export function getArg( + name: string, + opts?: { required?: boolean; multi?: boolean } +): string | string[]; +export function getArg( + name: string, + opts?: { required?: boolean; multi?: boolean } +): string | string[] { + const val = isCli() ? getCliArg(name, opts?.required) : cli(name, opts); + return opts?.multi ? val.split(MultiArgsSplitRe).filter(Boolean) : val; +} diff --git a/src/utils/docker/buildx.ts b/src/utils/docker/buildx.ts index 4c3a9c70d..676c9364c 100644 --- a/src/utils/docker/buildx.ts +++ b/src/utils/docker/buildx.ts @@ -1,6 +1,8 @@ import { existsSync } from 'fs'; +import { platform } from 'os'; import { join } from 'path'; -import { exec, resolveFile } from '../../util'; +import { exec } from '../../util'; +import { resolveFile } from '../fs'; import log from '../logger'; import { docker, dockerBuildx, dockerRun } from './common'; @@ -10,6 +12,12 @@ export async function init(): Promise { `.docker/cli-plugins/docker-buildx` ); + // istanbul ignore if + if (platform() !== 'linux') { + log.warn('Buildx support only on linux'); + return; + } + // istanbul ignore if if (existsSync(buildx)) { log('Buildx already initialized'); diff --git a/src/utils/env.ts b/src/utils/env.ts new file mode 100644 index 000000000..ff4ef7fe7 --- /dev/null +++ b/src/utils/env.ts @@ -0,0 +1,8 @@ +/** + * Get environment variable or empty string. + * Used for easy mocking. + * @param key variable name + */ +export function getEnv(key: string): string { + return process.env[key] ?? ''; +} diff --git a/src/utils/fs.ts b/src/utils/fs.ts new file mode 100644 index 000000000..70001efaf --- /dev/null +++ b/src/utils/fs.ts @@ -0,0 +1,41 @@ +import findUp = require('find-up'); +import { promises as fs } from 'fs'; +import { safeLoad } from 'js-yaml'; +import { join } from 'upath'; + +let _pkg: Promise; + +/** + * Resolve path for a file relative to renovate root directory (our package.json) + * @param file a file to resolve + */ +export async function resolveFile(file: string): Promise { + // eslint-disable-next-line @typescript-eslint/no-misused-promises + if (!_pkg) { + _pkg = findUp('package.json', { cwd: __dirname, type: 'file' }); + } + const pkg = await _pkg; + // istanbul ignore if + if (!pkg) { + throw new Error('Missing package.json'); + } + return join(pkg, '../', file); +} + +export async function readJson(file: string): Promise { + const path = join(process.cwd(), file); + const res = (await import(path)) as T | { default: T }; + // istanbul ignore next + return 'default' in res ? res?.default : res; +} + +export async function readFile(file: string): Promise { + const path = join(process.cwd(), file); + return await fs.readFile(path, 'utf8'); +} + +export async function readLocalYaml(file: string): Promise { + const path = await resolveFile(file); + const res = await fs.readFile(path, 'utf-8'); + return safeLoad(res, { json: true }) as T; +} diff --git a/test/commands/docker/builder.spec.ts b/test/commands/docker/builder.spec.ts index 6c6aef945..49afcfa6d 100644 --- a/test/commands/docker/builder.spec.ts +++ b/test/commands/docker/builder.spec.ts @@ -3,7 +3,9 @@ import * as _core from '@actions/core'; import * as _datasources from 'renovate/dist/datasource'; import { run } from '../../../src/commands/docker/builder'; import * as _utils from '../../../src/util'; +import * as _cli from '../../../src/utils/cli'; import * as _docker from '../../../src/utils/docker'; +import * as _fs from '../../../src/utils/fs'; import { getName, mocked } from '../../utils'; jest.mock('renovate/dist/datasource'); @@ -17,6 +19,8 @@ jest.mock('../../../src/utils/renovate'); const core = mocked(_core); const utils = mocked(_utils); const docker = mocked(_docker); +const fs = mocked(_fs); +const cli = mocked(_cli); const datasources = mocked(_datasources); const version = '1.22.4'; @@ -25,12 +29,12 @@ describe(getName(__filename), () => { jest.resetAllMocks(); core.getInput.mockReturnValueOnce('builder.json'); core.getInput.mockReturnValueOnce('yarn'); - utils.readJson.mockResolvedValueOnce(require('./__fixtures__/yarn.json')); - utils.getArg.mockImplementation((_, o) => (o?.multi ? [] : '')); + fs.readJson.mockResolvedValueOnce(require('./__fixtures__/yarn.json')); + cli.getArg.mockImplementation((_, o) => (o?.multi ? [] : '')); }); it('works yarn', async () => { - utils.readFile.mockResolvedValue( + fs.readFile.mockResolvedValue( `# renovate: datasource=npm depName=yarn versioning=npm\nARG YARN_VERSION=${version}\n` ); datasources.getPkgReleases.mockResolvedValueOnce({ @@ -44,10 +48,10 @@ describe(getName(__filename), () => { }); it('works pnpm', async () => { - utils.readJson.mockReset(); - utils.readJson.mockResolvedValueOnce(require('./__fixtures__/pnpm.json')); - utils.getArg.mockReturnValueOnce(['IMAGE=slim']); - utils.getArg.mockReturnValueOnce('slim'); + fs.readJson.mockReset(); + fs.readJson.mockResolvedValueOnce(require('./__fixtures__/pnpm.json')); + cli.getArg.mockReturnValueOnce(['IMAGE=slim']); + cli.getArg.mockReturnValueOnce('slim'); datasources.getPkgReleases.mockResolvedValueOnce({ releases: [{ version: '4.0.0-rc.24' }, { version: '5.0.0' }], }); @@ -59,8 +63,8 @@ describe(getName(__filename), () => { }); it('works gradle', async () => { - utils.readJson.mockReset(); - utils.readJson.mockResolvedValueOnce(require('./__fixtures__/gradle.json')); + fs.readJson.mockReset(); + fs.readJson.mockResolvedValueOnce(require('./__fixtures__/gradle.json')); datasources.getPkgReleases.mockResolvedValueOnce({ releases: [ { version: '0.7' }, @@ -79,7 +83,7 @@ describe(getName(__filename), () => { it('works dummy', async () => { jest.resetAllMocks(); - utils.readJson.mockResolvedValueOnce(require('./__fixtures__/dummy.json')); + fs.readJson.mockResolvedValueOnce(require('./__fixtures__/dummy.json')); await run(); @@ -88,15 +92,15 @@ describe(getName(__filename), () => { }); it('last-only dummy', async () => { - utils.readJson.mockReset(); - utils.readJson.mockResolvedValueOnce(require('./__fixtures__/dummy.json')); + fs.readJson.mockReset(); + fs.readJson.mockResolvedValueOnce(require('./__fixtures__/dummy.json')); core.getInput.mockReset(); core.getInput.mockReturnValueOnce('builder.json'); core.getInput.mockReturnValueOnce('true'); - utils.getArg.mockReturnValueOnce(['IMAGE=slim']); - utils.getArg.mockReturnValueOnce('slim'); - utils.getArg.mockReturnValueOnce('false'); - utils.getArg.mockReturnValueOnce('true'); + cli.getArg.mockReturnValueOnce(['IMAGE=slim']); + cli.getArg.mockReturnValueOnce('slim'); + cli.getArg.mockReturnValueOnce('false'); + cli.getArg.mockReturnValueOnce('true'); await run(); @@ -146,8 +150,8 @@ describe(getName(__filename), () => { }); it('unstable releases', async () => { - utils.readJson.mockReset(); - utils.readJson.mockResolvedValueOnce({ + fs.readJson.mockReset(); + fs.readJson.mockResolvedValueOnce({ ...require('./__fixtures__/pnpm.json'), ignoredVersions: ['3.5.4'], }); @@ -176,7 +180,7 @@ describe(getName(__filename), () => { it('throws missing-image', async () => { expect.assertions(1); jest.resetAllMocks(); - utils.readJson.mockResolvedValueOnce({}); + fs.readJson.mockResolvedValueOnce({}); core.getInput.mockReturnValueOnce(''); core.getInput.mockImplementationOnce(() => { throw new Error('missing-image'); @@ -190,7 +194,7 @@ describe(getName(__filename), () => { it('throws missing-config', async () => { expect.assertions(1); jest.resetAllMocks(); - utils.readJson.mockResolvedValueOnce(undefined); + fs.readJson.mockResolvedValueOnce(undefined); try { await run(); diff --git a/test/util.spec.ts b/test/util.spec.ts index db06705df..3e20c9c7e 100644 --- a/test/util.spec.ts +++ b/test/util.spec.ts @@ -2,6 +2,7 @@ import { existsSync } from 'fs'; import * as _core from '@actions/core'; import * as _exec from '@actions/exec'; import * as util from '../src/util'; +import * as fs from '../src/utils/fs'; import { getName, mocked } from './utils'; jest.mock('@actions/core'); @@ -56,13 +57,6 @@ describe(getName(__filename), () => { }); }); - describe('getEnv', () => { - it('works', () => { - expect(util.getEnv('NOT_FOUND_ENV_VAR')).toBe(''); - expect(util.getEnv('PATH')).toBeDefined(); - }); - }); - describe('getWorkspace', () => { let ws: string | undefined; beforeEach(() => { @@ -85,7 +79,7 @@ describe(getName(__filename), () => { }); it('works', async () => { process.env.GITHUB_WORKSPACE = process.cwd(); - expect(await util.readJson('.prettierrc.json')).toEqual({ + expect(await fs.readJson('.prettierrc.json')).toEqual({ singleQuote: true, trailingComma: 'es5', }); @@ -98,37 +92,17 @@ describe(getName(__filename), () => { }); it('works', async () => { process.env.GITHUB_WORKSPACE = process.cwd(); - expect(await util.readFile('Dockerfile')).toMatchSnapshot(); - }); - }); - - describe('getArg', () => { - it('single', () => { - core.getInput.mockReturnValueOnce('test;latest;slim'); - expect(util.getArg('dockerfile')).toBe('test;latest;slim'); - }); - - it('multi', () => { - core.getInput.mockReturnValueOnce('test;latest;slim'); - expect(util.getArg('dockerfile', { multi: true })).toEqual([ - 'test', - 'latest', - 'slim', - ]); - }); - - it('multi (null)', () => { - expect(util.getArg('dockerfile', { multi: true })).toEqual([]); + expect(await fs.readFile('Dockerfile')).toMatchSnapshot(); }); }); describe('resolveFile', () => { it('works', async () => { - const file = await util.resolveFile('bin/configure-docker.sh'); + const file = await fs.resolveFile('bin/configure-docker.sh'); expect(file).toBeDefined(); expect(existsSync(file)).toBe(true); - const file2 = await util.resolveFile('bin/dummy.sh'); + const file2 = await fs.resolveFile('bin/dummy.sh'); expect(file2).toBeDefined(); expect(existsSync(file2)).toBe(false); }); diff --git a/test/utils/cli.spec.ts b/test/utils/cli.spec.ts new file mode 100644 index 000000000..ab7153578 --- /dev/null +++ b/test/utils/cli.spec.ts @@ -0,0 +1,35 @@ +import * as _core from '@actions/core'; +import * as cli from '../../src/utils/cli'; +import { getName, mocked } from '../utils'; + +jest.mock('@actions/core'); +jest.mock('@actions/exec'); +jest.mock('../src/utils/logger'); + +const core = mocked(_core); + +describe(getName(__filename), () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('getArg', () => { + it('single', () => { + core.getInput.mockReturnValueOnce('test;latest;slim'); + expect(cli.getArg('dockerfile')).toBe('test;latest;slim'); + }); + + it('multi', () => { + core.getInput.mockReturnValueOnce('test;latest;slim'); + expect(cli.getArg('dockerfile', { multi: true })).toEqual([ + 'test', + 'latest', + 'slim', + ]); + }); + + it('multi (null)', () => { + expect(cli.getArg('dockerfile', { multi: true })).toEqual([]); + }); + }); +}); diff --git a/test/utils/env.spec.ts b/test/utils/env.spec.ts new file mode 100644 index 000000000..cdce3c4f1 --- /dev/null +++ b/test/utils/env.spec.ts @@ -0,0 +1,17 @@ +import { getEnv } from '../../src/utils/env'; +import { getName } from '../utils'; + +jest.mock('../src/utils/logger'); + +describe(getName(__filename), () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('getEnv', () => { + it('works', () => { + expect(getEnv('NOT_FOUND_ENV_VAR')).toBe(''); + expect(getEnv('PATH')).toBeDefined(); + }); + }); +}); diff --git a/test/utils/fs.spec.ts b/test/utils/fs.spec.ts new file mode 100644 index 000000000..61a603641 --- /dev/null +++ b/test/utils/fs.spec.ts @@ -0,0 +1,46 @@ +import { existsSync } from 'fs'; +import * as fs from '../../src/utils/fs'; +import { getName } from '../utils'; + +jest.mock('../src/utils/logger'); + +describe(getName(__filename), () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('readJson', () => { + afterEach(() => { + delete process.env.GITHUB_WORKSPACE; + }); + it('works', async () => { + process.env.GITHUB_WORKSPACE = process.cwd(); + expect(await fs.readJson('.prettierrc.json')).toEqual({ + singleQuote: true, + trailingComma: 'es5', + }); + }); + }); + + describe('readFile', () => { + afterEach(() => { + delete process.env.GITHUB_WORKSPACE; + }); + it('works', async () => { + process.env.GITHUB_WORKSPACE = process.cwd(); + expect(await fs.readFile('Dockerfile')).toMatchSnapshot(); + }); + }); + + describe('resolveFile', () => { + it('works', async () => { + const file = await fs.resolveFile('bin/configure-docker.sh'); + expect(file).toBeDefined(); + expect(existsSync(file)).toBe(true); + + const file2 = await fs.resolveFile('bin/dummy.sh'); + expect(file2).toBeDefined(); + expect(existsSync(file2)).toBe(false); + }); + }); +}); diff --git a/yarn.lock b/yarn.lock index 8855d2683..fe19c6a07 100644 --- a/yarn.lock +++ b/yarn.lock @@ -818,6 +818,11 @@ jest-diff "^25.2.1" pretty-format "^25.2.1" +"@types/js-yaml@3.12.4": + version "3.12.4" + resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-3.12.4.tgz#7d3b534ec35a0585128e2d332db1403ebe057e25" + integrity sha512-fYMgzN+9e28R81weVN49inn/u798ruU91En1ZnGvSZzCRc5jXx9B2EDhlRaWmcO1RIxFHL8AajRXzxDuJu93+A== + "@types/json-schema@^7.0.3": version "7.0.4" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339" @@ -1858,6 +1863,11 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" +commander@5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" + integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== + commander@6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/commander/-/commander-6.1.0.tgz#f8d722b78103141006b66f4c7ba1e97315ba75bc" @@ -4016,7 +4026,7 @@ js-tokens@^4.0.0: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@3.14.0, js-yaml@^3.10.0: +js-yaml@3.14.0, js-yaml@^3.10.0, js-yaml@^3.4.2: version "3.14.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== @@ -4369,6 +4379,11 @@ lodash.toarray@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561" integrity sha1-JMS/zWsvuji/0FlNsRedjptlZWE= +lodash@^4.17.11: + version "4.17.20" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" + integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== + lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" @@ -7327,6 +7342,11 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== +yaml-js@^0.1.3: + version "0.1.5" + resolved "https://registry.yarnpkg.com/yaml-js/-/yaml-js-0.1.5.tgz#a01369010b3558d8aaed2394615dfd0780fd8fac" + integrity sha1-oBNpAQs1WNiq7SOUYV39B4D9j6w= + yaml@^1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.0.tgz#3b593add944876077d4d683fee01081bd9fff31e" @@ -7368,3 +7388,12 @@ yargs@^15.3.1: which-module "^2.0.0" y18n "^4.0.0" yargs-parser "^18.1.1" + +yawn-yaml@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/yawn-yaml/-/yawn-yaml-1.5.0.tgz#95fba7544d5375fce3dc84514f12218ed0d2ebcb" + integrity sha512-sH2zX9K1QiWhWh9U19pye660qlzrEAd5c4ebw/6lqz17LZw7xYi7nqXlBoVLVtc2FZFXDKiJIsvVcKGYbLVyFQ== + dependencies: + js-yaml "^3.4.2" + lodash "^4.17.11" + yaml-js "^0.1.3"