Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
8c585f6
[feature]
SteveL-MSFT Nov 5, 2018
02f566b
[feature]
SteveL-MSFT Nov 20, 2018
6d290b4
[feature]
SteveL-MSFT Nov 20, 2018
6727dd7
[feature]
SteveL-MSFT Nov 20, 2018
745a91b
Update test/powershell/engine/ExperimentalFeature/Get-ExperimentalFea…
iSazonov Nov 30, 2018
e8218a3
Update test/powershell/engine/ExperimentalFeature/Get-ExperimentalFea…
iSazonov Nov 30, 2018
3f737e5
Update test/powershell/engine/ExperimentalFeature/Get-ExperimentalFea…
iSazonov Nov 30, 2018
0fd3980
Update test/powershell/engine/ExperimentalFeature/Get-ExperimentalFea…
iSazonov Nov 30, 2018
596afc7
Update test/powershell/engine/ExperimentalFeature/Get-ExperimentalFea…
iSazonov Nov 30, 2018
ce871df
Update test/powershell/engine/ExperimentalFeature/Get-ExperimentalFea…
iSazonov Nov 30, 2018
7269cf6
Update test/powershell/engine/ExperimentalFeature/Get-ExperimentalFea…
iSazonov Nov 30, 2018
903ea39
address Ilya's feedback
SteveL-MSFT Nov 30, 2018
ecf82cf
Update test/powershell/engine/ExperimentalFeature/Get-ExperimentalFea…
iSazonov Nov 30, 2018
890a412
Update test/powershell/engine/ExperimentalFeature/Get-ExperimentalFea…
iSazonov Nov 30, 2018
3b8d53e
add helpuri
SteveL-MSFT Nov 30, 2018
34e020b
change fwdlink for get-experimentalfeature to original
SteveL-MSFT Nov 30, 2018
0508fdd
Update src/System.Management.Automation/engine/ExperimentalFeature/En…
iSazonov Dec 3, 2018
8de4efe
Update src/System.Management.Automation/engine/ExperimentalFeature/En…
vexx32 Dec 4, 2018
86b56a2
[feature]
SteveL-MSFT Dec 4, 2018
93be24e
[feature]
SteveL-MSFT Dec 5, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Management.Automation;
using System.Management.Automation.Configuration;
using System.Management.Automation.Internal;
using System.Management.Automation.Language;

namespace Microsoft.PowerShell.Commands
{
/// <summary>
/// Base class for Enable/Disable-ExperimentalFeature cmdlet.
/// </summary>
public class EnableDisableExperimentalFeatureCommandBase : PSCmdlet
{
/// <summary>
/// Gets or sets the feature names.
/// </summary>
[Parameter(ValueFromPipelineByPropertyName = true, Position = 0, Mandatory = true)]
[ArgumentCompleter(typeof(ExperimentalFeatureNameCompleter))]
public string[] Name { get; set; }

/// <summary>
/// Gets or sets the scope of persistence of updating the PowerShell configuration json.
/// </summary>
[Parameter]
public ConfigScope Scope { get; set; } = ConfigScope.CurrentUser;
}

/// <summary>
/// Implements Enable-ExperimentalFeature cmdlet.
/// </summary>
[Cmdlet(VerbsLifecycle.Enable, "ExperimentalFeature", SupportsShouldProcess = true, HelpUri = "https://go.microsoft.com/fwlink/?LinkID=2046964")]
public class EnableExperimentalFeatureCommand : EnableDisableExperimentalFeatureCommandBase
{
/// <summary>
/// ProcessRecord method of this cmdlet.
/// </summary>
protected override void ProcessRecord()
{
ExperimentalFeatureConfigHelper.UpdateConfig(this, Name, Scope, enable: true);
}
}

/// <summary>
/// Implements Enable-ExperimentalFeature cmdlet.
/// </summary>
[Cmdlet(VerbsLifecycle.Disable, "ExperimentalFeature", SupportsShouldProcess = true, HelpUri = "https://go.microsoft.com/fwlink/?LinkID=2046963")]
public class DisableExperimentalFeatureCommand : EnableDisableExperimentalFeatureCommandBase
{
/// <summary>
/// ProcessRecord method of this cmdlet.
/// </summary>
protected override void ProcessRecord()
{
ExperimentalFeatureConfigHelper.UpdateConfig(this, Name, Scope, enable: false);
}
}

internal class ExperimentalFeatureConfigHelper
{
internal static void UpdateConfig(PSCmdlet cmdlet, string[] name, ConfigScope scope, bool enable)
{
IEnumerable<WildcardPattern> namePatterns = SessionStateUtilities.CreateWildcardsFromStrings(name, WildcardOptions.IgnoreCase | WildcardOptions.CultureInvariant);
GetExperimentalFeatureCommand getExperimentalFeatureCommand = new GetExperimentalFeatureCommand();
getExperimentalFeatureCommand.Context = cmdlet.Context;
bool foundFeature = false;
foreach (ExperimentalFeature feature in getExperimentalFeatureCommand.GetAvailableExperimentalFeatures(namePatterns))
{
foundFeature = true;
if (!cmdlet.ShouldProcess(feature.Name))
{
return;
}

PowerShellConfig.Instance.SetExperimentalFeatures(scope, feature.Name, enable);
}

if (!foundFeature)
{
string errMsg = string.Format(CultureInfo.InvariantCulture, ExperimentalFeatureStrings.ExperimentalFeatureNameNotFound, name);
cmdlet.WriteError(new ErrorRecord(new ItemNotFoundException(errMsg), "ItemNotFoundException", ErrorCategory.ObjectNotFound, name));
return;
}

cmdlet.WriteWarning(ExperimentalFeatureStrings.ExperimentalFeaturePending);
}
}

/// <summary>
/// Provides argument completion for ExperimentalFeature names.
/// </summary>
public class ExperimentalFeatureNameCompleter : IArgumentCompleter
{
/// <summary>
/// Returns completion results for experimental feature names used as arguments to experimental feature cmdlets.
/// </summary>
/// <param name="commandName">The command name.</param>
/// <param name="parameterName">The parameter name.</param>
/// <param name="wordToComplete">The word to complete.</param>
/// <param name="commandAst">The command AST.</param>
/// <param name="fakeBoundParameters">The fake bound parameters.</param>
/// <returns>List of Completion Results.</returns>
public IEnumerable<CompletionResult> CompleteArgument(string commandName, string parameterName, string wordToComplete, CommandAst commandAst, IDictionary fakeBoundParameters)
{
if (fakeBoundParameters == null)
{
throw PSTraceSource.NewArgumentNullException(nameof(fakeBoundParameters));
}

var commandInfo = new CmdletInfo("Get-ExperimentalFeature", typeof(GetExperimentalFeatureCommand));
var ps = System.Management.Automation.PowerShell.Create(RunspaceMode.CurrentRunspace)
.AddCommand(commandInfo)
.AddParameter("Name", wordToComplete + "*");

HashSet<string> names = new HashSet<string>();
var results = ps.Invoke<ExperimentalFeature>();
foreach (var result in results)
{
names.Add(result.Name);
}

return names.OrderBy(name => name).Select(name => new CompletionResult(name, name, CompletionResultType.Text, name));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,10 @@ public class GetExperimentalFeatureCommand : PSCmdlet
/// Get and set the feature names.
/// </summary>
[Parameter(ValueFromPipeline = true, Position = 0)]
[ArgumentCompleter(typeof(ExperimentalFeatureNameCompleter))]
[ValidateNotNullOrEmpty]
public string[] Name { get; set; }

/// <summary>
/// Get and set the switch flag to search module paths to find all available experimental features.
/// </summary>
[Parameter]
public SwitchParameter ListAvailable { get; set; }

/// <summary>
/// ProcessRecord method of this cmdlet.
/// </summary>
Expand All @@ -37,19 +32,9 @@ protected override void ProcessRecord()
const WildcardOptions wildcardOptions = WildcardOptions.IgnoreCase | WildcardOptions.CultureInvariant;
IEnumerable<WildcardPattern> namePatterns = SessionStateUtilities.CreateWildcardsFromStrings(Name, wildcardOptions);

if (ListAvailable)
{
foreach (ExperimentalFeature feature in GetAvailableExperimentalFeatures(namePatterns).OrderBy(GetSortingString))
{
WriteObject(feature);
}
}
else if (ExperimentalFeature.EnabledExperimentalFeatureNames.Count > 0)
foreach (ExperimentalFeature feature in GetAvailableExperimentalFeatures(namePatterns).OrderBy(GetSortingString))
{
foreach (ExperimentalFeature feature in GetEnabledExperimentalFeatures(namePatterns).OrderBy(GetSortingString))
{
WriteObject(feature);
}
WriteObject(feature);
}
}

Expand All @@ -67,61 +52,10 @@ private static (int, string) GetSortingString(ExperimentalFeature feature)
: (1, feature.Name);
}

/// <summary>
/// Get enabled experimental features based on the specified name patterns.
/// </summary>
private IEnumerable<ExperimentalFeature> GetEnabledExperimentalFeatures(IEnumerable<WildcardPattern> namePatterns)
{
var moduleFeatures = new List<string>();
var moduleNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

foreach (string featureName in ExperimentalFeature.EnabledExperimentalFeatureNames)
{
// Only process the feature names that matches any name patterns.
if (SessionStateUtilities.MatchesAnyWildcardPattern(featureName, namePatterns, defaultValue: true))
{
if (ExperimentalFeature.EngineExperimentalFeatureMap.TryGetValue(featureName, out ExperimentalFeature feature))
{
yield return feature;
}
else
{
moduleFeatures.Add(featureName);
int lastDotIndex = featureName.LastIndexOf('.');
moduleNames.Add(featureName.Substring(0, lastDotIndex));
}
}
}

if (moduleFeatures.Count > 0)
{
var featuresFromGivenModules = new Dictionary<string, ExperimentalFeature>(StringComparer.OrdinalIgnoreCase);
foreach (string moduleFile in GetValidModuleFiles(moduleNames))
{
foreach (var feature in ModuleIntrinsics.GetExperimentalFeature(moduleFile))
{
featuresFromGivenModules.TryAdd(feature.Name, feature);
}
}

foreach (string featureName in moduleFeatures)
{
if (featuresFromGivenModules.TryGetValue(featureName, out ExperimentalFeature feature))
{
yield return feature;
}
else
{
yield return new ExperimentalFeature(featureName, description: null, source: null, isEnabled: true);
}
}
}
}

/// <summary>
/// Get available experimental features based on the specified name patterns.
/// </summary>
private IEnumerable<ExperimentalFeature> GetAvailableExperimentalFeatures(IEnumerable<WildcardPattern> namePatterns)
internal IEnumerable<ExperimentalFeature> GetAvailableExperimentalFeatures(IEnumerable<WildcardPattern> namePatterns)
{
foreach (ExperimentalFeature feature in ExperimentalFeature.EngineExperimentalFeatures)
{
Expand Down
Loading