Files
Orchard/src/Orchard.Web/Modules/Orchard.Packaging/Services/PackageInstaller.cs

128 lines
5.8 KiB
C#

using System;
using System.IO;
using NuGet;
using Orchard.Environment.Extensions;
using Orchard.FileSystems.AppData;
using Orchard.Localization;
using Orchard.UI.Notify;
using NuGetPackageManager = NuGet.PackageManager;
namespace Orchard.Packaging.Services {
[OrchardFeature("PackagingServices")]
public class PackageInstaller : IPackageInstaller {
private const string PackagesPath = "packages";
private readonly INotifier _notifier;
private readonly IExtensionManager _extensionManager;
private readonly IAppDataFolderRoot _appDataFolderRoot;
public PackageInstaller(INotifier notifier,
IExtensionManager extensionManager,
IAppDataFolderRoot appDataFolderRoot) {
_notifier = notifier;
_extensionManager = extensionManager;
_appDataFolderRoot = appDataFolderRoot;
T = NullLocalizer.Instance;
}
public Localizer T { get; set; }
public PackageInfo Install(string packageId, string version, string location, string applicationPath) {
// instantiates the appropriate package repository
IPackageRepository packageRepository = PackageRepositoryFactory.Default.CreateRepository(new PackageSource(location, "Default"));
// gets an IPackage instance from the repository
var packageVersion = String.IsNullOrEmpty(version) ? null : new Version(version);
var package = packageRepository.FindPackage(packageId, packageVersion);
if (package == null)
{
throw new ArgumentException(T("The specified package could not be found, id:{0} version:{1}", packageId, String.IsNullOrEmpty(version) ? T("No version").Text : version).Text);
}
return Install(package, packageRepository, location, applicationPath);
}
public PackageInfo Install(IPackage package, string location, string applicationPath) {
// instantiates the appropriate package repository
IPackageRepository packageRepository = PackageRepositoryFactory.Default.CreateRepository(new PackageSource(location, "Default"));
return Install(package, packageRepository, location, applicationPath);
}
protected PackageInfo Install(IPackage package, IPackageRepository packageRepository, string location, string applicationPath) {
// this logger is used to render NuGet's log on the notifier
var logger = new NugetLogger(_notifier);
bool installed = false;
// if we can access the parent directory, and the solution is inside, NuGet-install the package here
var installedPackagesPath = Path.Combine(_appDataFolderRoot.RootFolder, PackagesPath);
try
{
var packageManager = new NuGetPackageManager(
packageRepository,
new DefaultPackagePathResolver(location),
new PhysicalFileSystem(installedPackagesPath) { Logger = logger }
) { Logger = logger };
packageManager.InstallPackage(package, ignoreDependencies: true);
installed = true;
}
catch
{
// installing the package in the appdata folder failed
}
// if the package got installed successfully, use it, otherwise use the previous repository
var sourceRepository = installed
? new LocalPackageRepository(installedPackagesPath)
: packageRepository;
var project = new FileBasedProjectSystem(applicationPath) { Logger = logger };
var projectManager = new ProjectManager(
sourceRepository, // source repository for the package to install
new DefaultPackagePathResolver(applicationPath),
project,
new ExtensionReferenceRepository(project, sourceRepository, _extensionManager)
) { Logger = logger };
// add the package to the project
projectManager.AddPackageReference(package.Id, package.Version);
return new PackageInfo
{
ExtensionName = package.Title ?? package.Id,
ExtensionVersion = package.Version.ToString(),
ExtensionType = package.Id.StartsWith("Orchard.Theme") ? "Theme" : "Module",
ExtensionPath = applicationPath
};
}
public void Uninstall(string packageId, string applicationPath) {
// this logger is used to render NuGet's log on the notifier
var logger = new NugetLogger(_notifier);
var installedPackagesPath = Path.Combine(_appDataFolderRoot.RootFolder, PackagesPath);
var sourcePackageRepository = new LocalPackageRepository(installedPackagesPath);
var project = new FileBasedProjectSystem(applicationPath) { Logger = logger };
var projectManager = new ProjectManager(
sourcePackageRepository,
new DefaultPackagePathResolver(installedPackagesPath),
project,
new ExtensionReferenceRepository(project, sourcePackageRepository, _extensionManager)
) { Logger = logger };
// add the package to the project
projectManager.RemovePackageReference(packageId);
var packageManager = new NuGetPackageManager(
sourcePackageRepository,
new DefaultPackagePathResolver(applicationPath),
new PhysicalFileSystem(installedPackagesPath) { Logger = logger }
) { Logger = logger };
packageManager.UninstallPackage(packageId);
}
}
}