From c62be2f284c2999981890a1fd6c7ccac8bea66fc Mon Sep 17 00:00:00 2001 From: Ryan Fu <69221034+ryfu-msft@users.noreply.github.com> Date: Wed, 20 Jul 2022 15:29:14 -0700 Subject: [PATCH] Make zip install an experimental feature (#2351) --- schemas/JSON/settings/settings.schema.0.2.json | 5 +++++ src/AppInstallerCLICore/Workflows/InstallFlow.cpp | 13 +++++++++++++ src/AppInstallerCLIE2ETests/BaseCommand.cs | 1 + src/AppInstallerCLIE2ETests/InstallCommand.cs | 6 ++++++ src/AppInstallerCLITests/WorkFlow.cpp | 10 ++++++++-- src/AppInstallerCommonCore/ExperimentalFeature.cpp | 4 ++++ .../Public/winget/ExperimentalFeature.h | 1 + .../Public/winget/UserSettings.h | 2 ++ src/AppInstallerCommonCore/UserSettings.cpp | 1 + 9 files changed, 41 insertions(+), 2 deletions(-) diff --git a/schemas/JSON/settings/settings.schema.0.2.json b/schemas/JSON/settings/settings.schema.0.2.json index ac9e508b33..6f9d1aa0b8 100644 --- a/schemas/JSON/settings/settings.schema.0.2.json +++ b/schemas/JSON/settings/settings.schema.0.2.json @@ -187,6 +187,11 @@ "description": "Enable use of MSI APIs rather than msiexec for MSI installs", "type": "boolean", "default": false + }, + "zipInstall": { + "description": "Enable support for installing zip packages.", + "type": "boolean", + "default": false } } } diff --git a/src/AppInstallerCLICore/Workflows/InstallFlow.cpp b/src/AppInstallerCLICore/Workflows/InstallFlow.cpp index 313a520231..2260d28750 100644 --- a/src/AppInstallerCLICore/Workflows/InstallFlow.cpp +++ b/src/AppInstallerCLICore/Workflows/InstallFlow.cpp @@ -72,6 +72,18 @@ namespace AppInstaller::CLI::Workflow } } + // TODO: Remove check once feature becomes stable + void EnsureFeatureEnabledForArchiveInstall(Execution::Context& context) + { + auto installer = context.Get().value(); + + if (IsArchiveType(installer.InstallerType)) + { + context << + Workflow::EnsureFeatureEnabled(Settings::ExperimentalFeature::Feature::ZipInstall); + } + } + Execution::Args::Type GetUnsupportedArgumentType(UnsupportedArgumentEnum unsupportedArgument) { Execution::Args::Type execArg; @@ -541,6 +553,7 @@ namespace AppInstaller::CLI::Workflow void EnsureSupportForInstall(Execution::Context& context) { context << + Workflow::EnsureFeatureEnabledForArchiveInstall << Workflow::EnsureSupportForPortableInstall << Workflow::EnsureNonPortableTypeForArchiveInstall << Workflow::EnsureValidNestedInstallerMetadataForArchiveInstall; diff --git a/src/AppInstallerCLIE2ETests/BaseCommand.cs b/src/AppInstallerCLIE2ETests/BaseCommand.cs index cc9a27f917..bfcef81596 100644 --- a/src/AppInstallerCLIE2ETests/BaseCommand.cs +++ b/src/AppInstallerCLIE2ETests/BaseCommand.cs @@ -48,6 +48,7 @@ public void InitializeAllFeatures(bool status) ConfigureFeature("experimentalCmd", status); ConfigureFeature("dependencies", status); ConfigureFeature("directMSI", status); + ConfigureFeature("zipInstall", status); } } } diff --git a/src/AppInstallerCLIE2ETests/InstallCommand.cs b/src/AppInstallerCLIE2ETests/InstallCommand.cs index 93946b4c14..35bf65b4b5 100644 --- a/src/AppInstallerCLIE2ETests/InstallCommand.cs +++ b/src/AppInstallerCLIE2ETests/InstallCommand.cs @@ -12,6 +12,12 @@ public class InstallCommand : BaseCommand private const string InstallTestMsiProductId = @"{A5D36CF1-1993-4F63-BFB4-3ACD910D36A1}"; private const string InstallTestMsixName = @"6c6338fe-41b7-46ca-8ba6-b5ad5312bb0e"; + [OneTimeSetUp] + public void OneTimeSetup() + { + ConfigureFeature("zipInstall", true); + } + [Test] public void InstallAppDoesNotExist() { diff --git a/src/AppInstallerCLITests/WorkFlow.cpp b/src/AppInstallerCLITests/WorkFlow.cpp index 21e2a3f92f..5e589e7854 100644 --- a/src/AppInstallerCLITests/WorkFlow.cpp +++ b/src/AppInstallerCLITests/WorkFlow.cpp @@ -988,6 +988,8 @@ TEST_CASE("InstallFlowWithNonApplicableArchitecture", "[InstallFlow][workflow]") TEST_CASE("InstallFlow_ZipWithExe", "[InstallFlow][workflow]") { TestCommon::TempFile installResultPath("TestExeInstalled.txt"); + TestCommon::TestUserSettings testSettings; + testSettings.Set(true); std::ostringstream installOutput; TestContext context{ installOutput, std::cin }; @@ -1014,6 +1016,8 @@ TEST_CASE("InstallFlow_ZipWithExe", "[InstallFlow][workflow]") TEST_CASE("InstallFlow_Zip_BadRelativePath", "[InstallFlow][workflow]") { TestCommon::TempFile installResultPath("TestExeInstalled.txt"); + TestCommon::TestUserSettings testSettings; + testSettings.Set(true); std::ostringstream installOutput; TestContext context{ installOutput, std::cin }; @@ -1036,6 +1040,8 @@ TEST_CASE("InstallFlow_Zip_BadRelativePath", "[InstallFlow][workflow]") TEST_CASE("InstallFlow_Zip_MissingNestedInstaller", "[InstallFlow][workflow]") { TestCommon::TempFile installResultPath("TestExeInstalled.txt"); + TestCommon::TestUserSettings testSettings; + testSettings.Set(true); std::ostringstream installOutput; TestContext context{ installOutput, std::cin }; @@ -1056,6 +1062,8 @@ TEST_CASE("InstallFlow_Zip_MissingNestedInstaller", "[InstallFlow][workflow]") TEST_CASE("InstallFlow_Zip_MultipleNonPortableNestedInstallers", "[InstallFlow][workflow]") { TestCommon::TempFile installResultPath("TestExeInstalled.txt"); + TestCommon::TestUserSettings testSettings; + testSettings.Set(true); std::ostringstream installOutput; TestContext context{ installOutput, std::cin }; @@ -1195,8 +1203,6 @@ TEST_CASE("PortableInstallFlow", "[InstallFlow][workflow]") TestCommon::TempDirectory tempDirectory("TestPortableInstallRoot", false); TestCommon::TempFile portableInstallResultPath("TestPortableInstalled.txt"); - TestCommon::TestUserSettings testSettings; - std::ostringstream installOutput; TestContext context{ installOutput, std::cin }; auto previousThreadGlobals = context.SetForCurrentThread(); diff --git a/src/AppInstallerCommonCore/ExperimentalFeature.cpp b/src/AppInstallerCommonCore/ExperimentalFeature.cpp index fa428ed99f..9afca0450a 100644 --- a/src/AppInstallerCommonCore/ExperimentalFeature.cpp +++ b/src/AppInstallerCommonCore/ExperimentalFeature.cpp @@ -42,6 +42,8 @@ namespace AppInstaller::Settings return userSettings.Get(); case ExperimentalFeature::Feature::DirectMSI: return userSettings.Get(); + case ExperimentalFeature::Feature::ZipInstall: + return userSettings.Get(); default: THROW_HR(E_UNEXPECTED); } @@ -73,6 +75,8 @@ namespace AppInstaller::Settings return ExperimentalFeature{ "Show Dependencies Information", "dependencies", "https://aka.ms/winget-settings", Feature::Dependencies }; case Feature::DirectMSI: return ExperimentalFeature{ "Direct MSI Installation", "directMSI", "https://aka.ms/winget-settings", Feature::DirectMSI }; + case Feature::ZipInstall: + return ExperimentalFeature{ "Zip Installation", "zipInstall", "https://aka.ms/winget-settings", Feature::ZipInstall }; default: THROW_HR(E_UNEXPECTED); } diff --git a/src/AppInstallerCommonCore/Public/winget/ExperimentalFeature.h b/src/AppInstallerCommonCore/Public/winget/ExperimentalFeature.h index 3276375a43..02e894ed52 100644 --- a/src/AppInstallerCommonCore/Public/winget/ExperimentalFeature.h +++ b/src/AppInstallerCommonCore/Public/winget/ExperimentalFeature.h @@ -23,6 +23,7 @@ namespace AppInstaller::Settings Dependencies = 0x1, // Before making DirectMSI non-experimental, it should be part of manifest validation. DirectMSI = 0x2, + ZipInstall = 0x4, Max, // This MUST always be after all experimental features // Features listed after Max will not be shown with the features command diff --git a/src/AppInstallerCommonCore/Public/winget/UserSettings.h b/src/AppInstallerCommonCore/Public/winget/UserSettings.h index a16d0bb482..ace3ab64da 100644 --- a/src/AppInstallerCommonCore/Public/winget/UserSettings.h +++ b/src/AppInstallerCommonCore/Public/winget/UserSettings.h @@ -73,6 +73,7 @@ namespace AppInstaller::Settings EFExperimentalCmd, EFExperimentalArg, EFDependencies, + EFZipInstall, TelemetryDisable, InstallScopePreference, InstallScopeRequirement, @@ -128,6 +129,7 @@ namespace AppInstaller::Settings SETTINGMAPPING_SPECIALIZATION(Setting::EFExperimentalCmd, bool, bool, false, ".experimentalFeatures.experimentalCmd"sv); SETTINGMAPPING_SPECIALIZATION(Setting::EFExperimentalArg, bool, bool, false, ".experimentalFeatures.experimentalArg"sv); SETTINGMAPPING_SPECIALIZATION(Setting::EFDependencies, bool, bool, false, ".experimentalFeatures.dependencies"sv); + SETTINGMAPPING_SPECIALIZATION(Setting::EFZipInstall, bool, bool, false, ".experimentalFeatures.zipInstall"sv); SETTINGMAPPING_SPECIALIZATION(Setting::TelemetryDisable, bool, bool, false, ".telemetry.disable"sv); SETTINGMAPPING_SPECIALIZATION(Setting::InstallArchitecturePreference, std::vector, std::vector, {}, ".installBehavior.preferences.architectures"sv); SETTINGMAPPING_SPECIALIZATION(Setting::InstallArchitectureRequirement, std::vector, std::vector, {}, ".installBehavior.requirements.architectures"sv); diff --git a/src/AppInstallerCommonCore/UserSettings.cpp b/src/AppInstallerCommonCore/UserSettings.cpp index 96f675df33..da01087de2 100644 --- a/src/AppInstallerCommonCore/UserSettings.cpp +++ b/src/AppInstallerCommonCore/UserSettings.cpp @@ -235,6 +235,7 @@ namespace AppInstaller::Settings WINGET_VALIDATE_PASS_THROUGH(EFExperimentalCmd) WINGET_VALIDATE_PASS_THROUGH(EFExperimentalArg) WINGET_VALIDATE_PASS_THROUGH(EFDependencies) + WINGET_VALIDATE_PASS_THROUGH(EFZipInstall) WINGET_VALIDATE_PASS_THROUGH(TelemetryDisable) WINGET_VALIDATE_PASS_THROUGH(EFDirectMSI) WINGET_VALIDATE_PASS_THROUGH(EnableSelfInitiatedMinidump)