From 01a8964c87a651e3adf3f87b66f80177b68e9b94 Mon Sep 17 00:00:00 2001
From: JoC0de <53140583+JoC0de@users.noreply.github.com>
Date: Sun, 22 Oct 2023 00:25:34 +0200
Subject: [PATCH] allow overwriting nuget cache location (#591)
* safely handle if 'localappdata' folder is not specified
* allow overriding nuget cache location
* add custom exception for failed cache directory creation
---
README.md | 2 +-
.../Editor/Helper/CredentialProviderHelper.cs | 9 ++-
.../Editor/PackageCacheManager.cs | 57 ++++++++++++++++---
3 files changed, 59 insertions(+), 9 deletions(-)
diff --git a/README.md b/README.md
index 376c3ad8..8790b353 100644
--- a/README.md
+++ b/README.md
@@ -152,7 +152,7 @@ Note: Depending on the size and number of packages you need to install, the `Res
If you are interested in the process NuGetForUnity follows or you are trying to debug an issue, you can force NuGetForUnity to use verbose logging to output an increased amount of data to the Unity console. Add the line `` to the `` element in the _NuGet.config_ file. You can disable verbose logging by either setting the value to false or completely deleting the line.
-The _.nupkg_ files downloaded from the NuGet server are cached locally in the current user's Application Data folder. (`C:\Users\[username]\AppData\Local\NuGet\Cache`). Packages previously installed are installed via the cache folder instead of downloading it from the server again.
+The _.nupkg_ files downloaded from the NuGet server are cached locally in the current user's Application Data folder `%localappdata%\NuGet\Cache` (`C:\Users\[username]\AppData\Local\NuGet\Cache`). The cache location can be overwrtten by setting the `NuGetCachePath` environment variable. Packages previously installed are installed via the cache folder instead of downloading it from the server again.
# Advanced settings
diff --git a/src/NuGetForUnity/Editor/Helper/CredentialProviderHelper.cs b/src/NuGetForUnity/Editor/Helper/CredentialProviderHelper.cs
index 3f6ba480..486cb97f 100644
--- a/src/NuGetForUnity/Editor/Helper/CredentialProviderHelper.cs
+++ b/src/NuGetForUnity/Editor/Helper/CredentialProviderHelper.cs
@@ -194,7 +194,14 @@ private static IEnumerable GetEnvironmentCredentialProviderPaths()
private static string GetDefaultCredentialProvidersPath()
{
- return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Nuget", "CredentialProviders");
+ var baseDirectory = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
+ if (string.IsNullOrEmpty(baseDirectory))
+ {
+ // we need a place to store the credential provider so we fallback to the temp location.
+ baseDirectory = Path.GetTempPath();
+ }
+
+ return Path.Combine(baseDirectory, "Nuget", "CredentialProviders");
}
private static bool DownloadCredentialProviders([NotNull] Uri feedUri)
diff --git a/src/NuGetForUnity/Editor/PackageCacheManager.cs b/src/NuGetForUnity/Editor/PackageCacheManager.cs
index fccd26aa..36a8a003 100644
--- a/src/NuGetForUnity/Editor/PackageCacheManager.cs
+++ b/src/NuGetForUnity/Editor/PackageCacheManager.cs
@@ -1,10 +1,22 @@
-using System;
+#pragma warning disable SA1512,SA1124 // Single-line comments should not be followed by blank line
+
+using System;
using System.IO;
using JetBrains.Annotations;
using NugetForUnity.Configuration;
using NugetForUnity.Models;
using NugetForUnity.PackageSource;
+#region No ReShaper
+
+// ReSharper disable All
+// needed because 'JetBrains.Annotations.NotNull' and 'System.Diagnostics.CodeAnalysis.NotNull' collide if this file is compiled with a never version of Unity / C#
+using SuppressMessageAttribute = System.Diagnostics.CodeAnalysis.SuppressMessageAttribute;
+
+// ReSharper restore All
+
+#endregion
+
namespace NugetForUnity
{
///
@@ -12,22 +24,35 @@ namespace NugetForUnity
///
internal static class PackageCacheManager
{
+ private const string CacheEnvironmentVariableName = "NuGetCachePath";
+
///
/// The path where to put created (packed) and downloaded (not installed yet) .nupkg files.
///
- internal static readonly string CacheOutputDirectory = Path.Combine(
- Path.GetFullPath(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)),
- "NuGet",
- "Cache");
+ [SuppressMessage(
+ "StyleCop.CSharp.OrderingRules",
+ "SA1202:Elements should be ordered by access",
+ Justification = "Conflicts with other warnings.")]
+ internal static readonly string CacheOutputDirectory = DetermineCacheOutputDirectory();
///
/// Initializes static members of the class.
/// Static constructor called only once.
///
+ [SuppressMessage("SonarQube", "S3877:Exceptions should not be thrown from unexpected methods", Justification = "Need to fail here.")]
static PackageCacheManager()
{
- // create the nupkgs directory, if it doesn't exist
- Directory.CreateDirectory(CacheOutputDirectory);
+ try
+ {
+ // create the cache directory, if it doesn't exist
+ Directory.CreateDirectory(CacheOutputDirectory);
+ }
+ catch (Exception exception)
+ {
+ throw new InvalidOperationException(
+ $"Failed to create the cache output directory '{CacheOutputDirectory}'. The cache directory can be changed by specifying the '{CacheEnvironmentVariableName}' environment variable.",
+ exception);
+ }
}
///
@@ -156,5 +181,23 @@ private static INugetPackage GetInstalledPackage([NotNull] INugetPackageIdentifi
installedPackage.Version);
return installedPackage;
}
+
+ private static string DetermineCacheOutputDirectory()
+ {
+ var cacheFromEnvironment = Environment.GetEnvironmentVariable(CacheEnvironmentVariableName);
+ if (!string.IsNullOrEmpty(cacheFromEnvironment))
+ {
+ return Path.GetFullPath(cacheFromEnvironment);
+ }
+
+ var localApplicationDataFolder = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
+ if (string.IsNullOrEmpty(localApplicationDataFolder))
+ {
+ throw new InvalidOperationException(
+ $"There is no system folder specified for '{Environment.SpecialFolder.LocalApplicationData}' you need to either configure it or set the NuGet cache directory by specifying the '{CacheEnvironmentVariableName}' environment variable.");
+ }
+
+ return Path.Combine(Path.GetFullPath(localApplicationDataFolder), "NuGet", "Cache");
+ }
}
}