diff options
author | Rob Mensching <rob@firegiant.com> | 2022-07-26 17:20:39 -0700 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2022-08-01 20:25:19 -0700 |
commit | a627ca9b720047e633a8fe72003ab9bee31006c5 (patch) | |
tree | 2bc8a924bb4141ab718e74d08f6459a0ffe8d573 /src/tools/heat/DirectoryHarvester.cs | |
parent | 521eb3c9cf38823a2c4019abb85dc0b3200b92cb (diff) | |
download | wix-a627ca9b720047e633a8fe72003ab9bee31006c5.tar.gz wix-a627ca9b720047e633a8fe72003ab9bee31006c5.tar.bz2 wix-a627ca9b720047e633a8fe72003ab9bee31006c5.zip |
Create WixToolset.Heat.nupkg to distribute heat.exe and Heat targets
Moves Heat functionality to the "tools" layer and packages it all
up in WixToolset.Heat.nupkg for distribution in WiX v4.
Completes 6838
Diffstat (limited to 'src/tools/heat/DirectoryHarvester.cs')
-rw-r--r-- | src/tools/heat/DirectoryHarvester.cs | 308 |
1 files changed, 308 insertions, 0 deletions
diff --git a/src/tools/heat/DirectoryHarvester.cs b/src/tools/heat/DirectoryHarvester.cs new file mode 100644 index 00000000..c1cc3edb --- /dev/null +++ b/src/tools/heat/DirectoryHarvester.cs | |||
@@ -0,0 +1,308 @@ | |||
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.Harvesters | ||
4 | { | ||
5 | using System; | ||
6 | using System.IO; | ||
7 | using WixToolset.Data; | ||
8 | using WixToolset.Harvesters.Data; | ||
9 | using WixToolset.Harvesters.Extensibility; | ||
10 | using Wix = WixToolset.Harvesters.Serialize; | ||
11 | |||
12 | /// <summary> | ||
13 | /// Harvest WiX authoring for a directory from the file system. | ||
14 | /// </summary> | ||
15 | public sealed class DirectoryHarvester : BaseHarvesterExtension | ||
16 | { | ||
17 | private FileHarvester fileHarvester; | ||
18 | |||
19 | private const string ComponentPrefix = "cmp"; | ||
20 | private const string DirectoryPrefix = "dir"; | ||
21 | private const string FilePrefix = "fil"; | ||
22 | |||
23 | /// <summary> | ||
24 | /// Instantiate a new DirectoryHarvester. | ||
25 | /// </summary> | ||
26 | public DirectoryHarvester() | ||
27 | { | ||
28 | this.fileHarvester = new FileHarvester(); | ||
29 | this.SetUniqueIdentifiers = true; | ||
30 | } | ||
31 | |||
32 | /// <summary> | ||
33 | /// Gets or sets what type of elements are to be generated. | ||
34 | /// </summary> | ||
35 | /// <value>The type of elements being generated.</value> | ||
36 | public GenerateType GenerateType { get; set; } | ||
37 | |||
38 | /// <summary> | ||
39 | /// Gets or sets the option to keep empty directories. | ||
40 | /// </summary> | ||
41 | /// <value>The option to keep empty directories.</value> | ||
42 | public bool KeepEmptyDirectories { get; set; } | ||
43 | |||
44 | /// <summary> | ||
45 | /// Gets or sets the rooted DirectoryRef Id if the user has supplied it. | ||
46 | /// </summary> | ||
47 | /// <value>The DirectoryRef Id to use as the root.</value> | ||
48 | public string RootedDirectoryRef { get; set; } | ||
49 | |||
50 | /// <summary> | ||
51 | /// Gets of sets the option to set unique identifiers. | ||
52 | /// </summary> | ||
53 | /// <value>The option to set unique identifiers.</value> | ||
54 | public bool SetUniqueIdentifiers { get; set; } | ||
55 | |||
56 | /// <summary> | ||
57 | /// Gets or sets the option to suppress including the root directory as an element. | ||
58 | /// </summary> | ||
59 | /// <value>The option to suppress including the root directory as an element.</value> | ||
60 | public bool SuppressRootDirectory { get; set; } | ||
61 | |||
62 | /// <summary> | ||
63 | /// Harvest a directory. | ||
64 | /// </summary> | ||
65 | /// <param name="argument">The path of the directory.</param> | ||
66 | /// <returns>The harvested directory.</returns> | ||
67 | public override Wix.Fragment[] Harvest(string argument) | ||
68 | { | ||
69 | if (null == argument) | ||
70 | { | ||
71 | throw new ArgumentNullException("argument"); | ||
72 | } | ||
73 | |||
74 | Wix.IParentElement harvestParent = this.HarvestDirectory(argument, true, this.GenerateType); | ||
75 | Wix.ISchemaElement harvestElement; | ||
76 | |||
77 | if (this.GenerateType == GenerateType.PayloadGroup) | ||
78 | { | ||
79 | Wix.PayloadGroup payloadGroup = (Wix.PayloadGroup)harvestParent; | ||
80 | payloadGroup.Id = this.RootedDirectoryRef; | ||
81 | harvestElement = payloadGroup; | ||
82 | } | ||
83 | else | ||
84 | { | ||
85 | Wix.Directory directory = (Wix.Directory)harvestParent; | ||
86 | |||
87 | Wix.DirectoryRef directoryRef = new Wix.DirectoryRef(); | ||
88 | directoryRef.Id = this.RootedDirectoryRef; | ||
89 | |||
90 | if (this.SuppressRootDirectory) | ||
91 | { | ||
92 | foreach (Wix.ISchemaElement element in directory.Children) | ||
93 | { | ||
94 | directoryRef.AddChild(element); | ||
95 | } | ||
96 | } | ||
97 | else | ||
98 | { | ||
99 | directoryRef.AddChild(directory); | ||
100 | } | ||
101 | harvestElement = directoryRef; | ||
102 | } | ||
103 | |||
104 | Wix.Fragment fragment = new Wix.Fragment(); | ||
105 | fragment.AddChild(harvestElement); | ||
106 | |||
107 | return new Wix.Fragment[] { fragment }; | ||
108 | } | ||
109 | |||
110 | /// <summary> | ||
111 | /// Harvest a directory. | ||
112 | /// </summary> | ||
113 | /// <param name="path">The path of the directory.</param> | ||
114 | /// <param name="harvestChildren">The option to harvest child directories and files.</param> | ||
115 | /// <returns>The harvested directory.</returns> | ||
116 | public Wix.Directory HarvestDirectory(string path, bool harvestChildren) | ||
117 | { | ||
118 | if (null == path) | ||
119 | { | ||
120 | throw new ArgumentNullException("path"); | ||
121 | } | ||
122 | |||
123 | return (Wix.Directory)this.HarvestDirectory(path, harvestChildren, GenerateType.Components); | ||
124 | } | ||
125 | |||
126 | /// <summary> | ||
127 | /// Harvest a directory. | ||
128 | /// </summary> | ||
129 | /// <param name="path">The path of the directory.</param> | ||
130 | /// <param name="harvestChildren">The option to harvest child directories and files.</param> | ||
131 | /// <param name="generateType">The type to generate.</param> | ||
132 | /// <returns>The harvested directory.</returns> | ||
133 | private Wix.IParentElement HarvestDirectory(string path, bool harvestChildren, GenerateType generateType) | ||
134 | { | ||
135 | if (File.Exists(path)) | ||
136 | { | ||
137 | throw new WixException(ErrorMessages.ExpectedDirectoryGotFile("dir", path)); | ||
138 | } | ||
139 | |||
140 | if (null == this.RootedDirectoryRef) | ||
141 | { | ||
142 | this.RootedDirectoryRef = "TARGETDIR"; | ||
143 | } | ||
144 | |||
145 | // use absolute paths | ||
146 | path = Path.GetFullPath(path); | ||
147 | |||
148 | // Remove any trailing separator to ensure Path.GetFileName() will return the directory name. | ||
149 | path = path.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); | ||
150 | |||
151 | Wix.IParentElement harvestParent; | ||
152 | if (generateType == GenerateType.PayloadGroup) | ||
153 | { | ||
154 | harvestParent = new Wix.PayloadGroup(); | ||
155 | } | ||
156 | else | ||
157 | { | ||
158 | Wix.Directory directory = new Wix.Directory(); | ||
159 | directory.Name = Path.GetFileName(path); | ||
160 | directory.FileSource = path; | ||
161 | |||
162 | if (this.SetUniqueIdentifiers) | ||
163 | { | ||
164 | if (this.SuppressRootDirectory) | ||
165 | { | ||
166 | directory.Id = this.Core.GenerateIdentifier(DirectoryPrefix, this.RootedDirectoryRef); | ||
167 | } | ||
168 | else | ||
169 | { | ||
170 | directory.Id = this.Core.GenerateIdentifier(DirectoryPrefix, this.RootedDirectoryRef, directory.Name); | ||
171 | } | ||
172 | } | ||
173 | harvestParent = directory; | ||
174 | } | ||
175 | |||
176 | if (harvestChildren) | ||
177 | { | ||
178 | try | ||
179 | { | ||
180 | int fileCount = this.HarvestDirectory(path, "SourceDir\\", harvestParent, generateType); | ||
181 | |||
182 | if (generateType != GenerateType.PayloadGroup) | ||
183 | { | ||
184 | // its an error to not harvest anything with the option to keep empty directories off | ||
185 | if (0 == fileCount && !this.KeepEmptyDirectories) | ||
186 | { | ||
187 | throw new WixException(HarvesterErrors.EmptyDirectory(path)); | ||
188 | } | ||
189 | } | ||
190 | } | ||
191 | catch (DirectoryNotFoundException) | ||
192 | { | ||
193 | throw new WixException(HarvesterErrors.DirectoryNotFound(path)); | ||
194 | } | ||
195 | } | ||
196 | |||
197 | return harvestParent; | ||
198 | } | ||
199 | |||
200 | /// <summary> | ||
201 | /// Harvest a directory. | ||
202 | /// </summary> | ||
203 | /// <param name="path">The path of the directory.</param> | ||
204 | /// <param name="relativePath">The relative path that will be used when harvesting.</param> | ||
205 | /// <param name="harvestParent">The directory for this path.</param> | ||
206 | /// <param name="generateType"></param> | ||
207 | /// <returns>The number of files harvested.</returns> | ||
208 | private int HarvestDirectory(string path, string relativePath, Wix.IParentElement harvestParent, GenerateType generateType) | ||
209 | { | ||
210 | int fileCount = 0; | ||
211 | Wix.Directory directory = generateType != GenerateType.PayloadGroup ? (Wix.Directory)harvestParent : null; | ||
212 | |||
213 | // harvest the child directories | ||
214 | foreach (string childDirectoryPath in Directory.GetDirectories(path)) | ||
215 | { | ||
216 | var childDirectoryName = Path.GetFileName(childDirectoryPath); | ||
217 | Wix.IParentElement newParent; | ||
218 | Wix.Directory childDirectory = null; | ||
219 | |||
220 | if (generateType == GenerateType.PayloadGroup) | ||
221 | { | ||
222 | newParent = harvestParent; | ||
223 | } | ||
224 | else | ||
225 | { | ||
226 | childDirectory = new Wix.Directory(); | ||
227 | newParent = childDirectory; | ||
228 | |||
229 | childDirectory.Name = childDirectoryName; | ||
230 | childDirectory.FileSource = childDirectoryPath; | ||
231 | |||
232 | if (this.SetUniqueIdentifiers) | ||
233 | { | ||
234 | childDirectory.Id = this.Core.GenerateIdentifier(DirectoryPrefix, directory.Id, childDirectory.Name); | ||
235 | } | ||
236 | } | ||
237 | |||
238 | int childFileCount = this.HarvestDirectory(childDirectoryPath, String.Concat(relativePath, childDirectoryName, "\\"), newParent, generateType); | ||
239 | |||
240 | if (generateType != GenerateType.PayloadGroup) | ||
241 | { | ||
242 | // keep the directory if it contained any files (or empty directories are being kept) | ||
243 | if (0 < childFileCount || this.KeepEmptyDirectories) | ||
244 | { | ||
245 | directory.AddChild(childDirectory); | ||
246 | } | ||
247 | } | ||
248 | |||
249 | fileCount += childFileCount; | ||
250 | } | ||
251 | |||
252 | // harvest the files | ||
253 | string[] files = Directory.GetFiles(path); | ||
254 | if (0 < files.Length) | ||
255 | { | ||
256 | foreach (string filePath in Directory.GetFiles(path)) | ||
257 | { | ||
258 | string fileName = Path.GetFileName(filePath); | ||
259 | string source = String.Concat(relativePath, fileName); | ||
260 | |||
261 | Wix.ISchemaElement newChild; | ||
262 | if (generateType == GenerateType.PayloadGroup) | ||
263 | { | ||
264 | Wix.Payload payload = new Wix.Payload(); | ||
265 | newChild = payload; | ||
266 | |||
267 | payload.SourceFile = source; | ||
268 | } | ||
269 | else | ||
270 | { | ||
271 | Wix.Component component = new Wix.Component(); | ||
272 | newChild = component; | ||
273 | |||
274 | Wix.File file = this.fileHarvester.HarvestFile(filePath); | ||
275 | file.Source = source; | ||
276 | |||
277 | if (this.SetUniqueIdentifiers) | ||
278 | { | ||
279 | file.Id = this.Core.GenerateIdentifier(FilePrefix, directory.Id, fileName); | ||
280 | component.Id = this.Core.GenerateIdentifier(ComponentPrefix, directory.Id, file.Id); | ||
281 | } | ||
282 | |||
283 | component.AddChild(file); | ||
284 | } | ||
285 | |||
286 | harvestParent.AddChild(newChild); | ||
287 | } | ||
288 | } | ||
289 | else if (generateType != GenerateType.PayloadGroup && 0 == fileCount && this.KeepEmptyDirectories) | ||
290 | { | ||
291 | Wix.Component component = new Wix.Component(); | ||
292 | component.KeyPath = Wix.YesNoType.yes; | ||
293 | |||
294 | if (this.SetUniqueIdentifiers) | ||
295 | { | ||
296 | component.Id = this.Core.GenerateIdentifier(ComponentPrefix, directory.Id); | ||
297 | } | ||
298 | |||
299 | Wix.CreateFolder createFolder = new Wix.CreateFolder(); | ||
300 | component.AddChild(createFolder); | ||
301 | |||
302 | directory.AddChild(component); | ||
303 | } | ||
304 | |||
305 | return fileCount + files.Length; | ||
306 | } | ||
307 | } | ||
308 | } | ||