/// <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);
            }
        }
示例#4
0
 /// <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);
 }
示例#5
0
        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);
        }
示例#7
0
 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);
                 }
             });
         }
     }
 }
示例#8
0
        /// <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));
                 }
             }
         }
     }
 }
示例#12
0
 public void LaunchProfile_IsSameProfileNameTests()
 {
     Assert.True(LaunchProfile.IsSameProfileName("test", "test"));
     Assert.False(LaunchProfile.IsSameProfileName("test", "Test"));
 }
示例#13
0
        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);
        }
示例#14
0
 /// <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)));
 }