/// <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) });
/// <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)>(),