microsoft / winget-cli

WinGet is the Windows Package Manager. This project includes a CLI (Command Line Interface), PowerShell modules, and a COM (Component Object Model) API (Application Programming Interface).
https://learn.microsoft.com/windows/package-manager/
MIT License
22.5k stars 1.39k forks source link

Allow controlling log level and output type using CLI arguments and environment variables #4508

Open mattmazzola opened 1 month ago

mattmazzola commented 1 month ago

Description of the new feature / enhancement

Issue

As far as I know there is only an option to increase verbosity of log level output via the --verbose argument, but there is not a way to decrease the log level.

The reason decreasing the level is desired is to make the logs more scannable when output in terminals which do not allow ANSI escape sequences to properly render progress indicators.

Advanced Terminal

For example, in an advanced terminal such as Windows Terminal winget could render an indeterminant progress indicator

Input:

winget configuration validate -f .\configurations\settings.dsc.yaml

Output Loop:

\ Retrieving configuration details

Final Output:

Validation found no issues.

This results in a nice compact total of

winget configuration validate -f .\configurations\settings.dsc.yaml
Validation found no issues.

Basic Terminal

I am using winget in a Github Action which is where the issue occurs. The rotating bar prints many new lines without offering any value to the user. This is wasteful and makes it hard to scan

  winget configuration validate -f .\configurations\settings.dsc.yaml
  shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'"

   - Initializing configuration system

   - Reading configuration file
   - Retrieving configuration details
   \ Retrieving configuration details
   - Retrieving configuration details
   ... <many lines removed>
   - Retrieving configuration details
   \ Retrieving configuration details
   | Retrieving configuration details
   | Retrieving configuration details
   / Retrieving configuration details
   - Retrieving configuration details
   \ Retrieving configuration details

Validation found no issues.

Proposed technical implementation details

Argument Options

How to make it work by default (use Environment variables)

It is common convention that tools behave differently when the CI=true flag is present. In other words, when CI=true, winget automatically applies No Progress, or ANSI output

This is enabled or set by default in ADO and Github so developers can use the same commands they are used to locally and they work properly without change in CI.

Could also add support for:

WINGET_LOGLEVEL
WINGET_NO_PROGRESS
Trenly commented 1 month ago

I know its not a perfect solution, but the log level can be controlled through the settings file - which could be written in the runner before executing winget

https://learn.microsoft.com/en-us/windows/package-manager/winget/settings#logging-settings https://github.com/microsoft/winget-cli/blob/master/doc/Settings.md#logging

mattmazzola commented 3 weeks ago

Thanks for the suggestion and links to information.

I think there is tradeoff between cost of implementation the settings hack vs cost of implementing some type of --no-progress flag.

From what I understand, writting a settings.json file is easy, it can even be hardcoded.

{
    "$schema": "https://aka.ms/winget-settings.schema.json",
    "logging": {
        "level": "warning"
    },
}

The hard part is dynamically figuring out the correct path to write the file based on the installed location

Issue is that the winget --info doesn't even print out the full path. It gets clipped even when writing output to file which is strange.

winget --info > winget_info.txt
code .\winget_info.txt
 winget --info
Windows Package Manager v1.7.11261
Copyright (c) Microsoft Corporation. All rights reserved.

Windows: Windows.Desktop v10.0.22631.3593
System Architecture: X64
Package: Microsoft.DesktopAppInstaller v1.22.11261.0

Winget Directories
-----------------------------------------------------------------------------------------------------------------------
Logs                               %LOCALAPPDATA%\Packages\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\LocalState\Diag…
User Settings                      %LOCALAPPDATA%\Packages\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\LocalState\sett…
Portable Links Directory (User)    %LOCALAPPDATA%\Microsoft\WinGet\Links

Example: C:\Users\mattm\AppData\Local\Packages\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\LocalState\settings.json

I tried to implement the suggestion of dynamically creating a settings.json file with logging set to something "lower" than default of "info" such as "warning"; however, it did not have the desired effect of preventing log output. I suspect the future winget calls from subsequent steps are not actually using the settings although I don't know why.

$settingsPath = $(winget --info | Select-String -Pattern "%LOCALAPPDATA%\\Packages\\Microsoft.DesktopAppInstaller_[\w]*\\LocalState\\s" | ForEach-Object { $_.Matches.Value -replace '\\s', '\settings.json' })
$expandedSettingsPath = [System.Environment]::ExpandEnvironmentVariables($settingsPath)
$settingsContent = Get-Content "./settings.json"
$settingsContent | Set-Content $expandedSettingsPath

Can see the build logs which still output the spinning bar progress loop