winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 10a2fac51b29aa3bf8b8ff1745c24c94c31429eb
parent 18a727d756ccd4ab6dd38b10df6b5339d9ef80a8
Author: Luis Chacón <lechacon@users.noreply.github.com>
Date:   Mon,  5 Apr 2021 17:33:56 -0700

Output sources from policy with --info (#848)


Diffstat:
Msrc/AppInstallerCLICore/Commands/RootCommand.cpp | 53+++++++++++++++++++++++++++++++++++++++++++++++++++--
Msrc/AppInstallerCLICore/Resources.h | 2++
Msrc/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw | 8++++++++
Msrc/AppInstallerCLITests/WorkflowGroupPolicy.cpp | 94++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Msrc/AppInstallerCommonCore/Public/winget/GroupPolicy.h | 8++++----
5 files changed, 158 insertions(+), 7 deletions(-)

diff --git a/src/AppInstallerCLICore/Commands/RootCommand.cpp b/src/AppInstallerCLICore/Commands/RootCommand.cpp @@ -28,10 +28,22 @@ namespace AppInstaller::CLI { namespace { + void OutputGroupPolicySourceList(Execution::Context& context, const std::vector<Settings::SourceFromPolicy>& sources, Resource::StringId header) + { + Execution::TableOutput<3> sourcesTable{ context.Reporter, { header, Resource::String::SourceListType, Resource::String::SourceListArg } }; + for (const auto& source : sources) + { + sourcesTable.OutputLine({ source.Name, source.Type, source.Arg }); + } + + sourcesTable.Complete(); + } + void OutputGroupPolicies(Execution::Context& context) { const auto& groupPolicies = Settings::GroupPolicies(); + // Get the state of policies that are a simple enabled/disabled toggle std::map<Settings::TogglePolicy::Policy, Settings::PolicyState> activePolicies; for (const auto& togglePolicy : Settings::TogglePolicy::GetAllPolicies()) { @@ -42,11 +54,19 @@ namespace AppInstaller::CLI } } - if (!activePolicies.empty()) + // The source update interval is the only ValuePolicy that is not gated by a TogglePolicy. + // We need to output the table if there is a TogglePolicy configured or if this one is configured. + // We can rework this when more policies are added. + auto sourceAutoUpdateIntervalPolicy = groupPolicies.GetValue<Settings::ValuePolicy::SourceAutoUpdateIntervalInMinutes>(); + + if (!activePolicies.empty() || sourceAutoUpdateIntervalPolicy.has_value()) { - context.Reporter.Info() << std::endl; + auto info = context.Reporter.Info(); + info << std::endl; Execution::TableOutput<2> policiesTable{ context.Reporter, { Resource::String::PoliciesPolicy, Resource::String::PoliciesState } }; + + // Output the toggle policies. for (const auto& activePolicy : activePolicies) { auto policy = Settings::TogglePolicy::GetPolicy(activePolicy.first); @@ -55,7 +75,36 @@ namespace AppInstaller::CLI Resource::LocString{ activePolicy.second == Settings::PolicyState::Enabled ? Resource::String::PoliciesEnabled : Resource::String::PoliciesDisabled }.get() }); } + // Output the update interval in the same table if needed. + if (sourceAutoUpdateIntervalPolicy.has_value()) + { + policiesTable.OutputLine({ + Resource::LocString{ AppInstaller::StringResource::String::PolicySourceAutoUpdateInterval }, + std::to_string(sourceAutoUpdateIntervalPolicy.value()) }); + } + policiesTable.Complete(); + + // Output the additional and allowed sources as separate tables. + if (groupPolicies.GetState(Settings::TogglePolicy::Policy::AdditionalSources) == Settings::PolicyState::Enabled) + { + info << std::endl; + auto sources = groupPolicies.GetValueRef<Settings::ValuePolicy::AdditionalSources>(); + if (sources.has_value() && !sources->get().empty()) + { + OutputGroupPolicySourceList(context, sources->get(), Resource::String::SourceListAdditionalSource); + } + } + + if (groupPolicies.GetState(Settings::TogglePolicy::Policy::AllowedSources) == Settings::PolicyState::Enabled) + { + info << std::endl; + auto sources = groupPolicies.GetValueRef<Settings::ValuePolicy::AllowedSources>(); + if (sources.has_value() && !sources->get().empty()) + { + OutputGroupPolicySourceList(context, sources->get(), Resource::String::SourceListAllowedSource); + } + } } } } diff --git a/src/AppInstallerCLICore/Resources.h b/src/AppInstallerCLICore/Resources.h @@ -190,6 +190,8 @@ namespace AppInstaller::CLI::Resource WINGET_DEFINE_RESOURCE_STRINGID(SourceCommandShortDescription); WINGET_DEFINE_RESOURCE_STRINGID(SourceExportCommandLongDescription); WINGET_DEFINE_RESOURCE_STRINGID(SourceExportCommandShortDescription); + WINGET_DEFINE_RESOURCE_STRINGID(SourceListAdditionalSource); + WINGET_DEFINE_RESOURCE_STRINGID(SourceListAllowedSource); WINGET_DEFINE_RESOURCE_STRINGID(SourceListArg); WINGET_DEFINE_RESOURCE_STRINGID(SourceListCommandLongDescription); WINGET_DEFINE_RESOURCE_STRINGID(SourceListCommandShortDescription); diff --git a/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw b/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw @@ -908,4 +908,12 @@ Configuration is disabled due to Group Policy.</value> <data name="SourceExportCommandShortDescription" xml:space="preserve"> <value>Export current sources</value> </data> + <data name="SourceListAdditionalSource" xml:space="preserve"> + <value>Additional source</value> + <comment>An additional source required by policy.</comment> + </data> + <data name="SourceListAllowedSource" xml:space="preserve"> + <value>Allowed source</value> + <comment>A source that the user is allowed to add.</comment> + </data> </root> \ No newline at end of file diff --git a/src/AppInstallerCLITests/WorkflowGroupPolicy.cpp b/src/AppInstallerCLITests/WorkflowGroupPolicy.cpp @@ -42,7 +42,6 @@ TEST_CASE("GroupPolicy_WinGet", "[groupPolicy]") rootCommand.Execute(context); REQUIRE_FALSE(context.IsTerminated()); - REQUIRE(output.str().find("Enable Windows Package Manager") != std::string::npos); } } @@ -90,3 +89,95 @@ TEST_CASE("GroupPolicy_LocalManifests", "[groupPolicy]") REQUIRE_NOTHROW(validateCommand.ValidateArguments(args)); } } + +TEST_CASE("GroupPolicy_Info", "[groupPolicy]") +{ + GroupPolicyTestOverride policies; + + std::ostringstream output; + Execution::Context context{ output, std::cin }; + context.Args.AddArg(Execution::Args::Type::Info); + RootCommand rootCommand({}); + + SECTION("Does not list not configured") + { + rootCommand.Execute(context); + INFO(output.str()); + + REQUIRE_FALSE(context.IsTerminated()); + REQUIRE(output.str().find("Group Policy") == std::string::npos); + } + SECTION("Shows enabled policies") + { + policies.SetState(TogglePolicy::Policy::HashOverride, PolicyState::Enabled); + + rootCommand.Execute(context); + INFO(output.str()); + + REQUIRE_FALSE(context.IsTerminated()); + REQUIRE(output.str().find("Group Policy") != std::string::npos); + REQUIRE(output.str().find("Hash Override Enabled") != std::string::npos); + } + SECTION("Shows disabled policies") + { + policies.SetState(TogglePolicy::Policy::LocalManifestFiles, PolicyState::Disabled); + + rootCommand.Execute(context); + INFO(output.str()); + + REQUIRE_FALSE(context.IsTerminated()); + REQUIRE(output.str().find("Group Policy") != std::string::npos); + REQUIRE(output.str().find("Local Manifest Files Disabled") != std::string::npos); + } + SECTION("Shows auto update interval") + { + policies.SetValue<ValuePolicy::SourceAutoUpdateIntervalInMinutes>(60); + + rootCommand.Execute(context); + INFO(output.str()); + + REQUIRE_FALSE(context.IsTerminated()); + REQUIRE(output.str().find("Group Policy") != std::string::npos); + REQUIRE(output.str().find("Source Auto Update Interval In Minutes 60") != std::string::npos); + } + SECTION("Shows additional sources list") + { + SourceFromPolicy source; + source.Name = "policy-source"; + source.Type = "Test.Type"; + source.Arg = "test-arg"; + policies.SetState(TogglePolicy::Policy::AdditionalSources, PolicyState::Enabled); + policies.SetValue<ValuePolicy::AdditionalSources>({ source }); + + rootCommand.Execute(context); + INFO(output.str()); + + REQUIRE_FALSE(context.IsTerminated()); + REQUIRE(output.str().find("Group Policy") != std::string::npos); + REQUIRE(output.str().find("Sources Enabled") != std::string::npos); + REQUIRE(output.str().find("Additional source") != std::string::npos); + REQUIRE(output.str().find(source.Name) != std::string::npos); + REQUIRE(output.str().find(source.Type) != std::string::npos); + REQUIRE(output.str().find(source.Arg) != std::string::npos); + } + SECTION("Shows allowed sources list") + { + SourceFromPolicy source; + source.Name = "allowed-source"; + source.Type = "Test.Type"; + source.Arg = "test-arg"; + policies.SetState(TogglePolicy::Policy::AllowedSources, PolicyState::Enabled); + policies.SetValue<ValuePolicy::AllowedSources>({ source }); + + rootCommand.Execute(context); + INFO(output.str()); + + REQUIRE_FALSE(context.IsTerminated()); + REQUIRE(output.str().find("Group Policy") != std::string::npos); + REQUIRE(output.str().find("Allowed Sources Enabled") != std::string::npos); + REQUIRE(output.str().find("Allowed source") != std::string::npos); + REQUIRE(output.str().find(source.Name) != std::string::npos); + REQUIRE(output.str().find(source.Type) != std::string::npos); + REQUIRE(output.str().find(source.Arg) != std::string::npos); + } +}+ \ No newline at end of file diff --git a/src/AppInstallerCommonCore/Public/winget/GroupPolicy.h b/src/AppInstallerCommonCore/Public/winget/GroupPolicy.h @@ -18,8 +18,8 @@ namespace AppInstaller::Settings enum class ValuePolicy { SourceAutoUpdateIntervalInMinutes, - AdditionalSources, // TODO - AllowedSources, // TODO + AdditionalSources, + AllowedSources, Max, }; @@ -37,8 +37,8 @@ namespace AppInstaller::Settings HashOverride, DefaultSource, MSStoreSource, - AdditionalSources, // TODO - AllowedSources, // TODO + AdditionalSources, + AllowedSources, Max, };