Skip to content

Commit

Permalink
allow overwriting nuget cache location (#591)
Browse files Browse the repository at this point in the history
* safely handle if 'localappdata' folder is not specified 
* allow overriding nuget cache location
* add custom exception for failed cache directory creation
  • Loading branch information
JoC0de authored Oct 21, 2023
1 parent 2262234 commit 01a8964
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 9 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<add key="verbose" value="true" />` to the `<config>` 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
Expand Down
9 changes: 8 additions & 1 deletion src/NuGetForUnity/Editor/Helper/CredentialProviderHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,14 @@ private static IEnumerable<string> 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)
Expand Down
57 changes: 50 additions & 7 deletions src/NuGetForUnity/Editor/PackageCacheManager.cs
Original file line number Diff line number Diff line change
@@ -1,33 +1,58 @@
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
{
/// <summary>
/// Manages the NuGet package cache, which is where .nupkg files are stored after they are downloaded from the server, but before they are installed.
/// </summary>
internal static class PackageCacheManager
{
private const string CacheEnvironmentVariableName = "NuGetCachePath";

/// <summary>
/// The path where to put created (packed) and downloaded (not installed yet) .nupkg files.
/// </summary>
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();

/// <summary>
/// Initializes static members of the <see cref="PackageCacheManager" /> class.
/// Static constructor called only once.
/// </summary>
[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);
}
}

/// <summary>
Expand Down Expand Up @@ -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");
}
}
}

0 comments on commit 01a8964

Please sign in to comment.