diff --git a/CHANGES.md b/CHANGES.md index c467bcdb..fb03b60f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,16 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. + +## [4.5.1](https://github.com/IBM-Swift/generator-swiftserver/compare/4.5.0...4.5.1) (2018-02-07) + + +### Bug Fixes + +* Init special chars bug ([#445](https://github.com/IBM-Swift/generator-swiftserver/issues/445)) ([ca255f1](https://github.com/IBM-Swift/generator-swiftserver/commit/ca255f1)) + + + # [4.5.0](https://github.com/IBM-Swift/generator-swiftserver/compare/4.4.0...4.5.0) (2018-02-01) diff --git a/app/index.js b/app/index.js index 8188a967..d225471a 100644 --- a/app/index.js +++ b/app/index.js @@ -63,6 +63,46 @@ module.exports = Generator.extend({ initializing: { ensureNotInProject: actions.ensureNotInProject, + initAppName: function () { + // save the initial directory for use by the fromSwagger processing. + this.initialWorkingDir = process.cwd() + + this.appname = null // Discard yeoman default appname + this.skipPromptingAppName = false + if (this.options.name) { + // User passed a desired application name as an argument + var validation = validateAppName(this.options.name) + if (validation === true) { + // Desired application name is valid, skip prompting for it + // later + this.appname = this.options.name + this.skipPromptingAppName = true + } else { + // Log reason for validation failure, if provided + validation = validation || 'Application name not valid' + debug(this.options.name, ' is not valid because ', validation) + this.log(validation) + } + } + + if (this.appname === null) { + // Fall back to name of current working directory + // Normalize if it contains special characters + var sanitizedCWD = path.basename(process.cwd()).replace(/[/@\s+%:.;,?&=+$]+?/g, '-') + // SanitizedCWD replaces /@\s+%:.;,?&=+$ with dashes. + // if the name still contains characters which + // are not encodable by encodeURIComponent, default to 'app' + if (validateAppName(sanitizedCWD) === true) { + this.appname = sanitizedCWD + } else { + // Fall back again to a known valid name + this.log('Failed to produce a valid application name from the current working directory') + debug(sanitizedCWD, ' is not a valid application name and defaulting to \'app\'') + this.appname = 'app' + } + } + }, + initSpec: function () { function isTrue (value) { return (value === true || value === 'true') @@ -107,6 +147,9 @@ module.exports = Generator.extend({ } else if (this.options.init) { // User passed the --init flag, so no prompts, just generate basic default scaffold this.destinationSet = true + if (this.appname !== path.basename(this.destinationRoot())) { + this.destinationRoot(path.resolve(this.appname)) + } this.skipPrompting = true this.appPattern = 'Basic' this.spec = { @@ -126,47 +169,6 @@ module.exports = Generator.extend({ } }, - initAppName: function () { - if (this.skipPrompting) return - - // save the initial directory for use by the fromSwagger processing. - this.initialWorkingDir = process.cwd() - - this.appname = null // Discard yeoman default appname - this.skipPromptingAppName = false - if (this.options.name) { - // User passed a desired application name as an argument - var validation = validateAppName(this.options.name) - if (validation === true) { - // Desired application name is valid, skip prompting for it - // later - this.appname = this.options.name - this.skipPromptingAppName = true - } else { - // Log reason for validation failure, if provided - validation = validation || 'Application name not valid' - debug(this.options.name, ' is not valid because ', validation) - this.log(validation) - } - } - - if (this.appname === null) { - // Fall back to name of current working directory - // Normalize if it contains special characters - var sanitizedCWD = path.basename(process.cwd()).replace(/[/@\s+%:.]+?/g, '-') - // We hope that sanitizedCWD is always valid, but check just - // in case it isn't - if (validateAppName(sanitizedCWD) === true) { - this.appname = sanitizedCWD - } else { - // Fall back again to a known valid name - this.log('Failed to produce a valid application name from the current working directory') - debug(sanitizedCWD, ' is not a valid application name and defaulting to \'app\'') - this.appname = 'app' - } - } - }, - initForPrompting: function () { if (this.skipPrompting) return // initialize for prompting diff --git a/lib/helpers.js b/lib/helpers.js index e8869847..4b194355 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -57,7 +57,7 @@ exports.validateDirName = function (name) { if (!name) { return 'Name is required' } - return validateValue(name, /[/@\s+%:]/) + return validateValue(name, /[/@\s+%:.;,?&=+$]/) } exports.validateRequiredCredential = function (name) { @@ -120,7 +120,7 @@ exports.validateAppName = function (name) { if (name.toLowerCase() === 'favicon.ico') { return format('Application name cannot be {favicon.ico}') } - return validateValue(name, /[/@\s+%:]/) + return validateValue(name, /[/@\s+%:.;,?&=+$]/) } /** @@ -206,7 +206,7 @@ exports.validateRequiredName = function (name) { if (!name) { return format('Name is required.') } - return validateValue(name, /[/@\s+%:.]/) + return validateValue(name, /[/@\s+%:.;,?&=+$]/) } /* @@ -236,7 +236,7 @@ exports.validateNewModel = function (name) { */ function validateValue (name, unallowedCharacters) { if (!unallowedCharacters) { - unallowedCharacters = /[/@\s+%:.]/ + unallowedCharacters = /[/@\s+%:.;,?&=+$]/ } if (name.match(unallowedCharacters)) { return format('The name %s cannot contain special characters (regex %s)', diff --git a/package-lock.json b/package-lock.json index cbe24b84..8f9c0569 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "generator-swiftserver", - "version": "4.5.0", + "version": "4.5.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 5e2f233b..89c84816 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "generator-swiftserver", - "version": "4.5.0", + "version": "4.5.1", "description": "Generator for Kitura REST webservice servers", "main": "app/index.js", "scripts": { diff --git a/test/unit/app.js b/test/unit/app.js index f83976a4..4f2b5aca 100644 --- a/test/unit/app.js +++ b/test/unit/app.js @@ -425,10 +425,10 @@ describe('Unit tests for swiftserver:app', function () { runContext = helpers.run(appGeneratorPath) .withGenerators(dependentGenerators) .inTmpDir(function (tmpDir) { - this.inDir(path.join(tmpDir, 'inva&%*lid')) + this.inDir(path.join(tmpDir, 'inva[%*lid')) }) .withOptions({ testmode: true }) - .withArguments(['inva&%*lid']) + .withArguments(['inva[%*lid']) return runContext.toPromise() }) @@ -502,6 +502,35 @@ describe('Unit tests for swiftserver:app', function () { })) }) + describe('in dir with invalid and sanitizable name using --init', function () { + var runContext + + before(function () { + runContext = helpers.run(appGeneratorPath) + .withGenerators(dependentGenerators) + .inTmpDir(function (tmpDir) { + this.inDir(path.join(tmpDir, 'i-n v&a%l@i$d s.y;m,b?o=l+s')) + }) + .withOptions({ testmode: true, init: true }) + return runContext.toPromise() + }) + + after(function () { + runContext.cleanTestDirectory() + }) + + commonTest.itUsedDestinationDirectory('i-n-v-a-l-i-d-s-y-m-b-o-l-s') + + it('created a spec object with appName defaulting to dir and no appDir', function () { + var spec = runContext.generator.spec + var expectedSpec = { + appName: 'i-n-v-a-l-i-d-s-y-m-b-o-l-s', + appDir: undefined + } + assert.objectContent(spec, expectedSpec) + }) + }) + describe('--enableUsecase specified', function () { describe('Valid --bluemix flag specified', function () { var runContext