Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Ignore Warnings suppress the output level entirely #4221

Merged
merged 15 commits into from
Mar 15, 2024
1 change: 1 addition & 0 deletions src/AppInstallerCLICore/Argument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,7 @@ namespace AppInstaller::CLI
args.push_back(ForType(Args::Type::RainbowStyle));
args.push_back(ForType(Args::Type::RetroStyle));
args.push_back(ForType(Args::Type::VerboseLogs));
args.push_back(ForType(Args::Type::IgnoreWarnings));
args.emplace_back(Args::Type::DisableInteractivity, Resource::String::DisableInteractivityArgumentDescription, ArgumentType::Flag, false);
}

Expand Down
4 changes: 4 additions & 0 deletions src/AppInstallerCLICore/ChannelStreams.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ namespace AppInstaller::CLI::Execution
OutputStream& operator<<(const VirtualTerminal::ConstructedSequence& sequence);
OutputStream& operator<<(const std::filesystem::path& path);

inline bool IsEnabled() {
return m_enabled;
}

private:
// Applies the format for the stream.
void ApplyFormat();
Expand Down
1 change: 0 additions & 1 deletion src/AppInstallerCLICore/Commands/ValidateCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ namespace AppInstaller::CLI
{
return {
Argument::ForType(Execution::Args::Type::ValidateManifest),
Argument::ForType(Execution::Args::Type::IgnoreWarnings),
};
}

Expand Down
6 changes: 6 additions & 0 deletions src/AppInstallerCLICore/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,12 @@ namespace AppInstaller::CLI
Logging::Log().SetLevel(Logging::Level::Verbose);
}

// Disable warnings if requested
if (context.Args.Contains(Execution::Args::Type::IgnoreWarnings))
{
context.Reporter.SetLevelMask(Execution::Reporter::Level::Warning, false);
}

context.UpdateForArgs();
context.SetExecutingCommand(command.get());
command->ValidateArguments(context.Args);
Expand Down
23 changes: 23 additions & 0 deletions src/AppInstallerCLICore/ExecutionReporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ namespace AppInstaller::CLI::Execution

OutputStream Reporter::GetOutputStream(Level level)
{
// If the level is not enabled, return a default stream which is disabled
if (WI_AreAllFlagsClear(m_enabledLevels, level))
{
return OutputStream(*m_out, false, false);
}

OutputStream result = GetBasicOutputStream();

switch (level)
Expand Down Expand Up @@ -164,6 +170,11 @@ namespace AppInstaller::CLI::Execution
void Reporter::PromptForEnter(Level level)
{
auto out = GetOutputStream(level);
if (!out.IsEnabled())
{
return;
}

out << std::endl << Resource::String::PressEnterToContinue << std::endl;
m_in.get();
}
Expand Down Expand Up @@ -319,4 +330,16 @@ namespace AppInstaller::CLI::Execution
}
m_out->RestoreDefault();
}

void Reporter::SetLevelMask(Level reporterLevel, bool setEnabled) {

if (setEnabled)
{
WI_SetAllFlags(m_enabledLevels, reporterLevel);
}
else
{
WI_ClearAllFlags(m_enabledLevels, reporterLevel);
}
}
}
28 changes: 20 additions & 8 deletions src/AppInstallerCLICore/ExecutionReporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,14 @@ namespace AppInstaller::CLI::Execution
};

// The level for the Output channel.
enum class Level
enum class Level : uint32_t
{
Verbose,
Info,
Warning,
Error,
None = 0x0,
Verbose = 0x1,
Info = 0x2,
Warning = 0x4,
Error = 0x8,
All = Verbose | Info | Warning | Error,
};

Reporter(std::ostream& outStream, std::istream& inStream);
Expand Down Expand Up @@ -98,13 +100,13 @@ namespace AppInstaller::CLI::Execution
void SetStyle(AppInstaller::Settings::VisualStyle style);

// Prompts the user, return true if they consented.
bool PromptForBoolResponse(Resource::LocString message, Level level = Level::Info);
bool PromptForBoolResponse(Resource::LocString message, Level level);
Trenly marked this conversation as resolved.
Show resolved Hide resolved

// Prompts the user, continues when Enter is pressed
void PromptForEnter(Level level = Level::Info);

// Prompts the user for a path.
std::filesystem::path PromptForPath(Resource::LocString message, Level level = Level::Info);
std::filesystem::path PromptForPath(Resource::LocString message, Level level);

// Used to show indefinite progress. Currently an indefinite spinner is the form of
// showing indefinite progress.
Expand Down Expand Up @@ -165,9 +167,14 @@ namespace AppInstaller::CLI::Execution
m_progressSink = sink;
}

void SetLevelMask(Level reporterLevel, bool setEnabled = true);

Level GetLevelMask() {
Trenly marked this conversation as resolved.
Show resolved Hide resolved
return m_enabledLevels;
}

private:
Reporter(std::shared_ptr<BaseStream> outStream, std::istream& inStream);

// Gets a stream for output for internal use.
OutputStream GetBasicOutputStream();

Expand All @@ -180,8 +187,13 @@ namespace AppInstaller::CLI::Execution
wil::srwlock m_progressCallbackLock;
std::atomic<ProgressCallback*> m_progressCallback;
std::atomic<IProgressSink*> m_progressSink;

// Enable all levels by default
Level m_enabledLevels = Level::All;
};

DEFINE_ENUM_FLAG_OPERATORS(Reporter::Level);

// Indirection to enable change without tracking down every place
extern const VirtualTerminal::Sequence& HelpCommandEmphasis;
extern const VirtualTerminal::Sequence& HelpArgumentEmphasis;
Expand Down
32 changes: 24 additions & 8 deletions src/AppInstallerCLICore/Workflows/PromptFlow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,29 @@
#include "ShowFlow.h"
#include <winget/UserSettings.h>

using namespace AppInstaller::CLI::Execution;
using namespace AppInstaller::Settings;
using namespace AppInstaller::Utility::literals;

namespace AppInstaller::CLI::Workflow
{
namespace
{
bool IsInteractivityAllowed(Execution::Context& context, Reporter::Level reporterLevel) {
Trenly marked this conversation as resolved.
Show resolved Hide resolved
// Interactivity can be disabled for several reasons:
// * We are running in a non-interactive context (e.g., COM call)
// * It is disabled in the settings
// * It was disabled from the command line
// * The output level required has been disabled
if (WI_AreAllFlagsClear(context.Reporter.GetLevelMask(), reporterLevel))
{
AICLI_LOG(CLI, Verbose, << "Skipping prompt. Interactivity is disabled due to reporter level being suppressed");
return false;
}

return IsInteractivityAllowed(context);
}

bool IsInteractivityAllowed(Execution::Context& context)
{
// Interactivity can be disabled for several reasons:
Expand Down Expand Up @@ -88,9 +104,9 @@ namespace AppInstaller::CLI::Workflow

bool accepted = context.Args.Contains(Execution::Args::Type::AcceptSourceAgreements);

if (!accepted && IsInteractivityAllowed(context))
if (!accepted && IsInteractivityAllowed(context, Reporter::Level::Info))
{
accepted = context.Reporter.PromptForBoolResponse(Resource::String::SourceAgreementsPrompt);
accepted = context.Reporter.PromptForBoolResponse(Resource::String::SourceAgreementsPrompt, Reporter::Level::Info);
}

if (accepted)
Expand Down Expand Up @@ -198,9 +214,9 @@ namespace AppInstaller::CLI::Workflow
if (showPrompt)
{
AICLI_LOG(CLI, Verbose, << "Prompting to accept package agreements");
if (IsInteractivityAllowed(context))
if (IsInteractivityAllowed(context, Reporter::Level::Info))
{
bool accepted = context.Reporter.PromptForBoolResponse(Resource::String::PackageAgreementsPrompt);
bool accepted = context.Reporter.PromptForBoolResponse(Resource::String::PackageAgreementsPrompt, Reporter::Level::Info);
if (accepted)
{
AICLI_LOG(CLI, Info, << "Package agreements accepted in prompt");
Expand Down Expand Up @@ -286,15 +302,15 @@ namespace AppInstaller::CLI::Workflow
private:
void PromptForInstallRoot(Execution::Context& context)
{
if (!IsInteractivityAllowed(context))
if (!IsInteractivityAllowed(context, Reporter::Level::Info))
{
AICLI_LOG(CLI, Error, << "Install location is required but was not provided.");
context.Reporter.Error() << Resource::String::InstallLocationNotProvided << std::endl;
AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_INSTALL_LOCATION_REQUIRED);
}

AICLI_LOG(CLI, Info, << "Prompting for install root.");
m_installLocation = context.Reporter.PromptForPath(Resource::String::PromptForInstallRoot);
m_installLocation = context.Reporter.PromptForPath(Resource::String::PromptForInstallRoot, Reporter::Level::Info);
AICLI_LOG(CLI, Info, << "Proceeding with installation using install root: " << m_installLocation);
}

Expand Down Expand Up @@ -349,12 +365,12 @@ namespace AppInstaller::CLI::Workflow
void PromptToProceed(Execution::Context& context)
{
AICLI_LOG(CLI, Info, << "Prompting before proceeding with installer that aborts terminal.");
if (!IsInteractivityAllowed(context))
if (!IsInteractivityAllowed(context, Reporter::Level::Warning))
{
return;
}

bool accepted = context.Reporter.PromptForBoolResponse(Resource::String::PromptToProceed, Execution::Reporter::Level::Warning);
bool accepted = context.Reporter.PromptForBoolResponse(Resource::String::PromptToProceed, Reporter::Level::Warning);
if (accepted)
{
AICLI_LOG(CLI, Info, << "Proceeding with installation");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ They can be configured through the settings file 'winget settings'.</value>
<value>Filter results by id</value>
</data>
<data name="IgnoreWarningsArgumentDescription" xml:space="preserve">
<value>Suppresses warning outputs.</value>
<value>Suppresses warning outputs</value>
</data>
<data name="InstallationDisclaimer1" xml:space="preserve">
<value>This application is licensed to you by its owner.</value>
Expand Down
Loading