From 6d43d64f7a22e7b2670f32ae8dce48b326207497 Mon Sep 17 00:00:00 2001 From: Adam Roberts Date: Wed, 27 Sep 2017 16:26:17 +0100 Subject: [PATCH 01/12] Add Prometheus attach and dependency --- app/templates/package.json | 1 + app/templates/server/server.js | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/templates/package.json b/app/templates/package.json index aa16e38..bf29d44 100644 --- a/app/templates/package.json +++ b/app/templates/package.json @@ -14,6 +14,7 @@ }, "dependencies": { "appmetrics-dash": "^3.3.2", + "appmetrics-prometheus": "^0.0.2", "body-parser": "^1.17.2", "express": "^4.15.3", "strong-supervisor": "^6.2.0", diff --git a/app/templates/server/server.js b/app/templates/server/server.js index f5d49bd..fca8cdd 100644 --- a/app/templates/server/server.js +++ b/app/templates/server/server.js @@ -1,4 +1,6 @@ require('appmetrics-dash').attach(); +require('appmetrics-prometheus').attach(); + const appName = require('./../package').name; const express = require('express'); const log4js = require('log4js'); @@ -22,4 +24,4 @@ app.listen(port, function(){ logger.info(`OpenAPI (Swagger) spec is available at http://localhost:${port}/swagger/api`); logger.info(`Swagger UI is available at http://localhost:${port}/explorer`); <% } %> -}); \ No newline at end of file +}); From c7304972cbbb01d41ee92a70e7eca81e80fa913e Mon Sep 17 00:00:00 2001 From: Adam Roberts Date: Thu, 28 Sep 2017 11:46:03 +0100 Subject: [PATCH 02/12] Add tests for appmetrics-dash and appmetrics-prometheus (attach and package.json) --- test/integration.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/integration.js b/test/integration.js index 0d90c0b..7ff6252 100644 --- a/test/integration.js +++ b/test/integration.js @@ -73,6 +73,7 @@ describe('core-node-express:app integration test with custom spec', function () }, "dependencies": { "appmetrics-dash": "^3.3.2", + "appmetrics-prometheus": "^0.0.2", "body-parser": "^1.17.2", "express": "^4.15.3", "strong-supervisor": "^6.2.0", @@ -155,6 +156,7 @@ describe('core-node-express:app integration test with custom bluemix', function }, "dependencies": { "appmetrics-dash": "^3.3.2", + "appmetrics-prometheus": "^0.0.2", "body-parser": "^1.17.2", "express": "^4.15.3", "log4js": "^1.1.1" @@ -185,6 +187,18 @@ describe('core-node-express:app integration test with custom bluemix', function }); }); + describe(common.file.server_js, () => { + it('contains appmetrics attach', () => { + assert.fileContent(common.file.server_js, "require('appmetrics-dash').attach();") + }); + }); + + describe(common.file.server_js, () => { + it('contains appmetrics-prometheus attach', () => { + assert.fileContent(common.file.server_js, "require('appmetrics-prometheus').attach();") + }); + }); + describe(common.file.gitignore, function () { it('contains node_modules', function () { assert.fileContent(common.file.gitignore, 'node_modules'); @@ -237,6 +251,7 @@ describe('core-node-express:app integration test with custom bluemix and spec', }, "dependencies": { "appmetrics-dash": "^3.3.2", + "appmetrics-prometheus": "^0.0.2", "body-parser": "^1.17.2", "express": "^4.15.3", "log4js": "^1.1.1" From accdc769c34b3653e92e16fab70a267f5c025687 Mon Sep 17 00:00:00 2001 From: Gibson Fahnestock Date: Tue, 26 Sep 2017 20:17:49 +0100 Subject: [PATCH 03/12] chore: tabs to spaces, remove trailing whitespace --- app/index.js | 52 +++++---- app/templates/public/swagger-ui/swagger-ui.js | 104 +++++++++--------- app/templates/server/config/local.json | 2 +- app/templates/server/routers/public.js | 6 +- app/templates/server/server.js | 16 +-- lib/helpers.js | 4 +- 6 files changed, 94 insertions(+), 90 deletions(-) diff --git a/app/index.js b/app/index.js index fbd0651..dd7ad72 100644 --- a/app/index.js +++ b/app/index.js @@ -29,6 +29,10 @@ module.exports = class extends Generator { constructor(args, opts) { super(args, opts); + if ( typeof opts.bluemix.quiet == "undefined" || ! opts.bluemix.quiet ) { + logger.info("Package info ::", Bundle.name, Bundle.version); + } + // bluemix option for YaaS integration this.argument(OPTION_BLUEMIX, { desc: 'Option for deploying with Bluemix. Stringified JSON.', @@ -50,16 +54,16 @@ module.exports = class extends Generator { this.skipPrompt = true; let bluemix_ok= this._sanitizeOption(this.options, OPTION_BLUEMIX); let spec_ok= this._sanitizeOption(this.options, OPTION_SPEC); - if ( ! (bluemix_ok || spec_ok )) throw ("Must specify either bluemix or spec parameter"); - - if ( typeof this.options.bluemix.quiet == "undefined" || ! this.options.bluemix.quiet ) { + if ( ! (bluemix_ok || spec_ok )) throw ("Must specify either bluemix or spec parameter"); + + if ( typeof this.options.bluemix.quiet == "undefined" || ! this.options.bluemix.quiet ) { logger.info("Package info ::", Bundle.name, Bundle.version); - } - + } + let appName = this.options.bluemix.name || this.options.spec.appname; this.options.sanitizedAppName = this._sanitizeAppName(appName); - this.options.genSwagger= false; - this.options.openApiFileType= "yaml"; // default + this.options.genSwagger= false; + this.options.openApiFileType= "yaml"; // default this.options.parsedSwagger = undefined; let formatters = { @@ -75,8 +79,8 @@ module.exports = class extends Generator { .then(response => { this.options.loadedApi = response.loaded; this.options.parsedSwagger = response.parsed; - this.options.openApiFileType= response.type; - this.options.genSwagger= true; + this.options.openApiFileType= response.type; + this.options.genSwagger= true; }) .catch(err => { err.message = 'failed to parse document from bluemix.openApiServers ' + err.message; @@ -84,9 +88,9 @@ module.exports = class extends Generator { }) } - // micro service always gets swagger ui and no public + // micro service always gets swagger ui and no public if(this.options.spec && this.options.spec.applicationType === 'MS') { - this.options.genSwagger= true; + this.options.genSwagger= true; } } @@ -116,21 +120,21 @@ module.exports = class extends Generator { this.fs.copyTpl(this.templatePath('package.json'), this.destinationPath('package.json'), this.options); this.fs.copyTpl(this.templatePath('README.md'), this.destinationPath('README.md'), this.options); - // if project will have swagger doc, ensure swagger ui and api route + // if project will have swagger doc, ensure swagger ui and api route if ( this.options.genSwagger ) { this.fs.copy(this.templatePath('public/swagger-ui'), this.destinationPath('public/swagger-ui')); - // if open api doc provided, write it else write default + // if open api doc provided, write it else write default if ( this.options.loadedApi ) { let yaml= this.options.bluemix.openApiServers[0].spec; //this.fs.writeJSON('public/swagger.'+this.options.openApiFileType, this.options.loadedApi); - this.fs.write('public/swagger.'+this.options.openApiFileType, yaml); - } + this.fs.write('public/swagger.'+this.options.openApiFileType, yaml); + } else { this.fs.copyTpl(this.templatePath('public/swagger.yaml'), this.destinationPath('public/swagger.yaml'), this.options); } } - else { + else { this.fs.delete(this.destinationPath('server/routers/swagger.js')); } @@ -138,11 +142,11 @@ module.exports = class extends Generator { if( this.options.genSwagger ) { this.fs.delete(this.destinationPath('server/routers/public.js')); } - else { + else { this.fs.copy(this.templatePath('public/index.html'), this.destinationPath('public/index.html')); } - // blank project is stripped down to bare minimum + // blank project is stripped down to bare minimum if(this.options.spec && this.options.spec.applicationType === 'BLANK') { this.fs.delete(this.destinationPath('server/routers/health.js')); } @@ -153,12 +157,12 @@ module.exports = class extends Generator { return name.toLowerCase().replace(REGEX_LEADING_ALPHA, '').replace(REGEX_ALPHA_NUM, ''); } - // return true if 'sanitized', false if missing, exception if bad data + // return true if 'sanitized', false if missing, exception if bad data _sanitizeOption(options, name) { let optionValue = options[name]; if (!optionValue) { logger.error("Missing", name, "parameter"); - return false; + return false; } if (typeof optionValue === "string" && optionValue.indexOf("file:") === 0) { @@ -166,16 +170,16 @@ module.exports = class extends Generator { let filePath = this.destinationPath("./" + fileName); logger.info("Reading", name, "parameter from local file", filePath); this.options[name] = this.fs.readJSON(filePath); - return true; + return true; } try { this.options[name] = typeof(this.options[name]) === "string" ? JSON.parse(this.options[name]) : this.options[name]; - return true; + return true; } catch (e) { logger.error(e); throw name + " parameter is expected to be a valid stringified JSON object"; - } + } } -}; \ No newline at end of file +}; diff --git a/app/templates/public/swagger-ui/swagger-ui.js b/app/templates/public/swagger-ui/swagger-ui.js index c5d7c98..3547b31 100644 --- a/app/templates/public/swagger-ui/swagger-ui.js +++ b/app/templates/public/swagger-ui/swagger-ui.js @@ -2233,12 +2233,12 @@ window.Docs = { var hour = originalGetUTCHours(this); var minute = originalGetUTCMinutes(this); var second = originalGetUTCSeconds(this); - return dayName[day] + ', ' + - (date < 10 ? '0' + date : date) + ' ' + - monthName[month] + ' ' + - year + ' ' + - (hour < 10 ? '0' + hour : hour) + ':' + - (minute < 10 ? '0' + minute : minute) + ':' + + return dayName[day] + ', ' + (date < 10 ? '0' + date : date) + ' ' + monthName[month] + ' ' + year + ' ' + (hour < 10 ? '0' + hour : hour) + ':' + (minute < 10 ? '0' + minute : minute) + ':' (second < 10 ? '0' + second : second) + ' GMT'; } }, hasNegativeMonthYearBug || hasToUTCStringFormatBug); @@ -2253,9 +2253,9 @@ window.Docs = { var date = this.getDate(); var month = this.getMonth(); var year = this.getFullYear(); - return dayName[day] + ' ' + - monthName[month] + ' ' + - (date < 10 ? '0' + date : date) + ' ' + + return dayName[day] + ' ' + monthName[month] + ' ' + (date < 10 ? '0' + date : date) + ' ' year; } }, hasNegativeMonthYearBug || hasToDateStringFormatBug); @@ -2276,15 +2276,15 @@ window.Docs = { var timezoneOffset = this.getTimezoneOffset(); var hoursOffset = Math.floor(Math.abs(timezoneOffset) / 60); var minutesOffset = Math.floor(Math.abs(timezoneOffset) % 60); - return dayName[day] + ' ' + - monthName[month] + ' ' + - (date < 10 ? '0' + date : date) + ' ' + - year + ' ' + - (hour < 10 ? '0' + hour : hour) + ':' + - (minute < 10 ? '0' + minute : minute) + ':' + - (second < 10 ? '0' + second : second) + ' GMT' + - (timezoneOffset > 0 ? '-' : '+') + - (hoursOffset < 10 ? '0' + hoursOffset : hoursOffset) + + return dayName[day] + ' ' + monthName[month] + ' ' + (date < 10 ? '0' + date : date) + ' ' + year + ' ' + (hour < 10 ? '0' + hour : hour) + ':' + (minute < 10 ? '0' + minute : minute) + ':' + (second < 10 ? '0' + second : second) + ' GMT' + (timezoneOffset > 0 ? '-' : '+') + (hoursOffset < 10 ? '0' + hoursOffset : hoursOffset) (minutesOffset < 10 ? '0' + minutesOffset : minutesOffset); }; if (supportsDescriptors) { @@ -2327,7 +2327,7 @@ window.Docs = { // the date time string format is specified in 15.9.1.15. var result = [month + 1, originalGetUTCDate(this), originalGetUTCHours(this), originalGetUTCMinutes(this), originalGetUTCSeconds(this)]; year = ( - (year < 0 ? '-' : (year > 9999 ? '+' : '')) + + (year < 0 ? '-' : (year > 9999 ? '+' : '')) strSlice('00000' + Math.abs(year), (0 <= year && year <= 9999) ? -4 : -6) ); @@ -2337,8 +2337,8 @@ window.Docs = { } // pad milliseconds to have three digits. return ( - year + '-' + arraySlice(result, 0, 2).join('-') + - 'T' + arraySlice(result, 2).join(':') + '.' + + year + '-' + arraySlice(result, 0, 2).join('-') + 'T' + arraySlice(result, 2).join(':') + '.' strSlice('000' + originalGetUTCMilliseconds(this), -3) + 'Z' ); } @@ -2452,8 +2452,8 @@ window.Docs = { }; // 15.9.1.15 Date Time String Format. - var isoDateExpression = new RegExp('^' + - '(\\d{4}|[+-]\\d{6})' + // four-digit year capture or sign + + var isoDateExpression = new RegExp('^' + '(\\d{4}|[+-]\\d{6})' + // four-digit year capture or sign // 6-digit extended year '(?:-(\\d{2})' + // optional month capture '(?:-(\\d{2})' + // optional day capture @@ -2463,15 +2463,15 @@ window.Docs = { '(?:' + // optional :seconds.milliseconds ':(\\d{2})' + // seconds capture '(?:(\\.\\d{1,}))?' + // milliseconds capture - ')?' + + ')?' '(' + // capture UTC offset component 'Z|' + // UTC capture '(?:' + // offset specifier +/-hours:minutes '([-+])' + // sign capture '(\\d{2})' + // hours offset capture ':(\\d{2})' + // minutes offset capture - ')' + - ')?)?)?)?' + + ')' + ')?)?)?)?' '$'); var months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365]; @@ -2479,10 +2479,10 @@ window.Docs = { var dayFromMonth = function dayFromMonth(year, month) { var t = month > 1 ? 1 : 0; return ( - months[month] + + months[month] Math.floor((year - 1969 + t) / 4) - - Math.floor((year - 1901 + t) / 100) + - Math.floor((year - 1601 + t) / 400) + + Math.floor((year - 1901 + t) / 100) + Math.floor((year - 1601 + t) / 400) 365 * (year - 1970) ); }; @@ -2549,12 +2549,12 @@ window.Docs = { day < (dayFromMonth(year, month + 1) - dayFromMonth(year, month)) ) { result = ( - (dayFromMonth(year, month) + day) * 24 + - hour + + (dayFromMonth(year, month) + day) * 24 + hour hourOffset * signOffset ) * 60; result = ( - (result + minute + minuteOffset * signOffset) * 60 + + (result + minute + minuteOffset * signOffset) * 60 second ) * 1000 + millisecond; if (isLocalTime) { @@ -2795,8 +2795,8 @@ window.Docs = { } var output = []; - var flags = (separator.ignoreCase ? 'i' : '') + - (separator.multiline ? 'm' : '') + + var flags = (separator.ignoreCase ? 'i' : '') + (separator.multiline ? 'm' : '') (separator.unicode ? 'u' : '') + // in ES6 (separator.sticky ? 'y' : ''), // Firefox 3+ and ES6 lastLastIndex = 0, @@ -2923,8 +2923,8 @@ window.Docs = { // ES5 15.5.4.20 // whitespace from: http://es5.github.io/#x15.5.4.20 - var ws = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' + - '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028' + + var ws = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' + '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028' '\u2029\uFEFF'; var zeroWidth = '\u200b'; var wsRegexChars = '[' + ws + ']'; @@ -3852,18 +3852,18 @@ SwaggerClient.prototype.buildFromSpec = function (response) { var operationGroup = self[clientProperty]; if (clientProperty !== tag) { - helpers.log('The \'' + tag + '\' tag conflicts with a SwaggerClient function/property name. Use \'client.' + + helpers.log('The \'' + tag + '\' tag conflicts with a SwaggerClient function/property name. Use \'client.' clientProperty + '\' or \'client.apis.' + tag + '\' instead of \'client.' + tag + '\'.'); } if (apiProperty !== tag) { - helpers.log('The \'' + tag + '\' tag conflicts with a SwaggerClient operation function/property name. Use ' + + helpers.log('The \'' + tag + '\' tag conflicts with a SwaggerClient operation function/property name. Use ' '\'client.apis.' + apiProperty + '\' instead of \'client.apis.' + tag + '\'.'); } if (_.indexOf(reservedApiTags, operationId) > -1) { - helpers.log('The \'' + operationId + '\' operationId conflicts with a SwaggerClient operation ' + - 'function/property name. Use \'client.apis.' + apiProperty + '._' + operationId + + helpers.log('The \'' + operationId + '\' operationId conflicts with a SwaggerClient operation ' + 'function/property name. Use \'client.apis.' + apiProperty + '._' + operationId '\' instead of \'client.apis.' + apiProperty + '.' + operationId + '\'.'); operationId = '_' + operationId; @@ -8295,7 +8295,7 @@ function checked (length) { // Note: cannot use `length < kMaxLength` here because that fails when // length is NaN (which is otherwise coerced to zero.) if (length >= kMaxLength()) { - throw new RangeError('Attempt to allocate Buffer larger than maximum ' + + throw new RangeError('Attempt to allocate Buffer larger than maximum ' 'size: 0x' + kMaxLength().toString(16) + ' bytes') } return length | 0 @@ -8919,14 +8919,14 @@ Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { return ((this[offset]) | (this[offset + 1] << 8) | - (this[offset + 2] << 16)) + + (this[offset + 2] << 16)) (this[offset + 3] * 0x1000000) } Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { if (!noAssert) checkOffset(offset, 4, this.length) - return (this[offset] * 0x1000000) + + return (this[offset] * 0x1000000) ((this[offset + 1] << 16) | (this[offset + 2] << 8) | this[offset + 3]) @@ -12703,7 +12703,7 @@ Mark.prototype.getSnippet = function getSnippet(indent, maxLength) { snippet = this.buffer.slice(start, end); - return common.repeat(' ', indent) + head + snippet + tail + '\n' + + return common.repeat(' ', indent) + head + snippet + tail + '\n' common.repeat(' ', indent + this.position - start + head.length) + '^'; }; @@ -13204,10 +13204,10 @@ var common = require('../common'); var Type = require('../type'); var YAML_FLOAT_PATTERN = new RegExp( - '^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?' + - '|\\.[0-9_]+(?:[eE][-+][0-9]+)?' + - '|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*' + - '|[-+]?\\.(?:inf|Inf|INF)' + + '^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?' + '|\\.[0-9_]+(?:[eE][-+][0-9]+)?' + '|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*' + '|[-+]?\\.(?:inf|Inf|INF)' '|\\.(?:nan|NaN|NAN))$'); function resolveYamlFloat(data) { @@ -14492,7 +14492,7 @@ var nativeMax = Math.max; * @example * * var say = _.restParam(function(what, names) { - * return what + ' ' + _.initial(names).join(', ') + + * return what + ' ' + _.initial(names).join(', ') * (_.size(names) > 1 ? ', & ' : '') + _.last(names); * }); * @@ -17429,7 +17429,7 @@ var fnToString = Function.prototype.toString; var hasOwnProperty = objectProto.hasOwnProperty; /** Used to detect if a method is native. */ -var reIsNative = RegExp('^' + +var reIsNative = RegExp('^' fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' ); @@ -18617,7 +18617,7 @@ function deprecate(callback, name, alternative) { return function () { if (typeof console !== "undefined" && typeof console.warn === "function") { - console.warn(name + " is deprecated, use " + alternative + + console.warn(name + " is deprecated, use " + alternative " instead.", new Error("").stack); } return callback.apply(callback, arguments); @@ -19770,7 +19770,7 @@ function any(promises) { pendingCount--; if (pendingCount === 0) { deferred.reject(new Error( - "Can't get fulfillment value from any promise, all " + + "Can't get fulfillment value from any promise, all " "promises were rejected." )); } diff --git a/app/templates/server/config/local.json b/app/templates/server/config/local.json index b56246b..8fb2c57 100644 --- a/app/templates/server/config/local.json +++ b/app/templates/server/config/local.json @@ -1,3 +1,3 @@ { - "port": 3000 + "port": 3000 } \ No newline at end of file diff --git a/app/templates/server/routers/public.js b/app/templates/server/routers/public.js index c1c704e..a7f8aab 100644 --- a/app/templates/server/routers/public.js +++ b/app/templates/server/routers/public.js @@ -1,7 +1,7 @@ var express = require('express'); module.exports = function(app){ - var router = express.Router(); - router.use(express.static(process.cwd() + '/public')); - app.use(router); + var router = express.Router(); + router.use(express.static(process.cwd() + '/public')); + app.use(router); } diff --git a/app/templates/server/server.js b/app/templates/server/server.js index f5d49bd..08f07ee 100644 --- a/app/templates/server/server.js +++ b/app/templates/server/server.js @@ -14,12 +14,12 @@ require('./routers/index')(app); const port = process.env.PORT || localConfig.port; app.listen(port, function(){ - logger.info(`<%= bluemix.name %> listening on http://localhost:${port}/appmetrics-dash`); - <% if( !genSwagger ){ %> - logger.info(`<%= bluemix.name %> listening on http://localhost:${port}`); - <% } %> - <% if( genSwagger ){ %> - logger.info(`OpenAPI (Swagger) spec is available at http://localhost:${port}/swagger/api`); - logger.info(`Swagger UI is available at http://localhost:${port}/explorer`); - <% } %> + logger.info(`<%= bluemix.name %> listening on http://localhost:${port}/appmetrics-dash`); + <% if( !genSwagger ){ %> + logger.info(`<%= bluemix.name %> listening on http://localhost:${port}`); + <% } %> + <% if( genSwagger ){ %> + logger.info(`OpenAPI (Swagger) spec is available at http://localhost:${port}/swagger/api`); + logger.info(`Swagger UI is available at http://localhost:${port}/explorer`); + <% } %> }); \ No newline at end of file diff --git a/lib/helpers.js b/lib/helpers.js index d36b632..a1dfa5e 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -22,6 +22,6 @@ exports.reformatPathToNodeExpress = (path) => path.replace(/{/g, ':').replace(/}/g, '') exports.resourceNameFromPath = function (path) { - // grab the first valid element of a path (or partial path) and return it. - return path.match(/^\/*([^/]+)/)[1] + // grab the first valid element of a path (or partial path) and return it. + return path.match(/^\/*([^/]+)/)[1] } From c8c325a9ffdd2e5799fee8cf4374cbe9fe22dd54 Mon Sep 17 00:00:00 2001 From: Gibson Fahnestock Date: Tue, 26 Sep 2017 20:16:42 +0100 Subject: [PATCH 04/12] Add idt.js script and related npm run scripts Allows user to install and run idt through `npm run` scripts. --- app/index.js | 1 + app/templates/idt.js | 77 ++++++++++++++++++++++++++++++++++++++ app/templates/package.json | 14 ++++++- 3 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 app/templates/idt.js diff --git a/app/index.js b/app/index.js index dd7ad72..2d1cae5 100644 --- a/app/index.js +++ b/app/index.js @@ -119,6 +119,7 @@ module.exports = class extends Generator { this.fs.copyTpl(this.templatePath('Dockerfile-tools'), this.destinationPath('Dockerfile-tools'), this.options); this.fs.copyTpl(this.templatePath('package.json'), this.destinationPath('package.json'), this.options); this.fs.copyTpl(this.templatePath('README.md'), this.destinationPath('README.md'), this.options); + this.fs.copyTpl(this.templatePath('idt.js'), this.destinationPath('idt.js'), this.options); // if project will have swagger doc, ensure swagger ui and api route if ( this.options.genSwagger ) { diff --git a/app/templates/idt.js b/app/templates/idt.js new file mode 100644 index 0000000..c4b9b1d --- /dev/null +++ b/app/templates/idt.js @@ -0,0 +1,77 @@ +const fs = require('fs'); +const process = require('process'); +const cp = require('child_process'); +const request = require('request'); +const path = require('path'); + +const chalk = require('chalk'); + +const node = process.execPath; +// Array of args passed to idt.js. +const args = process.argv.slice(2); +let win = (process.platform === 'win32'); + +// Either install idt or run bx dev. +if (args.includes('install')) { + downloadInstaller(); +} else { + // TODO(gib): Check for idt once this works in scripts. + // const checkCmd = win ? 'where idt' : 'which idt'; + const checkCmd = 'bx plugin show dev'; + let hasIDT = false; + try { + console.log(chalk.blue('Checking for idt')); + cp.execSync(checkCmd); // Don't inherit stdio, we don't want to print the path. + hasIDT = true; // If we didn't have idt, the previous command would have thrown. + } catch (e) { + const prompt = require('prompt-confirm'); + new prompt({ name: 'install', + message: 'IDT not found, do you want to install it? y/N', + default: false + }).ask((answer) => { + if (answer) { + downloadInstaller(() => runIDT(args)); + } else { + console.error(chalk.red(`Not installing idt, so not running: idt ${args.join(' ')}`)); + } + }); + } + if (hasIDT) runIDT(args); +} + +// Run IDT with whatever args we were given. +function runIDT(args) { + const cmd = 'bx dev ' + args.join(' '); + console.log(chalk.blue('Running:'), cmd); + cp.execSync(cmd, {stdio: 'inherit'}); +} + +// Download the IDT installer script and trigger run. +function downloadInstaller(cb) { + const url = win ? + 'http://ibm.biz/idt-win-installer' : + 'https://ibm.biz/idt-installer'; + + const fileName = url.split('/').pop() + + console.log(chalk.blue('Downloading installer from:'), url); + + const file = fs.createWriteStream(fileName); + + request + .get({url, followAllRedirects: true}) + .on('error', (err) => { console.error(err); }) + .pipe(file) + .on('finish', () => runInstaller(fileName, cb)); +} + +// Run the installer script and trigger callback (cb). +function runInstaller(fileName, cb) { + const shell = win ? 'powershell.exe' : 'bash'; + + const filePath = path.resolve(__dirname, fileName); + console.log(`Now running: ${shell} ${filePath}`); + + cp.spawnSync(shell, [filePath], {stdio: 'inherit'}); + cb(); +} diff --git a/app/templates/package.json b/app/templates/package.json index aa16e38..0ce38b6 100644 --- a/app/templates/package.json +++ b/app/templates/package.json @@ -10,7 +10,14 @@ "start": "node server/server.js", "start:cluster": "sl-run server/server.js", "debug": "node --debug server/server.js", - "test": "nyc mocha" + "test": "nyc mocha", + "build": "npm run build:idt", + "build:idt": "node idt.js build", + "test:idt": "node idt.js test", + "debug:idt": "node idt.js debug", + "run:idt": "node idt.js run", + "deploy:idt": "node idt.js deploy", + "install:idt": "node idt.js install" }, "dependencies": { "appmetrics-dash": "^3.3.2", @@ -21,8 +28,11 @@ }, "devDependencies": { "chai": "^4.0.0", + "chalk": "^1.1.3", "mocha": "^3.4.2", "nyc": "^10.3.2", - "proxyquire": "^1.8.0" + "prompt-confirm": "^1.2.0", + "proxyquire": "^1.8.0", + "request": "^2.82.0" } } From a219a38838ff9932a4104bfc6c6360bfad660478 Mon Sep 17 00:00:00 2001 From: cvignola Date: Thu, 28 Sep 2017 13:01:02 +0000 Subject: [PATCH 05/12] [Travis - npm version patch] Increment package version to 0.0.61 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9fa5077..3490d1d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "generator-ibm-core-node-express", - "version": "0.0.60", + "version": "0.0.61", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index e418892..7bb5762 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "generator-ibm-core-node-express", - "version": "0.0.60", + "version": "0.0.61", "description": "Yeoman generator for core node express application", "license": "Apache-2.0", "keywords": [ From 790ed52685bab8a618a93eef0b0d68fec2f1e708 Mon Sep 17 00:00:00 2001 From: Adam Roberts Date: Thu, 28 Sep 2017 14:42:41 +0100 Subject: [PATCH 06/12] appmetrics-dash in the test name --- test/integration.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration.js b/test/integration.js index 7ff6252..3aa84c3 100644 --- a/test/integration.js +++ b/test/integration.js @@ -188,7 +188,7 @@ describe('core-node-express:app integration test with custom bluemix', function }); describe(common.file.server_js, () => { - it('contains appmetrics attach', () => { + it('contains appmetrics-dash attach', () => { assert.fileContent(common.file.server_js, "require('appmetrics-dash').attach();") }); }); From cce41eb883342aa9adac951a3903224a9cfb83df Mon Sep 17 00:00:00 2001 From: Gibson Fahnestock Date: Thu, 28 Sep 2017 16:15:16 +0100 Subject: [PATCH 07/12] Revert "Add idt.js script and related npm run scripts" --- app/index.js | 53 ++++----- app/templates/idt.js | 77 ------------- app/templates/package.json | 14 +-- app/templates/public/swagger-ui/swagger-ui.js | 104 +++++++++--------- app/templates/server/config/local.json | 2 +- app/templates/server/routers/public.js | 6 +- app/templates/server/server.js | 16 +-- lib/helpers.js | 4 +- 8 files changed, 92 insertions(+), 184 deletions(-) delete mode 100644 app/templates/idt.js diff --git a/app/index.js b/app/index.js index 2d1cae5..fbd0651 100644 --- a/app/index.js +++ b/app/index.js @@ -29,10 +29,6 @@ module.exports = class extends Generator { constructor(args, opts) { super(args, opts); - if ( typeof opts.bluemix.quiet == "undefined" || ! opts.bluemix.quiet ) { - logger.info("Package info ::", Bundle.name, Bundle.version); - } - // bluemix option for YaaS integration this.argument(OPTION_BLUEMIX, { desc: 'Option for deploying with Bluemix. Stringified JSON.', @@ -54,16 +50,16 @@ module.exports = class extends Generator { this.skipPrompt = true; let bluemix_ok= this._sanitizeOption(this.options, OPTION_BLUEMIX); let spec_ok= this._sanitizeOption(this.options, OPTION_SPEC); - if ( ! (bluemix_ok || spec_ok )) throw ("Must specify either bluemix or spec parameter"); - - if ( typeof this.options.bluemix.quiet == "undefined" || ! this.options.bluemix.quiet ) { + if ( ! (bluemix_ok || spec_ok )) throw ("Must specify either bluemix or spec parameter"); + + if ( typeof this.options.bluemix.quiet == "undefined" || ! this.options.bluemix.quiet ) { logger.info("Package info ::", Bundle.name, Bundle.version); - } - + } + let appName = this.options.bluemix.name || this.options.spec.appname; this.options.sanitizedAppName = this._sanitizeAppName(appName); - this.options.genSwagger= false; - this.options.openApiFileType= "yaml"; // default + this.options.genSwagger= false; + this.options.openApiFileType= "yaml"; // default this.options.parsedSwagger = undefined; let formatters = { @@ -79,8 +75,8 @@ module.exports = class extends Generator { .then(response => { this.options.loadedApi = response.loaded; this.options.parsedSwagger = response.parsed; - this.options.openApiFileType= response.type; - this.options.genSwagger= true; + this.options.openApiFileType= response.type; + this.options.genSwagger= true; }) .catch(err => { err.message = 'failed to parse document from bluemix.openApiServers ' + err.message; @@ -88,9 +84,9 @@ module.exports = class extends Generator { }) } - // micro service always gets swagger ui and no public + // micro service always gets swagger ui and no public if(this.options.spec && this.options.spec.applicationType === 'MS') { - this.options.genSwagger= true; + this.options.genSwagger= true; } } @@ -119,23 +115,22 @@ module.exports = class extends Generator { this.fs.copyTpl(this.templatePath('Dockerfile-tools'), this.destinationPath('Dockerfile-tools'), this.options); this.fs.copyTpl(this.templatePath('package.json'), this.destinationPath('package.json'), this.options); this.fs.copyTpl(this.templatePath('README.md'), this.destinationPath('README.md'), this.options); - this.fs.copyTpl(this.templatePath('idt.js'), this.destinationPath('idt.js'), this.options); - // if project will have swagger doc, ensure swagger ui and api route + // if project will have swagger doc, ensure swagger ui and api route if ( this.options.genSwagger ) { this.fs.copy(this.templatePath('public/swagger-ui'), this.destinationPath('public/swagger-ui')); - // if open api doc provided, write it else write default + // if open api doc provided, write it else write default if ( this.options.loadedApi ) { let yaml= this.options.bluemix.openApiServers[0].spec; //this.fs.writeJSON('public/swagger.'+this.options.openApiFileType, this.options.loadedApi); - this.fs.write('public/swagger.'+this.options.openApiFileType, yaml); - } + this.fs.write('public/swagger.'+this.options.openApiFileType, yaml); + } else { this.fs.copyTpl(this.templatePath('public/swagger.yaml'), this.destinationPath('public/swagger.yaml'), this.options); } } - else { + else { this.fs.delete(this.destinationPath('server/routers/swagger.js')); } @@ -143,11 +138,11 @@ module.exports = class extends Generator { if( this.options.genSwagger ) { this.fs.delete(this.destinationPath('server/routers/public.js')); } - else { + else { this.fs.copy(this.templatePath('public/index.html'), this.destinationPath('public/index.html')); } - // blank project is stripped down to bare minimum + // blank project is stripped down to bare minimum if(this.options.spec && this.options.spec.applicationType === 'BLANK') { this.fs.delete(this.destinationPath('server/routers/health.js')); } @@ -158,12 +153,12 @@ module.exports = class extends Generator { return name.toLowerCase().replace(REGEX_LEADING_ALPHA, '').replace(REGEX_ALPHA_NUM, ''); } - // return true if 'sanitized', false if missing, exception if bad data + // return true if 'sanitized', false if missing, exception if bad data _sanitizeOption(options, name) { let optionValue = options[name]; if (!optionValue) { logger.error("Missing", name, "parameter"); - return false; + return false; } if (typeof optionValue === "string" && optionValue.indexOf("file:") === 0) { @@ -171,16 +166,16 @@ module.exports = class extends Generator { let filePath = this.destinationPath("./" + fileName); logger.info("Reading", name, "parameter from local file", filePath); this.options[name] = this.fs.readJSON(filePath); - return true; + return true; } try { this.options[name] = typeof(this.options[name]) === "string" ? JSON.parse(this.options[name]) : this.options[name]; - return true; + return true; } catch (e) { logger.error(e); throw name + " parameter is expected to be a valid stringified JSON object"; - } + } } -}; +}; \ No newline at end of file diff --git a/app/templates/idt.js b/app/templates/idt.js deleted file mode 100644 index c4b9b1d..0000000 --- a/app/templates/idt.js +++ /dev/null @@ -1,77 +0,0 @@ -const fs = require('fs'); -const process = require('process'); -const cp = require('child_process'); -const request = require('request'); -const path = require('path'); - -const chalk = require('chalk'); - -const node = process.execPath; -// Array of args passed to idt.js. -const args = process.argv.slice(2); -let win = (process.platform === 'win32'); - -// Either install idt or run bx dev. -if (args.includes('install')) { - downloadInstaller(); -} else { - // TODO(gib): Check for idt once this works in scripts. - // const checkCmd = win ? 'where idt' : 'which idt'; - const checkCmd = 'bx plugin show dev'; - let hasIDT = false; - try { - console.log(chalk.blue('Checking for idt')); - cp.execSync(checkCmd); // Don't inherit stdio, we don't want to print the path. - hasIDT = true; // If we didn't have idt, the previous command would have thrown. - } catch (e) { - const prompt = require('prompt-confirm'); - new prompt({ name: 'install', - message: 'IDT not found, do you want to install it? y/N', - default: false - }).ask((answer) => { - if (answer) { - downloadInstaller(() => runIDT(args)); - } else { - console.error(chalk.red(`Not installing idt, so not running: idt ${args.join(' ')}`)); - } - }); - } - if (hasIDT) runIDT(args); -} - -// Run IDT with whatever args we were given. -function runIDT(args) { - const cmd = 'bx dev ' + args.join(' '); - console.log(chalk.blue('Running:'), cmd); - cp.execSync(cmd, {stdio: 'inherit'}); -} - -// Download the IDT installer script and trigger run. -function downloadInstaller(cb) { - const url = win ? - 'http://ibm.biz/idt-win-installer' : - 'https://ibm.biz/idt-installer'; - - const fileName = url.split('/').pop() - - console.log(chalk.blue('Downloading installer from:'), url); - - const file = fs.createWriteStream(fileName); - - request - .get({url, followAllRedirects: true}) - .on('error', (err) => { console.error(err); }) - .pipe(file) - .on('finish', () => runInstaller(fileName, cb)); -} - -// Run the installer script and trigger callback (cb). -function runInstaller(fileName, cb) { - const shell = win ? 'powershell.exe' : 'bash'; - - const filePath = path.resolve(__dirname, fileName); - console.log(`Now running: ${shell} ${filePath}`); - - cp.spawnSync(shell, [filePath], {stdio: 'inherit'}); - cb(); -} diff --git a/app/templates/package.json b/app/templates/package.json index 0ce38b6..aa16e38 100644 --- a/app/templates/package.json +++ b/app/templates/package.json @@ -10,14 +10,7 @@ "start": "node server/server.js", "start:cluster": "sl-run server/server.js", "debug": "node --debug server/server.js", - "test": "nyc mocha", - "build": "npm run build:idt", - "build:idt": "node idt.js build", - "test:idt": "node idt.js test", - "debug:idt": "node idt.js debug", - "run:idt": "node idt.js run", - "deploy:idt": "node idt.js deploy", - "install:idt": "node idt.js install" + "test": "nyc mocha" }, "dependencies": { "appmetrics-dash": "^3.3.2", @@ -28,11 +21,8 @@ }, "devDependencies": { "chai": "^4.0.0", - "chalk": "^1.1.3", "mocha": "^3.4.2", "nyc": "^10.3.2", - "prompt-confirm": "^1.2.0", - "proxyquire": "^1.8.0", - "request": "^2.82.0" + "proxyquire": "^1.8.0" } } diff --git a/app/templates/public/swagger-ui/swagger-ui.js b/app/templates/public/swagger-ui/swagger-ui.js index 3547b31..c5d7c98 100644 --- a/app/templates/public/swagger-ui/swagger-ui.js +++ b/app/templates/public/swagger-ui/swagger-ui.js @@ -2233,12 +2233,12 @@ window.Docs = { var hour = originalGetUTCHours(this); var minute = originalGetUTCMinutes(this); var second = originalGetUTCSeconds(this); - return dayName[day] + ', ' - (date < 10 ? '0' + date : date) + ' ' - monthName[month] + ' ' - year + ' ' - (hour < 10 ? '0' + hour : hour) + ':' - (minute < 10 ? '0' + minute : minute) + ':' + return dayName[day] + ', ' + + (date < 10 ? '0' + date : date) + ' ' + + monthName[month] + ' ' + + year + ' ' + + (hour < 10 ? '0' + hour : hour) + ':' + + (minute < 10 ? '0' + minute : minute) + ':' + (second < 10 ? '0' + second : second) + ' GMT'; } }, hasNegativeMonthYearBug || hasToUTCStringFormatBug); @@ -2253,9 +2253,9 @@ window.Docs = { var date = this.getDate(); var month = this.getMonth(); var year = this.getFullYear(); - return dayName[day] + ' ' - monthName[month] + ' ' - (date < 10 ? '0' + date : date) + ' ' + return dayName[day] + ' ' + + monthName[month] + ' ' + + (date < 10 ? '0' + date : date) + ' ' + year; } }, hasNegativeMonthYearBug || hasToDateStringFormatBug); @@ -2276,15 +2276,15 @@ window.Docs = { var timezoneOffset = this.getTimezoneOffset(); var hoursOffset = Math.floor(Math.abs(timezoneOffset) / 60); var minutesOffset = Math.floor(Math.abs(timezoneOffset) % 60); - return dayName[day] + ' ' - monthName[month] + ' ' - (date < 10 ? '0' + date : date) + ' ' - year + ' ' - (hour < 10 ? '0' + hour : hour) + ':' - (minute < 10 ? '0' + minute : minute) + ':' - (second < 10 ? '0' + second : second) + ' GMT' - (timezoneOffset > 0 ? '-' : '+') - (hoursOffset < 10 ? '0' + hoursOffset : hoursOffset) + return dayName[day] + ' ' + + monthName[month] + ' ' + + (date < 10 ? '0' + date : date) + ' ' + + year + ' ' + + (hour < 10 ? '0' + hour : hour) + ':' + + (minute < 10 ? '0' + minute : minute) + ':' + + (second < 10 ? '0' + second : second) + ' GMT' + + (timezoneOffset > 0 ? '-' : '+') + + (hoursOffset < 10 ? '0' + hoursOffset : hoursOffset) + (minutesOffset < 10 ? '0' + minutesOffset : minutesOffset); }; if (supportsDescriptors) { @@ -2327,7 +2327,7 @@ window.Docs = { // the date time string format is specified in 15.9.1.15. var result = [month + 1, originalGetUTCDate(this), originalGetUTCHours(this), originalGetUTCMinutes(this), originalGetUTCSeconds(this)]; year = ( - (year < 0 ? '-' : (year > 9999 ? '+' : '')) + (year < 0 ? '-' : (year > 9999 ? '+' : '')) + strSlice('00000' + Math.abs(year), (0 <= year && year <= 9999) ? -4 : -6) ); @@ -2337,8 +2337,8 @@ window.Docs = { } // pad milliseconds to have three digits. return ( - year + '-' + arraySlice(result, 0, 2).join('-') - 'T' + arraySlice(result, 2).join(':') + '.' + year + '-' + arraySlice(result, 0, 2).join('-') + + 'T' + arraySlice(result, 2).join(':') + '.' + strSlice('000' + originalGetUTCMilliseconds(this), -3) + 'Z' ); } @@ -2452,8 +2452,8 @@ window.Docs = { }; // 15.9.1.15 Date Time String Format. - var isoDateExpression = new RegExp('^' - '(\\d{4}|[+-]\\d{6})' + // four-digit year capture or sign + var isoDateExpression = new RegExp('^' + + '(\\d{4}|[+-]\\d{6})' + // four-digit year capture or sign + // 6-digit extended year '(?:-(\\d{2})' + // optional month capture '(?:-(\\d{2})' + // optional day capture @@ -2463,15 +2463,15 @@ window.Docs = { '(?:' + // optional :seconds.milliseconds ':(\\d{2})' + // seconds capture '(?:(\\.\\d{1,}))?' + // milliseconds capture - ')?' + ')?' + '(' + // capture UTC offset component 'Z|' + // UTC capture '(?:' + // offset specifier +/-hours:minutes '([-+])' + // sign capture '(\\d{2})' + // hours offset capture ':(\\d{2})' + // minutes offset capture - ')' - ')?)?)?)?' + ')' + + ')?)?)?)?' + '$'); var months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365]; @@ -2479,10 +2479,10 @@ window.Docs = { var dayFromMonth = function dayFromMonth(year, month) { var t = month > 1 ? 1 : 0; return ( - months[month] + months[month] + Math.floor((year - 1969 + t) / 4) - - Math.floor((year - 1901 + t) / 100) - Math.floor((year - 1601 + t) / 400) + Math.floor((year - 1901 + t) / 100) + + Math.floor((year - 1601 + t) / 400) + 365 * (year - 1970) ); }; @@ -2549,12 +2549,12 @@ window.Docs = { day < (dayFromMonth(year, month + 1) - dayFromMonth(year, month)) ) { result = ( - (dayFromMonth(year, month) + day) * 24 - hour + (dayFromMonth(year, month) + day) * 24 + + hour + hourOffset * signOffset ) * 60; result = ( - (result + minute + minuteOffset * signOffset) * 60 + (result + minute + minuteOffset * signOffset) * 60 + second ) * 1000 + millisecond; if (isLocalTime) { @@ -2795,8 +2795,8 @@ window.Docs = { } var output = []; - var flags = (separator.ignoreCase ? 'i' : '') - (separator.multiline ? 'm' : '') + var flags = (separator.ignoreCase ? 'i' : '') + + (separator.multiline ? 'm' : '') + (separator.unicode ? 'u' : '') + // in ES6 (separator.sticky ? 'y' : ''), // Firefox 3+ and ES6 lastLastIndex = 0, @@ -2923,8 +2923,8 @@ window.Docs = { // ES5 15.5.4.20 // whitespace from: http://es5.github.io/#x15.5.4.20 - var ws = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' - '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028' + var ws = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' + + '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028' + '\u2029\uFEFF'; var zeroWidth = '\u200b'; var wsRegexChars = '[' + ws + ']'; @@ -3852,18 +3852,18 @@ SwaggerClient.prototype.buildFromSpec = function (response) { var operationGroup = self[clientProperty]; if (clientProperty !== tag) { - helpers.log('The \'' + tag + '\' tag conflicts with a SwaggerClient function/property name. Use \'client.' + helpers.log('The \'' + tag + '\' tag conflicts with a SwaggerClient function/property name. Use \'client.' + clientProperty + '\' or \'client.apis.' + tag + '\' instead of \'client.' + tag + '\'.'); } if (apiProperty !== tag) { - helpers.log('The \'' + tag + '\' tag conflicts with a SwaggerClient operation function/property name. Use ' + helpers.log('The \'' + tag + '\' tag conflicts with a SwaggerClient operation function/property name. Use ' + '\'client.apis.' + apiProperty + '\' instead of \'client.apis.' + tag + '\'.'); } if (_.indexOf(reservedApiTags, operationId) > -1) { - helpers.log('The \'' + operationId + '\' operationId conflicts with a SwaggerClient operation ' - 'function/property name. Use \'client.apis.' + apiProperty + '._' + operationId + helpers.log('The \'' + operationId + '\' operationId conflicts with a SwaggerClient operation ' + + 'function/property name. Use \'client.apis.' + apiProperty + '._' + operationId + '\' instead of \'client.apis.' + apiProperty + '.' + operationId + '\'.'); operationId = '_' + operationId; @@ -8295,7 +8295,7 @@ function checked (length) { // Note: cannot use `length < kMaxLength` here because that fails when // length is NaN (which is otherwise coerced to zero.) if (length >= kMaxLength()) { - throw new RangeError('Attempt to allocate Buffer larger than maximum ' + throw new RangeError('Attempt to allocate Buffer larger than maximum ' + 'size: 0x' + kMaxLength().toString(16) + ' bytes') } return length | 0 @@ -8919,14 +8919,14 @@ Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { return ((this[offset]) | (this[offset + 1] << 8) | - (this[offset + 2] << 16)) + (this[offset + 2] << 16)) + (this[offset + 3] * 0x1000000) } Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { if (!noAssert) checkOffset(offset, 4, this.length) - return (this[offset] * 0x1000000) + return (this[offset] * 0x1000000) + ((this[offset + 1] << 16) | (this[offset + 2] << 8) | this[offset + 3]) @@ -12703,7 +12703,7 @@ Mark.prototype.getSnippet = function getSnippet(indent, maxLength) { snippet = this.buffer.slice(start, end); - return common.repeat(' ', indent) + head + snippet + tail + '\n' + return common.repeat(' ', indent) + head + snippet + tail + '\n' + common.repeat(' ', indent + this.position - start + head.length) + '^'; }; @@ -13204,10 +13204,10 @@ var common = require('../common'); var Type = require('../type'); var YAML_FLOAT_PATTERN = new RegExp( - '^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?' - '|\\.[0-9_]+(?:[eE][-+][0-9]+)?' - '|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*' - '|[-+]?\\.(?:inf|Inf|INF)' + '^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?' + + '|\\.[0-9_]+(?:[eE][-+][0-9]+)?' + + '|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*' + + '|[-+]?\\.(?:inf|Inf|INF)' + '|\\.(?:nan|NaN|NAN))$'); function resolveYamlFloat(data) { @@ -14492,7 +14492,7 @@ var nativeMax = Math.max; * @example * * var say = _.restParam(function(what, names) { - * return what + ' ' + _.initial(names).join(', ') + * return what + ' ' + _.initial(names).join(', ') + * (_.size(names) > 1 ? ', & ' : '') + _.last(names); * }); * @@ -17429,7 +17429,7 @@ var fnToString = Function.prototype.toString; var hasOwnProperty = objectProto.hasOwnProperty; /** Used to detect if a method is native. */ -var reIsNative = RegExp('^' +var reIsNative = RegExp('^' + fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' ); @@ -18617,7 +18617,7 @@ function deprecate(callback, name, alternative) { return function () { if (typeof console !== "undefined" && typeof console.warn === "function") { - console.warn(name + " is deprecated, use " + alternative + console.warn(name + " is deprecated, use " + alternative + " instead.", new Error("").stack); } return callback.apply(callback, arguments); @@ -19770,7 +19770,7 @@ function any(promises) { pendingCount--; if (pendingCount === 0) { deferred.reject(new Error( - "Can't get fulfillment value from any promise, all " + "Can't get fulfillment value from any promise, all " + "promises were rejected." )); } diff --git a/app/templates/server/config/local.json b/app/templates/server/config/local.json index 8fb2c57..b56246b 100644 --- a/app/templates/server/config/local.json +++ b/app/templates/server/config/local.json @@ -1,3 +1,3 @@ { - "port": 3000 + "port": 3000 } \ No newline at end of file diff --git a/app/templates/server/routers/public.js b/app/templates/server/routers/public.js index a7f8aab..c1c704e 100644 --- a/app/templates/server/routers/public.js +++ b/app/templates/server/routers/public.js @@ -1,7 +1,7 @@ var express = require('express'); module.exports = function(app){ - var router = express.Router(); - router.use(express.static(process.cwd() + '/public')); - app.use(router); + var router = express.Router(); + router.use(express.static(process.cwd() + '/public')); + app.use(router); } diff --git a/app/templates/server/server.js b/app/templates/server/server.js index 08f07ee..f5d49bd 100644 --- a/app/templates/server/server.js +++ b/app/templates/server/server.js @@ -14,12 +14,12 @@ require('./routers/index')(app); const port = process.env.PORT || localConfig.port; app.listen(port, function(){ - logger.info(`<%= bluemix.name %> listening on http://localhost:${port}/appmetrics-dash`); - <% if( !genSwagger ){ %> - logger.info(`<%= bluemix.name %> listening on http://localhost:${port}`); - <% } %> - <% if( genSwagger ){ %> - logger.info(`OpenAPI (Swagger) spec is available at http://localhost:${port}/swagger/api`); - logger.info(`Swagger UI is available at http://localhost:${port}/explorer`); - <% } %> + logger.info(`<%= bluemix.name %> listening on http://localhost:${port}/appmetrics-dash`); + <% if( !genSwagger ){ %> + logger.info(`<%= bluemix.name %> listening on http://localhost:${port}`); + <% } %> + <% if( genSwagger ){ %> + logger.info(`OpenAPI (Swagger) spec is available at http://localhost:${port}/swagger/api`); + logger.info(`Swagger UI is available at http://localhost:${port}/explorer`); + <% } %> }); \ No newline at end of file diff --git a/lib/helpers.js b/lib/helpers.js index a1dfa5e..d36b632 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -22,6 +22,6 @@ exports.reformatPathToNodeExpress = (path) => path.replace(/{/g, ':').replace(/}/g, '') exports.resourceNameFromPath = function (path) { - // grab the first valid element of a path (or partial path) and return it. - return path.match(/^\/*([^/]+)/)[1] + // grab the first valid element of a path (or partial path) and return it. + return path.match(/^\/*([^/]+)/)[1] } From 7761fb7ddcd711fa3548a052291233619115e992 Mon Sep 17 00:00:00 2001 From: cvignola Date: Thu, 28 Sep 2017 17:34:18 +0000 Subject: [PATCH 08/12] [Travis - npm version patch] Increment package version to 0.0.62 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3490d1d..2b08111 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "generator-ibm-core-node-express", - "version": "0.0.61", + "version": "0.0.62", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 7bb5762..4d1f876 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "generator-ibm-core-node-express", - "version": "0.0.61", + "version": "0.0.62", "description": "Yeoman generator for core node express application", "license": "Apache-2.0", "keywords": [ From 7b0a609b8ffaf86eb847ff6fd9f8fbc489fedf53 Mon Sep 17 00:00:00 2001 From: Gibson Fahnestock Date: Tue, 26 Sep 2017 20:17:49 +0100 Subject: [PATCH 09/12] chore: tabs to spaces, remove trailing whitespace --- app/index.js | 48 +++++++++++++------------- app/templates/server/config/local.json | 2 +- app/templates/server/routers/public.js | 6 ++-- app/templates/server/server.js | 16 ++++----- lib/helpers.js | 4 +-- 5 files changed, 38 insertions(+), 38 deletions(-) diff --git a/app/index.js b/app/index.js index fbd0651..c9d2831 100644 --- a/app/index.js +++ b/app/index.js @@ -50,16 +50,16 @@ module.exports = class extends Generator { this.skipPrompt = true; let bluemix_ok= this._sanitizeOption(this.options, OPTION_BLUEMIX); let spec_ok= this._sanitizeOption(this.options, OPTION_SPEC); - if ( ! (bluemix_ok || spec_ok )) throw ("Must specify either bluemix or spec parameter"); - - if ( typeof this.options.bluemix.quiet == "undefined" || ! this.options.bluemix.quiet ) { + if ( ! (bluemix_ok || spec_ok )) throw ("Must specify either bluemix or spec parameter"); + + if ( typeof this.options.bluemix.quiet == "undefined" || ! this.options.bluemix.quiet ) { logger.info("Package info ::", Bundle.name, Bundle.version); - } - + } + let appName = this.options.bluemix.name || this.options.spec.appname; this.options.sanitizedAppName = this._sanitizeAppName(appName); - this.options.genSwagger= false; - this.options.openApiFileType= "yaml"; // default + this.options.genSwagger= false; + this.options.openApiFileType= "yaml"; // default this.options.parsedSwagger = undefined; let formatters = { @@ -75,8 +75,8 @@ module.exports = class extends Generator { .then(response => { this.options.loadedApi = response.loaded; this.options.parsedSwagger = response.parsed; - this.options.openApiFileType= response.type; - this.options.genSwagger= true; + this.options.openApiFileType= response.type; + this.options.genSwagger= true; }) .catch(err => { err.message = 'failed to parse document from bluemix.openApiServers ' + err.message; @@ -84,9 +84,9 @@ module.exports = class extends Generator { }) } - // micro service always gets swagger ui and no public + // micro service always gets swagger ui and no public if(this.options.spec && this.options.spec.applicationType === 'MS') { - this.options.genSwagger= true; + this.options.genSwagger= true; } } @@ -116,21 +116,21 @@ module.exports = class extends Generator { this.fs.copyTpl(this.templatePath('package.json'), this.destinationPath('package.json'), this.options); this.fs.copyTpl(this.templatePath('README.md'), this.destinationPath('README.md'), this.options); - // if project will have swagger doc, ensure swagger ui and api route + // if project will have swagger doc, ensure swagger ui and api route if ( this.options.genSwagger ) { this.fs.copy(this.templatePath('public/swagger-ui'), this.destinationPath('public/swagger-ui')); - // if open api doc provided, write it else write default + // if open api doc provided, write it else write default if ( this.options.loadedApi ) { let yaml= this.options.bluemix.openApiServers[0].spec; //this.fs.writeJSON('public/swagger.'+this.options.openApiFileType, this.options.loadedApi); - this.fs.write('public/swagger.'+this.options.openApiFileType, yaml); - } + this.fs.write('public/swagger.'+this.options.openApiFileType, yaml); + } else { this.fs.copyTpl(this.templatePath('public/swagger.yaml'), this.destinationPath('public/swagger.yaml'), this.options); } } - else { + else { this.fs.delete(this.destinationPath('server/routers/swagger.js')); } @@ -138,11 +138,11 @@ module.exports = class extends Generator { if( this.options.genSwagger ) { this.fs.delete(this.destinationPath('server/routers/public.js')); } - else { + else { this.fs.copy(this.templatePath('public/index.html'), this.destinationPath('public/index.html')); } - // blank project is stripped down to bare minimum + // blank project is stripped down to bare minimum if(this.options.spec && this.options.spec.applicationType === 'BLANK') { this.fs.delete(this.destinationPath('server/routers/health.js')); } @@ -153,12 +153,12 @@ module.exports = class extends Generator { return name.toLowerCase().replace(REGEX_LEADING_ALPHA, '').replace(REGEX_ALPHA_NUM, ''); } - // return true if 'sanitized', false if missing, exception if bad data + // return true if 'sanitized', false if missing, exception if bad data _sanitizeOption(options, name) { let optionValue = options[name]; if (!optionValue) { logger.error("Missing", name, "parameter"); - return false; + return false; } if (typeof optionValue === "string" && optionValue.indexOf("file:") === 0) { @@ -166,16 +166,16 @@ module.exports = class extends Generator { let filePath = this.destinationPath("./" + fileName); logger.info("Reading", name, "parameter from local file", filePath); this.options[name] = this.fs.readJSON(filePath); - return true; + return true; } try { this.options[name] = typeof(this.options[name]) === "string" ? JSON.parse(this.options[name]) : this.options[name]; - return true; + return true; } catch (e) { logger.error(e); throw name + " parameter is expected to be a valid stringified JSON object"; - } + } } -}; \ No newline at end of file +}; diff --git a/app/templates/server/config/local.json b/app/templates/server/config/local.json index b56246b..8fb2c57 100644 --- a/app/templates/server/config/local.json +++ b/app/templates/server/config/local.json @@ -1,3 +1,3 @@ { - "port": 3000 + "port": 3000 } \ No newline at end of file diff --git a/app/templates/server/routers/public.js b/app/templates/server/routers/public.js index c1c704e..a7f8aab 100644 --- a/app/templates/server/routers/public.js +++ b/app/templates/server/routers/public.js @@ -1,7 +1,7 @@ var express = require('express'); module.exports = function(app){ - var router = express.Router(); - router.use(express.static(process.cwd() + '/public')); - app.use(router); + var router = express.Router(); + router.use(express.static(process.cwd() + '/public')); + app.use(router); } diff --git a/app/templates/server/server.js b/app/templates/server/server.js index f5d49bd..08f07ee 100644 --- a/app/templates/server/server.js +++ b/app/templates/server/server.js @@ -14,12 +14,12 @@ require('./routers/index')(app); const port = process.env.PORT || localConfig.port; app.listen(port, function(){ - logger.info(`<%= bluemix.name %> listening on http://localhost:${port}/appmetrics-dash`); - <% if( !genSwagger ){ %> - logger.info(`<%= bluemix.name %> listening on http://localhost:${port}`); - <% } %> - <% if( genSwagger ){ %> - logger.info(`OpenAPI (Swagger) spec is available at http://localhost:${port}/swagger/api`); - logger.info(`Swagger UI is available at http://localhost:${port}/explorer`); - <% } %> + logger.info(`<%= bluemix.name %> listening on http://localhost:${port}/appmetrics-dash`); + <% if( !genSwagger ){ %> + logger.info(`<%= bluemix.name %> listening on http://localhost:${port}`); + <% } %> + <% if( genSwagger ){ %> + logger.info(`OpenAPI (Swagger) spec is available at http://localhost:${port}/swagger/api`); + logger.info(`Swagger UI is available at http://localhost:${port}/explorer`); + <% } %> }); \ No newline at end of file diff --git a/lib/helpers.js b/lib/helpers.js index d36b632..a1dfa5e 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -22,6 +22,6 @@ exports.reformatPathToNodeExpress = (path) => path.replace(/{/g, ':').replace(/}/g, '') exports.resourceNameFromPath = function (path) { - // grab the first valid element of a path (or partial path) and return it. - return path.match(/^\/*([^/]+)/)[1] + // grab the first valid element of a path (or partial path) and return it. + return path.match(/^\/*([^/]+)/)[1] } From 83b6fc7fa2f144ec64e5d8166bb7d1a3cef63adf Mon Sep 17 00:00:00 2001 From: Gibson Fahnestock Date: Tue, 26 Sep 2017 20:16:42 +0100 Subject: [PATCH 10/12] Add idt.js script and related npm run scripts Allows user to install and run idt through `npm run` scripts. --- app/index.js | 1 + app/templates/README.md | 16 ++++++- app/templates/idt.js | 89 ++++++++++++++++++++++++++++++++++++++ app/templates/package.json | 14 +++++- test/common.js | 3 +- test/integration.js | 10 ++++- 6 files changed, 128 insertions(+), 5 deletions(-) create mode 100644 app/templates/idt.js diff --git a/app/index.js b/app/index.js index c9d2831..b15ba5a 100644 --- a/app/index.js +++ b/app/index.js @@ -115,6 +115,7 @@ module.exports = class extends Generator { this.fs.copyTpl(this.templatePath('Dockerfile-tools'), this.destinationPath('Dockerfile-tools'), this.options); this.fs.copyTpl(this.templatePath('package.json'), this.destinationPath('package.json'), this.options); this.fs.copyTpl(this.templatePath('README.md'), this.destinationPath('README.md'), this.options); + this.fs.copyTpl(this.templatePath('idt.js'), this.destinationPath('idt.js'), this.options); // if project will have swagger doc, ensure swagger ui and api route if ( this.options.genSwagger ) { diff --git a/app/templates/README.md b/app/templates/README.md index cc8895d..758b9b3 100644 --- a/app/templates/README.md +++ b/app/templates/README.md @@ -5,8 +5,22 @@ A generated Bluemix application [![](https://img.shields.io/badge/bluemix-powered-blue.svg)](https://bluemix.net) ## Run locally as Node.js application + ```bash npm install npm test npm start -``` \ No newline at end of file +``` + +## Build, run, and deploy using IDT + +```bash +# Install needed dependencies: +npm run idt:install +# Build the docker image for your app: +npm run idt:build +# Run the app locally through docker: +npm run idt:run +# Deploy your app to IBM Cloud: +npm run idt:deploy +``` diff --git a/app/templates/idt.js b/app/templates/idt.js new file mode 100644 index 0000000..162a99d --- /dev/null +++ b/app/templates/idt.js @@ -0,0 +1,89 @@ +'use strict' + +/* + * Wrapper for the idt (IBM Developer Tools) command. + * Run with the same arguments as `idt`, e.g. + * `node idt.js build` -> `idt build`. + * If `idt` isn't installed, this will prompt you to install. Or you can run + * `node idt.js install` to automatically install idt and any other + * required dependencies (e.g. docker, git, kubernetes, helm). + * + */ + +const fs = require('fs'); +const process = require('process'); +const cp = require('child_process'); +const request = require('request'); +const path = require('path'); + +const chalk = require('chalk'); + +const node = process.execPath; +// Array of args passed to idt.js. +const args = process.argv.slice(2); +let win = (process.platform === 'win32'); + +// Either install idt or run idt + args. +if (args.includes('install')) { + downloadInstaller(); +} else { + // TODO(gib): Check for idt once this works in scripts: + // const checkCmd = win ? 'where idt' : 'which idt'; + const checkCmd = 'bx plugin show dev'; + let hasIDT = false; + try { + console.log(chalk.blue('Checking for idt')); + cp.execSync(checkCmd); // Don't inherit stdio, we don't want to print the output. + hasIDT = true; // If we didn't have idt, the previous command would have thrown. + } catch (e) { + const prompt = require('prompt-confirm'); + new prompt({ name: 'install', + message: 'IDT not found, do you want to install it? y/N', + default: false + }).ask((answer) => { + if (answer) { + downloadInstaller(() => runIDT(args)); + } else { + console.error(chalk.red(`Not installing idt, so not running: idt ${args.join(' ')}`)); + } + }); + } + if (hasIDT) runIDT(args); +} + +// Run IDT with whatever args we were given. +function runIDT(args) { + const cmd = 'bx dev ' + args.join(' '); + console.log(chalk.blue('Running:'), cmd); + cp.execSync(cmd, {stdio: 'inherit'}); +} + +// Download the IDT installer script and trigger runIDT(). +function downloadInstaller(cb) { + const url = win ? + 'https://ibm.biz/yeoman-idt-win-install' : + 'http://ibm.biz/yeoman-idt-install'; + + const fileName = url.split('/').pop() + + console.log(chalk.blue('Downloading installer from:'), url); + + const file = fs.createWriteStream(fileName); + + request + .get({url, followAllRedirects: true}) + .on('error', (err) => { console.error(err); }) + .pipe(file) + .on('finish', () => runInstaller(fileName, cb)); +} + +// Run the installer script and trigger callback (cb). +function runInstaller(fileName, cb) { + const shell = win ? 'powershell.exe' : 'bash'; + + const filePath = path.resolve(__dirname, fileName); + console.log(`Now running: ${shell} ${filePath}`); + + cp.spawnSync(shell, [filePath], {stdio: 'inherit'}); + cb(); +} diff --git a/app/templates/package.json b/app/templates/package.json index aa16e38..764d461 100644 --- a/app/templates/package.json +++ b/app/templates/package.json @@ -10,7 +10,14 @@ "start": "node server/server.js", "start:cluster": "sl-run server/server.js", "debug": "node --debug server/server.js", - "test": "nyc mocha" + "test": "nyc mocha", + "build": "npm run build:idt", + "idt:build": "node idt.js build", + "idt:test": "node idt.js test", + "idt:debug": "node idt.js debug", + "idt:run": "node idt.js run", + "idt:deploy": "node idt.js deploy", + "idt:install": "node idt.js install" }, "dependencies": { "appmetrics-dash": "^3.3.2", @@ -21,8 +28,11 @@ }, "devDependencies": { "chai": "^4.0.0", + "chalk": "^1.1.3", "mocha": "^3.4.2", "nyc": "^10.3.2", - "proxyquire": "^1.8.0" + "prompt-confirm": "^1.2.0", + "proxyquire": "^1.8.0", + "request": "^2.82.0" } } diff --git a/test/common.js b/test/common.js index 7d5fddd..8157d31 100644 --- a/test/common.js +++ b/test/common.js @@ -28,6 +28,7 @@ exports.file = { index_router: 'server/routers/index.js', public: 'server/routers/public.js', index_service: 'server/services/index.js', + idt_js: 'idt.js', cliconfig: 'cli-config.yml' }; @@ -35,4 +36,4 @@ exports.file = { exports.defaultPort = 3000; // The npm start command. -exports.npmStart = "node server.js" \ No newline at end of file +exports.npmStart = "node server.js" diff --git a/test/integration.js b/test/integration.js index 0d90c0b..803795e 100644 --- a/test/integration.js +++ b/test/integration.js @@ -69,7 +69,15 @@ describe('core-node-express:app integration test with custom spec', function () "scripts": { "start": "node server/server.js", "start:cluster": "sl-run server/server.js", - "test": "nyc mocha" + "debug": "node --debug server/server.js", + "test": "nyc mocha", + "build": "npm run build:idt", + "idt:build": "node idt.js build", + "idt:test": "node idt.js test", + "idt:debug": "node idt.js debug", + "idt:run": "node idt.js run", + "idt:deploy": "node idt.js deploy", + "idt:install": "node idt.js install" }, "dependencies": { "appmetrics-dash": "^3.3.2", From 78e9a5cfca359be4401a2488ad9789b7faaebf94 Mon Sep 17 00:00:00 2001 From: cvignola Date: Fri, 29 Sep 2017 15:32:22 +0000 Subject: [PATCH 11/12] [Travis - npm version patch] Increment package version to 0.0.63 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2b08111..a9035a4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "generator-ibm-core-node-express", - "version": "0.0.62", + "version": "0.0.63", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 4d1f876..3a780cf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "generator-ibm-core-node-express", - "version": "0.0.62", + "version": "0.0.63", "description": "Yeoman generator for core node express application", "license": "Apache-2.0", "keywords": [ From a96a25f79979bd8eed47e1a4e38b94634266cfc2 Mon Sep 17 00:00:00 2001 From: cvignola Date: Fri, 29 Sep 2017 15:50:22 +0000 Subject: [PATCH 12/12] [Travis - npm version patch] Increment package version to 0.0.64 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index a9035a4..db4b72c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "generator-ibm-core-node-express", - "version": "0.0.63", + "version": "0.0.64", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 3a780cf..1aa9c41 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "generator-ibm-core-node-express", - "version": "0.0.63", + "version": "0.0.64", "description": "Yeoman generator for core node express application", "license": "Apache-2.0", "keywords": [