From e991ef65a8fed5189dcc4d2172d56c6f1d25bade Mon Sep 17 00:00:00 2001 From: Jon Ursenbach Date: Fri, 1 Apr 2022 09:38:28 -0700 Subject: [PATCH] feat: throwing error messaging on node 12 being unsupported (#486) * feat: throwing error messaging on node 12 being unsupported * revert: adding some optional chaining back in * fix: removing optional chaining from the bin file * fix: pr feedback * fix: fixes --- .github/workflows/ci.yml | 20 +++++++++++++++++ __tests__/bin.test.js | 31 ++++++++++++++++++++++++++ __tests__/lib/getNodeVersion.test.js | 11 --------- __tests__/lib/nodeVersionUtils.test.js | 24 ++++++++++++++++++++ bin/rdme | 22 +++++++++++++----- src/lib/getNodeVersion.js | 15 ------------- src/lib/nodeVersionUtils.js | 21 +++++++++++++++++ 7 files changed, 113 insertions(+), 31 deletions(-) create mode 100644 __tests__/bin.test.js delete mode 100644 __tests__/lib/getNodeVersion.test.js create mode 100644 __tests__/lib/nodeVersionUtils.test.js delete mode 100644 src/lib/getNodeVersion.js create mode 100644 src/lib/nodeVersionUtils.js diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5bcd7f4d4..9ab49cd3d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,6 +24,26 @@ jobs: - name: Run tests run: npm test + build-node12: + name: Test Suite (Node 12) + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Use Node.js 12 + uses: actions/setup-node@v3 + with: + node-version: 12 + + - name: Install deps + run: npm ci + + # rdme doesn't work on Node 12 but we just want to run this single test to make sure that + # our "we don't support node 12" error is shown. + - name: Run tests + run: npx jest __tests__/bin.test.js + action: name: GitHub Action Dry Run runs-on: ubuntu-latest diff --git a/__tests__/bin.test.js b/__tests__/bin.test.js new file mode 100644 index 000000000..a9a6b31e2 --- /dev/null +++ b/__tests__/bin.test.js @@ -0,0 +1,31 @@ +const { exec } = require('child_process'); +const { isSupportedNodeVersion } = require('../src/lib/nodeVersionUtils'); +const pkg = require('../package.json'); + +describe('bin', () => { + if (isSupportedNodeVersion(process.version)) { + it('should show our help screen', async () => { + expect.assertions(1); + + await new Promise(done => { + exec(`node ${__dirname}/../bin/rdme`, (error, stdout) => { + expect(stdout).toContain('a utlity for interacting with ReadMe'); + done(); + }); + }); + }); + } else { + it('should fail with a message', async () => { + expect.assertions(1); + + await new Promise(done => { + exec(`node ${__dirname}/../bin/rdme`, (error, stdout, stderr) => { + expect(stderr).toContain( + `We're sorry, this release of rdme does not support Node.js v${process.version}. We support the following versions: ${pkg.engines.node}` + ); + done(); + }); + }); + }); + } +}); diff --git a/__tests__/lib/getNodeVersion.test.js b/__tests__/lib/getNodeVersion.test.js deleted file mode 100644 index 2fc7c60d0..000000000 --- a/__tests__/lib/getNodeVersion.test.js +++ /dev/null @@ -1,11 +0,0 @@ -const getNodeVersion = require('../../src/lib/getNodeVersion'); -const pkg = require('../../package.json'); -const semver = require('semver'); - -describe('#getNodeVersion()', () => { - it('should extract version that matches range in package.json', () => { - const version = parseInt(getNodeVersion(), 10); - const cleanedVersion = semver.valid(semver.coerce(version)); - expect(semver.satisfies(cleanedVersion, pkg.engines.node)).toBe(true); - }); -}); diff --git a/__tests__/lib/nodeVersionUtils.test.js b/__tests__/lib/nodeVersionUtils.test.js new file mode 100644 index 000000000..abc9c1e84 --- /dev/null +++ b/__tests__/lib/nodeVersionUtils.test.js @@ -0,0 +1,24 @@ +const { isSupportedNodeVersion, getNodeVersion } = require('../../src/lib/nodeVersionUtils'); +const pkg = require('../../package.json'); +const semver = require('semver'); + +describe('#isSupportedNodeVersion()', () => { + it('should return true for a supported version of node', () => { + expect(isSupportedNodeVersion('14.5.1')).toBe(true); + expect(isSupportedNodeVersion('16.0.0')).toBe(true); + }); + + it('should return false for an unsupported version of node', () => { + expect(isSupportedNodeVersion('10.0.0')).toBe(false); + expect(isSupportedNodeVersion('12.0.0')).toBe(false); + expect(isSupportedNodeVersion('18.0.0')).toBe(false); + }); +}); + +describe('#getNodeVersion()', () => { + it('should extract version that matches range in package.json', () => { + const version = parseInt(getNodeVersion(), 10); + const cleanedVersion = semver.valid(semver.coerce(version)); + expect(semver.satisfies(cleanedVersion, pkg.engines.node)).toBe(true); + }); +}); diff --git a/bin/rdme b/bin/rdme index 274ca3db3..d870fdcb9 100755 --- a/bin/rdme +++ b/bin/rdme @@ -1,4 +1,5 @@ #! /usr/bin/env node +/* eslint-disable no-console */ const chalk = require('chalk'); const core = require('@actions/core'); @@ -6,12 +7,23 @@ const updateNotifier = require('update-notifier'); const pkg = require('../package.json'); const isGHA = require('../src/lib/isGitHub'); +const { isSupportedNodeVersion } = require('../src/lib/nodeVersionUtils'); updateNotifier({ pkg }).notify(); +/** + * We use optional chaining throughout the library, which doesn't work on Node 12, so to curb + * support questions about why rdme is throwing an "Unexpected token '.'" error we should hard + * stop if we're being run with any Node version that we don't explicitly support. + */ +if (!isSupportedNodeVersion(process.version)) { + const message = `We're sorry, this release of rdme does not support Node.js v${process.version}. We support the following versions: ${pkg.engines.node}`; + console.error(chalk.red(`\n${message}\n`)); + process.exit(1); +} + require('../src')(process.argv.slice(2)) .then(msg => { - // eslint-disable-next-line no-console if (msg) console.log(msg); return process.exit(0); }) @@ -20,20 +32,20 @@ require('../src')(process.argv.slice(2)) 'support@readme.io' )}.`; - if (err?.message) { + if (err.message) { message = err.message; } /** * If we're in a GitHub Actions environment, log errors with that formatting instead. - * @link: https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-error-message - * @link: https://github.com/actions/toolkit/tree/main/packages/core#annotations + * + * @see {@link https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-error-message} + * @see {@link https://github.com/actions/toolkit/tree/main/packages/core#annotations} */ if (isGHA()) { return core.setFailed(message); } - // eslint-disable-next-line no-console console.error(chalk.red(`\n${message}\n`)); return process.exit(1); }); diff --git a/src/lib/getNodeVersion.js b/src/lib/getNodeVersion.js deleted file mode 100644 index 0fde1279d..000000000 --- a/src/lib/getNodeVersion.js +++ /dev/null @@ -1,15 +0,0 @@ -const pkg = require('../../package.json'); - -/** - * @example 14 - * @returns {String} The maximum major Node.js version specified in the package.json - */ -function extractNodeVersion() { - const { node } = pkg.engines; - - const match = Array.from(node.matchAll(/\d+/g)).pop(); - - return match; -} - -module.exports = extractNodeVersion; diff --git a/src/lib/nodeVersionUtils.js b/src/lib/nodeVersionUtils.js new file mode 100644 index 000000000..33b9b3bc3 --- /dev/null +++ b/src/lib/nodeVersionUtils.js @@ -0,0 +1,21 @@ +const semver = require('semver'); +const pkg = require('../../package.json'); + +module.exports = { + /** + * Determine if the current version of Node is one that we explicitly support. + * + */ + isSupportedNodeVersion(version) { + return semver.satisfies(semver.coerce(version), pkg.engines.node); + }, + + /** + * @example 14 + * @returns {String} The maximum major Node.js version specified in the package.json + */ + getNodeVersion() { + const { node } = pkg.engines; + return Array.from(node.matchAll(/\d+/g)).pop(); + }, +};