Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for NBGV_ThisAssemblyNamespace property. #911

Merged
merged 1 commit into from
Mar 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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