From a28f98ded567996387a23d9923f28df51faa834a Mon Sep 17 00:00:00 2001 From: aparajit-pratap Date: Tue, 25 Jun 2019 00:50:11 -0400 Subject: [PATCH 01/10] prevent duplicate custom node package from loading --- src/DynamoCore/Core/CustomNodeManager.cs | 9 ++++- src/DynamoCore/DynamoCore.csproj | 1 + ...DuplicateCustomNodePackageLoadException.cs | 33 +++++++++++++++++++ src/DynamoCore/Models/DynamoModel.cs | 2 ++ .../PackageManagerClientViewModel.cs | 12 +++++-- .../PackageManagerSearchViewModel.cs | 22 ++++++++++++- src/DynamoPackages/PackageLoader.cs | 19 +++++++++++ 7 files changed, 94 insertions(+), 4 deletions(-) create mode 100644 src/DynamoCore/Exceptions/DuplicateCustomNodePackageLoadException.cs diff --git a/src/DynamoCore/Core/CustomNodeManager.cs b/src/DynamoCore/Core/CustomNodeManager.cs index dca2ad07a1b..8053a90aeb7 100644 --- a/src/DynamoCore/Core/CustomNodeManager.cs +++ b/src/DynamoCore/Core/CustomNodeManager.cs @@ -6,6 +6,7 @@ using System.Xml; using Dynamo.Engine; using Dynamo.Engine.NodeToCode; +using Dynamo.Exceptions; using Dynamo.Graph; using Dynamo.Graph.Annotations; using Dynamo.Graph.Connectors; @@ -119,7 +120,7 @@ protected virtual void OnInfoUpdated(CustomNodeInfo obj) var handler = InfoUpdated; if (handler != null) handler(obj); } - + /// /// An event that is fired when a custom node is removed from Dynamo. /// @@ -455,6 +456,12 @@ private void SetNodeInfo(CustomNodeInfo newInfo) NodeInfos.Remove(guid); } + CustomNodeInfo value; + if (NodeInfos.TryGetValue(newInfo.FunctionId, out value)) + { + throw new DuplicateCustomNodePackageLoadException(Path.GetDirectoryName(value.Path), "duplicate package"); + } + NodeInfos[newInfo.FunctionId] = newInfo; OnInfoUpdated(newInfo); } diff --git a/src/DynamoCore/DynamoCore.csproj b/src/DynamoCore/DynamoCore.csproj index ffd42b76dc7..63aa7b33bbf 100644 --- a/src/DynamoCore/DynamoCore.csproj +++ b/src/DynamoCore/DynamoCore.csproj @@ -121,6 +121,7 @@ limitations under the License. + diff --git a/src/DynamoCore/Exceptions/DuplicateCustomNodePackageLoadException.cs b/src/DynamoCore/Exceptions/DuplicateCustomNodePackageLoadException.cs new file mode 100644 index 00000000000..abec871ecb6 --- /dev/null +++ b/src/DynamoCore/Exceptions/DuplicateCustomNodePackageLoadException.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Dynamo.Exceptions +{ + public class DuplicateCustomNodePackageLoadException : Exception + { + /// + /// File path of failing custom node package. + /// + public string Path; + + /// + /// Failure reason. + /// + public string Reason; + + /// + /// Constructor. + /// + /// + /// + public DuplicateCustomNodePackageLoadException(string path, string reason) + : base(String.Format(Properties.Resources.FailedToLoad, path, reason)) + { + Path = path; + Reason = reason; + } + } +} diff --git a/src/DynamoCore/Models/DynamoModel.cs b/src/DynamoCore/Models/DynamoModel.cs index b7121bcb607..f046a50fcc7 100644 --- a/src/DynamoCore/Models/DynamoModel.cs +++ b/src/DynamoCore/Models/DynamoModel.cs @@ -1122,6 +1122,8 @@ private void InitializeCustomNodeManager() CustomNodeManager.DefinitionUpdated += UpdateCustomNodeDefinition; } + + private void InitializeIncludedNodes() { var customNodeData = new TypeLoadData(typeof(Function)); diff --git a/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerClientViewModel.cs b/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerClientViewModel.cs index 0bc286a6ee0..d5e07a09cee 100644 --- a/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerClientViewModel.cs +++ b/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerClientViewModel.cs @@ -10,6 +10,7 @@ using System.Windows; using System.Windows.Input; using Dynamo.Core; +using Dynamo.Exceptions; using Dynamo.Graph.Nodes.CustomNodes; using Dynamo.Graph.Workspaces; using Dynamo.Models; @@ -183,6 +184,13 @@ public ObservableCollection Downloads set { _downloads = value; } } + private PackageManagerExtension pmExtension; + + internal PackageManagerExtension PackageManagerExtension + { + get { return pmExtension ?? (pmExtension = DynamoViewModel.Model.GetPackageManagerExtension()); } + } + public List CachedPackageList { get; private set; } public readonly DynamoViewModel DynamoViewModel; @@ -393,7 +401,6 @@ private void ShowNodePublishInfo(ICollection {p}); + + pmExtension.PackageLoader.LoadPackages(new List { p }); packageDownloadHandle.DownloadState = PackageDownloadHandle.State.Installed; } diff --git a/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs b/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs index 99ac1b20ec4..fba1b3e2e49 100644 --- a/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs +++ b/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs @@ -263,8 +263,9 @@ public PackageManagerSearchViewModel(PackageManagerClientViewModel client) : thi { this.PackageManagerClientViewModel = client; PackageManagerClientViewModel.Downloads.CollectionChanged += DownloadsOnCollectionChanged; + PackageManagerClientViewModel.PackageManagerExtension.PackageLoader.DuplicatePackageLoaded += DuplicateCustomNodePackageLoaded; } - + /// /// Sort the search results /// @@ -639,6 +640,25 @@ public static string FormatPackageVersionList(IEnumerable x.Item1.name + " " + x.Item2.version)); } + private void DuplicateCustomNodePackageLoaded(Package installed, Package duplicate) + { + var productName = PackageManagerClientViewModel.DynamoViewModel.BrandingResourceProvider.ProductName; + var message = string.Format(Resources.MessageUninstallToContinue2, + productName, JoinPackageNames(new List {installed}), + duplicate.Name + " " + duplicate.VersionName); + + var dialogResult = MessageBox.Show(message, + Resources.CannotDownloadPackageMessageBoxTitle, + MessageBoxButton.YesNo, MessageBoxImage.Error); + + if (dialogResult == MessageBoxResult.Yes) + { + // mark for uninstallation + var settings = PackageManagerClientViewModel.DynamoViewModel.Model.PreferenceSettings; + installed.MarkForUninstall(settings); + } + } + private void DownloadsOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs args) { if (args.NewItems != null) diff --git a/src/DynamoPackages/PackageLoader.cs b/src/DynamoPackages/PackageLoader.cs index 17971e79be6..25e38900ec5 100644 --- a/src/DynamoPackages/PackageLoader.cs +++ b/src/DynamoPackages/PackageLoader.cs @@ -207,6 +207,18 @@ internal void TryLoadPackageIntoLibrary(Package package) package.Loaded = true; this.PackgeLoaded?.Invoke(package); } + //catch (DuplicateCustomNodePackageLoadException e) + //{ + // Package originalPackage = + // localPackages.FirstOrDefault(x => x.CustomNodeDirectory == e.Path); + // OnDuplicatePackageLoaded(originalPackage, package); + // throw e; + //} + //catch (LibraryLoadFailedException e) + //{ + // Log(e.GetType() + ": " + e.Message); + // throw e; + //} catch (Exception e) { Log("Exception when attempting to load package " + package.Name + " from " + package.RootDirectory); @@ -214,6 +226,13 @@ internal void TryLoadPackageIntoLibrary(Package package) } } + public event Action DuplicatePackageLoaded; + protected virtual void OnDuplicatePackageLoaded(Package installed, Package duplicate) + { + var handler = DuplicatePackageLoaded; + handler?.Invoke(installed, duplicate); + } + /// /// Load the package into Dynamo (including all node libraries and custom nodes) /// and add to LocalPackages. From 155d5365400aafd2dea125a7947cf3378e2ee0e5 Mon Sep 17 00:00:00 2001 From: aparajit-pratap Date: Tue, 25 Jun 2019 22:23:40 -0400 Subject: [PATCH 02/10] rename --- src/DynamoCore/Core/CustomNodeManager.cs | 2 +- src/DynamoCore/DynamoCore.csproj | 2 +- ...geLoadException.cs => CustomNodePackageLoadException.cs} | 4 ++-- src/DynamoCore/Models/DynamoModel.cs | 2 -- .../PackageManager/PackageManagerClientViewModel.cs | 2 +- .../PackageManager/PackageManagerSearchViewModel.cs | 4 ++-- src/DynamoPackages/PackageLoader.cs | 6 +++--- 7 files changed, 10 insertions(+), 12 deletions(-) rename src/DynamoCore/Exceptions/{DuplicateCustomNodePackageLoadException.cs => CustomNodePackageLoadException.cs} (82%) diff --git a/src/DynamoCore/Core/CustomNodeManager.cs b/src/DynamoCore/Core/CustomNodeManager.cs index 8053a90aeb7..261c21bdf5a 100644 --- a/src/DynamoCore/Core/CustomNodeManager.cs +++ b/src/DynamoCore/Core/CustomNodeManager.cs @@ -459,7 +459,7 @@ private void SetNodeInfo(CustomNodeInfo newInfo) CustomNodeInfo value; if (NodeInfos.TryGetValue(newInfo.FunctionId, out value)) { - throw new DuplicateCustomNodePackageLoadException(Path.GetDirectoryName(value.Path), "duplicate package"); + throw new CustomNodePackageLoadException(Path.GetDirectoryName(value.Path), "duplicate package"); } NodeInfos[newInfo.FunctionId] = newInfo; diff --git a/src/DynamoCore/DynamoCore.csproj b/src/DynamoCore/DynamoCore.csproj index 63aa7b33bbf..aefff4b48db 100644 --- a/src/DynamoCore/DynamoCore.csproj +++ b/src/DynamoCore/DynamoCore.csproj @@ -121,7 +121,7 @@ limitations under the License. - + diff --git a/src/DynamoCore/Exceptions/DuplicateCustomNodePackageLoadException.cs b/src/DynamoCore/Exceptions/CustomNodePackageLoadException.cs similarity index 82% rename from src/DynamoCore/Exceptions/DuplicateCustomNodePackageLoadException.cs rename to src/DynamoCore/Exceptions/CustomNodePackageLoadException.cs index abec871ecb6..ca96765e77c 100644 --- a/src/DynamoCore/Exceptions/DuplicateCustomNodePackageLoadException.cs +++ b/src/DynamoCore/Exceptions/CustomNodePackageLoadException.cs @@ -6,7 +6,7 @@ namespace Dynamo.Exceptions { - public class DuplicateCustomNodePackageLoadException : Exception + public class CustomNodePackageLoadException : Exception { /// /// File path of failing custom node package. @@ -23,7 +23,7 @@ public class DuplicateCustomNodePackageLoadException : Exception /// /// /// - public DuplicateCustomNodePackageLoadException(string path, string reason) + public CustomNodePackageLoadException(string path, string reason) : base(String.Format(Properties.Resources.FailedToLoad, path, reason)) { Path = path; diff --git a/src/DynamoCore/Models/DynamoModel.cs b/src/DynamoCore/Models/DynamoModel.cs index f046a50fcc7..b7121bcb607 100644 --- a/src/DynamoCore/Models/DynamoModel.cs +++ b/src/DynamoCore/Models/DynamoModel.cs @@ -1122,8 +1122,6 @@ private void InitializeCustomNodeManager() CustomNodeManager.DefinitionUpdated += UpdateCustomNodeDefinition; } - - private void InitializeIncludedNodes() { var customNodeData = new TypeLoadData(typeof(Function)); diff --git a/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerClientViewModel.cs b/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerClientViewModel.cs index d5e07a09cee..ca5a7a218d2 100644 --- a/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerClientViewModel.cs +++ b/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerClientViewModel.cs @@ -498,7 +498,7 @@ internal void DownloadAndInstall(PackageDownloadHandle packageDownloadHandle, st { var p = Package.FromDirectory(dynPkg.RootDirectory, DynamoViewModel.Model.Logger); - pmExtension.PackageLoader.LoadPackages(new List { p }); + pmExtension.PackageLoader.LoadPackages(new List {p}); packageDownloadHandle.DownloadState = PackageDownloadHandle.State.Installed; } diff --git a/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs b/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs index fba1b3e2e49..b3d075e66cb 100644 --- a/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs +++ b/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs @@ -263,7 +263,7 @@ public PackageManagerSearchViewModel(PackageManagerClientViewModel client) : thi { this.PackageManagerClientViewModel = client; PackageManagerClientViewModel.Downloads.CollectionChanged += DownloadsOnCollectionChanged; - PackageManagerClientViewModel.PackageManagerExtension.PackageLoader.DuplicatePackageLoaded += DuplicateCustomNodePackageLoaded; + PackageManagerClientViewModel.PackageManagerExtension.PackageLoader.CustomNodePackageWithDuplicateNodeIDLoaded += CustomNodeNodeIdWithCustomNodePackageWithDuplicateNodeIdLoaded; } /// @@ -640,7 +640,7 @@ public static string FormatPackageVersionList(IEnumerable x.Item1.name + " " + x.Item2.version)); } - private void DuplicateCustomNodePackageLoaded(Package installed, Package duplicate) + private void CustomNodeNodeIdWithCustomNodePackageWithDuplicateNodeIdLoaded(Package installed, Package duplicate) { var productName = PackageManagerClientViewModel.DynamoViewModel.BrandingResourceProvider.ProductName; var message = string.Format(Resources.MessageUninstallToContinue2, diff --git a/src/DynamoPackages/PackageLoader.cs b/src/DynamoPackages/PackageLoader.cs index 25e38900ec5..a8900877443 100644 --- a/src/DynamoPackages/PackageLoader.cs +++ b/src/DynamoPackages/PackageLoader.cs @@ -207,7 +207,7 @@ internal void TryLoadPackageIntoLibrary(Package package) package.Loaded = true; this.PackgeLoaded?.Invoke(package); } - //catch (DuplicateCustomNodePackageLoadException e) + //catch (CustomNodePackageLoadException e) //{ // Package originalPackage = // localPackages.FirstOrDefault(x => x.CustomNodeDirectory == e.Path); @@ -226,10 +226,10 @@ internal void TryLoadPackageIntoLibrary(Package package) } } - public event Action DuplicatePackageLoaded; + public event Action CustomNodePackageWithDuplicateNodeIDLoaded; protected virtual void OnDuplicatePackageLoaded(Package installed, Package duplicate) { - var handler = DuplicatePackageLoaded; + var handler = CustomNodePackageWithDuplicateNodeIDLoaded; handler?.Invoke(installed, duplicate); } From 183d284c0fd55d4c816f44e5e7812c8b02140650 Mon Sep 17 00:00:00 2001 From: aparajit-pratap Date: Tue, 25 Jun 2019 22:26:43 -0400 Subject: [PATCH 03/10] rename --- .../PackageManager/PackageManagerSearchViewModel.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs b/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs index b3d075e66cb..98e59a27653 100644 --- a/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs +++ b/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs @@ -263,7 +263,7 @@ public PackageManagerSearchViewModel(PackageManagerClientViewModel client) : thi { this.PackageManagerClientViewModel = client; PackageManagerClientViewModel.Downloads.CollectionChanged += DownloadsOnCollectionChanged; - PackageManagerClientViewModel.PackageManagerExtension.PackageLoader.CustomNodePackageWithDuplicateNodeIDLoaded += CustomNodeNodeIdWithCustomNodePackageWithDuplicateNodeIdLoaded; + PackageManagerClientViewModel.PackageManagerExtension.PackageLoader.CustomNodePackageWithDuplicateNodeIDLoaded += CustomNodePackageWithDuplicateNodeIdLoaded; } /// @@ -640,7 +640,7 @@ public static string FormatPackageVersionList(IEnumerable x.Item1.name + " " + x.Item2.version)); } - private void CustomNodeNodeIdWithCustomNodePackageWithDuplicateNodeIdLoaded(Package installed, Package duplicate) + private void CustomNodePackageWithDuplicateNodeIdLoaded(Package installed, Package duplicate) { var productName = PackageManagerClientViewModel.DynamoViewModel.BrandingResourceProvider.ProductName; var message = string.Format(Resources.MessageUninstallToContinue2, From efe3784ee6037be0d5a22dfb329a83a337abe577 Mon Sep 17 00:00:00 2001 From: aparajit-pratap Date: Tue, 25 Jun 2019 23:51:54 -0400 Subject: [PATCH 04/10] code fixes --- src/DynamoCore/Core/CustomNodeManager.cs | 7 ++++++- .../Properties/Resources.Designer.cs | 11 +++++++++++ .../Properties/Resources.en-US.resx | 5 +++++ src/DynamoCore/Properties/Resources.resx | 5 +++++ .../PackageManagerSearchViewModel.cs | 13 +++++++------ src/DynamoPackages/PackageLoader.cs | 19 +++++++++---------- 6 files changed, 43 insertions(+), 17 deletions(-) diff --git a/src/DynamoCore/Core/CustomNodeManager.cs b/src/DynamoCore/Core/CustomNodeManager.cs index 261c21bdf5a..c7e8ff28392 100644 --- a/src/DynamoCore/Core/CustomNodeManager.cs +++ b/src/DynamoCore/Core/CustomNodeManager.cs @@ -459,7 +459,12 @@ private void SetNodeInfo(CustomNodeInfo newInfo) CustomNodeInfo value; if (NodeInfos.TryGetValue(newInfo.FunctionId, out value)) { - throw new CustomNodePackageLoadException(Path.GetDirectoryName(value.Path), "duplicate package"); + var message = string.Format(Resources.MessageUninstallCustomNodeToContinue, + "Dynamo", Path.GetDirectoryName(value.Path), Path.GetDirectoryName(newInfo.Path)); + LibraryLoadFailedException ex = new LibraryLoadFailedException(Path.GetDirectoryName(newInfo.Path), message); + Log(ex.Message, WarningLevel.Moderate); + Log(ex); + throw new CustomNodePackageLoadException(Path.GetDirectoryName(value.Path), message); } NodeInfos[newInfo.FunctionId] = newInfo; diff --git a/src/DynamoCore/Properties/Resources.Designer.cs b/src/DynamoCore/Properties/Resources.Designer.cs index 29a19fc343a..a028dcaa66f 100644 --- a/src/DynamoCore/Properties/Resources.Designer.cs +++ b/src/DynamoCore/Properties/Resources.Designer.cs @@ -871,6 +871,17 @@ public static string MalformedHeaderPackage { } } + /// + /// Looks up a localized string similar to {2} cannot be loaded. It has one or more node definitions that already exist in {1} that is currently loaded. To install {2}, {0} needs to first uninstall {1}. Restart {0} to complete the uninstall, then try and download {2} again. + /// + ///Uninstall the following packages: {1}?. + /// + public static string MessageUninstallCustomNodeToContinue { + get { + return ResourceManager.GetString("MessageUninstallCustomNodeToContinue", resourceCulture); + } + } + /// /// Looks up a localized string similar to SHOW MORE ({0}). /// diff --git a/src/DynamoCore/Properties/Resources.en-US.resx b/src/DynamoCore/Properties/Resources.en-US.resx index 951352426c7..091cf70bcbc 100644 --- a/src/DynamoCore/Properties/Resources.en-US.resx +++ b/src/DynamoCore/Properties/Resources.en-US.resx @@ -700,4 +700,9 @@ The input name should be a valid variable name, without spaces. An input type an Python template loaded from DynamoSettings.xml path + + {2} cannot be loaded. It has one or more node definitions that already exist in {1} that is currently loaded. To install {2}, {0} needs to first uninstall {1}. Restart {0} to complete the uninstall, then try and download {2} again. + +Uninstall the following packages: {1}? + \ No newline at end of file diff --git a/src/DynamoCore/Properties/Resources.resx b/src/DynamoCore/Properties/Resources.resx index d5f9f63c10f..06522e3ecdf 100644 --- a/src/DynamoCore/Properties/Resources.resx +++ b/src/DynamoCore/Properties/Resources.resx @@ -700,4 +700,9 @@ The input name should be a valid variable name, without spaces. An input type an Python template set by host integrator + + {2} cannot be loaded. It has one or more node definitions that already exist in {1} that is currently loaded. To install {2}, {0} needs to first uninstall {1}. Restart {0} to complete the uninstall, then try and download {2} again. + +Uninstall the following packages: {1}? + \ No newline at end of file diff --git a/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs b/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs index 98e59a27653..27bee1f46f0 100644 --- a/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs +++ b/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs @@ -263,7 +263,8 @@ public PackageManagerSearchViewModel(PackageManagerClientViewModel client) : thi { this.PackageManagerClientViewModel = client; PackageManagerClientViewModel.Downloads.CollectionChanged += DownloadsOnCollectionChanged; - PackageManagerClientViewModel.PackageManagerExtension.PackageLoader.CustomNodePackageWithDuplicateNodeIDLoaded += CustomNodePackageWithDuplicateNodeIdLoaded; + PackageManagerClientViewModel.PackageManagerExtension.PackageLoader.CustomNodePackageWithDuplicateNodeIDLoaded += + CustomNodePackageWithDuplicateNodeIdLoaded; } /// @@ -640,12 +641,12 @@ public static string FormatPackageVersionList(IEnumerable x.Item1.name + " " + x.Item2.version)); } - private void CustomNodePackageWithDuplicateNodeIdLoaded(Package installed, Package duplicate) + private void CustomNodePackageWithDuplicateNodeIdLoaded(Package installed, string message) { - var productName = PackageManagerClientViewModel.DynamoViewModel.BrandingResourceProvider.ProductName; - var message = string.Format(Resources.MessageUninstallToContinue2, - productName, JoinPackageNames(new List {installed}), - duplicate.Name + " " + duplicate.VersionName); + //var productName = PackageManagerClientViewModel.DynamoViewModel.BrandingResourceProvider.ProductName; + //var message = string.Format(Resources.MessageUninstallCustomNodeToContinue, + // productName, JoinPackageNames(new List {installed}), + // duplicate.Name + " " + duplicate.VersionName); var dialogResult = MessageBox.Show(message, Resources.CannotDownloadPackageMessageBoxTitle, diff --git a/src/DynamoPackages/PackageLoader.cs b/src/DynamoPackages/PackageLoader.cs index a8900877443..d9debfcea83 100644 --- a/src/DynamoPackages/PackageLoader.cs +++ b/src/DynamoPackages/PackageLoader.cs @@ -207,13 +207,12 @@ internal void TryLoadPackageIntoLibrary(Package package) package.Loaded = true; this.PackgeLoaded?.Invoke(package); } - //catch (CustomNodePackageLoadException e) - //{ - // Package originalPackage = - // localPackages.FirstOrDefault(x => x.CustomNodeDirectory == e.Path); - // OnDuplicatePackageLoaded(originalPackage, package); - // throw e; - //} + catch (CustomNodePackageLoadException e) + { + Package originalPackage = + localPackages.FirstOrDefault(x => x.CustomNodeDirectory == e.Path); + OnDuplicatePackageLoaded(originalPackage, e.Reason); + } //catch (LibraryLoadFailedException e) //{ // Log(e.GetType() + ": " + e.Message); @@ -226,11 +225,11 @@ internal void TryLoadPackageIntoLibrary(Package package) } } - public event Action CustomNodePackageWithDuplicateNodeIDLoaded; - protected virtual void OnDuplicatePackageLoaded(Package installed, Package duplicate) + public event Action CustomNodePackageWithDuplicateNodeIDLoaded; + protected virtual void OnDuplicatePackageLoaded(Package installed, string reason) { var handler = CustomNodePackageWithDuplicateNodeIDLoaded; - handler?.Invoke(installed, duplicate); + handler?.Invoke(installed, reason); } /// From 01e12cb4c8796a68b5c59b5fb952ac85ad60dc19 Mon Sep 17 00:00:00 2001 From: aparajit-pratap Date: Thu, 27 Jun 2019 00:59:19 -0400 Subject: [PATCH 05/10] code cleanup --- src/DynamoCore/Core/CustomNodeManager.cs | 18 ++++++++++----- .../CustomNodePackageLoadException.cs | 23 ++++++++----------- .../Properties/Resources.Designer.cs | 8 +++---- .../Properties/Resources.en-US.resx | 6 ++--- src/DynamoCore/Properties/Resources.resx | 6 ++--- .../Properties/Resources.Designer.cs | 11 +++++++++ .../Properties/Resources.en-US.resx | 5 ++++ src/DynamoCoreWpf/Properties/Resources.resx | 5 ++++ .../PackageManagerSearchViewModel.cs | 12 ++++------ src/DynamoPackages/PackageLoader.cs | 17 +++++--------- 10 files changed, 60 insertions(+), 51 deletions(-) diff --git a/src/DynamoCore/Core/CustomNodeManager.cs b/src/DynamoCore/Core/CustomNodeManager.cs index c7e8ff28392..727c969052c 100644 --- a/src/DynamoCore/Core/CustomNodeManager.cs +++ b/src/DynamoCore/Core/CustomNodeManager.cs @@ -456,15 +456,21 @@ private void SetNodeInfo(CustomNodeInfo newInfo) NodeInfos.Remove(guid); } - CustomNodeInfo value; - if (NodeInfos.TryGetValue(newInfo.FunctionId, out value)) + CustomNodeInfo info; + if (NodeInfos.TryGetValue(newInfo.FunctionId, out info)) { - var message = string.Format(Resources.MessageUninstallCustomNodeToContinue, - "Dynamo", Path.GetDirectoryName(value.Path), Path.GetDirectoryName(newInfo.Path)); - LibraryLoadFailedException ex = new LibraryLoadFailedException(Path.GetDirectoryName(newInfo.Path), message); + var newInfoPath = Path.GetDirectoryName(newInfo.Path); + var infoPath = Path.GetDirectoryName(info.Path); + var message = string.Format(Resources.MessageCustomNodePackageFailedToLoad, + infoPath, newInfoPath); + + var ex = new CustomNodePackageLoadException(newInfoPath, infoPath, message); Log(ex.Message, WarningLevel.Moderate); + + // Log to notification view extension Log(ex); - throw new CustomNodePackageLoadException(Path.GetDirectoryName(value.Path), message); + + throw ex; } NodeInfos[newInfo.FunctionId] = newInfo; diff --git a/src/DynamoCore/Exceptions/CustomNodePackageLoadException.cs b/src/DynamoCore/Exceptions/CustomNodePackageLoadException.cs index ca96765e77c..f72cba8c736 100644 --- a/src/DynamoCore/Exceptions/CustomNodePackageLoadException.cs +++ b/src/DynamoCore/Exceptions/CustomNodePackageLoadException.cs @@ -6,28 +6,23 @@ namespace Dynamo.Exceptions { - public class CustomNodePackageLoadException : Exception + public class CustomNodePackageLoadException : LibraryLoadFailedException { /// - /// File path of failing custom node package. + /// File path of existing custom node package. /// - public string Path; - - /// - /// Failure reason. - /// - public string Reason; + public string InstalledPath { get; } /// /// Constructor. /// - /// - /// - public CustomNodePackageLoadException(string path, string reason) - : base(String.Format(Properties.Resources.FailedToLoad, path, reason)) + /// File path of failing custom node package. + /// File path of existing package. + /// Failure reason. + public CustomNodePackageLoadException(string path, string installedPath, string reason) + : base(path, reason) { - Path = path; - Reason = reason; + InstalledPath = installedPath; } } } diff --git a/src/DynamoCore/Properties/Resources.Designer.cs b/src/DynamoCore/Properties/Resources.Designer.cs index a028dcaa66f..e319a4a6190 100644 --- a/src/DynamoCore/Properties/Resources.Designer.cs +++ b/src/DynamoCore/Properties/Resources.Designer.cs @@ -872,13 +872,11 @@ public static string MalformedHeaderPackage { } /// - /// Looks up a localized string similar to {2} cannot be loaded. It has one or more node definitions that already exist in {1} that is currently loaded. To install {2}, {0} needs to first uninstall {1}. Restart {0} to complete the uninstall, then try and download {2} again. - /// - ///Uninstall the following packages: {1}?. + /// Looks up a localized string similar to {1} cannot be loaded. It has one or more node definitions that already exist in {0} that is currently loaded. To install {1}, Dynamo needs to first uninstall {0}. Restart Dynamo to complete the uninstall, then try and download {1} again.. /// - public static string MessageUninstallCustomNodeToContinue { + public static string MessageCustomNodePackageFailedToLoad { get { - return ResourceManager.GetString("MessageUninstallCustomNodeToContinue", resourceCulture); + return ResourceManager.GetString("MessageCustomNodePackageFailedToLoad", resourceCulture); } } diff --git a/src/DynamoCore/Properties/Resources.en-US.resx b/src/DynamoCore/Properties/Resources.en-US.resx index 091cf70bcbc..08d85ffb693 100644 --- a/src/DynamoCore/Properties/Resources.en-US.resx +++ b/src/DynamoCore/Properties/Resources.en-US.resx @@ -700,9 +700,7 @@ The input name should be a valid variable name, without spaces. An input type an Python template loaded from DynamoSettings.xml path - - {2} cannot be loaded. It has one or more node definitions that already exist in {1} that is currently loaded. To install {2}, {0} needs to first uninstall {1}. Restart {0} to complete the uninstall, then try and download {2} again. - -Uninstall the following packages: {1}? + + {1} cannot be loaded. It has one or more node definitions that already exist in {0} that is currently loaded. To install {1}, Dynamo needs to first uninstall {0}. Restart Dynamo to complete the uninstall, then try and download {1} again. \ No newline at end of file diff --git a/src/DynamoCore/Properties/Resources.resx b/src/DynamoCore/Properties/Resources.resx index 06522e3ecdf..757c1d1ce67 100644 --- a/src/DynamoCore/Properties/Resources.resx +++ b/src/DynamoCore/Properties/Resources.resx @@ -700,9 +700,7 @@ The input name should be a valid variable name, without spaces. An input type an Python template set by host integrator - - {2} cannot be loaded. It has one or more node definitions that already exist in {1} that is currently loaded. To install {2}, {0} needs to first uninstall {1}. Restart {0} to complete the uninstall, then try and download {2} again. - -Uninstall the following packages: {1}? + + {1} cannot be loaded. It has one or more node definitions that already exist in {0} that is currently loaded. To install {1}, Dynamo needs to first uninstall {0}. Restart Dynamo to complete the uninstall, then try and download {1} again. \ No newline at end of file diff --git a/src/DynamoCoreWpf/Properties/Resources.Designer.cs b/src/DynamoCoreWpf/Properties/Resources.Designer.cs index e073ee8104c..ce7c20b1921 100644 --- a/src/DynamoCoreWpf/Properties/Resources.Designer.cs +++ b/src/DynamoCoreWpf/Properties/Resources.Designer.cs @@ -3304,6 +3304,17 @@ public static string MessageToUndeprecatePackage { } } + /// + /// Looks up a localized string similar to {1} cannot be loaded. It has one or more node definitions that already exist in {0} that is currently loaded. To install {1}, Dynamo needs to first uninstall {0}. Restart Dynamo to complete the uninstall, then try and download {1} again. + /// + ///Uninstall the following packages: {1}?. + /// + public static string MessageUninstallCustomNodeToContinue { + get { + return ResourceManager.GetString("MessageUninstallCustomNodeToContinue", resourceCulture); + } + } + /// /// Looks up a localized string similar to {0} needs to uninstall {1} to continue, but cannot as one of its types appears to be in use. Try restarting {0}.. /// diff --git a/src/DynamoCoreWpf/Properties/Resources.en-US.resx b/src/DynamoCoreWpf/Properties/Resources.en-US.resx index e76ecc5027d..af6b05364f4 100644 --- a/src/DynamoCoreWpf/Properties/Resources.en-US.resx +++ b/src/DynamoCoreWpf/Properties/Resources.en-US.resx @@ -2199,4 +2199,9 @@ Do you want to install the latest Dynamo update? No new tab is added, as the extension is already present in the extensions side bar. + + {1} cannot be loaded. It has one or more node definitions that already exist in {0} that is currently loaded. To install {1}, Dynamo needs to first uninstall {0}. Restart Dynamo to complete the uninstall, then try and download {1} again. + +Uninstall the following packages: {1}? + \ No newline at end of file diff --git a/src/DynamoCoreWpf/Properties/Resources.resx b/src/DynamoCoreWpf/Properties/Resources.resx index aa9654c1942..1a55427a87b 100644 --- a/src/DynamoCoreWpf/Properties/Resources.resx +++ b/src/DynamoCoreWpf/Properties/Resources.resx @@ -2202,4 +2202,9 @@ Want to publish a different package? No new tab is added, as the extension is already present in the extensions side bar. + + {1} cannot be loaded. It has one or more node definitions that already exist in {0} that is currently loaded. To install {1}, Dynamo needs to first uninstall {0}. Restart Dynamo to complete the uninstall, then try and download {1} again. + +Uninstall the following packages: {1}? + \ No newline at end of file diff --git a/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs b/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs index 27bee1f46f0..e57aee9476c 100644 --- a/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs +++ b/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs @@ -263,8 +263,8 @@ public PackageManagerSearchViewModel(PackageManagerClientViewModel client) : thi { this.PackageManagerClientViewModel = client; PackageManagerClientViewModel.Downloads.CollectionChanged += DownloadsOnCollectionChanged; - PackageManagerClientViewModel.PackageManagerExtension.PackageLoader.CustomNodePackageWithDuplicateNodeIDLoaded += - CustomNodePackageWithDuplicateNodeIdLoaded; + PackageManagerClientViewModel.PackageManagerExtension.PackageLoader.ConflictingCustomNodePackageLoaded += + ConflictingCustomNodePackageLoaded; } /// @@ -641,12 +641,10 @@ public static string FormatPackageVersionList(IEnumerable x.Item1.name + " " + x.Item2.version)); } - private void CustomNodePackageWithDuplicateNodeIdLoaded(Package installed, string message) + private void ConflictingCustomNodePackageLoaded(Package installed, Package conflicting) { - //var productName = PackageManagerClientViewModel.DynamoViewModel.BrandingResourceProvider.ProductName; - //var message = string.Format(Resources.MessageUninstallCustomNodeToContinue, - // productName, JoinPackageNames(new List {installed}), - // duplicate.Name + " " + duplicate.VersionName); + var message = string.Format(Resources.MessageUninstallCustomNodeToContinue, + installed.Name + " " + installed.VersionName, conflicting.Name + " " + conflicting.VersionName); var dialogResult = MessageBox.Show(message, Resources.CannotDownloadPackageMessageBoxTitle, diff --git a/src/DynamoPackages/PackageLoader.cs b/src/DynamoPackages/PackageLoader.cs index d9debfcea83..4c400d46b6a 100644 --- a/src/DynamoPackages/PackageLoader.cs +++ b/src/DynamoPackages/PackageLoader.cs @@ -210,14 +210,9 @@ internal void TryLoadPackageIntoLibrary(Package package) catch (CustomNodePackageLoadException e) { Package originalPackage = - localPackages.FirstOrDefault(x => x.CustomNodeDirectory == e.Path); - OnDuplicatePackageLoaded(originalPackage, e.Reason); + localPackages.FirstOrDefault(x => x.CustomNodeDirectory == e.InstalledPath); + OnConflictingPackageLoaded(originalPackage, package); } - //catch (LibraryLoadFailedException e) - //{ - // Log(e.GetType() + ": " + e.Message); - // throw e; - //} catch (Exception e) { Log("Exception when attempting to load package " + package.Name + " from " + package.RootDirectory); @@ -225,11 +220,11 @@ internal void TryLoadPackageIntoLibrary(Package package) } } - public event Action CustomNodePackageWithDuplicateNodeIDLoaded; - protected virtual void OnDuplicatePackageLoaded(Package installed, string reason) + public event Action ConflictingCustomNodePackageLoaded; + private void OnConflictingPackageLoaded(Package installed, Package conflicting) { - var handler = CustomNodePackageWithDuplicateNodeIDLoaded; - handler?.Invoke(installed, reason); + var handler = ConflictingCustomNodePackageLoaded; + handler?.Invoke(installed, conflicting); } /// From e1b3a5caca8c347ce344823940ea5e2dec589808 Mon Sep 17 00:00:00 2001 From: aparajit-pratap Date: Thu, 27 Jun 2019 16:05:54 -0400 Subject: [PATCH 06/10] update wording of custom node package fail dialog --- src/DynamoCoreWpf/Properties/Resources.Designer.cs | 5 ++++- src/DynamoCoreWpf/Properties/Resources.en-US.resx | 5 ++++- src/DynamoCoreWpf/Properties/Resources.resx | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/DynamoCoreWpf/Properties/Resources.Designer.cs b/src/DynamoCoreWpf/Properties/Resources.Designer.cs index ce7c20b1921..7674829dc54 100644 --- a/src/DynamoCoreWpf/Properties/Resources.Designer.cs +++ b/src/DynamoCoreWpf/Properties/Resources.Designer.cs @@ -3305,7 +3305,10 @@ public static string MessageToUndeprecatePackage { } /// - /// Looks up a localized string similar to {1} cannot be loaded. It has one or more node definitions that already exist in {0} that is currently loaded. To install {1}, Dynamo needs to first uninstall {0}. Restart Dynamo to complete the uninstall, then try and download {1} again. + /// Looks up a localized string similar to {1} cannot be loaded. + ///Installing it will conflict with one or more node definitions that already exist in {0}, which is currently loaded. + ///To install {1}, Dynamo needs to first uninstall {0}. + ///Restart Dynamo to complete the uninstall, then try and download {1} again. /// ///Uninstall the following packages: {1}?. /// diff --git a/src/DynamoCoreWpf/Properties/Resources.en-US.resx b/src/DynamoCoreWpf/Properties/Resources.en-US.resx index af6b05364f4..960be07933e 100644 --- a/src/DynamoCoreWpf/Properties/Resources.en-US.resx +++ b/src/DynamoCoreWpf/Properties/Resources.en-US.resx @@ -2200,7 +2200,10 @@ Do you want to install the latest Dynamo update? No new tab is added, as the extension is already present in the extensions side bar. - {1} cannot be loaded. It has one or more node definitions that already exist in {0} that is currently loaded. To install {1}, Dynamo needs to first uninstall {0}. Restart Dynamo to complete the uninstall, then try and download {1} again. + {1} cannot be loaded. +Installing it will conflict with one or more node definitions that already exist in {0}, which is currently loaded. +To install {1}, Dynamo needs to first uninstall {0}. +Restart Dynamo to complete the uninstall, then try and download {1} again. Uninstall the following packages: {1}? diff --git a/src/DynamoCoreWpf/Properties/Resources.resx b/src/DynamoCoreWpf/Properties/Resources.resx index 1a55427a87b..04aaea8ff45 100644 --- a/src/DynamoCoreWpf/Properties/Resources.resx +++ b/src/DynamoCoreWpf/Properties/Resources.resx @@ -2203,7 +2203,10 @@ Want to publish a different package? No new tab is added, as the extension is already present in the extensions side bar. - {1} cannot be loaded. It has one or more node definitions that already exist in {0} that is currently loaded. To install {1}, Dynamo needs to first uninstall {0}. Restart Dynamo to complete the uninstall, then try and download {1} again. + {1} cannot be loaded. +Installing it will conflict with one or more node definitions that already exist in {0}, which is currently loaded. +To install {1}, Dynamo needs to first uninstall {0}. +Restart Dynamo to complete the uninstall, then try and download {1} again. Uninstall the following packages: {1}? From 81afbd7f6bf1a9bae079cb751dedda29a9bfcfdc Mon Sep 17 00:00:00 2001 From: aparajit-pratap Date: Fri, 28 Jun 2019 10:29:44 -0400 Subject: [PATCH 07/10] address review comments --- src/DynamoCore/Properties/Resources.Designer.cs | 5 ++++- src/DynamoCore/Properties/Resources.en-US.resx | 5 ++++- src/DynamoCore/Properties/Resources.resx | 5 ++++- src/DynamoCoreWpf/Properties/Resources.Designer.cs | 2 +- src/DynamoCoreWpf/Properties/Resources.en-US.resx | 2 +- src/DynamoCoreWpf/Properties/Resources.resx | 2 +- .../PackageManager/PackageManagerSearchViewModel.cs | 11 ++++++++++- .../PackageManager/PackageManagerSearchView.xaml.cs | 6 ++++-- src/DynamoPackages/PackageLoader.cs | 4 ++++ 9 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/DynamoCore/Properties/Resources.Designer.cs b/src/DynamoCore/Properties/Resources.Designer.cs index e319a4a6190..2d5588d8fcf 100644 --- a/src/DynamoCore/Properties/Resources.Designer.cs +++ b/src/DynamoCore/Properties/Resources.Designer.cs @@ -872,7 +872,10 @@ public static string MalformedHeaderPackage { } /// - /// Looks up a localized string similar to {1} cannot be loaded. It has one or more node definitions that already exist in {0} that is currently loaded. To install {1}, Dynamo needs to first uninstall {0}. Restart Dynamo to complete the uninstall, then try and download {1} again.. + /// Looks up a localized string similar to {1} cannot be loaded. + ///Installing it will conflict with one or more node definitions that already exist in {0}, which is currently loaded. + ///To install {1}, Dynamo needs to first uninstall {0}. + ///Restart Dynamo to complete the uninstall, then try and download {1} again.. /// public static string MessageCustomNodePackageFailedToLoad { get { diff --git a/src/DynamoCore/Properties/Resources.en-US.resx b/src/DynamoCore/Properties/Resources.en-US.resx index 08d85ffb693..c9aa5dcab21 100644 --- a/src/DynamoCore/Properties/Resources.en-US.resx +++ b/src/DynamoCore/Properties/Resources.en-US.resx @@ -701,6 +701,9 @@ The input name should be a valid variable name, without spaces. An input type an Python template loaded from DynamoSettings.xml path - {1} cannot be loaded. It has one or more node definitions that already exist in {0} that is currently loaded. To install {1}, Dynamo needs to first uninstall {0}. Restart Dynamo to complete the uninstall, then try and download {1} again. + {1} cannot be loaded. +Installing it will conflict with one or more node definitions that already exist in {0}, which is currently loaded. +To install {1}, Dynamo needs to first uninstall {0}. +Restart Dynamo to complete the uninstall, then try and download {1} again. \ No newline at end of file diff --git a/src/DynamoCore/Properties/Resources.resx b/src/DynamoCore/Properties/Resources.resx index 757c1d1ce67..7aaac80ac40 100644 --- a/src/DynamoCore/Properties/Resources.resx +++ b/src/DynamoCore/Properties/Resources.resx @@ -701,6 +701,9 @@ The input name should be a valid variable name, without spaces. An input type an Python template set by host integrator - {1} cannot be loaded. It has one or more node definitions that already exist in {0} that is currently loaded. To install {1}, Dynamo needs to first uninstall {0}. Restart Dynamo to complete the uninstall, then try and download {1} again. + {1} cannot be loaded. +Installing it will conflict with one or more node definitions that already exist in {0}, which is currently loaded. +To install {1}, Dynamo needs to first uninstall {0}. +Restart Dynamo to complete the uninstall, then try and download {1} again. \ No newline at end of file diff --git a/src/DynamoCoreWpf/Properties/Resources.Designer.cs b/src/DynamoCoreWpf/Properties/Resources.Designer.cs index 7674829dc54..65300fecfc3 100644 --- a/src/DynamoCoreWpf/Properties/Resources.Designer.cs +++ b/src/DynamoCoreWpf/Properties/Resources.Designer.cs @@ -3310,7 +3310,7 @@ public static string MessageToUndeprecatePackage { ///To install {1}, Dynamo needs to first uninstall {0}. ///Restart Dynamo to complete the uninstall, then try and download {1} again. /// - ///Uninstall the following packages: {1}?. + ///Uninstall the following packages: {0}?. /// public static string MessageUninstallCustomNodeToContinue { get { diff --git a/src/DynamoCoreWpf/Properties/Resources.en-US.resx b/src/DynamoCoreWpf/Properties/Resources.en-US.resx index 960be07933e..adac53cf9d1 100644 --- a/src/DynamoCoreWpf/Properties/Resources.en-US.resx +++ b/src/DynamoCoreWpf/Properties/Resources.en-US.resx @@ -2205,6 +2205,6 @@ Installing it will conflict with one or more node definitions that already exist To install {1}, Dynamo needs to first uninstall {0}. Restart Dynamo to complete the uninstall, then try and download {1} again. -Uninstall the following packages: {1}? +Uninstall the following packages: {0}? \ No newline at end of file diff --git a/src/DynamoCoreWpf/Properties/Resources.resx b/src/DynamoCoreWpf/Properties/Resources.resx index 04aaea8ff45..fa9e4ff8151 100644 --- a/src/DynamoCoreWpf/Properties/Resources.resx +++ b/src/DynamoCoreWpf/Properties/Resources.resx @@ -2208,6 +2208,6 @@ Installing it will conflict with one or more node definitions that already exist To install {1}, Dynamo needs to first uninstall {0}. Restart Dynamo to complete the uninstall, then try and download {1} again. -Uninstall the following packages: {1}? +Uninstall the following packages: {0}? \ No newline at end of file diff --git a/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs b/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs index e57aee9476c..fee6bbae50c 100644 --- a/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs +++ b/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs @@ -743,8 +743,17 @@ public void SelectPrevious() SelectedIndex = SelectedIndex - 1; } + internal void UnregisterHandlers() + { + RequestShowFileDialog -= OnRequestShowFileDialog; + SearchResults.CollectionChanged -= SearchResultsOnCollectionChanged; + PackageManagerClientViewModel.Downloads.CollectionChanged -= DownloadsOnCollectionChanged; + PackageManagerClientViewModel.PackageManagerExtension.PackageLoader.ConflictingCustomNodePackageLoaded -= + ConflictingCustomNodePackageLoaded; + } + /// - /// Performs a search using the internal SearcText as the query and + /// Performs a search using the internal SearchText as the query and /// updates the observable SearchResults property. /// internal void SearchAndUpdateResults() diff --git a/src/DynamoCoreWpf/Views/PackageManager/PackageManagerSearchView.xaml.cs b/src/DynamoCoreWpf/Views/PackageManager/PackageManagerSearchView.xaml.cs index ee7fab803c1..ae261951f1d 100644 --- a/src/DynamoCoreWpf/Views/PackageManager/PackageManagerSearchView.xaml.cs +++ b/src/DynamoCoreWpf/Views/PackageManager/PackageManagerSearchView.xaml.cs @@ -25,8 +25,10 @@ public PackageManagerSearchView(PackageManagerSearchViewModel pm) protected override void OnClosing(System.ComponentModel.CancelEventArgs e) { - (this.DataContext as PackageManagerSearchViewModel).RequestShowFileDialog -= OnRequestShowFileDialog; - this.Owner.Focus(); + var viewModel = DataContext as PackageManagerSearchViewModel; + viewModel.UnregisterHandlers(); + + Owner.Focus(); base.OnClosing(e); } diff --git a/src/DynamoPackages/PackageLoader.cs b/src/DynamoPackages/PackageLoader.cs index 4c400d46b6a..04d0646ab23 100644 --- a/src/DynamoPackages/PackageLoader.cs +++ b/src/DynamoPackages/PackageLoader.cs @@ -220,6 +220,10 @@ internal void TryLoadPackageIntoLibrary(Package package) } } + /// + /// Event raised when a custom node package containing conflicting node definition + /// with an existing package is tried to load. + /// public event Action ConflictingCustomNodePackageLoaded; private void OnConflictingPackageLoaded(Package installed, Package conflicting) { From f9d14d535c403857fb1eff391778daa7e2567f1d Mon Sep 17 00:00:00 2001 From: aparajit-pratap Date: Sun, 30 Jun 2019 23:44:57 -0400 Subject: [PATCH 08/10] add test custom node packages with test --- .../PackageManagerTests/PackageLoaderTests.cs | 37 +- test/pkgs/EvenOdd/dyf/EvenOdd.dyf | 397 ++++++++++++++++++ test/pkgs/EvenOdd/pkg.json | 1 + test/pkgs/EvenOdd2/dyf/EvenOdd.dyf | 397 ++++++++++++++++++ test/pkgs/EvenOdd2/pkg.json | 1 + 5 files changed, 829 insertions(+), 4 deletions(-) create mode 100644 test/pkgs/EvenOdd/dyf/EvenOdd.dyf create mode 100644 test/pkgs/EvenOdd/pkg.json create mode 100644 test/pkgs/EvenOdd2/dyf/EvenOdd.dyf create mode 100644 test/pkgs/EvenOdd2/pkg.json diff --git a/test/Libraries/PackageManagerTests/PackageLoaderTests.cs b/test/Libraries/PackageManagerTests/PackageLoaderTests.cs index 9a9af8feb62..77c1d544939 100644 --- a/test/Libraries/PackageManagerTests/PackageLoaderTests.cs +++ b/test/Libraries/PackageManagerTests/PackageLoaderTests.cs @@ -2,6 +2,7 @@ using System.IO; using System.Linq; using Dynamo.Extensions; +using Dynamo.Search.SearchElements; using Moq; using NUnit.Framework; @@ -129,8 +130,8 @@ public void LoadPackagesReturnsAllValidPackagesInValidDirectory() PathManager = CurrentDynamoModel.PathManager }); - // There are 11 packages in "GitHub\Dynamo\test\pkgs" - Assert.AreEqual(11, loader.LocalPackages.Count()); + // There are 13 packages in "GitHub\Dynamo\test\pkgs" + Assert.AreEqual(13, loader.LocalPackages.Count()); // Verify that interdependent packages are resolved successfully var libs = CurrentDynamoModel.LibraryServices.ImportedLibraries.ToList(); @@ -160,8 +161,8 @@ public void LoadingPackageDoesNotAffectLoadedSearchEntries() PathManager = CurrentDynamoModel.PathManager }); - // There are 11 packages in "GitHub\Dynamo\test\pkgs" - Assert.AreEqual(11, loader.LocalPackages.Count()); + // There are 13 packages in "GitHub\Dynamo\test\pkgs" + Assert.AreEqual(13, loader.LocalPackages.Count()); // Simulate loading new package from PM string packageDirectory = Path.Combine(TestDirectory, @"core\packageDependencyTests\ZTTestPackage"); @@ -177,6 +178,34 @@ public void LoadingPackageDoesNotAffectLoadedSearchEntries() Assert.IsTrue(entries.Count(x => x.FullName == "AnotherPackage.AnotherPackage.AnotherPackage.HelloAnotherWorld") == 1); } + [Test] + public void LoadingConflictingCustomNodePackageDoesNotGetLoaded() + { + var loader = new PackageLoader(PackagesDirectory); + var libraryLoader = new ExtensionLibraryLoader(CurrentDynamoModel); + + loader.PackagesLoaded += libraryLoader.LoadPackages; + loader.RequestLoadNodeLibrary += libraryLoader.LoadNodeLibrary; + loader.RequestLoadCustomNodeDirectory += + (dir) => CurrentDynamoModel.CustomNodeManager.AddUninitializedCustomNodesInPath(dir, true); + + loader.LoadAll(new LoadPackageParams + { + Preferences = CurrentDynamoModel.PreferenceSettings, + PathManager = CurrentDynamoModel.PathManager + }); + + // There are 13 packages in "GitHub\Dynamo\test\pkgs" + Assert.AreEqual(13, loader.LocalPackages.Count()); + + var entries = CurrentDynamoModel.SearchModel.SearchEntries.OfType(); + + // Check that conflicting custom node package "EvenOdd2" is not installed + Assert.IsTrue(entries.Count(x => Path.GetDirectoryName(x.Path).EndsWith(@"EvenOdd2\dyf")) == 0); + Assert.IsTrue(entries.Count(x => Path.GetDirectoryName(x.Path).EndsWith(@"EvenOdd\dyf") && + x.FullName == "Test.EvenOdd") == 1); + } + [Test] public void LoadPackagesReturnsNoPackagesForInvalidDirectory() { diff --git a/test/pkgs/EvenOdd/dyf/EvenOdd.dyf b/test/pkgs/EvenOdd/dyf/EvenOdd.dyf new file mode 100644 index 00000000000..d2ea6b57082 --- /dev/null +++ b/test/pkgs/EvenOdd/dyf/EvenOdd.dyf @@ -0,0 +1,397 @@ +{ + "Uuid": "3f19c484-d3f3-49ba-88c2-6c386a41f6ac", + "IsCustomNode": true, + "Category": "Test", + "Description": "Tells if a number in a range is even or odd", + "Name": "EvenOdd", + "ElementResolver": { + "ResolutionMap": {} + }, + "Inputs": [], + "Outputs": [], + "Nodes": [ + { + "ConcreteType": "CoreNodeModels.Range, CoreNodeModels", + "NodeType": "ExtensionNode", + "Id": "41fdfda5044b44f0b364e1a31d10bcb3", + "Inputs": [ + { + "Id": "39c5ca40b4ff41a1bb4379032f7dff27", + "Name": "start", + "Description": "Number or letter to start the sequence at\r\nDefault value: 0", + "UsingDefaultValue": true, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + }, + { + "Id": "c70ffc1d585447acb96b26313ba350af", + "Name": "end", + "Description": "Number or letter to end the sequence at\r\nDefault value: 9", + "UsingDefaultValue": true, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + }, + { + "Id": "31390c529e1440dba846361af4a77905", + "Name": "step", + "Description": "Space between numbers or letters\r\nDefault value: 1", + "UsingDefaultValue": true, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "889f5e5e5a6a453aba1818f22d485fb5", + "Name": "seq", + "Description": "New sequence", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Auto", + "Description": "Creates a sequence of numbers or letters in the specified range." + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.CodeBlockNodeModel, DynamoCore", + "NodeType": "CodeBlockNode", + "Code": "2;", + "Id": "1713fa72580348369985b6d3ff43f6b6", + "Inputs": [], + "Outputs": [ + { + "Id": "19fe83cf33d84d10bbcc70a75b535d7f", + "Name": "", + "Description": "Value of expression at line 1", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Allows for DesignScript code to be authored directly" + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.ZeroTouch.DSFunction, DynamoCore", + "NodeType": "FunctionNode", + "FunctionSignature": "%@var[]..[],var[]..[]", + "Id": "1ddf4b4cc39f42acadd578db42bcb6d3", + "Inputs": [ + { + "Id": "52c34d69fe42408ca5c857f371168587", + "Name": "x", + "Description": "x value.\n\nvar[]..[]", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + }, + { + "Id": "02afc74a897f47b4a939f9adde53d613", + "Name": "y", + "Description": "y value.\n\nvar[]..[]", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "b92ceaf7eae649c280a7e8e3206631ee", + "Name": "var[]..[]", + "Description": "var[]..[]", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Auto", + "Description": "Finds the remainder of x/y\n\n% (x: var[]..[], y: var[]..[]): var[]..[]" + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.CodeBlockNodeModel, DynamoCore", + "NodeType": "CodeBlockNode", + "Code": "x == 0 ? \"even\" : \"odd\";", + "Id": "7151fed9e4db49ada604b0d42eb7f7f2", + "Inputs": [ + { + "Id": "412b1849c1f142aaa72ad8f81d8166ba", + "Name": "x", + "Description": "x", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "87b4d22fb0aa4fe28c96a6217ecd874c", + "Name": "", + "Description": "Value of expression at line 1", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Allows for DesignScript code to be authored directly" + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.CustomNodes.Symbol, DynamoCore", + "NodeType": "InputNode", + "Parameter": { + "Name": "start", + "TypeName": "var", + "TypeRank": -1, + "DefaultValue": null, + "Description": "" + }, + "Id": "d1285386263b495388a76953bfc82357", + "Inputs": [], + "Outputs": [ + { + "Id": "3bd721697c394adf9b6550f16674e34f", + "Name": "", + "Description": "Symbol", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "A function parameter, use with custom nodes.\r\n\r\nYou can specify the type and default value for parameter. E.g.,\r\n\r\ninput : var[]..[]\r\nvalue : bool = false" + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.CustomNodes.Symbol, DynamoCore", + "NodeType": "InputNode", + "Parameter": { + "Name": "end", + "TypeName": "var", + "TypeRank": -1, + "DefaultValue": null, + "Description": "" + }, + "Id": "6bbad8b9abae4e029957792104a3f50e", + "Inputs": [], + "Outputs": [ + { + "Id": "3a5786784fcb4732a91e16eb237da7d4", + "Name": "", + "Description": "Symbol", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "A function parameter, use with custom nodes.\r\n\r\nYou can specify the type and default value for parameter. E.g.,\r\n\r\ninput : var[]..[]\r\nvalue : bool = false" + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.CustomNodes.Symbol, DynamoCore", + "NodeType": "InputNode", + "Parameter": { + "Name": "step", + "TypeName": "var", + "TypeRank": -1, + "DefaultValue": null, + "Description": "" + }, + "Id": "a8b1297e19224a30ba48e2bfca132423", + "Inputs": [], + "Outputs": [ + { + "Id": "08dbbcb643984628a3b6779d3aa03f5f", + "Name": "", + "Description": "Symbol", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "A function parameter, use with custom nodes.\r\n\r\nYou can specify the type and default value for parameter. E.g.,\r\n\r\ninput : var[]..[]\r\nvalue : bool = false" + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.CustomNodes.Output, DynamoCore", + "NodeType": "OutputNode", + "ElementResolver": null, + "Symbol": "", + "Id": "2bcbfb454357477181db694346874e71", + "Inputs": [ + { + "Id": "40390ef2e99a4a23992a7df06b8be2bf", + "Name": "", + "Description": "", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [], + "Replication": "Disabled", + "Description": "A function output, use with custom nodes" + } + ], + "Connectors": [ + { + "Start": "889f5e5e5a6a453aba1818f22d485fb5", + "End": "52c34d69fe42408ca5c857f371168587", + "Id": "6576704eb36f4ed0b8f00fd6f2734dac" + }, + { + "Start": "19fe83cf33d84d10bbcc70a75b535d7f", + "End": "02afc74a897f47b4a939f9adde53d613", + "Id": "6b3cecd3c41249e6baa4c6ecb53c696b" + }, + { + "Start": "b92ceaf7eae649c280a7e8e3206631ee", + "End": "412b1849c1f142aaa72ad8f81d8166ba", + "Id": "f3de091f0a464646b785d132fbdb2cb4" + }, + { + "Start": "87b4d22fb0aa4fe28c96a6217ecd874c", + "End": "40390ef2e99a4a23992a7df06b8be2bf", + "Id": "46ac5c27131b426cb949b3c6c41e3a93" + }, + { + "Start": "3bd721697c394adf9b6550f16674e34f", + "End": "39c5ca40b4ff41a1bb4379032f7dff27", + "Id": "fe5b410acf474dfb8daf509305c0bd72" + }, + { + "Start": "3a5786784fcb4732a91e16eb237da7d4", + "End": "c70ffc1d585447acb96b26313ba350af", + "Id": "874e6d04ff5e4308a9bcccd33a3206ea" + }, + { + "Start": "08dbbcb643984628a3b6779d3aa03f5f", + "End": "31390c529e1440dba846361af4a77905", + "Id": "c74a545ec25d4aea95e9aabc2b51c79b" + } + ], + "Dependencies": [], + "PackageDependencies": [], + "Bindings": [], + "View": { + "Dynamo": { + "ScaleFactor": 1.0, + "HasRunWithoutCrash": false, + "IsVisibleInDynamoLibrary": true, + "Version": "2.3.0.5425", + "RunType": "Manual", + "RunPeriod": "1000" + }, + "Camera": { + "Name": "Background Preview", + "EyeX": -17.0, + "EyeY": 24.0, + "EyeZ": 50.0, + "LookX": 12.0, + "LookY": -13.0, + "LookZ": -58.0, + "UpX": 0.0, + "UpY": 1.0, + "UpZ": 0.0 + }, + "NodeViews": [ + { + "ShowGeometry": true, + "Name": "Range", + "Id": "41fdfda5044b44f0b364e1a31d10bcb3", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "X": 250.0, + "Y": 0.0 + }, + { + "ShowGeometry": true, + "Name": "Code Block", + "Id": "1713fa72580348369985b6d3ff43f6b6", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "X": 492.12166172106822, + "Y": 126.10385756676556 + }, + { + "ShowGeometry": true, + "Name": "%", + "Id": "1ddf4b4cc39f42acadd578db42bcb6d3", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "X": 648.22551928783378, + "Y": 21.169139465875332 + }, + { + "ShowGeometry": true, + "Name": "Code Block", + "Id": "7151fed9e4db49ada604b0d42eb7f7f2", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "X": 874.0, + "Y": 69.0 + }, + { + "ShowGeometry": true, + "Name": "Input", + "Id": "d1285386263b495388a76953bfc82357", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "X": 0.0, + "Y": 0.0 + }, + { + "ShowGeometry": true, + "Name": "Input", + "Id": "6bbad8b9abae4e029957792104a3f50e", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "X": 0.0, + "Y": 150.0 + }, + { + "ShowGeometry": true, + "Name": "Input", + "Id": "a8b1297e19224a30ba48e2bfca132423", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "X": 0.0, + "Y": 300.0 + }, + { + "ShowGeometry": true, + "Name": "Output", + "Id": "2bcbfb454357477181db694346874e71", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "X": 1205.4955489614242, + "Y": 84.272997032640973 + } + ], + "Annotations": [], + "X": 58.237500000000011, + "Y": 100.88749999999999, + "Zoom": 0.8425 + } +} \ No newline at end of file diff --git a/test/pkgs/EvenOdd/pkg.json b/test/pkgs/EvenOdd/pkg.json new file mode 100644 index 00000000000..392194be880 --- /dev/null +++ b/test/pkgs/EvenOdd/pkg.json @@ -0,0 +1 @@ +{"license":"","file_hash":null,"name":"EvenOdd","version":"1.0.0","description":"Tells if a number in a range is even or odd","group":"","keywords":null,"dependencies":[],"contents":"EvenOdd - Tells if a number in a range is even or odd","engine_version":"2.1.0.7840","engine":"dynamo","engine_metadata":"","site_url":"","repository_url":"","contains_binaries":false,"node_libraries":[]} \ No newline at end of file diff --git a/test/pkgs/EvenOdd2/dyf/EvenOdd.dyf b/test/pkgs/EvenOdd2/dyf/EvenOdd.dyf new file mode 100644 index 00000000000..d2ea6b57082 --- /dev/null +++ b/test/pkgs/EvenOdd2/dyf/EvenOdd.dyf @@ -0,0 +1,397 @@ +{ + "Uuid": "3f19c484-d3f3-49ba-88c2-6c386a41f6ac", + "IsCustomNode": true, + "Category": "Test", + "Description": "Tells if a number in a range is even or odd", + "Name": "EvenOdd", + "ElementResolver": { + "ResolutionMap": {} + }, + "Inputs": [], + "Outputs": [], + "Nodes": [ + { + "ConcreteType": "CoreNodeModels.Range, CoreNodeModels", + "NodeType": "ExtensionNode", + "Id": "41fdfda5044b44f0b364e1a31d10bcb3", + "Inputs": [ + { + "Id": "39c5ca40b4ff41a1bb4379032f7dff27", + "Name": "start", + "Description": "Number or letter to start the sequence at\r\nDefault value: 0", + "UsingDefaultValue": true, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + }, + { + "Id": "c70ffc1d585447acb96b26313ba350af", + "Name": "end", + "Description": "Number or letter to end the sequence at\r\nDefault value: 9", + "UsingDefaultValue": true, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + }, + { + "Id": "31390c529e1440dba846361af4a77905", + "Name": "step", + "Description": "Space between numbers or letters\r\nDefault value: 1", + "UsingDefaultValue": true, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "889f5e5e5a6a453aba1818f22d485fb5", + "Name": "seq", + "Description": "New sequence", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Auto", + "Description": "Creates a sequence of numbers or letters in the specified range." + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.CodeBlockNodeModel, DynamoCore", + "NodeType": "CodeBlockNode", + "Code": "2;", + "Id": "1713fa72580348369985b6d3ff43f6b6", + "Inputs": [], + "Outputs": [ + { + "Id": "19fe83cf33d84d10bbcc70a75b535d7f", + "Name": "", + "Description": "Value of expression at line 1", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Allows for DesignScript code to be authored directly" + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.ZeroTouch.DSFunction, DynamoCore", + "NodeType": "FunctionNode", + "FunctionSignature": "%@var[]..[],var[]..[]", + "Id": "1ddf4b4cc39f42acadd578db42bcb6d3", + "Inputs": [ + { + "Id": "52c34d69fe42408ca5c857f371168587", + "Name": "x", + "Description": "x value.\n\nvar[]..[]", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + }, + { + "Id": "02afc74a897f47b4a939f9adde53d613", + "Name": "y", + "Description": "y value.\n\nvar[]..[]", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "b92ceaf7eae649c280a7e8e3206631ee", + "Name": "var[]..[]", + "Description": "var[]..[]", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Auto", + "Description": "Finds the remainder of x/y\n\n% (x: var[]..[], y: var[]..[]): var[]..[]" + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.CodeBlockNodeModel, DynamoCore", + "NodeType": "CodeBlockNode", + "Code": "x == 0 ? \"even\" : \"odd\";", + "Id": "7151fed9e4db49ada604b0d42eb7f7f2", + "Inputs": [ + { + "Id": "412b1849c1f142aaa72ad8f81d8166ba", + "Name": "x", + "Description": "x", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "87b4d22fb0aa4fe28c96a6217ecd874c", + "Name": "", + "Description": "Value of expression at line 1", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Allows for DesignScript code to be authored directly" + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.CustomNodes.Symbol, DynamoCore", + "NodeType": "InputNode", + "Parameter": { + "Name": "start", + "TypeName": "var", + "TypeRank": -1, + "DefaultValue": null, + "Description": "" + }, + "Id": "d1285386263b495388a76953bfc82357", + "Inputs": [], + "Outputs": [ + { + "Id": "3bd721697c394adf9b6550f16674e34f", + "Name": "", + "Description": "Symbol", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "A function parameter, use with custom nodes.\r\n\r\nYou can specify the type and default value for parameter. E.g.,\r\n\r\ninput : var[]..[]\r\nvalue : bool = false" + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.CustomNodes.Symbol, DynamoCore", + "NodeType": "InputNode", + "Parameter": { + "Name": "end", + "TypeName": "var", + "TypeRank": -1, + "DefaultValue": null, + "Description": "" + }, + "Id": "6bbad8b9abae4e029957792104a3f50e", + "Inputs": [], + "Outputs": [ + { + "Id": "3a5786784fcb4732a91e16eb237da7d4", + "Name": "", + "Description": "Symbol", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "A function parameter, use with custom nodes.\r\n\r\nYou can specify the type and default value for parameter. E.g.,\r\n\r\ninput : var[]..[]\r\nvalue : bool = false" + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.CustomNodes.Symbol, DynamoCore", + "NodeType": "InputNode", + "Parameter": { + "Name": "step", + "TypeName": "var", + "TypeRank": -1, + "DefaultValue": null, + "Description": "" + }, + "Id": "a8b1297e19224a30ba48e2bfca132423", + "Inputs": [], + "Outputs": [ + { + "Id": "08dbbcb643984628a3b6779d3aa03f5f", + "Name": "", + "Description": "Symbol", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "A function parameter, use with custom nodes.\r\n\r\nYou can specify the type and default value for parameter. E.g.,\r\n\r\ninput : var[]..[]\r\nvalue : bool = false" + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.CustomNodes.Output, DynamoCore", + "NodeType": "OutputNode", + "ElementResolver": null, + "Symbol": "", + "Id": "2bcbfb454357477181db694346874e71", + "Inputs": [ + { + "Id": "40390ef2e99a4a23992a7df06b8be2bf", + "Name": "", + "Description": "", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [], + "Replication": "Disabled", + "Description": "A function output, use with custom nodes" + } + ], + "Connectors": [ + { + "Start": "889f5e5e5a6a453aba1818f22d485fb5", + "End": "52c34d69fe42408ca5c857f371168587", + "Id": "6576704eb36f4ed0b8f00fd6f2734dac" + }, + { + "Start": "19fe83cf33d84d10bbcc70a75b535d7f", + "End": "02afc74a897f47b4a939f9adde53d613", + "Id": "6b3cecd3c41249e6baa4c6ecb53c696b" + }, + { + "Start": "b92ceaf7eae649c280a7e8e3206631ee", + "End": "412b1849c1f142aaa72ad8f81d8166ba", + "Id": "f3de091f0a464646b785d132fbdb2cb4" + }, + { + "Start": "87b4d22fb0aa4fe28c96a6217ecd874c", + "End": "40390ef2e99a4a23992a7df06b8be2bf", + "Id": "46ac5c27131b426cb949b3c6c41e3a93" + }, + { + "Start": "3bd721697c394adf9b6550f16674e34f", + "End": "39c5ca40b4ff41a1bb4379032f7dff27", + "Id": "fe5b410acf474dfb8daf509305c0bd72" + }, + { + "Start": "3a5786784fcb4732a91e16eb237da7d4", + "End": "c70ffc1d585447acb96b26313ba350af", + "Id": "874e6d04ff5e4308a9bcccd33a3206ea" + }, + { + "Start": "08dbbcb643984628a3b6779d3aa03f5f", + "End": "31390c529e1440dba846361af4a77905", + "Id": "c74a545ec25d4aea95e9aabc2b51c79b" + } + ], + "Dependencies": [], + "PackageDependencies": [], + "Bindings": [], + "View": { + "Dynamo": { + "ScaleFactor": 1.0, + "HasRunWithoutCrash": false, + "IsVisibleInDynamoLibrary": true, + "Version": "2.3.0.5425", + "RunType": "Manual", + "RunPeriod": "1000" + }, + "Camera": { + "Name": "Background Preview", + "EyeX": -17.0, + "EyeY": 24.0, + "EyeZ": 50.0, + "LookX": 12.0, + "LookY": -13.0, + "LookZ": -58.0, + "UpX": 0.0, + "UpY": 1.0, + "UpZ": 0.0 + }, + "NodeViews": [ + { + "ShowGeometry": true, + "Name": "Range", + "Id": "41fdfda5044b44f0b364e1a31d10bcb3", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "X": 250.0, + "Y": 0.0 + }, + { + "ShowGeometry": true, + "Name": "Code Block", + "Id": "1713fa72580348369985b6d3ff43f6b6", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "X": 492.12166172106822, + "Y": 126.10385756676556 + }, + { + "ShowGeometry": true, + "Name": "%", + "Id": "1ddf4b4cc39f42acadd578db42bcb6d3", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "X": 648.22551928783378, + "Y": 21.169139465875332 + }, + { + "ShowGeometry": true, + "Name": "Code Block", + "Id": "7151fed9e4db49ada604b0d42eb7f7f2", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "X": 874.0, + "Y": 69.0 + }, + { + "ShowGeometry": true, + "Name": "Input", + "Id": "d1285386263b495388a76953bfc82357", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "X": 0.0, + "Y": 0.0 + }, + { + "ShowGeometry": true, + "Name": "Input", + "Id": "6bbad8b9abae4e029957792104a3f50e", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "X": 0.0, + "Y": 150.0 + }, + { + "ShowGeometry": true, + "Name": "Input", + "Id": "a8b1297e19224a30ba48e2bfca132423", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "X": 0.0, + "Y": 300.0 + }, + { + "ShowGeometry": true, + "Name": "Output", + "Id": "2bcbfb454357477181db694346874e71", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "X": 1205.4955489614242, + "Y": 84.272997032640973 + } + ], + "Annotations": [], + "X": 58.237500000000011, + "Y": 100.88749999999999, + "Zoom": 0.8425 + } +} \ No newline at end of file diff --git a/test/pkgs/EvenOdd2/pkg.json b/test/pkgs/EvenOdd2/pkg.json new file mode 100644 index 00000000000..3829f8ddad3 --- /dev/null +++ b/test/pkgs/EvenOdd2/pkg.json @@ -0,0 +1 @@ +{"license":"","file_hash":null,"name":"EvenOdd2","version":"1.0.0","description":"Tells if number in range is even or odd","group":"","keywords":null,"dependencies":[],"contents":"EvenOdd - Tells if a number in a range is even or odd","engine_version":"2.1.0.7840","engine":"dynamo","engine_metadata":"","site_url":"","repository_url":"","contains_binaries":false,"node_libraries":[]} \ No newline at end of file From 344175e1c447f7f57ab88dd3c62011a7ae264128 Mon Sep 17 00:00:00 2001 From: aparajit-pratap Date: Mon, 1 Jul 2019 23:39:42 -0400 Subject: [PATCH 09/10] fix failing tests --- src/DynamoCore/Core/CustomNodeManager.cs | 34 +++++++++---------- test/DynamoCoreTests/CustomNodes.cs | 2 +- test/DynamoCoreWpfTests/SerializationTests.cs | 15 ++++---- test/DynamoCoreWpfTests/WorkspaceSaving.cs | 22 ++++++------ 4 files changed, 37 insertions(+), 36 deletions(-) diff --git a/src/DynamoCore/Core/CustomNodeManager.cs b/src/DynamoCore/Core/CustomNodeManager.cs index 727c969052c..6b12e64606b 100644 --- a/src/DynamoCore/Core/CustomNodeManager.cs +++ b/src/DynamoCore/Core/CustomNodeManager.cs @@ -342,7 +342,7 @@ public bool AddUninitializedCustomNode(string file, bool isTestMode, out CustomN { if (TryGetInfoFromPath(file, isTestMode, out info)) { - SetNodeInfo(info); + SetNodeInfo(info, isTestMode); return true; } return false; @@ -398,7 +398,7 @@ public IEnumerable AddUninitializedCustomNodesInPath(string path { info.IsPackageMember = isPackageMember; - SetNodeInfo(info); + SetNodeInfo(info, isTestMode); result.Add(info); } return result; @@ -443,7 +443,7 @@ private IEnumerable ScanNodeHeadersInDirectory(string dir, bool /// Stores the path and function definition without initializing a node. Overwrites /// the existing NodeInfo if necessary /// - private void SetNodeInfo(CustomNodeInfo newInfo) + private void SetNodeInfo(CustomNodeInfo newInfo, bool isTestMode) { var guids = NodeInfos.Where(x => { @@ -457,7 +457,7 @@ private void SetNodeInfo(CustomNodeInfo newInfo) } CustomNodeInfo info; - if (NodeInfos.TryGetValue(newInfo.FunctionId, out info)) + if (!isTestMode && NodeInfos.TryGetValue(newInfo.FunctionId, out info)) { var newInfoPath = Path.GetDirectoryName(newInfo.Path); var infoPath = Path.GetDirectoryName(info.Path); @@ -663,7 +663,7 @@ public bool OpenCustomNodeWorkspace( if (InitializeCustomNode( workspaceInfo, xmlDoc, - out customNodeWorkspace)) + out customNodeWorkspace, isTestMode)) { workspace = customNodeWorkspace; return true; @@ -675,7 +675,7 @@ public bool OpenCustomNodeWorkspace( private bool InitializeCustomNode( WorkspaceInfo workspaceInfo, XmlDocument xmlDoc, - out CustomNodeWorkspaceModel workspace) + out CustomNodeWorkspaceModel workspace, bool isTestMode) { // Add custom node definition firstly so that a recursive // custom node won't recursively load itself. @@ -709,21 +709,21 @@ private bool InitializeCustomNode( } } - RegisterCustomNodeWorkspace(newWorkspace); + RegisterCustomNodeWorkspace(newWorkspace, isTestMode); workspace = newWorkspace; return true; } - private void RegisterCustomNodeWorkspace(CustomNodeWorkspaceModel newWorkspace) + private void RegisterCustomNodeWorkspace(CustomNodeWorkspaceModel newWorkspace, bool isTestMode = false) { RegisterCustomNodeWorkspace( newWorkspace, newWorkspace.CustomNodeInfo, - newWorkspace.CustomNodeDefinition); + newWorkspace.CustomNodeDefinition, isTestMode); } private void RegisterCustomNodeWorkspace( - CustomNodeWorkspaceModel newWorkspace, CustomNodeInfo info, CustomNodeDefinition definition) + CustomNodeWorkspaceModel newWorkspace, CustomNodeInfo info, CustomNodeDefinition definition, bool isTestMode) { loadedWorkspaceModels[newWorkspace.CustomNodeId] = newWorkspace; SetFunctionDefinition(definition); @@ -735,12 +735,12 @@ private void RegisterCustomNodeWorkspace( OnDefinitionUpdated(newDef); }; - SetNodeInfo(info); + SetNodeInfo(info, isTestMode); newWorkspace.InfoChanged += () => { var newInfo = newWorkspace.CustomNodeInfo; - SetNodeInfo(newInfo); + SetNodeInfo(newInfo, isTestMode); OnInfoUpdated(newInfo); }; @@ -782,7 +782,7 @@ private bool InitializeCustomNode( info.ID = functionId.ToString(); if (migrationManager.ProcessWorkspace(info, xmlDoc, isTestMode, nodeFactory)) { - return InitializeCustomNode(info, xmlDoc, out workspace); + return InitializeCustomNode(info, xmlDoc, out workspace, isTestMode); } } } @@ -791,7 +791,7 @@ private bool InitializeCustomNode( // TODO: Skip Json migration for now WorkspaceInfo.FromJsonDocument(strInput, path, isTestMode, false, AsLogger(), out info); info.ID = functionId.ToString(); - return InitializeCustomNode(info, null, out workspace); + return InitializeCustomNode(info, null, out workspace, isTestMode); } else throw ex; Log(string.Format(Properties.Resources.CustomNodeCouldNotBeInitialized, customNodeInfo.Name)); @@ -821,7 +821,7 @@ private bool InitializeCustomNode( /// Optional identifier to be used for the custom node. By default, will make a new unique one. /// /// Newly created Custom Node Workspace. - internal WorkspaceModel CreateCustomNode(string name, string category, string description, Guid? functionId = null) + internal WorkspaceModel CreateCustomNode(string name, string category, string description, Guid? functionId = null, bool isTestMode = false) { var newId = functionId ?? Guid.NewGuid(); @@ -838,7 +838,7 @@ internal WorkspaceModel CreateCustomNode(string name, string category, string de }; var workspace = new CustomNodeWorkspaceModel(info, nodeFactory); - RegisterCustomNodeWorkspace(workspace); + RegisterCustomNodeWorkspace(workspace, isTestMode); return workspace; } @@ -1264,7 +1264,7 @@ from output in outputs newWorkspace.HasUnsavedChanges = true; - RegisterCustomNodeWorkspace(newWorkspace); + RegisterCustomNodeWorkspace(newWorkspace, isTestMode); Debug.WriteLine("Collapsed workspace has {0} nodes and {1} connectors", newWorkspace.Nodes.Count(), newWorkspace.Connectors.Count()); diff --git a/test/DynamoCoreTests/CustomNodes.cs b/test/DynamoCoreTests/CustomNodes.cs index 53ac98b0306..931901fac75 100644 --- a/test/DynamoCoreTests/CustomNodes.cs +++ b/test/DynamoCoreTests/CustomNodes.cs @@ -1208,7 +1208,7 @@ public void InputNodesShouldMaintainCommentsWhenSavingBrandNewCustomNode() const string nodeName = "someCustomNode"; const string catName1 = "CatName1"; - var cnworkspace = CurrentDynamoModel.CustomNodeManager.CreateCustomNode(nodeName, catName1, "a node with an input with comments"); + var cnworkspace = CurrentDynamoModel.CustomNodeManager.CreateCustomNode(nodeName, catName1, "a node with an input with comments", null, true); var inputNode = new Symbol(); inputNode.InputSymbol = "/* a new and better comment*/" + Environment.NewLine + "inputName: string = \"a def string\""; cnworkspace.AddAndRegisterNode(inputNode); diff --git a/test/DynamoCoreWpfTests/SerializationTests.cs b/test/DynamoCoreWpfTests/SerializationTests.cs index 8ca6fb59310..b7fcf40f8b3 100644 --- a/test/DynamoCoreWpfTests/SerializationTests.cs +++ b/test/DynamoCoreWpfTests/SerializationTests.cs @@ -922,19 +922,19 @@ public void NewCustomNodeSaveAndLoadPt1() var funcguid = GuidUtility.Create(GuidUtility.UrlNamespace, "NewCustomNodeSaveAndLoad"); //first create a new custom node. - this.ViewModel.ExecuteCommand(new DynamoModel.CreateCustomNodeCommand(funcguid, "testnode", "testcategory", "atest", true)); + var ws = this.ViewModel.Model.CustomNodeManager.CreateCustomNode("testnode", "testcategory", "atest", funcguid, true); var outnode1 = new Output(); outnode1.Symbol = "out1"; var outnode2 = new Output(); - outnode1.Symbol = "out2"; + outnode2.Symbol = "out2"; var numberNode = new DoubleInput(); numberNode.Value = "5"; - this.ViewModel.CurrentSpace.AddAndRegisterNode(numberNode); - this.ViewModel.CurrentSpace.AddAndRegisterNode(outnode1); - this.ViewModel.CurrentSpace.AddAndRegisterNode(outnode2); + ws.AddAndRegisterNode(numberNode); + ws.AddAndRegisterNode(outnode1); + ws.AddAndRegisterNode(outnode2); new ConnectorModel(numberNode.OutPorts.FirstOrDefault(), outnode1.InPorts.FirstOrDefault(), Guid.NewGuid()); new ConnectorModel(numberNode.OutPorts.FirstOrDefault(), outnode2.InPorts.FirstOrDefault(), Guid.NewGuid()); @@ -942,7 +942,7 @@ public void NewCustomNodeSaveAndLoadPt1() var savePath = Path.Combine(this.ViewModel.Model.PathManager.DefinitionDirectories.FirstOrDefault(), "NewCustomNodeSaveAndLoad.dyf"); //save it to the definitions folder so it gets loaded at startup. - this.ViewModel.CurrentSpace.Save(savePath); + ws.Save(savePath); //assert the filesaved Assert.IsTrue(File.Exists(savePath)); @@ -955,7 +955,8 @@ public void NewCustomNodeSaveAndLoadPt2() // This unit test is a follow-up of NewCustomNodeSaveAndLoadPt1 test to make sure the newly created // custom node will be loaded once DynamoCore restarted var funcguid = GuidUtility.Create(GuidUtility.UrlNamespace, "NewCustomNodeSaveAndLoad"); - var functionnode = this.ViewModel.Model.CustomNodeManager.CreateCustomNodeInstance(funcguid,"testnode",true); + var functionnode = + this.ViewModel.Model.CustomNodeManager.CreateCustomNodeInstance(funcguid, "testnode", true); Assert.IsTrue(functionnode.IsCustomFunction); Assert.IsFalse(functionnode.IsInErrorState); Assert.AreEqual(functionnode.OutPorts.Count, 2); diff --git a/test/DynamoCoreWpfTests/WorkspaceSaving.cs b/test/DynamoCoreWpfTests/WorkspaceSaving.cs index 32d575a1e49..b1c12511a63 100644 --- a/test/DynamoCoreWpfTests/WorkspaceSaving.cs +++ b/test/DynamoCoreWpfTests/WorkspaceSaving.cs @@ -228,7 +228,7 @@ public void CustomNodeWorkspaceFilePathIsUpdatedOnSaveAs() var nodeName = "Cool node"; var catName = "Custom Nodes"; - var def = dynamoModel.CustomNodeManager.CreateCustomNode(nodeName, catName, ""); + var def = dynamoModel.CustomNodeManager.CreateCustomNode(nodeName, catName, "", null, true); var newPath = GetNewFileNameOnTempPath("dyf"); def.Save(newPath); @@ -274,7 +274,7 @@ public void CustomNodeWorkspaceCanSaveAsMultipleTimes() var nodeName = "Cool node"; var catName = "Custom Nodes"; - var def = dynamoModel.CustomNodeManager.CreateCustomNode(nodeName, catName, ""); + var def = dynamoModel.CustomNodeManager.CreateCustomNode(nodeName, catName, "", null, true); foreach (var i in Enumerable.Range(0, 10)) { @@ -333,7 +333,7 @@ public void CustomNodeWorkspaceCanSaveAsAndThenSaveExistingFile() var nodeName = "Cool node"; var catName = "Custom Nodes"; - var def = dynamoModel.CustomNodeManager.CreateCustomNode(nodeName, catName, ""); + var def = dynamoModel.CustomNodeManager.CreateCustomNode(nodeName, catName, "", null, true); var newPath = GetNewFileNameOnTempPath("dyf"); def.Save(newPath); @@ -402,7 +402,7 @@ public void CustomNodeWorkspaceCanSaveMultipleTimes() var nodeName = "Cool node"; var catName = "Custom Nodes"; - var def = dynamoModel.CustomNodeManager.CreateCustomNode(nodeName, catName, ""); + var def = dynamoModel.CustomNodeManager.CreateCustomNode(nodeName, catName, "", null, true); var newPath = GetNewFileNameOnTempPath("dyf"); def.Save(newPath); @@ -666,7 +666,7 @@ public void CustomNodeWorkspaceHasUnsavedChangesPropertyIsSetOnSaveAs() var nodeName = "Cool node"; var catName = "Custom Nodes"; - var def = dynamoModel.CustomNodeManager.CreateCustomNode(nodeName, catName, ""); + var def = dynamoModel.CustomNodeManager.CreateCustomNode(nodeName, catName, "", null, true); Assert.IsFalse(def.HasUnsavedChanges); var node = new DSFunction(dynamoModel.LibraryServices.GetFunctionDescriptor("+")); @@ -720,7 +720,7 @@ public void CustomNodeSaveAsDoesGiveNewFunctionIdToNewCustomNode() var catName = "Custom Nodes"; var initialId = Guid.NewGuid(); - var def = dynamoModel.CustomNodeManager.CreateCustomNode(nodeName, catName, "", initialId); + var def = dynamoModel.CustomNodeManager.CreateCustomNode(nodeName, catName, "", initialId, true); var workspace = (CustomNodeWorkspaceModel)def; var newPath = GetNewFileNameOnTempPath("dyf"); @@ -807,7 +807,7 @@ public void CustomNodeEditNodeDescriptionKeepingViewBlockInDyf() var catName = "Custom Nodes"; var initialId = Guid.NewGuid(); - var def = dynamoModel.CustomNodeManager.CreateCustomNode(nodeName, catName, "", initialId); + var def = dynamoModel.CustomNodeManager.CreateCustomNode(nodeName, catName, "", initialId, true); var workspace = (CustomNodeWorkspaceModel)def; // Set file path @@ -852,7 +852,7 @@ public void CustomNodeEditNodeDescriptionKeepingIsVisibleInDynamoLibraryInDyf() var customNodeWorkspace = dynamoModel.CurrentWorkspace; var initialId = new Guid("6aecda57-7679-4afb-aa02-05a75cc3433e"); - var newCustNodeInstance = dynamoModel.CustomNodeManager.CreateCustomNodeInstance(initialId); + var newCustNodeInstance = dynamoModel.CustomNodeManager.CreateCustomNodeInstance(initialId, null, true); // Switch HomeWorkspace and place custom node on it dynamoModel.CurrentWorkspace = dynamoModel.Workspaces.First(); dynamoModel.CurrentWorkspace.AddAndRegisterNode(newCustNodeInstance, false); @@ -1152,7 +1152,7 @@ public void MultipleCustomNodeSaveAsOperationsAddsMultipleValidFunctionIdsToCust var nodeName = "Cool node"; var catName = "Custom Nodes"; - var def = dynamoModel.CustomNodeManager.CreateCustomNode(nodeName, catName, ""); + var def = dynamoModel.CustomNodeManager.CreateCustomNode(nodeName, catName, "", null, true); var workspace = (CustomNodeWorkspaceModel)def; var listGuids = new List(); @@ -1203,7 +1203,7 @@ public void CusotmNodeSaveAsUpdateItsName() var nodeName = "Foo"; var catName = "Custom Nodes"; - var def = dynamoModel.CustomNodeManager.CreateCustomNode(nodeName, catName, ""); + var def = dynamoModel.CustomNodeManager.CreateCustomNode(nodeName, catName, "", null, true); var workspace = (CustomNodeWorkspaceModel)def; ViewModel.SearchViewModel.Visible = true; @@ -1246,7 +1246,7 @@ public void CustomNodeWorkspaceSavedToSamePlaceNotCausingDuplicatedLibraryItems( var nodeName = Guid.NewGuid().ToString(); var catName = "Custom Nodes"; - var def = dynamoModel.CustomNodeManager.CreateCustomNode(nodeName, catName, ""); + var def = dynamoModel.CustomNodeManager.CreateCustomNode(nodeName, catName, "", null, true); var tempPath1 = Path.Combine(TempFolder, nodeName + ".dyf"); From 619a70945d94f80e2eb25f1c9bafe105d3cc1fb4 Mon Sep 17 00:00:00 2001 From: aparajit-pratap Date: Tue, 2 Jul 2019 15:09:23 -0400 Subject: [PATCH 10/10] fix test --- test/Libraries/PackageManagerTests/PackageLoaderTests.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/Libraries/PackageManagerTests/PackageLoaderTests.cs b/test/Libraries/PackageManagerTests/PackageLoaderTests.cs index 77c1d544939..0a4d39239d8 100644 --- a/test/Libraries/PackageManagerTests/PackageLoaderTests.cs +++ b/test/Libraries/PackageManagerTests/PackageLoaderTests.cs @@ -186,8 +186,11 @@ public void LoadingConflictingCustomNodePackageDoesNotGetLoaded() loader.PackagesLoaded += libraryLoader.LoadPackages; loader.RequestLoadNodeLibrary += libraryLoader.LoadNodeLibrary; - loader.RequestLoadCustomNodeDirectory += - (dir) => CurrentDynamoModel.CustomNodeManager.AddUninitializedCustomNodesInPath(dir, true); + + // This test needs the "isTestMode" flag to be turned off as an exception to be able + // to test duplicate custom node def loading. + loader.RequestLoadCustomNodeDirectory += + (dir) => CurrentDynamoModel.CustomNodeManager.AddUninitializedCustomNodesInPath(dir, isTestMode: false); loader.LoadAll(new LoadPackageParams {