From 7517d926d76434998977b21b7c1f487118e13c22 Mon Sep 17 00:00:00 2001 From: Joscha Feth Date: Tue, 12 Dec 2017 16:37:17 +1100 Subject: [PATCH 1/8] allow JSON output --- packages/percy-storybook/src/args.js | 4 ++++ packages/percy-storybook/src/cli.js | 11 ++++++----- packages/percy-storybook/src/uploadStorybook.js | 17 +++++++++++------ 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/packages/percy-storybook/src/args.js b/packages/percy-storybook/src/args.js index ff321c4b..86961d70 100644 --- a/packages/percy-storybook/src/args.js +++ b/packages/percy-storybook/src/args.js @@ -20,6 +20,10 @@ export const options = { description: 'Directory to load the static storybook built by build-storybook from', requiresArg: true, }, + json: { + description: 'Log the build parameters in JSON. Incompatible with --debug', + requiresArg: false, + }, rtl: { description: 'Runs stories a second time with a direction parameter set to rtl', requiresArg: false, diff --git a/packages/percy-storybook/src/cli.js b/packages/percy-storybook/src/cli.js index be0670ff..2bffc725 100644 --- a/packages/percy-storybook/src/cli.js +++ b/packages/percy-storybook/src/cli.js @@ -46,11 +46,12 @@ export async function run(argv) { const options = { debug: argv.debug, buildDir: argv.build_dir, + json: argv.json && !argv.debug, }; if (process.env.PERCY_ENABLE === '0') { // eslint-disable-next-line no-console - console.log('The PERCY_ENABLE environment variable is set to 0. Exiting.'); + console.log(options.json ? '{}' : 'The PERCY_ENABLE environment variable is set to 0. Exiting.'); return; } @@ -66,13 +67,13 @@ export async function run(argv) { // debug('assets %o', assets); const stories = await getStories(assets[storybookJavascriptPath], options); - debug('stories %o', stories); + options.debug && debug('stories %o', stories); const selectedStories = selectStories(stories, rtlRegex); - debug('selectedStories %o', selectedStories); + options.debug && debug('selectedStories %o', selectedStories); if (selectedStories.length === 0) { - console.log('WARNING: No stories were found.'); // eslint-disable-line no-console + console.log(options.json ? '{}' : 'WARNING: No stories were found.'); // eslint-disable-line no-console return; } @@ -83,5 +84,5 @@ export async function run(argv) { `storybook/${storybookVersion()} react/${reactVersion()}`, ); - return uploadStorybook(client, selectedStories, widths, minimumHeight, storyHtml, assets); + return uploadStorybook(client, selectedStories, widths, minimumHeight, storyHtml, assets, options.json); } diff --git a/packages/percy-storybook/src/uploadStorybook.js b/packages/percy-storybook/src/uploadStorybook.js index 6d13bc00..81b39bc7 100644 --- a/packages/percy-storybook/src/uploadStorybook.js +++ b/packages/percy-storybook/src/uploadStorybook.js @@ -7,10 +7,11 @@ export default async function uploadStorybook( minimumHeight, storyHtml, assets, + jsonOutput, ) { const snapshotPluralization = selectedStories.length === 1 ? 'snapshot' : 'snapshots'; // eslint-disable-next-line no-console - console.log('\nUploading', selectedStories.length, snapshotPluralization, 'to Percy.'); + !jsonOutput && console.log('\nUploading', selectedStories.length, snapshotPluralization, 'to Percy.'); const resources = client.makeResources(assets); const build = await client.createBuild(resources); @@ -19,9 +20,13 @@ export default async function uploadStorybook( await uploadStories(client, build, selectedStories, widths, minimumHeight, assets, storyHtml); await client.finalizeBuild(build); - // eslint-disable-next-line no-console - console.log( - 'Percy snapshots uploaded. Visual diffs are now processing:', - build.attributes['web-url'], - ); + if (jsonOutput) { + console.log(JSON.stringify(build.attributes)); + } else { + // eslint-disable-next-line no-console + console.log( + 'Percy snapshots uploaded. Visual diffs are now processing:', + build.attributes['web-url'], + ); + } } From 2b61d40c77a4a4b272480b947376216053100593 Mon Sep 17 00:00:00 2001 From: Joscha Feth Date: Tue, 12 Dec 2017 16:39:15 +1100 Subject: [PATCH 2/8] fix lints --- packages/percy-storybook/src/cli.js | 14 ++++++++++++-- packages/percy-storybook/src/uploadStorybook.js | 7 +++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/packages/percy-storybook/src/cli.js b/packages/percy-storybook/src/cli.js index 2bffc725..d9ec0435 100644 --- a/packages/percy-storybook/src/cli.js +++ b/packages/percy-storybook/src/cli.js @@ -51,7 +51,9 @@ export async function run(argv) { if (process.env.PERCY_ENABLE === '0') { // eslint-disable-next-line no-console - console.log(options.json ? '{}' : 'The PERCY_ENABLE environment variable is set to 0. Exiting.'); + console.log( + options.json ? '{}' : 'The PERCY_ENABLE environment variable is set to 0. Exiting.', + ); return; } @@ -84,5 +86,13 @@ export async function run(argv) { `storybook/${storybookVersion()} react/${reactVersion()}`, ); - return uploadStorybook(client, selectedStories, widths, minimumHeight, storyHtml, assets, options.json); + return uploadStorybook( + client, + selectedStories, + widths, + minimumHeight, + storyHtml, + assets, + options.json, + ); } diff --git a/packages/percy-storybook/src/uploadStorybook.js b/packages/percy-storybook/src/uploadStorybook.js index 81b39bc7..d7da3432 100644 --- a/packages/percy-storybook/src/uploadStorybook.js +++ b/packages/percy-storybook/src/uploadStorybook.js @@ -10,8 +10,10 @@ export default async function uploadStorybook( jsonOutput, ) { const snapshotPluralization = selectedStories.length === 1 ? 'snapshot' : 'snapshots'; - // eslint-disable-next-line no-console - !jsonOutput && console.log('\nUploading', selectedStories.length, snapshotPluralization, 'to Percy.'); + + !jsonOutput && + // eslint-disable-next-line no-console + console.log('\nUploading', selectedStories.length, snapshotPluralization, 'to Percy.'); const resources = client.makeResources(assets); const build = await client.createBuild(resources); @@ -21,6 +23,7 @@ export default async function uploadStorybook( await client.finalizeBuild(build); if (jsonOutput) { + // eslint-disable-next-line no-console console.log(JSON.stringify(build.attributes)); } else { // eslint-disable-next-line no-console From 835835abc87c4eb079f81930d542ef334f4103d5 Mon Sep 17 00:00:00 2001 From: Tim Haines Date: Wed, 13 Dec 2017 12:14:58 -0800 Subject: [PATCH 3/8] Rename json param to output_format. Parse and validate it. --- .../src/__tests__/getMinimumHeight-tests.js | 2 +- .../src/__tests__/getOutputFormat-tests.js | 16 ++++++++++ packages/percy-storybook/src/args.js | 8 ++--- packages/percy-storybook/src/cli.js | 29 +++++++++++++------ .../percy-storybook/src/getOutputFormat.js | 9 ++++++ .../percy-storybook/src/uploadStorybook.js | 9 +++--- 6 files changed, 55 insertions(+), 18 deletions(-) create mode 100644 packages/percy-storybook/src/__tests__/getOutputFormat-tests.js create mode 100644 packages/percy-storybook/src/getOutputFormat.js diff --git a/packages/percy-storybook/src/__tests__/getMinimumHeight-tests.js b/packages/percy-storybook/src/__tests__/getMinimumHeight-tests.js index 34602a6d..33eee277 100644 --- a/packages/percy-storybook/src/__tests__/getMinimumHeight-tests.js +++ b/packages/percy-storybook/src/__tests__/getMinimumHeight-tests.js @@ -1,6 +1,6 @@ import getMinimumHeight from '../getMinimumHeight'; -it('returns number when passed a number ', () => { +it('returns number when passed a number', () => { expect(getMinimumHeight(100)).toEqual(100); }); diff --git a/packages/percy-storybook/src/__tests__/getOutputFormat-tests.js b/packages/percy-storybook/src/__tests__/getOutputFormat-tests.js new file mode 100644 index 00000000..5551f6b4 --- /dev/null +++ b/packages/percy-storybook/src/__tests__/getOutputFormat-tests.js @@ -0,0 +1,16 @@ +import getOutputFormat from '../getOutputFormat'; + +it('returns text when passed text', () => { + expect(getOutputFormat('text')).toEqual('text'); +}); + +it('returns JSON when passed JSON', () => { + expect(getOutputFormat('JSON')).toEqual('JSON'); +}); + +it('raises an error if called with an invalid value', () => { + expect(() => getOutputFormat()).toThrow(); + expect(() => getOutputFormat('xml')).toThrow(); + expect(() => getOutputFormat(7)).toThrow(); + expect(() => getOutputFormat('')).toThrow(); +}); diff --git a/packages/percy-storybook/src/args.js b/packages/percy-storybook/src/args.js index 86961d70..2806329b 100644 --- a/packages/percy-storybook/src/args.js +++ b/packages/percy-storybook/src/args.js @@ -20,9 +20,9 @@ export const options = { description: 'Directory to load the static storybook built by build-storybook from', requiresArg: true, }, - json: { - description: 'Log the build parameters in JSON. Incompatible with --debug', - requiresArg: false, + output_format: { + description: 'Specify JSON to log the build parameters in JSON. Incompatible with --debug.', + requiresArg: true, }, rtl: { description: 'Runs stories a second time with a direction parameter set to rtl', @@ -34,4 +34,4 @@ export const options = { }, }; -export const usage = 'Usage: $0 --widths=320,1280 --debug'; +export const usage = 'Usage: $0 --widths=320,1280 --output_format=JSON'; diff --git a/packages/percy-storybook/src/cli.js b/packages/percy-storybook/src/cli.js index d9ec0435..a16b819d 100644 --- a/packages/percy-storybook/src/cli.js +++ b/packages/percy-storybook/src/cli.js @@ -4,6 +4,7 @@ import getStories from './getStories'; import getStaticAssets from './getStaticAssets'; import getWidths from './getWidths'; import getMinimumHeight from './getMinimumHeight'; +import getOutputFormat from '../getOutputFormat'; import getRtlRegex from './getRtlRegex'; import selectStories from './selectStories'; import uploadStorybook from './uploadStorybook'; @@ -27,6 +28,7 @@ export async function run(argv) { .options(args.options) .epilogue(args.docs) .default('build_dir', 'storybook-static') + .default('output_format', 'text') .default('minimum_height', '800').argv; if (argv.help) { @@ -46,14 +48,17 @@ export async function run(argv) { const options = { debug: argv.debug, buildDir: argv.build_dir, - json: argv.json && !argv.debug, + outputFormat: getOutputFormat(argv.output_format), }; if (process.env.PERCY_ENABLE === '0') { - // eslint-disable-next-line no-console - console.log( - options.json ? '{}' : 'The PERCY_ENABLE environment variable is set to 0. Exiting.', - ); + if (options.outputFormat == 'text') { + // eslint-disable-next-line no-console + console.log('The PERCY_ENABLE environment variable is set to 0. Exiting.'); + } else if (options.outputFormat == 'JSON') { + // eslint-disable-next-line no-console + console.log(`{'exitReason':'The PERCY_ENABLE environment variable is set to 0.'}`); + } return; } @@ -69,13 +74,19 @@ export async function run(argv) { // debug('assets %o', assets); const stories = await getStories(assets[storybookJavascriptPath], options); - options.debug && debug('stories %o', stories); + debug('stories %o', stories); const selectedStories = selectStories(stories, rtlRegex); - options.debug && debug('selectedStories %o', selectedStories); + debug('selectedStories %o', selectedStories); if (selectedStories.length === 0) { - console.log(options.json ? '{}' : 'WARNING: No stories were found.'); // eslint-disable-line no-console + if (options.outputFormat == 'text') { + // eslint-disable-next-line no-console + console.log('No stories were found.'); + } else if (options.outputFormat == 'JSON') { + // eslint-disable-next-line no-console + console.log(`{'exitReason':'No stories were found.'}`); + } return; } @@ -93,6 +104,6 @@ export async function run(argv) { minimumHeight, storyHtml, assets, - options.json, + options.outputFormat, ); } diff --git a/packages/percy-storybook/src/getOutputFormat.js b/packages/percy-storybook/src/getOutputFormat.js new file mode 100644 index 00000000..ee339c15 --- /dev/null +++ b/packages/percy-storybook/src/getOutputFormat.js @@ -0,0 +1,9 @@ +export default function getOutputFormat(outputFormatString) { + if (outputFormatString != 'text' && outputFormatString != 'JSON') { + throw new Error( + `Output format must be either 'text' or 'JSON'. Received: ${outputFormatString}`, + ); + } + + return outputFormatString; +} diff --git a/packages/percy-storybook/src/uploadStorybook.js b/packages/percy-storybook/src/uploadStorybook.js index d7da3432..adfed2e8 100644 --- a/packages/percy-storybook/src/uploadStorybook.js +++ b/packages/percy-storybook/src/uploadStorybook.js @@ -7,13 +7,14 @@ export default async function uploadStorybook( minimumHeight, storyHtml, assets, - jsonOutput, + outputFormat, ) { const snapshotPluralization = selectedStories.length === 1 ? 'snapshot' : 'snapshots'; - !jsonOutput && + if (outputFormat == 'text') { // eslint-disable-next-line no-console console.log('\nUploading', selectedStories.length, snapshotPluralization, 'to Percy.'); + } const resources = client.makeResources(assets); const build = await client.createBuild(resources); @@ -22,10 +23,10 @@ export default async function uploadStorybook( await uploadStories(client, build, selectedStories, widths, minimumHeight, assets, storyHtml); await client.finalizeBuild(build); - if (jsonOutput) { + if (outputFormat == 'JSON') { // eslint-disable-next-line no-console console.log(JSON.stringify(build.attributes)); - } else { + } else if (outputFormat == 'text') { // eslint-disable-next-line no-console console.log( 'Percy snapshots uploaded. Visual diffs are now processing:', From 4a4370e0d76ec3002bdca5d81f02eae18c429a12 Mon Sep 17 00:00:00 2001 From: Tim Haines Date: Wed, 13 Dec 2017 12:46:34 -0800 Subject: [PATCH 4/8] Adjust debugging --- packages/percy-storybook/src/args.js | 4 ++-- packages/percy-storybook/src/cli.js | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/percy-storybook/src/args.js b/packages/percy-storybook/src/args.js index 2806329b..77efef4c 100644 --- a/packages/percy-storybook/src/args.js +++ b/packages/percy-storybook/src/args.js @@ -21,7 +21,7 @@ export const options = { requiresArg: true, }, output_format: { - description: 'Specify JSON to log the build parameters in JSON. Incompatible with --debug.', + description: 'Specify JSON to log the build parameters in JSON. Note: --debug outputs non-JSON', requiresArg: true, }, rtl: { @@ -34,4 +34,4 @@ export const options = { }, }; -export const usage = 'Usage: $0 --widths=320,1280 --output_format=JSON'; +export const usage = 'Usage: $0 --widths=320,1280 --debug'; diff --git a/packages/percy-storybook/src/cli.js b/packages/percy-storybook/src/cli.js index a16b819d..0a05fcc9 100644 --- a/packages/percy-storybook/src/cli.js +++ b/packages/percy-storybook/src/cli.js @@ -4,7 +4,7 @@ import getStories from './getStories'; import getStaticAssets from './getStaticAssets'; import getWidths from './getWidths'; import getMinimumHeight from './getMinimumHeight'; -import getOutputFormat from '../getOutputFormat'; +import getOutputFormat from './getOutputFormat'; import getRtlRegex from './getRtlRegex'; import selectStories from './selectStories'; import uploadStorybook from './uploadStorybook'; @@ -74,10 +74,10 @@ export async function run(argv) { // debug('assets %o', assets); const stories = await getStories(assets[storybookJavascriptPath], options); - debug('stories %o', stories); + options.debug && debug('stories %o', stories); const selectedStories = selectStories(stories, rtlRegex); - debug('selectedStories %o', selectedStories); + options.debug && debug('selectedStories %o', selectedStories); if (selectedStories.length === 0) { if (options.outputFormat == 'text') { From d2a9b055cc51a574015ae91fbd62107ba8b2e6dd Mon Sep 17 00:00:00 2001 From: Tim Haines Date: Wed, 13 Dec 2017 12:53:07 -0800 Subject: [PATCH 5/8] Fix stripping buildDir if it's prefixed with ./ --- packages/percy-storybook/src/getStaticAssets.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/percy-storybook/src/getStaticAssets.js b/packages/percy-storybook/src/getStaticAssets.js index 34b0f9d0..7ba8c480 100644 --- a/packages/percy-storybook/src/getStaticAssets.js +++ b/packages/percy-storybook/src/getStaticAssets.js @@ -33,7 +33,12 @@ function gatherBuildResources(buildDir) { resourceUrl = resourceUrl.replace(/\\/g, '/'); } - resourceUrl = resourceUrl.replace(buildDir, ''); + // Strip the buildDir from the start of the resourceUrl + if (buildDir.startsWith('./')) { + resourceUrl = resourceUrl.replace(buildDir.substr(2), ''); + } else { + resourceUrl = resourceUrl.replace(buildDir, ''); + } // Remove the leading / if (resourceUrl.charAt(0) === '/') { From 4db303d0587668362f5114a07f487d569fd62aad Mon Sep 17 00:00:00 2001 From: Tim Haines Date: Wed, 13 Dec 2017 13:02:54 -0800 Subject: [PATCH 6/8] Handle output_format flag of JSON or json --- .../src/__tests__/getOutputFormat-tests.js | 6 ++++-- packages/percy-storybook/src/cli.js | 4 ++-- packages/percy-storybook/src/getOutputFormat.js | 8 +++++--- packages/percy-storybook/src/uploadStorybook.js | 2 +- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/percy-storybook/src/__tests__/getOutputFormat-tests.js b/packages/percy-storybook/src/__tests__/getOutputFormat-tests.js index 5551f6b4..966dcf26 100644 --- a/packages/percy-storybook/src/__tests__/getOutputFormat-tests.js +++ b/packages/percy-storybook/src/__tests__/getOutputFormat-tests.js @@ -1,11 +1,13 @@ import getOutputFormat from '../getOutputFormat'; it('returns text when passed text', () => { + expect(getOutputFormat('TEXT')).toEqual('text'); expect(getOutputFormat('text')).toEqual('text'); }); -it('returns JSON when passed JSON', () => { - expect(getOutputFormat('JSON')).toEqual('JSON'); +it('returns json when passed JSON', () => { + expect(getOutputFormat('JSON')).toEqual('json'); + expect(getOutputFormat('json')).toEqual('json'); }); it('raises an error if called with an invalid value', () => { diff --git a/packages/percy-storybook/src/cli.js b/packages/percy-storybook/src/cli.js index 0a05fcc9..2fb958aa 100644 --- a/packages/percy-storybook/src/cli.js +++ b/packages/percy-storybook/src/cli.js @@ -55,7 +55,7 @@ export async function run(argv) { if (options.outputFormat == 'text') { // eslint-disable-next-line no-console console.log('The PERCY_ENABLE environment variable is set to 0. Exiting.'); - } else if (options.outputFormat == 'JSON') { + } else if (options.outputFormat == 'json') { // eslint-disable-next-line no-console console.log(`{'exitReason':'The PERCY_ENABLE environment variable is set to 0.'}`); } @@ -83,7 +83,7 @@ export async function run(argv) { if (options.outputFormat == 'text') { // eslint-disable-next-line no-console console.log('No stories were found.'); - } else if (options.outputFormat == 'JSON') { + } else if (options.outputFormat == 'json') { // eslint-disable-next-line no-console console.log(`{'exitReason':'No stories were found.'}`); } diff --git a/packages/percy-storybook/src/getOutputFormat.js b/packages/percy-storybook/src/getOutputFormat.js index ee339c15..1700a48c 100644 --- a/packages/percy-storybook/src/getOutputFormat.js +++ b/packages/percy-storybook/src/getOutputFormat.js @@ -1,9 +1,11 @@ export default function getOutputFormat(outputFormatString) { - if (outputFormatString != 'text' && outputFormatString != 'JSON') { + const outputFormatLowerCaseString = outputFormatString.toLowerCase(); + + if (outputFormatLowerCaseString != 'text' && outputFormatLowerCaseString != 'json') { throw new Error( - `Output format must be either 'text' or 'JSON'. Received: ${outputFormatString}`, + `Output format must be either 'text' or 'json'. Received: ${outputFormatString}`, ); } - return outputFormatString; + return outputFormatLowerCaseString; } diff --git a/packages/percy-storybook/src/uploadStorybook.js b/packages/percy-storybook/src/uploadStorybook.js index adfed2e8..6df90100 100644 --- a/packages/percy-storybook/src/uploadStorybook.js +++ b/packages/percy-storybook/src/uploadStorybook.js @@ -23,7 +23,7 @@ export default async function uploadStorybook( await uploadStories(client, build, selectedStories, widths, minimumHeight, assets, storyHtml); await client.finalizeBuild(build); - if (outputFormat == 'JSON') { + if (outputFormat == 'json') { // eslint-disable-next-line no-console console.log(JSON.stringify(build.attributes)); } else if (outputFormat == 'text') { From b0a96e4bd955bb19a0299be1cad08677ae3654e6 Mon Sep 17 00:00:00 2001 From: Tim Haines Date: Wed, 13 Dec 2017 13:39:03 -0800 Subject: [PATCH 7/8] Rename variable from outputFormatLowerCaseString to normalizedOutputFormat --- packages/percy-storybook/src/getOutputFormat.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/percy-storybook/src/getOutputFormat.js b/packages/percy-storybook/src/getOutputFormat.js index 1700a48c..aff50bf9 100644 --- a/packages/percy-storybook/src/getOutputFormat.js +++ b/packages/percy-storybook/src/getOutputFormat.js @@ -1,11 +1,11 @@ export default function getOutputFormat(outputFormatString) { - const outputFormatLowerCaseString = outputFormatString.toLowerCase(); + const normalizedOutputFormat = outputFormatString.toLowerCase(); - if (outputFormatLowerCaseString != 'text' && outputFormatLowerCaseString != 'json') { + if (normalizedOutputFormat != 'text' && normalizedOutputFormat != 'json') { throw new Error( `Output format must be either 'text' or 'json'. Received: ${outputFormatString}`, ); } - return outputFormatLowerCaseString; + return normalizedOutputFormat; } From 7838d1b2148f0a4cba0ac9a185ff2cde6aeff68b Mon Sep 17 00:00:00 2001 From: Tim Haines Date: Wed, 13 Dec 2017 13:55:15 -0800 Subject: [PATCH 8/8] Improve debug toggling --- packages/percy-storybook/src/cli.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/percy-storybook/src/cli.js b/packages/percy-storybook/src/cli.js index 2fb958aa..817683f4 100644 --- a/packages/percy-storybook/src/cli.js +++ b/packages/percy-storybook/src/cli.js @@ -46,11 +46,15 @@ export async function run(argv) { const rtlRegex = getRtlRegex(argv.rtl, argv.rtl_regex); const options = { - debug: argv.debug, + // Configure debug logging if flag specified, or if it was already enabled via DEBUG env var + debug: argv.debug || debug.enabled, buildDir: argv.build_dir, outputFormat: getOutputFormat(argv.output_format), }; + // Enable debug logging based on options. + debug.enabled = options.debug; + if (process.env.PERCY_ENABLE === '0') { if (options.outputFormat == 'text') { // eslint-disable-next-line no-console @@ -74,10 +78,10 @@ export async function run(argv) { // debug('assets %o', assets); const stories = await getStories(assets[storybookJavascriptPath], options); - options.debug && debug('stories %o', stories); + debug('stories %o', stories); const selectedStories = selectStories(stories, rtlRegex); - options.debug && debug('selectedStories %o', selectedStories); + debug('selectedStories %o', selectedStories); if (selectedStories.length === 0) { if (options.outputFormat == 'text') {