diff options
| author | Rob Mensching <rob@firegiant.com> | 2018-08-11 01:06:40 -0700 |
|---|---|---|
| committer | Rob Mensching <rob@firegiant.com> | 2018-08-11 01:06:40 -0700 |
| commit | 2a27f9032aa115bc2f88d9be695d9b049db1a894 (patch) | |
| tree | 7882bd4c94da118a6fc655a3c22e1dd0cf3b60e1 /src/WixToolset.Core | |
| parent | b54516035b4ebbfbd8899b26de501bfa13f53e8b (diff) | |
| download | wix-2a27f9032aa115bc2f88d9be695d9b049db1a894.tar.gz wix-2a27f9032aa115bc2f88d9be695d9b049db1a894.tar.bz2 wix-2a27f9032aa115bc2f88d9be695d9b049db1a894.zip | |
Track files to enable clean builds in MSBuild
Diffstat (limited to 'src/WixToolset.Core')
| -rw-r--r-- | src/WixToolset.Core/CommandLine/BuildCommand.cs | 3 | ||||
| -rw-r--r-- | src/WixToolset.Core/ExtensibilityServices/BackendHelper.cs | 12 | ||||
| -rw-r--r-- | src/WixToolset.Core/FileTransfer.cs | 2 | ||||
| -rw-r--r-- | src/WixToolset.Core/Layout.cs | 140 | ||||
| -rw-r--r-- | src/WixToolset.Core/LayoutContext.cs | 2 | ||||
| -rw-r--r-- | src/WixToolset.Core/TrackedFile.cs | 26 |
6 files changed, 148 insertions, 37 deletions
diff --git a/src/WixToolset.Core/CommandLine/BuildCommand.cs b/src/WixToolset.Core/CommandLine/BuildCommand.cs index 5c089b5f..b460e48f 100644 --- a/src/WixToolset.Core/CommandLine/BuildCommand.cs +++ b/src/WixToolset.Core/CommandLine/BuildCommand.cs | |||
| @@ -276,8 +276,9 @@ namespace WixToolset.Core.CommandLine | |||
| 276 | 276 | ||
| 277 | { | 277 | { |
| 278 | var layout = new Layout(this.ServiceProvider); | 278 | var layout = new Layout(this.ServiceProvider); |
| 279 | layout.TrackedFiles = bindResult.TrackedFiles; | ||
| 279 | layout.FileTransfers = bindResult.FileTransfers; | 280 | layout.FileTransfers = bindResult.FileTransfers; |
| 280 | layout.ContentFilePaths = bindResult.ContentFilePaths; | 281 | layout.IntermediateFolder = this.IntermediateFolder; |
| 281 | layout.ContentsFile = this.ContentsFile; | 282 | layout.ContentsFile = this.ContentsFile; |
| 282 | layout.OutputsFile = this.OutputsFile; | 283 | layout.OutputsFile = this.OutputsFile; |
| 283 | layout.BuiltOutputsFile = this.BuiltOutputsFile; | 284 | layout.BuiltOutputsFile = this.BuiltOutputsFile; |
diff --git a/src/WixToolset.Core/ExtensibilityServices/BackendHelper.cs b/src/WixToolset.Core/ExtensibilityServices/BackendHelper.cs index 0cda4437..6cc91487 100644 --- a/src/WixToolset.Core/ExtensibilityServices/BackendHelper.cs +++ b/src/WixToolset.Core/ExtensibilityServices/BackendHelper.cs | |||
| @@ -19,18 +19,17 @@ namespace WixToolset.Core.ExtensibilityServices | |||
| 19 | 19 | ||
| 20 | private IMessaging Messaging { get; } | 20 | private IMessaging Messaging { get; } |
| 21 | 21 | ||
| 22 | public IFileTransfer CreateFileTransfer(string source, string destination, bool move, FileTransferType type, SourceLineNumber sourceLineNumbers) | 22 | public IFileTransfer CreateFileTransfer(string source, string destination, bool move, SourceLineNumber sourceLineNumbers = null) |
| 23 | { | 23 | { |
| 24 | var sourceFullPath = GetValidatedFullPath(sourceLineNumbers, source); | 24 | var sourceFullPath = this.GetValidatedFullPath(sourceLineNumbers, source); |
| 25 | 25 | ||
| 26 | var destinationFullPath = GetValidatedFullPath(sourceLineNumbers, destination); | 26 | var destinationFullPath = this.GetValidatedFullPath(sourceLineNumbers, destination); |
| 27 | 27 | ||
| 28 | return (String.IsNullOrEmpty(sourceFullPath) || String.IsNullOrEmpty(destinationFullPath)) ? null : new FileTransfer | 28 | return (String.IsNullOrEmpty(sourceFullPath) || String.IsNullOrEmpty(destinationFullPath)) ? null : new FileTransfer |
| 29 | { | 29 | { |
| 30 | Source = sourceFullPath, | 30 | Source = sourceFullPath, |
| 31 | Destination = destinationFullPath, | 31 | Destination = destinationFullPath, |
| 32 | Move = move, | 32 | Move = move, |
| 33 | Type = type, | ||
| 34 | SourceLineNumbers = sourceLineNumbers, | 33 | SourceLineNumbers = sourceLineNumbers, |
| 35 | Redundant = String.Equals(sourceFullPath, destinationFullPath, StringComparison.OrdinalIgnoreCase) | 34 | Redundant = String.Equals(sourceFullPath, destinationFullPath, StringComparison.OrdinalIgnoreCase) |
| 36 | }; | 35 | }; |
| @@ -41,6 +40,11 @@ namespace WixToolset.Core.ExtensibilityServices | |||
| 41 | return Uuid.NewUuid(namespaceGuid, value).ToString("B").ToUpperInvariant(); | 40 | return Uuid.NewUuid(namespaceGuid, value).ToString("B").ToUpperInvariant(); |
| 42 | } | 41 | } |
| 43 | 42 | ||
| 43 | public ITrackedFile TrackFile(string path, TrackedFileType type, SourceLineNumber sourceLineNumbers = null) | ||
| 44 | { | ||
| 45 | return new TrackedFile(path, type, sourceLineNumbers); | ||
| 46 | } | ||
| 47 | |||
| 44 | private string GetValidatedFullPath(SourceLineNumber sourceLineNumbers, string path) | 48 | private string GetValidatedFullPath(SourceLineNumber sourceLineNumbers, string path) |
| 45 | { | 49 | { |
| 46 | try | 50 | try |
diff --git a/src/WixToolset.Core/FileTransfer.cs b/src/WixToolset.Core/FileTransfer.cs index 9da406eb..7f9ed0f3 100644 --- a/src/WixToolset.Core/FileTransfer.cs +++ b/src/WixToolset.Core/FileTransfer.cs | |||
| @@ -15,8 +15,6 @@ namespace WixToolset.Core | |||
| 15 | 15 | ||
| 16 | public SourceLineNumber SourceLineNumbers { get; set; } | 16 | public SourceLineNumber SourceLineNumbers { get; set; } |
| 17 | 17 | ||
| 18 | public FileTransferType Type { get; set; } | ||
| 19 | |||
| 20 | public bool Redundant { get; set; } | 18 | public bool Redundant { get; set; } |
| 21 | } | 19 | } |
| 22 | } | 20 | } |
diff --git a/src/WixToolset.Core/Layout.cs b/src/WixToolset.Core/Layout.cs index 128efc61..b1b03aa7 100644 --- a/src/WixToolset.Core/Layout.cs +++ b/src/WixToolset.Core/Layout.cs | |||
| @@ -28,9 +28,11 @@ namespace WixToolset.Core | |||
| 28 | 28 | ||
| 29 | private IMessaging Messaging { get; } | 29 | private IMessaging Messaging { get; } |
| 30 | 30 | ||
| 31 | public IEnumerable<ITrackedFile> TrackedFiles { get; set; } | ||
| 32 | |||
| 31 | public IEnumerable<IFileTransfer> FileTransfers { get; set; } | 33 | public IEnumerable<IFileTransfer> FileTransfers { get; set; } |
| 32 | 34 | ||
| 33 | public IEnumerable<string> ContentFilePaths { get; set; } | 35 | public string IntermediateFolder { get; set; } |
| 34 | 36 | ||
| 35 | public string ContentsFile { get; set; } | 37 | public string ContentsFile { get; set; } |
| 36 | 38 | ||
| @@ -46,8 +48,8 @@ namespace WixToolset.Core | |||
| 46 | 48 | ||
| 47 | var context = this.ServiceProvider.GetService<ILayoutContext>(); | 49 | var context = this.ServiceProvider.GetService<ILayoutContext>(); |
| 48 | context.Extensions = extensionManager.Create<ILayoutExtension>(); | 50 | context.Extensions = extensionManager.Create<ILayoutExtension>(); |
| 51 | context.TrackedFiles = this.TrackedFiles; | ||
| 49 | context.FileTransfers = this.FileTransfers; | 52 | context.FileTransfers = this.FileTransfers; |
| 50 | context.ContentFilePaths = this.ContentFilePaths; | ||
| 51 | context.ContentsFile = this.ContentsFile; | 53 | context.ContentsFile = this.ContentsFile; |
| 52 | context.OutputsFile = this.OutputsFile; | 54 | context.OutputsFile = this.OutputsFile; |
| 53 | context.BuiltOutputsFile = this.BuiltOutputsFile; | 55 | context.BuiltOutputsFile = this.BuiltOutputsFile; |
| @@ -71,24 +73,29 @@ namespace WixToolset.Core | |||
| 71 | var command = new TransferFilesCommand(this.Messaging, context.Extensions, context.FileTransfers, context.SuppressAclReset); | 73 | var command = new TransferFilesCommand(this.Messaging, context.Extensions, context.FileTransfers, context.SuppressAclReset); |
| 72 | command.Execute(); | 74 | command.Execute(); |
| 73 | } | 75 | } |
| 76 | |||
| 77 | if (context.TrackedFiles != null) | ||
| 78 | { | ||
| 79 | this.CleanTempFiles(context.TrackedFiles); | ||
| 80 | } | ||
| 74 | } | 81 | } |
| 75 | finally | 82 | finally |
| 76 | { | 83 | { |
| 77 | if (!String.IsNullOrEmpty(context.ContentsFile) && context.ContentFilePaths != null) | 84 | if (context.TrackedFiles != null) |
| 78 | { | 85 | { |
| 79 | this.CreateContentsFile(context.ContentsFile, context.ContentFilePaths); | 86 | if (!String.IsNullOrEmpty(context.ContentsFile)) |
| 80 | } | 87 | { |
| 88 | this.CreateContentsFile(context.ContentsFile, context.TrackedFiles); | ||
| 89 | } | ||
| 81 | 90 | ||
| 82 | if (context.FileTransfers != null) | ||
| 83 | { | ||
| 84 | if (!String.IsNullOrEmpty(context.OutputsFile)) | 91 | if (!String.IsNullOrEmpty(context.OutputsFile)) |
| 85 | { | 92 | { |
| 86 | this.CreateOutputsFile(context.OutputsFile, context.FileTransfers); | 93 | this.CreateOutputsFile(context.OutputsFile, context.TrackedFiles); |
| 87 | } | 94 | } |
| 88 | 95 | ||
| 89 | if (!String.IsNullOrEmpty(context.BuiltOutputsFile)) | 96 | if (!String.IsNullOrEmpty(context.BuiltOutputsFile)) |
| 90 | { | 97 | { |
| 91 | this.CreateBuiltOutputsFile(context.BuiltOutputsFile, context.FileTransfers); | 98 | this.CreateBuiltOutputsFile(context.BuiltOutputsFile, context.TrackedFiles); |
| 92 | } | 99 | } |
| 93 | } | 100 | } |
| 94 | } | 101 | } |
| @@ -105,16 +112,23 @@ namespace WixToolset.Core | |||
| 105 | /// </summary> | 112 | /// </summary> |
| 106 | /// <param name="path">Path to write file.</param> | 113 | /// <param name="path">Path to write file.</param> |
| 107 | /// <param name="contentFilePaths">Collection of paths to content files that will be written to file.</param> | 114 | /// <param name="contentFilePaths">Collection of paths to content files that will be written to file.</param> |
| 108 | private void CreateContentsFile(string path, IEnumerable<string> contentFilePaths) | 115 | private void CreateContentsFile(string path, IEnumerable<ITrackedFile> trackedFiles) |
| 109 | { | 116 | { |
| 117 | var uniqueInputFilePaths = new SortedSet<string>(trackedFiles.Where(t => t.Type == TrackedFileType.Input).Select(t => t.Path), StringComparer.OrdinalIgnoreCase); | ||
| 118 | |||
| 119 | if (!uniqueInputFilePaths.Any()) | ||
| 120 | { | ||
| 121 | return; | ||
| 122 | } | ||
| 123 | |||
| 110 | var directory = Path.GetDirectoryName(path); | 124 | var directory = Path.GetDirectoryName(path); |
| 111 | Directory.CreateDirectory(directory); | 125 | Directory.CreateDirectory(directory); |
| 112 | 126 | ||
| 113 | using (var contents = new StreamWriter(path, false)) | 127 | using (var contents = new StreamWriter(path, false)) |
| 114 | { | 128 | { |
| 115 | foreach (string contentPath in contentFilePaths) | 129 | foreach (string inputPath in uniqueInputFilePaths) |
| 116 | { | 130 | { |
| 117 | contents.WriteLine(contentPath); | 131 | contents.WriteLine(inputPath); |
| 118 | } | 132 | } |
| 119 | } | 133 | } |
| 120 | } | 134 | } |
| @@ -124,22 +138,28 @@ namespace WixToolset.Core | |||
| 124 | /// </summary> | 138 | /// </summary> |
| 125 | /// <param name="path">Path to write file.</param> | 139 | /// <param name="path">Path to write file.</param> |
| 126 | /// <param name="fileTransfers">Collection of files that were transferred to the output directory.</param> | 140 | /// <param name="fileTransfers">Collection of files that were transferred to the output directory.</param> |
| 127 | private void CreateOutputsFile(string path, IEnumerable<IFileTransfer> fileTransfers) | 141 | private void CreateOutputsFile(string path, IEnumerable<ITrackedFile> trackedFiles) |
| 128 | { | 142 | { |
| 143 | var uniqueOutputPaths = new SortedSet<string>(trackedFiles.Where(t => t.Clean).Select(t => t.Path), StringComparer.OrdinalIgnoreCase); | ||
| 144 | |||
| 145 | if (!uniqueOutputPaths.Any()) | ||
| 146 | { | ||
| 147 | return; | ||
| 148 | } | ||
| 149 | |||
| 129 | var directory = Path.GetDirectoryName(path); | 150 | var directory = Path.GetDirectoryName(path); |
| 130 | Directory.CreateDirectory(directory); | 151 | Directory.CreateDirectory(directory); |
| 131 | 152 | ||
| 132 | using (var outputs = new StreamWriter(path, false)) | 153 | using (var outputs = new StreamWriter(path, false)) |
| 133 | { | 154 | { |
| 134 | foreach (var fileTransfer in fileTransfers) | 155 | //// Don't list files where the source is the same as the destination since |
| 156 | //// that might be the only place the file exists. The outputs file is often | ||
| 157 | //// used to delete stuff and losing the original source would be bad. | ||
| 158 | //var uniqueOutputPaths = new SortedSet<string>(fileTransfers.Where(ft => !ft.Redundant).Select(ft => ft.Destination), StringComparer.OrdinalIgnoreCase); | ||
| 159 | |||
| 160 | foreach (var outputPath in uniqueOutputPaths) | ||
| 135 | { | 161 | { |
| 136 | // Don't list files where the source is the same as the destination since | 162 | outputs.WriteLine(outputPath); |
| 137 | // that might be the only place the file exists. The outputs file is often | ||
| 138 | // used to delete stuff and losing the original source would be bad. | ||
| 139 | if (!fileTransfer.Redundant) | ||
| 140 | { | ||
| 141 | outputs.WriteLine(fileTransfer.Destination); | ||
| 142 | } | ||
| 143 | } | 163 | } |
| 144 | } | 164 | } |
| 145 | } | 165 | } |
| @@ -149,21 +169,83 @@ namespace WixToolset.Core | |||
| 149 | /// </summary> | 169 | /// </summary> |
| 150 | /// <param name="path">Path to write file.</param> | 170 | /// <param name="path">Path to write file.</param> |
| 151 | /// <param name="fileTransfers">Collection of files that were transferred to the output directory.</param> | 171 | /// <param name="fileTransfers">Collection of files that were transferred to the output directory.</param> |
| 152 | private void CreateBuiltOutputsFile(string path, IEnumerable<IFileTransfer> fileTransfers) | 172 | private void CreateBuiltOutputsFile(string path, IEnumerable<ITrackedFile> trackedFiles) |
| 153 | { | 173 | { |
| 174 | var uniqueBuiltPaths = new SortedSet<string>(trackedFiles.Where(t => t.Type == TrackedFileType.Final).Select(t => t.Path), StringComparer.OrdinalIgnoreCase); | ||
| 175 | |||
| 176 | if (!uniqueBuiltPaths.Any()) | ||
| 177 | { | ||
| 178 | return; | ||
| 179 | } | ||
| 180 | |||
| 154 | var directory = Path.GetDirectoryName(path); | 181 | var directory = Path.GetDirectoryName(path); |
| 155 | Directory.CreateDirectory(directory); | 182 | Directory.CreateDirectory(directory); |
| 156 | 183 | ||
| 157 | using (var outputs = new StreamWriter(path, false)) | 184 | using (var outputs = new StreamWriter(path, false)) |
| 158 | { | 185 | { |
| 159 | foreach (var fileTransfer in fileTransfers) | 186 | foreach (var builtPath in uniqueBuiltPaths) |
| 160 | { | 187 | { |
| 161 | // Only write the built file transfers. Also, skip redundant | 188 | outputs.WriteLine(builtPath); |
| 162 | // files for the same reason spelled out in this.CreateOutputsFile(). | 189 | } |
| 163 | if (fileTransfer.Type == FileTransferType.Built && !fileTransfer.Redundant) | 190 | } |
| 164 | { | 191 | } |
| 165 | outputs.WriteLine(fileTransfer.Destination); | 192 | |
| 166 | } | 193 | private void CleanTempFiles(IEnumerable<ITrackedFile> trackedFiles) |
| 194 | { | ||
| 195 | var uniqueTempPaths = new SortedSet<string>(trackedFiles.Where(t => t.Type == TrackedFileType.Temporary).Select(t => t.Path), StringComparer.OrdinalIgnoreCase); | ||
| 196 | |||
| 197 | if (!uniqueTempPaths.Any()) | ||
| 198 | { | ||
| 199 | return; | ||
| 200 | } | ||
| 201 | |||
| 202 | var uniqueFolders = new SortedSet<string>(StringComparer.OrdinalIgnoreCase) | ||
| 203 | { | ||
| 204 | this.IntermediateFolder | ||
| 205 | }; | ||
| 206 | |||
| 207 | // Clean up temp files. | ||
| 208 | foreach (var tempPath in uniqueTempPaths) | ||
| 209 | { | ||
| 210 | try | ||
| 211 | { | ||
| 212 | this.SplitUniqueFolders(tempPath, uniqueFolders); | ||
| 213 | |||
| 214 | File.Delete(tempPath); | ||
| 215 | } | ||
| 216 | catch // delete is best effort. | ||
| 217 | { | ||
| 218 | } | ||
| 219 | } | ||
| 220 | |||
| 221 | // Clean up empty temp folders. | ||
| 222 | foreach (var folder in uniqueFolders.Reverse()) | ||
| 223 | { | ||
| 224 | try | ||
| 225 | { | ||
| 226 | Directory.Delete(folder); | ||
| 227 | } | ||
| 228 | catch // delete is best effort. | ||
| 229 | { | ||
| 230 | } | ||
| 231 | } | ||
| 232 | } | ||
| 233 | |||
| 234 | private void SplitUniqueFolders(string tempPath, SortedSet<string> uniqueFolders) | ||
| 235 | { | ||
| 236 | if (tempPath.StartsWith(this.IntermediateFolder, StringComparison.OrdinalIgnoreCase)) | ||
| 237 | { | ||
| 238 | var folder = Path.GetDirectoryName(tempPath).Substring(this.IntermediateFolder.Length); | ||
| 239 | |||
| 240 | var parts = folder.Split(new[] { '\\', '/' }, StringSplitOptions.RemoveEmptyEntries); | ||
| 241 | |||
| 242 | folder = this.IntermediateFolder; | ||
| 243 | |||
| 244 | foreach (var part in parts) | ||
| 245 | { | ||
| 246 | folder = Path.Combine(folder, part); | ||
| 247 | |||
| 248 | uniqueFolders.Add(folder); | ||
| 167 | } | 249 | } |
| 168 | } | 250 | } |
| 169 | } | 251 | } |
diff --git a/src/WixToolset.Core/LayoutContext.cs b/src/WixToolset.Core/LayoutContext.cs index 99ca611a..20d29b5f 100644 --- a/src/WixToolset.Core/LayoutContext.cs +++ b/src/WixToolset.Core/LayoutContext.cs | |||
| @@ -22,7 +22,7 @@ namespace WixToolset.Core | |||
| 22 | 22 | ||
| 23 | public IEnumerable<IFileTransfer> FileTransfers { get; set; } | 23 | public IEnumerable<IFileTransfer> FileTransfers { get; set; } |
| 24 | 24 | ||
| 25 | public IEnumerable<string> ContentFilePaths { get; set; } | 25 | public IEnumerable<ITrackedFile> TrackedFiles { get; set; } |
| 26 | 26 | ||
| 27 | public string OutputPdbPath { get; set; } | 27 | public string OutputPdbPath { get; set; } |
| 28 | 28 | ||
diff --git a/src/WixToolset.Core/TrackedFile.cs b/src/WixToolset.Core/TrackedFile.cs new file mode 100644 index 00000000..312b09f4 --- /dev/null +++ b/src/WixToolset.Core/TrackedFile.cs | |||
| @@ -0,0 +1,26 @@ | |||
| 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 | ||
| 4 | { | ||
| 5 | using WixToolset.Data; | ||
| 6 | using WixToolset.Extensibility.Data; | ||
| 7 | |||
| 8 | internal class TrackedFile : ITrackedFile | ||
| 9 | { | ||
| 10 | public TrackedFile(string path, TrackedFileType type, SourceLineNumber sourceLineNumbers) | ||
| 11 | { | ||
| 12 | this.Path = path; | ||
| 13 | this.Type = type; | ||
| 14 | this.SourceLineNumbers = sourceLineNumbers; | ||
| 15 | this.Clean = (type == TrackedFileType.Intermediate || type == TrackedFileType.Final); | ||
| 16 | } | ||
| 17 | |||
| 18 | public bool Clean { get; set; } | ||
| 19 | |||
| 20 | public string Path { get; set; } | ||
| 21 | |||
| 22 | public SourceLineNumber SourceLineNumbers { get; set; } | ||
| 23 | |||
| 24 | public TrackedFileType Type { get; set; } | ||
| 25 | } | ||
| 26 | } | ||
