summaryrefslogtreecommitdiff
path: root/src/tools/heat/Extensibility
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2022-07-26 17:20:39 -0700
committerRob Mensching <rob@firegiant.com>2022-08-01 20:25:19 -0700
commita627ca9b720047e633a8fe72003ab9bee31006c5 (patch)
tree2bc8a924bb4141ab718e74d08f6459a0ffe8d573 /src/tools/heat/Extensibility
parent521eb3c9cf38823a2c4019abb85dc0b3200b92cb (diff)
downloadwix-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/Extensibility')
-rw-r--r--src/tools/heat/Extensibility/BaseHarvesterExtension.cs26
-rw-r--r--src/tools/heat/Extensibility/BaseHeatExtension.cs55
-rw-r--r--src/tools/heat/Extensibility/BaseMutatorExtension.cs202
-rw-r--r--src/tools/heat/Extensibility/IHarvester.cs31
-rw-r--r--src/tools/heat/Extensibility/IHarvesterCore.cs51
-rw-r--r--src/tools/heat/Extensibility/IHarvesterExtension.cs14
-rw-r--r--src/tools/heat/Extensibility/IHeatCore.cs29
-rw-r--r--src/tools/heat/Extensibility/IHeatExtension.cs16
-rw-r--r--src/tools/heat/Extensibility/IMutator.cs44
-rw-r--r--src/tools/heat/Extensibility/IMutatorExtension.cs18
10 files changed, 486 insertions, 0 deletions
diff --git a/src/tools/heat/Extensibility/BaseHarvesterExtension.cs b/src/tools/heat/Extensibility/BaseHarvesterExtension.cs
new file mode 100644
index 00000000..02696d5b
--- /dev/null
+++ b/src/tools/heat/Extensibility/BaseHarvesterExtension.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
3namespace WixToolset.Harvesters.Extensibility
4{
5 using Wix = WixToolset.Harvesters.Serialize;
6
7 /// <summary>
8 /// The base harvester extension. Any of these methods can be overridden to change
9 /// the behavior of the harvester.
10 /// </summary>
11 public abstract class BaseHarvesterExtension : IHarvesterExtension
12 {
13 /// <summary>
14 /// Gets or sets the harvester core for the extension.
15 /// </summary>
16 /// <value>The harvester core for the extension.</value>
17 public IHarvesterCore Core { get; set; }
18
19 /// <summary>
20 /// Harvest a WiX document.
21 /// </summary>
22 /// <param name="argument">The argument for harvesting.</param>
23 /// <returns>The harvested Fragments.</returns>
24 public abstract Wix.Fragment[] Harvest(string argument);
25 }
26}
diff --git a/src/tools/heat/Extensibility/BaseHeatExtension.cs b/src/tools/heat/Extensibility/BaseHeatExtension.cs
new file mode 100644
index 00000000..b76aaf62
--- /dev/null
+++ b/src/tools/heat/Extensibility/BaseHeatExtension.cs
@@ -0,0 +1,55 @@
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
3namespace WixToolset.Harvesters.Extensibility
4{
5 using System;
6 using WixToolset.Harvesters.Data;
7
8 /// <summary>
9 /// An extension for the WiX Toolset Harvester application.
10 /// </summary>
11 public abstract class BaseHeatExtension : IHeatExtension
12 {
13 /// <summary>
14 /// Gets or sets the heat core for the extension.
15 /// </summary>
16 /// <value>The heat core for the extension.</value>
17 public IHeatCore Core { get; set; }
18
19 /// <summary>
20 /// Gets the supported command line types for this extension.
21 /// </summary>
22 /// <value>The supported command line types for this extension.</value>
23 public virtual HeatCommandLineOption[] CommandLineTypes
24 {
25 get { return null; }
26 }
27
28 /// <summary>
29 /// Parse the command line options for this extension.
30 /// </summary>
31 /// <param name="type">The active harvester type.</param>
32 /// <param name="args">The option arguments.</param>
33 public virtual void ParseOptions(string type, string[] args)
34 {
35 }
36
37 /// <summary>
38 /// Determines if the index refers to an argument.
39 /// </summary>
40 /// <param name="args"></param>
41 /// <param name="index"></param>
42 /// <returns></returns>
43 public static bool IsValidArg(string[] args, int index)
44 {
45 if (args.Length <= index || String.IsNullOrEmpty(args[index]) || '/' == args[index][0] || '-' == args[index][0])
46 {
47 return false;
48 }
49 else
50 {
51 return true;
52 }
53 }
54 }
55}
diff --git a/src/tools/heat/Extensibility/BaseMutatorExtension.cs b/src/tools/heat/Extensibility/BaseMutatorExtension.cs
new file mode 100644
index 00000000..c36a8ed1
--- /dev/null
+++ b/src/tools/heat/Extensibility/BaseMutatorExtension.cs
@@ -0,0 +1,202 @@
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
3namespace WixToolset.Harvesters.Extensibility
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Text;
8 using Wix = WixToolset.Harvesters.Serialize;
9
10 /// <summary>
11 /// The base mutator extension. Any of these methods can be overridden to change
12 /// the behavior of the mutator.
13 /// </summary>
14 public abstract class BaseMutatorExtension : IMutatorExtension
15 {
16 /// <summary>
17 /// Gets or sets the mutator core for the extension.
18 /// </summary>
19 /// <value>The mutator core for the extension.</value>
20 public IHarvesterCore Core { get; set; }
21
22 /// <summary>
23 /// Gets the sequence of the extension.
24 /// </summary>
25 /// <value>The sequence of the extension.</value>
26 public abstract int Sequence { get; }
27
28 /// <summary>
29 /// Mutate a WiX document.
30 /// </summary>
31 /// <param name="wix">The Wix document element.</param>
32 public virtual void Mutate(Wix.Wix wix)
33 {
34 }
35
36 /// <summary>
37 /// Mutate a WiX document as a string.
38 /// </summary>
39 /// <param name="wixString">The Wix document element as a string.</param>
40 /// <returns>The mutated Wix document as a string.</returns>
41 public virtual string Mutate(string wixString)
42 {
43 return wixString;
44 }
45
46 /// <summary>
47 /// Generate unique MSI identifiers.
48 /// </summary>
49 protected class IdentifierGenerator
50 {
51 /// <summary>
52 ///
53 /// </summary>
54 public const int MaxProductIdentifierLength = 72;
55
56 /// <summary>
57 ///
58 /// </summary>
59 public const int MaxModuleIdentifierLength = 35;
60
61 private string baseName;
62 private int maxLength;
63 private Dictionary<string, object> existingIdentifiers;
64 private Dictionary<string, object> possibleIdentifiers;
65 private IHarvesterCore harvesterCore;
66
67 /// <summary>
68 /// Instantiate a new IdentifierGenerator.
69 /// </summary>
70 /// <param name="baseName">The base resource name to use if a resource name contains no usable characters.</param>
71 /// <param name="harvesterCore"></param>
72 public IdentifierGenerator(string baseName, IHarvesterCore harvesterCore)
73 {
74 this.baseName = baseName;
75 this.maxLength = IdentifierGenerator.MaxProductIdentifierLength;
76 this.existingIdentifiers = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
77 this.possibleIdentifiers = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
78 this.harvesterCore = harvesterCore;
79 }
80
81 /// <summary>
82 /// Gets or sets the maximum length for generated identifiers.
83 /// </summary>
84 /// <value>Maximum length for generated identifiers. (Default is 72.)</value>
85 public int MaxIdentifierLength
86 {
87 get { return this.maxLength; }
88 set { this.maxLength = value; }
89 }
90
91 /// <summary>
92 /// Index an existing identifier for collision detection.
93 /// </summary>
94 /// <param name="identifier">The identifier.</param>
95 public void IndexExistingIdentifier(string identifier)
96 {
97 if (null == identifier)
98 {
99 throw new ArgumentNullException("identifier");
100 }
101
102 this.existingIdentifiers[identifier] = null;
103 }
104
105 /// <summary>
106 /// Index a resource name for collision detection.
107 /// </summary>
108 /// <param name="name">The resource name.</param>
109 public void IndexName(string name)
110 {
111 if (null == name)
112 {
113 throw new ArgumentNullException("name");
114 }
115
116 string identifier = this.CreateIdentifier(name, 0);
117
118 if (this.possibleIdentifiers.ContainsKey(identifier))
119 {
120 this.possibleIdentifiers[identifier] = String.Empty;
121 }
122 else
123 {
124 this.possibleIdentifiers.Add(identifier, null);
125 }
126 }
127
128 /// <summary>
129 /// Get the identifier for the given resource name.
130 /// </summary>
131 /// <param name="name">The resource name.</param>
132 /// <returns>A legal MSI identifier.</returns>
133 public string GetIdentifier(string name)
134 {
135 if (null == name)
136 {
137 throw new ArgumentNullException("name");
138 }
139
140 for (int i = 0; i <= Int32.MaxValue; i++)
141 {
142 string identifier = this.CreateIdentifier(name, i);
143
144 if (this.existingIdentifiers.ContainsKey(identifier) || // already used
145 (0 == i && 0 != this.possibleIdentifiers.Count && null != this.possibleIdentifiers[identifier]) || // needs an index because its duplicated
146 (0 != i && this.possibleIdentifiers.ContainsKey(identifier))) // collides with another possible identifier
147 {
148 continue;
149 }
150 else // use this identifier
151 {
152 this.existingIdentifiers.Add(identifier, null);
153
154 return identifier;
155 }
156 }
157
158 throw new InvalidOperationException("Could not find a unique identifier for the given resource name.");
159 }
160
161 /// <summary>
162 /// Create a legal MSI identifier from a resource name and an index.
163 /// </summary>
164 /// <param name="name">The name of the resource for which an identifier should be created.</param>
165 /// <param name="index">An index to append to the end of the identifier to make it unique.</param>
166 /// <returns>A legal MSI identifier.</returns>
167 public string CreateIdentifier(string name, int index)
168 {
169 if (null == name)
170 {
171 throw new ArgumentNullException("name");
172 }
173
174 StringBuilder identifier = new StringBuilder();
175
176 // Convert the name to a standard MSI identifier
177 identifier.Append(this.harvesterCore.CreateIdentifierFromFilename(name));
178
179 // no legal identifier characters were found, use the base id instead
180 if (0 == identifier.Length)
181 {
182 identifier.Append(this.baseName);
183 }
184
185 // truncate the identifier if it's too long (reserve 3 characters for up to 99 collisions)
186 int adjustedMaxLength = this.MaxIdentifierLength - (index != 0 ? 3 : 0);
187 if (adjustedMaxLength < identifier.Length)
188 {
189 identifier.Length = adjustedMaxLength;
190 }
191
192 // if the index is not zero, then append it to the identifier name
193 if (0 != index)
194 {
195 identifier.AppendFormat("_{0}", index);
196 }
197
198 return identifier.ToString();
199 }
200 }
201 }
202}
diff --git a/src/tools/heat/Extensibility/IHarvester.cs b/src/tools/heat/Extensibility/IHarvester.cs
new file mode 100644
index 00000000..6d363b50
--- /dev/null
+++ b/src/tools/heat/Extensibility/IHarvester.cs
@@ -0,0 +1,31 @@
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
3namespace WixToolset.Harvesters.Extensibility
4{
5 using Wix = WixToolset.Harvesters.Serialize;
6
7 /// <summary>
8 /// Interface for the harvester.
9 /// </summary>
10 public interface IHarvester
11 {
12 /// <summary>
13 /// Gets or sets the harvester core for the extension.
14 /// </summary>
15 /// <value>The harvester core for the extension.</value>
16 IHarvesterCore Core { get; }
17
18 /// <summary>
19 /// Gets or sets the extension.
20 /// </summary>
21 /// <value>The extension.</value>
22 IHarvesterExtension Extension { get; set; }
23
24 /// <summary>
25 /// Harvest wix authoring.
26 /// </summary>
27 /// <param name="argument">The argument for harvesting.</param>
28 /// <returns>The harvested wix authoring.</returns>
29 Wix.Wix Harvest(string argument);
30 }
31}
diff --git a/src/tools/heat/Extensibility/IHarvesterCore.cs b/src/tools/heat/Extensibility/IHarvesterCore.cs
new file mode 100644
index 00000000..3c34b8a1
--- /dev/null
+++ b/src/tools/heat/Extensibility/IHarvesterCore.cs
@@ -0,0 +1,51 @@
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
3namespace WixToolset.Harvesters.Extensibility
4{
5 using WixToolset.Extensibility.Services;
6
7 /// <summary>
8 /// The WiX Toolset harvester core.
9 /// </summary>
10 public interface IHarvesterCore
11 {
12 /// <summary>
13 ///
14 /// </summary>
15 IMessaging Messaging { get; set; }
16
17 /// <summary>
18 /// Gets or sets the value of the extension argument passed to heat.
19 /// </summary>
20 /// <value>The extension argument.</value>
21 string ExtensionArgument { get; set; }
22
23 /// <summary>
24 /// Gets or sets the value of the root directory that is being harvested.
25 /// </summary>
26 /// <value>The root directory being harvested.</value>
27 string RootDirectory { get; set; }
28
29 /// <summary>
30 /// Create an identifier based on passed file name
31 /// </summary>
32 /// <param name="filename">File name to generate identifer from</param>
33 /// <returns></returns>
34 string CreateIdentifierFromFilename(string filename);
35
36 /// <summary>
37 /// Generate an identifier by hashing data from the row.
38 /// </summary>
39 /// <param name="prefix">Three letter or less prefix for generated row identifier.</param>
40 /// <param name="args">Information to hash.</param>
41 /// <returns>The generated identifier.</returns>
42 string GenerateIdentifier(string prefix, params string[] args);
43
44 /// <summary>
45 /// Resolves a file's path if the Wix.File.Source value starts with "SourceDir\".
46 /// </summary>
47 /// <param name="fileSource">The Wix.File.Source value with "SourceDir\".</param>
48 /// <returns>The full path of the file.</returns>
49 string ResolveFilePath(string fileSource);
50 }
51}
diff --git a/src/tools/heat/Extensibility/IHarvesterExtension.cs b/src/tools/heat/Extensibility/IHarvesterExtension.cs
new file mode 100644
index 00000000..5125ea32
--- /dev/null
+++ b/src/tools/heat/Extensibility/IHarvesterExtension.cs
@@ -0,0 +1,14 @@
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
3namespace WixToolset.Harvesters.Extensibility
4{
5 using Wix = WixToolset.Harvesters.Serialize;
6
7#pragma warning disable 1591 // TODO: add documentation
8 public interface IHarvesterExtension
9 {
10 IHarvesterCore Core { get; set; }
11
12 Wix.Fragment[] Harvest(string argument);
13 }
14}
diff --git a/src/tools/heat/Extensibility/IHeatCore.cs b/src/tools/heat/Extensibility/IHeatCore.cs
new file mode 100644
index 00000000..0aa01b62
--- /dev/null
+++ b/src/tools/heat/Extensibility/IHeatCore.cs
@@ -0,0 +1,29 @@
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
3namespace WixToolset.Harvesters.Extensibility
4{
5 using WixToolset.Extensibility.Services;
6
7 /// <summary>
8 /// The WiX Toolset Harvester application core.
9 /// </summary>
10 public interface IHeatCore
11 {
12 /// <summary>
13 /// Gets the harvester.
14 /// </summary>
15 /// <value>The harvester.</value>
16 IHarvester Harvester { get; }
17
18 /// <summary>
19 ///
20 /// </summary>
21 IMessaging Messaging { get; }
22
23 /// <summary>
24 /// Gets the mutator.
25 /// </summary>
26 /// <value>The mutator.</value>
27 IMutator Mutator { get; }
28 }
29}
diff --git a/src/tools/heat/Extensibility/IHeatExtension.cs b/src/tools/heat/Extensibility/IHeatExtension.cs
new file mode 100644
index 00000000..8a00da37
--- /dev/null
+++ b/src/tools/heat/Extensibility/IHeatExtension.cs
@@ -0,0 +1,16 @@
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
3namespace WixToolset.Harvesters.Extensibility
4{
5 using WixToolset.Harvesters.Data;
6
7#pragma warning disable 1591 // TODO: add documentation
8 public interface IHeatExtension
9 {
10 IHeatCore Core { get; set; }
11
12 HeatCommandLineOption[] CommandLineTypes { get; }
13
14 void ParseOptions(string type, string[] args);
15 }
16}
diff --git a/src/tools/heat/Extensibility/IMutator.cs b/src/tools/heat/Extensibility/IMutator.cs
new file mode 100644
index 00000000..c936339e
--- /dev/null
+++ b/src/tools/heat/Extensibility/IMutator.cs
@@ -0,0 +1,44 @@
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
3namespace WixToolset.Harvesters.Extensibility
4{
5 using Wix = WixToolset.Harvesters.Serialize;
6
7 /// <summary>
8 /// Interface for a mutator.
9 /// </summary>
10 public interface IMutator
11 {
12 /// <summary>
13 /// Gets or sets the harvester core for the extension.
14 /// </summary>
15 /// <value>The harvester core for the extension.</value>
16 IHarvesterCore Core { get; }
17
18 /// <summary>
19 /// Gets or sets the value of the extension argument passed to heat.
20 /// </summary>
21 /// <value>The extension argument.</value>
22 string ExtensionArgument { get; }
23
24 /// <summary>
25 /// Adds a mutator extension.
26 /// </summary>
27 /// <param name="mutatorExtension">The mutator extension to add.</param>
28 void AddExtension(IMutatorExtension mutatorExtension);
29
30 /// <summary>
31 /// Mutate a WiX document.
32 /// </summary>
33 /// <param name="wix">The Wix document element.</param>
34 /// <returns>true if mutation was successful</returns>
35 bool Mutate(Wix.Wix wix);
36
37 /// <summary>
38 /// Mutate a WiX document.
39 /// </summary>
40 /// <param name="wixString">The Wix document as a string.</param>
41 /// <returns>The mutated Wix document as a string if mutation was successful, else null.</returns>
42 string Mutate(string wixString);
43 }
44}
diff --git a/src/tools/heat/Extensibility/IMutatorExtension.cs b/src/tools/heat/Extensibility/IMutatorExtension.cs
new file mode 100644
index 00000000..b81f586e
--- /dev/null
+++ b/src/tools/heat/Extensibility/IMutatorExtension.cs
@@ -0,0 +1,18 @@
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
3namespace WixToolset.Harvesters.Extensibility
4{
5 using Wix = WixToolset.Harvesters.Serialize;
6
7#pragma warning disable 1591 // TODO: add documentation
8 public interface IMutatorExtension
9 {
10 IHarvesterCore Core { get; set; }
11
12 int Sequence { get; }
13
14 void Mutate(Wix.Wix wix);
15
16 string Mutate(string wixString);
17 }
18}