diff --git a/src/DynamoCoreWpf/ViewModels/Menu/PreferencesViewModel.cs b/src/DynamoCoreWpf/ViewModels/Menu/PreferencesViewModel.cs index 0f3e28b9ac3..405b9f4503a 100644 --- a/src/DynamoCoreWpf/ViewModels/Menu/PreferencesViewModel.cs +++ b/src/DynamoCoreWpf/ViewModels/Menu/PreferencesViewModel.cs @@ -319,6 +319,7 @@ public string SelectedPackagePathForInstall if (preferenceSettings.SelectedPackagePathForInstall != value) { preferenceSettings.SelectedPackagePathForInstall = value; + //TODO remove along with PackageLoader.DefaultPackagesDirectory and PackageLoader.DefaultPackagesDirectoryIndex dynamoViewModel.PackageManagerClientViewModel.PackageManagerExtension.PackageLoader.SetPackagesDownloadDirectory( value, dynamoViewModel.Model.PathManager.UserDataDirectory); RaisePropertyChanged(nameof(SelectedPackagePathForInstall)); diff --git a/src/DynamoCoreWpf/ViewModels/PackageManager/PackagePathViewModel.cs b/src/DynamoCoreWpf/ViewModels/PackageManager/PackagePathViewModel.cs index ee49fdbff34..3190f6f06be 100644 --- a/src/DynamoCoreWpf/ViewModels/PackageManager/PackagePathViewModel.cs +++ b/src/DynamoCoreWpf/ViewModels/PackageManager/PackagePathViewModel.cs @@ -10,6 +10,7 @@ using Dynamo.Models; using System.Windows.Data; using System.Globalization; +using System.Linq; namespace Dynamo.ViewModels { @@ -130,7 +131,9 @@ private void RaiseCanExecuteChanged() private bool CanDelete(int param) { - if (RootLocations.IndexOf(Resources.PackagePathViewModel_Standard_Library) == param) + var programDataPackagePathIndex = GetIndexOfProgramDataPackagePath(); + if (RootLocations.IndexOf(Resources.PackagePathViewModel_Standard_Library) == param || + programDataPackagePathIndex == param) { return false; } @@ -150,7 +153,19 @@ private bool CanMoveDown(int param) private bool CanUpdate(int param) { - return RootLocations.IndexOf(Resources.PackagePathViewModel_Standard_Library) != param; + var programDataPackagePathIndex = GetIndexOfProgramDataPackagePath(); + + //editing builtin packages or programData package paths is not allowed. + return RootLocations.IndexOf(Resources.PackagePathViewModel_Standard_Library) != param && + programDataPackagePathIndex != param; + } + + private int GetIndexOfProgramDataPackagePath() + { + var programDataPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData); + var programDataPackagePath = RootLocations.Where(x => x.StartsWith(programDataPath)).FirstOrDefault(); + var programDataPackagePathIndex = RootLocations.IndexOf(programDataPackagePath); + return programDataPackagePathIndex; } // The position of the selected entry must always be the first parameter. diff --git a/src/DynamoPackages/PackageLoader.cs b/src/DynamoPackages/PackageLoader.cs index 462806be902..01b562bf067 100644 --- a/src/DynamoPackages/PackageLoader.cs +++ b/src/DynamoPackages/PackageLoader.cs @@ -73,14 +73,16 @@ public IEnumerable RequestedExtensions private readonly List packagesDirectories = new List(); - + //TODO remove. private int defaultPackagesDirectoryIndex = -1; + //TODO this should get DefaultPackagesDirectoryFrom PathManager directly. /// /// Returns the default package directory where new packages will be installed /// This is the first non standard library directory /// The first entry is the standard library. /// /// Returns the path to the DefaultPackagesDirectory if found - or null if something has gone wrong. + [Obsolete("This property is redundant, please use the PathManager.DefaultPackagesDirectory property instead.")] public string DefaultPackagesDirectory { get { return defaultPackagesDirectoryIndex != -1 ? packagesDirectories[defaultPackagesDirectoryIndex] : null; } @@ -114,6 +116,7 @@ private static string TransformPath(string root, string userDataFolder, string e return root; } + //TODO remove when removing DefaultPackagesDirectory and DefaultPackagesDirectoryIndex internal void SetPackagesDownloadDirectory(string downloadDirectory, string userDataFolder) { defaultPackagesDirectoryIndex = packagesDirectories.IndexOf( @@ -214,11 +217,6 @@ private void InitPackageLoader(IEnumerable packagesDirectories, string s defaultPackagesDirectoryIndex = standardLibraryIndex == 1 ? 0 : safeIndex; } - var error = PathHelper.CreateFolderIfNotExist(DefaultPackagesDirectory); - - if (error != null) - Log(error); - packagesDirectoriesToVerifyCertificates.Add(stdLibDirectory); } diff --git a/src/DynamoPackages/PackageManagerClient.cs b/src/DynamoPackages/PackageManagerClient.cs index 509cc8ed712..6df5c9c847e 100644 --- a/src/DynamoPackages/PackageManagerClient.cs +++ b/src/DynamoPackages/PackageManagerClient.cs @@ -28,9 +28,9 @@ public class PackageManagerClient private readonly IPackageUploadBuilder uploadBuilder; /// - /// The directory where all packages are to be stored for this session. + /// The directory where new packages are created during the upload process. /// - private readonly string packagesDirectory; + private readonly string packageUploadDirectory; /// /// The URL of the package manager website @@ -42,9 +42,9 @@ public string BaseUrl #endregion - internal PackageManagerClient(IGregClient client, IPackageUploadBuilder builder, string packagesDirectory) + internal PackageManagerClient(IGregClient client, IPackageUploadBuilder builder, string packageUploadDirectory) { - this.packagesDirectory = packagesDirectory; + this.packageUploadDirectory = packageUploadDirectory; this.uploadBuilder = builder; this.client = client; } @@ -184,14 +184,14 @@ internal void Publish(Package package, IEnumerable files, bool isNewVers ResponseBody ret = null; if (isNewVersion) { - var pkg = uploadBuilder.NewPackageVersionUpload(package, packagesDirectory, files, + var pkg = uploadBuilder.NewPackageVersionUpload(package, packageUploadDirectory, files, packageUploadHandle); packageUploadHandle.UploadState = PackageUploadHandle.State.Uploading; ret = this.client.ExecuteAndDeserialize(pkg); } else { - var pkg = uploadBuilder.NewPackageUpload(package, packagesDirectory, files, + var pkg = uploadBuilder.NewPackageUpload(package, packageUploadDirectory, files, packageUploadHandle); packageUploadHandle.UploadState = PackageUploadHandle.State.Uploading; ret = this.client.ExecuteAndDeserialize(pkg); diff --git a/src/DynamoPackages/PackageManagerExtension.cs b/src/DynamoPackages/PackageManagerExtension.cs index 2f0232c965f..ecef246adef 100644 --- a/src/DynamoPackages/PackageManagerExtension.cs +++ b/src/DynamoPackages/PackageManagerExtension.cs @@ -162,21 +162,21 @@ public void Startup(StartupParams startupParams) PackageUploadBuilder.SetEngineVersion(startupParams.DynamoVersion); var uploadBuilder = new PackageUploadBuilder(dirBuilder, new MutatingFileCompressor()); - // Align the package install directory with the package download directory - + // Align the package upload directory with the package download directory - // either the one selected by the user or the default directory. - string packageInstallDirectory; + string packageUploadDirectory; if (startupParams.Preferences is PreferenceSettings preferences) { - packageInstallDirectory = string.IsNullOrEmpty(preferences.SelectedPackagePathForInstall) ? - PackageLoader.DefaultPackagesDirectory : preferences.SelectedPackagePathForInstall; + packageUploadDirectory = string.IsNullOrEmpty(preferences.SelectedPackagePathForInstall) ? + startupParams.PathManager.DefaultPackagesDirectory : preferences.SelectedPackagePathForInstall; } else { - packageInstallDirectory = PackageLoader.DefaultPackagesDirectory; + packageUploadDirectory = startupParams.PathManager.DefaultPackagesDirectory; } PackageManagerClient = new PackageManagerClient( new GregClient(startupParams.AuthProvider, url), - uploadBuilder, packageInstallDirectory); + uploadBuilder, packageUploadDirectory); LoadPackages(startupParams.Preferences, startupParams.PathManager); } diff --git a/test/DynamoCoreWpfTests/DynamoTestUIBase.cs b/test/DynamoCoreWpfTests/DynamoTestUIBase.cs index 7e84b82bdfa..aba50885215 100644 --- a/test/DynamoCoreWpfTests/DynamoTestUIBase.cs +++ b/test/DynamoCoreWpfTests/DynamoTestUIBase.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; @@ -231,6 +232,24 @@ public NoteView NoteViewWithGuid(string guid) return noteViewsOfType.First(); } + protected static string GetAppDataFolder() + { + var folder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); + var dynamoVersion = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location); + var appDataFolder = Path.Combine(Path.Combine(folder, "Dynamo", "Dynamo Core"), + $"{dynamoVersion.FileMajorPart}.{dynamoVersion.FileMinorPart}"); + + return appDataFolder; + } + protected static string GetCommonDataDirectory() + { + var folder = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData); + var dynamoVersion = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location); + var commonDataFolder = Path.Combine(Path.Combine(folder, "Dynamo", "Dynamo Core"), + $"{dynamoVersion.FileMajorPart}.{dynamoVersion.FileMinorPart}"); + return commonDataFolder; + } + #endregion } } diff --git a/test/DynamoCoreWpfTests/PackagePathTests.cs b/test/DynamoCoreWpfTests/PackagePathTests.cs index 583b13e1c89..8a7cb75b7ea 100644 --- a/test/DynamoCoreWpfTests/PackagePathTests.cs +++ b/test/DynamoCoreWpfTests/PackagePathTests.cs @@ -1,10 +1,13 @@  using System.IO; +using System.Linq; using System.Reflection; using Dynamo.Configuration; using Dynamo.Core; +using Dynamo.Interfaces; using Dynamo.Models; using Dynamo.PackageManager; +using Dynamo.Scheduler; using Dynamo.ViewModels; using NUnit.Framework; using SystemTestServices; @@ -86,6 +89,37 @@ public void CannotUpdateStandardLibraryPath() }; + var vm = CreatePackagePathViewModel(setting); + + Assert.AreEqual(2, vm.RootLocations.Count); + Assert.IsFalse(vm.UpdatePathCommand.CanExecute(0)); + Assert.IsTrue(vm.UpdatePathCommand.CanExecute(1)); + } + [Test] + public void CannotDeleteProgramDataPath() + { + var setting = new PreferenceSettings + { + CustomPackageFolders = { Path.Combine(ViewModel.Model.PathManager.CommonDataDirectory,"Packages"), @"C:\" } + }; + + + var vm = CreatePackagePathViewModel(setting); + + Assert.AreEqual(2, vm.RootLocations.Count); + Assert.IsFalse(vm.DeletePathCommand.CanExecute(0)); + Assert.IsTrue(vm.DeletePathCommand.CanExecute(1)); + } + + [Test] + public void CannotUpdateProgramDataPath() + { + var setting = new PreferenceSettings + { + CustomPackageFolders = { Path.Combine(ViewModel.Model.PathManager.CommonDataDirectory, "Packages"), @"C:\" } + }; + + var vm = CreatePackagePathViewModel(setting); Assert.AreEqual(2, vm.RootLocations.Count); @@ -186,6 +220,8 @@ public void PathEnabledConverterStdLibPath() Assert.False((bool)x.Convert(new object[] { vm, @"Z:\" }, null, null, null)); } + + #endregion #region Setup methods private PackagePathViewModel CreatePackagePathViewModel(PreferenceSettings setting) @@ -199,7 +235,46 @@ private PackagePathViewModel CreatePackagePathViewModel(PreferenceSettings setti CustomNodeManager customNodeManager = Model.CustomNodeManager; return new PackagePathViewModel(loader, loadParams, customNodeManager); } - #endregion } + + class PackagePathTests_CustomPrefs : DynamoTestUIBase + { + /// + /// Derived test classes can override this method to provide different configurations. + /// + /// A path resolver to pass to the DynamoModel. + protected override DynamoModel.IStartConfiguration CreateStartConfiguration(IPathResolver pathResolver) + { + return new DynamoModel.DefaultStartConfiguration() + { + PathResolver = pathResolver, + StartInTestMode = true, + GeometryFactoryPath = preloader.GeometryFactoryPath, + ProcessMode = TaskProcessMode.Synchronous, + Preferences = new PreferenceSettings() + { + //program data first + CustomPackageFolders = { Path.Combine(GetCommonDataDirectory(),PathManager.PackagesDirectoryName), @"C:\", GetAppDataFolder(), } + } + }; + } + + [Test] + [Category("TechDebt")] + public void IfProgramDataPathIsFirstDefaultPackagePathIsStillAppData() + { + var setting = Model.PreferenceSettings; + var loader = Model.GetPackageManagerExtension().PackageLoader; + + var appDataFolder = Path.Combine(GetAppDataFolder()); + Assert.AreEqual(3, ViewModel.Model.PathManager.PackagesDirectories.Count()); + Assert.AreEqual(4, setting.CustomPackageFolders.Count); + Assert.AreEqual(Path.Combine(appDataFolder, PathManager.PackagesDirectoryName), ViewModel.Model.PathManager.DefaultPackagesDirectory); + Assert.AreEqual(appDataFolder, setting.SelectedPackagePathForInstall); + //TODO this is incorrect, but this property has been obsoleted and will be made correct after refactoring pathmanager and packageloader. + //this should be changed to Assert.AreEqual after refactor. + Assert.AreNotEqual(Path.Combine(appDataFolder, PathManager.PackagesDirectoryName), loader.DefaultPackagesDirectory); + } + } } diff --git a/test/Libraries/SystemTestServices/SystemTestBase.cs b/test/Libraries/SystemTestServices/SystemTestBase.cs index 9145537772e..da47b9ade62 100644 --- a/test/Libraries/SystemTestServices/SystemTestBase.cs +++ b/test/Libraries/SystemTestServices/SystemTestBase.cs @@ -4,7 +4,6 @@ using System.Linq; using System.Reflection; using System.Threading; - using Dynamo.Configuration; using Dynamo.Controls; using Dynamo.Extensions; @@ -16,7 +15,6 @@ using Dynamo.Tests; using Dynamo.Updates; using Dynamo.ViewModels; -using Dynamo.Wpf.Extensions; using DynamoShapeManager; using NUnit.Framework;