using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Xml.Linq; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.Packaging; using Umbraco.Core.Services; using File = System.IO.File; namespace Umbraco.Core.Packaging { /// /// Installs package files /// internal class PackageFileInstallation { private readonly CompiledPackageXmlParser _parser; private readonly IProfilingLogger _logger; private readonly PackageExtraction _packageExtraction; public PackageFileInstallation(CompiledPackageXmlParser parser, IProfilingLogger logger) { _parser = parser; _logger = logger; _packageExtraction = new PackageExtraction(); } /// /// Returns a list of all installed file paths /// /// /// /// /// The absolute path of where to extract the package files (normally the application root) /// /// public IEnumerable InstallFiles(CompiledPackage compiledPackage, FileInfo packageFile, string targetRootFolder) { using (_logger.DebugDuration( "Installing package files for package " + compiledPackage.Name, "Package file installation complete for package " + compiledPackage.Name)) { var sourceAndRelativeDest = _parser.ExtractSourceDestinationFileInformation(compiledPackage.Files); var sourceAndAbsDest = AppendRootToDestination(targetRootFolder, sourceAndRelativeDest); _packageExtraction.CopyFilesFromArchive(packageFile, sourceAndAbsDest); return sourceAndRelativeDest.Select(sd => sd.appRelativePath).ToArray(); } } public IEnumerable UninstallFiles(PackageDefinition package) { var removedFiles = new List(); foreach (var item in package.Files.ToArray()) { removedFiles.Add(item.GetRelativePath()); //here we need to try to find the file in question as most packages does not support the tilde char var file = IOHelper.FindFile(item); if (file != null) { // TODO: Surely this should be ~/ ? file = file.EnsureStartsWith("/"); var filePath = IOHelper.MapPath(file); if (File.Exists(filePath)) File.Delete(filePath); } package.Files.Remove(file); } return removedFiles; } private static IEnumerable<(string packageUniqueFile, string appAbsolutePath)> AppendRootToDestination(string applicationRootFolder, IEnumerable<(string packageUniqueFile, string appRelativePath)> sourceDestination) { return sourceDestination.Select( sd => (sd.packageUniqueFile, Path.Combine(applicationRootFolder, sd.appRelativePath))).ToArray(); } } }