From ed862f86d36fe472296a2d10baa484566dcc5f2c Mon Sep 17 00:00:00 2001 From: Bram Borggreve Date: Sun, 8 Jan 2017 01:25:34 -0500 Subject: [PATCH] fix(new): improve error message when project name does not match regex Fix #3816 Close #3902 --- packages/angular-cli/commands/new.ts | 30 ++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/packages/angular-cli/commands/new.ts b/packages/angular-cli/commands/new.ts index 9b58b21f2c96..a51cb8aeb15e 100644 --- a/packages/angular-cli/commands/new.ts +++ b/packages/angular-cli/commands/new.ts @@ -1,12 +1,27 @@ import * as chalk from 'chalk'; import InitCommand from './init'; -import {oneLine} from 'common-tags'; +import {oneLine, stripIndent} from 'common-tags'; const Command = require('../ember-cli/lib/models/command'); const Project = require('../ember-cli/lib/models/project'); const SilentError = require('silent-error'); const validProjectName = require('../ember-cli/lib/utilities/valid-project-name'); +const packageNameRegexp = /^[a-zA-Z][.0-9a-zA-Z]*(-[a-zA-Z][.0-9a-zA-Z]*)*$/; + +function getRegExpFailPosition(str: string) { + const parts = str.split('-'); + const matched: string[] = []; + + parts.forEach(part => { + if (part.match(packageNameRegexp)) { + matched.push(part); + } + }); + + const compare = matched.join('-'); + return (str !== compare) ? compare.length : null; +} const NewCommand = Command.extend({ name: 'new', @@ -39,11 +54,18 @@ const NewCommand = Command.extend({ `The "ng ${this.name}" command requires a name argument to be specified. ` + `For more details, use "ng help".`)); } - if (!packageName.match(/^[a-zA-Z][.0-9a-zA-Z]*(-[a-zA-Z][.0-9a-zA-Z]*)*$/)) { - return Promise.reject(new SilentError(oneLine` + if (!packageName.match(packageNameRegexp)) { + const firstMessage = oneLine` Project name "${packageName}" is not valid. New project names must start with a letter, and must contain only alphanumeric characters or dashes. - `)); + When adding a dash the segment after the dash must start with a letter too. + `; + const msg = stripIndent` + ${firstMessage} + ${packageName} + ${Array(getRegExpFailPosition(packageName) + 1).join(' ') + '^'} + `; + return Promise.reject(new SilentError(msg)); } commandOptions.name = packageName;