Skip to content

Commit

Permalink
Merge pull request #911 from alexrp/main
Browse files Browse the repository at this point in the history
Add support for `NBGV_ThisAssemblyNamespace` property.
  • Loading branch information
AArnott committed Mar 28, 2023
2 parents 56b1dac + b09b391 commit 6d30af4
Show file tree
Hide file tree
Showing 3 changed files with 241 additions and 17 deletions.
77 changes: 60 additions & 17 deletions src/Nerdbank.GitVersioning.Tasks/AssemblyVersionInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ public class AssemblyVersionInfo : Microsoft.Build.Utilities.Task

public string RootNamespace { get; set; }

public string ThisAssemblyNamespace { get; set; }

public string AssemblyOriginatorKeyFile { get; set; }

public string AssemblyKeyContainerName { get; set; }
Expand Down Expand Up @@ -112,14 +114,15 @@ public class AssemblyVersionInfo : Microsoft.Build.Utilities.Task

public string BuildCode()
{
this.generator = this.CreateGenerator();
this.generator = this.CreateGenerator(this.ThisAssemblyNamespace, this.RootNamespace);

if (this.generator is object)
{
this.generator.AddComment(FileHeaderComment);
this.generator.AddBlankLine();
this.generator.AddAnalysisSuppressions();
this.generator.AddBlankLine();
this.generator.EmitNamespaceIfRequired(this.RootNamespace ?? "AssemblyInfo");

this.GenerateAssemblyAttributes();

if (this.EmitThisAssemblyClass)
Expand Down Expand Up @@ -368,6 +371,7 @@ private IEnumerable<CodeAttributeDeclaration> CreateAssemblyAttributes()

private void GenerateAssemblyAttributes()
{
this.generator.StartAssemblyAttributes();
this.generator.DeclareAttribute(typeof(AssemblyVersionAttribute), this.AssemblyVersion);
this.generator.DeclareAttribute(typeof(AssemblyFileVersionAttribute), this.AssemblyFileVersion);
this.generator.DeclareAttribute(typeof(AssemblyInformationalVersionAttribute), this.AssemblyInformationalVersion);
Expand Down Expand Up @@ -560,18 +564,23 @@ private void GenerateThisAssemblyClass()
this.generator.EndThisAssemblyClass();
}

private CodeGenerator CreateGenerator()
private CodeGenerator CreateGenerator(string thisAssemblyNamespace, string rootNamespace)
{
// The C#/VB generators did not emit namespaces in past versions of NB.GV, so for compatibility, only check the
// new ThisAssemblyNamespace property for these.
var userNs = !string.IsNullOrEmpty(thisAssemblyNamespace) ? thisAssemblyNamespace : null;

switch (this.CodeLanguage.ToLowerInvariant())
{
case "c#":
return new CSharpCodeGenerator();
return new CSharpCodeGenerator(userNs);
case "visual basic":
case "visualbasic":
case "vb":
return new VisualBasicCodeGenerator();
return new VisualBasicCodeGenerator(userNs);
case "f#":
return new FSharpCodeGenerator();
// The F# generator must emit a namespace, so it respects both ThisAssemblyNamespace and RootNamespace.
return new FSharpCodeGenerator(userNs ?? (!string.IsNullOrEmpty(rootNamespace) ? rootNamespace : "AssemblyInfo"));
default:
return null;
}
Expand Down Expand Up @@ -626,13 +635,16 @@ private bool TryReadKeyInfo(out string publicKey, out string publicKeyToken)

private abstract class CodeGenerator
{
internal CodeGenerator()
internal CodeGenerator(string ns)
{
this.CodeBuilder = new StringBuilder();
this.Namespace = ns;
}

protected StringBuilder CodeBuilder { get; }

protected string Namespace { get; }

protected virtual IEnumerable<string> WarningCodesToSuppress { get; } = new string[]
{
"CA2243", // Attribute string literals should parse correctly
Expand All @@ -642,6 +654,10 @@ internal CodeGenerator()

internal abstract void AddComment(string comment);

internal virtual void StartAssemblyAttributes()
{
}

internal abstract void DeclareAttribute(Type type, string arg);

internal abstract void StartThisAssemblyClass();
Expand All @@ -654,14 +670,6 @@ internal CodeGenerator()

internal abstract void EndThisAssemblyClass();

/// <summary>
/// Gives languages that *require* a namespace a chance to emit such.
/// </summary>
/// <param name="ns">The RootNamespace of the project.</param>
internal virtual void EmitNamespaceIfRequired(string ns)
{
}

internal string GetCode() => this.CodeBuilder.ToString();

internal void AddBlankLine()
Expand All @@ -683,6 +691,11 @@ protected void AddCodeComment(string comment, string token)

private class FSharpCodeGenerator : CodeGenerator
{
public FSharpCodeGenerator(string ns)
: base(ns)
{
}

internal override void AddAnalysisSuppressions()
{
this.CodeBuilder.AppendLine($"#nowarn {string.Join(" ", this.WarningCodesToSuppress.Select(c => $"\"{c}\""))}");
Expand All @@ -708,9 +721,9 @@ internal override void AddThisAssemblyMember(string name, DateTime value)
this.CodeBuilder.AppendLine($" static member internal {name} = new System.DateTime({value.Ticks}L, System.DateTimeKind.Utc)");
}

internal override void EmitNamespaceIfRequired(string ns)
internal override void StartAssemblyAttributes()
{
this.CodeBuilder.AppendLine($"namespace {ns}");
this.CodeBuilder.AppendLine($"namespace {this.Namespace}");
}

internal override void DeclareAttribute(Type type, string arg)
Expand Down Expand Up @@ -738,6 +751,11 @@ internal override void StartThisAssemblyClass()

private class CSharpCodeGenerator : CodeGenerator
{
public CSharpCodeGenerator(string ns)
: base(ns)
{
}

internal override void AddAnalysisSuppressions()
{
this.CodeBuilder.AppendLine($"#pragma warning disable {string.Join(", ", this.WarningCodesToSuppress)}");
Expand All @@ -755,6 +773,11 @@ internal override void DeclareAttribute(Type type, string arg)

internal override void StartThisAssemblyClass()
{
if (this.Namespace is { } ns)
{
this.CodeBuilder.AppendLine($"namespace {ns} {{");
}

this.CodeBuilder.AppendLine($"#if {CompilerDefinesAroundGeneratedCodeAttribute}");
this.CodeBuilder.AppendLine($"[System.CodeDom.Compiler.GeneratedCode(\"{GeneratorName}\",\"{GeneratorVersion}\")]");
this.CodeBuilder.AppendLine("#endif");
Expand Down Expand Up @@ -782,11 +805,21 @@ internal override void AddThisAssemblyMember(string name, DateTime value)
internal override void EndThisAssemblyClass()
{
this.CodeBuilder.AppendLine("}");

if (this.Namespace is not null)
{
this.CodeBuilder.AppendLine("}");
}
}
}

private class VisualBasicCodeGenerator : CodeGenerator
{
public VisualBasicCodeGenerator(string ns)
: base(ns)
{
}

internal override void AddAnalysisSuppressions()
{
this.CodeBuilder.AppendLine($"#Disable Warning {string.Join(", ", this.WarningCodesToSuppress)}");
Expand All @@ -804,6 +837,11 @@ internal override void DeclareAttribute(Type type, string arg)

internal override void StartThisAssemblyClass()
{
if (this.Namespace is { } ns)
{
this.CodeBuilder.AppendLine($"Namespace {ns}");
}

this.CodeBuilder.AppendLine($"#If {CompilerDefinesAroundExcludeFromCodeCoverageAttribute.Replace("||", " Or ")} Then");
this.CodeBuilder.AppendLine($"<System.CodeDom.Compiler.GeneratedCode(\"{GeneratorName}\",\"{GeneratorVersion}\")>");
this.CodeBuilder.AppendLine("<System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage>");
Expand Down Expand Up @@ -834,6 +872,11 @@ internal override void AddThisAssemblyMember(string name, DateTime value)
internal override void EndThisAssemblyClass()
{
this.CodeBuilder.AppendLine("End Class");

if (this.Namespace is not null)
{
this.CodeBuilder.AppendLine("End Namespace");
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@
AssemblyInformationalVersion="$(AssemblyInformationalVersion)"
AssemblyName="$(AssemblyName)"
RootNamespace="$(RootNamespace)"
ThisAssemblyNamespace="$(NBGV_ThisAssemblyNamespace)"
AssemblyOriginatorKeyFile="$(AssemblyOriginatorKeyFile)"
AssemblyTitle="$(AssemblyTitle)"
AssemblyProduct="$(AssemblyProduct)"
Expand Down

0 comments on commit 6d30af4

Please sign in to comment.