Skip to content

Various fixes and improvements #582

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

Merged
merged 10 commits into from
Oct 18, 2023
16 changes: 11 additions & 5 deletions src/NuGetForUnity/Editor/InstalledPackagesManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -207,10 +207,16 @@ internal static void UpdateInstalledPackages()
}
}

// if the source code & assets for a package are pulled directly into the project (ex: via a symlink/junction) it should have a .nuspec defining the package
var nuspecFiles = Directory.GetFiles(ConfigurationManager.NugetConfigFile.RepositoryPath, "*.nuspec", SearchOption.AllDirectories);
foreach (var nuspecFile in nuspecFiles)
{
var directoryName = Path.GetFileName(Path.GetDirectoryName(nuspecFile));
if (!string.IsNullOrEmpty(directoryName) && directoryName[0] == '.')
{
// Skip nuspec files that are in directories starting with '.' since those are considered hidden and should be ignored.
continue;
}

var package = NugetPackageLocal.FromNuspec(
NuspecFile.Load(nuspecFile),
new NugetPackageSourceLocal(
Expand Down Expand Up @@ -249,9 +255,9 @@ internal static bool RemoveUnnecessaryPackages()
foreach (var folder in directories)
{
var folderName = Path.GetFileName(folder);
if (folderName.Equals(".svn", StringComparison.OrdinalIgnoreCase))
if (folderName.StartsWith(".", StringComparison.Ordinal))
{
// ignore folder required by SVN tool
// ignore folders whose name starts with a dot because they are considered hidden
continue;
}

Expand Down Expand Up @@ -322,8 +328,8 @@ internal static List<INugetPackage> GetInstalledRootPackages()
// remove a package as a root if another package is dependent on it
foreach (var package in InstalledPackages)
{
var frameworkGroup = TargetFrameworkResolver.GetBestDependencyFrameworkGroupForCurrentSettings(package);
foreach (var dependency in frameworkGroup.Dependencies)
var frameworkDependencies = package.GetFrameworkMatchingDependencies();
foreach (var dependency in frameworkDependencies)
{
roots.RemoveAll(p => p.Id == dependency.Id);
}
Expand Down
6 changes: 6 additions & 0 deletions src/NuGetForUnity/Editor/Models/INugetPackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,5 +113,11 @@ public interface INugetPackage : INugetPackageIdentifier
/// </summary>
/// <param name="outputFilePath">Path where the downloaded file is placed.</param>
void DownloadNupkgToFile([NotNull] string outputFilePath);

/// <summary>
/// Gets the list of dependencies for the framework that best matches what is available in Unity.
/// </summary>
/// <returns>List of dependencies.</returns>
IReadOnlyList<INugetPackageIdentifier> GetFrameworkMatchingDependencies();
}
}
4 changes: 2 additions & 2 deletions src/NuGetForUnity/Editor/Models/NugetFrameworkGroup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public class NugetFrameworkGroup
public NugetFrameworkGroup()
{
TargetFramework = string.Empty;
Dependencies = new List<NugetPackageIdentifier>();
Dependencies = new List<INugetPackageIdentifier>();
}

/// <summary>
Expand All @@ -48,6 +48,6 @@ public NugetFrameworkGroup()
[NotNull]
[field: SerializeField]
[SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "Setter required for serialization.")]
public List<NugetPackageIdentifier> Dependencies { get; set; }
public List<INugetPackageIdentifier> Dependencies { get; set; }
}
}
17 changes: 16 additions & 1 deletion src/NuGetForUnity/Editor/Models/NugetPackageV2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ internal sealed class NugetPackageV2 : NugetPackageV2Base
[SerializeField]
private NugetPackageSourceV2 packageSourceV2;

[CanBeNull]
[SerializeField]
private List<NugetPackageVersion> versions;

/// <summary>
/// Initializes a new instance of the <see cref="NugetPackageV2" /> class.
/// </summary>
Expand All @@ -29,7 +33,18 @@ public NugetPackageV2([NotNull] NugetPackageSourceV2 packageSourceV2)
public override INugetPackageSource PackageSource => packageSourceV2;

/// <inheritdoc />
public override List<NugetPackageVersion> Versions => new List<NugetPackageVersion> { PackageVersion };
public override List<NugetPackageVersion> Versions
{
get
{
if (versions == null)
{
versions = new List<NugetPackageVersion> { PackageVersion };
}

return versions;
}
}

/// <summary>
/// Creates a new <see cref="NugetPackageLocal" /> from the given <see cref="NuspecFile" />.
Expand Down
15 changes: 15 additions & 0 deletions src/NuGetForUnity/Editor/Models/NugetPackageV2Base.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ internal abstract class NugetPackageV2Base : NugetPackageIdentifier, INugetPacka
[NonSerialized]
private Task<Texture2D> iconTask;

[ItemNotNull]
[CanBeNull]
[NonSerialized]
private List<INugetPackageIdentifier> frameworkMatchingDependencies;

/// <summary>
/// Gets or sets the URL for the location of the actual (.nupkg) NuGet package.
/// </summary>
Expand Down Expand Up @@ -146,6 +151,16 @@ public void DownloadNupkgToFile(string outputFilePath)
PackageSource.DownloadNupkgToFile(this, outputFilePath, DownloadUrl);
}

public IReadOnlyList<INugetPackageIdentifier> GetFrameworkMatchingDependencies()
{
if (frameworkMatchingDependencies == null)
{
frameworkMatchingDependencies = TargetFrameworkResolver.GetBestDependencyFrameworkGroupForCurrentSettings(Dependencies).Dependencies;
}

return frameworkMatchingDependencies;
}

/// <inheritdoc />
public void OnBeforeSerialize()
{
Expand Down
15 changes: 15 additions & 0 deletions src/NuGetForUnity/Editor/Models/NugetPackageV3.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ internal sealed class NugetPackageV3 : NugetPackageIdentifier, INugetPackage, IS
[NotNull]
private NugetPackageSourceV3 packageSource;

[ItemNotNull]
[CanBeNull]
[NonSerialized]
private IReadOnlyList<INugetPackageIdentifier> frameworkMatchingDependencies;

/// <summary>
/// Initializes a new instance of the <see cref="NugetPackageV3" /> class.
/// </summary>
Expand Down Expand Up @@ -204,6 +209,16 @@ public void DownloadNupkgToFile(string outputFilePath)
packageSource.DownloadNupkgToFile(this, outputFilePath, null);
}

public IReadOnlyList<INugetPackageIdentifier> GetFrameworkMatchingDependencies()
{
if (frameworkMatchingDependencies == null)
{
frameworkMatchingDependencies = TargetFrameworkResolver.GetBestDependencyFrameworkGroupForCurrentSettings(Dependencies).Dependencies;
}

return frameworkMatchingDependencies;
}

/// <inheritdoc />
public void OnBeforeSerialize()
{
Expand Down
29 changes: 9 additions & 20 deletions src/NuGetForUnity/Editor/NugetPackageInstaller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ private static bool Install([NotNull] INugetPackage package, bool refreshAssets,
installedPackage.Version,
package.Version,
package.Version);
return NugetPackageUpdater.Update(installedPackage, package, false);
return NugetPackageUpdater.Update(installedPackage, package, refreshAssets);
}

if (comparisonResult > 0)
Expand All @@ -84,7 +84,7 @@ private static bool Install([NotNull] INugetPackage package, bool refreshAssets,
installedPackage.Id,
installedPackage.Version,
package.Version);
return NugetPackageUpdater.Update(installedPackage, package, false);
return NugetPackageUpdater.Update(installedPackage, package, refreshAssets);
}

NugetLogger.LogVerbose(
Expand All @@ -105,10 +105,7 @@ private static bool Install([NotNull] INugetPackage package, bool refreshAssets,
{
NugetLogger.LogVerbose("Installing: {0} {1}", package.Id, package.Version);

if (refreshAssets)
{
EditorUtility.DisplayProgressBar($"Installing {package.Id} {package.Version}", "Installing Dependencies", 0.1f);
}
EditorUtility.DisplayProgressBar($"Installing {package.Id} {package.Version}", "Installing Dependencies", 0.1f);

if (!isSlimRestoreInstall)
{
Expand All @@ -131,7 +128,7 @@ private static bool Install([NotNull] INugetPackage package, bool refreshAssets,
foreach (var dependency in frameworkGroup.Dependencies)
{
NugetLogger.LogVerbose("Installing Dependency: {0} {1}", dependency.Id, dependency.Version);
var installed = InstallIdentifier(dependency, refreshAssets);
var installed = InstallIdentifier(dependency, false);
if (!installed)
{
throw new InvalidOperationException($"Failed to install dependency: {dependency.Id} {dependency.Version}.");
Expand All @@ -152,18 +149,12 @@ private static bool Install([NotNull] INugetPackage package, bool refreshAssets,
{
NugetLogger.LogVerbose("Downloading package {0} {1}", package.Id, package.Version);

if (refreshAssets)
{
EditorUtility.DisplayProgressBar($"Installing {package.Id} {package.Version}", "Downloading Package", 0.3f);
}
EditorUtility.DisplayProgressBar($"Installing {package.Id} {package.Version}", "Downloading Package", 0.3f);

package.DownloadNupkgToFile(cachedPackagePath);
}

if (refreshAssets)
{
EditorUtility.DisplayProgressBar($"Installing {package.Id} {package.Version}", "Extracting Package", 0.6f);
}
EditorUtility.DisplayProgressBar($"Installing {package.Id} {package.Version}", "Extracting Package", 0.6f);

if (File.Exists(cachedPackagePath))
{
Expand Down Expand Up @@ -281,10 +272,7 @@ private static bool Install([NotNull] INugetPackage package, bool refreshAssets,
Debug.LogErrorFormat("File not found: {0}", cachedPackagePath);
}

if (refreshAssets)
{
EditorUtility.DisplayProgressBar($"Installing {package.Id} {package.Version}", "Cleaning Package", 0.9f);
}
EditorUtility.DisplayProgressBar($"Installing {package.Id} {package.Version}", "Cleaning Package", 0.9f);

// clean
PackageContentManager.CleanInstallationDirectory(package);
Expand All @@ -304,8 +292,9 @@ private static bool Install([NotNull] INugetPackage package, bool refreshAssets,
{
EditorUtility.DisplayProgressBar($"Installing {package.Id} {package.Version}", "Importing Package", 0.95f);
AssetDatabase.Refresh();
EditorUtility.ClearProgressBar();
}

EditorUtility.ClearProgressBar();
}
}

Expand Down
9 changes: 4 additions & 5 deletions src/NuGetForUnity/Editor/NugetPackageUninstaller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,16 @@ public static void Uninstall([NotNull] INugetPackageIdentifier package, bool ref
PackageContentManager.DeletePackageContentPackage(foundPackage);

// uninstall all non manually installed dependencies that are not a dependency of another installed package
var frameworkGroup = TargetFrameworkResolver.GetBestDependencyFrameworkGroupForCurrentSettings(foundPackage);
foreach (var dependency in frameworkGroup.Dependencies)
var frameworkDependencies = foundPackage.GetFrameworkMatchingDependencies();
foreach (var dependency in frameworkDependencies)
{
if (InstalledPackagesManager.GetManuallyInstalledFlagFromConfiguration(dependency.Id))
{
continue;
}

var hasMoreParents = InstalledPackagesManager.InstalledPackages
.Select(TargetFrameworkResolver.GetBestDependencyFrameworkGroupForCurrentSettings)
.Any(frameworkGrp => frameworkGrp.Dependencies.Any(dep => dep.Id == dependency.Id));
var hasMoreParents = InstalledPackagesManager.InstalledPackages.SelectMany(
installedPackage => installedPackage.GetFrameworkMatchingDependencies()).Any(dep => dep.Id == dependency.Id);

if (!hasMoreParents)
{
Expand Down
22 changes: 10 additions & 12 deletions src/NuGetForUnity/Editor/PackageRestorer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,16 @@ public static void Restore(bool slimRestore)

foreach (var package in packagesToInstall)
{
if (package != null)
{
EditorUtility.DisplayProgressBar(
"Restoring NuGet Packages",
$"Restoring {package.Id} {package.Version}",
currentProgress);
NugetLogger.LogVerbose("---Restoring {0} {1}", package.Id, package.Version);
NugetPackageInstaller.InstallIdentifier(
package,
isSlimRestoreInstall: slimRestore);
somethingChanged = true;
}
EditorUtility.DisplayProgressBar(
"Restoring NuGet Packages",
$"Restoring {package.Id} {package.Version}",
currentProgress);
NugetLogger.LogVerbose("---Restoring {0} {1}", package.Id, package.Version);
NugetPackageInstaller.InstallIdentifier(
package,
false,
slimRestore);
somethingChanged = true;

currentProgress += progressStep;
}
Expand Down
4 changes: 2 additions & 2 deletions src/NuGetForUnity/Editor/PackageSource/NugetApiClientV3.cs
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ public async Task<List<NugetFrameworkGroup>> GetPackageDetails(
return new NugetFrameworkGroup
{
Dependencies = dependencyGroup.dependencies.ConvertAll(
dependency => new NugetPackageIdentifier(
dependency => (INugetPackageIdentifier)new NugetPackageIdentifier(
dependency.id ??
throw new InvalidOperationException(
$"missing '{nameof(dependency.id)}' inside '{nameof(dependencyGroup.dependencies)}' for dependency group: '{dependencyGroup.targetFramework}'"),
Expand Down Expand Up @@ -321,7 +321,7 @@ private static List<INugetPackage> SearchResultToNugetPackages(List<SearchResult
}

var versions = item.versions.ConvertAll(searchVersion => new NugetPackageVersion(searchVersion.version));
versions.Sort();
versions.Sort((v1, v2) => v2.CompareTo(v1));
packages.Add(
new NugetPackageV3(
item.id,
Expand Down
57 changes: 52 additions & 5 deletions src/NuGetForUnity/Editor/PackageSource/NugetPackageSourceV2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
Expand Down Expand Up @@ -266,7 +267,7 @@ public List<INugetPackage> GetUpdates(
}

var url =
$"{ExpandedPath}GetUpdates()?packageIds='{packageIds}'&versions='{versions}'&includePrerelease={includePrerelease.ToString().ToLowerInvariant()}&targetFrameworks='{targetFrameworks}'&versionConstraints='{versionConstraints}'";
$"{ExpandedPath}GetUpdates()?packageIds='{packageIds}'&versions='{versions}'&includePrerelease={includePrerelease.ToString().ToLowerInvariant()}&targetFrameworks='{targetFrameworks}'&versionConstraints='{versionConstraints}'&includeAllVersions=true";

try
{
Expand All @@ -287,9 +288,6 @@ public List<INugetPackage> GetUpdates(
}
}

// sort alphabetically, then by version descending
updates.Sort();

#if TEST_GET_UPDATES_FALLBACK
// Enable this define in order to test that GetUpdatesFallback is working as intended. This tests that it returns the same set of packages
// that are returned by the GetUpdates API. Since GetUpdates isn't available when using a Visual Studio Team Services feed, the intention
Expand All @@ -299,7 +297,56 @@ public List<INugetPackage> GetUpdates(
ComparePackageLists(updates, updatesReplacement, "GetUpdatesFallback doesn't match GetUpdates API");
#endif

return updates;
if (updates.Count <= 1)
{
return updates;
}

// sort alphabetically, then by version ascending
updates.Sort();

var resultUpdates = new List<INugetPackage>();
var lastPackage = (NugetPackageV2Base)updates[0];
resultUpdates.Add(lastPackage);

var sb = new StringBuilder();
sb.Append(lastPackage.PackageVersion).Append(": ").Append(lastPackage.ReleaseNotes);
var lastReleaseNotes = lastPackage.ReleaseNotes;
for (var i = 1; i < updates.Count; i++)
{
var nextPackage = updates[i];
if (string.Equals(lastPackage.Id, nextPackage.Id, StringComparison.Ordinal))
{
lastPackage.Versions.Add(nextPackage.PackageVersion);
if (nextPackage.ReleaseNotes != null &&
(lastReleaseNotes == null || !string.Equals(lastReleaseNotes, nextPackage.ReleaseNotes, StringComparison.Ordinal)))
{
sb.Insert(0, "\n").Insert(0, nextPackage.ReleaseNotes).Insert(0, ": ").Insert(0, nextPackage.PackageVersion);
}

lastReleaseNotes = nextPackage.ReleaseNotes;

if (lastPackage.PackageVersion < nextPackage.PackageVersion)
{
lastPackage.PackageVersion = nextPackage.PackageVersion;
}
}
else
{
lastPackage.Versions.Reverse();
lastPackage.ReleaseNotes = sb.ToString();
lastPackage = (NugetPackageV2Base)nextPackage;
resultUpdates.Add(lastPackage);
sb.Clear();
sb.Append(lastPackage.PackageVersion).Append(": ").Append(lastPackage.ReleaseNotes);
lastReleaseNotes = lastPackage.ReleaseNotes;
}
}

lastPackage.Versions.Reverse();
lastPackage.ReleaseNotes = sb.ToString();

return resultUpdates;
}

/// <inheritdoc />
Expand Down
Loading