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

Add an option to not strip out PDB symbols from nutget feeds #689

Merged
merged 1 commit into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,9 @@ dotnet_diagnostic.CA2234.severity=none
dotnet_diagnostic.CA2007.severity=none
dotnet_diagnostic.CA1056.severity=none # URI-like properties should not be strings
dotnet_diagnostic.CA1054.severity=none # URI parameters should not be strings
dotnet_diagnostic.CA2249.severity=none # Cant use String.Contains as it doesn't support StringComparison type on .net framework
dotnet_diagnostic.CA1307.severity=none # Cant use String.Replace with StringComparison type on .net framework
dotnet_diagnostic.CA1865.severity=none # Cant use String.StartsWith with char on .net framework
# ReSharper properties
resharper_wrap_after_declaration_lpar=true

Expand Down
37 changes: 37 additions & 0 deletions src/NuGetForUnity.Tests/Assets/Tests/Editor/NuGetTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using NUnit.Framework;
using UnityEditor;
using UnityEngine;
using UnityEngine.TestTools;

public class NuGetTests
{
Expand Down Expand Up @@ -1129,6 +1130,42 @@ public void NativeSettingsTest(string runtime, BuildTarget buildTarget)
$"Native mapping for {runtime} is missing build target {buildTarget}");
}

[Test]
public void KeepPdbFileTest()
{
ConfigureNugetConfig(InstallMode.ApiV3Only);
var nugetConfigFile = ConfigurationManager.NugetConfigFile;
nugetConfigFile.KeepingPdbFiles = true;
LogAssert.ignoreFailingMessages = true;

try
{
var package = new NugetPackageIdentifier("Fody", "6.8.2") { IsManuallyInstalled = true };
Assume.That(
InstalledPackagesManager.IsInstalled(package, false),
Is.False,
"The package IS installed: {0} {1}",
package.Id,
package.Version);

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

var packageDirectory = Path.Combine(ConfigurationManager.NugetConfigFile.RepositoryPath, $"{package.Id}.{package.Version}");

Assert.That(Path.Combine(packageDirectory, "netclassictask", "Mono.Cecil.pdb"), Does.Exist);
}
finally
{
LogAssert.ignoreFailingMessages = false;
nugetConfigFile.KeepingPdbFiles = false;
}
}

private static void ConfigureNugetConfig(InstallMode installMode)
{
var nugetConfigFile = ConfigurationManager.NugetConfigFile;
Expand Down
36 changes: 31 additions & 5 deletions src/NuGetForUnity/Editor/Configuration/NugetConfigFile.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma warning disable SA1512,SA1124 // Single-line comments should not be followed by blank line

#region No ReShaper

using System;
using System.Collections.Generic;
using System.Globalization;
Expand All @@ -12,8 +14,6 @@
using NugetForUnity.PackageSource;
using UnityEngine;

#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;
Expand Down Expand Up @@ -54,6 +54,8 @@ public class NugetConfigFile

private const string PreferNetStandardOverNetFrameworkConfigKey = "PreferNetStandardOverNetFramework";

private const string KeepingPdbFilesConfigKey = "KeepingPdbFiles";

private const string ProtocolVersionAttributeName = "protocolVersion";

private const string PasswordAttributeName = "password";
Expand Down Expand Up @@ -189,10 +191,15 @@ public string RelativePackagesConfigDirectoryPath
public int RequestTimeoutSeconds { get; set; } = DefaultRequestTimeout;

/// <summary>
/// Gets or sets the value indicating whether .NET Standard is preferred over .NET Framework as the TargetFramework.
/// Gets or sets a value indicating whether .NET Standard is preferred over .NET Framework as the TargetFramework.
/// </summary>
public bool PreferNetStandardOverNetFramework { get; set; }

/// <summary>
/// Gets or sets a value indicating whether PDB files included in NuGet packages should not be deleted if they can be read by Unity.
/// </summary>
internal bool KeepingPdbFiles { get; set; }

/// <summary>
/// Gets the value that tells the system how to determine where the packages are to be installed and configurations are to be stored.
/// </summary>
Expand All @@ -209,6 +216,10 @@ public string RelativePackagesConfigDirectoryPath
/// <param name="filePath">The full file-path to the NuGet.config file to load.</param>
/// <returns>The newly loaded <see cref="NugetConfigFile" />.</returns>
[NotNull]
[SuppressMessage(
"Usage",
"CA2263:Prefer generic overload when type is known",
Justification = "When targeting .net-framework there is no generic overload.")]
public static NugetConfigFile Load([NotNull] string filePath)
{
var configFile = new NugetConfigFile
Expand Down Expand Up @@ -238,7 +249,10 @@ public static NugetConfigFile Load([NotNull] string filePath)
var updateSearchBatchSizeString = add.Attribute(UpdateSearchBatchSizeAttributeName)?.Value;
if (!string.IsNullOrEmpty(updateSearchBatchSizeString))
{
sourceV3.UpdateSearchBatchSize = Mathf.Clamp(int.Parse(updateSearchBatchSizeString), 1, int.MaxValue);
sourceV3.UpdateSearchBatchSize = Mathf.Clamp(
int.Parse(updateSearchBatchSizeString, CultureInfo.InvariantCulture),
1,
int.MaxValue);
}

var supportsPackageIdSearchFilterString = add.Attribute(SupportsPackageIdSearchFilterAttributeName)?.Value;
Expand Down Expand Up @@ -318,7 +332,7 @@ public static NugetConfigFile Load([NotNull] string filePath)

if (string.Equals(key, "packageInstallLocation", StringComparison.OrdinalIgnoreCase))
{
configFile.InstallLocation = (PackageInstallLocation)Enum.Parse(typeof(PackageInstallLocation), value);
configFile.InstallLocation = (PackageInstallLocation)Enum.Parse(typeof(PackageInstallLocation), value, true);
}
else if (string.Equals(key, "repositoryPath", StringComparison.OrdinalIgnoreCase))
{
Expand Down Expand Up @@ -356,6 +370,10 @@ public static NugetConfigFile Load([NotNull] string filePath)
{
configFile.PreferNetStandardOverNetFramework = bool.Parse(value);
}
else if (string.Equals(key, KeepingPdbFilesConfigKey, StringComparison.OrdinalIgnoreCase))
{
configFile.KeepingPdbFiles = bool.Parse(value);
}
}

return configFile;
Expand Down Expand Up @@ -547,6 +565,14 @@ public void Save([NotNull] string filePath)
config.Add(addElement);
}

if (KeepingPdbFiles)
{
addElement = new XElement("add");
addElement.Add(new XAttribute("key", KeepingPdbFilesConfigKey));
addElement.Add(new XAttribute("value", KeepingPdbFiles.ToString().ToLowerInvariant()));
config.Add(addElement);
}

var configuration = new XElement("configuration");
configuration.Add(packageSources);
configuration.Add(disabledPackageSources);
Expand Down
25 changes: 25 additions & 0 deletions src/NuGetForUnity/Editor/Helper/PortableSymbolFileHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System.IO;

namespace NugetForUnity.Helper
{
/// <summary>
/// Provides methods for working with symbol files.
/// </summary>
internal static class PortableSymbolFileHelper
{
/// <summary>
/// Determines whether the specified PDB file is a portable symbol file.
/// </summary>
/// <param name="filePath">The path to the PDB file.</param>
/// <returns>
/// <c>true</c> if the specified PDB file is a portable symbol file; otherwise, <c>false</c>.
/// </returns>
public static bool IsPortableSymbolFile(string filePath)
{
using (var stream = File.OpenRead(filePath))
{
return stream.ReadByte() == 'B' && stream.ReadByte() == 'S' && stream.ReadByte() == 'J' && stream.ReadByte() == 'B';
}
}
}
}
11 changes: 11 additions & 0 deletions src/NuGetForUnity/Editor/Helper/PortableSymbolFileHelper.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/NuGetForUnity/Editor/InstalledPackagesManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ internal static List<INugetPackage> GetInstalledRootPackages()
return roots;
}

private static void AddPackageToInstalledInternal([NotNull] INugetPackage package, ref int manuallyInstalledPackagesNumber)
private static void AddPackageToInstalledInternal([NotNull] NugetPackageLocal package, ref int manuallyInstalledPackagesNumber)
{
var packages = InstalledPackagesDictionary;
if (!packages.ContainsKey(package.Id))
Expand Down
4 changes: 2 additions & 2 deletions src/NuGetForUnity/Editor/NugetPackageInstaller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ private static void WriteInitialExcludeAllPluginImporterConfig([NotNull] string
}

private static void TryExtractBestFrameworkSources(
[NotNull] [ItemNotNull] IReadOnlyDictionary<string, List<ZipArchiveEntry>> frameworks,
[NotNull] [ItemNotNull] Dictionary<string, List<ZipArchiveEntry>> frameworks,
[NotNull] string sourceDirName,
[NotNull] INugetPackage package,
[NotNull] PackageConfig packageConfig)
Expand Down Expand Up @@ -477,7 +477,7 @@ private static void TryExtractBestFrameworkSources(
}

private static void FillFrameworkZipEntries(
IDictionary<string, List<ZipArchiveEntry>> frameworkZipEntries,
Dictionary<string, List<ZipArchiveEntry>> frameworkZipEntries,
string framework,
ZipArchiveEntry entry)
{
Expand Down
18 changes: 15 additions & 3 deletions src/NuGetForUnity/Editor/PackageContentManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ internal static void CleanInstallationDirectory([NotNull] INugetPackageIdentifie
/// <returns>True if the file can be skipped, is not needed.</returns>
internal static bool ShouldSkipUnpackingOnPath([NotNull] string path, PackageInstallOperationResultEntry operationResultEntry)
{
if (path.EndsWith("/"))
if (path.EndsWith("/", StringComparison.Ordinal))
{
// We do not want to extract empty directory entries. If there are empty directories within the .nupkg, we
// expect them to have a file named '_._' in them that indicates that it should be extracted, usually as a
Expand Down Expand Up @@ -208,8 +208,9 @@ internal static bool ShouldSkipUnpackingOnPath([NotNull] string path, PackageIns
return true;
}

// Skip all PDB files since Unity uses Mono and requires MDB files, which causes it to output "missing MDB" errors
if (path.EndsWith(".pdb", StringComparison.OrdinalIgnoreCase))
// If not configured skip all PDB files. Unity uses Mono and requires MDB files or portable PDB files, else it produces "missing MDB" errors.
if (!ConfigurationManager.NugetConfigFile.KeepingPdbFiles &&
(path.EndsWith(".pdb", StringComparison.OrdinalIgnoreCase) || path.EndsWith(".pdb.meta", StringComparison.OrdinalIgnoreCase)))
{
return true;
}
Expand Down Expand Up @@ -325,6 +326,17 @@ internal static string ExtractPackageEntry([NotNull] ZipArchiveEntry entry, [Not

entry.ExtractToFile(filePath, true);

if (filePath.EndsWith(".pdb", StringComparison.OrdinalIgnoreCase) && !PortableSymbolFileHelper.IsPortableSymbolFile(filePath))
{
// Unity uses Mono and requires MDB files or portable PDB files, else it produces "missing MDB" errors.
new FileInfo(filePath).Delete();
new FileInfo($"{filePath}.meta").Delete();
NugetLogger.LogVerbose(
"The PDB file '{0}' doesn't have the new PDB file format that can be read by Unity so we delete it.",
filePath);
return null;
}

if (ConfigurationManager.NugetConfigFile.ReadOnlyPackageFiles)
{
var extractedFile = new FileInfo(filePath);
Expand Down
14 changes: 3 additions & 11 deletions src/NuGetForUnity/Editor/PackageSource/NugetPackageSourceV2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -393,10 +393,7 @@
}

#if TEST_GET_UPDATES_FALLBACK
private static void ComparePackageLists(
List<NugetPackage> updates,
List<NugetPackage> updatesReplacement,
string errorMessageToDisplayIfListsDoNotMatch)
private static void ComparePackageLists(List<NugetPackage> updates, List<NugetPackage> updatesReplacement, string errorMessageToDisplayIfListsDoNotMatch)
{
var matchingComparison = new StringBuilder();
var missingComparison = new StringBuilder();
Expand Down Expand Up @@ -426,12 +423,7 @@

if (missingComparison.Length > 0 || extraComparison.Length > 0)
{
Debug.LogWarningFormat(
"{0}\n{1}\n{2}\n{3}",
errorMessageToDisplayIfListsDoNotMatch,
matchingComparison,
missingComparison,
extraComparison);
Debug.LogWarningFormat("{0}\n{1}\n{2}\n{3}", errorMessageToDisplayIfListsDoNotMatch, matchingComparison, missingComparison, extraComparison);
}
}
#endif
Expand Down Expand Up @@ -528,7 +520,7 @@
return updates;
}

private void CopyIsManuallyInstalled(List<INugetPackage> newPackages, ICollection<INugetPackage> packagesToUpdate)
private static void CopyIsManuallyInstalled(List<INugetPackage> newPackages, ICollection<INugetPackage> packagesToUpdate)

Check warning on line 523 in src/NuGetForUnity/Editor/PackageSource/NugetPackageSourceV2.cs

View workflow job for this annotation

GitHub Actions / Pack .NET Core Global Tool (CLI) and PluginAPI

Check warning on line 523 in src/NuGetForUnity/Editor/PackageSource/NugetPackageSourceV2.cs

View workflow job for this annotation

GitHub Actions / Pack .NET Core Global Tool (CLI) and PluginAPI

Check warning on line 523 in src/NuGetForUnity/Editor/PackageSource/NugetPackageSourceV2.cs

View workflow job for this annotation

GitHub Actions / Pack .NET Core Global Tool (CLI) and PluginAPI

{
foreach (var newPackage in newPackages)
{
Expand Down
22 changes: 11 additions & 11 deletions src/NuGetForUnity/Editor/PackageSource/NugetPackageSourceV3.cs
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,17 @@ public Task<List<NugetFrameworkGroup>> GetPackageDetailsAsync(
return ApiClient.GetPackageDetailsAsync(this, package, cancellationToken);
}

private static void CopyIsManuallyInstalled(List<INugetPackage> newPackages, ICollection<INugetPackage> packagesToUpdate)
{
foreach (var newPackage in newPackages)
{
newPackage.IsManuallyInstalled =
packagesToUpdate.FirstOrDefault(packageToUpdate => packageToUpdate.Id.Equals(newPackage.Id, StringComparison.OrdinalIgnoreCase))
?.IsManuallyInstalled ??
false;
}
}

[NotNull]
private NugetApiClientV3 InitializeApiClient()
{
Expand All @@ -318,16 +329,5 @@ private NugetApiClientV3 InitializeApiClient()
ApiClientCache.Add(SavedPath, apiClient);
return apiClient;
}

private void CopyIsManuallyInstalled(List<INugetPackage> newPackages, ICollection<INugetPackage> packagesToUpdate)
{
foreach (var newPackage in newPackages)
{
newPackage.IsManuallyInstalled =
packagesToUpdate.FirstOrDefault(packageToUpdate => packageToUpdate.Id.Equals(newPackage.Id, StringComparison.OrdinalIgnoreCase))
?.IsManuallyInstalled ??
false;
}
}
}
}
19 changes: 18 additions & 1 deletion src/NuGetForUnity/Editor/Ui/NugetPreferences.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ public class NugetPreferences : SettingsProvider

private const float LabelPading = 5;

private static readonly string[] SearchKeywords = { "NuGet", "Packages" };

private readonly GUIContent deleteX = new GUIContent("\u2716");

private readonly GUIContent downArrow = new GUIContent("\u25bc");
Expand Down Expand Up @@ -79,8 +81,12 @@ public class NugetPreferences : SettingsProvider
/// Initializes a new instance of the <see cref="NugetPreferences" /> class.
/// Path of packages.config file is checked here as well in case it was manually changed.
/// </summary>
[SuppressMessage(
"Usage",
"CA2249:Consider using 'string.Contains' instead of 'string.IndexOf'",
Justification = ".Net Framework doesn't have a string contains that is case insensitive.")]
private NugetPreferences()
: base(MenuItemLocation, SettingsScope.Project, new[] { "NuGet", "Packages" })
: base(MenuItemLocation, SettingsScope.Project, SearchKeywords)
{
shouldShowPackagesConfigPathWarning = ConfigurationManager.NugetConfigFile.InstallLocation == PackageInstallLocation.CustomWithinAssets &&
!UnityPathHelper.IsPathInAssets(ConfigurationManager.NugetConfigFile.PackagesConfigDirectoryPath);
Expand Down Expand Up @@ -129,6 +135,17 @@ public override void OnGUI([CanBeNull] string searchContext)
ConfigurationManager.NugetConfigFile.InstallFromCache = installFromCache;
}

var keepingPdbFiles = EditorGUILayout.Toggle(
new GUIContent(
"Keep PDB Files",
"Do not delete PDB files included in a NuGet package if they can be read by Unity (have the new portable PDB format)."),
ConfigurationManager.NugetConfigFile.KeepingPdbFiles);
if (keepingPdbFiles != ConfigurationManager.NugetConfigFile.KeepingPdbFiles)
{
preferencesChangedThisFrame = true;
ConfigurationManager.NugetConfigFile.KeepingPdbFiles = keepingPdbFiles;
}

var readOnlyPackageFiles = EditorGUILayout.Toggle("Read-Only Package Files", ConfigurationManager.NugetConfigFile.ReadOnlyPackageFiles);
if (readOnlyPackageFiles != ConfigurationManager.NugetConfigFile.ReadOnlyPackageFiles)
{
Expand Down
Loading