/// <summary> /// Re-applies in-memory profiles to the newly created snapshot. Note that we don't want to merge in the error /// profile /// </summary> protected static void MergeExistingInMemoryProfiles(LaunchSettingsData newSnapshot, ILaunchSettings prevSnapshot) { for (int i = 0; i < prevSnapshot.Profiles.Count; i++) { ILaunchProfile profile = prevSnapshot.Profiles[i]; if (profile.IsInMemoryObject() && !string.Equals(profile.CommandName, ErrorProfileCommandName)) { Assumes.NotNull(newSnapshot.Profiles); // Does it already have one with this name? if (newSnapshot.Profiles.FirstOrDefault((p1, p2) => LaunchProfile.IsSameProfileName(p1.Name, p2.Name), profile) == null) { // Create a new one from the existing in-memory profile and insert it in the same location, or the end if it // is beyond the end of the list if (i > newSnapshot.Profiles.Count) { newSnapshot.Profiles.Add(LaunchProfileData.FromILaunchProfile(profile)); } else { newSnapshot.Profiles.Insert(i, LaunchProfileData.FromILaunchProfile(profile)); } } } } }
/// <summary> /// Handles changes to the ProjectDebugger properties. Gets the active profile and generates a launch settings update if it /// has changed. The first evaluation generally kicks off the first snapshot /// </summary> protected async Task ProjectRuleBlock_ChangedAsync(IProjectVersionedValue <IProjectSubscriptionUpdate> projectSubscriptionUpdate) { if (projectSubscriptionUpdate.Value.CurrentState.TryGetValue(ProjectDebugger.SchemaName, out IProjectRuleSnapshot ruleSnapshot)) { ruleSnapshot.Properties.TryGetValue(ProjectDebugger.ActiveDebugProfileProperty, out string activeProfile); var snapshot = CurrentSnapshot; if (snapshot == null || !LaunchProfile.IsSameProfileName(activeProfile, snapshot.ActiveProfile?.Name)) { await UpdateActiveProfileInSnapshotAsync(activeProfile).ConfigureAwait(false); } } }
/// <summary> /// Removes the specified profile from the list and saves to disk. /// </summary> public async Task RemoveProfileAsync(string profileName) { var currentSettings = await GetSnapshotThrowIfErrors().ConfigureAwait(false); var existingProfile = currentSettings.Profiles.FirstOrDefault(p => LaunchProfile.IsSameProfileName(p.Name, profileName)); if (existingProfile != null) { var profiles = currentSettings.Profiles.Remove(existingProfile); var newSnapshot = new LaunchSettings(profiles, currentSettings.GlobalSettings, currentSettings.ActiveProfile?.Name); await UpdateAndSaveSettingsAsync(newSnapshot).ConfigureAwait(false); } }
/// <summary> /// Removes the specified profile from the list and saves to disk. /// </summary> public async Task RemoveProfileAsync(string profileName) { // Updates need to be sequenced await _sequentialTaskQueue.ExecuteTask(async() => { var currentSettings = await GetSnapshotThrowIfErrors().ConfigureAwait(false); var existingProfile = currentSettings.Profiles.FirstOrDefault(p => LaunchProfile.IsSameProfileName(p.Name, profileName)); if (existingProfile != null) { var profiles = currentSettings.Profiles.Remove(existingProfile); var newSnapshot = new LaunchSettings(profiles, currentSettings.GlobalSettings, currentSettings.ActiveProfile?.Name); await UpdateAndSaveSettingsInternalAsync(newSnapshot).ConfigureAwait(false); } }).ConfigureAwait(false); }
public Task AddOrUpdateProfileAsync(ILaunchProfile profile, bool addToFront) { // Updates need to be sequenced return(_sequentialTaskQueue.ExecuteTask(async() => { ILaunchSettings currentSettings = await GetSnapshotThrowIfErrors(); ILaunchProfile existingProfile = null; int insertionIndex = 0; foreach (ILaunchProfile p in currentSettings.Profiles) { if (LaunchProfile.IsSameProfileName(p.Name, profile.Name)) { existingProfile = p; break; } insertionIndex++; } ImmutableList <ILaunchProfile> profiles; if (existingProfile != null) { profiles = currentSettings.Profiles.Remove(existingProfile); } else { profiles = currentSettings.Profiles; } if (addToFront) { profiles = profiles.Insert(0, new LaunchProfile(profile)); } else { // Insertion index will be set to the current count (end of list) if an existing item was not found otherwise // it will point to where the previous one was found profiles = profiles.Insert(insertionIndex, new LaunchProfile(profile)); } // If the new profile is in-memory only, we don't want to touch the disk unless it replaces an existing disk based // profile bool saveToDisk = !profile.IsInMemoryObject() || (existingProfile != null && !existingProfile.IsInMemoryObject()); var newSnapshot = new LaunchSettings(profiles, currentSettings?.GlobalSettings, currentSettings?.ActiveProfile?.Name); await UpdateAndSaveSettingsInternalAsync(newSnapshot, saveToDisk); })); }
/// <summary> /// Removes the specified profile from the list and saves to disk. /// </summary> public async Task RemoveProfileAsync(string profileName) { // Updates need to be sequenced await _sequentialTaskQueue.ExecuteTask(async () => { var currentSettings = await GetSnapshotThrowIfErrors().ConfigureAwait(false); var existingProfile = currentSettings.Profiles.FirstOrDefault(p => LaunchProfile.IsSameProfileName(p.Name, profileName)); if (existingProfile != null) { var profiles = currentSettings.Profiles.Remove(existingProfile); // If the new profile is in-nmemory only, we don't want to touch the disk bool saveToDisk = !existingProfile.IsInMemoryObject(); var newSnapshot = new LaunchSettings(profiles, currentSettings.GlobalSettings, currentSettings.ActiveProfile?.Name); await UpdateAndSaveSettingsInternalAsync(newSnapshot, saveToDisk).ConfigureAwait(false); } }).ConfigureAwait(false); }
protected async Task ProjectRuleBlock_ChangedAsync(IProjectVersionedValue <Tuple <IProjectSubscriptionUpdate, IProjectCapabilitiesSnapshot> > projectSnapshot) { if (projectSnapshot.Value.Item1.CurrentState.TryGetValue(ProjectDebugger.SchemaName, out IProjectRuleSnapshot ruleSnapshot)) { ruleSnapshot.Properties.TryGetValue(ProjectDebugger.ActiveDebugProfileProperty, out string activeProfile); ILaunchSettings snapshot = CurrentSnapshot; if (snapshot == null || !LaunchProfile.IsSameProfileName(activeProfile, snapshot.ActiveProfile?.Name)) { // Updates need to be sequenced await _sequentialTaskQueue.ExecuteTask(async() => { using (ProjectCapabilitiesContext.CreateIsolatedContext(_commonProjectServices.Project, projectSnapshot.Value.Item2)) { await UpdateActiveProfileInSnapshotAsync(activeProfile); } }); } } }
/// <summary> /// Adds the given profile to the list and saves to disk. If a profile with the same /// name exists (case sensitive), it will be replaced with the new profile. If addToFront is /// true the profile will be the first one in the list. This is useful since quite often callers want /// their just added profile to be listed first in the start menu. If addToFront is false but there is /// an existing profile, the new one will be inserted at the same location rather than at the end. /// </summary> public async Task AddOrUpdateProfileAsync(ILaunchProfile profile, bool addToFront) { // Updates need to be sequenced await _sequentialTaskQueue.ExecuteTask(async() => { var currentSettings = await GetSnapshotThrowIfErrors().ConfigureAwait(false); ILaunchProfile existingProfile = null; int insertionIndex = 0; foreach (var p in currentSettings.Profiles) { if (LaunchProfile.IsSameProfileName(p.Name, profile.Name)) { existingProfile = p; break; } insertionIndex++; } ImmutableList <ILaunchProfile> profiles; if (existingProfile != null) { profiles = currentSettings.Profiles.Remove(existingProfile); } else { profiles = currentSettings.Profiles; } if (addToFront) { profiles = profiles.Insert(0, new LaunchProfile(profile)); } else { // Insertion index will be set to the current count (end of list) if an existing item was not found otherwise // it will point to where the previous one was found profiles = profiles.Insert(insertionIndex, new LaunchProfile(profile)); } var newSnapshot = new LaunchSettings(profiles, currentSettings?.GlobalSettings, currentSettings?.ActiveProfile?.Name); await UpdateAndSaveSettingsInternalAsync(newSnapshot).ConfigureAwait(false); }).ConfigureAwait(false); }
public WritableLaunchSettings(ILaunchSettings settings) { if (settings.Profiles != null) { foreach (ILaunchProfile profile in settings.Profiles) { Profiles.Add(new WritableLaunchProfile(profile)); } } // For global settings we want to make new copies of each entry so that the snapshot remains immutable. If the object implements // ICloneable that is used, otherwise, it is serialized back to json, and a new object rehydrated from that if (settings.GlobalSettings != null) { var jsonSerializerSettings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; foreach ((string key, object value) in settings.GlobalSettings) { if (value is ICloneable cloneableObject) { GlobalSettings.Add(key, cloneableObject.Clone()); } else { string jsonString = JsonConvert.SerializeObject(value, Formatting.Indented, jsonSerializerSettings); object?clonedObject = JsonConvert.DeserializeObject(jsonString, value.GetType()); if (clonedObject is not null) { GlobalSettings.Add(key, clonedObject); } } } } if (settings.ActiveProfile != null) { ActiveProfile = Profiles.Find(profile => LaunchProfile.IsSameProfileName(profile.Name, settings.ActiveProfile.Name)); } }
public WritableLaunchSettings(ILaunchSettings settings) { if (settings.Profiles != null) { foreach (ILaunchProfile profile in settings.Profiles) { Profiles.Add(new WritableLaunchProfile(profile)); } } // For global settings we want to make new copies of each entry so that the snapshot remains immutable. If the object implements // ICloneable that is used, otherwise, it is serialized back to json, and a new object rehydrated from that if (settings.GlobalSettings != null) { foreach (KeyValuePair <string, object> kvp in settings.GlobalSettings) { if (kvp.Value is ICloneable clonableObject) { GlobalSettings.Add(kvp.Key, clonableObject.Clone()); } else { string jsonString = JsonConvert.SerializeObject(kvp.Value, Formatting.Indented, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore }); object clonedObject = JsonConvert.DeserializeObject(jsonString, kvp.Value.GetType()); GlobalSettings.Add(kvp.Key, clonedObject); } } } if (settings.ActiveProfile != null) { ActiveProfile = Profiles.FirstOrDefault((profile) => LaunchProfile.IsSameProfileName(profile.Name, settings.ActiveProfile.Name)); } }
/// <summary> /// Re-applies in-memory profiles to the newly created snapshot /// </summary> protected void MergeExistingInMemoryProfiles(LaunchSettingsData newSnapshot, ILaunchSettings prevSnapshot) { for (int i = 0; i < prevSnapshot.Profiles.Count; i++) { var profile = prevSnapshot.Profiles[i]; if (profile.IsInMemoryObject()) { // Does it already have one with this name? if (newSnapshot.Profiles.FirstOrDefault(p => LaunchProfile.IsSameProfileName(p.Name, profile.Name)) == null) { // Create a new one from the existing in-memory profile and insert it in the same location, or the end if it // is beyond the end of the list if (i > newSnapshot.Profiles.Count) { newSnapshot.Profiles.Add(LaunchProfileData.FromILaunchProfile(profile)); } else { newSnapshot.Profiles.Insert(i, LaunchProfileData.FromILaunchProfile(profile)); } } } } }
public void LaunchProfile_IsSameProfileNameTests() { Assert.True(LaunchProfile.IsSameProfileName("test", "test")); Assert.False(LaunchProfile.IsSameProfileName("test", "Test")); }
public static bool ProfilesAreDifferent(this ILaunchSettings launchSettings, IList <ILaunchProfile> profilesToCompare) { bool detectedChanges = launchSettings.Profiles == null || launchSettings.Profiles.Count != profilesToCompare.Count; if (!detectedChanges) { // Now compare each item foreach (var profile in profilesToCompare) { var existingProfile = launchSettings.Profiles.FirstOrDefault(p => LaunchProfile.IsSameProfileName(p.Name, profile.Name)); if (existingProfile == null || !LaunchProfile.ProfilesAreEqual(profile, existingProfile, true)) { detectedChanges = true; break; } } } return(detectedChanges); }
/// <summary> /// See <see cref="IDynamicEnumValuesGenerator"/> /// </summary> public async Task <IEnumValue> TryCreateEnumValueAsync(string userSuppliedValue) { return((await listedValues.GetValueAsync().ConfigureAwait(true)) .FirstOrDefault(v => LaunchProfile.IsSameProfileName(v.Name, userSuppliedValue))); }