diff options
| author | Rob Mensching <rob@firegiant.com> | 2018-07-21 07:36:34 -0700 |
|---|---|---|
| committer | Rob Mensching <rob@firegiant.com> | 2018-07-21 07:36:34 -0700 |
| commit | 306f1d0c528cb6c151594ff96a41b5c01a5c4d9b (patch) | |
| tree | 95deb0884b59decc082eae7adf5d65d45c5f3848 /src/WixToolset.BuildTasks/ResolveWixReferences.cs | |
| parent | 6fc54af07b10742e883f3a39ef0114e55e6a36a0 (diff) | |
| download | wix-306f1d0c528cb6c151594ff96a41b5c01a5c4d9b.tar.gz wix-306f1d0c528cb6c151594ff96a41b5c01a5c4d9b.tar.bz2 wix-306f1d0c528cb6c151594ff96a41b5c01a5c4d9b.zip | |
Integrate tools from Core project
Diffstat (limited to 'src/WixToolset.BuildTasks/ResolveWixReferences.cs')
| -rw-r--r-- | src/WixToolset.BuildTasks/ResolveWixReferences.cs | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/src/WixToolset.BuildTasks/ResolveWixReferences.cs b/src/WixToolset.BuildTasks/ResolveWixReferences.cs new file mode 100644 index 00000000..9b8cfe6f --- /dev/null +++ b/src/WixToolset.BuildTasks/ResolveWixReferences.cs | |||
| @@ -0,0 +1,212 @@ | |||
| 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.BuildTasks | ||
| 4 | { | ||
| 5 | using System; | ||
| 6 | using System.Collections.Generic; | ||
| 7 | using Microsoft.Build.Utilities; | ||
| 8 | using Microsoft.Build.Framework; | ||
| 9 | using System.IO; | ||
| 10 | |||
| 11 | /// <summary> | ||
| 12 | /// This task searches for paths to references using the order specified in SearchPaths. | ||
| 13 | /// </summary> | ||
| 14 | public class ResolveWixReferences : Task | ||
| 15 | { | ||
| 16 | /// <summary> | ||
| 17 | /// Token value used in SearchPaths to indicate that the item's HintPath metadata should | ||
| 18 | /// be searched as a full file path to resolve the reference. | ||
| 19 | /// Must match wix.targets, case sensitive. | ||
| 20 | /// </summary> | ||
| 21 | private const string HintPathToken = "{HintPathFromItem}"; | ||
| 22 | |||
| 23 | /// <summary> | ||
| 24 | /// Token value used in SearchPaths to indicate that the item's Identity should | ||
| 25 | /// be searched as a full file path to resolve the reference. | ||
| 26 | /// Must match wix.targets, case sensitive. | ||
| 27 | /// </summary> | ||
| 28 | private const string RawFileNameToken = "{RawFileName}"; | ||
| 29 | |||
| 30 | /// <summary> | ||
| 31 | /// The list of references to resolve. | ||
| 32 | /// </summary> | ||
| 33 | [Required] | ||
| 34 | public ITaskItem[] WixReferences | ||
| 35 | { | ||
| 36 | get; | ||
| 37 | set; | ||
| 38 | } | ||
| 39 | |||
| 40 | /// <summary> | ||
| 41 | /// The directories or special locations that are searched to find the files | ||
| 42 | /// on disk that represent the references. The order in which the search paths are listed | ||
| 43 | /// is important. For each reference, the list of paths is searched from left to right. | ||
| 44 | /// When a file that represents the reference is found, that search stops and the search | ||
| 45 | /// for the next reference starts. | ||
| 46 | /// | ||
| 47 | /// This parameter accepts the following types of values: | ||
| 48 | /// A directory path. | ||
| 49 | /// {HintPathFromItem}: Specifies that the task will examine the HintPath metadata | ||
| 50 | /// of the base item. | ||
| 51 | /// TODO : {CandidateAssemblyFiles}: Specifies that the task will examine the files | ||
| 52 | /// passed in through the CandidateAssemblyFiles parameter. | ||
| 53 | /// TODO : {Registry:_AssemblyFoldersBase_, _RuntimeVersion_, _AssemblyFoldersSuffix_}: | ||
| 54 | /// TODO : {AssemblyFolders}: Specifies the task will use the Visual Studio.NET 2003 | ||
| 55 | /// finding-assemblies-from-registry scheme. | ||
| 56 | /// TODO : {GAC}: Specifies the task will search in the GAC. | ||
| 57 | /// {RawFileName}: Specifies the task will consider the Include value of the item to be | ||
| 58 | /// an exact path and file name. | ||
| 59 | /// </summary> | ||
| 60 | public string[] SearchPaths | ||
| 61 | { | ||
| 62 | get; | ||
| 63 | set; | ||
| 64 | } | ||
| 65 | |||
| 66 | /// <summary> | ||
| 67 | /// The filename extension(s) to be checked when searching. | ||
| 68 | /// </summary> | ||
| 69 | public string[] SearchFilenameExtensions | ||
| 70 | { | ||
| 71 | get; | ||
| 72 | set; | ||
| 73 | } | ||
| 74 | |||
| 75 | /// <summary> | ||
| 76 | /// Output items that contain the same metadata as input references and have been resolved to full paths. | ||
| 77 | /// </summary> | ||
| 78 | [Output] | ||
| 79 | public ITaskItem[] ResolvedWixReferences | ||
| 80 | { | ||
| 81 | get; | ||
| 82 | private set; | ||
| 83 | } | ||
| 84 | |||
| 85 | /// <summary> | ||
| 86 | /// Resolves reference paths by searching for referenced items using the specified SearchPaths. | ||
| 87 | /// </summary> | ||
| 88 | /// <returns>True on success, or throws an exception on failure.</returns> | ||
| 89 | public override bool Execute() | ||
| 90 | { | ||
| 91 | List<ITaskItem> resolvedReferences = new List<ITaskItem>(); | ||
| 92 | |||
| 93 | foreach (ITaskItem reference in this.WixReferences) | ||
| 94 | { | ||
| 95 | ITaskItem resolvedReference = ResolveWixReferences.ResolveReference(reference, this.SearchPaths, this.SearchFilenameExtensions, this.Log); | ||
| 96 | |||
| 97 | this.Log.LogMessage(MessageImportance.Low, "Resolved path {0}", resolvedReference.ItemSpec); | ||
| 98 | resolvedReferences.Add(resolvedReference); | ||
| 99 | } | ||
| 100 | |||
| 101 | this.ResolvedWixReferences = resolvedReferences.ToArray(); | ||
| 102 | return true; | ||
| 103 | } | ||
| 104 | |||
| 105 | /// <summary> | ||
| 106 | /// Resolves a single reference item by searcheing for referenced items using the specified SearchPaths. | ||
| 107 | /// This method is made public so the resolution logic can be reused by other tasks. | ||
| 108 | /// </summary> | ||
| 109 | /// <param name="reference">The referenced item.</param> | ||
| 110 | /// <param name="searchPaths">The paths to search.</param> | ||
| 111 | /// <param name="searchFilenameExtensions">Filename extensions to check.</param> | ||
| 112 | /// <param name="log">Logging helper.</param> | ||
| 113 | /// <returns>The resolved reference item, or the original reference if it could not be resolved.</returns> | ||
| 114 | public static ITaskItem ResolveReference(ITaskItem reference, string[] searchPaths, string[] searchFilenameExtensions, TaskLoggingHelper log) | ||
| 115 | { | ||
| 116 | if (reference == null) | ||
| 117 | { | ||
| 118 | throw new ArgumentNullException("reference"); | ||
| 119 | } | ||
| 120 | |||
| 121 | if (searchPaths == null) | ||
| 122 | { | ||
| 123 | // Nothing to search, so just return the original reference item. | ||
| 124 | return reference; | ||
| 125 | } | ||
| 126 | |||
| 127 | if (searchFilenameExtensions == null) | ||
| 128 | { | ||
| 129 | searchFilenameExtensions = new string[] { }; | ||
| 130 | } | ||
| 131 | |||
| 132 | // Copy all the metadata from the source | ||
| 133 | TaskItem resolvedReference = new TaskItem(reference); | ||
| 134 | log.LogMessage(MessageImportance.Low, "WixReference: {0}", reference.ItemSpec); | ||
| 135 | |||
| 136 | // Now find the resolved path based on our order of precedence | ||
| 137 | foreach (string searchPath in searchPaths) | ||
| 138 | { | ||
| 139 | log.LogMessage(MessageImportance.Low, "Trying {0}", searchPath); | ||
| 140 | if (searchPath.Equals(HintPathToken, StringComparison.Ordinal)) | ||
| 141 | { | ||
| 142 | string path = reference.GetMetadata("HintPath"); | ||
| 143 | log.LogMessage(MessageImportance.Low, "Trying path {0}", path); | ||
| 144 | if (File.Exists(path)) | ||
| 145 | { | ||
| 146 | resolvedReference.ItemSpec = path; | ||
| 147 | break; | ||
| 148 | } | ||
| 149 | } | ||
| 150 | else if (searchPath.Equals(RawFileNameToken, StringComparison.Ordinal)) | ||
| 151 | { | ||
| 152 | log.LogMessage(MessageImportance.Low, "Trying path {0}", resolvedReference.ItemSpec); | ||
| 153 | if (File.Exists(resolvedReference.ItemSpec)) | ||
| 154 | { | ||
| 155 | break; | ||
| 156 | } | ||
| 157 | |||
| 158 | if (ResolveWixReferences.ResolveFilenameExtensions(resolvedReference, | ||
| 159 | resolvedReference.ItemSpec, searchFilenameExtensions, log)) | ||
| 160 | { | ||
| 161 | break; | ||
| 162 | } | ||
| 163 | } | ||
| 164 | else | ||
| 165 | { | ||
| 166 | string path = Path.Combine(searchPath, Path.GetFileName(reference.ItemSpec)); | ||
| 167 | log.LogMessage(MessageImportance.Low, "Trying path {0}", path); | ||
| 168 | if (File.Exists(path)) | ||
| 169 | { | ||
| 170 | resolvedReference.ItemSpec = path; | ||
| 171 | break; | ||
| 172 | } | ||
| 173 | |||
| 174 | if (ResolveWixReferences.ResolveFilenameExtensions(resolvedReference, | ||
| 175 | path, searchFilenameExtensions, log)) | ||
| 176 | { | ||
| 177 | break; | ||
| 178 | } | ||
| 179 | } | ||
| 180 | } | ||
| 181 | |||
| 182 | // Normalize the item path | ||
| 183 | resolvedReference.ItemSpec = resolvedReference.GetMetadata("FullPath"); | ||
| 184 | |||
| 185 | return resolvedReference; | ||
| 186 | } | ||
| 187 | |||
| 188 | /// <summary> | ||
| 189 | /// Helper method for checking filename extensions when resolving references. | ||
| 190 | /// </summary> | ||
| 191 | /// <param name="reference">The reference being resolved.</param> | ||
| 192 | /// <param name="basePath">Full filename path without extension.</param> | ||
| 193 | /// <param name="filenameExtensions">Filename extensions to check.</param> | ||
| 194 | /// <param name="log">Logging helper.</param> | ||
| 195 | /// <returns>True if the item was resolved, else false.</returns> | ||
| 196 | private static bool ResolveFilenameExtensions(ITaskItem reference, string basePath, string[] filenameExtensions, TaskLoggingHelper log) | ||
| 197 | { | ||
| 198 | foreach (string filenameExtension in filenameExtensions) | ||
| 199 | { | ||
| 200 | string path = basePath + filenameExtension; | ||
| 201 | log.LogMessage(MessageImportance.Low, "Trying path {0}", path); | ||
| 202 | if (File.Exists(path)) | ||
| 203 | { | ||
| 204 | reference.ItemSpec = path; | ||
| 205 | return true; | ||
| 206 | } | ||
| 207 | } | ||
| 208 | |||
| 209 | return false; | ||
| 210 | } | ||
| 211 | } | ||
| 212 | } | ||
