Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Made packages.config path configurable from NuGet preferences #551

Merged
merged 10 commits into from
Aug 11, 2023
5 changes: 3 additions & 2 deletions src/NuGetForUnity.Tests/Assets/NuGet.config
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="NuGet" value="http://www.nuget.org/api/v2/" />
Expand All @@ -12,6 +12,7 @@
<add key="repositoryPath" value="./Packages" />
<add key="DefaultPushSource" value="http://www.nuget.org/api/v2/" />
<add key="verbose" value="true" />
<add key="PackagesConfigPath" value="Assets" />
<add key="ReadOnlyPackageFiles" value="false" />
popara96 marked this conversation as resolved.
Show resolved Hide resolved
</config>
</configuration>
</configuration>
29 changes: 23 additions & 6 deletions src/NuGetForUnity.Tests/Assets/Tests/Editor/NuGetTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -649,11 +649,11 @@ public void TestSerializeNugetPackageIdentifier(string version)
public void TestPostprocessInstall(string packageId, string packageVersion)
{
var package = new NugetPackageIdentifier(packageId, packageVersion) { IsManuallyInstalled = true };
var filepath = NugetHelper.PackagesConfigFilePath;
var filepath = NugetHelper.NugetConfigFile.PackagesConfigFilePath;

var packagesConfigFile = new PackagesConfigFile();
packagesConfigFile.AddPackage(package);
packagesConfigFile.Save(filepath);
packagesConfigFile.Save();

Assert.IsFalse(NugetHelper.IsInstalled(package), "The package IS installed: {0} {1}", package.Id, package.Version);

Expand All @@ -669,13 +669,13 @@ public void TestPostprocessInstall(string packageId, string packageVersion)
public void TestPostprocessUninstall(string packageId, string packageVersion)
{
var package = new NugetPackageIdentifier(packageId, packageVersion) { IsManuallyInstalled = true };
var filepath = NugetHelper.PackagesConfigFilePath;
var filepath = NugetHelper.NugetConfigFile.PackagesConfigFilePath;

NugetHelper.InstallIdentifier(package);
Assert.IsTrue(NugetHelper.IsInstalled(package), "The package was NOT installed: {0} {1}", package.Id, package.Version);

var packagesConfigFile = new PackagesConfigFile();
packagesConfigFile.Save(filepath);
packagesConfigFile.Save();

var assetsIndex = filepath.LastIndexOf("Assets", StringComparison.Ordinal);
filepath = filepath.Substring(assetsIndex);
Expand All @@ -691,14 +691,14 @@ public void TestPostprocessDifferentVersion(string packageId, string packageVers
{
var packageOld = new NugetPackageIdentifier(packageId, packageVersionOld) { IsManuallyInstalled = true };
var packageNew = new NugetPackageIdentifier(packageId, packageVersionNew) { IsManuallyInstalled = true };
var filepath = NugetHelper.PackagesConfigFilePath;
var filepath = NugetHelper.NugetConfigFile.PackagesConfigFilePath;

NugetHelper.InstallIdentifier(packageOld);
Assert.IsTrue(NugetHelper.IsInstalled(packageOld), "The package was NOT installed: {0} {1}", packageOld.Id, packageOld.Version);

var packagesConfigFile = new PackagesConfigFile();
packagesConfigFile.AddPackage(packageNew);
packagesConfigFile.Save(filepath);
packagesConfigFile.Save();

var assetsIndex = filepath.LastIndexOf("Assets", StringComparison.Ordinal);
filepath = filepath.Substring(assetsIndex);
Expand All @@ -718,4 +718,21 @@ private static void ConfigureNugetConfig(InstallMode installMode)
installMode == InstallMode.ApiV2Only || installMode == InstallMode.ApiV2AllowCached;
nugetConfigFile.InstallFromCache = installMode == InstallMode.ApiV2AllowCached;
}

[Test]
[TestCase("", "Assets")]
[TestCase("../", ".")]
[TestCase("/../../", null)]
[TestCase("a/b/c", "Assets/a/b/c")]
public void PathTest(string append, string expected)
{
var path = Path.GetFullPath(Path.Combine(Application.dataPath, append));
var relativePath = NugetHelper.GetProjectRelativePath(path);
if (expected == null)
{
expected = path;
}

Assert.That(relativePath, Is.EqualTo(expected));
}
}
5 changes: 3 additions & 2 deletions src/NuGetForUnity.Tests/Assets/Tests/Resources/NuGet.config
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
Expand All @@ -16,6 +16,7 @@
</activePackageSource>
<config>
<add key="repositoryPath" value="./Packages" />
<add key="PackagesConfigPath" value="Assets" />
<add key="ReadOnlyPackageFiles" value="false" />
</config>
</configuration>
</configuration>
42 changes: 42 additions & 0 deletions src/NuGetForUnity/Editor/NugetConfigFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,37 @@ public class NugetConfigFile
/// </summary>
public bool ReadOnlyPackageFiles { get; set; }

public string PackagesConfigPath;
popara96 marked this conversation as resolved.
Show resolved Hide resolved

public string RelativePackagesConfigPath
popara96 marked this conversation as resolved.
Show resolved Hide resolved
{
get => NugetHelper.GetProjectRelativePath(PackagesConfigPath);

private set
{
var tempValue = Environment.ExpandEnvironmentVariables(value);
popara96 marked this conversation as resolved.
Show resolved Hide resolved
if (tempValue == "Assets" || tempValue == "Assets/" || tempValue == "Assets\\")
{
PackagesConfigPath = Application.dataPath;
}
else if (tempValue.StartsWith("Assets/") || tempValue.StartsWith("Assets\\"))
{
PackagesConfigPath = Path.Combine(Application.dataPath, tempValue.Substring("Assets/".Length));
}
popara96 marked this conversation as resolved.
Show resolved Hide resolved
else
{
Debug.LogWarning($"Path to packages.config in NuGet.config must be relative to the project root (attempted path: {tempValue}). Setting to default.");
PackagesConfigPath = Application.dataPath;
Save(NugetHelper.NugetConfigFilePath);
}
}
}

/// <summary>
/// The path to the packages.config file.
/// </summary>
public string PackagesConfigFilePath => Path.Combine(PackagesConfigPath, PackagesConfigFile.FileName);

/// <summary>
/// Gets or sets the timeout in seconds used for all web requests to NuGet sources.
/// </summary>
Expand Down Expand Up @@ -147,6 +178,11 @@ public void Save(string filePath)
addElement.Add(new XAttribute("value", savedRepositoryPath));
config.Add(addElement);

addElement = new XElement("add");
addElement.Add(new XAttribute("key", "PackagesConfigPath"));
popara96 marked this conversation as resolved.
Show resolved Hide resolved
addElement.Add(new XAttribute("value", RelativePackagesConfigPath));
JoC0de marked this conversation as resolved.
Show resolved Hide resolved
config.Add(addElement);

// save the default push source
if (DefaultPushSource != null)
{
Expand Down Expand Up @@ -233,6 +269,7 @@ public static NugetConfigFile Load(string filePath)
configFile.PackageSources = new List<INugetPackageSource>();
configFile.InstallFromCache = true;
configFile.ReadOnlyPackageFiles = false;
configFile.RelativePackagesConfigPath = "Assets";

var file = XDocument.Load(filePath);

Expand Down Expand Up @@ -355,6 +392,10 @@ public static NugetConfigFile Load(string filePath)
{
configFile.LockPackagesOnRestore = bool.Parse(value);
}
else if (string.Equals(key, "PackagesConfigPath", StringComparison.OrdinalIgnoreCase))
{
configFile.RelativePackagesConfigPath = value;
}
}
}

Expand All @@ -380,6 +421,7 @@ public static NugetConfigFile CreateDefaultFile(string filePath)
</activePackageSource>
<config>
<add key=""repositoryPath"" value=""./Packages"" />
<add key=""PackagesConfigPath"" value=""Assets"" />
</config>
</configuration>";

Expand Down
49 changes: 35 additions & 14 deletions src/NuGetForUnity/Editor/NugetHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,6 @@ public static class NugetHelper
/// </remarks>
public static readonly string NugetConfigFilePath = Path.GetFullPath(Path.Combine(Application.dataPath, NugetConfigFile.FileName));

/// <summary>
/// The path to the packages.config file.
/// </summary>
/// <remarks>
/// <see cref="PackagesConfigFile" />.
/// </remarks>
internal static readonly string PackagesConfigFilePath = Path.GetFullPath(Path.Combine(Application.dataPath, PackagesConfigFile.FileName));

/// <summary>
/// Gets the absolute path to the Unity-Project root directory.
/// </summary>
Expand Down Expand Up @@ -97,7 +89,7 @@ public static PackagesConfigFile PackagesConfigFile
{
if (packagesConfigFile == null)
{
packagesConfigFile = PackagesConfigFile.Load(PackagesConfigFilePath);
packagesConfigFile = PackagesConfigFile.Load();
}

return packagesConfigFile;
Expand Down Expand Up @@ -756,7 +748,7 @@ public static void Uninstall(INugetPackageIdentifier package, bool refreshAssets
// update the package.config file
if (PackagesConfigFile.RemovePackage(foundPackage))
{
PackagesConfigFile.Save(PackagesConfigFilePath);
PackagesConfigFile.Save();
}

var packageInstallDirectory = Path.Combine(NugetConfigFile.RepositoryPath, $"{foundPackage.Id}.{foundPackage.Version}");
Expand Down Expand Up @@ -855,7 +847,7 @@ public static void UpdateAll(IEnumerable<INugetPackage> updates, IEnumerable<INu
internal static void SetManuallyInstalledFlag(INugetPackageIdentifier package)
{
PackagesConfigFile.SetManuallyInstalledFlag(package);
PackagesConfigFile.Save(PackagesConfigFilePath);
PackagesConfigFile.Save();
}

/// <summary>
Expand Down Expand Up @@ -927,8 +919,7 @@ void AddPackageToInstalled(INugetPackage package)
{
PackagesConfigFile.SetManuallyInstalledFlag(rootPackage);
}

PackagesConfigFile.Save(PackagesConfigFilePath);
PackagesConfigFile.Save();
}
}

Expand Down Expand Up @@ -1283,7 +1274,7 @@ public static bool Install(INugetPackage package, bool refreshAssets = true, boo

// update packages.config
PackagesConfigFile.AddPackage(package);
PackagesConfigFile.Save(PackagesConfigFilePath);
PackagesConfigFile.Save();

var cachedPackagePath = Path.Combine(PackOutputDirectory, package.PackageFileName);
if (NugetConfigFile.InstallFromCache && File.Exists(cachedPackagePath))
Expand Down Expand Up @@ -1589,5 +1580,35 @@ internal static bool IsInstalled(INugetPackageIdentifier package)

return isInstalled;
}

/// <summary>
/// Returns the path relative to project directory, or path if it's not relative to project directory.
/// Should the project upgrade to .NET Standard 2.1, this will be removed and instead we will use Path.GetRelativePath(relativeTo, path);
/// </summary>
/// <param name="absolutePath">The destination path.</param>
public static string GetProjectRelativePath(string absolutePath)
{
var projectFolder = (Path.GetDirectoryName(Application.dataPath) ?? string.Empty).Replace('\\', '/');

if (string.IsNullOrEmpty(projectFolder) || string.IsNullOrEmpty(absolutePath) || !Path.IsPathRooted(absolutePath))
{
return absolutePath;
}

var path = absolutePath.Replace('\\', '/');

if (!path.StartsWith(projectFolder, StringComparison.Ordinal))
{
return absolutePath;
}

var projectFolderLength = projectFolder.Length;
if (path.Length > projectFolderLength && path[projectFolderLength] == '/')
{
projectFolderLength++;
}

return path.Length > projectFolderLength ? path.Substring(projectFolderLength) : ".";
}
}
}
8 changes: 7 additions & 1 deletion src/NuGetForUnity/Editor/NugetPackageAssetPostprocessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,13 @@ internal static void OnPostprocessAllAssets(
string[] movedAssets,
string[] movedFromAssetPaths)
{
var packagesConfigFilePath = Path.GetFullPath(NugetHelper.PackagesConfigFilePath);
// currently only importedAssets are important for us, so if there are none, we do nothing
if (importedAssets.Length == 0)
{
return;
}

var packagesConfigFilePath = NugetHelper.NugetConfigFile.PackagesConfigFilePath;
var foundPackagesConfigAsset = importedAssets.Any(
importedAsset => Path.GetFullPath(importedAsset).Equals(packagesConfigFilePath, StringComparison.Ordinal));

Expand Down
32 changes: 31 additions & 1 deletion src/NuGetForUnity/Editor/NugetPreferences.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using UnityEditor;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;

namespace NugetForUnity
Expand Down Expand Up @@ -72,6 +74,34 @@ public override void OnGUI(string searchContext)
NugetHelper.NugetConfigFile.Verbose = verbose;
}

EditorGUILayout.BeginHorizontal();
{
var packagesConfigPath = NugetHelper.NugetConfigFile.RelativePackagesConfigPath;
EditorGUILayout.LabelField($"Packages Config path: {packagesConfigPath}");
packagesConfigPath = Path.GetFullPath(packagesConfigPath);
if (GUILayout.Button("Browse"))
popara96 marked this conversation as resolved.
Show resolved Hide resolved
{
var newPath = EditorUtility.OpenFolderPanel("Select Folder", packagesConfigPath, "");

if (!string.IsNullOrEmpty(newPath) && newPath != packagesConfigPath)
{
var pathCheck = NugetHelper.GetProjectRelativePath(newPath);

// make sure the path is within Assets directory
if (!pathCheck.StartsWith("Assets"))
{
popara96 marked this conversation as resolved.
Show resolved Hide resolved
Debug.LogError("packages.config path has to be within <project root>/Assets.");
}
else
{
PackagesConfigFile.Move(newPath);
preferencesChangedThisFrame = true;
}
}
}
}
EditorGUILayout.EndHorizontal();

var requestTimeout = EditorGUILayout.IntField(
new GUIContent(
"Request Timeout in seconds",
Expand Down
Loading
Loading