Skip to content

Commit 6f7b2e4

Browse files
authored
Add info command to display key information (#461)
1 parent 23535d2 commit 6f7b2e4

File tree

17 files changed

+546
-17
lines changed

17 files changed

+546
-17
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ choco install wingetcreate
5252
| [Token](doc/token.md) | Command for managing cached GitHub personal access tokens |
5353
| [Settings](doc/settings.md) | Command for editing the settings file configurations |
5454
| [Cache](doc/cache.md) | Command for managing downloaded installers stored in cache
55+
| [Info](doc/info.md) | Displays information about the client |
5556
| [-?](doc/help.md) | Displays command line help |
5657

5758
Click on the individual commands to learn more.

doc/info.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# info command (Winget-Create)
2+
3+
The **info** command of the [Winget-Create](../README.md) tool is used to show useful information about the client. This information includes the location of the settings file, the local installer cache (download directory) and the logs directory. It also offers links to external resources like the GitHub repository and privacy statement.
4+
5+
## Usage
6+
7+
* Display information related to the client: `wingetcreate.exe info`

doc/settings.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ If set to true, the `telemetry.disable` setting will prevent any event from bein
2121

2222
## CleanUp
2323

24-
The `CleanUp` settings determine whether Winget-Create will handle the removal of temporary files (installer cache and logs) generated during the manifest creation process. These settings provide control over the decision to remove files or not and the frequency at which this clean up occurs.
24+
The `CleanUp` settings determine whether Winget-Create will handle the removal of temporary files i.e., installers downloaded and logs generated during the manifest creation process. You can view the location of these files using the [info](./info.md) command. These settings provide control over the decision to remove files or not and the frequency at which this clean up occurs.
2525

2626
### disable
2727

@@ -60,3 +60,17 @@ The `name` setting specifies the name of the targeted GitHub repository. By defa
6060
"name": "winget-pkgs"
6161
}
6262
```
63+
64+
## Visual
65+
66+
The `Visual` settings control the appearance of the Winget-Create CLI output.
67+
68+
### anonymizePaths
69+
70+
The `anonymizePaths` setting controls whether the paths of files and directories are anonymized in the Winget-Create CLI output. This means that a path such as `C:\Users\user\Documents\manifests\` will be displayed as `%USERPROFILE%\Documents\manifests` (i.e., substitute environment variables where possible). By default, this is set to `true`.
71+
72+
```json
73+
"Visual": {
74+
"anonymizePaths": true
75+
}
76+
```

src/WingetCreateCLI/Commands/BaseCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ protected static string SaveManifestDirToLocalPath(
194194
}
195195

196196
Console.WriteLine();
197-
Logger.InfoLocalized(nameof(Resources.ManifestSaved_Message), fullDirPath);
197+
Logger.InfoLocalized(nameof(Resources.ManifestSaved_Message), Common.GetPathForDisplay(fullDirPath, UserSettings.AnonymizePaths));
198198
Console.WriteLine();
199199

200200
return fullDirPath;
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
// Licensed under the MIT license.
3+
4+
namespace Microsoft.WingetCreateCLI.Commands
5+
{
6+
using System;
7+
using System.IO;
8+
using System.Threading.Tasks;
9+
using CommandLine;
10+
using Microsoft.WingetCreateCLI.Logging;
11+
using Microsoft.WingetCreateCLI.Properties;
12+
using Microsoft.WingetCreateCLI.Telemetry;
13+
using Microsoft.WingetCreateCLI.Telemetry.Events;
14+
using Microsoft.WingetCreateCore;
15+
using Microsoft.WingetCreateCore.Common;
16+
17+
/// <summary>
18+
/// Info command to display general information regarding the tool.
19+
/// </summary>
20+
[Verb("info", HelpText = "InfoCommand_HelpText", ResourceType = typeof(Resources))]
21+
public class InfoCommand : BaseCommand
22+
{
23+
/// <summary>
24+
/// Executes the info command flow.
25+
/// </summary>
26+
/// <returns>Boolean representing success or fail of the command.</returns>
27+
public override async Task<bool> Execute()
28+
{
29+
CommandExecutedEvent commandEvent = new CommandExecutedEvent
30+
{
31+
Command = nameof(InfoCommand),
32+
};
33+
34+
DisplayApplicationHeaderAndCopyright();
35+
Console.WriteLine();
36+
DisplaySystemInformation();
37+
Console.WriteLine();
38+
DisplayInfoTable();
39+
40+
TelemetryManager.Log.WriteEvent(commandEvent);
41+
return await Task.FromResult(commandEvent.IsSuccessful = true);
42+
}
43+
44+
private static void DisplayApplicationHeaderAndCopyright()
45+
{
46+
Console.WriteLine(string.Format(
47+
Resources.Heading,
48+
Utils.GetEntryAssemblyVersion()) +
49+
Environment.NewLine +
50+
Constants.MicrosoftCopyright);
51+
}
52+
53+
private static void DisplaySystemInformation()
54+
{
55+
Logger.DebugLocalized(nameof(Resources.OperatingSystem_Info), Environment.OSVersion.VersionString);
56+
Logger.DebugLocalized(nameof(Resources.SystemArchitecture_Info), System.Runtime.InteropServices.RuntimeInformation.OSArchitecture);
57+
}
58+
59+
private static void DisplayInfoTable()
60+
{
61+
string logsdirectory = Common.GetPathForDisplay(Path.Combine(Common.LocalAppStatePath, Constants.DiagnosticOutputDirectoryFolderName), UserSettings.AnonymizePaths);
62+
string settingsDirectory = Common.GetPathForDisplay(UserSettings.SettingsJsonPath, UserSettings.AnonymizePaths);
63+
string installerCacheDirectory = Common.GetPathForDisplay(PackageParser.InstallerDownloadPath, UserSettings.AnonymizePaths);
64+
65+
new TableOutput(Resources.WingetCreateDirectories_Heading, Resources.Path_Heading)
66+
.AddRow(Resources.Logs_Heading, logsdirectory)
67+
.AddRow(Resources.UserSettings_Heading, settingsDirectory)
68+
.AddRow(Resources.InstallerCache_Heading, installerCacheDirectory)
69+
.Print();
70+
71+
Console.WriteLine();
72+
73+
new TableOutput(Resources.Links_Heading, string.Empty)
74+
.AddRow(Resources.PrivacyStatement_Heading, Constants.PrivacyStatementUrl)
75+
.AddRow(Resources.LicenseAgreement_Heading, Constants.LicenseUrl)
76+
.AddRow(Resources.ThirdPartyNotices_Heading, Constants.ThirdPartyNoticeUrl)
77+
.AddRow(Resources.Homepage_Heading, Constants.HomePageUrl)
78+
.Print();
79+
}
80+
}
81+
}

src/WingetCreateCLI/Common.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ namespace Microsoft.WingetCreateCLI
1313
public static class Common
1414
{
1515
private const string ModuleName = "WindowsPackageManagerManifestCreator";
16+
private const string UserProfileEnvironmentVariable = "%USERPROFILE%";
17+
private const string LocalAppDataEnvironmentVariable = "%LOCALAPPDATA%";
18+
private const string TempEnvironmentVariable = "%TEMP%";
1619

1720
private static readonly Lazy<string> AppStatePathLazy = new(() =>
1821
{
@@ -61,6 +64,39 @@ public static void CleanUpFilesOlderThan(string cleanUpDirectory, int cleanUpDay
6164
}
6265
}
6366

67+
/// <summary>
68+
/// Gets the path for display. This will anonymize the path if caller provides the appropriate flag.
69+
/// </summary>
70+
/// <param name="path">Path to be displayed.</param>
71+
/// <param name="substituteEnvironmentVariables">Whether or not to substitute environment variables.</param>
72+
/// <returns>Anonymized path or original path.</returns>
73+
public static string GetPathForDisplay(string path, bool substituteEnvironmentVariables = true)
74+
{
75+
if (string.IsNullOrEmpty(path) || !substituteEnvironmentVariables)
76+
{
77+
return path;
78+
}
79+
80+
string userProfilePath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
81+
string localAppDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
82+
string tempPath = Path.GetTempPath().TrimEnd(Path.DirectorySeparatorChar);
83+
84+
if (path.StartsWith(tempPath, StringComparison.OrdinalIgnoreCase))
85+
{
86+
return path.Replace(tempPath, TempEnvironmentVariable, StringComparison.OrdinalIgnoreCase);
87+
}
88+
else if (path.StartsWith(localAppDataPath, StringComparison.OrdinalIgnoreCase))
89+
{
90+
return path.Replace(localAppDataPath, LocalAppDataEnvironmentVariable, StringComparison.OrdinalIgnoreCase);
91+
}
92+
else if (path.StartsWith(userProfilePath, StringComparison.OrdinalIgnoreCase))
93+
{
94+
return path.Replace(userProfilePath, UserProfileEnvironmentVariable, StringComparison.OrdinalIgnoreCase);
95+
}
96+
97+
return path;
98+
}
99+
64100
private static bool IsRunningAsUwp()
65101
{
66102
DesktopBridge.Helpers helpers = new DesktopBridge.Helpers();

src/WingetCreateCLI/Logger/Logger.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ namespace Microsoft.WingetCreateCLI.Logging
77
using System.Globalization;
88
using System.IO;
99
using Microsoft.WingetCreateCLI.Properties;
10+
using Microsoft.WingetCreateCore.Common;
1011
using NLog;
1112
using NLog.Conditions;
1213
using NLog.Config;
@@ -21,7 +22,7 @@ public static class Logger
2122

2223
private static readonly FileTarget FileTarget = new()
2324
{
24-
FileName = @$"{Path.Combine(Common.LocalAppStatePath, "DiagOutputDir")}\WingetCreateLog-{DateTime.Now:yyyy-MM-dd-HH-mm.fff}.txt",
25+
FileName = @$"{Path.Combine(Common.LocalAppStatePath, Constants.DiagnosticOutputDirectoryFolderName)}\WingetCreateLog-{DateTime.Now:yyyy-MM-dd-HH-mm.fff}.txt",
2526

2627
// Current layout example: 2021-01-01 08:30:59.0000|INFO|Microsoft.WingetCreateCLI.Commands.NewCommand.Execute|Log Message Example
2728
Layout = "${longdate}|${level:uppercase=true}|${callsite}|${message}",

src/WingetCreateCLI/Models/SettingsModel.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,17 @@ public partial class WindowsPackageManagerRepository
4848
public string Name { get; set; } = "winget-pkgs";
4949

5050

51+
}
52+
53+
/// <summary>Visual settings</summary>
54+
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.4.3.0 (Newtonsoft.Json v11.0.0.0)")]
55+
public partial class Visual
56+
{
57+
/// <summary>Controls whether paths displayed on the console are substituted with environment variables</summary>
58+
[Newtonsoft.Json.JsonProperty("anonymizePaths", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
59+
public bool AnonymizePaths { get; set; } = true;
60+
61+
5162
}
5263

5364
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.4.3.0 (Newtonsoft.Json v11.0.0.0)")]
@@ -69,6 +80,10 @@ public partial class SettingsManifest
6980
[System.ComponentModel.DataAnnotations.Required]
7081
public WindowsPackageManagerRepository WindowsPackageManagerRepository { get; set; } = new WindowsPackageManagerRepository();
7182

83+
[Newtonsoft.Json.JsonProperty("Visual", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
84+
[System.ComponentModel.DataAnnotations.Required]
85+
public Visual Visual { get; set; } = new Visual();
86+
7287

7388
}
74-
}
89+
}

src/WingetCreateCLI/Program.cs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ private static async Task<int> Main(string[] args)
4747
typeof(TokenCommand),
4848
typeof(CacheCommand),
4949
typeof(ShowCommand),
50+
typeof(InfoCommand),
5051
};
5152
var parserResult = myParser.ParseArguments(args, types);
5253

@@ -59,9 +60,11 @@ private static async Task<int> Main(string[] args)
5960
return args.Any() ? 1 : 0;
6061
}
6162

62-
if (command is not SettingsCommand && command is not CacheCommand)
63+
bool commandHandlesToken = command is not CacheCommand and not InfoCommand and not SettingsCommand;
64+
65+
// Do not load github client for commands that do not deal with a GitHub token.
66+
if (commandHandlesToken)
6367
{
64-
// Do not load github client for settings or cache command.
6568
if (await command.LoadGitHubClient())
6669
{
6770
try
@@ -71,7 +74,7 @@ private static async Task<int> Main(string[] args)
7174
if (trimmedVersion != Utils.GetEntryAssemblyVersion())
7275
{
7376
Logger.WarnLocalized(nameof(Resources.OutdatedVersionNotice_Message));
74-
Logger.WarnLocalized(nameof(Resources.GetLatestVersion_Message), latestVersion, "https://github.com/microsoft/winget-create/releases");
77+
Logger.WarnLocalized(nameof(Resources.GetLatestVersion_Message), latestVersion, Constants.GitHubReleasesUrl);
7578
Logger.WarnLocalized(nameof(Resources.UpgradeUsingWinget_Message));
7679
Console.WriteLine();
7780
}
@@ -113,7 +116,7 @@ private static async Task<int> Main(string[] args)
113116
if (!UserSettings.CleanUpDisabled)
114117
{
115118
Common.CleanUpFilesOlderThan(PackageParser.InstallerDownloadPath, UserSettings.CleanUpDays);
116-
Common.CleanUpFilesOlderThan(Path.Combine(Common.LocalAppStatePath, "DiagOutputDir"), UserSettings.CleanUpDays);
119+
Common.CleanUpFilesOlderThan(Path.Combine(Common.LocalAppStatePath, Constants.DiagnosticOutputDirectoryFolderName), UserSettings.CleanUpDays);
117120
}
118121
}
119122
}
@@ -126,11 +129,13 @@ private static void DisplayHelp(NotParsed<object> result)
126129
{
127130
h.AddDashesToOption = true;
128131
h.AdditionalNewLineAfterOption = false;
129-
h.Heading = string.Format(Resources.Heading, Utils.GetEntryAssemblyVersion()) + Environment.NewLine;
132+
h.Heading = string.Format(Resources.Heading, Utils.GetEntryAssemblyVersion());
130133
h.Copyright = Constants.MicrosoftCopyright;
131134
h.AddNewLineBetweenHelpSections = true;
132135
h.AddPreOptionsLine(Resources.AppDescription_HelpText);
133-
h.AddPostOptionsLines(new string[] { Resources.MoreHelp_HelpText, Resources.PrivacyStatement_HelpText });
136+
h.AddPreOptionsLine(Environment.NewLine);
137+
h.AddPreOptionsLine(Resources.CommandsAvailable_Message);
138+
h.AddPostOptionsLines(new string[] { Resources.MoreHelp_HelpText, string.Format(Resources.PrivacyStatement_HelpText, Constants.PrivacyStatementUrl) });
134139
h.MaximumDisplayWidth = 100;
135140
h.AutoHelp = false;
136141
h.AutoVersion = false;

0 commit comments

Comments
 (0)