summaryrefslogtreecommitdiff
path: root/src/tools/heat/Extensibility
diff options
context:
space:
mode:
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}