diff options
Diffstat (limited to 'src/WixToolset.Core.ExtensionCache')
7 files changed, 565 insertions, 0 deletions
diff --git a/src/WixToolset.Core.ExtensionCache/CachedExtension.cs b/src/WixToolset.Core.ExtensionCache/CachedExtension.cs new file mode 100644 index 00000000..9ed874d9 --- /dev/null +++ b/src/WixToolset.Core.ExtensionCache/CachedExtension.cs | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | namespace WixToolset.Core.ExtensionCache | ||
| 4 | { | ||
| 5 | public class CachedExtension | ||
| 6 | { | ||
| 7 | internal CachedExtension(string id, string version, bool damaged) | ||
| 8 | { | ||
| 9 | this.Id = id; | ||
| 10 | this.Version = version; | ||
| 11 | this.Damaged = damaged; | ||
| 12 | } | ||
| 13 | |||
| 14 | public string Id { get; } | ||
| 15 | |||
| 16 | public string Version { get; } | ||
| 17 | |||
| 18 | public bool Damaged { get; } | ||
| 19 | } | ||
| 20 | } | ||
diff --git a/src/WixToolset.Core.ExtensionCache/ExtensionCacheManager.cs b/src/WixToolset.Core.ExtensionCache/ExtensionCacheManager.cs new file mode 100644 index 00000000..3ec6451e --- /dev/null +++ b/src/WixToolset.Core.ExtensionCache/ExtensionCacheManager.cs | |||
| @@ -0,0 +1,252 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | namespace WixToolset.Core.ExtensionCache | ||
| 4 | { | ||
| 5 | using System; | ||
| 6 | using System.Collections.Generic; | ||
| 7 | using System.IO; | ||
| 8 | using System.Linq; | ||
| 9 | using System.Threading; | ||
| 10 | using System.Threading.Tasks; | ||
| 11 | using NuGet.Common; | ||
| 12 | using NuGet.Configuration; | ||
| 13 | using NuGet.Credentials; | ||
| 14 | using NuGet.Packaging; | ||
| 15 | using NuGet.Protocol; | ||
| 16 | using NuGet.Protocol.Core.Types; | ||
| 17 | using NuGet.Versioning; | ||
| 18 | |||
| 19 | /// <summary> | ||
| 20 | /// Extension cache manager. | ||
| 21 | /// </summary> | ||
| 22 | public class ExtensionCacheManager | ||
| 23 | { | ||
| 24 | public string CacheFolder(bool global) => global ? this.GlobalCacheFolder() : this.LocalCacheFolder(); | ||
| 25 | |||
| 26 | public string LocalCacheFolder() => Path.Combine(Environment.CurrentDirectory, @".wix\extensions\"); | ||
| 27 | |||
| 28 | public string GlobalCacheFolder() | ||
| 29 | { | ||
| 30 | var baseFolder = Environment.GetEnvironmentVariable("WIX_EXTENSIONS") ?? Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); | ||
| 31 | return Path.Combine(baseFolder, @".wix\extensions\"); | ||
| 32 | } | ||
| 33 | |||
| 34 | public async Task<bool> AddAsync(bool global, string extension, CancellationToken cancellationToken) | ||
| 35 | { | ||
| 36 | if (String.IsNullOrEmpty(extension)) | ||
| 37 | { | ||
| 38 | throw new ArgumentNullException(nameof(extension)); | ||
| 39 | } | ||
| 40 | |||
| 41 | (var extensionId, var extensionVersion) = ParseExtensionReference(extension); | ||
| 42 | |||
| 43 | var result = await this.DownloadAndExtractAsync(global, extensionId, extensionVersion, cancellationToken); | ||
| 44 | |||
| 45 | return result; | ||
| 46 | } | ||
| 47 | |||
| 48 | public Task<bool> RemoveAsync(bool global, string extension, CancellationToken cancellationToken) | ||
| 49 | { | ||
| 50 | if (String.IsNullOrEmpty(extension)) | ||
| 51 | { | ||
| 52 | throw new ArgumentNullException(nameof(extension)); | ||
| 53 | } | ||
| 54 | |||
| 55 | (var extensionId, var extensionVersion) = ParseExtensionReference(extension); | ||
| 56 | |||
| 57 | var cacheFolder = this.CacheFolder(global); | ||
| 58 | |||
| 59 | cacheFolder = Path.Combine(cacheFolder, extensionId, extensionVersion); | ||
| 60 | |||
| 61 | if (Directory.Exists(cacheFolder)) | ||
| 62 | { | ||
| 63 | cancellationToken.ThrowIfCancellationRequested(); | ||
| 64 | |||
| 65 | Directory.Delete(cacheFolder, true); | ||
| 66 | return Task.FromResult(true); | ||
| 67 | } | ||
| 68 | |||
| 69 | return Task.FromResult(false); | ||
| 70 | } | ||
| 71 | |||
| 72 | public Task<IEnumerable<CachedExtension>> ListAsync(bool global, string extension, CancellationToken cancellationToken) | ||
| 73 | { | ||
| 74 | var found = new List<CachedExtension>(); | ||
| 75 | |||
| 76 | (var extensionId, var extensionVersion) = ParseExtensionReference(extension); | ||
| 77 | |||
| 78 | var cacheFolder = this.CacheFolder(global); | ||
| 79 | |||
| 80 | var searchFolder = Path.Combine(cacheFolder, extensionId, extensionVersion); | ||
| 81 | |||
| 82 | if (!Directory.Exists(searchFolder)) | ||
| 83 | { | ||
| 84 | } | ||
| 85 | else if (!String.IsNullOrEmpty(extensionVersion)) // looking for an explicit version of an extension. | ||
| 86 | { | ||
| 87 | var extensionFolder = Path.Combine(cacheFolder, extensionId, extensionVersion); | ||
| 88 | if (Directory.Exists(extensionFolder)) | ||
| 89 | { | ||
| 90 | var present = ExtensionFileExists(cacheFolder, extensionId, extensionVersion); | ||
| 91 | found.Add(new CachedExtension(extensionId, extensionVersion, !present)); | ||
| 92 | } | ||
| 93 | } | ||
| 94 | else // looking for all versions of an extension or all versions of all extensions. | ||
| 95 | { | ||
| 96 | IEnumerable<string> foundExtensionIds; | ||
| 97 | |||
| 98 | if (String.IsNullOrEmpty(extensionId)) | ||
| 99 | { | ||
| 100 | // Looking for all versions of all extensions. | ||
| 101 | foundExtensionIds = Directory.GetDirectories(cacheFolder).Select(folder => Path.GetFileName(folder)).ToList(); | ||
| 102 | } | ||
| 103 | else | ||
| 104 | { | ||
| 105 | // Looking for all versions of a single extension. | ||
| 106 | var extensionFolder = Path.Combine(cacheFolder, extensionId); | ||
| 107 | foundExtensionIds = Directory.Exists(extensionFolder) ? new[] { extensionId } : Array.Empty<string>(); | ||
| 108 | } | ||
| 109 | |||
| 110 | foreach (var foundExtensionId in foundExtensionIds) | ||
| 111 | { | ||
| 112 | var extensionFolder = Path.Combine(cacheFolder, foundExtensionId); | ||
| 113 | |||
| 114 | foreach (var folder in Directory.GetDirectories(extensionFolder)) | ||
| 115 | { | ||
| 116 | cancellationToken.ThrowIfCancellationRequested(); | ||
| 117 | |||
| 118 | var foundExtensionVersion = Path.GetFileName(folder); | ||
| 119 | |||
| 120 | if (!NuGetVersion.TryParse(foundExtensionVersion, out _)) | ||
| 121 | { | ||
| 122 | continue; | ||
| 123 | } | ||
| 124 | |||
| 125 | var present = ExtensionFileExists(cacheFolder, foundExtensionId, foundExtensionVersion); | ||
| 126 | found.Add(new CachedExtension(foundExtensionId, foundExtensionVersion, !present)); | ||
| 127 | } | ||
| 128 | } | ||
| 129 | } | ||
| 130 | |||
| 131 | return Task.FromResult((IEnumerable<CachedExtension>)found); | ||
| 132 | } | ||
| 133 | |||
| 134 | private async Task<bool> DownloadAndExtractAsync(bool global, string id, string version, CancellationToken cancellationToken) | ||
| 135 | { | ||
| 136 | var logger = NullLogger.Instance; | ||
| 137 | |||
| 138 | DefaultCredentialServiceUtility.SetupDefaultCredentialService(logger, nonInteractive: false); | ||
| 139 | |||
| 140 | var settings = Settings.LoadDefaultSettings(root: Environment.CurrentDirectory); | ||
| 141 | var sources = PackageSourceProvider.LoadPackageSources(settings).Where(s => s.IsEnabled); | ||
| 142 | |||
| 143 | using (var cache = new SourceCacheContext()) | ||
| 144 | { | ||
| 145 | PackageSource versionSource = null; | ||
| 146 | |||
| 147 | var nugetVersion = String.IsNullOrEmpty(version) ? null : new NuGetVersion(version); | ||
| 148 | |||
| 149 | if (nugetVersion is null) | ||
| 150 | { | ||
| 151 | foreach (var source in sources) | ||
| 152 | { | ||
| 153 | var repository = Repository.Factory.GetCoreV3(source.Source); | ||
| 154 | var resource = await repository.GetResourceAsync<FindPackageByIdResource>(); | ||
| 155 | |||
| 156 | var availableVersions = await resource.GetAllVersionsAsync(id, cache, logger, cancellationToken); | ||
| 157 | foreach (var availableVersion in availableVersions) | ||
| 158 | { | ||
| 159 | if (nugetVersion is null || nugetVersion < availableVersion) | ||
| 160 | { | ||
| 161 | nugetVersion = availableVersion; | ||
| 162 | versionSource = source; | ||
| 163 | } | ||
| 164 | } | ||
| 165 | } | ||
| 166 | |||
| 167 | if (nugetVersion is null) | ||
| 168 | { | ||
| 169 | return false; | ||
| 170 | } | ||
| 171 | } | ||
| 172 | |||
| 173 | var searchSources = versionSource is null ? sources : new[] { versionSource }; | ||
| 174 | |||
| 175 | var extensionFolder = Path.Combine(this.CacheFolder(global), id, nugetVersion.ToString()); | ||
| 176 | |||
| 177 | foreach (var source in searchSources) | ||
| 178 | { | ||
| 179 | var repository = Repository.Factory.GetCoreV3(source.Source); | ||
| 180 | var resource = await repository.GetResourceAsync<FindPackageByIdResource>(); | ||
| 181 | |||
| 182 | using (var stream = new MemoryStream()) | ||
| 183 | { | ||
| 184 | var downloaded = await resource.CopyNupkgToStreamAsync(id, nugetVersion, stream, cache, logger, cancellationToken); | ||
| 185 | |||
| 186 | if (downloaded) | ||
| 187 | { | ||
| 188 | stream.Position = 0; | ||
| 189 | |||
| 190 | using (var archive = new PackageArchiveReader(stream)) | ||
| 191 | { | ||
| 192 | var files = PackagingConstants.Folders.Known.SelectMany(folder => archive.GetFiles(folder)).Distinct(StringComparer.OrdinalIgnoreCase); | ||
| 193 | await archive.CopyFilesAsync(extensionFolder, files, this.ExtractProgress, logger, cancellationToken); | ||
| 194 | } | ||
| 195 | |||
| 196 | return true; | ||
| 197 | } | ||
| 198 | } | ||
| 199 | } | ||
| 200 | } | ||
| 201 | |||
| 202 | return false; | ||
| 203 | } | ||
| 204 | |||
| 205 | private string ExtractProgress(string sourceFile, string targetPath, Stream fileStream) => fileStream.CopyToFile(targetPath); | ||
| 206 | |||
| 207 | private static (string extensionId, string extensionVersion) ParseExtensionReference(string extensionReference) | ||
| 208 | { | ||
| 209 | var extensionId = extensionReference ?? String.Empty; | ||
| 210 | var extensionVersion = String.Empty; | ||
| 211 | |||
| 212 | var index = extensionId.LastIndexOf('/'); | ||
| 213 | if (index > 0) | ||
| 214 | { | ||
| 215 | extensionVersion = extensionReference.Substring(index + 1); | ||
| 216 | extensionId = extensionReference.Substring(0, index); | ||
| 217 | |||
| 218 | if (!NuGetVersion.TryParse(extensionVersion, out _)) | ||
| 219 | { | ||
| 220 | throw new ArgumentException($"Invalid extension version in {extensionReference}"); | ||
| 221 | } | ||
| 222 | |||
| 223 | if (String.IsNullOrEmpty(extensionId)) | ||
| 224 | { | ||
| 225 | throw new ArgumentException($"Invalid extension id in {extensionReference}"); | ||
| 226 | } | ||
| 227 | } | ||
| 228 | |||
| 229 | return (extensionId, extensionVersion); | ||
| 230 | } | ||
| 231 | |||
| 232 | private static bool ExtensionFileExists(string baseFolder, string extensionId, string extensionVersion) | ||
| 233 | { | ||
| 234 | var toolsFolder = Path.Combine(baseFolder, extensionId, extensionVersion, "tools"); | ||
| 235 | if (!Directory.Exists(toolsFolder)) | ||
| 236 | { | ||
| 237 | return false; | ||
| 238 | } | ||
| 239 | |||
| 240 | var extensionAssembly = Path.Combine(toolsFolder, extensionId + ".dll"); | ||
| 241 | |||
| 242 | var present = File.Exists(extensionAssembly); | ||
| 243 | if (!present) | ||
| 244 | { | ||
| 245 | extensionAssembly = Path.Combine(toolsFolder, extensionId + ".exe"); | ||
| 246 | present = File.Exists(extensionAssembly); | ||
| 247 | } | ||
| 248 | |||
| 249 | return present; | ||
| 250 | } | ||
| 251 | } | ||
| 252 | } | ||
diff --git a/src/WixToolset.Core.ExtensionCache/ExtensionCacheManagerCommand.cs b/src/WixToolset.Core.ExtensionCache/ExtensionCacheManagerCommand.cs new file mode 100644 index 00000000..5016f430 --- /dev/null +++ b/src/WixToolset.Core.ExtensionCache/ExtensionCacheManagerCommand.cs | |||
| @@ -0,0 +1,170 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | namespace WixToolset.Core.ExtensionCache | ||
| 4 | { | ||
| 5 | using System; | ||
| 6 | using System.Collections.Generic; | ||
| 7 | using System.Linq; | ||
| 8 | using System.Threading; | ||
| 9 | using System.Threading.Tasks; | ||
| 10 | using WixToolset.Extensibility.Data; | ||
| 11 | using WixToolset.Extensibility.Services; | ||
| 12 | |||
| 13 | /// <summary> | ||
| 14 | /// Extension cache manager command. | ||
| 15 | /// </summary> | ||
| 16 | internal class ExtensionCacheManagerCommand : ICommandLineCommand | ||
| 17 | { | ||
| 18 | private enum CacheSubcommand | ||
| 19 | { | ||
| 20 | Add, | ||
| 21 | Remove, | ||
| 22 | List | ||
| 23 | } | ||
| 24 | |||
| 25 | public ExtensionCacheManagerCommand(IWixToolsetServiceProvider serviceProvider) | ||
| 26 | { | ||
| 27 | this.Messaging = serviceProvider.GetService<IMessaging>(); | ||
| 28 | this.ExtensionReferences = new List<string>(); | ||
| 29 | } | ||
| 30 | |||
| 31 | private IMessaging Messaging { get; } | ||
| 32 | |||
| 33 | public bool ShowLogo { get; private set; } | ||
| 34 | |||
| 35 | public bool StopParsing { get; private set; } | ||
| 36 | |||
| 37 | private bool ShowHelp { get; set; } | ||
| 38 | |||
| 39 | private bool Global { get; set; } | ||
| 40 | |||
| 41 | private CacheSubcommand? Subcommand { get; set; } | ||
| 42 | |||
| 43 | private List<string> ExtensionReferences { get; } | ||
| 44 | |||
| 45 | public async Task<int> ExecuteAsync(CancellationToken cancellationToken) | ||
| 46 | { | ||
| 47 | if (this.ShowHelp || !this.Subcommand.HasValue) | ||
| 48 | { | ||
| 49 | DisplayHelp(); | ||
| 50 | return 1; | ||
| 51 | } | ||
| 52 | |||
| 53 | var success = false; | ||
| 54 | var cacheManager = new ExtensionCacheManager(); | ||
| 55 | |||
| 56 | switch (this.Subcommand) | ||
| 57 | { | ||
| 58 | case CacheSubcommand.Add: | ||
| 59 | success = await this.AddExtensions(cacheManager, cancellationToken); | ||
| 60 | break; | ||
| 61 | |||
| 62 | case CacheSubcommand.Remove: | ||
| 63 | success = await this.RemoveExtensions(cacheManager, cancellationToken); | ||
| 64 | break; | ||
| 65 | |||
| 66 | case CacheSubcommand.List: | ||
| 67 | success = await this.ListExtensions(cacheManager, cancellationToken); | ||
| 68 | break; | ||
| 69 | } | ||
| 70 | |||
| 71 | return success ? 0 : 2; | ||
| 72 | } | ||
| 73 | |||
| 74 | public bool TryParseArgument(ICommandLineParser parser, string argument) | ||
| 75 | { | ||
| 76 | if (!parser.IsSwitch(argument)) | ||
| 77 | { | ||
| 78 | if (!this.Subcommand.HasValue) | ||
| 79 | { | ||
| 80 | if (!Enum.TryParse(argument, true, out CacheSubcommand subcommand)) | ||
| 81 | { | ||
| 82 | return false; | ||
| 83 | } | ||
| 84 | |||
| 85 | this.Subcommand = subcommand; | ||
| 86 | } | ||
| 87 | else | ||
| 88 | { | ||
| 89 | this.ExtensionReferences.Add(argument); | ||
| 90 | } | ||
| 91 | |||
| 92 | return true; | ||
| 93 | } | ||
| 94 | |||
| 95 | var parameter = argument.Substring(1); | ||
| 96 | switch (parameter.ToLowerInvariant()) | ||
| 97 | { | ||
| 98 | case "?": | ||
| 99 | this.ShowHelp = true; | ||
| 100 | this.ShowLogo = true; | ||
| 101 | this.StopParsing = true; | ||
| 102 | return true; | ||
| 103 | |||
| 104 | case "nologo": | ||
| 105 | this.ShowLogo = false; | ||
| 106 | return true; | ||
| 107 | |||
| 108 | case "g": | ||
| 109 | case "-global": | ||
| 110 | this.Global = true; | ||
| 111 | return true; | ||
| 112 | } | ||
| 113 | |||
| 114 | return false; | ||
| 115 | } | ||
| 116 | |||
| 117 | private async Task<bool> AddExtensions(ExtensionCacheManager cacheManager, CancellationToken cancellationToken) | ||
| 118 | { | ||
| 119 | var success = true; | ||
| 120 | |||
| 121 | foreach (var extensionRef in this.ExtensionReferences) | ||
| 122 | { | ||
| 123 | var added = await cacheManager.AddAsync(this.Global, extensionRef, cancellationToken); | ||
| 124 | success |= added; | ||
| 125 | } | ||
| 126 | |||
| 127 | return success; | ||
| 128 | } | ||
| 129 | |||
| 130 | private async Task<bool> RemoveExtensions(ExtensionCacheManager cacheManager, CancellationToken cancellationToken) | ||
| 131 | { | ||
| 132 | var success = true; | ||
| 133 | |||
| 134 | foreach (var extensionRef in this.ExtensionReferences) | ||
| 135 | { | ||
| 136 | var removed = await cacheManager.RemoveAsync(this.Global, extensionRef, cancellationToken); | ||
| 137 | success |= removed; | ||
| 138 | } | ||
| 139 | |||
| 140 | return success; | ||
| 141 | } | ||
| 142 | |||
| 143 | private async Task<bool> ListExtensions(ExtensionCacheManager cacheManager, CancellationToken cancellationToken) | ||
| 144 | { | ||
| 145 | var found = false; | ||
| 146 | var extensionRef = this.ExtensionReferences.FirstOrDefault(); | ||
| 147 | |||
| 148 | var extensions = await cacheManager.ListAsync(this.Global, extensionRef, cancellationToken); | ||
| 149 | |||
| 150 | foreach (var extension in extensions) | ||
| 151 | { | ||
| 152 | this.Messaging.Write($"{extension.Id} {extension.Version}{(extension.Damaged ? " (damaged)" : String.Empty)}"); | ||
| 153 | found = true; | ||
| 154 | } | ||
| 155 | |||
| 156 | return found; | ||
| 157 | } | ||
| 158 | |||
| 159 | private static void DisplayHelp() | ||
| 160 | { | ||
| 161 | Console.WriteLine(" usage: wix.exe extension add|remove|list [extensionRef]"); | ||
| 162 | Console.WriteLine(); | ||
| 163 | Console.WriteLine(" -g add/remove the extension for the current user"); | ||
| 164 | Console.WriteLine(" -nologo suppress displaying the logo information"); | ||
| 165 | Console.WriteLine(" -? this help information"); | ||
| 166 | Console.WriteLine(); | ||
| 167 | Console.WriteLine(" extensionRef format: extensionId/version (the version is optional)"); | ||
| 168 | } | ||
| 169 | } | ||
| 170 | } | ||
diff --git a/src/WixToolset.Core.ExtensionCache/ExtensionCacheManagerExtensionCommandLine.cs b/src/WixToolset.Core.ExtensionCache/ExtensionCacheManagerExtensionCommandLine.cs new file mode 100644 index 00000000..81e96718 --- /dev/null +++ b/src/WixToolset.Core.ExtensionCache/ExtensionCacheManagerExtensionCommandLine.cs | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | namespace WixToolset.Core.ExtensionCache | ||
| 4 | { | ||
| 5 | using System; | ||
| 6 | using System.Collections.Generic; | ||
| 7 | using WixToolset.Extensibility; | ||
| 8 | using WixToolset.Extensibility.Data; | ||
| 9 | using WixToolset.Extensibility.Services; | ||
| 10 | |||
| 11 | /// <summary> | ||
| 12 | /// Parses the "extension" command-line command. See <c>ExtensionCacheManagerCommand</c> | ||
| 13 | /// for the bulk of the command-line processing. | ||
| 14 | /// </summary> | ||
| 15 | internal class ExtensionCacheManagerExtensionCommandLine : BaseExtensionCommandLine | ||
| 16 | { | ||
| 17 | public ExtensionCacheManagerExtensionCommandLine(IWixToolsetServiceProvider serviceProvider) | ||
| 18 | { | ||
| 19 | this.ServiceProvider = serviceProvider; | ||
| 20 | } | ||
| 21 | |||
| 22 | private IWixToolsetServiceProvider ServiceProvider { get; } | ||
| 23 | |||
| 24 | // TODO: Do something with CommandLineSwitches | ||
| 25 | public override IEnumerable<ExtensionCommandLineSwitch> CommandLineSwitches => base.CommandLineSwitches; | ||
| 26 | |||
| 27 | public override bool TryParseCommand(ICommandLineParser parser, string argument, out ICommandLineCommand command) | ||
| 28 | { | ||
| 29 | command = null; | ||
| 30 | |||
| 31 | if ("extension".Equals(argument, StringComparison.OrdinalIgnoreCase)) | ||
| 32 | { | ||
| 33 | command = new ExtensionCacheManagerCommand(this.ServiceProvider); | ||
| 34 | } | ||
| 35 | |||
| 36 | return command != null; | ||
| 37 | } | ||
| 38 | } | ||
| 39 | } | ||
diff --git a/src/WixToolset.Core.ExtensionCache/ExtensionCacheManagerExtensionFactory.cs b/src/WixToolset.Core.ExtensionCache/ExtensionCacheManagerExtensionFactory.cs new file mode 100644 index 00000000..44fc4b86 --- /dev/null +++ b/src/WixToolset.Core.ExtensionCache/ExtensionCacheManagerExtensionFactory.cs | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | namespace WixToolset.Core.ExtensionCache | ||
| 4 | { | ||
| 5 | using System; | ||
| 6 | using WixToolset.Extensibility; | ||
| 7 | using WixToolset.Extensibility.Services; | ||
| 8 | |||
| 9 | internal class ExtensionCacheManagerExtensionFactory : IExtensionFactory | ||
| 10 | { | ||
| 11 | public ExtensionCacheManagerExtensionFactory(IWixToolsetServiceProvider serviceProvider) | ||
| 12 | { | ||
| 13 | this.ServiceProvider = serviceProvider; | ||
| 14 | } | ||
| 15 | |||
| 16 | private IWixToolsetServiceProvider ServiceProvider { get; } | ||
| 17 | |||
| 18 | public bool TryCreateExtension(Type extensionType, out object extension) | ||
| 19 | { | ||
| 20 | extension = null; | ||
| 21 | |||
| 22 | if (extensionType == typeof(IExtensionCommandLine)) | ||
| 23 | { | ||
| 24 | extension = new ExtensionCacheManagerExtensionCommandLine(this.ServiceProvider); | ||
| 25 | } | ||
| 26 | |||
| 27 | return extension != null; | ||
| 28 | } | ||
| 29 | } | ||
| 30 | } | ||
diff --git a/src/WixToolset.Core.ExtensionCache/WixToolset.Core.ExtensionCache.csproj b/src/WixToolset.Core.ExtensionCache/WixToolset.Core.ExtensionCache.csproj new file mode 100644 index 00000000..7ae5cdbb --- /dev/null +++ b/src/WixToolset.Core.ExtensionCache/WixToolset.Core.ExtensionCache.csproj | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | <?xml version="1.0" encoding="utf-8"?> | ||
| 2 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | ||
| 3 | |||
| 4 | <Project Sdk="Microsoft.NET.Sdk"> | ||
| 5 | <PropertyGroup> | ||
| 6 | <TargetFrameworks>netstandard2.0;net461;net472</TargetFrameworks> | ||
| 7 | <Description>Extension Cache</Description> | ||
| 8 | <Title>WiX Toolset Extension Cache</Title> | ||
| 9 | <DebugType>embedded</DebugType> | ||
| 10 | <PublishRepositoryUrl>true</PublishRepositoryUrl> | ||
| 11 | </PropertyGroup> | ||
| 12 | |||
| 13 | <ItemGroup> | ||
| 14 | <ProjectReference Include="..\WixToolset.Core\WixToolset.Core.csproj" /> | ||
| 15 | </ItemGroup> | ||
| 16 | |||
| 17 | <ItemGroup> | ||
| 18 | <PackageReference Include="NuGet.Credentials" Version="5.6.0" /> | ||
| 19 | <PackageReference Include="NuGet.Protocol" Version="5.6.0" /> | ||
| 20 | </ItemGroup> | ||
| 21 | |||
| 22 | <ItemGroup> | ||
| 23 | <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" /> | ||
| 24 | <PackageReference Include="Nerdbank.GitVersioning" Version="2.1.65" PrivateAssets="All" /> | ||
| 25 | </ItemGroup> | ||
| 26 | </Project> | ||
diff --git a/src/WixToolset.Core.ExtensionCache/WixToolsetCoreServiceProviderExtensions.cs b/src/WixToolset.Core.ExtensionCache/WixToolsetCoreServiceProviderExtensions.cs new file mode 100644 index 00000000..c1579330 --- /dev/null +++ b/src/WixToolset.Core.ExtensionCache/WixToolsetCoreServiceProviderExtensions.cs | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | namespace WixToolset.Core.ExtensionCache | ||
| 4 | { | ||
| 5 | using System; | ||
| 6 | using System.Collections.Generic; | ||
| 7 | using WixToolset.Extensibility.Services; | ||
| 8 | |||
| 9 | public static class WixToolsetCoreServiceProviderExtensions | ||
| 10 | { | ||
| 11 | public static IWixToolsetCoreServiceProvider AddExtensionCacheManager(this IWixToolsetCoreServiceProvider serviceProvider) | ||
| 12 | { | ||
| 13 | var extensionManager = serviceProvider.GetService<IExtensionManager>(); | ||
| 14 | extensionManager.Add(typeof(ExtensionCacheManagerExtensionFactory).Assembly); | ||
| 15 | |||
| 16 | serviceProvider.AddService(CreateExtensionCacheManager); | ||
| 17 | return serviceProvider; | ||
| 18 | } | ||
| 19 | |||
| 20 | private static ExtensionCacheManager CreateExtensionCacheManager(IWixToolsetCoreServiceProvider provider, Dictionary<Type, object> singletons) | ||
| 21 | { | ||
| 22 | var extensionCacheManager = new ExtensionCacheManager(); | ||
| 23 | singletons.Add(typeof(ExtensionCacheManager), extensionCacheManager); | ||
| 24 | |||
| 25 | return extensionCacheManager; | ||
| 26 | } | ||
| 27 | } | ||
| 28 | } | ||
