/// <summary>
        /// Creates a copy of <paramref name="profile"/> in which tokens are replaced via <paramref name="replaceAsync"/>.
        /// </summary>
        /// <remarks>
        /// Intended to replace tokens such as environment variables and MSBuild properties.
        /// </remarks>
        /// <param name="profile">The source profile to copy from.</param>
        /// <param name="replaceAsync">A function that performs token substitution.</param>
        /// <returns>A profile with tokens substituted.</returns>
        internal static async Task <LaunchProfile> ReplaceTokensAsync(ILaunchProfile profile, Func <string, Task <string> > replaceAsync)
        {
            return(new(
                       name : profile.Name,
                       commandName : profile.CommandName,
                       executablePath : await ReplaceOrNullAsync(profile.ExecutablePath),
                       commandLineArgs : await ReplaceOrNullAsync(profile.CommandLineArgs),
                       workingDirectory : await ReplaceOrNullAsync(profile.WorkingDirectory),
                       launchBrowser : profile.LaunchBrowser,
                       launchUrl : await ReplaceOrNullAsync(profile.LaunchUrl),
                       doNotPersist : profile.IsInMemoryObject(),
                       environmentVariables : await GetEnvironmentVariablesAsync(),
                       otherSettings : await GetOtherSettingsAsync()));

            Task <string?> ReplaceOrNullAsync(string?s)
            {
                if (Strings.IsNullOrWhiteSpace(s))
                {
                    return(TaskResult.Null <string>());
                }

                return(replaceAsync(s) !);
            }

            Task <ImmutableArray <(string Key, string Value)> > GetEnvironmentVariablesAsync()
            {
                return(profile switch
                {
                    ILaunchProfile2 profile2 => ReplaceValuesAsync(profile2.EnvironmentVariables, replaceAsync),
                    _ => ReplaceValuesAsync(profile.FlattenEnvironmentVariables(), replaceAsync)
                });
예제 #2
0
 /// <summary>
 /// Enumerates the profile's environment variables, preserving order if possible.
 /// </summary>
 /// <remarks>
 /// <para>
 /// If <paramref name="profile"/> is <see cref="ILaunchProfile2"/>, we enumerate
 /// <see cref="ILaunchProfile2.EnvironmentVariables"/> directly which has an
 /// explicit order.
 /// </para>
 /// <para>
 /// If <paramref name="profile"/> is <see cref="ILaunchProfile"/>,
 /// <see cref="ILaunchProfile.EnvironmentVariables"/> is unordered (hash ordered),
 /// so we order by key.
 /// </para>
 /// </remarks>
 /// <param name="profile">The profile to read from.</param>
 /// <returns>An ordered enumeration of environment variable name/value pairs.</returns>
 public static IEnumerable <(string Key, string Value)> EnumerateEnvironmentVariables(this ILaunchProfile profile)
 {
     return(profile switch
     {
         ILaunchProfile2 launchProfile => launchProfile.EnvironmentVariables,
         ILaunchProfile {
             EnvironmentVariables : null or {
                 Count : 0
             }
         } => Enumerable.Empty <(string Key, string Value)>(),