From a2b1a0001ae792c8c510942400350166c0ed8be0 Mon Sep 17 00:00:00 2001 From: Austin McGee <947888+amcgee@users.noreply.github.com> Date: Wed, 16 Oct 2019 11:18:12 +0200 Subject: [PATCH] fix: detect an occupied port and find an open one (#122) * fix: detect an occupied port and find an open one * docs: update start docs --- cli/package.json | 1 + cli/src/commands/start.js | 35 +++++++++++++++++++++++++++++------ cli/src/lib/shell/env.js | 9 ++------- docs/scripts/start.md | 1 + examples/simple-app/yarn.lock | 2 +- yarn.lock | 15 ++++++++++++++- 6 files changed, 48 insertions(+), 15 deletions(-) diff --git a/cli/package.json b/cli/package.json index 08eddfd13..0ce911239 100644 --- a/cli/package.json +++ b/cli/package.json @@ -30,6 +30,7 @@ "babel-jest": "^24.9.0", "chalk": "^2.4.2", "classnames": "^2.2.6", + "detect-port": "^1.3.0", "dotenv": "^8.1.0", "dotenv-expand": "^5.1.0", "fs-extra": "^8.1.0", diff --git a/cli/src/commands/start.js b/cli/src/commands/start.js index 586101758..07dbb5fed 100644 --- a/cli/src/commands/start.js +++ b/cli/src/commands/start.js @@ -1,5 +1,6 @@ const { reporter } = require('@dhis2/cli-helpers-engine') const chalk = require('chalk') +const detectPort = require('detect-port') const i18n = require('../lib/i18n') const compile = require('../lib/compile') @@ -8,9 +9,15 @@ const makeShell = require('../lib/shell') const parseConfig = require('../lib/parseConfig') const exitOnCatch = require('../lib/exitOnCatch') const loadEnvFiles = require('../lib/loadEnvFiles') -const { getShellPort } = require('../lib/shell/env') -const handler = async ({ cwd, force, shell: shellSource }) => { +const defaultPort = 3000 + +const handler = async ({ + cwd, + force, + port = process.env.PORT || defaultPort, + shell: shellSource, +}) => { const paths = makePaths(cwd) const mode = 'development' @@ -49,15 +56,24 @@ const handler = async ({ cwd, force, shell: shellSource }) => { watch: true, }) - reporter.print(chalk.dim('\n---\n')) + const newPort = await detectPort(port) + if (newPort !== port) { + reporter.print('') + reporter.warn( + `Something is already running on port ${port}, using ${newPort} instead.` + ) + } + + reporter.print('') reporter.info('Starting development server...') reporter.print( `The app ${chalk.bold( config.name - )} is now available on port ${getShellPort()}` + )} is now available on port ${newPort}` ) - reporter.print(chalk.dim('\n---\n')) - await shell.start() + reporter.print('') + + await shell.start({ port: newPort }) }, { name: 'start', @@ -72,6 +88,13 @@ const command = { aliases: 's', desc: 'Start a development server running a DHIS2 app within the DHIS2 app-shell', + builder: { + port: { + alias: 'p', + type: 'number', + description: 'The port to use when running the development server', + }, + }, handler, } diff --git a/cli/src/lib/shell/env.js b/cli/src/lib/shell/env.js index 6d0eeb82d..75e96ad73 100644 --- a/cli/src/lib/shell/env.js +++ b/cli/src/lib/shell/env.js @@ -1,8 +1,5 @@ const { reporter } = require('@dhis2/cli-helpers-engine') -const defaultShellPort = 3000 -const getShellPort = () => process.env.PORT || defaultShellPort - const filterEnv = () => Object.keys(process.env) .filter(key => key.indexOf('DHIS2_') === 0) @@ -32,18 +29,16 @@ const makeShellEnv = vars => {} ) -module.exports = vars => { +module.exports = ({ port, ...vars }) => { const env = { ...prefixEnvForCRA({ ...filterEnv(), ...makeShellEnv(vars), }), - PORT: getShellPort(), + PORT: port, PUBLIC_URL: process.env.PUBLIC_URL, } reporter.debug('Env passed to app-shell:', env) return env } -module.exports.defaultShellPort = defaultShellPort -module.exports.getShellPort = getShellPort diff --git a/docs/scripts/start.md b/docs/scripts/start.md index 3fb1665c8..b1b72d459 100644 --- a/docs/scripts/start.md +++ b/docs/scripts/start.md @@ -14,5 +14,6 @@ Options: --cwd working directory to use (defaults to cwd) --version Show version number [boolean] --config Path to JSON config file + --port, -p The port to use when running the development server [number] -h, --help Show help [boolean] ``` diff --git a/examples/simple-app/yarn.lock b/examples/simple-app/yarn.lock index 42e762fbc..f964dbec1 100644 --- a/examples/simple-app/yarn.lock +++ b/examples/simple-app/yarn.lock @@ -927,7 +927,7 @@ integrity sha512-rt2PZYZHwOq7qkkyczLYBgfReaENwauxx8iaTimTwdJrAXRUPkbhjlor63/00XgAY95tsZL7nMK7x3TwiSUfpQ== "@dhis2/cli-app-scripts@file:../../cli": - version "1.5.1" + version "1.5.3" dependencies: "@babel/core" "^7.6.2" "@babel/plugin-proposal-class-properties" "^7.4.4" diff --git a/yarn.lock b/yarn.lock index b8ce81987..0373d799a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1404,6 +1404,11 @@ acorn@^7.0.0, acorn@^7.1.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.0.tgz#949d36f2c292535da602283586c2477c57eb2d6c" integrity sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ== +address@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" + integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== + aggregate-error@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.0.0.tgz#5b5a3c95e9095f311c9ab16c19fb4f3527cd3f79" @@ -2799,7 +2804,7 @@ date-fns@^2.0.1: resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.4.1.tgz#b53f9bb65ae6bd9239437035710e01cf383b625e" integrity sha512-2RhmH/sjDSCYW2F3ZQxOUx/I7PvzXpi89aQL2d3OAxSTwLx6NilATeUbe0menFE3Lu5lFkOFci36ivimwYHHxw== -debug@2.6.9, debug@^2.2.0, debug@^2.3.3: +debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -2950,6 +2955,14 @@ detect-newline@^2.1.0: resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= +detect-port@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.3.0.tgz#d9c40e9accadd4df5cac6a782aefd014d573d1f1" + integrity sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ== + dependencies: + address "^1.0.1" + debug "^2.6.0" + diff-sequences@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5"