From fbea30c879e0f92067b4baf35b47c7d760698994 Mon Sep 17 00:00:00 2001 From: Oliver Byford Date: Tue, 26 May 2020 13:46:54 +0100 Subject: [PATCH 1/8] Update node-sass to v4.14.1 v4.12.0 does not support Node v14: > Error: Node Sass does not yet support your current environment: OS X 64-bit with Unsupported runtime (83) > For more information on which environments are supported please see: > https://github.com/sass/node-sass/releases/tag/v4.13.1 > at module.exports (/Users/oliverbyford/Code/govuk-prototype-kit/node_modules/node-sass/lib/binding.js:13:13) > at Object. (/Users/oliverbyford/Code/govuk-prototype-kit/node_modules/node-sass/lib/index.js:14:35) > at Module._compile (internal/modules/cjs/loader.js:1200:30) > at Object.Module._extensions..js (internal/modules/cjs/loader.js:1220:10) > at Module.load (internal/modules/cjs/loader.js:1049:32) > at Function.Module._load (internal/modules/cjs/loader.js:937:14) > at Module.require (internal/modules/cjs/loader.js:1089:19) > at require (internal/modules/cjs/helpers.js:73:18) > at Object. (/Users/oliverbyford/Code/govuk-prototype-kit/node_modules/gulp-sass/index.js:162:21) > at Module._compile (internal/modules/cjs/loader.js:1200:30) > gulp exited with code 1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7ceb80d782..99335f389c 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "devDependencies": { "glob": "^7.1.4", "jest": "^25.2.7", - "node-sass": "^4.12.0", + "node-sass": "^4.14.1", "standard": "^14.3.3", "supertest": "^4.0.2" } From 3595a276d78394b3d1f9fdc6a6fedc8736ed049a Mon Sep 17 00:00:00 2001 From: Oliver Byford Date: Tue, 26 May 2020 14:17:57 +0100 Subject: [PATCH 2/8] Update findAvailablePort to use inquirer Prompt's dependency winston is causing a warning in the console: > (node:15613) Warning: Accessing non-existent property 'padLevels' of module exports inside circular dependency This has been raised as an issue on prompt's GitHub repo [1] but given the last release of prompt was 4 years ago, I think it makes sense to move away to an alternative that's actively maintained. [1]: https://github.com/flatiron/prompt/issues/199 --- lib/utils.js | 23 +++++++---------------- package.json | 1 + 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/lib/utils.js b/lib/utils.js index faf6819927..63494814ff 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -6,7 +6,7 @@ const getKeypath = require('keypather/get') const marked = require('marked') const path = require('path') const portScanner = require('portscanner') -const prompt = require('prompt') +const inquirer = require('inquirer') const request = require('sync-request') // Local dependencies @@ -86,23 +86,14 @@ exports.findAvailablePort = function (app, callback) { } else { // Port in use - offer to change to available port console.error('ERROR: Port ' + port + ' in use - you may have another prototype running.\n') - // Set up prompt settings - prompt.colors = false - prompt.start() - prompt.message = '' - prompt.delimiter = '' // Ask user if they want to change port - prompt.get([{ - name: 'answer', - description: 'Change to an available port? (y/n)', - required: true, - type: 'string', - pattern: /y(es)?|no?/i, - message: 'Please enter y or n' - }], function (err, result) { - if (err) { throw err } - if (result.answer.match(/y(es)?/i)) { + inquirer.prompt([{ + name: 'changePort', + message: 'Change to an available port?', + type: 'confirm' + }]).then(answers => { + if (answers.changePort) { // User answers yes port = availablePort fs.writeFileSync(path.join(__dirname, '/../.port.tmp'), port) diff --git a/package.json b/package.json index 99335f389c..7692d73051 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "gulp-nodemon": "^2.5.0", "gulp-sass": "^4.0.1", "gulp-sourcemaps": "^2.6.0", + "inquirer": "^7.1.0", "keypather": "^3.0.0", "marked": "^0.8.2", "notifications-node-client": "^4.7.2", From 14267407ef2fbf77041d0f5b1c265fe5441c5e55 Mon Sep 17 00:00:00 2001 From: Oliver Byford Date: Tue, 26 May 2020 14:20:01 +0100 Subject: [PATCH 3/8] Convert port number to string when writing to file This fixes a type error that's being thrown by Object.writeFileSync in Node v14: > UnhandledPromiseRejectionWarning: TypeError [ERR_INVALID_ARG_TYPE]: The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received type number (3001) > at Object.writeFileSync (fs.js:1380:5) > at /Users/oliverbyford/Code/govuk-prototype-kit/lib/utils.js:99:14 > at processTicksAndRejections (internal/process/task_queues.js:97:5) --- lib/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/utils.js b/lib/utils.js index 63494814ff..c038a1c3b6 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -96,7 +96,7 @@ exports.findAvailablePort = function (app, callback) { if (answers.changePort) { // User answers yes port = availablePort - fs.writeFileSync(path.join(__dirname, '/../.port.tmp'), port) + fs.writeFileSync(path.join(__dirname, '/../.port.tmp'), port.toString()) console.log('Changed to port ' + port) callback(port) From f69d62bfdf9ad09cc2155c8190839313491bd7dc Mon Sep 17 00:00:00 2001 From: Oliver Byford Date: Tue, 26 May 2020 15:25:28 +0100 Subject: [PATCH 4/8] Update askForUsageDataPermission to use inquirer Prompt's dependency winston is causing a warning in the console: > (node:15613) Warning: Accessing non-existent property 'padLevels' of module exports inside circular dependency This has been raised as an issue on prompt's GitHub repo [1] but given the last release of prompt was 4 years ago, I think it makes sense to move away to an alternative that's actively maintained. [1]: https://github.com/flatiron/prompt/issues/199 --- lib/usage-data-prompt.txt | 2 +- lib/usage_data.js | 37 +++++++++---------------------------- start.js | 15 ++++++--------- 3 files changed, 16 insertions(+), 38 deletions(-) diff --git a/lib/usage-data-prompt.txt b/lib/usage-data-prompt.txt index f30221456d..e3e6b92374 100644 --- a/lib/usage-data-prompt.txt +++ b/lib/usage-data-prompt.txt @@ -6,4 +6,4 @@ With your permission, the kit can send useful anonymous usage data for analysis to help the team improve the service. Read more here: https://govuk-prototype-kit.herokuapp.com/docs/usage-data -Do you give permission for the kit to send anonymous usage data? (y/n) +Do you give permission for the kit to send anonymous usage data? diff --git a/lib/usage_data.js b/lib/usage_data.js index 8f8ca61169..d93ed2f44e 100644 --- a/lib/usage_data.js +++ b/lib/usage_data.js @@ -4,7 +4,7 @@ const fs = require('fs') const os = require('os') // NPM dependencies -const prompt = require('prompt') +const inquirer = require('inquirer') const universalAnalytics = require('universal-analytics') const uuidv4 = require('uuid/v4') @@ -37,34 +37,15 @@ exports.setUsageDataConfig = function (usageDataConfig) { // returns a Promise with the user's answer exports.askForUsageDataPermission = function () { return new Promise(function (resolve, reject) { - // Set up prompt settings - prompt.colors = false - prompt.start() - prompt.message = '' - prompt.delimiter = '' + const description = fs.readFileSync(path.join(__dirname, 'usage-data-prompt.txt'), 'utf8').trim() - const description = fs.readFileSync(path.join(__dirname, 'usage-data-prompt.txt'), 'utf8') - - prompt.get([{ - name: 'answer', - description: description, - required: true, - type: 'string', - pattern: /y(es)?|no?/i, - message: 'Please enter y or n', - ask: function () { - return process.stdout.isTTY - } - }], function (err, result) { - if (err) { - reject(err) - } - if (result.answer.match(/y(es)?/i)) { - resolve('yes') - } else { - resolve('no') - } - }) + inquirer.prompt([{ + name: 'usageData', + message: description, + type: 'confirm', + when: () => process.stdout.isTTY, + default: false + }]).then(answers => resolve(answers.usageData)) }) } diff --git a/start.js b/start.js index 074a906b9e..3ea89565a8 100644 --- a/start.js +++ b/start.js @@ -13,17 +13,14 @@ const usageDataConfig = usageData.getUsageDataConfig() if (usageDataConfig.collectUsageData === undefined) { // No recorded answer, so ask for permission const promptPromise = usageData.askForUsageDataPermission() - promptPromise.then(function (answer) { - if (answer === 'yes') { - usageDataConfig.collectUsageData = true - usageData.setUsageDataConfig(usageDataConfig) + promptPromise.then(function (permissionGranted) { + usageDataConfig.collectUsageData = permissionGranted + usageData.setUsageDataConfig(usageDataConfig) + + if (permissionGranted) { usageData.startTracking(usageDataConfig) - } else if (answer === 'no') { - usageDataConfig.collectUsageData = false - usageData.setUsageDataConfig(usageDataConfig) - } else { - console.error(answer) } + runGulp() }) } else if (usageDataConfig.collectUsageData === true) { From 74d0b5b73c11e6b22f461644934a5b8ec75af154 Mon Sep 17 00:00:00 2001 From: Oliver Byford Date: Tue, 26 May 2020 15:29:25 +0100 Subject: [PATCH 5/8] Avoid deep include of UUID > DeprecationWarning: Deep requiring like `const uuidv4 = require('uuid/v4');` is deprecated as of uuid@7.x. Please require the top-level module when using the Node.js CommonJS module or use ECMAScript Modules when bundling for the browser. See https://github.com/uuidjs/uuid#deep-requires-now-deprecated for more information. --- lib/usage_data.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/usage_data.js b/lib/usage_data.js index d93ed2f44e..f4f1cb89a2 100644 --- a/lib/usage_data.js +++ b/lib/usage_data.js @@ -6,7 +6,7 @@ const os = require('os') // NPM dependencies const inquirer = require('inquirer') const universalAnalytics = require('universal-analytics') -const uuidv4 = require('uuid/v4') +const { v4: uuidv4 } = require('uuid') // Local dependencies const packageJson = require('../package.json') From b93bf6c7c2e2253837896f875924e11c7691f134 Mon Sep 17 00:00:00 2001 From: Oliver Byford Date: Tue, 26 May 2020 15:56:35 +0100 Subject: [PATCH 6/8] Test on Node v14 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Node v14 will become the active LTS release in October 2020, at which point we should recommend that users start installing it. (v12 will remain supported under LTS until 30 April 2022) Until then, some users may only be able to install v14 as the current/latest version – for example, if a department provides Node through a managed software centre – so we should make sure it works with it. --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index df895b16e2..29d36699a6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,7 @@ language: node_js node_js: - "lts/dubnium" - "lts/erbium" + - 14 os: - linux From 6e533378b026af39744d2f9f98f947f3e020a077 Mon Sep 17 00:00:00 2001 From: Oliver Byford Date: Tue, 26 May 2020 16:00:16 +0100 Subject: [PATCH 7/8] Remove dependency on prompt Both places that used prompt have been updated to use inquirer instead, so prompt can now be removed. --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 7692d73051..3320fcd52e 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,6 @@ "notifications-node-client": "^4.7.2", "nunjucks": "^3.2.1", "portscanner": "^2.1.1", - "prompt": "^1.0.0", "require-dir": "^1.0.0", "sync-request": "^6.0.0", "universal-analytics": "^0.4.16", From d00733d8ccde1a79c2bd24caf0a5e8ec7725a609 Mon Sep 17 00:00:00 2001 From: Oliver Byford Date: Wed, 27 May 2020 09:05:31 +0100 Subject: [PATCH 8/8] Document in changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e3799f88e..06530b81d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Unreleased +- [Pull request #901: Add support for Node v14](https://github.com/alphagov/govuk-prototype-kit/pull/901) + # 9.6.1 (Patch release) - [Pull request #884: Bump nunjucks from v3.1.3 to v3.2.1](https://github.com/alphagov/govuk-prototype-kit/pull/884)