Skip to content

Commit de62fd2

Browse files
committed
(chocolatey#2591) Add headers to limit output commands
When a user asks for limited output from Chocolatey, it is not uncommon to pipe that output to `ConvertFrom-String` or `ConvertFrom-Csv` and manually add headers to get back an object. This allows for getting a header row back so that the end user doesn't need to add their own headers and discern what they are. This also adds a StringResources static class that allows us to store constant strings in and use them across the code to reduce duplication.
1 parent e35fe2b commit de62fd2

18 files changed

+271
-26
lines changed

src/chocolatey/StringResources.cs

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
6+
namespace chocolatey
7+
{
8+
public static class StringResources
9+
{
10+
public static class OptionDescriptions
11+
{
12+
public const string DISPLAY_HEADERS = "Display headers - Display headers when limit-output is used. Requires <INSERT RELEASED VERSION HERE>";
13+
}
14+
15+
public static class Options
16+
{
17+
public const string DISPLAY_HEADERS = "display-headers|use-headers";
18+
}
19+
}
20+
}

src/chocolatey/chocolatey.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,7 @@
360360
<Compile Include="ObjectExtensions.cs" />
361361
<Compile Include="Properties\AssemblyInfo.cs" />
362362
<Compile Include="StringExtensions.cs" />
363+
<Compile Include="StringResources.cs" />
363364
<Compile Include="TypeExtensions.cs" />
364365
</ItemGroup>
365366
<ItemGroup>

src/chocolatey/infrastructure.app/ApplicationParameters.cs

+1
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ public static class Features
208208
public static readonly string LogValidationResultsOnWarnings = "logValidationResultsOnWarnings";
209209
public static readonly string UsePackageRepositoryOptimizations = "usePackageRepositoryOptimizations";
210210
public static readonly string DisableCompatibilityChecks = "disableCompatibilityChecks";
211+
public static readonly string AlwaysDisplayHeaders = "alwaysDisplayHeaders";
211212
}
212213

213214
public static class Messages

src/chocolatey/infrastructure.app/builders/ConfigurationBuilder.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,8 @@ private static void set_feature_flags(ChocolateyConfiguration config, ConfigFile
318318
config.Features.LogValidationResultsOnWarnings = set_feature_flag(ApplicationParameters.Features.LogValidationResultsOnWarnings, configFileSettings, defaultEnabled: true, description: "Log validation results on warnings - Should the validation results be logged if there are warnings? Available in 0.10.12+.");
319319
config.Features.UsePackageRepositoryOptimizations = set_feature_flag(ApplicationParameters.Features.UsePackageRepositoryOptimizations, configFileSettings, defaultEnabled: true, description: "Use Package Repository Optimizations - Turn on optimizations for reducing bandwidth with repository queries during package install/upgrade/outdated operations. Should generally be left enabled, unless a repository needs to support older methods of query. When disabled, this makes queries similar to the way they were done in Chocolatey v0.10.11 and before. Available in 0.10.14+.");
320320
config.PromptForConfirmation = !set_feature_flag(ApplicationParameters.Features.AllowGlobalConfirmation, configFileSettings, defaultEnabled: false, description: "Prompt for confirmation in scripts or bypass.");
321-
config.DisableCompatibilityChecks = set_feature_flag(ApplicationParameters.Features.DisableCompatibilityChecks, configFileSettings, defaultEnabled: false, description: "Disable Compatibility Checks - Should a warning we shown, before and after command execution, when a runtime compatibility check determines that there is an incompatibility between Chocolatey and Chocolatey Licensed Extension. Available in 1.1.0+");
321+
config.DisableCompatibilityChecks = set_feature_flag(ApplicationParameters.Features.DisableCompatibilityChecks, configFileSettings, defaultEnabled: false, description: "Disable Compatibility Checks - Should a warning be shown, before and after command execution, when a runtime compatibility check determines that there is an incompatibility between Chocolatey and Chocolatey Licensed Extension. Available in 1.1.0+");
322+
config.DisplayHeaders = set_feature_flag(ApplicationParameters.Features.AlwaysDisplayHeaders, configFileSettings, defaultEnabled: false, description: StringResources.OptionDescriptions.DISPLAY_HEADERS);
322323
}
323324

324325
private static bool set_feature_flag(string featureName, ConfigFileSettings configFileSettings, bool defaultEnabled, string description)

src/chocolatey/infrastructure.app/commands/ChocolateyApiKeyCommand.cs

+8
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyCon
5151
.Add("rem|remove",
5252
"Removes an API key from Chocolatey",
5353
option => configuration.ApiKeyCommand.Remove = true)
54+
.Add(StringResources.Options.DISPLAY_HEADERS,
55+
StringResources.OptionDescriptions.DISPLAY_HEADERS,
56+
option => configuration.DisplayHeaders = true)
5457
;
5558
}
5659

@@ -156,6 +159,11 @@ public virtual void run(ChocolateyConfiguration configuration)
156159
}
157160
else if (string.IsNullOrWhiteSpace(configuration.ApiKeyCommand.Key))
158161
{
162+
if (!configuration.RegularOutput && configuration.DisplayHeaders)
163+
{
164+
this.Log().Info("Source|Key");
165+
}
166+
159167
_configSettingsService.get_api_key(configuration, (key) =>
160168
{
161169
string authenticatedString = string.IsNullOrWhiteSpace(key.Key) ? string.Empty : "(Authenticated)";

src/chocolatey/infrastructure.app/commands/ChocolateyConfigCommand.cs

+3
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyCon
5151
"value=",
5252
"Value - the value of the config setting. Required with some actions. Defaults to empty.",
5353
option => configuration.ConfigCommand.ConfigValue = option.remove_surrounding_quotes())
54+
.Add(StringResources.Options.DISPLAY_HEADERS,
55+
StringResources.OptionDescriptions.DISPLAY_HEADERS,
56+
option => configuration.DisplayHeaders = true)
5457
;
5558
}
5659

src/chocolatey/infrastructure.app/commands/ChocolateyFeatureCommand.cs

+3
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyCon
4747
.Add("n=|name=",
4848
"Name - the name of the source. Required with actions other than list. Defaults to empty.",
4949
option => configuration.FeatureCommand.Name = option.remove_surrounding_quotes())
50+
.Add(StringResources.Options.DISPLAY_HEADERS,
51+
StringResources.OptionDescriptions.DISPLAY_HEADERS,
52+
option => configuration.DisplayHeaders = true)
5053
;
5154
}
5255

src/chocolatey/infrastructure.app/commands/ChocolateyInfoCommand.cs

+3
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ public override void configure_argument_parser(OptionSet optionSet, ChocolateyCo
7373
configuration.Features.UsePackageRepositoryOptimizations = false;
7474
}
7575
})
76+
.Add(StringResources.Options.DISPLAY_HEADERS,
77+
StringResources.OptionDescriptions.DISPLAY_HEADERS,
78+
option => configuration.DisplayHeaders = true)
7679
;
7780
}
7881

src/chocolatey/infrastructure.app/commands/ChocolateyListCommand.cs

+3
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,9 @@ public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyCon
136136
configuration.Features.UsePackageRepositoryOptimizations = false;
137137
}
138138
})
139+
.Add(StringResources.Options.DISPLAY_HEADERS,
140+
StringResources.OptionDescriptions.DISPLAY_HEADERS,
141+
option => configuration.DisplayHeaders = true)
139142
;
140143
}
141144

src/chocolatey/infrastructure.app/commands/ChocolateyOutdatedCommand.cs

+3
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyCon
7171
configuration.Features.UsePackageRepositoryOptimizations = false;
7272
}
7373
})
74+
.Add(StringResources.Options.DISPLAY_HEADERS,
75+
StringResources.OptionDescriptions.DISPLAY_HEADERS,
76+
option => configuration.DisplayHeaders = true)
7477
;
7578
}
7679

src/chocolatey/infrastructure.app/commands/ChocolateyPinCommand.cs

+7
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyCon
5454
.Add("version=",
5555
"Version - Used when multiple versions of a package are installed. Defaults to empty.",
5656
option => configuration.Version = option.remove_surrounding_quotes())
57+
.Add(StringResources.Options.DISPLAY_HEADERS,
58+
StringResources.OptionDescriptions.DISPLAY_HEADERS,
59+
option => configuration.DisplayHeaders = true)
5760
;
5861
}
5962

@@ -172,6 +175,10 @@ public virtual void list_pins(IPackageManager packageManager, ChocolateyConfigur
172175
config.QuietOutput = quiet;
173176
config.Input = input;
174177

178+
if (!config.RegularOutput && config.DisplayHeaders)
179+
{
180+
this.Log().Info("PackageId|Version");
181+
}
175182
foreach (var pkg in packages.or_empty_list_if_null())
176183
{
177184
var pkgInfo = _packageInfoService.get_package_information(pkg.Package);

src/chocolatey/infrastructure.app/commands/ChocolateySourceCommand.cs

+3
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyCon
7474
.Add("adminonly|admin-only",
7575
"Visible to Administrators Only - Should this source be visible to non-administrators? Requires business edition (v1.12.2+). Defaults to false. Available in 0.10.8+.",
7676
option => configuration.SourceCommand.VisibleToAdminsOnly = option != null)
77+
.Add(StringResources.Options.DISPLAY_HEADERS,
78+
StringResources.OptionDescriptions.DISPLAY_HEADERS,
79+
option => configuration.DisplayHeaders = true)
7780
;
7881
}
7982

src/chocolatey/infrastructure.app/commands/ChocolateyTemplateCommand.cs

+5-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,11 @@ public void configure_argument_parser(OptionSet optionSet, ChocolateyConfigurati
4444
optionSet
4545
.Add("n=|name=",
4646
"The name of the template to get information about.",
47-
option => configuration.TemplateCommand.Name = option.remove_surrounding_quotes().ToLower());
47+
option => configuration.TemplateCommand.Name = option.remove_surrounding_quotes().ToLower())
48+
.Add(StringResources.Options.DISPLAY_HEADERS,
49+
StringResources.OptionDescriptions.DISPLAY_HEADERS,
50+
option => configuration.DisplayHeaders = true)
51+
;
4852
// todo: #2570 Allow for templates from an external path? Requires #1477
4953
}
5054

src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs

+2
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public ChocolateyConfiguration()
5656
Proxy = new ProxyConfiguration();
5757
ExportCommand = new ExportCommandConfiguration();
5858
TemplateCommand = new TemplateCommandConfiguration();
59+
DisplayHeaders = false;
5960
#if DEBUG
6061
AllowUnofficialBuild = true;
6162
#endif
@@ -328,6 +329,7 @@ private void append_output(StringBuilder propertyValues, string append)
328329
public string DownloadChecksumType { get; set; }
329330
public string DownloadChecksumType64 { get; set; }
330331
public bool PinPackage { get; set; }
332+
public bool DisplayHeaders { get; set; }
331333

332334
/// <summary>
333335
/// Configuration values provided by choco.

src/chocolatey/infrastructure.app/services/ChocolateyConfigSettingsService.cs

+45-20
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ public virtual bool skip_source(ConfigFileSourceSetting source, ChocolateyConfig
6161

6262
public virtual IEnumerable<ChocolateySource> source_list(ChocolateyConfiguration configuration)
6363
{
64+
if (!configuration.RegularOutput && configuration.DisplayHeaders)
65+
{
66+
this.Log().Info("SourceId|Location|Disabled|UserName|Certificate|Priority|BypassProxy|AllowSelfService|AdminOnly");
67+
}
68+
6469
var list = new List<ChocolateySource>();
6570
foreach (var source in configFileSettings.Sources)
6671
{
@@ -217,6 +222,11 @@ public void source_enable(ChocolateyConfiguration configuration)
217222

218223
public void feature_list(ChocolateyConfiguration configuration)
219224
{
225+
if (!configuration.RegularOutput && configuration.DisplayHeaders)
226+
{
227+
this.Log().Info("FeatureName|Enabled|Description");
228+
}
229+
220230
foreach (var feature in configFileSettings.Features)
221231
{
222232
if (configuration.RegularOutput)
@@ -364,27 +374,42 @@ public void remove_api_key(ChocolateyConfiguration configuration)
364374

365375
public void config_list(ChocolateyConfiguration configuration)
366376
{
367-
this.Log().Info(ChocolateyLoggers.Important, "Settings");
368-
foreach (var config in configFileSettings.ConfigSettings)
369-
{
370-
this.Log().Info(() => "{0} = {1} | {2}".format_with(config.Key, config.Value, config.Description));
371-
}
372-
373-
this.Log().Info("");
374-
this.Log().Info(ChocolateyLoggers.Important, "Sources");
375-
source_list(configuration);
376-
this.Log().Info("");
377-
this.Log().Info(@"NOTE: Use choco source to interact with sources.");
378-
this.Log().Info("");
379-
this.Log().Info(ChocolateyLoggers.Important, "Features");
380-
feature_list(configuration);
381-
this.Log().Info("");
382-
this.Log().Info(@"NOTE: Use choco feature to interact with features.");
383-
;
384-
this.Log().Info("");
385-
this.Log().Info(ChocolateyLoggers.Important, "API Keys");
386-
this.Log().Info(@"NOTE: Api Keys are not shown through this command.
377+
if (configuration.RegularOutput)
378+
{
379+
this.Log().Info(ChocolateyLoggers.Important, "Settings");
380+
foreach (var config in configFileSettings.ConfigSettings)
381+
{
382+
this.Log().Info(() => "{0} = {1} | {2}".format_with(config.Key, config.Value, config.Description));
383+
}
384+
385+
this.Log().Info("");
386+
this.Log().Info(ChocolateyLoggers.Important, "Sources");
387+
source_list(configuration);
388+
this.Log().Info("");
389+
this.Log().Info(@"NOTE: Use choco source to interact with sources.");
390+
this.Log().Info("");
391+
this.Log().Info(ChocolateyLoggers.Important, "Features");
392+
feature_list(configuration);
393+
this.Log().Info("");
394+
this.Log().Info(@"NOTE: Use choco feature to interact with features.");
395+
;
396+
this.Log().Info("");
397+
this.Log().Info(ChocolateyLoggers.Important, "API Keys");
398+
this.Log().Info(@"NOTE: Api Keys are not shown through this command.
387399
Use choco apikey to interact with API keys.");
400+
}
401+
else
402+
{
403+
if (configuration.DisplayHeaders)
404+
{
405+
this.Log().Info("Name|Value|Description");
406+
}
407+
408+
foreach (var config in configFileSettings.ConfigSettings)
409+
{
410+
this.Log().Info(() => "{0}|{1}|{2}".format_with(config.Key, config.Value, config.Description));
411+
}
412+
}
388413
}
389414

390415
public void config_get(ChocolateyConfiguration configuration)

src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs

+22-2
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,17 @@ public virtual IEnumerable<PackageResult> list_run(ChocolateyConfiguration confi
174174
yield break;
175175
}
176176

177-
if (config.RegularOutput) this.Log().Debug(() => "Searching for package information");
177+
if (config.RegularOutput)
178+
{
179+
this.Log().Debug(() => "Searching for package information");
180+
}
181+
else
182+
{
183+
if (config.DisplayHeaders)
184+
{
185+
this.Log().Info("PackageID|Version");
186+
}
187+
}
178188

179189
var packages = new List<IPackage>();
180190

@@ -643,9 +653,19 @@ public virtual void outdated_run(ChocolateyConfiguration config)
643653
return;
644654
}
645655

646-
if (config.RegularOutput) this.Log().Info(ChocolateyLoggers.Important, @"Outdated Packages
656+
if (config.RegularOutput)
657+
{
658+
this.Log().Info(ChocolateyLoggers.Important, @"Outdated Packages
647659
Output is package name | current version | available version | pinned?
648660
");
661+
}
662+
else
663+
{
664+
if(config.DisplayHeaders)
665+
{
666+
this.Log().Info("PackageName|CurrentVersion|AvailableVersion|Pinned");
667+
}
668+
}
649669

650670
config.PackageNames = ApplicationParameters.AllPackages;
651671
config.UpgradeCommand.NotifyOnlyAvailableUpgrades = true;

src/chocolatey/infrastructure.app/services/TemplateService.cs

+7-2
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,11 @@ public void list(ChocolateyConfiguration configuration)
232232

233233
if (string.IsNullOrWhiteSpace(configuration.TemplateCommand.Name))
234234
{
235+
if (!configuration.RegularOutput && configuration.DisplayHeaders)
236+
{
237+
this.Log().Info("TemplateName|Version");
238+
}
239+
235240
if (templateDirList.Any())
236241
{
237242
foreach (var templateDir in templateDirList)
@@ -240,11 +245,11 @@ public void list(ChocolateyConfiguration configuration)
240245
list_custom_template_info(configuration, packageManager);
241246
}
242247

243-
this.Log().Info(configuration.RegularOutput ? "{0} Custom templates found at {1}{2}".format_with(templateDirList.Count(), ApplicationParameters.TemplatesLocation, Environment.NewLine) : string.Empty);
248+
this.Log().Info(configuration.RegularOutput ? ChocolateyLoggers.Normal : ChocolateyLoggers.LogFileOnly, "{0} Custom templates found at {1}{2}".format_with(templateDirList.Count(), ApplicationParameters.TemplatesLocation, Environment.NewLine));
244249
}
245250
else
246251
{
247-
this.Log().Info(configuration.RegularOutput ? "No custom templates installed in {0}{1}".format_with(ApplicationParameters.TemplatesLocation, Environment.NewLine) : string.Empty);
252+
this.Log().Info(configuration.RegularOutput ? ChocolateyLoggers.Normal : ChocolateyLoggers.LogFileOnly, "No custom templates installed in {0}{1}".format_with(ApplicationParameters.TemplatesLocation, Environment.NewLine));
248253
}
249254

250255
list_built_in_template_info(configuration, isBuiltInTemplateOverriden, isBuiltInOrDefaultTemplateDefault);

0 commit comments

Comments
 (0)