Updating packaging commands to handle solution-less applications

If the solution is not found, don't NuGet-Install the package, but still NuGet-AddReference
Uninstallation deletes the module if there is no solution folder
Creating a specific ReferenceRepository implementation to remove the packages.config dependency

--HG--
branch : dev
This commit is contained in:
Sébastien Ros
2010-11-11 23:19:23 -08:00
parent 1f3ddc98ed
commit 686a9e6f4d
5 changed files with 158 additions and 58 deletions

View File

@@ -8,8 +8,7 @@ using Orchard.UI.Notify;
namespace Orchard.Packaging.Commands { namespace Orchard.Packaging.Commands {
[OrchardFeature("Orchard.Packaging")] [OrchardFeature("Orchard.Packaging")]
public class PackagingCommands : DefaultOrchardCommandHandler { public class PackagingCommands : DefaultOrchardCommandHandler {
private static readonly string OrchardWebProj = HostingEnvironment.MapPath("~/Orchard.Web.csproj"); private static readonly string ApplicationPath = HostingEnvironment.MapPath("~/");
private const string CreatePackagePath = "CreatedPackages";
private readonly IPackageManager _packageManager; private readonly IPackageManager _packageManager;
private readonly INotifier _notifier; private readonly INotifier _notifier;
@@ -54,13 +53,7 @@ namespace Orchard.Packaging.Commands {
[CommandName("package install")] [CommandName("package install")]
[OrchardSwitches("Version")] [OrchardSwitches("Version")]
public void InstallPackage(string packageId, string location) { public void InstallPackage(string packageId, string location) {
var solutionFolder = GetSolutionFolder(); _packageManager.Install(packageId, Version, Path.GetFullPath(location), ApplicationPath);
if(solutionFolder == null) {
Context.Output.WriteLine(T("The project's location is not supported"));
}
_packageManager.Install(packageId, Version, Path.GetFullPath(location), solutionFolder);
foreach(var message in _notifier.List()) { foreach(var message in _notifier.List()) {
Context.Output.WriteLine(message.Message); Context.Output.WriteLine(message.Message);
@@ -70,21 +63,11 @@ namespace Orchard.Packaging.Commands {
[CommandHelp("package uninstall <packageId> \r\n\t" + "Uninstall a module or a theme.")] [CommandHelp("package uninstall <packageId> \r\n\t" + "Uninstall a module or a theme.")]
[CommandName("package uninstall")] [CommandName("package uninstall")]
public void UninstallPackage(string packageId) { public void UninstallPackage(string packageId) {
var solutionFolder = GetSolutionFolder(); _packageManager.Uninstall(packageId, ApplicationPath);
if ( solutionFolder == null ) {
Context.Output.WriteLine(T("The project's location is not supported"));
}
_packageManager.Uninstall(packageId, solutionFolder);
foreach ( var message in _notifier.List() ) { foreach ( var message in _notifier.List() ) {
Context.Output.WriteLine(message.Message); Context.Output.WriteLine(message.Message);
} }
} }
private static string GetSolutionFolder() {
var orchardDirectory = Directory.GetParent(OrchardWebProj);
return orchardDirectory.Parent == null ? null : orchardDirectory.Parent.FullName;
}
} }
} }

View File

@@ -85,6 +85,7 @@
<Compile Include="Models\PackagingSource.cs" /> <Compile Include="Models\PackagingSource.cs" />
<Compile Include="ResourceManifest.cs" /> <Compile Include="ResourceManifest.cs" />
<Compile Include="Services\AtomExtensions.cs" /> <Compile Include="Services\AtomExtensions.cs" />
<Compile Include="Services\ExtensionReferenceRepository.cs" />
<Compile Include="Services\FileBaseProjectSystem.cs" /> <Compile Include="Services\FileBaseProjectSystem.cs" />
<Compile Include="Services\IPackageBuilder.cs" /> <Compile Include="Services\IPackageBuilder.cs" />
<Compile Include="Services\IPackageInstaller.cs" /> <Compile Include="Services\IPackageInstaller.cs" />

View File

@@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using NuGet;
using Orchard.Environment.Extensions;
namespace Orchard.Packaging.Services {
/// <summary>
/// This repository implementation informs about what packages are already installed.
/// </summary>
public class ExtensionReferenceRepository : PackageRepositoryBase {
private readonly IExtensionManager _extensionManager;
public ExtensionReferenceRepository(IProjectSystem project, IPackageRepository sourceRepository, IExtensionManager extensionManager) {
if (project == null) {
throw new ArgumentNullException("project");
}
if (sourceRepository == null) {
throw new ArgumentNullException("sourceRepository");
}
if (extensionManager == null) {
throw new ArgumentNullException("extensionManager");
}
Project = project;
SourceRepository = sourceRepository;
_extensionManager = extensionManager;
}
private IProjectSystem Project {
get;
set;
}
private IPackageRepository SourceRepository {
get;
set;
}
public override IQueryable<IPackage> GetPackages() {
IEnumerable<IPackage> packages;
packages = from extension in _extensionManager.AvailableExtensions()
let id = "Orchard." + extension.ExtensionType + "." + extension.Name
let version = Version.Parse(extension.Version)
let package = SourceRepository.FindPackage(id, version)
where package != null
select package;
return packages.AsQueryable();
}
public override void AddPackage(IPackage package) {
}
public override void RemovePackage(IPackage package) {
}
}
}

View File

@@ -7,7 +7,7 @@ namespace Orchard.Packaging.Services {
} }
public interface IPackageInstaller : IDependency { public interface IPackageInstaller : IDependency {
PackageInfo Install(string packageId, string version, string location, string solutionFolder); PackageInfo Install(string packageId, string version, string location, string applicationFolder);
void Uninstall(string packageId, string solutionFolder); void Uninstall(string packageId, string applicationFolder);
} }
} }

View File

@@ -5,26 +5,30 @@ using Orchard.Environment.Extensions;
using Orchard.Localization; using Orchard.Localization;
using Orchard.UI.Notify; using Orchard.UI.Notify;
using NuGetPackageManager = NuGet.PackageManager; using NuGetPackageManager = NuGet.PackageManager;
using System.Security.Permissions;
using System.Security;
using System.Web.Hosting;
namespace Orchard.Packaging.Services { namespace Orchard.Packaging.Services {
[OrchardFeature("PackagingServices")] [OrchardFeature("PackagingServices")]
public class PackageInstaller : IPackageInstaller { public class PackageInstaller : IPackageInstaller {
private const string PackagesPath = "packages"; private const string PackagesPath = "packages";
private const string ProjectPath = "Orchard.Web"; private const string SolutionFilename = "Orchard.sln";
private readonly INotifier _notifier; private readonly INotifier _notifier;
private readonly IExtensionManager _extensionManager;
public PackageInstaller(INotifier notifier) { public PackageInstaller(INotifier notifier, IExtensionManager extensionManager) {
_notifier = notifier; _notifier = notifier;
_extensionManager = extensionManager;
T = NullLocalizer.Instance; T = NullLocalizer.Instance;
} }
public Localizer T { get; set; } public Localizer T { get; set; }
public PackageInfo Install(string packageId, string version, string location, string solutionFolder) { public PackageInfo Install(string packageId, string version, string location, string applicationPath) {
// this logger is used to render NuGet's log on the notifier
var packagesPath = Path.Combine(solutionFolder, PackagesPath); // where to download/uncompress packages
var projectPath = Path.Combine(solutionFolder, ProjectPath); // where to install packages (in the project's folder)
var logger = new NugetLogger(_notifier); var logger = new NugetLogger(_notifier);
// instantiates the appropriate package repository // instantiates the appropriate package repository
@@ -34,23 +38,43 @@ namespace Orchard.Packaging.Services {
var packageVersion = String.IsNullOrEmpty(version) ? null : new Version(version); var packageVersion = String.IsNullOrEmpty(version) ? null : new Version(version);
var package = packageRepository.FindPackage(packageId, packageVersion); var package = packageRepository.FindPackage(packageId, packageVersion);
if ( package == null ) { 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); 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);
} }
var packageManager = new NuGetPackageManager( bool installed = false;
packageRepository,
new DefaultPackagePathResolver(location),
new PhysicalFileSystem(packagesPath) { Logger = logger }
) {Logger = logger};
// specifically tells to ignore dependencies // if we can access the parent directory, and the solution is inside, NuGet-install the package here
packageManager.InstallPackage(package, ignoreDependencies: true); string solutionPath;
var installedPackagesPath = String.Empty;
if (TryGetSolutionPath(applicationPath, out solutionPath)) {
installedPackagesPath = Path.Combine(solutionPath, 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 at the solution level 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( var projectManager = new ProjectManager(
new LocalPackageRepository(packagesPath), // source repository for the package to install sourceRepository, // source repository for the package to install
new DefaultPackagePathResolver(location), new DefaultPackagePathResolver(location),
new FileBasedProjectSystem(projectPath) { Logger = logger } // the location of the project (where to copy the content files) project,
new ExtensionReferenceRepository(project, sourceRepository, _extensionManager)
) {Logger = logger}; ) {Logger = logger};
// add the package to the project // add the package to the project
@@ -59,38 +83,68 @@ namespace Orchard.Packaging.Services {
return new PackageInfo { return new PackageInfo {
ExtensionName = package.Title ?? package.Id, ExtensionName = package.Title ?? package.Id,
ExtensionVersion = package.Version.ToString(), ExtensionVersion = package.Version.ToString(),
ExtensionType = String.Empty, // todo: assign value ExtensionType = package.Id.StartsWith("Orchard.Theme") ? "Theme" : "Module",
ExtensionPath = projectPath ExtensionPath = applicationPath
}; };
} }
public void Uninstall(string packageId, string solutionFolder) { public void Uninstall(string packageId, string applicationPath) {
var packagesPath = Path.Combine(solutionFolder, PackagesPath); // where to download/uncompress packages // this logger is used to render NuGet's log on the notifier
var projectPath = Path.Combine(solutionFolder, ProjectPath); // where to install packages (in the project's folder)
var logger = new NugetLogger(_notifier); var logger = new NugetLogger(_notifier);
// instantiates the appropriate package repository string solutionPath;
var packageRepository = PackageRepositoryFactory.Default.CreateRepository(new PackageSource("Default", packagesPath)); // if we can access the parent directory, and the solution is inside, NuGet-uninstall the package here
if (TryGetSolutionPath(applicationPath, out solutionPath)) {
var installedPackagesPath = Path.Combine(solutionPath, PackagesPath);
var projectManager = new ProjectManager( var sourcePackageRepository = new LocalPackageRepository(installedPackagesPath);
new LocalPackageRepository(packagesPath), var project = new FileBasedProjectSystem(applicationPath) { Logger = logger };
new DefaultPackagePathResolver(packagesPath), var projectManager = new ProjectManager(
new FileBasedProjectSystem(projectPath) { Logger = logger } sourcePackageRepository,
) { Logger = logger }; new DefaultPackagePathResolver(installedPackagesPath),
project,
new ExtensionReferenceRepository(project, sourcePackageRepository, _extensionManager)
) { Logger = logger };
// removes the package from the project // add the package to the project
projectManager.RemovePackageReference(packageId); projectManager.RemovePackageReference(packageId);
var packageManager = new NuGetPackageManager( var packageManager = new NuGetPackageManager(
packageRepository, sourcePackageRepository,
new DefaultPackagePathResolver(packagesPath), new DefaultPackagePathResolver(applicationPath),
new PhysicalFileSystem(packagesPath) { Logger = logger } new PhysicalFileSystem(installedPackagesPath) { Logger = logger }
) { Logger = logger }; ) { Logger = logger };
packageManager.UninstallPackage(packageId);
}
else {
// otherwise delete the folder
packageManager.UninstallPackage(packageId); string extensionPath = packageId.StartsWith("Orchard.Themes.")
? "~/Themes/" + packageId.Substring("Orchard.Theme.".Length)
: "~/Modules/" + packageId.Substring("Orchard.Module.".Length);
string extensionFullPath = HostingEnvironment.MapPath(extensionPath);
if (Directory.Exists(extensionFullPath)) {
Directory.Delete(extensionFullPath, true);
}
else {
throw new OrchardException(T("Package not found: ", packageId));
}
}
}
private bool TryGetSolutionPath(string applicationPath, out string parentPath) {
try {
parentPath = Directory.GetParent(applicationPath).Parent.FullName;
var solutionPath = Path.Combine(parentPath, SolutionFilename);
return File.Exists(solutionPath);
}
catch {
parentPath = null;
return false;
}
} }
} }
} }