Skip to content

Commit 8ec9808

Browse files
authored
Merge pull request #255 from kwpatrick/fix/149
Fix for issue #149 - Adding F# support for AssemblyInfo generation
2 parents fb1ec38 + cf0dd1a commit 8ec9808

File tree

3 files changed

+125
-16
lines changed

3 files changed

+125
-16
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using Nerdbank.GitVersioning.Tasks;
7+
using Xunit;
8+
9+
namespace NerdBank.GitVersioning.Tests
10+
{
11+
public class AssemblyInfoTest
12+
{
13+
[Fact]
14+
public void FSharpGenerator()
15+
{
16+
var info = new AssemblyVersionInfo();
17+
info.AssemblyCompany = "company";
18+
info.AssemblyFileVersion = "1.3.1.0";
19+
info.AssemblyVersion = "1.3.0.0";
20+
info.CodeLanguage = "f#";
21+
22+
var built = info.BuildCode();
23+
24+
var expected = @"//------------------------------------------------------------------------------
25+
// <auto-generated>
26+
// This code was generated by a tool.
27+
// Runtime Version:4.0.30319.42000
28+
//
29+
// Changes to this file may cause incorrect behavior and will be lost if
30+
// the code is regenerated.
31+
// </auto-generated>
32+
//------------------------------------------------------------------------------
33+
34+
namespace AssemblyInfo
35+
[<assembly: System.Reflection.AssemblyVersionAttribute(""1.3.0.0"")>]
36+
[<assembly: System.Reflection.AssemblyFileVersionAttribute(""1.3.1.0"")>]
37+
[<assembly: System.Reflection.AssemblyInformationalVersionAttribute("""")>]
38+
do()
39+
type internal ThisAssembly() =
40+
static member internal AssemblyVersion = ""1.3.0.0""
41+
static member internal AssemblyFileVersion = ""1.3.1.0""
42+
static member internal AssemblyCompany = ""company""
43+
static member internal RootNamespace = """"
44+
do()
45+
";
46+
Assert.Equal(expected, built);
47+
}
48+
}
49+
}

src/NerdBank.GitVersioning.Tests/NerdBank.GitVersioning.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
<EmbeddedResource Include="repos\submodules.7z" />
2121
</ItemGroup>
2222
<ItemGroup>
23+
<ProjectReference Include="..\MSBuildExtensionTask\MSBuildExtensionTask.csproj" />
2324
<ProjectReference Include="..\Nerdbank.GitVersioning.Tasks\Nerdbank.GitVersioning.Tasks.csproj" />
2425
<ProjectReference Include="..\NerdBank.GitVersioning\NerdBank.GitVersioning.csproj" />
2526
</ItemGroup>

src/Nerdbank.GitVersioning.Tasks/AssemblyVersionInfo.cs

Lines changed: 75 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using System.CodeDom;
55
using System.CodeDom.Compiler;
66
using System.Collections.Generic;
7-
using System.Diagnostics;
87
using System.IO;
98
using System.Linq;
109
using System.Reflection;
@@ -22,7 +21,7 @@ public class AssemblyVersionInfo : Task
2221
};
2322

2423
private CodeCompileUnit generatedFile;
25-
#else
24+
#endif
2625
private const string FileHeaderComment = @"------------------------------------------------------------------------------
2726
<auto-generated>
2827
This code was generated by a tool.
@@ -36,8 +35,6 @@ the code is regenerated.
3635

3736
private CodeGenerator generator;
3837

39-
#endif
40-
4138
[Required]
4239
public string CodeLanguage { get; set; }
4340

@@ -101,7 +98,17 @@ public override bool Execute()
10198
}
10299
else
103100
{
104-
this.Log.LogError("CodeDomProvider not available for language: {0}. No version info will be embedded into assembly.", this.CodeLanguage);
101+
// attempt to use local codegen
102+
string fileContent = this.BuildCode();
103+
if (fileContent != null)
104+
{
105+
Directory.CreateDirectory(Path.GetDirectoryName(this.OutputFile));
106+
Utilities.FileOperationWithRetry(() => File.WriteAllText(this.OutputFile, fileContent));
107+
}
108+
else
109+
{
110+
this.Log.LogError("CodeDomProvider not available for language: {0}. No version info will be embedded into assembly.", this.CodeLanguage);
111+
}
105112
}
106113

107114
return !this.Log.HasLoggedErrors;
@@ -216,24 +223,36 @@ private static CodeAttributeDeclaration DeclareAttribute(Type attributeType, par
216223
#else
217224

218225
public override bool Execute()
226+
{
227+
string fileContent = this.BuildCode();
228+
if (fileContent != null)
229+
{
230+
Directory.CreateDirectory(Path.GetDirectoryName(this.OutputFile));
231+
Utilities.FileOperationWithRetry(() => File.WriteAllText(this.OutputFile, fileContent));
232+
}
233+
234+
return !this.Log.HasLoggedErrors;
235+
}
236+
237+
#endif
238+
239+
public string BuildCode()
219240
{
220241
this.generator = this.CreateGenerator();
221242
if (this.generator != null)
222243
{
223244
this.generator.AddComment(FileHeaderComment);
224245
this.generator.AddBlankLine();
225-
this.CreateAssemblyAttributes();
226-
this.CreateThisAssemblyClass();
227-
228-
Directory.CreateDirectory(Path.GetDirectoryName(this.OutputFile));
229-
string fileContent = this.generator.GetCode();
230-
Utilities.FileOperationWithRetry(() => File.WriteAllText(this.OutputFile, fileContent));
246+
this.generator.EmitNamespaceIfRequired(this.RootNamespace ?? "AssemblyInfo");
247+
this.GenerateAssemblyAttributes();
248+
this.GenerateThisAssemblyClass();
249+
return this.generator.GetCode();
231250
}
232251

233-
return !this.Log.HasLoggedErrors;
252+
return null;
234253
}
235254

236-
private void CreateAssemblyAttributes()
255+
private void GenerateAssemblyAttributes()
237256
{
238257
this.generator.DeclareAttribute(typeof(AssemblyVersionAttribute), this.AssemblyVersion);
239258
this.generator.DeclareAttribute(typeof(AssemblyFileVersionAttribute), this.AssemblyFileVersion);
@@ -262,7 +281,7 @@ private void CreateAssemblyAttributes()
262281
}
263282
}
264283

265-
private void CreateThisAssemblyClass()
284+
private void GenerateThisAssemblyClass()
266285
{
267286
this.generator.StartThisAssemblyClass();
268287

@@ -302,6 +321,7 @@ private void CreateThisAssemblyClass()
302321

303322
this.generator.EndThisAssemblyClass();
304323
}
324+
305325
private CodeGenerator CreateGenerator()
306326
{
307327
switch (this.CodeLanguage.ToLowerInvariant())
@@ -312,8 +332,9 @@ private CodeGenerator CreateGenerator()
312332
case "visualbasic":
313333
case "vb":
314334
return new VisualBasicCodeGenerator();
335+
case "f#":
336+
return new FSharpCodeGenerator();
315337
default:
316-
this.Log.LogError("Code provider not available for language: {0}. No version info will be embedded into assembly.", this.CodeLanguage);
317338
return null;
318339
}
319340
}
@@ -337,6 +358,12 @@ internal CodeGenerator()
337358

338359
internal abstract void EndThisAssemblyClass();
339360

361+
/// <summary>
362+
/// Gives languages that *require* a namespace a chance to emit such.
363+
/// </summary>
364+
/// <param name="ns">The RootNamespace of the project.</param>
365+
internal virtual void EmitNamespaceIfRequired(string ns) { }
366+
340367
internal string GetCode() => this.codeBuilder.ToString();
341368

342369
internal void AddBlankLine()
@@ -356,6 +383,39 @@ protected void AddCodeComment(string comment, string token)
356383
}
357384
}
358385

386+
private class FSharpCodeGenerator : CodeGenerator
387+
{
388+
internal override void AddComment(string comment)
389+
{
390+
this.AddCodeComment(comment, "//");
391+
}
392+
393+
internal override void AddThisAssemblyMember(string name, string value)
394+
{
395+
this.codeBuilder.AppendLine($" static member internal {name} = \"{value}\"");
396+
}
397+
398+
internal override void EmitNamespaceIfRequired(string ns)
399+
{
400+
this.codeBuilder.AppendLine($"namespace {ns}");
401+
}
402+
403+
internal override void DeclareAttribute(Type type, string arg)
404+
{
405+
this.codeBuilder.AppendLine($"[<assembly: {type.FullName}(\"{arg}\")>]");
406+
}
407+
408+
internal override void EndThisAssemblyClass()
409+
{
410+
this.codeBuilder.AppendLine("do()");
411+
}
412+
413+
internal override void StartThisAssemblyClass()
414+
{
415+
this.codeBuilder.AppendLine("do()\r\ntype internal ThisAssembly() =");
416+
}
417+
}
418+
359419
private class CSharpCodeGenerator : CodeGenerator
360420
{
361421
internal override void AddComment(string comment)
@@ -411,7 +471,6 @@ internal override void EndThisAssemblyClass()
411471
this.codeBuilder.AppendLine("End Class");
412472
}
413473
}
414-
#endif
415474

416475
private static string ToHex(byte[] data)
417476
{

0 commit comments

Comments
 (0)