Skip to content

Commit

Permalink
Feature Query API (#9665)
Browse files Browse the repository at this point in the history
* implement CheckFeatureAvailability
  • Loading branch information
surayya-MS authored Feb 6, 2024
1 parent 668b199 commit 5768954
Show file tree
Hide file tree
Showing 21 changed files with 264 additions and 2 deletions.
12 changes: 12 additions & 0 deletions src/Build.UnitTests/Evaluation/Expander_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4333,6 +4333,18 @@ public void PropertyFunctionGuidNewGuid()
Assert.True(Guid.TryParse(result, out Guid guid));
}

// TODO: update features list
[Theory]
[InlineData("NonExistingFeature", "Undefined")]
public void PropertyFunctionCheckFeatureAvailability(string featureName, string availability)
{
var expander = new Expander<ProjectPropertyInstance, ProjectItemInstance>(new PropertyDictionary<ProjectPropertyInstance>(), FileSystems.Default);

var result = expander.ExpandIntoStringLeaveEscaped($"$([MSBuild]::CheckFeatureAvailability({featureName}))", ExpanderOptions.ExpandProperties, MockElementLocation.Instance);

Assert.Equal(availability, result);
}

[Fact]
public void PropertyFunctionIntrinsicFunctionGetCurrentToolsDirectory()
{
Expand Down
8 changes: 8 additions & 0 deletions src/Build/Evaluation/Expander.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4171,6 +4171,14 @@ private bool TryExecuteWellKnownFunction(out object returnVal, object objectInst
return true;
}
}
else if (string.Equals(_methodMethodName, nameof(IntrinsicFunctions.CheckFeatureAvailability), StringComparison.OrdinalIgnoreCase))
{
if (TryGetArg(args, out string arg0))
{
returnVal = IntrinsicFunctions.CheckFeatureAvailability(arg0);
return true;
}
}
else if (string.Equals(_methodMethodName, nameof(IntrinsicFunctions.BitwiseOr), StringComparison.OrdinalIgnoreCase))
{
if (TryGetArgs(args, out int arg0, out int arg1))
Expand Down
5 changes: 5 additions & 0 deletions src/Build/Evaluation/IntrinsicFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,11 @@ internal static bool AreFeaturesEnabled(Version wave)
return ChangeWaves.AreFeaturesEnabled(wave);
}

internal static string CheckFeatureAvailability(string featureName)
{
return Features.CheckFeatureAvailability(featureName).ToString();
}

public static string GetCurrentToolsDirectory()
{
return BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory;
Expand Down
59 changes: 59 additions & 0 deletions src/Framework/Features.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Microsoft.Build.Framework
{
/// <summary>
/// The status of a feature.
/// </summary>
public enum FeatureStatus
{
/// <summary>
/// The feature availability is not determined.
/// </summary>
Undefined,

/// <summary>
/// The feature is available.
/// </summary>
Available,

/// <summary>
/// The feature is not available.
/// </summary>
NotAvailable,

/// <summary>
/// The feature is in preview, subject to change API or behavior between releases.
/// </summary>
Preview,
}

/// <summary>
/// This class is used to manage features.
/// </summary>
public static class Features
{
private static readonly Dictionary<string, FeatureStatus> _featureStatusMap = new Dictionary<string, FeatureStatus>
{
// TODO: Fill in the dictionary with the features and their status
};

/// <summary>
/// Checks if a feature is available or not.
/// </summary>
/// <param name="featureName">The name of the feature.</param>
/// <returns>A feature status <see cref="FeatureStatus"/>.</returns>
public static FeatureStatus CheckFeatureAvailability(string featureName)
{
return _featureStatusMap.TryGetValue(featureName, out FeatureStatus status) ?
status : FeatureStatus.Undefined;
}
}
}
20 changes: 20 additions & 0 deletions src/MSBuild.UnitTests/CommandLineSwitches_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,26 @@ public void TargetsSwitchIdentificationTests(string @switch)
emptyParametersAllowed.ShouldBeFalse();
}

[Theory]
[InlineData("featureavailability")]
[InlineData("fa")]
public void FeatureAvailibilitySwitchIdentificationTest(string switchName)
{
CommandLineSwitches.IsParameterizedSwitch(
switchName,
out CommandLineSwitches.ParameterizedSwitch parameterizedSwitch,
out string duplicateSwitchErrorMessage,
out bool multipleParametersAllowed,
out string missingParametersErrorMessage,
out _,
out _);

parameterizedSwitch.ShouldBe(CommandLineSwitches.ParameterizedSwitch.FeatureAvailability);
duplicateSwitchErrorMessage.ShouldBeNull();
multipleParametersAllowed.ShouldBeTrue();
missingParametersErrorMessage.ShouldNotBeNullOrEmpty();
}

[Fact]
public void TargetsSwitchParameter()
{
Expand Down
4 changes: 4 additions & 0 deletions src/MSBuild/CommandLineSwitches.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ internal enum ParameterlessSwitch
#if DEBUG
WaitForDebugger,
#endif
// This has to be kept as last enum value
NumberOfParameterlessSwitches
}

Expand Down Expand Up @@ -115,6 +116,8 @@ internal enum ParameterizedSwitch
GetProperty,
GetItem,
GetTargetResult,
FeatureAvailability,
// This has to be kept as last enum value
NumberOfParameterizedSwitches,
}

Expand Down Expand Up @@ -280,6 +283,7 @@ internal ParameterizedSwitchInfo(
new ParameterizedSwitchInfo( new string[] { "getProperty" }, ParameterizedSwitch.GetProperty, null, true, "MissingGetPropertyError", true, false),
new ParameterizedSwitchInfo( new string[] { "getItem" }, ParameterizedSwitch.GetItem, null, true, "MissingGetItemError", true, false),
new ParameterizedSwitchInfo( new string[] { "getTargetResult" }, ParameterizedSwitch.GetTargetResult, null, true, "MissingGetTargetResultError", true, false),
new ParameterizedSwitchInfo( new string[] { "featureavailability", "fa" }, ParameterizedSwitch.FeatureAvailability, null, true, "MissingFeatureAvailabilityError", true, false),
};

/// <summary>
Expand Down
10 changes: 9 additions & 1 deletion src/MSBuild/Resources/Strings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1053,6 +1053,14 @@
LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized.
</comment>
</data>
<data name="MissingFeatureAvailabilityError" UESanitized="true" Visibility="Public">
<value>MSBUILD : error MSB1067: Must provide a feature name for the featureavailability switch.</value>
<comment>
{StrBegin="MSBUILD : error MSB1067: "}UE: This happens if the user does something like "msbuild.exe -featureavailability". The user must pass in an actual feature name
following the switch, as in "msbuild.exe -featureavailability:blah".
LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized.
</comment>
</data>
<data name="MissingGetItemError" UESanitized="true" Visibility="Public">
<value>MSBUILD : error MSB1014: Must provide an item name for the getItem switch.</value>
<comment>
Expand Down Expand Up @@ -1559,7 +1567,7 @@
<!--
The command line message bucket is: MSB1001 - MSB1999
Next error code should be MSB1067.
Next error code should be MSB1068.
Don't forget to update this comment after using the new code.
-->
Expand Down
9 changes: 9 additions & 0 deletions src/MSBuild/Resources/xlf/Strings.cs.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions src/MSBuild/Resources/xlf/Strings.de.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions src/MSBuild/Resources/xlf/Strings.es.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions src/MSBuild/Resources/xlf/Strings.fr.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions src/MSBuild/Resources/xlf/Strings.it.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions src/MSBuild/Resources/xlf/Strings.ja.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions src/MSBuild/Resources/xlf/Strings.ko.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions src/MSBuild/Resources/xlf/Strings.pl.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions src/MSBuild/Resources/xlf/Strings.pt-BR.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions src/MSBuild/Resources/xlf/Strings.ru.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 5768954

Please sign in to comment.