Skip to content

Commit

Permalink
make windows feature experimental (#3620)
Browse files Browse the repository at this point in the history
  • Loading branch information
ryfu-msft committed Sep 13, 2023
1 parent f7c1a44 commit 4262a0f
Show file tree
Hide file tree
Showing 10 changed files with 54 additions and 0 deletions.
11 changes: 11 additions & 0 deletions doc/Settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -272,4 +272,15 @@ You can enable the feature as shown below.
"experimentalFeatures": {
"configuration": true
},
```

### windowsFeature

This feature enables the ability to enable Windows Feature dependencies during installation.
You can enable the feature as shown below.

```json
"experimentalFeatures": {
"windowsFeature": true
},
```
5 changes: 5 additions & 0 deletions schemas/JSON/settings/settings.schema.0.2.json
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,11 @@
"description": "Enable support for configuration",
"type": "boolean",
"default": false
},
"windowsFeature": {
"description": "Enable support for enabling Windows Feature(s)",
"type": "boolean",
"default": false
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/AppInstallerCLICore/Workflows/DependenciesFlow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ namespace AppInstaller::CLI::Workflow

void EnableWindowsFeaturesDependencies(Execution::Context& context)
{
if (!Settings::ExperimentalFeature::IsEnabled(Settings::ExperimentalFeature::Feature::WindowsFeature))
{
return;
}

const auto& rootDependencies = context.Get<Execution::Data::Installer>()->Dependencies;

if (rootDependencies.Empty())
Expand Down
1 change: 1 addition & 0 deletions src/AppInstallerCLIE2ETests/FeaturesCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public void EnableExperimentalFeatures()
WinGetSettingsHelper.ConfigureFeature("experimentalArg", true);
WinGetSettingsHelper.ConfigureFeature("experimentalCmd", true);
WinGetSettingsHelper.ConfigureFeature("directMSI", true);
WinGetSettingsHelper.ConfigureFeature("windowsFeature", true);
var result = TestCommon.RunAICLICommand("features", string.Empty);
Assert.True(result.StdOut.Contains("Enabled"));
}
Expand Down
9 changes: 9 additions & 0 deletions src/AppInstallerCLIE2ETests/InstallCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ namespace AppInstallerCLIE2ETests
/// </summary>
public class InstallCommand : BaseCommand
{
/// <summary>
/// One time setup.
/// </summary>
[OneTimeSetUp]
public void OneTimeSetup()
{
WinGetSettingsHelper.ConfigureFeature("windowsFeature", true);
}

/// <summary>
/// Set up.
/// </summary>
Expand Down
15 changes: 15 additions & 0 deletions src/AppInstallerCLITests/WindowsFeature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ TEST_CASE("InstallFlow_WindowsFeatureDoesNotExist", "[windowsFeature]")

TestCommon::TempFile installResultPath("TestExeInstalled.txt");

TestCommon::TestUserSettings testSettings;
testSettings.Set<Setting::EFWindowsFeature>(true);

std::ostringstream installOutput;
TestContext context{ installOutput, std::cin };
auto previousThreadGlobals = context.SetForCurrentThread();
Expand Down Expand Up @@ -57,6 +60,9 @@ TEST_CASE("InstallFlow_FailedToEnableWindowsFeature", "[windowsFeature]")

TestCommon::TempFile installResultPath("TestExeInstalled.txt");

TestCommon::TestUserSettings testSettings;
testSettings.Set<Setting::EFWindowsFeature>(true);

std::ostringstream installOutput;
TestContext context{ installOutput, std::cin };
auto previousThreadGlobals = context.SetForCurrentThread();
Expand Down Expand Up @@ -92,6 +98,9 @@ TEST_CASE("InstallFlow_FailedToEnableWindowsFeature_Force", "[windowsFeature]")

TestCommon::TempFile installResultPath("TestExeInstalled.txt");

TestCommon::TestUserSettings testSettings;
testSettings.Set<Setting::EFWindowsFeature>(true);

// Override with arbitrary DISM api error (DISMAPI_E_DISMAPI_NOT_INITIALIZED) and make windows feature discoverable.
HRESULT dismErrorResult = 0xc0040001;
LocIndString testFeatureDisplayName = LocIndString{ "Test Windows Feature"_liv };
Expand Down Expand Up @@ -139,6 +148,9 @@ TEST_CASE("InstallFlow_RebootRequired", "[windowsFeature]")

TestCommon::TempFile installResultPath("TestExeInstalled.txt");

TestCommon::TestUserSettings testSettings;
testSettings.Set<Setting::EFWindowsFeature>(true);

// Override with reboot required HRESULT.
auto mockDismHelperOverride = TestHook::MockDismHelper_Override();
auto setEnableFeatureOverride = TestHook::SetEnableWindowsFeatureResult_Override(ERROR_SUCCESS_REBOOT_REQUIRED);
Expand Down Expand Up @@ -173,6 +185,9 @@ TEST_CASE("InstallFlow_RebootRequired_Force", "[windowsFeature]")

TestCommon::TempFile installResultPath("TestExeInstalled.txt");

TestCommon::TestUserSettings testSettings;
testSettings.Set<Setting::EFWindowsFeature>(true);

// Override with reboot required HRESULT.
auto mockDismHelperOverride = TestHook::MockDismHelper_Override();
auto setEnableFeatureOverride = TestHook::SetEnableWindowsFeatureResult_Override(ERROR_SUCCESS_REBOOT_REQUIRED);
Expand Down
4 changes: 4 additions & 0 deletions src/AppInstallerCommonCore/ExperimentalFeature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ namespace AppInstaller::Settings
return userSettings.Get<Setting::EFExperimentalArg>();
case ExperimentalFeature::Feature::DirectMSI:
return userSettings.Get<Setting::EFDirectMSI>();
case ExperimentalFeature::Feature::WindowsFeature:
return userSettings.Get<Setting::EFWindowsFeature>();
default:
THROW_HR(E_UNEXPECTED);
}
Expand Down Expand Up @@ -69,6 +71,8 @@ namespace AppInstaller::Settings
return ExperimentalFeature{ "Argument Sample", "experimentalArg", "https://aka.ms/winget-settings", Feature::ExperimentalArg };
case Feature::DirectMSI:
return ExperimentalFeature{ "Direct MSI Installation", "directMSI", "https://aka.ms/winget-settings", Feature::DirectMSI };
case Feature::WindowsFeature:
return ExperimentalFeature{ "Windows Feature Dependencies", "windowsFeature", "https://aka.ms/winget-settings", Feature::WindowsFeature };
default:
THROW_HR(E_UNEXPECTED);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ namespace AppInstaller::Settings
None = 0x0,
// Before making DirectMSI non-experimental, it should be part of manifest validation.
DirectMSI = 0x1,
WindowsFeature = 0x2,
Max, // This MUST always be after all experimental features

// Features listed after Max will not be shown with the features command
Expand Down
2 changes: 2 additions & 0 deletions src/AppInstallerCommonCore/Public/winget/UserSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ namespace AppInstaller::Settings
EFExperimentalCmd,
EFExperimentalArg,
EFDirectMSI,
EFWindowsFeature,
// Telemetry
TelemetryDisable,
// Install behavior
Expand Down Expand Up @@ -145,6 +146,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::EFDirectMSI, bool, bool, false, ".experimentalFeatures.directMSI"sv);
SETTINGMAPPING_SPECIALIZATION(Setting::EFWindowsFeature, bool, bool, false, ".experimentalFeatures.windowsFeature"sv);
// Telemetry
SETTINGMAPPING_SPECIALIZATION(Setting::TelemetryDisable, bool, bool, false, ".telemetry.disable"sv);
// Install behavior
Expand Down
1 change: 1 addition & 0 deletions src/AppInstallerCommonCore/UserSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ namespace AppInstaller::Settings
WINGET_VALIDATE_PASS_THROUGH(EFExperimentalCmd)
WINGET_VALIDATE_PASS_THROUGH(EFExperimentalArg)
WINGET_VALIDATE_PASS_THROUGH(EFDirectMSI)
WINGET_VALIDATE_PASS_THROUGH(EFWindowsFeature)
WINGET_VALIDATE_PASS_THROUGH(AnonymizePathForDisplay)
WINGET_VALIDATE_PASS_THROUGH(TelemetryDisable)
WINGET_VALIDATE_PASS_THROUGH(InteractivityDisable)
Expand Down

0 comments on commit 4262a0f

Please sign in to comment.