diff options
Diffstat (limited to 'src/WixToolset.Core/Layout.cs')
-rw-r--r-- | src/WixToolset.Core/Layout.cs | 140 |
1 files changed, 111 insertions, 29 deletions
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 | } |