// Displays the list of templates in a table, one row per template group. // // The columns displayed are as follows: // Except where noted, the values are taken from the highest-precedence template in the group. The info could vary among the templates in the group, but shouldn't. // (There is no check that the info doesn't vary.) // - Template Name // - Short Name: displays the first short name from the highest precedence template in the group. // - Language: All languages supported by any template in the group are displayed, with the default language in brackets, e.g.: [C#] // - Tags private static void DisplayTemplateList(IReadOnlyCollection <ITemplateMatchInfo> templates, IEngineEnvironmentSettings environmentSettings, INewCommandInput commandInput, string defaultLanguage) { IReadOnlyCollection <TemplateGroupTableRow> groupsForDisplay = TemplateGroupDisplay.GetTemplateGroupsForListDisplay(templates, commandInput.Language, defaultLanguage); HelpFormatter <TemplateGroupTableRow> formatter = HelpFormatter .For( environmentSettings, commandInput, groupsForDisplay, columnPadding: 2, headerSeparator: '-', blankLineBetweenRows: false) .DefineColumn(t => t.Name, LocalizableStrings.ColumnNameTemplateName, shrinkIfNeeded: true, minWidth: 15, showAlways: true) .DefineColumn(t => t.ShortName, LocalizableStrings.ColumnNameShortName, showAlways: true) .DefineColumn(t => t.Languages, out object languageColumn, LocalizableStrings.ColumnNameLanguage, NewCommandInputCli.LanguageColumnFilter, defaultColumn: true) .DefineColumn(t => t.Type, LocalizableStrings.ColumnNameType, NewCommandInputCli.TypeColumnFilter, defaultColumn: false) .DefineColumn(t => t.Author, LocalizableStrings.ColumnNameAuthor, NewCommandInputCli.AuthorColumnFilter, defaultColumn: false, shrinkIfNeeded: true, minWidth: 10) .DefineColumn(t => t.Classifications, out object tagsColumn, LocalizableStrings.ColumnNameTags, NewCommandInputCli.TagsColumnFilter, defaultColumn: true) .OrderByDescending(languageColumn, new NullOrEmptyIsLastStringComparer()) .OrderBy(tagsColumn); Reporter.Output.WriteLine(formatter.Layout()); }
private static void DisplayResultsForPack(TemplateSourceSearchResult sourceResult, IEngineEnvironmentSettings environmentSettings, INewCommandInput commandInput, string defaultLanguage) { string sourceHeader = string.Format(LocalizableStrings.SearchResultSourceIndicator, sourceResult.SourceDisplayName); Reporter.Output.WriteLine(sourceHeader); Reporter.Output.WriteLine(); IReadOnlyCollection <SearchResultTableRow> data = GetSearchResultsForDisplay(sourceResult, commandInput.Language, defaultLanguage); HelpFormatter <SearchResultTableRow> formatter = HelpFormatter .For( environmentSettings, commandInput, data, columnPadding: 2, headerSeparator: '-', blankLineBetweenRows: false) .DefineColumn(r => r.TemplateGroupInfo.Name, LocalizableStrings.ColumnNameTemplateName, showAlways: true, shrinkIfNeeded: true, minWidth: 15) .DefineColumn(r => r.TemplateGroupInfo.ShortName, LocalizableStrings.ColumnNameShortName, showAlways: true) .DefineColumn(r => r.TemplateGroupInfo.Author, LocalizableStrings.ColumnNameAuthor, NewCommandInputCli.AuthorColumnFilter, defaultColumn: true, shrinkIfNeeded: true, minWidth: 10) .DefineColumn(r => r.TemplateGroupInfo.Languages, LocalizableStrings.ColumnNameLanguage, NewCommandInputCli.LanguageColumnFilter, defaultColumn: true) .DefineColumn(r => r.TemplateGroupInfo.Type, LocalizableStrings.ColumnNameType, NewCommandInputCli.TypeColumnFilter, defaultColumn: false) .DefineColumn(r => r.TemplateGroupInfo.Classifications, LocalizableStrings.ColumnNameTags, NewCommandInputCli.TagsColumnFilter, defaultColumn: false, shrinkIfNeeded: true, minWidth: 10) .DefineColumn(r => r.PackageName, out object packageColumn, LocalizableStrings.ColumnNamePackage, showAlways: true) .DefineColumn(r => r.PrintableTotalDownloads, LocalizableStrings.ColumnNameTotalDownloads, showAlways: true, rightAlign: true) .OrderBy(packageColumn); Reporter.Output.WriteLine(formatter.Layout()); }
/// <summary> /// Displays the help when <paramref name="unambiguousTemplateGroup"/> contains the invokable templates with ambiguous precedence. /// </summary> /// <param name="unambiguousTemplateGroup">resolved unambiguous template group to use based on the command input</param> /// <param name="environmentSettings"></param> /// <param name="commandInput">the command input</param> /// <param name="installUnitDescriptors">the list of install unit descriptors</param> /// <returns></returns> /// <exception cref="ArgumentNullException">when <paramref name="unambiguousTemplateGroup"/>is <see cref="null"/></exception> /// <exception cref="ArgumentNullException">when <paramref name="commandInput"/>is <see cref="null"/></exception> private static CreationResultStatus DisplayAmbiguousPrecedenceError( TemplateGroup unambiguousTemplateGroup, IEngineEnvironmentSettings environmentSettings, INewCommandInput commandInput, IEnumerable <IInstallUnitDescriptor> installUnitDescriptors) { _ = unambiguousTemplateGroup ?? throw new ArgumentNullException(paramName: nameof(unambiguousTemplateGroup)); _ = unambiguousTemplateGroup ?? throw new ArgumentNullException(paramName: nameof(commandInput)); Reporter.Error.WriteLine(LocalizableStrings.AmbiguousTemplatesHeader.Bold().Red()); List <AmbiguousTemplateDetails> ambiguousTemplateDetails = new List <AmbiguousTemplateDetails>(); foreach (ITemplateMatchInfo template in unambiguousTemplateGroup.GetHighestPrecedenceInvokableTemplates(true)) { ambiguousTemplateDetails.Add(new AmbiguousTemplateDetails { TemplateIdentity = template.Info.Identity, TemplateName = template.Info.Name, TemplateShortName = template.Info.ShortName, TemplateLanguage = template.Info.GetLanguage(), TemplatePrecedence = template.Info.Precedence, TemplateAuthor = template.Info.Author, InstallationDescriptor = installUnitDescriptors?.FirstOrDefault(descriptor => descriptor.MountPointId == template.Info.ConfigMountPointId) }); } HelpFormatter <AmbiguousTemplateDetails> formatter = HelpFormatter .For( environmentSettings, commandInput, ambiguousTemplateDetails, columnPadding: 2, headerSeparator: '-', blankLineBetweenRows: false) .DefineColumn(t => t.TemplateIdentity, LocalizableStrings.ColumnNameIdentity, showAlways: true) .DefineColumn(t => t.TemplateName, LocalizableStrings.ColumnNameTemplateName, shrinkIfNeeded: true, minWidth: 15, showAlways: true) .DefineColumn(t => t.TemplateShortName, LocalizableStrings.ColumnNameShortName, showAlways: true) .DefineColumn(t => t.TemplateLanguage, LocalizableStrings.ColumnNameLanguage, showAlways: true) .DefineColumn(t => t.TemplatePrecedence.ToString(), out object prcedenceColumn, LocalizableStrings.ColumnNamePrecedence, showAlways: true) .DefineColumn(t => t.TemplateAuthor, LocalizableStrings.ColumnNameAuthor, showAlways: true, shrinkIfNeeded: true, minWidth: 10) .DefineColumn(t => t.InstallationDescriptor != null ? t.InstallationDescriptor.Identifier : string.Empty, LocalizableStrings.ColumnNamePackage, showAlways: true) .OrderByDescending(prcedenceColumn, new NullOrEmptyIsLastStringComparer()); Reporter.Error.WriteLine(formatter.Layout().Bold().Red()); string hintMessage = LocalizableStrings.AmbiguousTemplatesMultiplePackagesHint; if (unambiguousTemplateGroup.Templates.AllAreTheSame(t => t.Info.ConfigMountPointId)) { IInstallUnitDescriptor descriptor = installUnitDescriptors?.First(descriptor => descriptor.MountPointId == unambiguousTemplateGroup.Templates.First().Info.ConfigMountPointId); if (descriptor?.Details?.ContainsKey("NuGetPackageId") ?? false) { hintMessage = string.Format(LocalizableStrings.AmbiguousTemplatesSamePackageHint, descriptor.Identifier); } } Reporter.Error.WriteLine(hintMessage.Bold().Red()); return(CreationResultStatus.NotFound); }
private static async Task <CreationResultStatus> DisplayAmbiguousPrecedenceErrorAsync( TemplateGroup unambiguousTemplateGroup, IEngineEnvironmentSettings environmentSettings, INewCommandInput commandInput) { _ = unambiguousTemplateGroup ?? throw new ArgumentNullException(paramName: nameof(unambiguousTemplateGroup)); _ = unambiguousTemplateGroup ?? throw new ArgumentNullException(paramName: nameof(commandInput)); Reporter.Error.WriteLine(LocalizableStrings.AmbiguousTemplatesHeader.Bold().Red()); List <AmbiguousTemplateDetails> ambiguousTemplateDetails = new List <AmbiguousTemplateDetails>(); foreach (ITemplateMatchInfo template in unambiguousTemplateGroup.GetHighestPrecedenceInvokableTemplates(true)) { ambiguousTemplateDetails.Add(new AmbiguousTemplateDetails { TemplateIdentity = template.Info.Identity, TemplateName = template.Info.Name, TemplateShortNames = template.Info.ShortNameList, TemplateLanguage = template.Info.GetLanguage(), TemplatePrecedence = template.Info.Precedence, TemplateAuthor = template.Info.Author ?? string.Empty, TemplatePackage = await template.Info.GetTemplatePackageAsync(environmentSettings).ConfigureAwait(false) as IManagedTemplatePackage }); } HelpFormatter <AmbiguousTemplateDetails> formatter = HelpFormatter .For( environmentSettings, commandInput, ambiguousTemplateDetails, columnPadding: 2, headerSeparator: '-', blankLineBetweenRows: false) .DefineColumn(t => t.TemplateIdentity, LocalizableStrings.ColumnNameIdentity, showAlways: true) .DefineColumn(t => t.TemplateName, LocalizableStrings.ColumnNameTemplateName, shrinkIfNeeded: true, minWidth: 15, showAlways: true) .DefineColumn(t => string.Join(",", t.TemplateShortNames), LocalizableStrings.ColumnNameShortName, showAlways: true) .DefineColumn(t => t.TemplateLanguage, LocalizableStrings.ColumnNameLanguage, showAlways: true) .DefineColumn(t => t.TemplatePrecedence.ToString(), out object prcedenceColumn, LocalizableStrings.ColumnNamePrecedence, showAlways: true) .DefineColumn(t => t.TemplateAuthor, LocalizableStrings.ColumnNameAuthor, showAlways: true, shrinkIfNeeded: true, minWidth: 10) .DefineColumn(t => t.TemplatePackage != null ? t.TemplatePackage.Identifier : string.Empty, LocalizableStrings.ColumnNamePackage, showAlways: true) .OrderByDescending(prcedenceColumn, new NullOrEmptyIsLastStringComparer()); Reporter.Error.WriteLine(formatter.Layout().Bold().Red()); string hintMessage = LocalizableStrings.AmbiguousTemplatesMultiplePackagesHint; if (unambiguousTemplateGroup.Templates.AllAreTheSame(t => t.Info.MountPointUri)) { IManagedTemplatePackage?templatePackage = await unambiguousTemplateGroup.Templates.First().Info.GetTemplatePackageAsync(environmentSettings).ConfigureAwait(false) as IManagedTemplatePackage; if (templatePackage != null) { hintMessage = string.Format(LocalizableStrings.AmbiguousTemplatesSamePackageHint, templatePackage.Identifier); } } Reporter.Error.WriteLine(hintMessage.Bold().Red()); return(CreationResultStatus.NotFound); }
public void CanShowUserSelectedColumns() { ITemplateEngineHost host = new TestHost { HostIdentifier = "TestRunner", Version = "1.0.0.0", Locale = "en-US" }; IEngineEnvironmentSettings environmentSettings = new MockEngineEnvironmentSettings() { Host = host, Environment = new MockEnvironment() { ConsoleBufferWidth = 100 } }; INewCommandInput command = new MockNewCommandInput() { Columns = new List <string>() { "column3" } }; IEnumerable <Tuple <string, string, string> > data = new List <Tuple <string, string, string> >() { new Tuple <string, string, string>("My test data", "My test data", "Column 3 data"), new Tuple <string, string, string>("My test data", "My test data", "Column 3 data") }; string expectedOutput = $"Column 1 Column 3 {Environment.NewLine}------------ -------------{Environment.NewLine}My test data Column 3 data{Environment.NewLine}My test data Column 3 data{Environment.NewLine}"; HelpFormatter <Tuple <string, string, string> > formatter = HelpFormatter .For( environmentSettings, command, data, columnPadding: 2, headerSeparator: '-', blankLineBetweenRows: false) .DefineColumn(t => t.Item1, "Column 1", showAlways: true) .DefineColumn(t => t.Item2, "Column 2", columnName: "column2") //defaultColumn: true by default .DefineColumn(t => t.Item3, "Column 3", columnName: "column3", defaultColumn: false); string result = formatter.Layout(); Assert.Equal(expectedOutput, result); }
// Displays the list of templates in a table, one row per template group. // // The columns displayed are as follows: // Except where noted, the values are taken from the highest-precedence template in the group. The info could vary among the templates in the group, but shouldn't. // (There is no check that the info doesn't vary.) // - Template Name // - Short Name: displays the first short name from the highest precedence template in the group. // - Language: All languages supported by any template in the group are displayed, with the default language in brackets, e.g.: [C#] // - Tags private static void DisplayTemplateList(IReadOnlyList <ITemplateMatchInfo> templates, IEngineEnvironmentSettings environmentSettings, string language, string defaultLanguage) { IReadOnlyList <TemplateGroupForListDisplay> groupsForDisplay = GetTemplateGroupsForListDisplay(templates, language, defaultLanguage); HelpFormatter <TemplateGroupForListDisplay> formatter = HelpFormatter.For(environmentSettings, groupsForDisplay, 6, '-', false) .DefineColumn(t => t.Name, LocalizableStrings.Templates) .DefineColumn(t => t.ShortName, LocalizableStrings.ShortName) .DefineColumn(t => t.Languages, out object languageColumn, LocalizableStrings.Language) .DefineColumn(t => t.Classifications, out object tagsColumn, LocalizableStrings.Tags) .OrderByDescending(languageColumn, new NullOrEmptyIsLastStringComparer()) .OrderBy(tagsColumn); Reporter.Output.WriteLine(formatter.Layout()); }
// Displays the list of templates in a table, one row per template group. // // The columns displayed are as follows // Note: Except language, the values are taken from one template in the group. The info could vary among the templates in the group, but shouldn't. // There is no check that the info doesn't vary. // - Templates // - Short Name // - Language: All languages supported by the group are displayed, with the default language in brackets, e.g.: [C#] // - Tags private static void DisplayTemplateList(IReadOnlyList <ITemplateMatchInfo> templates, IEngineEnvironmentSettings environmentSettings, string language, string defaultLanguage) { IReadOnlyDictionary <ITemplateInfo, string> templateGroupsLanguages = GetLanguagesForTemplateGroups(templates, language, defaultLanguage); HelpFormatter <KeyValuePair <ITemplateInfo, string> > formatter = HelpFormatter.For(environmentSettings, templateGroupsLanguages, 6, '-', false) .DefineColumn(t => t.Key.Name, LocalizableStrings.Templates) .DefineColumn(t => t.Key.ShortName, LocalizableStrings.ShortName) .DefineColumn(t => t.Value, out object languageColumn, LocalizableStrings.Language) .DefineColumn(t => t.Key.Classifications != null ? string.Join("/", t.Key.Classifications) : null, out object tagsColumn, LocalizableStrings.Tags) .OrderByDescending(languageColumn, new NullOrEmptyIsLastStringComparer()) .OrderBy(tagsColumn); Reporter.Output.WriteLine(formatter.Layout()); }
public void CanShrinkMultipleColumns() { ITemplateEngineHost host = new TestHost { HostIdentifier = "TestRunner", Version = "1.0.0.0", Locale = "en-US" }; IEngineEnvironmentSettings environmentSettings = new MockEngineEnvironmentSettings() { Host = host, Environment = new MockEnvironment() { ConsoleBufferWidth = 5 + 2 + 7 + 1, } }; INewCommandInput command = new MockNewCommandInput(); IEnumerable <Tuple <string, string> > data = new List <Tuple <string, string> >() { new Tuple <string, string>("My test data", "My test data"), new Tuple <string, string>("My test data", "My test data") }; string expectedOutput = $"Co... Colu...{Environment.NewLine}----- -------{Environment.NewLine}My... My t...{Environment.NewLine}My... My t...{Environment.NewLine}"; HelpFormatter <Tuple <string, string> > formatter = HelpFormatter .For( environmentSettings, command, data, columnPadding: 2, headerSeparator: '-', blankLineBetweenRows: false) .DefineColumn(t => t.Item1, "Column 1", shrinkIfNeeded: true, minWidth: 2) .DefineColumn(t => t.Item2, "Column 2", shrinkIfNeeded: true, minWidth: 2); string result = formatter.Layout(); Assert.Equal(expectedOutput, result); }
public void CanRightAlign() { ITemplateEngineHost host = new TestHost { HostIdentifier = "TestRunner", Version = "1.0.0.0", Locale = "en-US" }; IEngineEnvironmentSettings environmentSettings = new MockEngineEnvironmentSettings() { Host = host, Environment = new MockEnvironment() { ConsoleBufferWidth = 10, //less than need for data below } }; INewCommandInput command = new MockNewCommandInput(); IEnumerable <Tuple <string, string> > data = new List <Tuple <string, string> >() { new Tuple <string, string>("Monday", "Wednesday"), new Tuple <string, string>("Tuesday", "Sunday") }; string expectedOutput = $"Column 1 Column 2{Environment.NewLine}-------- ---------{Environment.NewLine}Monday Wednesday{Environment.NewLine}Tuesday Sunday{Environment.NewLine}"; HelpFormatter <Tuple <string, string> > formatter = HelpFormatter .For( environmentSettings, command, data, columnPadding: 2, headerSeparator: '-', blankLineBetweenRows: false) .DefineColumn(t => t.Item1, "Column 1") .DefineColumn(t => t.Item2, "Column 2", rightAlign: true); string result = formatter.Layout(); Assert.Equal(expectedOutput, result); }
// Displays the list of templates in a table, one row per template group. // // The columns displayed are as follows: // Except where noted, the values are taken from the highest-precedence template in the group. The info could vary among the templates in the group, but shouldn't. // (There is no check that the info doesn't vary.) // - Template Name // - Short Name: displays the first short name from the highest precedence template in the group. // - Language: All languages supported by any template in the group are displayed, with the default language in brackets, e.g.: [C#] // - Tags private static void DisplayTemplateList(IReadOnlyCollection <IGrouping <string, ITemplateMatchInfo> > templates, IEngineEnvironmentSettings environmentSettings, string language, string defaultLanguage) { IReadOnlyCollection <TemplateGroupForListDisplay> groupsForDisplay = GetTemplateGroupsForListDisplay(templates, language, defaultLanguage); HelpFormatter <TemplateGroupForListDisplay> formatter = HelpFormatter .For( environmentSettings, groupsForDisplay, columnPadding: 2, headerSeparator: '-', blankLineBetweenRows: false) .DefineColumn(t => t.Name, LocalizableStrings.Templates, shrinkIfNeeded: true) .DefineColumn(t => t.ShortName, LocalizableStrings.ShortName) .DefineColumn(t => t.Languages, out object languageColumn, LocalizableStrings.Language) .DefineColumn(t => t.Classifications, out object tagsColumn, LocalizableStrings.Tags) .OrderByDescending(languageColumn, new NullOrEmptyIsLastStringComparer()) .OrderBy(tagsColumn); Reporter.Output.WriteLine(formatter.Layout()); }
public void CanShowAllColumns() { IEngineEnvironmentSettings environmentSettings = new MockEngineEnvironmentSettings() { Environment = new MockEnvironment() { ConsoleBufferWidth = 100 } }; INewCommandInput command = new MockNewCommandInput().WithCommandOption("--columns-all"); IEnumerable <Tuple <string, string, string> > data = new List <Tuple <string, string, string> >() { new Tuple <string, string, string>("Column 1 data", "Column 2 data", "Column 3 data"), new Tuple <string, string, string>("Column 1 data", "Column 2 data", "Column 3 data") }; string expectedOutput = $"Column 1 Column 2 Column 3 {Environment.NewLine}------------- ------------- -------------{Environment.NewLine}Column 1 data Column 2 data Column 3 data{Environment.NewLine}Column 1 data Column 2 data Column 3 data{Environment.NewLine}"; HelpFormatter <Tuple <string, string, string> > formatter = HelpFormatter .For( environmentSettings, command, data, columnPadding: 2, headerSeparator: '-', blankLineBetweenRows: false) .DefineColumn(t => t.Item1, "Column 1", showAlways: true) .DefineColumn(t => t.Item2, "Column 2", columnName: "column2") //defaultColumn: true by default .DefineColumn(t => t.Item3, "Column 3", columnName: "column3", defaultColumn: false); string result = formatter.Layout(); Assert.Equal(expectedOutput, result); }
public void CannotShrinkOverMinimumWidth() { IEngineEnvironmentSettings environmentSettings = new MockEngineEnvironmentSettings() { Environment = new MockEnvironment() { ConsoleBufferWidth = 10, //less than need for data below } }; INewCommandInput command = new MockNewCommandInput(); IEnumerable <Tuple <string, string> > data = new List <Tuple <string, string> >() { new Tuple <string, string>("My test data", "My test data"), new Tuple <string, string>("My test data", "My test data") }; string expectedOutput = $"Column 1 Column 2 {Environment.NewLine}------------ -----------{Environment.NewLine}My test data My test ...{Environment.NewLine}My test data My test ...{Environment.NewLine}"; HelpFormatter <Tuple <string, string> > formatter = HelpFormatter .For( environmentSettings, command, data, columnPadding: 2, headerSeparator: '-', blankLineBetweenRows: false) .DefineColumn(t => t.Item1, "Column 1", shrinkIfNeeded: true, minWidth: 15) .DefineColumn(t => t.Item2, "Column 2", shrinkIfNeeded: true, minWidth: 8); string result = formatter.Layout(); Assert.Equal(expectedOutput, result); }
public void CanShrinkMultipleColumnsAndBalanceShrinking() { IEngineEnvironmentSettings environmentSettings = new MockEngineEnvironmentSettings() { Environment = new MockEnvironment() { ConsoleBufferWidth = 6 + 2 + 6 + 1, } }; INewCommandInput command = new MockNewCommandInput(); IEnumerable <Tuple <string, string> > data = new List <Tuple <string, string> >() { new Tuple <string, string>("My test data", "My test data"), new Tuple <string, string>("My test data", "My test data") }; string expectedOutput = $"Col... Col...{Environment.NewLine}------ ------{Environment.NewLine}My ... My ...{Environment.NewLine}My ... My ...{Environment.NewLine}"; HelpFormatter <Tuple <string, string> > formatter = HelpFormatter .For( environmentSettings, command, data, columnPadding: 2, headerSeparator: '-', blankLineBetweenRows: false) .DefineColumn(t => t.Item1, "Column 1", shrinkIfNeeded: true, minWidth: 2) .DefineColumn(t => t.Item2, "Column 2", shrinkIfNeeded: true, minWidth: 2); string result = formatter.Layout(); Assert.Equal(expectedOutput, result); }
private static void ShowParameterHelp(IReadOnlyDictionary <string, string> inputParams, bool showImplicitlyHiddenParams, TemplateGroupParameterDetails parameterDetails, IEngineEnvironmentSettings environmentSettings) { if (!string.IsNullOrEmpty(parameterDetails.AdditionalInfo)) { Reporter.Error.WriteLine(parameterDetails.AdditionalInfo.Bold().Red()); Reporter.Output.WriteLine(); } IEnumerable <ITemplateParameter> filteredParams = TemplateParameterHelpBase.FilterParamsForHelp(parameterDetails.AllParams.ParameterDefinitions, parameterDetails.ExplicitlyHiddenParams, showImplicitlyHiddenParams, parameterDetails.HasPostActionScriptRunner, parameterDetails.ParametersToAlwaysShow); if (filteredParams.Any()) { HelpFormatter <ITemplateParameter> formatter = new HelpFormatter <ITemplateParameter>(environmentSettings, filteredParams, 2, null, true); formatter.DefineColumn( param => { string options; if (string.Equals(param.Name, "allow-scripts", StringComparison.OrdinalIgnoreCase)) { options = "--" + param.Name; } else { // the key is guaranteed to exist IList <string> variants = parameterDetails.GroupVariantsForCanonicals[param.Name].ToList(); options = string.Join("|", variants.Reverse()); } return(" " + options); }, LocalizableStrings.Options ); formatter.DefineColumn(delegate(ITemplateParameter param) { StringBuilder displayValue = new StringBuilder(255); displayValue.AppendLine(param.Documentation); if (string.Equals(param.DataType, "choice", StringComparison.OrdinalIgnoreCase)) { int longestChoiceLength = param.Choices.Keys.Max(x => x.Length); foreach (KeyValuePair <string, string> choiceInfo in param.Choices) { displayValue.Append(" " + choiceInfo.Key.PadRight(longestChoiceLength + 4)); if (!string.IsNullOrWhiteSpace(choiceInfo.Value)) { displayValue.Append("- " + choiceInfo.Value); } displayValue.AppendLine(); } } else { displayValue.Append(param.DataType ?? "string"); displayValue.AppendLine(" - " + param.Priority.ToString()); } // display the configured value if there is one string configuredValue = null; if (parameterDetails.AllParams.ResolvedValues.TryGetValue(param, out object resolvedValueObject)) { string resolvedValue = resolvedValueObject as string; if (!string.IsNullOrEmpty(resolvedValue) && !string.IsNullOrEmpty(param.DefaultValue) && !string.Equals(param.DefaultValue, resolvedValue)) { configuredValue = resolvedValue; } } if (string.IsNullOrEmpty(configuredValue)) { // this will catch when the user inputs the default value. The above deliberately skips it on the resolved values. if (string.Equals(param.DataType, "bool", StringComparison.OrdinalIgnoreCase) && parameterDetails.GroupUserParamsWithDefaultValues.Contains(param.Name)) { configuredValue = "true"; } else { inputParams.TryGetValue(param.Name, out configuredValue); } } if (!string.IsNullOrEmpty(configuredValue)) { string realValue = configuredValue; if (parameterDetails.InvalidParams.Contains(param.Name) || (string.Equals(param.DataType, "choice", StringComparison.OrdinalIgnoreCase) && !param.Choices.ContainsKey(configuredValue))) { realValue = realValue.Bold().Red(); } else if (parameterDetails.AllParams.TryGetRuntimeValue(environmentSettings, param.Name, out object runtimeVal) && runtimeVal != null) { realValue = runtimeVal.ToString(); } displayValue.AppendLine(string.Format(LocalizableStrings.ConfiguredValue, realValue)); } // display the default value if there is one if (!string.IsNullOrEmpty(param.DefaultValue)) { displayValue.AppendLine(string.Format(LocalizableStrings.DefaultValue, param.DefaultValue)); } return(displayValue.ToString()); }, string.Empty); Reporter.Output.WriteLine(formatter.Layout()); } else { Reporter.Output.WriteLine(LocalizableStrings.NoParameters); } }
private static void ShowParameterHelp(IReadOnlyDictionary <string, string> inputParams, bool showImplicitlyHiddenParams, TemplateGroupParameterDetails parameterDetails, IEngineEnvironmentSettings environmentSettings, INewCommandInput commandInput) { IEnumerable <ITemplateParameter> filteredParams = TemplateParameterHelpBase.FilterParamsForHelp( parameterDetails.AllParams.ParameterDefinitions, parameterDetails.ExplicitlyHiddenParams, showImplicitlyHiddenParams, parameterDetails.HasPostActionScriptRunner, parameterDetails.ParametersToAlwaysShow); if (filteredParams.Any()) { HelpFormatter <ITemplateParameter> formatter = new HelpFormatter <ITemplateParameter>(environmentSettings, commandInput, filteredParams, 2, null, true); formatter.DefineColumn( param => { string options; if (string.Equals(param.Name, "allow-scripts", StringComparison.OrdinalIgnoreCase)) { options = "--" + param.Name; } else { // the key is guaranteed to exist IList <string> variants = parameterDetails.GroupVariantsForCanonicals[param.Name].ToList(); options = string.Join("|", variants.Reverse()); } return(" " + options); }, LocalizableStrings.Options ); formatter.DefineColumn( delegate(ITemplateParameter param) { StringBuilder displayValue = new StringBuilder(255); displayValue.AppendLine(param.Documentation); if (string.Equals(param.DataType, "choice", StringComparison.OrdinalIgnoreCase)) { int longestChoiceLength = param.Choices.Keys.Max(x => x.Length); foreach (KeyValuePair <string, ParameterChoice> choiceInfo in param.Choices) { displayValue.Append(" " + choiceInfo.Key.PadRight(longestChoiceLength + 4)); if (!string.IsNullOrWhiteSpace(choiceInfo.Value.Description)) { displayValue.Append("- " + choiceInfo.Value.Description); } displayValue.AppendLine(); } } else { displayValue.Append(param.DataType ?? "string"); displayValue.AppendLine(" - " + param.Priority.ToString()); } // determine the configured value string configuredValue = null; if (parameterDetails.AllParams.ResolvedValues.TryGetValue(param, out object resolvedValueObject)) { // Set the configured value as long as it's non-empty and not the default value. // If it's the default, we're not sure if it was explicitly entered or not. // Below, there's a check if the user entered a value. If so, set it. string resolvedValue = resolvedValueObject?.ToString() ?? string.Empty; if (!string.IsNullOrEmpty(resolvedValue)) { // bools get ToString() values of "True" & "False", but most templates use "true" & "false" // So do a case-insensitive comparison on bools, case-sensitive on other values. StringComparison comparisonType = string.Equals(param.DataType, "bool", StringComparison.OrdinalIgnoreCase) ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal; if (!string.Equals(param.DefaultValue, resolvedValue, comparisonType)) { configuredValue = resolvedValue; } } } // If the resolved value is null/empty, or the default, only display the configured value if // the user explicitly specified it or if it can be resolved from the DefaultIfOptionWithoutValue (or bool='true' for backwards compat). if (string.IsNullOrEmpty(configuredValue)) { bool handled = false; if (parameterDetails.GroupUserParamsWithDefaultValues.Contains(param.Name)) { if (param is IAllowDefaultIfOptionWithoutValue parameterWithNoValueDefault) { if (!string.IsNullOrEmpty(parameterWithNoValueDefault.DefaultIfOptionWithoutValue)) { configuredValue = parameterWithNoValueDefault.DefaultIfOptionWithoutValue; handled = true; } } else if (string.Equals(param.DataType, "bool", StringComparison.OrdinalIgnoreCase)) { // Before the introduction of DefaultIfOptionWithoutValue, bool params were handled like this. // Other param types didn't have any analogous handling. configuredValue = "true"; handled = true; } } if (!handled) { // If the user explicitly specified the switch, the value is in the inputParams, so try to retrieve it here. inputParams.TryGetValue(param.Name, out configuredValue); } } // display the configured value if there is one if (!string.IsNullOrEmpty(configuredValue)) { string realValue = configuredValue; if (parameterDetails.InvalidParams.Contains(param.Name) || (string.Equals(param.DataType, "choice", StringComparison.OrdinalIgnoreCase) && !param.Choices.ContainsKey(configuredValue))) { realValue = realValue.Bold().Red(); } else if (parameterDetails.AllParams.TryGetRuntimeValue(environmentSettings, param.Name, out object runtimeVal) && runtimeVal != null) { realValue = runtimeVal.ToString(); } displayValue.AppendLine(string.Format(LocalizableStrings.ConfiguredValue, realValue)); } // display the default value if there is one if (!string.IsNullOrWhiteSpace(param.DefaultValue)) { displayValue.AppendLine(string.Format(LocalizableStrings.DefaultValue, param.DefaultValue)); } if (param is IAllowDefaultIfOptionWithoutValue paramWithNoValueDefault && !string.IsNullOrWhiteSpace(paramWithNoValueDefault.DefaultIfOptionWithoutValue)) { // default if option is provided without a value should not be displayed if: // - it is bool parameter with "DefaultIfOptionWithoutValue": "true" // - it is not bool parameter (int, string, etc) and default value coincides with "DefaultIfOptionWithoutValue" if (string.Equals(param.DataType, "bool", StringComparison.OrdinalIgnoreCase)) { if (!string.Equals(paramWithNoValueDefault.DefaultIfOptionWithoutValue, "true", StringComparison.OrdinalIgnoreCase)) { displayValue.AppendLine(string.Format(LocalizableStrings.DefaultIfOptionWithoutValue, paramWithNoValueDefault.DefaultIfOptionWithoutValue)); } } else { if (!string.Equals(paramWithNoValueDefault.DefaultIfOptionWithoutValue, param.DefaultValue, StringComparison.Ordinal)) { displayValue.AppendLine(string.Format(LocalizableStrings.DefaultIfOptionWithoutValue, paramWithNoValueDefault.DefaultIfOptionWithoutValue)); } } } return(displayValue.ToString()); }, string.Empty); Reporter.Output.WriteLine(formatter.Layout()); } else { Reporter.Output.WriteLine(LocalizableStrings.NoParameters); } }