Skip to content
This repository was archived by the owner on Feb 12, 2025. It is now read-only.

Commit 3fbbc5e

Browse files
author
Sergii Lutai
committed
added CustomLabeller with tests
CustomLabeller allows generate label with plain cs code
1 parent bba79ac commit 3fbbc5e

File tree

4 files changed

+229
-0
lines changed

4 files changed

+229
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
using Exortech.NetReflector;
2+
using NUnit.Framework;
3+
using ThoughtWorks.CruiseControl.Core.Label;
4+
5+
namespace ThoughtWorks.CruiseControl.UnitTests.Core.Label
6+
{
7+
[TestFixture]
8+
public class CustomLabellerTest : IntegrationFixture
9+
{
10+
private CustomLabeller labeller;
11+
12+
private string exampleCode = @"
13+
14+
if (
15+
integrationResult != null
16+
&& integrationResult.LastIntegration != null
17+
&& !integrationResult.LastIntegration.IsInitial()
18+
)
19+
{
20+
if (integrationResult.LastIntegration.Status == ThoughtWorks.CruiseControl.Remote.IntegrationStatus.Success)
21+
{
22+
System.Version lastVersion = System.Version.Parse(integrationResult.LastIntegration.Label);
23+
System.Version nextVersion = new System.Version(lastVersion.Major, lastVersion.Minor, lastVersion.Build, lastVersion.Revision + 1);
24+
ret = nextVersion.ToString();
25+
}
26+
else
27+
{
28+
ret = integrationResult.LastIntegration.Label;
29+
}
30+
}
31+
else
32+
{
33+
ret = new System.Version(1, 1, 1, 1).ToString();
34+
}
35+
36+
37+
";
38+
39+
[SetUp]
40+
public void SetUp()
41+
{
42+
labeller = new CustomLabeller();
43+
}
44+
45+
[Test]
46+
public void GenerateInitialLabelWoCode()
47+
{
48+
Assert.AreEqual("0.0.0.0", labeller.Generate(InitialIntegrationResult()));
49+
}
50+
51+
[Test]
52+
public void GenerateLabelWoCode()
53+
{
54+
Assert.AreEqual("0.0.0.0", labeller.Generate(SuccessfulResult("35")));
55+
}
56+
57+
[Test]
58+
public void GenerateNextLabel()
59+
{
60+
labeller.CsCode = @"ret = ""somelabel"";";
61+
Assert.AreEqual("somelabel", labeller.Generate(SuccessfulResult("previouslabel")));
62+
}
63+
64+
[Test]
65+
public void GenerateInitialLabel()
66+
{
67+
labeller.CsCode = @"ret = ""somelabel"";";
68+
Assert.AreEqual("somelabel", labeller.Generate(SuccessfulResult("previouslabel")));
69+
}
70+
71+
[Test]
72+
public void GenerateInitialLabelWithExampleCode()
73+
{
74+
labeller.CsCode = exampleCode;
75+
Assert.AreEqual("1.1.1.1", labeller.Generate(InitialIntegrationResult()));
76+
}
77+
78+
[Test]
79+
public void GenerateNextLabelWithExampleCode()
80+
{
81+
labeller.CsCode = exampleCode;
82+
Assert.AreEqual("1.2.3.5", labeller.Generate(SuccessfulResult("1.2.3.4")));
83+
}
84+
85+
[Test]
86+
public void GenerateSameLabelWithExampleCode()
87+
{
88+
labeller.CsCode = exampleCode;
89+
Assert.AreEqual("1.2.3.4", labeller.Generate(FailedResult("1.2.3.4")));
90+
}
91+
}
92+
}

project/UnitTests/UnitTests.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,7 @@
376376
<Compile Include="Core\Extensions\IntegrationPerformanceCountersExtensionTests.cs" />
377377
<Compile Include="Core\Extensions\DiskSpaceMonitorExtensionTests.cs" />
378378
<Compile Include="Core\Extensions\IntegrationRequestThrottleExtensionTests.cs" />
379+
<Compile Include="Core\Label\CustomLabellerTest.cs" />
379380
<Compile Include="Core\Publishers\ConditionalPublisherTests.cs" />
380381
<Compile Include="Core\Publishers\ManifestGeneratorTests.cs" />
381382
<Compile Include="Core\Publishers\ManifestImporterTests.cs" />

project/core/core.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@
372372
<Compile Include="label\DateLabeller.cs">
373373
<SubType>Code</SubType>
374374
</Compile>
375+
<Compile Include="label\CustomLabeller.cs" />
375376
<Compile Include="label\DefaultLabeller.cs">
376377
<SubType>Code</SubType>
377378
</Compile>

project/core/label/CustomLabeller.cs

+135
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
using System;
2+
using System.Linq;
3+
using System.Text.RegularExpressions;
4+
using Exortech.NetReflector;
5+
using ThoughtWorks.CruiseControl.Remote;
6+
using System.Globalization;
7+
using Microsoft.CSharp;
8+
using System.CodeDom.Compiler;
9+
using System.Reflection;
10+
11+
namespace ThoughtWorks.CruiseControl.Core.Label
12+
{
13+
/// <summary>
14+
/// <para>
15+
/// Allows CCNet create custom code-generated labels
16+
/// </para>
17+
/// <para>
18+
/// You can do this by specifying your own configuration of the default labeller in your project.
19+
/// </para>
20+
/// </summary>
21+
/// <title>Custom Labeller</title>
22+
/// <version>1.0</version>
23+
/// <example>
24+
/// <code>
25+
/// &lt;labeller type="customlabeller"&gt;
26+
/// &lt;cscode&gt;1&lt;/cscode&gt;
27+
/// &lt;/labeller&gt;
28+
/// </code>
29+
/// </example>
30+
[ReflectorType("customlabeller")]
31+
public class CustomLabeller
32+
: LabellerBase
33+
{
34+
/// <summary>
35+
/// Generates the specified integration result.
36+
/// </summary>
37+
/// <param name="integrationResult">The integration result.</param>
38+
/// <returns></returns>
39+
/// <remarks></remarks>
40+
public override string Generate(IIntegrationResult integrationResult)
41+
{
42+
MethodInfo method = this.CreateFunction(this.CsCode);
43+
string ret = (string)method.Invoke(null, new object[1] { integrationResult });
44+
return ret;
45+
}
46+
47+
[ReflectorProperty("usings", Required = false)]
48+
public string Usings { get; set; }
49+
50+
[ReflectorProperty("referencedassemblies", Required = false)]
51+
public string ReferencedAssemblies { get; set; }
52+
53+
[ReflectorProperty("cscode", Required = true)]
54+
public string CsCode { get; set; }
55+
56+
private string CSCodeWrapper
57+
{
58+
get
59+
{
60+
return @"
61+
62+
using System;
63+
using ThoughtWorks.CruiseControl.Core;
64+
using ThoughtWorks.CruiseControl.Remote;
65+
66+
namespace CustomLabelerGeneratorUserFunctions
67+
{
68+
public class CustomLabelerGenerator
69+
{
70+
public static string Generate(ThoughtWorks.CruiseControl.Core.IIntegrationResult integrationResult)
71+
{
72+
string ret = ""0.0.0.0"";
73+
<customCodeForReplace>
74+
return ret;
75+
}
76+
}
77+
}
78+
";
79+
}
80+
}
81+
82+
public MethodInfo CreateFunction(string function)
83+
{
84+
System.Text.StringBuilder usings = new System.Text.StringBuilder();
85+
if (!string.IsNullOrWhiteSpace(this.Usings))
86+
{
87+
foreach (var each in this.Usings.Split(';'))
88+
{
89+
if (!string.IsNullOrWhiteSpace(each))
90+
{
91+
usings.AppendFormat("using {0};", each);
92+
usings.AppendLine();
93+
}
94+
}
95+
}
96+
97+
string finalCode = usings.ToString() + CSCodeWrapper.Replace("<customCodeForReplace>", function);
98+
99+
CSharpCodeProvider provider = new CSharpCodeProvider();
100+
var parameters = new CompilerParameters();
101+
parameters.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);
102+
parameters.ReferencedAssemblies.Add(typeof(ThoughtWorks.CruiseControl.Remote.IntegrationStatus).Assembly.Location);
103+
if (!string.IsNullOrWhiteSpace(this.ReferencedAssemblies))
104+
{
105+
foreach (var each in this.ReferencedAssemblies.Split(';'))
106+
{
107+
if (!string.IsNullOrWhiteSpace(each))
108+
{
109+
parameters.ReferencedAssemblies.Add(each);
110+
}
111+
}
112+
}
113+
114+
parameters.GenerateInMemory = true;
115+
parameters.GenerateExecutable = false;
116+
parameters.IncludeDebugInformation = false;
117+
CompilerResults results = provider.CompileAssemblyFromSource(parameters, finalCode);
118+
if (results.Errors != null && results.Errors.Count > 0)
119+
{
120+
var path = System.IO.Path.GetTempFileName();
121+
System.IO.File.WriteAllText(path, finalCode);
122+
foreach (var each in results.Errors)
123+
{
124+
Console.WriteLine("ERROR in {0}: {1}", path, each);
125+
}
126+
127+
throw new ApplicationException("There are compilation errors. Please see " + path);
128+
}
129+
130+
131+
Type binaryFunction = results.CompiledAssembly.GetType("CustomLabelerGeneratorUserFunctions.CustomLabelerGenerator");
132+
return binaryFunction.GetMethod("Generate");
133+
}
134+
}
135+
}

0 commit comments

Comments
 (0)