diff --git a/src/Build.UnitTests/Evaluation/Expander_Tests.cs b/src/Build.UnitTests/Evaluation/Expander_Tests.cs index 030c6db60c3..1fb7e636e55 100644 --- a/src/Build.UnitTests/Evaluation/Expander_Tests.cs +++ b/src/Build.UnitTests/Evaluation/Expander_Tests.cs @@ -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(new PropertyDictionary(), FileSystems.Default); + + var result = expander.ExpandIntoStringLeaveEscaped($"$([MSBuild]::CheckFeatureAvailability({featureName}))", ExpanderOptions.ExpandProperties, MockElementLocation.Instance); + + Assert.Equal(availability, result); + } + [Fact] public void PropertyFunctionIntrinsicFunctionGetCurrentToolsDirectory() { diff --git a/src/Build/Evaluation/Expander.cs b/src/Build/Evaluation/Expander.cs index c998910190e..b98f902e994 100644 --- a/src/Build/Evaluation/Expander.cs +++ b/src/Build/Evaluation/Expander.cs @@ -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)) diff --git a/src/Build/Evaluation/IntrinsicFunctions.cs b/src/Build/Evaluation/IntrinsicFunctions.cs index 0f721647326..37312b8c83e 100644 --- a/src/Build/Evaluation/IntrinsicFunctions.cs +++ b/src/Build/Evaluation/IntrinsicFunctions.cs @@ -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; diff --git a/src/Framework/Features.cs b/src/Framework/Features.cs new file mode 100644 index 00000000000..636a30ba859 --- /dev/null +++ b/src/Framework/Features.cs @@ -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 +{ + /// + /// The status of a feature. + /// + public enum FeatureStatus + { + /// + /// The feature availability is not determined. + /// + Undefined, + + /// + /// The feature is available. + /// + Available, + + /// + /// The feature is not available. + /// + NotAvailable, + + /// + /// The feature is in preview, subject to change API or behavior between releases. + /// + Preview, + } + + /// + /// This class is used to manage features. + /// + public static class Features + { + private static readonly Dictionary _featureStatusMap = new Dictionary + { + // TODO: Fill in the dictionary with the features and their status + }; + + /// + /// Checks if a feature is available or not. + /// + /// The name of the feature. + /// A feature status . + public static FeatureStatus CheckFeatureAvailability(string featureName) + { + return _featureStatusMap.TryGetValue(featureName, out FeatureStatus status) ? + status : FeatureStatus.Undefined; + } + } +} diff --git a/src/MSBuild.UnitTests/CommandLineSwitches_Tests.cs b/src/MSBuild.UnitTests/CommandLineSwitches_Tests.cs index 735b63da358..53e4555fcf2 100644 --- a/src/MSBuild.UnitTests/CommandLineSwitches_Tests.cs +++ b/src/MSBuild.UnitTests/CommandLineSwitches_Tests.cs @@ -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() { diff --git a/src/MSBuild/CommandLineSwitches.cs b/src/MSBuild/CommandLineSwitches.cs index 3ae01e17f17..3a53be7303a 100644 --- a/src/MSBuild/CommandLineSwitches.cs +++ b/src/MSBuild/CommandLineSwitches.cs @@ -50,6 +50,7 @@ internal enum ParameterlessSwitch #if DEBUG WaitForDebugger, #endif + // This has to be kept as last enum value NumberOfParameterlessSwitches } @@ -115,6 +116,8 @@ internal enum ParameterizedSwitch GetProperty, GetItem, GetTargetResult, + FeatureAvailability, + // This has to be kept as last enum value NumberOfParameterizedSwitches, } @@ -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), }; /// diff --git a/src/MSBuild/Resources/Strings.resx b/src/MSBuild/Resources/Strings.resx index 0daf54d6adf..a8f93e5f609 100644 --- a/src/MSBuild/Resources/Strings.resx +++ b/src/MSBuild/Resources/Strings.resx @@ -1053,6 +1053,14 @@ LOCALIZATION: The prefix "MSBUILD : error MSBxxxx:" should not be localized. + + MSBUILD : error MSB1067: Must provide a feature name for the featureavailability switch. + + {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. + + MSBUILD : error MSB1014: Must provide an item name for the getItem switch. @@ -1559,7 +1567,7 @@ diff --git a/src/MSBuild/Resources/xlf/Strings.cs.xlf b/src/MSBuild/Resources/xlf/Strings.cs.xlf index 2ed7d5da6bb..63f1e4b57e9 100644 --- a/src/MSBuild/Resources/xlf/Strings.cs.xlf +++ b/src/MSBuild/Resources/xlf/Strings.cs.xlf @@ -1334,6 +1334,15 @@ Když se nastaví na MessageUponIsolationViolation (nebo jeho krátký Protokoly MSBuild a informace o ladění budou dostupné v „{0}“ + + MSBUILD : error MSB1067: Must provide a feature name for the featureavailability switch. + MSBUILD : error MSB1067: Must provide a feature name for the featureavailability switch. + + {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. + + MSBUILD : error MSB1014: Must provide an item name for the getItem switch. MSBUILD : error MSB1014: Je nutné zadat název položky pro přepínač getItem. diff --git a/src/MSBuild/Resources/xlf/Strings.de.xlf b/src/MSBuild/Resources/xlf/Strings.de.xlf index d95a1823546..594aafe0c99 100644 --- a/src/MSBuild/Resources/xlf/Strings.de.xlf +++ b/src/MSBuild/Resources/xlf/Strings.de.xlf @@ -1322,6 +1322,15 @@ Dieses Protokollierungsformat ist standardmäßig aktiviert. MSBuild-Protokolle und Debuginformationen befinden sich auf "{0}" + + MSBUILD : error MSB1067: Must provide a feature name for the featureavailability switch. + MSBUILD : error MSB1067: Must provide a feature name for the featureavailability switch. + + {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. + + MSBUILD : error MSB1014: Must provide an item name for the getItem switch. MSBUILD : error MSB1014: Es muss ein Elementname für den getItem-Switch angegeben werden. diff --git a/src/MSBuild/Resources/xlf/Strings.es.xlf b/src/MSBuild/Resources/xlf/Strings.es.xlf index 7cd424ea80f..fdbbc390fb1 100644 --- a/src/MSBuild/Resources/xlf/Strings.es.xlf +++ b/src/MSBuild/Resources/xlf/Strings.es.xlf @@ -1328,6 +1328,15 @@ Esta marca es experimental y puede que no funcione según lo previsto. Los registros de MSBuild y la información de depuración estarán en "{0}" + + MSBUILD : error MSB1067: Must provide a feature name for the featureavailability switch. + MSBUILD : error MSB1067: Must provide a feature name for the featureavailability switch. + + {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. + + MSBUILD : error MSB1014: Must provide an item name for the getItem switch. MSBUILD : error MSB1014: debe proporcionar un nombre de elemento para el modificador getItem. diff --git a/src/MSBuild/Resources/xlf/Strings.fr.xlf b/src/MSBuild/Resources/xlf/Strings.fr.xlf index 4439fa3e05a..8834e00d9c3 100644 --- a/src/MSBuild/Resources/xlf/Strings.fr.xlf +++ b/src/MSBuild/Resources/xlf/Strings.fr.xlf @@ -1321,6 +1321,15 @@ Remarque : verbosité des enregistreurs d’événements de fichiers Les journaux MSBuild et les informations de débogage seront au "{0}" + + MSBUILD : error MSB1067: Must provide a feature name for the featureavailability switch. + MSBUILD : error MSB1067: Must provide a feature name for the featureavailability switch. + + {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. + + MSBUILD : error MSB1014: Must provide an item name for the getItem switch. MSBUILD : error MSB1014: Must provide an item name for the getItem switch. diff --git a/src/MSBuild/Resources/xlf/Strings.it.xlf b/src/MSBuild/Resources/xlf/Strings.it.xlf index d549fbef333..eb32ad8f7ea 100644 --- a/src/MSBuild/Resources/xlf/Strings.it.xlf +++ b/src/MSBuild/Resources/xlf/Strings.it.xlf @@ -1332,6 +1332,15 @@ Nota: livello di dettaglio dei logger di file I log e le informazioni di debug di MSBuild sono contenuti in "{0}" + + MSBUILD : error MSB1067: Must provide a feature name for the featureavailability switch. + MSBUILD : error MSB1067: Must provide a feature name for the featureavailability switch. + + {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. + + MSBUILD : error MSB1014: Must provide an item name for the getItem switch. MSBUILD : error MSB1014: è necessario specificare un nome elemento per l'opzione getItem. diff --git a/src/MSBuild/Resources/xlf/Strings.ja.xlf b/src/MSBuild/Resources/xlf/Strings.ja.xlf index bde74466fc0..9959eee142e 100644 --- a/src/MSBuild/Resources/xlf/Strings.ja.xlf +++ b/src/MSBuild/Resources/xlf/Strings.ja.xlf @@ -1321,6 +1321,15 @@ MSBuild のログとデバッグ情報は、"{0}" にあります。 + + MSBUILD : error MSB1067: Must provide a feature name for the featureavailability switch. + MSBUILD : error MSB1067: Must provide a feature name for the featureavailability switch. + + {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. + + MSBUILD : error MSB1014: Must provide an item name for the getItem switch. MSBUILD : error MSB1014: getItem スイッチに項目名を指定する必要があります。 diff --git a/src/MSBuild/Resources/xlf/Strings.ko.xlf b/src/MSBuild/Resources/xlf/Strings.ko.xlf index 6b2e1b97d3c..1b37fe9bf0a 100644 --- a/src/MSBuild/Resources/xlf/Strings.ko.xlf +++ b/src/MSBuild/Resources/xlf/Strings.ko.xlf @@ -1321,6 +1321,15 @@ MSBuild 로그 및 디버그 정보는 "{0}"에 있습니다. + + MSBUILD : error MSB1067: Must provide a feature name for the featureavailability switch. + MSBUILD : error MSB1067: Must provide a feature name for the featureavailability switch. + + {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. + + MSBUILD : error MSB1014: Must provide an item name for the getItem switch. MSBUILD : error MSB1014: getItem 스위치의 항목 이름을 제공해야 합니다. diff --git a/src/MSBuild/Resources/xlf/Strings.pl.xlf b/src/MSBuild/Resources/xlf/Strings.pl.xlf index 38eafd9dbc1..7c9f4c4f8db 100644 --- a/src/MSBuild/Resources/xlf/Strings.pl.xlf +++ b/src/MSBuild/Resources/xlf/Strings.pl.xlf @@ -1332,6 +1332,15 @@ Ta flaga jest eksperymentalna i może nie działać zgodnie z oczekiwaniami. Dzienniki i informacje debugowania programu MSBuild będą znajdować się w lokalizacji „{0}” + + MSBUILD : error MSB1067: Must provide a feature name for the featureavailability switch. + MSBUILD : error MSB1067: Must provide a feature name for the featureavailability switch. + + {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. + + MSBUILD : error MSB1014: Must provide an item name for the getItem switch. MSBUILD : error MSB1014: Musi podać nazwę elementu dla przełącznika getItem. diff --git a/src/MSBuild/Resources/xlf/Strings.pt-BR.xlf b/src/MSBuild/Resources/xlf/Strings.pt-BR.xlf index 9399e73a222..62fb9b8962e 100644 --- a/src/MSBuild/Resources/xlf/Strings.pt-BR.xlf +++ b/src/MSBuild/Resources/xlf/Strings.pt-BR.xlf @@ -1322,6 +1322,15 @@ arquivo de resposta. Os logs e as informações de depuração do MSBuild estarão no "{0}" + + MSBUILD : error MSB1067: Must provide a feature name for the featureavailability switch. + MSBUILD : error MSB1067: Must provide a feature name for the featureavailability switch. + + {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. + + MSBUILD : error MSB1014: Must provide an item name for the getItem switch. MSBUILD : error MSB1014: É preciso fornecer um nome de item para a chave getItem. diff --git a/src/MSBuild/Resources/xlf/Strings.ru.xlf b/src/MSBuild/Resources/xlf/Strings.ru.xlf index 09b513f67b4..58cdfbad974 100644 --- a/src/MSBuild/Resources/xlf/Strings.ru.xlf +++ b/src/MSBuild/Resources/xlf/Strings.ru.xlf @@ -1320,6 +1320,15 @@ Журналы MSBuild и отладочные сведения будут доступны по адресу "{0}" + + MSBUILD : error MSB1067: Must provide a feature name for the featureavailability switch. + MSBUILD : error MSB1067: Must provide a feature name for the featureavailability switch. + + {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. + + MSBUILD : error MSB1014: Must provide an item name for the getItem switch. MSBUILD : error MSB1014: необходимо указать имя элемента для переключателя getItem. diff --git a/src/MSBuild/Resources/xlf/Strings.tr.xlf b/src/MSBuild/Resources/xlf/Strings.tr.xlf index 37bd0d98a4f..2feeaee0f2e 100644 --- a/src/MSBuild/Resources/xlf/Strings.tr.xlf +++ b/src/MSBuild/Resources/xlf/Strings.tr.xlf @@ -1325,6 +1325,15 @@ MSBuild günlükleri ve hata ayıklama bilgileri "{0}" yolunda olacak + + MSBUILD : error MSB1067: Must provide a feature name for the featureavailability switch. + MSBUILD : error MSB1067: Must provide a feature name for the featureavailability switch. + + {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. + + MSBUILD : error MSB1014: Must provide an item name for the getItem switch. MSBUILD : error MSB1014: getItem anahtarı için bir öğe adı sağlanması gerekiyor. diff --git a/src/MSBuild/Resources/xlf/Strings.zh-Hans.xlf b/src/MSBuild/Resources/xlf/Strings.zh-Hans.xlf index bb43d7a64f0..048ca7aa3b2 100644 --- a/src/MSBuild/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/MSBuild/Resources/xlf/Strings.zh-Hans.xlf @@ -1321,6 +1321,15 @@ MSBuild 日志和调试信息将位于"{0}" + + MSBUILD : error MSB1067: Must provide a feature name for the featureavailability switch. + MSBUILD : error MSB1067: Must provide a feature name for the featureavailability switch. + + {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. + + MSBUILD : error MSB1014: Must provide an item name for the getItem switch. MSBUILD : error MSB1014: 必须为 getItem 开关提供项名称。 diff --git a/src/MSBuild/Resources/xlf/Strings.zh-Hant.xlf b/src/MSBuild/Resources/xlf/Strings.zh-Hant.xlf index 64eb661fc18..4e65455c5bd 100644 --- a/src/MSBuild/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/MSBuild/Resources/xlf/Strings.zh-Hant.xlf @@ -1321,6 +1321,15 @@ MSBuild 記錄和偵錯工具資訊將位於 "{0}" + + MSBUILD : error MSB1067: Must provide a feature name for the featureavailability switch. + MSBUILD : error MSB1067: Must provide a feature name for the featureavailability switch. + + {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. + + MSBUILD : error MSB1014: Must provide an item name for the getItem switch. MSBUILD : error MSB1014: 必須提供 getItem 切換的項目名稱。 diff --git a/src/MSBuild/XMake.cs b/src/MSBuild/XMake.cs index 773bd785a7e..545fdbc9844 100644 --- a/src/MSBuild/XMake.cs +++ b/src/MSBuild/XMake.cs @@ -15,6 +15,8 @@ using System.Reflection; using System.Security; using System.Text; +using System.Text.Json; +using System.Text.Json.Nodes; using System.Text.RegularExpressions; using System.Threading; using Microsoft.Build.Collections; @@ -2445,7 +2447,8 @@ private static bool ProcessCommandLineSwitches( !commandLineSwitches.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Preprocess) && !commandLineSwitches.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.GetProperty) && !commandLineSwitches.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.GetItem) && - !commandLineSwitches.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.GetTargetResult); + !commandLineSwitches.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.GetTargetResult) && + !commandLineSwitches.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.FeatureAvailability); // show copyright message if nologo switch is not set // NOTE: we heed the nologo switch even if there are switch errors @@ -2501,6 +2504,11 @@ private static bool ProcessCommandLineSwitches( { ShowVersion(); } + // if featureavailability switch is set, just show the feature availability and quit (ignore the other switches) + else if (commandLineSwitches.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.FeatureAvailability)) + { + ShowFeatureAvailability(commandLineSwitches[CommandLineSwitches.ParameterizedSwitch.FeatureAvailability]); + } else { bool foundProjectAutoResponseFile = CheckAndGatherProjectAutoResponseFile(switchesFromAutoResponseFile, commandLineSwitches, recursing, commandLine); @@ -4529,5 +4537,26 @@ private static void ShowVersion() Console.Write(ProjectCollection.Version.ToString()); } } + + private static void ShowFeatureAvailability(string[] features) + { + if (features.Length == 1) + { + string featureName = features[0]; + FeatureStatus availability = Features.CheckFeatureAvailability(featureName); + Console.WriteLine(availability); + } + else + { + var jsonNode = new JsonObject(); + foreach (string featureName in features) + { + jsonNode[featureName] = Features.CheckFeatureAvailability(featureName).ToString(); + } + + var options = new JsonSerializerOptions() { AllowTrailingCommas = false, WriteIndented = true }; + Console.WriteLine(jsonNode.ToJsonString(options)); + } + } } }