Skip to content

Commit 0a947b3

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 bb2dc72 commit 0a947b3

17 files changed

+233
-8
lines changed

src/chocolatey/StringResources.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,15 @@ public static class EnvironmentVariables
5656
[Browsable(false)]
5757
internal const string PackageNuspecVersion = "packageNuspecVersion";
5858
}
59+
60+
public static class OptionDescriptions
61+
{
62+
public const string DISPLAY_HEADERS = "Display headers - Display headers when limit-output is used. Requires 2.3.0";
63+
}
64+
65+
public static class Options
66+
{
67+
public const string DISPLAY_HEADERS = "headers"; // TODO: This option name needs to be decided and agreed upon.
68+
}
5969
}
60-
}
70+
}

src/chocolatey/infrastructure.app/ApplicationParameters.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ public static class Features
226226
public static readonly string LogValidationResultsOnWarnings = "logValidationResultsOnWarnings";
227227
public static readonly string UsePackageRepositoryOptimizations = "usePackageRepositoryOptimizations";
228228
public static readonly string DisableCompatibilityChecks = "disableCompatibilityChecks";
229+
public static readonly string AlwaysDisplayHeaders = "alwaysDisplayHeaders";
229230
}
230231

231232
public static class Messages

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,8 @@ private static void SetAllFeatureFlags(ChocolateyConfiguration config, ConfigFil
334334
config.Features.LogValidationResultsOnWarnings = SetFeatureFlag(ApplicationParameters.Features.LogValidationResultsOnWarnings, configFileSettings, defaultEnabled: true, description: "Log validation results on warnings - Should the validation results be logged if there are warnings?");
335335
config.Features.UsePackageRepositoryOptimizations = SetFeatureFlag(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 earlier versions of Chocolatey.");
336336
config.PromptForConfirmation = !SetFeatureFlag(ApplicationParameters.Features.AllowGlobalConfirmation, configFileSettings, defaultEnabled: false, description: "Prompt for confirmation in scripts or bypass.");
337-
config.DisableCompatibilityChecks = SetFeatureFlag(ApplicationParameters.Features.DisableCompatibilityChecks, configFileSettings, defaultEnabled: false, description: "Disable Compatibility Checks - Disable showing a warning when there is an incompatibility between Chocolatey CLI and Chocolatey Licensed Extension. Available in 1.1.0+");
337+
config.DisableCompatibilityChecks = SetFeatureFlag(ApplicationParameters.Features.DisableCompatibilityChecks, configFileSettings, defaultEnabled: false, description: "Disable Compatibility Checks - Disable showing a warning when there is an incompatibility between Chocolatey CLI and Chocolatey Licensed Extension. Available in 1.1.0+"),
338+
config.DisplayHeaders = SetFeatureFlag(ApplicationParameters.Features.AlwaysDisplayHeaders, configFileSettings, defaultEnabled: false, description: StringResources.OptionDescriptions.DISPLAY_HEADERS);
338339
}
339340

340341
private static bool SetFeatureFlag(string featureName, ConfigFileSettings configFileSettings, bool defaultEnabled, string description)

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ public virtual void ConfigureArgumentParser(OptionSet optionSet, ChocolateyConfi
5050
.Add("k=|key=|apikey=|api-key=",
5151
"ApiKey - The API key for the source. This is the authentication that identifies you and allows you to push to a source. With some sources this is either a key or it could be a user name and password specified as 'user:password'.",
5252
option => configuration.ApiKeyCommand.Key = option.UnquoteSafe())
53+
.Add(StringResources.Options.DISPLAY_HEADERS,
54+
StringResources.OptionDescriptions.DISPLAY_HEADERS,
55+
option => configuration.DisplayHeaders = true)
5356
;
5457
}
5558

@@ -192,6 +195,11 @@ public virtual void Run(ChocolateyConfiguration configuration)
192195
_configSettingsService.SetApiKey(configuration);
193196
break;
194197
default:
198+
if (!configuration.RegularOutput && configuration.DisplayHeaders)
199+
{
200+
this.Log().Info("Source|Key");
201+
}
202+
195203
_configSettingsService.GetApiKey(configuration, (key) =>
196204
{
197205
string authenticatedString = string.IsNullOrWhiteSpace(key.Key) ? string.Empty : "(Authenticated)";

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ public virtual void ConfigureArgumentParser(OptionSet optionSet, ChocolateyConfi
5151
"value=",
5252
"Value - the value of the config setting. Required with some actions. Defaults to empty.",
5353
option => configuration.ConfigCommand.ConfigValue = option.UnquoteSafe())
54+
.Add(
55+
StringResources.Options.DISPLAY_HEADERS,
56+
StringResources.OptionDescriptions.DISPLAY_HEADERS,
57+
option => configuration.DisplayHeaders = true)
5458
;
5559
}
5660

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ public virtual void ConfigureArgumentParser(OptionSet optionSet, ChocolateyConfi
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.UnquoteSafe())
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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ public override void ConfigureArgumentParser(OptionSet optionSet, ChocolateyConf
7474
configuration.Features.UsePackageRepositoryOptimizations = false;
7575
}
7676
})
77+
.Add(StringResources.Options.DISPLAY_HEADERS,
78+
StringResources.OptionDescriptions.DISPLAY_HEADERS,
79+
option => configuration.DisplayHeaders = true)
7780
;
7881
}
7982

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,10 @@ public virtual void ConfigureArgumentParser(OptionSet optionSet, ChocolateyConfi
134134
option => configuration.ListCommand.IdStartsWith = option != null)
135135
.Add("detail|detailed",
136136
"Detailed - Alias for verbose.",
137-
option => configuration.Verbose = option != null);
137+
option => configuration.Verbose = option != null),
138+
.Add(StringResources.Options.DISPLAY_HEADER,
139+
StringResources.OptionDescriptions.DISPLAY_HEADER,
140+
option => configuration.DisplayHeaders = true);
138141
}
139142

140143
public virtual int Count(ChocolateyConfiguration config)

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ public virtual void ConfigureArgumentParser(OptionSet optionSet, ChocolateyConfi
7272
configuration.Features.UsePackageRepositoryOptimizations = false;
7373
}
7474
})
75+
.Add(StringResources.Options.DISPLAY_HEADERS,
76+
StringResources.OptionDescriptions.DISPLAY_HEADERS,
77+
option => configuration.DisplayHeaders = true)
7578
;
7679
}
7780

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ public virtual void ConfigureArgumentParser(OptionSet optionSet, ChocolateyConfi
5656
.Add("version=",
5757
"Version - Used when multiple versions of a package are installed. Defaults to empty.",
5858
option => configuration.Version = option.UnquoteSafe())
59+
.Add(StringResources.Options.DISPLAY_HEADERS,
60+
StringResources.OptionDescriptions.DISPLAY_HEADERS,
61+
option => configuration.DisplayHeaders = true)
5962
;
6063
}
6164

@@ -169,6 +172,11 @@ public virtual void ListPins(ChocolateyConfiguration config)
169172
config.QuietOutput = quiet;
170173
config.Input = input;
171174

175+
if (!config.RegularOutput && config.DisplayHeaders)
176+
{
177+
this.Log().Info("PackageId|Version");
178+
}
179+
172180
foreach (var pkg in packages.OrEmpty())
173181
{
174182
var pkgInfo = _packageInfoService.Get(pkg.PackageMetadata);

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ public virtual void ConfigureArgumentParser(OptionSet optionSet, ChocolateyConfi
7575
.Add("adminonly|admin-only",
7676
"Visible to Administrators Only - Should this source be visible to non-administrators? Requires business edition (v1.12.2+). Defaults to false.",
7777
option => configuration.SourceCommand.VisibleToAdminsOnly = option != null)
78+
.Add(StringResources.Options.DISPLAY_HEADERS,
79+
StringResources.OptionDescriptions.DISPLAY_HEADERS,
80+
option => configuration.DisplayHeaders = true)
7881
;
7982
}
8083

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@ public void ConfigureArgumentParser(OptionSet optionSet, ChocolateyConfiguration
4545
optionSet
4646
.Add("n=|name=",
4747
"The name of the template to get information about.",
48-
option => configuration.TemplateCommand.Name = option.UnquoteSafe().ToLower());
48+
option => configuration.TemplateCommand.Name = option.UnquoteSafe().ToLower()),
49+
.Add(StringResources.Options.DISPLAY_HEADERS,
50+
StringResources.OptionDescriptions.DISPLAY_HEADERS,
51+
option => configuration.DisplayHeaders = true);
4952
// todo: #2570 Allow for templates from an external path? Requires #1477
5053
}
5154

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ public ChocolateyConfiguration()
5858
ExportCommand = new ExportCommandConfiguration();
5959
TemplateCommand = new TemplateCommandConfiguration();
6060
CacheCommand = new CacheCommandConfiguration();
61+
DisplayHeaders = false;
6162
#if DEBUG
6263
AllowUnofficialBuild = true;
6364
#endif
@@ -358,6 +359,7 @@ private void AppendOutput(StringBuilder propertyValues, string append)
358359
public string DownloadChecksumType { get; set; }
359360
public string DownloadChecksumType64 { get; set; }
360361
public bool PinPackage { get; set; }
362+
public bool DisplayHeaders { get; set; }
361363

362364
/// <summary>
363365
/// Configuration values provided by choco.

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ public virtual bool SkipSource(ConfigFileSourceSetting source, ChocolateyConfigu
6262

6363
public virtual IEnumerable<ChocolateySource> ListSources(ChocolateyConfiguration configuration)
6464
{
65+
if (!configuration.RegularOutput && configuration.DisplayHeaders)
66+
{
67+
this.Log().Info("SourceId|Location|Disabled|UserName|Certificate|Priority|BypassProxy|AllowSelfService|AdminOnly");
68+
}
6569
var list = new List<ChocolateySource>();
6670
foreach (var source in ConfigFileSettings.Sources.OrEmpty().OrderBy(s => s.Id))
6771
{
@@ -218,6 +222,11 @@ public void EnableSource(ChocolateyConfiguration configuration)
218222

219223
public void ListFeatures(ChocolateyConfiguration configuration)
220224
{
225+
if (!configuration.RegularOutput && configuration.DisplayHeaders)
226+
{
227+
this.Log().Info("FeatureName|Enabled|Description");
228+
}
229+
221230
foreach (var feature in ConfigFileSettings.Features.OrEmpty().OrderBy(f => f.Name))
222231
{
223232
if (configuration.RegularOutput)
@@ -387,6 +396,11 @@ public void RemoveApiKey(ChocolateyConfiguration configuration)
387396

388397
public void ListConfig(ChocolateyConfiguration configuration)
389398
{
399+
if (!configuration.RegularOutput && configuration.DisplayHeaders)
400+
{
401+
this.Log().Info("Name|Value|Description");
402+
}
403+
390404
foreach (var config in ConfigFileSettings.ConfigSettings.OrEmpty().OrderBy(c => c.Key))
391405
{
392406
if (configuration.RegularOutput)

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

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,18 @@ public virtual IEnumerable<PackageResult> List(ChocolateyConfiguration config)
255255
yield break;
256256
}
257257

258-
if (config.RegularOutput) this.Log().Debug(() => "Searching for package information");
258+
if (config.RegularOutput)
259+
{
260+
// This doesn't make sense as a Debug message to me... Debug messages don't really show up when you're running normally...
261+
this.Log().Debug(() => "Searching for package information");
262+
}
263+
else
264+
{
265+
if (config.DisplayHeaders)
266+
{
267+
this.Log().Info("PackageID|Version");
268+
}
269+
}
259270

260271
var packages = new List<PackageResult>();
261272

@@ -758,9 +769,19 @@ public virtual void Outdated(ChocolateyConfiguration config)
758769
return;
759770
}
760771

761-
if (config.RegularOutput) this.Log().Info(ChocolateyLoggers.Important, @"Outdated Packages
772+
if (config.RegularOutput)
773+
{
774+
this.Log().Info(ChocolateyLoggers.Important, @"Outdated Packages
762775
Output is package name | current version | available version | pinned?
763776
");
777+
}
778+
else
779+
{
780+
if (config.DisplayHeaders)
781+
{
782+
this.Log().Info("PackageName|CurrentVersion|AvailableVersion|Pinned");
783+
}
784+
}
764785

765786
config.PackageNames = ApplicationParameters.AllPackages;
766787
config.UpgradeCommand.NotifyOnlyAvailableUpgrades = true;

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,11 @@ public void List(ChocolateyConfiguration configuration)
227227

228228
if (string.IsNullOrWhiteSpace(configuration.TemplateCommand.Name))
229229
{
230+
if (!configuration.RegularOutput && configuration.DisplayHeaders)
231+
{
232+
this.Log().Info("TemplateName|Version");
233+
}
234+
230235
if (templateDirList.Any())
231236
{
232237
foreach (var templateDir in templateDirList)
@@ -235,11 +240,11 @@ public void List(ChocolateyConfiguration configuration)
235240
ListCustomTemplateInformation(configuration);
236241
}
237242

238-
this.Log().Info(configuration.RegularOutput ? "{0} Custom templates found at {1}{2}".FormatWith(templateDirList.Count(), ApplicationParameters.TemplatesLocation, Environment.NewLine) : string.Empty);
243+
this.Log().Info(configuration.RegularOutput ? ChocolateyLoggers.Normal : ChocolateyLoggers.LogFileOnly, "{0} Custom templates found at {1}{2}".FormatWith(templateDirList.Count(), ApplicationParameters.TemplatesLocation, Environment.NewLine));
239244
}
240245
else
241246
{
242-
this.Log().Info(configuration.RegularOutput ? "No custom templates installed in {0}{1}".FormatWith(ApplicationParameters.TemplatesLocation, Environment.NewLine) : string.Empty);
247+
this.Log().Info(configuration.RegularOutput ? ChocolateyLoggers.Normal : ChocolateyLoggers.LogFileOnly, "No custom templates installed in {0}{1}".FormatWith(ApplicationParameters.TemplatesLocation, Environment.NewLine));
243248
}
244249

245250
ListBuiltinTemplateInformation(configuration, isBuiltInTemplateOverridden, isBuiltInOrDefaultTemplateDefault);

0 commit comments

Comments
 (0)