Skip to content

Commit

Permalink
Refactor package operations into common extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
glopesdev committed Sep 3, 2024
1 parent f76ff32 commit c2071ca
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 75 deletions.
28 changes: 19 additions & 9 deletions Bonsai.Configuration/Bootstrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace Bonsai.Configuration
Expand All @@ -29,9 +30,9 @@ public LicenseAwarePackageManager PackageManager
get { return packageManager; }
}

protected virtual async Task RunPackageOperationAsync(Func<Task> operationFactory)
protected virtual async Task RunPackageOperationAsync(Func<CancellationToken, Task> operationFactory, CancellationToken cancellationToken)
{
await operationFactory();
await operationFactory(cancellationToken);
}

static NuGetVersion ParseVersion(string version)
Expand All @@ -52,7 +53,8 @@ public async Task RunAsync(
NuGetFramework projectFramework,
PackageConfiguration packageConfiguration,
string bootstrapperPath,
PackageIdentity bootstrapperPackage)
PackageIdentity bootstrapperPackage,
CancellationToken cancellationToken = default)
{
const string OldExtension = ".old";
var backupExePath = bootstrapperPath + OldExtension;
Expand All @@ -65,7 +67,7 @@ public async Task RunAsync(
var missingPackages = GetMissingPackages(packageConfiguration, packageManager.LocalRepository).ToList();
if (missingPackages.Count > 0)
{
async Task RestoreMissingPackages()
async Task RestoreMissingPackages(CancellationToken cancellationToken)
{
using var monitor = new PackageConfigurationUpdater(
projectFramework,
Expand All @@ -75,31 +77,39 @@ async Task RestoreMissingPackages()
bootstrapperPackage);
foreach (var package in missingPackages)
{
await packageManager.StartRestorePackage(package.Id, ParseVersion(package.Version), projectFramework);
await packageManager.RestorePackageAsync(
package.Id,
ParseVersion(package.Version),
projectFramework,
cancellationToken);
}
};

packageManager.RestorePackages = true;
try { await RunPackageOperationAsync(RestoreMissingPackages); }
try { await RunPackageOperationAsync(RestoreMissingPackages, cancellationToken); }
finally { packageManager.RestorePackages = false; }
}

var editorPackage = packageManager.LocalRepository.FindLocalPackage(bootstrapperPackage.Id);
if (editorPackage == null || editorPackage.Identity.Version < bootstrapperPackage.Version)
{
async Task RestoreEditorPackage()
async Task RestoreEditorPackage(CancellationToken cancellationToken)
{
using var monitor = new PackageConfigurationUpdater(
projectFramework,
packageConfiguration,
packageManager,
bootstrapperPath,
bootstrapperPackage);
var package = await packageManager.StartInstallPackage(bootstrapperPackage.Id, bootstrapperPackage.Version, projectFramework);
var package = await packageManager.InstallPackageAsync(
bootstrapperPackage.Id,
bootstrapperPackage.Version,
projectFramework,
cancellationToken);
editorPackage = packageManager.LocalRepository.GetLocalPackage(package.GetIdentity());
};

await RunPackageOperationAsync(RestoreEditorPackage);
await RunPackageOperationAsync(RestoreEditorPackage, cancellationToken);
}
}

Expand Down
29 changes: 8 additions & 21 deletions Bonsai.Configuration/PackageConfigurationUpdater.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,8 @@ namespace Bonsai.Configuration
{
public class PackageConfigurationUpdater : IDisposable
{
const string PackageTagFilter = "Bonsai";
const string GalleryDirectory = "Gallery";
const string ExtensionsDirectory = "Extensions";
const string BinDirectory = "bin";
const string DebugDirectory = "debug";
const string BonsaiExtension = ".bonsai";
const string AssemblyExtension = ".dll";
const string OldExtension = ".old";

Expand Down Expand Up @@ -55,7 +51,7 @@ public PackageConfigurationUpdater(NuGetFramework projectFramework, PackageConfi
configurationPlugin = new PackageConfigurationPlugin(this);
packageManager.PackageManagerPlugins.Add(configurationPlugin);

var galleryPath = Path.Combine(bootstrapperDirectory, GalleryDirectory);
var galleryPath = Path.Combine(bootstrapperDirectory, Constants.GalleryDirectory);
var galleryPackageSource = new PackageSource(galleryPath);
galleryRepository = new SourceRepository(galleryPackageSource, Repository.Provider.GetCoreV3());
NormalizePathSeparators(packageConfiguration);
Expand Down Expand Up @@ -92,12 +88,6 @@ static void NormalizePathSeparators(PackageConfiguration configuration)
}
}

static bool IsTaggedPackage(PackageReaderBase package)
{
var tags = package.NuspecReader.GetTags();
return tags != null && tags.Contains(PackageTagFilter);
}

static ProcessorArchitecture ResolveArchitectureAlias(string name)
{
switch (name)
Expand Down Expand Up @@ -410,10 +400,7 @@ public PackageConfigurationPlugin(PackageConfigurationUpdater owner)

public override async Task<bool> OnPackageInstallingAsync(PackageIdentity package, NuGetFramework projectFramework, PackageReaderBase packageReader, string installPath)
{
var entryPoint = package.Id + BonsaiExtension;
var nearestFrameworkGroup = packageReader.GetContentItems().GetNearest(projectFramework);
var executablePackage = nearestFrameworkGroup?.Items.Any(file => PathUtility.GetRelativePath(ContentFolder, file) == entryPoint);
if (executablePackage.GetValueOrDefault())
if (packageReader.IsExecutablePackage(package, projectFramework))
{
var packageFolder = Path.GetDirectoryName(packageReader.GetNuspecFile());
var resolver = new VersionFolderPathResolver(packageFolder, isLowercase: false);
Expand Down Expand Up @@ -461,15 +448,15 @@ public override async Task<bool> OnPackageInstallingAsync(PackageIdentity packag
public override Task OnPackageInstalledAsync(PackageIdentity package, NuGetFramework projectFramework, PackageReaderBase packageReader, string installPath)
{
var packageConfiguration = Owner.packageConfiguration;
var taggedPackage = IsTaggedPackage(packageReader);
var addReferences = packageReader.IsLibraryPackage();
var relativePath = Owner.GetRelativePath(installPath);
if (!packageConfiguration.Packages.Contains(package.Id))
{
packageConfiguration.Packages.Add(package.Id, package.Version.ToString());
}
else packageConfiguration.Packages[package.Id].Version = package.Version.ToString();

Owner.AddContentFolders(installPath, ExtensionsDirectory);
Owner.AddContentFolders(installPath, Constants.ExtensionsDirectory);
Owner.RegisterLibraryFolders(packageReader, relativePath);
Owner.RegisterAssemblyLocations(packageReader, installPath, relativePath, false);
if (IsRunningOnMono) Owner.AddAssemblyConfigFiles(packageReader, installPath);
Expand All @@ -494,7 +481,7 @@ public override Task OnPackageInstalledAsync(PackageIdentity package, NuGetFrame
// resolution is OS-specific and architecture-specific and should not be versioned together
// with the package dependency graph.
var assemblyLocations = GetCompatibleAssemblyReferences(projectFramework, packageReader);
Owner.RegisterAssemblyLocations(assemblyLocations, installPath, relativePath, taggedPackage);
Owner.RegisterAssemblyLocations(assemblyLocations, installPath, relativePath, addReferences);
packageConfiguration.Save();

if (package.Id == Owner.bootstrapperPackageId && package.Version > Owner.bootstrapperVersion)
Expand All @@ -516,11 +503,11 @@ public override Task OnPackageInstalledAsync(PackageIdentity package, NuGetFrame

public override async Task OnPackageUninstalledAsync(PackageIdentity package, NuGetFramework projectFramework, PackageReaderBase packageReader, string installPath)
{
var taggedPackage = IsTaggedPackage(packageReader);
var removeReferences = packageReader.IsLibraryPackage();
var relativePath = Owner.GetRelativePath(installPath);
Owner.packageConfiguration.Packages.Remove(package.Id);

Owner.RemoveContentFolders(packageReader, installPath, ExtensionsDirectory);
Owner.RemoveContentFolders(packageReader, installPath, Constants.ExtensionsDirectory);
Owner.RemoveLibraryFolders(packageReader, relativePath);
Owner.RemoveAssemblyLocations(packageReader, relativePath, false);
if (IsRunningOnMono) Owner.RemoveAssemblyConfigFiles(packageReader, installPath);
Expand All @@ -541,7 +528,7 @@ public override async Task OnPackageUninstalledAsync(PackageIdentity package, Nu
}

var assemblyLocations = GetCompatibleAssemblyReferences(projectFramework, packageReader);
Owner.RemoveAssemblyLocations(assemblyLocations, relativePath, taggedPackage);
Owner.RemoveAssemblyLocations(assemblyLocations, relativePath, removeReferences);
Owner.packageConfiguration.Save();

if (pivots.Length > 0)
Expand Down
2 changes: 1 addition & 1 deletion Bonsai.NuGet.Design/GalleryDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public override Task<bool> OnPackageInstallingAsync(PackageIdentity package, NuG
{
if (PackageIdentityComparer.Default.Equals(package, Owner.targetPackage))
{
Owner.InstallPath = PackageHelper.InstallExecutablePackage(package, projectFramework, packageReader, Owner.targetPath);
Owner.InstallPath = packageReader.InstallExecutablePackage(package, projectFramework, Owner.targetPath);
Owner.DialogResult = DialogResult.OK;
}

Expand Down
4 changes: 2 additions & 2 deletions Bonsai.NuGet.Design/PackageManagerDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ public ExecutablePackagePlugin(PackageManagerDialog owner)

public override Task<bool> OnPackageInstallingAsync(PackageIdentity package, NuGetFramework projectFramework, PackageReaderBase packageReader, string installPath)
{
if (PackageHelper.IsExecutablePackage(package, projectFramework, packageReader))
if (packageReader.IsExecutablePackage(package, projectFramework))
{
Owner.Invoke((Action)(() =>
{
Expand All @@ -204,7 +204,7 @@ public override Task<bool> OnPackageInstallingAsync(PackageIdentity package, NuG
if (Owner.saveFolderDialog.ShowDialog(Owner) == DialogResult.OK)
{
var targetPath = Owner.saveFolderDialog.FileName;
Owner.InstallPath = PackageHelper.InstallExecutablePackage(package, projectFramework, packageReader, targetPath);
Owner.InstallPath = packageReader.InstallExecutablePackage(package, projectFramework, targetPath);
Owner.DialogResult = DialogResult.OK;
}
}
Expand Down
1 change: 1 addition & 0 deletions Bonsai.NuGet/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ public static class Constants
{
public const string BonsaiDirectory = "Bonsai";
public const string GalleryDirectory = "Gallery";
public const string ExtensionsDirectory = "Extensions";
public const string BonsaiExtension = ".bonsai";
public const string LayoutExtension = ".layout";
public const string LibraryPackageType = "BonsaiLibrary";
Expand Down
88 changes: 64 additions & 24 deletions Bonsai.NuGet/PackageHelper.cs → Bonsai.NuGet/PackageExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
Expand All @@ -9,23 +10,63 @@
using NuGet.Frameworks;
using NuGet.Packaging;
using NuGet.Packaging.Core;
using NuGet.Protocol;
using NuGet.Versioning;

namespace Bonsai.NuGet
{
public static class PackageHelper
public static class PackageExtensions
{
const string PackageTagFilter = "Bonsai";
public static readonly string ContentFolder = PathUtility.EnsureTrailingSlash(PackagingConstants.Folders.Content);

public static bool IsExecutablePackage(PackageIdentity package, NuGetFramework projectFramework, PackageReaderBase packageReader)
public static bool IsPackageType(this LocalPackageInfo packageInfo, string typeName)
{
var entryPoint = package.Id + Constants.BonsaiExtension;
return packageInfo.Nuspec.IsPackageType(typeName);
}

public static bool IsPackageType(this PackageReaderBase packageReader, string typeName)
{
return packageReader.NuspecReader.IsPackageType(typeName);
}

public static bool IsPackageType(this NuspecReader reader, string typeName)
{
return reader.GetPackageTypes().IsPackageType(typeName);
}

public static bool IsPackageType(this IReadOnlyList<PackageType> packageTypes, string typeName)
{
if (packageTypes.Count == 0
&& PackageType.PackageTypeNameComparer.Equals(typeName, PackageType.Dependency.Name))
{
return true;
}

return packageTypes.Any(type => PackageType.PackageTypeNameComparer.Equals(type.Name, typeName));
}

public static bool IsLibraryPackage(this PackageReaderBase packageReader)
{
return packageReader.IsPackageType(Constants.LibraryPackageType)
|| packageReader.NuspecReader.GetTags()?.Contains(PackageTagFilter) is true;
}

public static bool IsGalleryPackage(this PackageReaderBase packageReader)
{
return packageReader.IsPackageType(Constants.GalleryPackageType)
|| packageReader.NuspecReader.GetTags()?.Contains(PackageTagFilter) is true;
}

public static bool IsExecutablePackage(this PackageReaderBase packageReader, PackageIdentity identity, NuGetFramework projectFramework)
{
var entryPoint = identity.Id + Constants.BonsaiExtension;
var nearestFrameworkGroup = packageReader.GetContentItems().GetNearest(projectFramework);
var executablePackage = nearestFrameworkGroup?.Items.Any(file => PathUtility.GetRelativePath(PackageHelper.ContentFolder, file) == entryPoint);
return executablePackage.GetValueOrDefault();
var executablePackage = nearestFrameworkGroup?.Items.Any(file => PathUtility.GetRelativePath(ContentFolder, file) == entryPoint);
return IsGalleryPackage(packageReader) && executablePackage.GetValueOrDefault();
}

public static string InstallExecutablePackage(PackageIdentity package, NuGetFramework projectFramework, PackageReaderBase packageReader, string targetPath)
public static string InstallExecutablePackage(this PackageReaderBase packageReader, PackageIdentity package, NuGetFramework projectFramework, string targetPath)
{
var targetId = Path.GetFileName(targetPath);
var targetEntryPoint = targetId + Constants.BonsaiExtension;
Expand Down Expand Up @@ -71,30 +112,29 @@ public static string InstallExecutablePackage(PackageIdentity package, NuGetFram
return effectiveEntryPoint;
}

public static async Task StartInstallPackage(this IPackageManager packageManager, PackageIdentity package, NuGetFramework projectFramework)
{
if (package == null)
{
throw new ArgumentNullException(nameof(package));
}

packageManager.Logger.LogInformation(string.Format(Resources.InstallPackageVersion, package.Id, package.Version));
await packageManager.InstallPackageAsync(package, projectFramework, ignoreDependencies: false, CancellationToken.None);
}

public static async Task<PackageReaderBase> StartInstallPackage(this IPackageManager packageManager, string packageId, NuGetVersion version, NuGetFramework projectFramework)
public static async Task<PackageReaderBase> InstallPackageAsync(
this IPackageManager packageManager,
string packageId,
NuGetVersion version,
NuGetFramework projectFramework,
CancellationToken cancellationToken = default)
{
var logMessage = version == null ? Resources.InstallPackageLatestVersion : Resources.InstallPackageVersion;
packageManager.Logger.LogInformation(string.Format(logMessage, packageId, version));
var package = new PackageIdentity(packageId, version);
return await packageManager.InstallPackageAsync(package, projectFramework, ignoreDependencies: false, CancellationToken.None);
var logMessage = package.Version == null ? Resources.InstallPackageLatestVersion : Resources.InstallPackageVersion;
packageManager.Logger.LogInformation(string.Format(logMessage, package.Id, package.Version));
return await packageManager.InstallPackageAsync(package, projectFramework, ignoreDependencies: false, cancellationToken);
}

public static async Task<PackageReaderBase> StartRestorePackage(this IPackageManager packageManager, string packageId, NuGetVersion version, NuGetFramework projectFramework)
public static async Task<PackageReaderBase> RestorePackageAsync(
this IPackageManager packageManager,
string packageId,
NuGetVersion version,
NuGetFramework projectFramework,
CancellationToken cancellationToken = default)
{
packageManager.Logger.LogInformation(string.Format(Resources.RestorePackageVersion, packageId, version));
var package = new PackageIdentity(packageId, version);
return await packageManager.InstallPackageAsync(package, projectFramework, ignoreDependencies: true, CancellationToken.None);
packageManager.Logger.LogInformation(string.Format(Resources.RestorePackageVersion, packageId, version));
return await packageManager.InstallPackageAsync(package, projectFramework, ignoreDependencies: true, cancellationToken);
}
}
}
Loading

0 comments on commit c2071ca

Please sign in to comment.