2010-07-18 12:36:02 -07:00
using System ;
2010-07-06 18:56:55 -07:00
using System.IO ;
2010-12-02 15:27:00 -08:00
using System.Web.Hosting ;
2010-11-05 18:17:12 -07:00
using NuGet ;
2010-07-22 22:09:34 -07:00
using Orchard.Environment.Extensions ;
2010-12-01 17:37:11 -08:00
using Orchard.Environment.Extensions.Models ;
2010-07-18 14:29:31 -07:00
using Orchard.Localization ;
2010-11-09 16:37:38 -08:00
using Orchard.UI.Notify ;
2010-11-05 18:17:12 -07:00
using NuGetPackageManager = NuGet . PackageManager ;
2010-07-22 22:09:34 -07:00
namespace Orchard.Packaging.Services {
[OrchardFeature("PackagingServices")]
2010-11-11 13:50:32 -08:00
public class PackageInstaller : IPackageInstaller {
private const string PackagesPath = "packages" ;
2010-12-02 15:27:00 -08:00
private const string SolutionFilename = "Orchard.sln" ;
2010-11-11 13:50:32 -08:00
2010-11-09 16:37:38 -08:00
private readonly INotifier _notifier ;
2010-11-11 23:19:23 -08:00
private readonly IExtensionManager _extensionManager ;
2010-07-18 14:29:31 -07:00
2010-12-01 15:40:44 -08:00
public PackageInstaller ( INotifier notifier ,
2010-12-02 15:27:00 -08:00
IExtensionManager extensionManager ) {
2010-11-09 16:37:38 -08:00
_notifier = notifier ;
2010-11-11 23:19:23 -08:00
_extensionManager = extensionManager ;
2010-07-18 14:29:31 -07:00
T = NullLocalizer . Instance ;
2010-07-06 18:56:55 -07:00
}
2010-07-18 14:29:31 -07:00
public Localizer T { get ; set ; }
2010-11-11 23:19:23 -08:00
public PackageInfo Install ( string packageId , string version , string location , string applicationPath ) {
2010-11-09 15:32:58 -08:00
// instantiates the appropriate package repository
2010-12-01 15:40:44 -08:00
IPackageRepository packageRepository = PackageRepositoryFactory . Default . CreateRepository ( new PackageSource ( location , "Default" ) ) ;
2010-11-05 18:17:12 -07:00
2010-11-09 15:32:58 -08:00
// gets an IPackage instance from the repository
var packageVersion = String . IsNullOrEmpty ( version ) ? null : new Version ( version ) ;
var package = packageRepository . FindPackage ( packageId , packageVersion ) ;
2010-12-01 15:40:44 -08:00
if ( package = = null )
{
2010-11-09 15:32:58 -08:00
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 ) ;
}
2010-11-05 18:17:12 -07:00
2010-12-01 15:40:44 -08:00
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 ) ;
2010-11-11 23:19:23 -08:00
bool installed = false ;
// if we can access the parent directory, and the solution is inside, NuGet-install the package here
2010-12-02 15:27:00 -08:00
string solutionPath ;
var installedPackagesPath = String . Empty ;
if ( TryGetSolutionPath ( applicationPath , out solutionPath ) ) {
installedPackagesPath = Path . Combine ( solutionPath , PackagesPath ) ;
try {
var packageManager = new NuGetPackageManager (
2010-12-01 15:40:44 -08:00
packageRepository ,
new DefaultPackagePathResolver ( location ) ,
2010-12-02 15:27:00 -08:00
new PhysicalFileSystem ( installedPackagesPath ) { Logger = logger }
) { Logger = logger } ;
packageManager . InstallPackage ( package , true ) ;
installed = true ;
}
catch {
// installing the package at the solution level failed
}
2010-11-11 23:19:23 -08:00
}
2010-11-05 18:17:12 -07:00
2010-11-11 23:19:23 -08:00
// if the package got installed successfully, use it, otherwise use the previous repository
2010-12-01 15:40:44 -08:00
var sourceRepository = installed
2010-11-11 23:19:23 -08:00
? new LocalPackageRepository ( installedPackagesPath )
: packageRepository ;
2010-11-05 18:17:12 -07:00
2010-11-11 23:19:23 -08:00
var project = new FileBasedProjectSystem ( applicationPath ) { Logger = logger } ;
2010-11-09 15:32:58 -08:00
var projectManager = new ProjectManager (
2010-11-11 23:19:23 -08:00
sourceRepository , // source repository for the package to install
2010-11-12 13:23:39 -08:00
new DefaultPackagePathResolver ( applicationPath ) ,
2010-11-11 23:19:23 -08:00
project ,
new ExtensionReferenceRepository ( project , sourceRepository , _extensionManager )
2010-12-01 15:40:44 -08:00
) { Logger = logger } ;
2010-11-05 18:17:12 -07:00
2010-11-09 15:32:58 -08:00
// add the package to the project
2010-12-01 15:40:44 -08:00
projectManager . AddPackageReference ( package . Id , package . Version ) ;
2010-07-06 18:56:55 -07:00
2010-12-01 15:40:44 -08:00
return new PackageInfo
{
2010-11-09 16:37:38 -08:00
ExtensionName = package . Title ? ? package . Id ,
2010-11-09 15:32:58 -08:00
ExtensionVersion = package . Version . ToString ( ) ,
2010-12-08 16:00:58 -08:00
ExtensionType = package . Id . StartsWith ( PackagingSourceManager . ThemesPrefix ) ? DefaultExtensionTypes . Theme : DefaultExtensionTypes . Module ,
2010-11-11 23:19:23 -08:00
ExtensionPath = applicationPath
2010-07-18 13:09:45 -07:00
} ;
2010-07-06 18:56:55 -07:00
}
2010-11-11 23:19:23 -08:00
public void Uninstall ( string packageId , string applicationPath ) {
// this logger is used to render NuGet's log on the notifier
2010-11-11 13:50:32 -08:00
var logger = new NugetLogger ( _notifier ) ;
2010-12-02 15:27:00 -08:00
string solutionPath ;
// 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 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 } ;
2010-11-11 14:37:03 -08:00
2010-12-02 15:27:00 -08:00
// add the package to the project
projectManager . RemovePackageReference ( packageId ) ;
2010-11-11 13:50:32 -08:00
2010-12-02 15:27:00 -08:00
var packageManager = new NuGetPackageManager (
2010-12-01 15:40:44 -08:00
sourcePackageRepository ,
new DefaultPackagePathResolver ( applicationPath ) ,
new PhysicalFileSystem ( installedPackagesPath ) { Logger = logger }
2010-12-02 15:27:00 -08:00
) { Logger = logger } ;
packageManager . UninstallPackage ( packageId ) ;
} else {
// otherwise delete the folder
2010-12-08 16:00:58 -08:00
string extensionPath = packageId . StartsWith ( PackagingSourceManager . ThemesPrefix )
? "~/Themes/" + packageId . Substring ( PackagingSourceManager . ThemesPrefix . Length )
: "~/Modules/" + packageId . Substring ( PackagingSourceManager . ThemesPrefix . Length ) ;
2010-11-11 13:50:32 -08:00
2010-12-02 15:27:00 -08:00
string extensionFullPath = HostingEnvironment . MapPath ( extensionPath ) ;
if ( Directory . Exists ( extensionFullPath ) ) {
Directory . Delete ( extensionFullPath , true ) ;
}
else {
throw new OrchardException ( T ( "Package not found: " , packageId ) ) ;
}
}
}
2010-12-07 16:11:29 -08:00
private static bool TryGetSolutionPath ( string applicationPath , out string parentPath ) {
2010-12-02 15:27:00 -08:00
try {
parentPath = Directory . GetParent ( applicationPath ) . Parent . FullName ;
var solutionPath = Path . Combine ( parentPath , SolutionFilename ) ;
return File . Exists ( solutionPath ) ;
}
catch {
// Either solution does not exist or we are running under medium trust
parentPath = null ;
return false ;
}
2010-11-11 13:50:32 -08:00
}
2010-07-06 18:56:55 -07:00
}
}