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