From 3653634ddd1f2d679204604fa0053aad0bbfce2d Mon Sep 17 00:00:00 2001 From: AWolf81 Date: Tue, 9 Oct 2018 23:24:34 +0200 Subject: [PATCH 01/12] add process logger service --- package.json | 3 +- src/config/app.js | 2 + src/sagas/task.saga.js | 7 ++ src/services/dependencies.service.js | 3 +- src/services/process-logger.service.js | 25 +++++++ yarn.lock | 98 ++++++++++++++++++++++++-- 6 files changed, 132 insertions(+), 6 deletions(-) create mode 100644 src/services/process-logger.service.js diff --git a/package.json b/package.json index 313672e3..9a8830c1 100644 --- a/package.json +++ b/package.json @@ -145,7 +145,8 @@ "webpack": "3.10.0", "webpack-dev-server": "2.11.0", "webpack-manifest-plugin": "1.3.2", - "whatwg-fetch": "2.0.3" + "whatwg-fetch": "2.0.3", + "winston": "^3.1.0" }, "browserslist": { "development": [ diff --git a/src/config/app.js b/src/config/app.js index b1721229..b4975212 100644 --- a/src/config/app.js +++ b/src/config/app.js @@ -1,4 +1,6 @@ // app-wide settings (no user changable settings here) module.exports = { PACKAGE_MANAGER: 'yarn', + // Enable logging, if enabled all terminal responses are visible in the console (useful for debugging) + LOGGING: true, }; diff --git a/src/sagas/task.saga.js b/src/sagas/task.saga.js index 354f29e0..3226f258 100644 --- a/src/sagas/task.saga.js +++ b/src/sagas/task.saga.js @@ -25,6 +25,7 @@ import { getBaseProjectEnvironment, PACKAGE_MANAGER_CMD, } from '../services/platform.service'; +import { processLogger } from '../services/process-logger.service'; import type { Action } from 'redux'; import type { Saga } from 'redux-saga'; @@ -57,6 +58,8 @@ export function* launchDevServer({ task }: Action): Saga { } ); + processLogger(child, 'DEVSERVER'); + // Now that we have a port/processId for the server, attach it to // the task. The port is used for opening the app, the pid is used // to kill the process @@ -181,6 +184,8 @@ export function* taskRun({ task }: Action): Saga { } ); + processLogger(child, 'TASK'); + // TODO: Does the renderer process still need to know about the child // processId? yield put(attachTaskMetadata(task, child.pid)); @@ -249,6 +254,8 @@ export function* taskRun({ task }: Action): Saga { } ); + processLogger(installProcess, 'EJECT_INSTALL'); + // `waitForChildProcessToComplete` waits for proper exit before moving on // otherwise the next tasks (UI related) run too early before `yarn install` // is finished diff --git a/src/services/dependencies.service.js b/src/services/dependencies.service.js index 383b2083..90cd357c 100644 --- a/src/services/dependencies.service.js +++ b/src/services/dependencies.service.js @@ -1,5 +1,6 @@ // @flow import { PACKAGE_MANAGER_CMD } from './platform.service'; +import { processLogger } from './process-logger.service'; import * as childProcess from 'child_process'; import type { QueuedDependency } from '../types'; @@ -24,7 +25,7 @@ const spawnProcess = ( 'exit', code => (code ? reject(output.stderr) : resolve(output.stdout)) ); - // logger(child) // service will be used here later + processLogger(child, 'DEPENDENCY'); }); export const getDependencyInstallationCommand = ( diff --git a/src/services/process-logger.service.js b/src/services/process-logger.service.js new file mode 100644 index 00000000..ec10d9ad --- /dev/null +++ b/src/services/process-logger.service.js @@ -0,0 +1,25 @@ +const { LOGGING } = require('../config/app'); +const winston = require('winston'); +const { combine } = winston.format; + +export const winstonLogger = winston.createLogger({ + format: combine(winston.format.splat(), winston.format.simple()), + transports: [new winston.transports.Console()], + silent: !LOGGING || process.env.NODE_ENV === 'production', // logging off or production +}); + +export const processLogger = (child, label, level = 'info') => { + if (!child.stdout) { + return; // needed for tests + } + + // Todo: Handle color codes in logging to console (if supported). There are many control characters in the console output. + child.stdout.on('data', data => { + // data is an uint8 array --> decode to string + winstonLogger.log(level, '[%s]: %s', label, data.toString()); + }); + + child.stderr.on('data', data => { + winstonLogger.log('error', '[%s]: %s', label, data.toString()); + }); +}; diff --git a/yarn.lock b/yarn.lock index b22a7e13..5533e429 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1382,7 +1382,7 @@ async-limiter@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" -async@2.6.1, async@^2.1.2, async@^2.1.4, async@^2.3.0, async@^2.4.1: +async@2.6.1, async@^2.1.2, async@^2.1.4, async@^2.3.0, async@^2.4.1, async@^2.6.0: version "2.6.1" resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" dependencies: @@ -3120,7 +3120,7 @@ color-string@^1.5.2: color-name "^1.0.0" simple-swizzle "^0.2.2" -color@3.0.0: +color@3.0.0, color@3.0.x: version "3.0.0" resolved "https://registry.yarnpkg.com/color/-/color-3.0.0.tgz#d920b4328d534a3ac8295d68f7bd4ba6c427be9a" dependencies: @@ -3143,10 +3143,25 @@ colormin@^1.0.5: css-color-names "0.0.4" has "^1.0.1" +colornames@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/colornames/-/colornames-1.1.1.tgz#f8889030685c7c4ff9e2a559f5077eb76a816f96" + +colors@^1.2.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.2.tgz#2df8ff573dfbf255af562f8ce7181d6b971a359b" + colors@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" +colorspace@1.1.x: + version "1.1.1" + resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.1.tgz#9ac2491e1bc6f8fb690e2176814f8d091636d972" + dependencies: + color "3.0.x" + text-hex "1.0.x" + combined-stream@1.0.6, combined-stream@~1.0.5, combined-stream@~1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818" @@ -3905,6 +3920,14 @@ detect-port-alt@1.1.6: address "^1.0.1" debug "^2.6.0" +diagnostics@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/diagnostics/-/diagnostics-1.1.1.tgz#cab6ac33df70c9d9a727490ae43ac995a769b22a" + dependencies: + colorspace "1.1.x" + enabled "1.0.x" + kuler "1.0.x" + diff@^3.2.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" @@ -4211,6 +4234,12 @@ emojis-list@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" +enabled@1.0.x: + version "1.0.2" + resolved "https://registry.yarnpkg.com/enabled/-/enabled-1.0.2.tgz#965f6513d2c2d1c5f4652b64a2e3396467fc2f93" + dependencies: + env-variable "0.0.x" + encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" @@ -4244,6 +4273,10 @@ env-paths@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-1.0.0.tgz#4168133b42bb05c38a35b1ae4397c8298ab369e0" +env-variable@0.0.x: + version "0.0.5" + resolved "https://registry.yarnpkg.com/env-variable/-/env-variable-0.0.5.tgz#913dd830bef11e96a039c038d4130604eba37f88" + envify@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/envify/-/envify-4.1.0.tgz#f39ad3db9d6801b4e6b478b61028d3f0b6819f7e" @@ -4855,6 +4888,10 @@ fast-memoize@^2.2.7: version "2.5.1" resolved "https://registry.yarnpkg.com/fast-memoize/-/fast-memoize-2.5.1.tgz#c3519241e80552ce395e1a32dcdde8d1fd680f5d" +fast-safe-stringify@^2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz#04b26106cc56681f51a044cfc0d76cf0008ac2c2" + fastparse@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.1.tgz#d1e2643b38a94d7583b479060e6c4affc94071f8" @@ -4907,6 +4944,10 @@ fd-slicer@~1.0.1: dependencies: pend "~1.2.0" +fecha@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fecha/-/fecha-2.3.3.tgz#948e74157df1a32fd1b12c3a3c3cdcb6ec9d96cd" + figures@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" @@ -7023,6 +7064,12 @@ kleur@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/kleur/-/kleur-1.0.2.tgz#637f126d3cda40a423b1297da88cf753bd04ebdd" +kuler@1.0.x: + version "1.0.1" + resolved "https://registry.yarnpkg.com/kuler/-/kuler-1.0.1.tgz#ef7c784f36c9fb6e16dd3150d152677b2b0228a6" + dependencies: + colornames "^1.1.1" + latest-version@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" @@ -7349,6 +7396,16 @@ log-update@^1.0.2: ansi-escapes "^1.0.0" cli-cursor "^1.0.2" +logform@^1.9.1: + version "1.10.0" + resolved "https://registry.yarnpkg.com/logform/-/logform-1.10.0.tgz#c9d5598714c92b546e23f4e78147c40f1e02012e" + dependencies: + colors "^1.2.1" + fast-safe-stringify "^2.0.4" + fecha "^2.3.3" + ms "^2.1.1" + triple-beam "^1.2.0" + loglevel@^1.4.1: version "1.6.1" resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa" @@ -7719,7 +7776,7 @@ ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" -ms@2.1.1: +ms@2.1.1, ms@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" @@ -8129,6 +8186,10 @@ once@^1.3.0, once@^1.3.1, once@^1.3.3, once@^1.4.0: dependencies: wrappy "1" +one-time@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/one-time/-/one-time-0.0.4.tgz#f8cdf77884826fe4dff93e3a9cc37b1e4480742e" + onetime@^1.0.0: version "1.1.0" resolved "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" @@ -10514,7 +10575,7 @@ stable@~0.1.6: version "0.1.8" resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" -stack-trace@^0.0.10: +stack-trace@0.0.x, stack-trace@^0.0.10: version "0.0.10" resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" @@ -10930,6 +10991,10 @@ test-exclude@^4.2.1: read-pkg-up "^1.0.1" require-main-filename "^1.0.1" +text-hex@1.0.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5" + text-table@0.2.0, text-table@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -11102,6 +11167,10 @@ trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" +triple-beam@^1.2.0, triple-beam@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9" + truncate-utf8-bytes@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz#405923909592d56f78a5818434b0b78489ca5f2b" @@ -11711,6 +11780,27 @@ window-size@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" +winston-transport@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.2.0.tgz#a20be89edf2ea2ca39ba25f3e50344d73e6520e5" + dependencies: + readable-stream "^2.3.6" + triple-beam "^1.2.0" + +winston@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/winston/-/winston-3.1.0.tgz#80724376aef164e024f316100d5b178d78ac5331" + dependencies: + async "^2.6.0" + diagnostics "^1.1.1" + is-stream "^1.1.0" + logform "^1.9.1" + one-time "0.0.4" + readable-stream "^2.3.6" + stack-trace "0.0.x" + triple-beam "^1.3.0" + winston-transport "^4.2.0" + wordwrap@0.0.2, wordwrap@~0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" From dd5e77e55902215b11d1333ee7dbe63be3f60bb1 Mon Sep 17 00:00:00 2001 From: AWolf81 Date: Wed, 10 Oct 2018 00:58:49 +0200 Subject: [PATCH 02/12] removed winston --- package.json | 3 +- src/services/process-logger.service.js | 20 ++---- yarn.lock | 98 ++------------------------ 3 files changed, 11 insertions(+), 110 deletions(-) diff --git a/package.json b/package.json index 9a8830c1..313672e3 100644 --- a/package.json +++ b/package.json @@ -145,8 +145,7 @@ "webpack": "3.10.0", "webpack-dev-server": "2.11.0", "webpack-manifest-plugin": "1.3.2", - "whatwg-fetch": "2.0.3", - "winston": "^3.1.0" + "whatwg-fetch": "2.0.3" }, "browserslist": { "development": [ diff --git a/src/services/process-logger.service.js b/src/services/process-logger.service.js index ec10d9ad..fdd0a368 100644 --- a/src/services/process-logger.service.js +++ b/src/services/process-logger.service.js @@ -1,25 +1,17 @@ -const { LOGGING } = require('../config/app'); -const winston = require('winston'); -const { combine } = winston.format; +import { LOGGING } from '../config/app'; -export const winstonLogger = winston.createLogger({ - format: combine(winston.format.splat(), winston.format.simple()), - transports: [new winston.transports.Console()], - silent: !LOGGING || process.env.NODE_ENV === 'production', // logging off or production -}); - -export const processLogger = (child, label, level = 'info') => { - if (!child.stdout) { - return; // needed for tests +export const processLogger = (child, label) => { + if (!LOGGING || process.env.NODE_ENV === 'production') { + return; // no logging } // Todo: Handle color codes in logging to console (if supported). There are many control characters in the console output. child.stdout.on('data', data => { // data is an uint8 array --> decode to string - winstonLogger.log(level, '[%s]: %s', label, data.toString()); + console.log('[%s]: %s', label, data.toString()); }); child.stderr.on('data', data => { - winstonLogger.log('error', '[%s]: %s', label, data.toString()); + console.error('[%s]: %s', label, data.toString()); }); }; diff --git a/yarn.lock b/yarn.lock index 5533e429..b22a7e13 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1382,7 +1382,7 @@ async-limiter@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" -async@2.6.1, async@^2.1.2, async@^2.1.4, async@^2.3.0, async@^2.4.1, async@^2.6.0: +async@2.6.1, async@^2.1.2, async@^2.1.4, async@^2.3.0, async@^2.4.1: version "2.6.1" resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" dependencies: @@ -3120,7 +3120,7 @@ color-string@^1.5.2: color-name "^1.0.0" simple-swizzle "^0.2.2" -color@3.0.0, color@3.0.x: +color@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/color/-/color-3.0.0.tgz#d920b4328d534a3ac8295d68f7bd4ba6c427be9a" dependencies: @@ -3143,25 +3143,10 @@ colormin@^1.0.5: css-color-names "0.0.4" has "^1.0.1" -colornames@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/colornames/-/colornames-1.1.1.tgz#f8889030685c7c4ff9e2a559f5077eb76a816f96" - -colors@^1.2.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.2.tgz#2df8ff573dfbf255af562f8ce7181d6b971a359b" - colors@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" -colorspace@1.1.x: - version "1.1.1" - resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.1.tgz#9ac2491e1bc6f8fb690e2176814f8d091636d972" - dependencies: - color "3.0.x" - text-hex "1.0.x" - combined-stream@1.0.6, combined-stream@~1.0.5, combined-stream@~1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818" @@ -3920,14 +3905,6 @@ detect-port-alt@1.1.6: address "^1.0.1" debug "^2.6.0" -diagnostics@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/diagnostics/-/diagnostics-1.1.1.tgz#cab6ac33df70c9d9a727490ae43ac995a769b22a" - dependencies: - colorspace "1.1.x" - enabled "1.0.x" - kuler "1.0.x" - diff@^3.2.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" @@ -4234,12 +4211,6 @@ emojis-list@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" -enabled@1.0.x: - version "1.0.2" - resolved "https://registry.yarnpkg.com/enabled/-/enabled-1.0.2.tgz#965f6513d2c2d1c5f4652b64a2e3396467fc2f93" - dependencies: - env-variable "0.0.x" - encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" @@ -4273,10 +4244,6 @@ env-paths@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-1.0.0.tgz#4168133b42bb05c38a35b1ae4397c8298ab369e0" -env-variable@0.0.x: - version "0.0.5" - resolved "https://registry.yarnpkg.com/env-variable/-/env-variable-0.0.5.tgz#913dd830bef11e96a039c038d4130604eba37f88" - envify@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/envify/-/envify-4.1.0.tgz#f39ad3db9d6801b4e6b478b61028d3f0b6819f7e" @@ -4888,10 +4855,6 @@ fast-memoize@^2.2.7: version "2.5.1" resolved "https://registry.yarnpkg.com/fast-memoize/-/fast-memoize-2.5.1.tgz#c3519241e80552ce395e1a32dcdde8d1fd680f5d" -fast-safe-stringify@^2.0.4: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz#04b26106cc56681f51a044cfc0d76cf0008ac2c2" - fastparse@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.1.tgz#d1e2643b38a94d7583b479060e6c4affc94071f8" @@ -4944,10 +4907,6 @@ fd-slicer@~1.0.1: dependencies: pend "~1.2.0" -fecha@^2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/fecha/-/fecha-2.3.3.tgz#948e74157df1a32fd1b12c3a3c3cdcb6ec9d96cd" - figures@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" @@ -7064,12 +7023,6 @@ kleur@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/kleur/-/kleur-1.0.2.tgz#637f126d3cda40a423b1297da88cf753bd04ebdd" -kuler@1.0.x: - version "1.0.1" - resolved "https://registry.yarnpkg.com/kuler/-/kuler-1.0.1.tgz#ef7c784f36c9fb6e16dd3150d152677b2b0228a6" - dependencies: - colornames "^1.1.1" - latest-version@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" @@ -7396,16 +7349,6 @@ log-update@^1.0.2: ansi-escapes "^1.0.0" cli-cursor "^1.0.2" -logform@^1.9.1: - version "1.10.0" - resolved "https://registry.yarnpkg.com/logform/-/logform-1.10.0.tgz#c9d5598714c92b546e23f4e78147c40f1e02012e" - dependencies: - colors "^1.2.1" - fast-safe-stringify "^2.0.4" - fecha "^2.3.3" - ms "^2.1.1" - triple-beam "^1.2.0" - loglevel@^1.4.1: version "1.6.1" resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa" @@ -7776,7 +7719,7 @@ ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" -ms@2.1.1, ms@^2.1.1: +ms@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" @@ -8186,10 +8129,6 @@ once@^1.3.0, once@^1.3.1, once@^1.3.3, once@^1.4.0: dependencies: wrappy "1" -one-time@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/one-time/-/one-time-0.0.4.tgz#f8cdf77884826fe4dff93e3a9cc37b1e4480742e" - onetime@^1.0.0: version "1.1.0" resolved "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" @@ -10575,7 +10514,7 @@ stable@~0.1.6: version "0.1.8" resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" -stack-trace@0.0.x, stack-trace@^0.0.10: +stack-trace@^0.0.10: version "0.0.10" resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" @@ -10991,10 +10930,6 @@ test-exclude@^4.2.1: read-pkg-up "^1.0.1" require-main-filename "^1.0.1" -text-hex@1.0.x: - version "1.0.0" - resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5" - text-table@0.2.0, text-table@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -11167,10 +11102,6 @@ trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" -triple-beam@^1.2.0, triple-beam@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9" - truncate-utf8-bytes@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz#405923909592d56f78a5818434b0b78489ca5f2b" @@ -11780,27 +11711,6 @@ window-size@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" -winston-transport@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.2.0.tgz#a20be89edf2ea2ca39ba25f3e50344d73e6520e5" - dependencies: - readable-stream "^2.3.6" - triple-beam "^1.2.0" - -winston@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/winston/-/winston-3.1.0.tgz#80724376aef164e024f316100d5b178d78ac5331" - dependencies: - async "^2.6.0" - diagnostics "^1.1.1" - is-stream "^1.1.0" - logform "^1.9.1" - one-time "0.0.4" - readable-stream "^2.3.6" - stack-trace "0.0.x" - triple-beam "^1.3.0" - winston-transport "^4.2.0" - wordwrap@0.0.2, wordwrap@~0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" From 91a20c7f1e2ac7f238c977628a306c97c465cd99 Mon Sep 17 00:00:00 2001 From: AWolf81 Date: Wed, 10 Oct 2018 01:18:55 +0200 Subject: [PATCH 03/12] fixed test --- src/services/process-logger.service.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/services/process-logger.service.js b/src/services/process-logger.service.js index fdd0a368..5adc2fa2 100644 --- a/src/services/process-logger.service.js +++ b/src/services/process-logger.service.js @@ -5,6 +5,10 @@ export const processLogger = (child, label) => { return; // no logging } + if (!child.stdout) { + return; // needed during tests + } + // Todo: Handle color codes in logging to console (if supported). There are many control characters in the console output. child.stdout.on('data', data => { // data is an uint8 array --> decode to string From aba69660d8ee120ee29f1640c26fe2df30ac35eb Mon Sep 17 00:00:00 2001 From: AWolf81 Date: Sun, 14 Oct 2018 17:04:11 +0200 Subject: [PATCH 04/12] added next.js project type --- src/assets/images/nextjs.svg | 34 +++++++++++++++++++ .../CreateNewProjectWizard/MainPane.js | 10 ++++++ src/reducers/tasks.reducer.js | 11 ++++-- src/sagas/task.saga.js | 5 +++ src/services/create-project.service.js | 7 ++++ src/services/project-type-specifics.js | 2 ++ src/types.js | 2 +- 7 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 src/assets/images/nextjs.svg diff --git a/src/assets/images/nextjs.svg b/src/assets/images/nextjs.svg new file mode 100644 index 00000000..c029e0f8 --- /dev/null +++ b/src/assets/images/nextjs.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + diff --git a/src/components/CreateNewProjectWizard/MainPane.js b/src/components/CreateNewProjectWizard/MainPane.js index 8694a8dd..17db5649 100644 --- a/src/components/CreateNewProjectWizard/MainPane.js +++ b/src/components/CreateNewProjectWizard/MainPane.js @@ -5,6 +5,7 @@ import styled from 'styled-components'; import reactIconSrc from '../../assets/images/react-icon.svg'; import gatsbyIconSrc from '../../assets/images/gatsby_small.png'; +import nextjsIconSrc from '../../assets/images/nextjs.svg'; import FormField from '../FormField'; import ProjectIconSelection from '../ProjectIconSelection'; @@ -79,6 +80,7 @@ class MainPane extends PureComponent { isFocused={activeField === 'projectType'} > + {/* Todo: Make it easier to add new flows - e.g. map over an array to generate the UI*/} } @@ -96,6 +98,14 @@ class MainPane extends PureComponent { > Gatsby + + } + onClick={() => this.updateProjectType('nextjs')} + > + Next.js + diff --git a/src/reducers/tasks.reducer.js b/src/reducers/tasks.reducer.js index c7c020e5..a359f871 100644 --- a/src/reducers/tasks.reducer.js +++ b/src/reducers/tasks.reducer.js @@ -251,7 +251,9 @@ export const getTaskDescription = (name: string) => { export const isDevServerTask = (name: string) => // Gatsby and create-react-app use different names for the same task. - name === 'start' || name === 'develop'; + // also next.js uses a different name + // todo: refactor this mapping + name === 'start' || name === 'develop' || name === 'dev'; // https://docs.npmjs.com/misc/scripts const preExistingTasks = [ @@ -291,7 +293,7 @@ const getTaskType = name => { // For a dev server, "running" is a successful status - it means there are // no errors - while for a short-term task, "running" is essentially the same // as "loading", it's a yellow-light kind of thing. - const sustainedTasks = ['start', 'develop']; + const sustainedTasks = ['start', 'develop', 'dev']; return sustainedTasks.includes(name) ? 'sustained' : 'short-term'; }; @@ -378,6 +380,11 @@ export const getDevServerTaskForProjectId = ( case 'gatsby': { return state.tasks[props.projectId].develop; } + // todo: refactor so it's easier to add new flows + case 'nextjs': { + console.log('get dev', state.tasks[props.projectId]); + return state.tasks[props.projectId].dev; + } default: throw new Error('Unrecognized project type: ' + props.projectType); diff --git a/src/sagas/task.saga.js b/src/sagas/task.saga.js index 3226f258..7b264df2 100644 --- a/src/sagas/task.saga.js +++ b/src/sagas/task.saga.js @@ -374,6 +374,11 @@ export const getDevServerCommand = ( args: ['run', task.name, '-p', port], env: {}, }; + // todo: refactor so it's easier to add new project types + case 'nextjs': + return { + args: ['run', task.name, '-p', port], + }; default: throw new Error('Unrecognized project type: ' + projectType); } diff --git a/src/services/create-project.service.js b/src/services/create-project.service.js index 98692121..9dbef9f9 100644 --- a/src/services/create-project.service.js +++ b/src/services/create-project.service.js @@ -5,6 +5,7 @@ import * as childProcess from 'child_process'; import * as fs from 'fs'; import * as path from 'path'; import * as uuid from 'uuid/v1'; +import { processLogger } from './process-logger.service'; import { COLORS } from '../constants'; @@ -74,6 +75,8 @@ export default ( const process = childProcess.spawn(instruction, args); + processLogger(process, 'CREATE_PROJECT'); + process.stdout.on('data', onStatusUpdate); process.stderr.on('data', onError); @@ -169,6 +172,10 @@ export const getBuildInstructions = ( return [command, 'create-react-app', projectPath]; case 'gatsby': return [command, 'gatsby', 'new', projectPath]; + case 'nextjs': + // todo: add an issue at create-next-app so creating project with path will work + // --> for now fixed on a fork + return [command, 'github:awolf81/create-next-app', projectPath]; default: throw new Error('Unrecognized project type: ' + projectType); } diff --git a/src/services/project-type-specifics.js b/src/services/project-type-specifics.js index 7379d2fe..7b74b534 100644 --- a/src/services/project-type-specifics.js +++ b/src/services/project-type-specifics.js @@ -16,6 +16,8 @@ export const getDocumentationLink = (projectType: ProjectType) => { return 'https://github.com/facebook/create-react-app#user-guide'; case 'gatsby': return 'https://www.gatsbyjs.org/docs/'; + case 'nextjs': + return 'https://nextjs.org/docs/'; default: throw new Error('Unrecognized project type: ' + projectType); } diff --git a/src/types.js b/src/types.js index 8a04657f..09a580d5 100644 --- a/src/types.js +++ b/src/types.js @@ -1,5 +1,5 @@ // @flow -export type ProjectType = 'create-react-app' | 'gatsby'; +export type ProjectType = 'create-react-app' | 'gatsby' | 'nextjs'; export type SubmittedProject = { projectName: string, From b5ca5d170ce7dd9d4b832c38c75e3bcc96eee607 Mon Sep 17 00:00:00 2001 From: AWolf81 Date: Sun, 14 Oct 2018 21:19:01 +0200 Subject: [PATCH 05/12] WIP: Initial refactor. Just Gatsby format & test needs to be checked. --- src/config/project-types.js | 54 +++++++++++++++++++++ src/reducers/tasks.reducer.js | 32 +++++------- src/sagas/task.saga.js | 67 ++++++++++++++++++-------- src/services/create-project.service.js | 24 ++++----- 4 files changed, 123 insertions(+), 54 deletions(-) create mode 100644 src/config/project-types.js diff --git a/src/config/project-types.js b/src/config/project-types.js new file mode 100644 index 00000000..c4276cf8 --- /dev/null +++ b/src/config/project-types.js @@ -0,0 +1,54 @@ +// project type configuration +// used for +// - create project command args +// - devServer name mapping +// +export default { + 'create-react-app': { + devServer: { + taskName: 'start', + args: ['run', 'start'], + env: { + PORT: '$port', + }, + }, + create: { + // not sure if we need that nesting but I think there could be more to configure + args: projectPath => [ + // used for project creation previous getBuildInstructions + 'create-react-app', + projectPath, + ], + }, + }, + gatsby: { + devServer: { + taskName: 'develop', + // gatsby needs -p instead of env for port changing + args: ['run', 'develop', '-p', '$port'], + }, + create: { + // not sure if we need that nesting but I think there could be more to configure + args: projectPath => [ + // used for project creation previous getBuildInstructions + 'gatsby', + 'new', + projectPath, // todo replace later with config variables like $projectPath - so we can remove the function. Also check if it's getting complicated. + ], + }, + }, + nextjs: { + devServer: { + taskName: 'dev', + args: ['run', 'dev', '-p', '$port'], + }, + create: { + // not sure if we need that nesting but I think there could be more to configure + args: projectPath => [ + // used for project creation previous getBuildInstructions + 'github:awolf81/create-next-app', // later will be 'create-next-app' --> issue not filed yet + projectPath, + ], + }, + }, +}; diff --git a/src/reducers/tasks.reducer.js b/src/reducers/tasks.reducer.js index a359f871..1d440450 100644 --- a/src/reducers/tasks.reducer.js +++ b/src/reducers/tasks.reducer.js @@ -32,6 +32,7 @@ import { CLEAR_CONSOLE, RESET_ALL_STATE, } from '../actions'; +import projectConfigs from '../config/project-types'; import type { Action } from 'redux'; import type { Task, ProjectType } from '../types'; @@ -222,6 +223,10 @@ export default (state: State = initialState, action: Action = {}) => { // // // Helpers +export const devServerTaskNames = Object.keys(projectConfigs).map( + projectType => projectConfigs[projectType].devServer.taskName +); + export const getTaskDescription = (name: string) => { // NOTE: This information is currently derivable, and it's bad to store // derivable data in the reducer... but, I expect soon this info will be @@ -251,9 +256,7 @@ export const getTaskDescription = (name: string) => { export const isDevServerTask = (name: string) => // Gatsby and create-react-app use different names for the same task. - // also next.js uses a different name - // todo: refactor this mapping - name === 'start' || name === 'develop' || name === 'dev'; + devServerTaskNames.indexOf(name) !== -1; // https://docs.npmjs.com/misc/scripts const preExistingTasks = [ @@ -293,7 +296,7 @@ const getTaskType = name => { // For a dev server, "running" is a successful status - it means there are // no errors - while for a short-term task, "running" is essentially the same // as "loading", it's a yellow-light kind of thing. - const sustainedTasks = ['start', 'develop', 'dev']; + const sustainedTasks = devServerTaskNames; // We could have other tasks we could add - for now we also could use devServerTaskNames directly return sustainedTasks.includes(name) ? 'sustained' : 'short-term'; }; @@ -372,21 +375,10 @@ export const getDevServerTaskForProjectId = ( projectType: ProjectType, } ) => { - switch (props.projectType) { - case 'create-react-app': { - return state.tasks[props.projectId].start; - } - - case 'gatsby': { - return state.tasks[props.projectId].develop; - } - // todo: refactor so it's easier to add new flows - case 'nextjs': { - console.log('get dev', state.tasks[props.projectId]); - return state.tasks[props.projectId].dev; - } - - default: - throw new Error('Unrecognized project type: ' + props.projectType); + const config = projectConfigs[props.projectType]; + const { taskName } = config.devServer; + if (!config) { + throw new Error('Unrecognized project type: ' + props.projectType); } + return state.tasks[props.projectId][taskName]; }; diff --git a/src/sagas/task.saga.js b/src/sagas/task.saga.js index 7b264df2..8f1edb45 100644 --- a/src/sagas/task.saga.js +++ b/src/sagas/task.saga.js @@ -15,6 +15,7 @@ import { receiveDataFromTaskExecution, loadDependencyInfoFromDisk, } from '../actions'; +import projectConfigs from '../config/project-types'; import { getProjectById } from '../reducers/projects.reducer'; import { getPathForProjectId } from '../reducers/paths.reducer'; import { isDevServerTask } from '../reducers/tasks.reducer'; @@ -356,32 +357,58 @@ const createStdioChannel = ( }); }; +export const substituteConfigVariables = (configObject, variableMap) => { + // e.g. $port inside args will be replaced with variable reference from variabeMap obj. {$port: port} + return Object.keys(configObject).reduce( + (config, key) => { + if (config[key] instanceof Array) { + // replace $port inside args array + config[key] = config[key].map(arg => variableMap[arg] || arg); + } else { + // check config[key] e.g. is {env: { PORT: '$port'} } + if (config[key] instanceof Object) { + // config[key] = {PORT: '$port'}, key = 'env' + config[key] = Object.keys(config[key]).reduce( + (newObj, nestedKey) => { + // use replacement value if available + newObj[nestedKey] = + variableMap[newObj[nestedKey]] || newObj[nestedKey]; + return newObj; + }, + { ...config[key] } + ); + } + } + // todo: add top level substiution - not used yet but maybe needed later e.g. { env: $port } won't be replaced. + // Bad example but just to have it as reminder. + return config; + }, + { ...configObject } + ); +}; + export const getDevServerCommand = ( task: Task, projectType: ProjectType, port: string ) => { - switch (projectType) { - case 'create-react-app': - return { - args: ['run', task.name], - env: { - PORT: port, - }, - }; - case 'gatsby': - return { - args: ['run', task.name, '-p', port], - env: {}, - }; - // todo: refactor so it's easier to add new project types - case 'nextjs': - return { - args: ['run', task.name, '-p', port], - }; - default: - throw new Error('Unrecognized project type: ' + projectType); + const config = projectConfigs[projectType]; + + if (!config) { + throw new Error('Unrecognized project type: ' + projectType); } + + // Substitution is needed as we'd like to have $port as args or in env + // we can use it in either position and it will be subsituted with the port value here + const devServer = substituteConfigVariables(config.devServer, { + // pass every value that is needed in the commands here + $port: port, + }); + + return { + args: devServer.args, + env: devServer.env || {}, + }; }; export const stripUnusableControlCharacters = (text: string) => diff --git a/src/services/create-project.service.js b/src/services/create-project.service.js index 9dbef9f9..44e8ae4c 100644 --- a/src/services/create-project.service.js +++ b/src/services/create-project.service.js @@ -5,6 +5,7 @@ import * as childProcess from 'child_process'; import * as fs from 'fs'; import * as path from 'path'; import * as uuid from 'uuid/v1'; +import projectConfigs from '../config/project-types'; import { processLogger } from './process-logger.service'; import { COLORS } from '../constants'; @@ -110,9 +111,11 @@ export default ( // Gatsby specific fix - the command 'npx gatsby new ...' always sets the // name key in package.json to `gatsby-starter-default`. Overwrite it so // project is named correctly. - if (projectType === 'gatsby') { - packageJson.name = projectDirectoryName; - } + // if (projectType === 'gatsby') { + // packageJson.name = projectDirectoryName; + // } + // Todo: Check if always setting the name is a problem --> we don't want project-type specific stuff here + packageJson.name = projectDirectoryName; const prettyPrintedPackageJson = JSON.stringify(packageJson, null, 2); @@ -167,16 +170,9 @@ export const getBuildInstructions = ( // Windows tries to run command as a script rather than on a cmd // To force it we add *.cmd to the commands const command = formatCommandForPlatform('npx'); - switch (projectType) { - case 'create-react-app': - return [command, 'create-react-app', projectPath]; - case 'gatsby': - return [command, 'gatsby', 'new', projectPath]; - case 'nextjs': - // todo: add an issue at create-next-app so creating project with path will work - // --> for now fixed on a fork - return [command, 'github:awolf81/create-next-app', projectPath]; - default: - throw new Error('Unrecognized project type: ' + projectType); + if (!projectConfigs.hasOwnProperty(projectType)) { + throw new Error('Unrecognized project type: ' + projectType); } + + return [command, ...projectConfigs[projectType].create.args(projectPath)]; }; From e16204d6ee006b03daa475b01f53875ab0e87bc1 Mon Sep 17 00:00:00 2001 From: AWolf81 Date: Sun, 14 Oct 2018 21:39:39 +0200 Subject: [PATCH 06/12] fixed flow typing --- src/reducers/tasks.reducer.js | 6 +++--- src/sagas/task.saga.js | 10 +++++++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/reducers/tasks.reducer.js b/src/reducers/tasks.reducer.js index 1d440450..c92feca6 100644 --- a/src/reducers/tasks.reducer.js +++ b/src/reducers/tasks.reducer.js @@ -223,9 +223,9 @@ export default (state: State = initialState, action: Action = {}) => { // // // Helpers -export const devServerTaskNames = Object.keys(projectConfigs).map( - projectType => projectConfigs[projectType].devServer.taskName -); +export const devServerTaskNames: Array = Object.keys( + projectConfigs +).map(projectType => projectConfigs[projectType].devServer.taskName); export const getTaskDescription = (name: string) => { // NOTE: This information is currently derivable, and it's bad to store diff --git a/src/sagas/task.saga.js b/src/sagas/task.saga.js index 8f1edb45..a7b0fbc7 100644 --- a/src/sagas/task.saga.js +++ b/src/sagas/task.saga.js @@ -32,6 +32,11 @@ import type { Action } from 'redux'; import type { Saga } from 'redux-saga'; import type { Task, ProjectType } from '../types'; +// Mapping type for config template variables '$port' +export type VariableMap = { + $port: string, +}; + const chalk = new chalkRaw.constructor({ level: 3 }); export function* launchDevServer({ task }: Action): Saga { @@ -357,7 +362,10 @@ const createStdioChannel = ( }); }; -export const substituteConfigVariables = (configObject, variableMap) => { +export const substituteConfigVariables = ( + configObject: any, + variableMap: VariableMap +) => { // e.g. $port inside args will be replaced with variable reference from variabeMap obj. {$port: port} return Object.keys(configObject).reduce( (config, key) => { From 030b40c37519b72bf4f91592c2d7da9354335963 Mon Sep 17 00:00:00 2001 From: AWolf81 Date: Sat, 20 Oct 2018 11:35:37 +0200 Subject: [PATCH 07/12] replaced icon to triangle logo --- src/assets/images/nextjs.png | Bin 0 -> 8241 bytes src/assets/images/nextjs.svg | 34 ------------------ src/assets/images/nextjs_small.png | Bin 0 -> 1494 bytes .../CreateNewProjectWizard/MainPane.js | 2 +- 4 files changed, 1 insertion(+), 35 deletions(-) create mode 100644 src/assets/images/nextjs.png delete mode 100644 src/assets/images/nextjs.svg create mode 100644 src/assets/images/nextjs_small.png diff --git a/src/assets/images/nextjs.png b/src/assets/images/nextjs.png new file mode 100644 index 0000000000000000000000000000000000000000..2e728d7097fe81120a7c8236960c8f60019751bc GIT binary patch literal 8241 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 VK5C8qv={<6WqA#`V%Zk~{{!XTehmNs literal 0 HcmV?d00001 diff --git a/src/assets/images/nextjs.svg b/src/assets/images/nextjs.svg deleted file mode 100644 index c029e0f8..00000000 --- a/src/assets/images/nextjs.svg +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/assets/images/nextjs_small.png b/src/assets/images/nextjs_small.png new file mode 100644 index 0000000000000000000000000000000000000000..4572854f7cb3a603031c80dd2d056ca55564a0df GIT binary patch literal 1494 zcmV;{1u6Q8P) zK~#9!?VCGj6kQmG-#I%oxok{U0uf?iz((vO+66R)rD<%$!a|#1;{}5#cmWYCEG!}f zBBCLpLF{5gP$99f2nv#Dqb7|BA+VB-JG(pA*Xk_e{G0rV*`1l)?197Fb{C%K`_6Zk z!x@Dnv5lL+Hg9zSbpdq&(KW|$wxC&ZWQ-C42#l=M?lSu*~0PfhagYVwGV^l3v0r`BM z=gyrg!ULcXf(H*CtbGBV=W%v+_AhwZTUuH;JUm?60t~}oUteEI0RY(5)kV`ZYg2&h zx_tBI&6@B4*woa-t5>hqrhwnSfAheB1M3O^z>ba%E-Wn6mH^wf`RLK3|AhxYP1AVl z)T!DMkWQ!B(b2IX0RY(6*2d}S>DmxbC=__@+O-YC%W3h*kt4MsU~X=XLWoTX0KnGP zR*sF0RkwhAKF^aUPi`7s_I>;IRj&Zob@}1Lhku3#z+^JXJ9q9>r+{28$DW>^EeQa? z&dyGz)9LCG;5ZJSKYzYucmQl@XkdSTe{~7SWHQ{dXHQuK0APE2JHLGSQXK*;%i`U; zcgqG3fU2tU*s){PAz*1~iA_ySWfcH`sZ@%uUcHL9fI^|b{{H^5!vmnADD3X;j;{dE z^Z5Dm=Ze7lSB~!AzaLKlg+hTxj~=b40J&z6%jM!Fz;#_tOiWZ99snB~8#ypA5HA6S zVQ~Nc{h=Y=c4bzM$P zO+^kb*9>mnycw>5d_K?a?(SF!0Knb5cXMfJDI5Wg4q4WOH*fTU%S1N~PG|-p=0M-c1V- z8`wdD+1Xh9bG~okw`#QRj8^8P1B0UL?VI3#YH@L@SwbVgk0Cfg$oy=-N~gW z5JLO~D}*QtNhA``G!5Bo7LOl4MmC!*j{wi}Fg`wx$;rvc;WbTzrfEfJd9A8yF)MUk z$I8kI?%lgr9s#ClVqjn(7AY^IF2QBwgG0fxEWCaD7W4D-TNB{AE{2DP@%{Vv$l?9b z4%PuFLUvu(vAVj7!NI|;3CLtJxPJY5Bq{F)lF-2#;C~(zLJ~7GGnk&9{x<=x>*Cg} zTgYTGk&O2sP%zs5jPMTuf3_Hgv7wnul$!SD=H@n4NGdVK1-t*5zYqq8fRrGFz|WsQ zF)=Z*IRT#M;o`-Mp~IIF;D^$6{Vx&zXa3Lohf6M(!;2R$*4>pZg3+IxoW%I}cw~_e zM$-=#tolI#{-GhyS5{W=^y$-$39xM&=g*%Hz1Xdl@})p!+6N1wjJ%A#{ETUun3|eG zI-Oo$faiG_9UaBY%uMLTE|}KA>mX=w2>1)5zaYw?lg(!F?Af#R1sH~bD_5?BUgb*_ zx!}E0W4%;%l==-#(?AkmzkV(GpGL@O@5YTASYBSP^wxZMo(IQqV45Zhg+j5LrdjNk zW&P)Rt!~>kY} Date: Sat, 20 Oct 2018 14:35:00 +0200 Subject: [PATCH 08/12] changed devServer handling --- src/actions/index.js | 7 ++- .../DevelopmentServerPane.js | 6 +- .../TaskDetailsModal/TaskDetailsModal.js | 14 +++-- .../TaskRunnerPane/TaskRunnerPane.js | 18 ++++-- src/reducers/tasks.reducer.js | 59 +++++++++++++++---- src/sagas/task.saga.js | 4 +- src/sagas/task.saga.test.js | 22 +++++-- 7 files changed, 100 insertions(+), 30 deletions(-) diff --git a/src/actions/index.js b/src/actions/index.js index b682d202..f98e3180 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -166,9 +166,14 @@ export const attachTaskMetadata = ( port, }); -export const abortTask = (task: Task, timestamp: Date) => ({ +export const abortTask = ( + task: Task, + projectType: string, + timestamp: Date +) => ({ type: ABORT_TASK, task, + projectType, timestamp, }); diff --git a/src/components/DevelopmentServerPane/DevelopmentServerPane.js b/src/components/DevelopmentServerPane/DevelopmentServerPane.js index 6b8de36c..450e02ca 100644 --- a/src/components/DevelopmentServerPane/DevelopmentServerPane.js +++ b/src/components/DevelopmentServerPane/DevelopmentServerPane.js @@ -24,12 +24,12 @@ type Props = { project: Project, task: ?Task, launchDevServer: (task: Task, timestamp: Date) => void, - abortTask: (task: Task, timestamp: Date) => void, + abortTask: (task: Task, projectType: string, timestamp: Date) => void, }; class DevelopmentServerPane extends PureComponent { handleToggle = (isToggled: boolean) => { - const { task, launchDevServer, abortTask } = this.props; + const { task, launchDevServer, abortTask, project } = this.props; if (!task) { // Should be impossible, since the Toggle control won't render without @@ -42,7 +42,7 @@ class DevelopmentServerPane extends PureComponent { if (isToggled) { launchDevServer(task, timestamp); } else { - abortTask(task, timestamp); + abortTask(task, project.type, timestamp); } }; diff --git a/src/components/TaskDetailsModal/TaskDetailsModal.js b/src/components/TaskDetailsModal/TaskDetailsModal.js index a816a00e..a143be9f 100644 --- a/src/components/TaskDetailsModal/TaskDetailsModal.js +++ b/src/components/TaskDetailsModal/TaskDetailsModal.js @@ -12,6 +12,7 @@ import { isTaskDisabled, } from '../../reducers/tasks.reducer'; import { getIsQueueEmpty } from '../../reducers/queue.reducer'; +import { getSelectedProject } from '../../reducers/projects.reducer'; import Modal from '../Modal'; import ModalHeader from '../ModalHeader'; @@ -21,7 +22,7 @@ import EjectButton from '../EjectButton'; import TerminalOutput from '../TerminalOutput'; import WindowDimensions from '../WindowDimensions'; -import type { Task } from '../../types'; +import type { Task, Project } from '../../types'; type Props = { projectId: string, @@ -31,19 +32,22 @@ type Props = { onDismiss: () => void, // From Redux: task: Task, + project: Project, runTask: (task: Task, timestamp: Date) => any, - abortTask: (task: Task, timestamp: Date) => any, + abortTask: (task: Task, projectType: string, timestamp: Date) => any, }; class TaskDetailsModal extends PureComponent { handleToggle = () => { - const { task, runTask, abortTask } = this.props; + const { task, runTask, abortTask, project } = this.props; const isRunning = !!task.processId; const timestamp = new Date(); - isRunning ? abortTask(task, timestamp) : runTask(task, timestamp); + isRunning + ? abortTask(task, project.type, timestamp) + : runTask(task, timestamp); }; renderPrimaryStatusText = () => { @@ -233,6 +237,7 @@ const HorizontalRule = styled.div` `; const mapStateToProps = (state, ownProps) => { + const selectedProject = getSelectedProject(state); const dependenciesChangingForProject = !getIsQueueEmpty(state, ownProps); const task = getTaskByProjectIdAndTaskName(state, ownProps); @@ -241,6 +246,7 @@ const mapStateToProps = (state, ownProps) => { return { task, + project: selectedProject, isDisabled, }; }; diff --git a/src/components/TaskRunnerPane/TaskRunnerPane.js b/src/components/TaskRunnerPane/TaskRunnerPane.js index d7763e2f..e81ded81 100644 --- a/src/components/TaskRunnerPane/TaskRunnerPane.js +++ b/src/components/TaskRunnerPane/TaskRunnerPane.js @@ -4,7 +4,10 @@ import { connect } from 'react-redux'; import * as actions from '../../actions'; import { GUPPY_REPO_URL } from '../../constants'; -import { getSelectedProjectId } from '../../reducers/projects.reducer'; +import { + getSelectedProjectId, + getSelectedProject, +} from '../../reducers/projects.reducer'; import { getTasksInTaskListForProjectId, isTaskDisabled, @@ -15,10 +18,11 @@ import Module from '../Module'; import TaskRunnerPaneRow from '../TaskRunnerPaneRow'; import TaskDetailsModal from '../TaskDetailsModal'; -import type { Task } from '../../types'; +import type { Task, Project } from '../../types'; type Props = { projectId: string, + project: Project, tasks: Array, runTask: Function, abortTask: Function, @@ -48,7 +52,7 @@ class TaskRunnerPane extends Component { } handleToggleTask = (taskName: string) => { - const { tasks, runTask, abortTask } = this.props; + const { tasks, runTask, abortTask, project } = this.props; // eslint-disable-next-line no-shadow const task = tasks.find(task => task.name === taskName); @@ -62,7 +66,9 @@ class TaskRunnerPane extends Component { const timestamp = new Date(); - isRunning ? abortTask(task, timestamp) : runTask(task, timestamp); + isRunning + ? abortTask(task, project.type, timestamp) + : runTask(task, timestamp); }; handleViewDetails = (taskName: string) => { @@ -116,6 +122,8 @@ class TaskRunnerPane extends Component { } const mapStateToProps = state => { + const selectedProject = getSelectedProject(state); + const projectId = getSelectedProjectId(state); const dependenciesChangingForProject = @@ -125,7 +133,7 @@ const mapStateToProps = state => { ? getTasksInTaskListForProjectId(state, { projectId }) : []; - return { tasks, dependenciesChangingForProject }; + return { tasks, dependenciesChangingForProject, project: selectedProject }; }; export default connect( diff --git a/src/reducers/tasks.reducer.js b/src/reducers/tasks.reducer.js index c92feca6..5ad5d88c 100644 --- a/src/reducers/tasks.reducer.js +++ b/src/reducers/tasks.reducer.js @@ -223,9 +223,29 @@ export default (state: State = initialState, action: Action = {}) => { // // // Helpers -export const devServerTaskNames: Array = Object.keys( - projectConfigs -).map(projectType => projectConfigs[projectType].devServer.taskName); +// +// devServerTaskNameMap is a mapping Object +// Needed because next.js also contains a script named 'start' which is not the devServer task. +// So we can test if name is a devServerName by simply accessing map['create-react-app'][testString] which will return true or undefined. +// Mapping Object structure: +// { +// 'create-react-app': { +// 'start': true +// }, +// ... +// } +// Notice: We could simplify this by using projectConfigs[projectType].devServer.taskName === name in isDevServer check but +// we also need it in getTaskType which runs before the reducer so we don't have access to projectType. +export const devServerTaskNameMap = Object.keys(projectConfigs).reduce( + (devServerNamesObj, projectType) => { + const name = projectConfigs[projectType].devServer.taskName; + devServerNamesObj[projectType] = { + [name]: true, + }; + return devServerNamesObj; + }, + {} +); export const getTaskDescription = (name: string) => { // NOTE: This information is currently derivable, and it's bad to store @@ -254,9 +274,9 @@ export const getTaskDescription = (name: string) => { } }; -export const isDevServerTask = (name: string) => - // Gatsby and create-react-app use different names for the same task. - devServerTaskNames.indexOf(name) !== -1; +export const isDevServerTask = (name: string, projectType: string) => + // Each framework uses a different name for the task that starts the development server + projectConfigs[projectType].devServer.taskName === name; // https://docs.npmjs.com/misc/scripts const preExistingTasks = [ @@ -296,8 +316,19 @@ const getTaskType = name => { // For a dev server, "running" is a successful status - it means there are // no errors - while for a short-term task, "running" is essentially the same // as "loading", it's a yellow-light kind of thing. - const sustainedTasks = devServerTaskNames; // We could have other tasks we could add - for now we also could use devServerTaskNames directly - + // Todo: We need to re-work this as next.js has two long-running tasks dev & start. + // How do we handle it? This needs to be discussed in an issue - will be create soon. + + // {create-react-app: { start: true } } --> ["start", ...] + const sustainedTasks = Object.keys(devServerTaskNameMap).reduce( + (devServerTaskNames, projectType) => { + devServerTaskNames.push( + Object.keys(devServerTaskNameMap[projectType])[0] + ); + return devServerTaskNames; + }, + [] + ); return sustainedTasks.includes(name) ? 'sustained' : 'short-term'; }; @@ -357,14 +388,20 @@ export const getTasksForProjectId = ( return state.tasks[props.projectId]; }; +// Todo: Why is it not possible to move getTypeOfSelectedProject to projects.reducer.js? Always getting an error from reselect that it is undefined. +const getTypeOfSelectedProject = (state: any, props) => { + return state.projects.byId[props.projectId].guppy.type; +}; + export const getTasksInTaskListForProjectId = createSelector( - [getTasksForProjectId], - tasks => + [getTasksForProjectId, getTypeOfSelectedProject], + (tasks, projectType) => Object.keys(tasks) .map(taskId => tasks[taskId]) .filter( (task, i, tasksArray) => - !isDevServerTask(task.name) && !isLifeCycleHook(task.name, tasksArray) + !isDevServerTask(task.name, projectType) && + !isLifeCycleHook(task.name, tasksArray) ) ); diff --git a/src/sagas/task.saga.js b/src/sagas/task.saga.js index a7b0fbc7..4ca4e3fb 100644 --- a/src/sagas/task.saga.js +++ b/src/sagas/task.saga.js @@ -279,7 +279,7 @@ export function* taskRun({ task }: Action): Saga { } } -export function* taskAbort({ task }: Action): Saga { +export function* taskAbort({ task, projectType }: Action): Saga { const { processId, name } = task; yield call(killProcessId, processId); @@ -291,7 +291,7 @@ export function* taskAbort({ task }: Action): Saga { // but given that we're treating `start` as its own special thing, // I'm realizing that it should vary depending on the task type. // TODO: Find a better place for this to live. - const abortMessage = isDevServerTask(name) + const abortMessage = isDevServerTask(name, projectType) ? 'Server stopped' : 'Task aborted'; diff --git a/src/sagas/task.saga.test.js b/src/sagas/task.saga.test.js index f542f6cb..71019939 100644 --- a/src/sagas/task.saga.test.js +++ b/src/sagas/task.saga.test.js @@ -315,7 +315,10 @@ describe('task saga', () => { describe('taskAbort saga', () => { it('should kill process and notify renderer', () => { const processId = 12345; - const saga = taskAbort({ task: { name: 'start', processId } }); + const saga = taskAbort({ + task: { name: 'start', processId }, + projectType: 'create-react-app', + }); expect(saga.next().value).toEqual(call(killProcessId, processId)); expect(saga.next().value).toEqual( @@ -325,7 +328,7 @@ describe('task saga', () => { it('should display correct message for dev server task', () => { const task = { name: 'start', processId: 12345 }; // react - let saga = taskAbort({ task }); + let saga = taskAbort({ task, projectType: 'create-react-app' }); saga.next(); saga.next(); @@ -336,7 +339,18 @@ describe('task saga', () => { ); task.name = 'develop'; // gatsby - saga = taskAbort({ task }); + saga = taskAbort({ task, projectType: 'gatsby' }); + saga.next(); + saga.next(); + + expect(saga.next().value).toEqual( + put( + receiveDataFromTaskExecution(task, chalk.bold.red('Server stopped')) + ) + ); + + task.name = 'dev'; // nextjs + saga = taskAbort({ task, projectType: 'nextjs' }); saga.next(); saga.next(); @@ -349,7 +363,7 @@ describe('task saga', () => { it('should display correct message for non dev server task', () => { const task = { name: 'test', processId: 12345 }; - const saga = taskAbort({ task }); + const saga = taskAbort({ task, projectType: 'create-react-app' }); saga.next(); saga.next(); From 470ec2ecb68a6588bbc7a9e0e09f96d66d380213 Mon Sep 17 00:00:00 2001 From: AWolf81 Date: Sat, 20 Oct 2018 16:01:01 +0200 Subject: [PATCH 09/12] disabled logging --- src/config/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/app.js b/src/config/app.js index b4975212..e6b07517 100644 --- a/src/config/app.js +++ b/src/config/app.js @@ -2,5 +2,5 @@ module.exports = { PACKAGE_MANAGER: 'yarn', // Enable logging, if enabled all terminal responses are visible in the console (useful for debugging) - LOGGING: true, + LOGGING: false, }; From e91b7065256d684dcaca6f0a73fa4f235818327c Mon Sep 17 00:00:00 2001 From: AWolf81 Date: Sat, 20 Oct 2018 16:07:20 +0200 Subject: [PATCH 10/12] added NextjsIcon styled component --- src/components/CreateNewProjectWizard/MainPane.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/CreateNewProjectWizard/MainPane.js b/src/components/CreateNewProjectWizard/MainPane.js index bffdae3e..32b42626 100644 --- a/src/components/CreateNewProjectWizard/MainPane.js +++ b/src/components/CreateNewProjectWizard/MainPane.js @@ -101,7 +101,7 @@ class MainPane extends PureComponent { } + icon={} onClick={() => this.updateProjectType('nextjs')} > Next.js @@ -163,6 +163,11 @@ const GatsbyIcon = styled.img` height: 22px; `; +const NextjsIcon = styled.img` + width: 22px; + height: 22px; +`; + const ProjectTypeTogglesWrapper = styled.div` margin-top: 8px; margin-left: -8px; From c7fbb21653bb03183d30bd8690cb1062154b6b24 Mon Sep 17 00:00:00 2001 From: AWolf81 Date: Sat, 20 Oct 2018 16:19:23 +0200 Subject: [PATCH 11/12] added explanation comment to substituteConfigVariables function --- src/sagas/task.saga.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sagas/task.saga.js b/src/sagas/task.saga.js index 4ca4e3fb..e1275b48 100644 --- a/src/sagas/task.saga.js +++ b/src/sagas/task.saga.js @@ -362,6 +362,9 @@ const createStdioChannel = ( }); }; +// We're using "template" variables inside the project type configuration file (config/project-types.js) +// so with the following function we can replace the string $port with the real port number e.g. 3000 +// (see type VariableMap for used mapping strings) export const substituteConfigVariables = ( configObject: any, variableMap: VariableMap From a5f212d362fad6b8d94d847ec09d6b5aa2ad66dc Mon Sep 17 00:00:00 2001 From: AWolf81 Date: Thu, 1 Nov 2018 14:42:59 +0100 Subject: [PATCH 12/12] updated comment --- src/config/project-types.js | 4 +--- src/sagas/task.saga.js | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/config/project-types.js b/src/config/project-types.js index c4276cf8..a386f6af 100644 --- a/src/config/project-types.js +++ b/src/config/project-types.js @@ -43,10 +43,8 @@ export default { args: ['run', 'dev', '-p', '$port'], }, create: { - // not sure if we need that nesting but I think there could be more to configure args: projectPath => [ - // used for project creation previous getBuildInstructions - 'github:awolf81/create-next-app', // later will be 'create-next-app' --> issue not filed yet + 'github:awolf81/create-next-app', // later will be 'create-next-app' --> added a comment to the following issue https://github.com/segmentio/create-next-app/issues/30 projectPath, ], }, diff --git a/src/sagas/task.saga.js b/src/sagas/task.saga.js index e1275b48..c8b73340 100644 --- a/src/sagas/task.saga.js +++ b/src/sagas/task.saga.js @@ -390,7 +390,7 @@ export const substituteConfigVariables = ( ); } } - // todo: add top level substiution - not used yet but maybe needed later e.g. { env: $port } won't be replaced. + // todo: add top level substitution - not used yet but maybe needed later e.g. { env: $port } won't be replaced. // Bad example but just to have it as reminder. return config; },