diff --git a/bin/main.js b/bin/main.js index 6df70ced3..26caf5ba8 100755 --- a/bin/main.js +++ b/bin/main.js @@ -16,7 +16,9 @@ import { rewriteErrorMessage } from './lib/utils'; import getTasks from './tasks'; import fatalError from './ui/messages/errors/fatalError'; import fetchError from './ui/messages/errors/fetchError'; +import invalidPackageJson from './ui/messages/errors/invalidPackageJson'; import missingStories from './ui/messages/errors/missingStories'; +import noPackageJson from './ui/messages/errors/noPackageJson'; import runtimeError from './ui/messages/errors/runtimeError'; import taskError from './ui/messages/errors/taskError'; import intro from './ui/messages/info/intro'; @@ -25,8 +27,18 @@ export async function main(argv) { const sessionId = uuid(); const env = getEnv(); const log = createLogger(sessionId, env); + const packagePath = await pkgUp(); // the user's own package.json + if (!packagePath) { + log.error(noPackageJson()); + process.exit(253); + } + const packageJson = await readFile(packagePath); + if (typeof packageJson !== 'object' || typeof packageJson.scripts !== 'object') { + log.error(invalidPackageJson(packagePath)); + process.exit(252); + } // Warning: chromaui/action directly invokes runAll, so if new properties or arguments are added // here, they must also be added to the GitHub Action. diff --git a/bin/main.test.js b/bin/main.test.js index 332e42196..2f652aa0f 100644 --- a/bin/main.test.js +++ b/bin/main.test.js @@ -160,7 +160,7 @@ beforeEach(() => { CHROMATIC_PROJECT_TOKEN: undefined, }; execa.mockReset(); - execa.mockReturnValue({ stdout: '1.2.3' }); + execa.mockReturnValue(Promise.resolve({ stdout: '1.2.3' })); }); afterEach(() => { process.env = processEnv; diff --git a/bin/tasks/build.test.js b/bin/tasks/build.test.js index 32219f235..c0a680efa 100644 --- a/bin/tasks/build.test.js +++ b/bin/tasks/build.test.js @@ -35,7 +35,7 @@ describe('setSpawnParams', () => { beforeEach(() => { process.env.npm_execpath = npmExecPath; - execa.mockReturnValue({ stdout: '1.2.3' }); + execa.mockReturnValue(Promise.resolve({ stdout: '1.2.3' })); }); it('sets the spawn params on the context', async () => { @@ -50,6 +50,7 @@ describe('setSpawnParams', () => { expect(ctx.spawnParams).toEqual({ client: 'npm', clientVersion: '1.2.3', + nodeVersion: '1.2.3', platform: expect.stringMatching(/darwin|linux|win32/), command: 'npm', clientArgs: ['run', '--silent'], @@ -61,10 +62,6 @@ describe('setSpawnParams', () => { '--webpack-stats-json', './source-dir/', ], - spawnOptions: { - preferLocal: true, - localDir: expect.stringMatching(/node_modules[/\\]\.bin$/), - }, }); }); @@ -80,14 +77,11 @@ describe('setSpawnParams', () => { expect(ctx.spawnParams).toEqual({ client: 'yarn', clientVersion: '1.2.3', + nodeVersion: '1.2.3', platform: expect.stringMatching(/darwin|linux|win32/), command: expect.stringMatching(/node/), clientArgs: ['/path/to/yarn.js', 'run'], scriptArgs: ['build:storybook', '--output-dir', './source-dir/'], - spawnOptions: { - preferLocal: true, - localDir: expect.stringMatching(/node_modules[/\\]\.bin$/), - }, }); }); diff --git a/bin/ui/messages/errors/invalidPackageJson.js b/bin/ui/messages/errors/invalidPackageJson.js new file mode 100644 index 000000000..b7b29bf48 --- /dev/null +++ b/bin/ui/messages/errors/invalidPackageJson.js @@ -0,0 +1,11 @@ +import chalk from 'chalk'; +import dedent from 'ts-dedent'; + +import { error } from '../../components/icons'; + +export default (packagePath) => + dedent(chalk` + ${error} {bold Invalid package.json} + Found invalid package.json at {bold ${packagePath}} + Make sure this is a valid Node.js package file, is readable, and contains a {bold "scripts"} block. + `); diff --git a/bin/ui/messages/errors/invalidPackageJson.stories.js b/bin/ui/messages/errors/invalidPackageJson.stories.js new file mode 100644 index 000000000..1a92022ea --- /dev/null +++ b/bin/ui/messages/errors/invalidPackageJson.stories.js @@ -0,0 +1,7 @@ +import invalidPackageJson from './invalidPackageJson'; + +export default { + title: 'CLI/Messages/Errors', +}; + +export const InvalidPackageJson = () => invalidPackageJson('/path/to/package.json'); diff --git a/bin/ui/messages/errors/noPackageJson.js b/bin/ui/messages/errors/noPackageJson.js new file mode 100644 index 000000000..9a5414983 --- /dev/null +++ b/bin/ui/messages/errors/noPackageJson.js @@ -0,0 +1,12 @@ +import chalk from 'chalk'; +import dedent from 'ts-dedent'; + +import { error } from '../../components/icons'; + +export default () => + dedent(chalk` + ${error} {bold No package.json found} + Chromatic only works from inside a JavaScript project. + We expected to find a package.json somewhere up the directory tree. + Are you sure you're running from your project directory? + `); diff --git a/bin/ui/messages/errors/noPackageJson.stories.js b/bin/ui/messages/errors/noPackageJson.stories.js new file mode 100644 index 000000000..7d0347fa9 --- /dev/null +++ b/bin/ui/messages/errors/noPackageJson.stories.js @@ -0,0 +1,7 @@ +import noPackageJson from './noPackageJson'; + +export default { + title: 'CLI/Messages/Errors', +}; + +export const NoPackageJson = () => noPackageJson();