Skip to content

Commit

Permalink
Changes per Mike's informal review. Fixed output when trying to remov…
Browse files Browse the repository at this point in the history
…e an alias that doesn't exist.
  • Loading branch information
seancpeters committed Apr 11, 2017
1 parent e0bef05 commit bfe0c46
Show file tree
Hide file tree
Showing 7 changed files with 204 additions and 69 deletions.
2 changes: 1 addition & 1 deletion Microsoft.TemplateEngine.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26214.0
VisualStudioVersion = 15.0.26312.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{7DAC892E-ADAE-4CEB-8A0C-EDC452A5826A}"
EndProject
Expand Down
93 changes: 82 additions & 11 deletions src/Microsoft.TemplateEngine.Cli/AliasSupport.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.TemplateEngine.Abstractions;
using Microsoft.TemplateEngine.Cli.CommandParsing;
using Microsoft.TemplateEngine.Edge.Settings;
Expand Down Expand Up @@ -28,40 +30,109 @@ public static AliasExpansionStatus TryExpandAliases(INewCommandInput commandInpu
return AliasExpansionStatus.ExpansionError;
}

public static CreationResultStatus ManipulateAliasValue(INewCommandInput commandInput, AliasRegistry aliasRegistry)
// Matches on any non-word character (letter, number, or underscore)
// Almost the same as \W, except \W has some quirks with unicode characters, and we allow '.'
private static readonly Regex InvalidAliasRegex = new Regex("[^a-z0-9_.]", RegexOptions.IgnoreCase);
// The first token must be a valid template short name. This naively tests for it by checking the first character.
// TODO: make this test more robust.
private static readonly Regex ValidFirstTokenRegex = new Regex("^[a-z0-9]", RegexOptions.IgnoreCase);

public static CreationResultStatus ManipulateAliasIfValid(AliasRegistry aliasRegistry, string aliasName, List<string> inputTokens, HashSet<string> reservedAliasNames)
{
List<string> inputTokens = commandInput.Tokens.ToList();
if (reservedAliasNames.Contains(aliasName))
{
Reporter.Output.WriteLine(string.Format(LocalizableStrings.AliasCannotBeShortName, aliasName));
return CreationResultStatus.CreateFailed;
}
else if (InvalidAliasRegex.IsMatch(aliasName))
{
Reporter.Output.WriteLine(LocalizableStrings.AliasNameContainsInvalidCharacters); // TODO - change this string
return CreationResultStatus.InvalidParamValues;
}

inputTokens.RemoveAt(0); // remove the command name
AliasManipulationResult result = aliasRegistry.TryCreateOrRemoveAlias(inputTokens);
IReadOnlyList<string> aliasTokens = FilterForAliasTokens(inputTokens); // remove '-a' or '--alias', and the alias name

// The first token refers to a template name, or another alias.
if (aliasTokens.Count > 0 && !ValidFirstTokenRegex.IsMatch(aliasTokens[0]))
{
Reporter.Output.WriteLine(LocalizableStrings.AliasValueFirstArgError);
return CreationResultStatus.InvalidParamValues;
}

// create, update, or delete an alias.
return ManipulateAliasValue(aliasName, aliasTokens, aliasRegistry);
}

private static CreationResultStatus ManipulateAliasValue(string aliasName, IReadOnlyList<string> aliasTokens, AliasRegistry aliasRegistry)
{
AliasManipulationResult result = aliasRegistry.TryCreateOrRemoveAlias(aliasName, aliasTokens);
CreationResultStatus returnStatus = CreationResultStatus.OperationNotSpecified;

switch (result.Status)
{
case AliasManipulationStatus.Created:
Reporter.Output.WriteLine(string.Format("Successfully created alias named '{0}' with value '{1}'", result.AliasName, result.AliasValue));
Reporter.Output.WriteLine(string.Format(LocalizableStrings.AliasCreated, result.AliasName, result.AliasValue));
returnStatus = CreationResultStatus.Success;
break;
case AliasManipulationStatus.Removed:
Reporter.Output.WriteLine(string.Format("Successfully removed alias named '{0}' whose value was '{1}'", result.AliasName, result.AliasValue));
Reporter.Output.WriteLine(string.Format(LocalizableStrings.AliasRemoved, result.AliasName, result.AliasValue));
returnStatus = CreationResultStatus.Success;
break;
case AliasManipulationStatus.RemoveNonExistentFailed:
Reporter.Output.WriteLine(string.Format(LocalizableStrings.AliasRemoveNonExistentFailed, result.AliasName));
break;
case AliasManipulationStatus.Updated:
Reporter.Output.WriteLine(string.Format("Successfully updated alias named '{0}' to value '{1}'", result.AliasName, result.AliasValue));
Reporter.Output.WriteLine(string.Format(LocalizableStrings.AliasUpdated, result.AliasName, result.AliasValue));
returnStatus = CreationResultStatus.Success;
break;
case AliasManipulationStatus.WouldCreateCycle:
Reporter.Output.WriteLine(string.Format("Alias not created. It would have created an alias cycle, resulting in infinite expansion."));
Reporter.Output.WriteLine(LocalizableStrings.AliasCycleError);
returnStatus = CreationResultStatus.CreateFailed;
break;
case AliasManipulationStatus.InvalidInput:
Reporter.Output.WriteLine(string.Format("Alias not created. The input was invalid"));
Reporter.Output.WriteLine(LocalizableStrings.AliasNotCreatedInvalidInput);
returnStatus = CreationResultStatus.InvalidParamValues;
break;
}

return returnStatus;
}

private static IReadOnlyList<string> FilterForAliasTokens(IReadOnlyList<string> inputTokens)
{
List<string> aliasTokens = new List<string>();
bool nextIsAliasName = false;
string aliasName = null;

foreach (string token in inputTokens)
{
if (nextIsAliasName)
{
aliasName = token;
nextIsAliasName = false;
}
else if (string.Equals(token, "-a", StringComparison.Ordinal) || string.Equals(token, "--alias", StringComparison.Ordinal))
{
if (!string.IsNullOrEmpty(aliasName))
{
// found multiple alias names, which is invalid.
aliasTokens.Clear();
aliasName = null;
return aliasTokens;
}

nextIsAliasName = true;
}
else if (!token.StartsWith("--debug:", StringComparison.Ordinal))
{
aliasTokens.Add(token);
}
}

return aliasTokens;
}

public static CreationResultStatus DisplayAliasValues(IEngineEnvironmentSettings environment, INewCommandInput commandInput, AliasRegistry aliasRegistry)
{
IReadOnlyDictionary<string, string> aliasesToShow;
Expand All @@ -77,14 +148,14 @@ public static CreationResultStatus DisplayAliasValues(IEngineEnvironmentSettings
}
else
{
Reporter.Output.WriteLine(string.Format("Unknown alias name '{0}'\nRun 'dotnet --show-aliases' with no args to show all aliases.", commandInput.ShowAliasesAliasName));
Reporter.Output.WriteLine(string.Format(LocalizableStrings.AliasShowErrorUnknownAlias, commandInput.ShowAliasesAliasName));
return CreationResultStatus.InvalidParamValues;
}
}
else
{
aliasesToShow = aliasRegistry.AllAliases;
Reporter.Output.WriteLine("All Aliases:");
Reporter.Output.WriteLine(LocalizableStrings.AliasShowAllAliasesHeader);
}

HelpFormatter<KeyValuePair<string, string>> formatter = new HelpFormatter<KeyValuePair<string, string>>(environment, aliasesToShow, 2, '-', false)
Expand Down
93 changes: 83 additions & 10 deletions src/Microsoft.TemplateEngine.Cli/LocalizableStrings.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 28 additions & 3 deletions src/Microsoft.TemplateEngine.Cli/LocalizableStrings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@
<value>Alias</value>
</data>
<data name="AliasCreated" xml:space="preserve">
<value>Alias creation successful.</value>
<value>Successfully created alias named '{0}' with value '{1}'</value>
</data>
<data name="AmbiguousInputTemplateName" xml:space="preserve">
<value>Unable to determine the desired template from the input template name: {0}.</value>
Expand Down Expand Up @@ -443,8 +443,8 @@
<data name="ShowAliasesHelp" xml:space="preserve">
<value>Displays the value of the named alias, or all aliases if no name is specified.</value>
</data>
<data name="AliasCannotBeginWithDashes" xml:space="preserve">
<value>Alias names cannot begin with dashes ('-').</value>
<data name="AliasNameContainsInvalidCharacters" xml:space="preserve">
<value>Alias names can only contain letters, numbers, underscores, and periods.</value>
</data>
<data name="AliasCannotBeShortName" xml:space="preserve">
<value>Alias '{0}' is a template short name, and therefore cannot be aliased.</value>
Expand All @@ -463,4 +463,29 @@
<value>After expanding the extra args files, the command is:
dotnet {0}</value>
</data>
<data name="AliasCycleError" xml:space="preserve">
<value>Alias not created. It would have created an alias cycle, resulting in infinite expansion.</value>
</data>
<data name="AliasNotCreatedInvalidInput" xml:space="preserve">
<value>Alias not created. The input was invalid.</value>
</data>
<data name="AliasRemoved" xml:space="preserve">
<value>Successfully removed alias named '{0}' whose value was '{1}'.</value>
</data>
<data name="AliasShowAllAliasesHeader" xml:space="preserve">
<value>All Aliases:</value>
</data>
<data name="AliasShowErrorUnknownAlias" xml:space="preserve">
<value>Unknown alias name '{0}'.
Run 'dotnet --show-aliases' with no args to show all aliases.</value>
</data>
<data name="AliasUpdated" xml:space="preserve">
<value>Successfully updated alias named '{0}' to value '{1}'.</value>
</data>
<data name="AliasValueFirstArgError" xml:space="preserve">
<value>First argument of an alias value must be a letter or digit.</value>
</data>
<data name="AliasRemoveNonExistentFailed" xml:space="preserve">
<value>Unable to remove alias '{0}'. It did not exist.</value>
</data>
</root>
16 changes: 1 addition & 15 deletions src/Microsoft.TemplateEngine.Cli/New3Command.cs
Original file line number Diff line number Diff line change
Expand Up @@ -968,22 +968,8 @@ private async Task<CreationResultStatus> ExecuteAsync()
{
if (!string.IsNullOrEmpty(_commandInput.Alias) && !_commandInput.IsHelpFlagSpecified)
{
// Check that the alias name is not the short name of a template.
if (AllTemplateShortNames.Contains(_commandInput.Alias))
{
Reporter.Output.WriteLine(string.Format(LocalizableStrings.AliasCannotBeShortName, _commandInput.Alias));
return CreationResultStatus.CreateFailed;
}
else if (_commandInput.Alias.StartsWith("-"))
{
Reporter.Output.WriteLine(LocalizableStrings.AliasCannotBeginWithDashes);
return CreationResultStatus.InvalidParamValues;
}

// create, update, or delete an alias.
return AliasSupport.ManipulateAliasValue(_commandInput, _aliasRegistry);
return AliasSupport.ManipulateAliasIfValid(_aliasRegistry, _commandInput.Alias, _commandInput.Tokens.ToList(), AllTemplateShortNames);
}
// TODO try expanding aliases... then redo everything except checking for alias expansion.

if (string.IsNullOrWhiteSpace(TemplateName))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ public enum AliasManipulationStatus
{
Created,
Removed,
RemoveNonExistentFailed, // for trying to remove an alias that didn't exist.
Updated,
WouldCreateCycle,
InvalidInput
Expand Down
Loading

0 comments on commit bfe0c46

Please sign in to comment.