private static CreationResultStatus DisplayHelpForAmbiguousTemplateGroup(TemplateListResolutionResult templateResolutionResult, IEngineEnvironmentSettings environmentSettings, INewCommandInput commandInput, IHostSpecificDataLoader hostDataLoader, ITelemetryLogger telemetryLogger, string defaultLanguage) { if (!string.IsNullOrEmpty(commandInput.TemplateName) && templateResolutionResult.GetBestTemplateMatchList(true).Count > 0 && templateResolutionResult.GetBestTemplateMatchList(true).All(x => x.MatchDisposition.Any(d => d.Location == MatchLocation.Language && d.Kind == MatchKind.Mismatch))) { string errorMessage = GetLanguageMismatchErrorMessage(commandInput); //Reporter.Error.WriteLine(errorMessage.Bold().Red()); //Reporter.Error.WriteLine(string.Format(LocalizableStrings.RunHelpForInformationAboutAcceptedParameters, $"{commandInput.CommandName} {commandInput.TemplateName}").Bold().Red()); return(CreationResultStatus.NotFound); } // The following occurs when: // --alias <value> is specifed // --help is specified // template (group) can't be resolved if (!string.IsNullOrWhiteSpace(commandInput.Alias)) { //Reporter.Error.WriteLine(LocalizableStrings.InvalidInputSwitch.Bold().Red()); //Reporter.Error.WriteLine(" " + commandInput.TemplateParamInputFormat("--alias").Bold().Red()); return(CreationResultStatus.NotFound); } bool hasInvalidParameters = false; IReadOnlyList <ITemplateMatchInfo> templatesForDisplay = templateResolutionResult.GetBestTemplateMatchList(true); GetParametersInvalidForTemplatesInList(templatesForDisplay, out IReadOnlyList <string> invalidForAllTemplates, out IReadOnlyList <string> invalidForSomeTemplates); if (invalidForAllTemplates.Any() || invalidForSomeTemplates.Any()) { hasInvalidParameters = true; DisplayInvalidParameters(invalidForAllTemplates); DisplayParametersInvalidForSomeTemplates(invalidForSomeTemplates, LocalizableStrings.PartialTemplateMatchSwitchesNotValidForAllMatches); } if (commandInput.IsHelpFlagSpecified) { // usage help should show first (if it's being shown at all). telemetryLogger.TrackEvent(commandInput.CommandName + "-Help"); ShowUsageHelp(commandInput); } ShowContextAndTemplateNameMismatchHelp(templateResolutionResult, commandInput.TemplateName, commandInput.TypeFilter); DisplayTemplateList(templatesForDisplay, environmentSettings, commandInput.Language, defaultLanguage); if (!commandInput.IsListFlagSpecified) { TemplateUsageHelp.ShowInvocationExamples(templateResolutionResult, hostDataLoader, commandInput.CommandName); } if (hasInvalidParameters) { return(CreationResultStatus.NotFound); } else if (commandInput.IsListFlagSpecified || commandInput.IsHelpFlagSpecified) { return(CreationResultStatus.Success); } else { return(CreationResultStatus.OperationNotSpecified); } }
private static void DisplayPartialNameMatchAndContextProblems(string templateName, string context, TemplateListResolutionResult templateResolutionResult, out bool shouldShowTemplateList) { shouldShowTemplateList = false; if (templateResolutionResult.IsTemplateAmbiguous) { // Unable to determine the desired template from the input template name: {0}.. Reporter.Error.WriteLine(string.Format(LocalizableStrings.AmbiguousInputTemplateName, templateName).Bold().Red()); } else if (templateResolutionResult.IsNoTemplatesMatchedState) { // No templates matched the input template name: {0} Reporter.Error.WriteLine(string.Format(LocalizableStrings.NoTemplatesMatchName, templateName).Bold().Red()); Reporter.Error.WriteLine(); return; } bool anythingReported = false; foreach (IReadOnlyList <ITemplateMatchInfo> templateGroup in templateResolutionResult.ContextProblemMatchGroups) { // all templates in a group should have the same context & name if (templateGroup[0].Info.Tags != null && templateGroup[0].Info.Tags.TryGetValue("type", out ICacheTag typeTag)) { MatchInfo?matchInfo = WellKnownSearchFilters.ContextFilter(context)(templateGroup[0].Info); if ((matchInfo?.Kind ?? MatchKind.Mismatch) == MatchKind.Mismatch) { // {0} matches the specified name, but has been excluded by the --type parameter. Remove or change the --type parameter to use that template Reporter.Error.WriteLine(string.Format(LocalizableStrings.TemplateNotValidGivenTheSpecifiedFilter, templateGroup[0].Info.Name).Bold().Red()); anythingReported = true; } } else { // this really shouldn't ever happen. But better to have a generic error than quietly ignore the partial match. // //{0} cannot be created in the target location Reporter.Error.WriteLine(string.Format(LocalizableStrings.GenericPlaceholderTemplateContextError, templateGroup[0].Info.Name).Bold().Red()); anythingReported = true; } } if (templateResolutionResult.RemainingPartialMatchGroups.Count > 0) { // The following templates partially match the input. Be more specific with the template name and/or language Reporter.Error.WriteLine(LocalizableStrings.TemplateMultiplePartialNameMatches.Bold().Red()); anythingReported = true; shouldShowTemplateList = true; } if (anythingReported) { Reporter.Error.WriteLine(); } }
public void MultipleTemplatesInGroupHavingSingularStartMatchesOnDifferentParams_HighPrecedenceIsChosen() { List <ITemplateInfo> templatesToSearch = new List <ITemplateInfo>(); templatesToSearch.Add(new TemplateInfo() { ShortName = "foo", Name = "Foo template", Identity = "foo.test_1", GroupIdentity = "foo.test.template", Precedence = 100, Tags = new Dictionary <string, ICacheTag>(StringComparer.OrdinalIgnoreCase) { { "MyChoice", ResolutionTestHelper.CreateTestCacheTag(new List <string>() { "value_1", "other_value" }) }, // single starts with { "OtherChoice", ResolutionTestHelper.CreateTestCacheTag(new List <string>() { "foo_" }) } // exact }, CacheParameters = new Dictionary <string, ICacheParameter>(), }); templatesToSearch.Add(new TemplateInfo() { ShortName = "foo", Name = "Foo template", Identity = "foo.test_2", GroupIdentity = "foo.test.template", Precedence = 200, Tags = new Dictionary <string, ICacheTag>(StringComparer.OrdinalIgnoreCase) { { "MyChoice", ResolutionTestHelper.CreateTestCacheTag(new List <string>() { "value_" }) }, // exact { "OtherChoice", ResolutionTestHelper.CreateTestCacheTag(new List <string>() { "foo_", "bar_1" }) } // single starts with }, CacheParameters = new Dictionary <string, ICacheParameter>(), }); INewCommandInput userInputs = new MockNewCommandInput( new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase) { { "MyChoice", "value_" }, { "OtherChoice", "foo_" } } ) { TemplateName = "foo" }; IHostSpecificDataLoader hostSpecificDataLoader = new MockHostSpecificDataLoader(); TemplateListResolutionResult matchResult = TemplateListResolver.GetTemplateResolutionResult(templatesToSearch, hostSpecificDataLoader, userInputs, null); // make sure there's an unambiguous group, otherwise the singular match check is meaningless Assert.True(matchResult.TryGetUnambiguousTemplateGroupToUse(out IReadOnlyList <ITemplateMatchInfo> unambiguousGroup)); Assert.Equal(2, unambiguousGroup.Count); Assert.Equal(2, matchResult.GetBestTemplateMatchList().Count); Assert.True(matchResult.TryGetSingularInvokableMatch(out ITemplateMatchInfo singularInvokableMatch)); Assert.Equal("foo.test_2", singularInvokableMatch.Info.Identity); }
private static CreationResultStatus DisplayListOrHelpForAmbiguousTemplateGroup(TemplateListResolutionResult templateResolutionResult, IEngineEnvironmentSettings environmentSettings, INewCommandInput commandInput, IHostSpecificDataLoader hostDataLoader, ITelemetryLogger telemetryLogger, string defaultLanguage) { // The following occurs when: // --alias <value> is specifed // --help is specified // template (group) can't be resolved if (!string.IsNullOrWhiteSpace(commandInput.Alias)) { Reporter.Error.WriteLine(LocalizableStrings.InvalidInputSwitch.Bold().Red()); Reporter.Error.WriteLine(" " + commandInput.TemplateParamInputFormat("--alias").Bold().Red()); return(CreationResultStatus.NotFound); } bool hasInvalidParameters = false; IReadOnlyCollection <ITemplateMatchInfo> templatesForDisplay = templateResolutionResult.ExactMatchedTemplates; GetParametersInvalidForTemplatesInList(templatesForDisplay, out IReadOnlyList <string> invalidForAllTemplates, out IReadOnlyList <string> invalidForSomeTemplates); if (invalidForAllTemplates.Any() || invalidForSomeTemplates.Any()) { hasInvalidParameters = true; DisplayInvalidParameters(invalidForAllTemplates); DisplayParametersInvalidForSomeTemplates(invalidForSomeTemplates, LocalizableStrings.PartialTemplateMatchSwitchesNotValidForAllMatches); } if (templateResolutionResult.HasExactMatches) { ShowTemplatesFoundMessage(commandInput); DisplayTemplateList(templateResolutionResult.ExactMatchedTemplateGroups, environmentSettings, commandInput, defaultLanguage); } else { ShowContextAndTemplateNameMismatchHelp(templateResolutionResult, commandInput); } if (!commandInput.IsListFlagSpecified) { TemplateUsageHelp.ShowInvocationExamples(templateResolutionResult, hostDataLoader, commandInput.CommandName); } if (hasInvalidParameters) { return(CreationResultStatus.NotFound); } else if (commandInput.IsListFlagSpecified || commandInput.IsHelpFlagSpecified) { return(templateResolutionResult.HasExactMatches ? CreationResultStatus.Success : CreationResultStatus.NotFound); } else { return(CreationResultStatus.OperationNotSpecified); } }