Skip to content

BRO1615: File should have the XML copyright header

Every file starts with StyleCop's XML header: a <copyright> tag naming the file and the company, around the copyright text. Replaces StyleCop SA1633 (with StyleCop's default xmlHeader: true) and SA1634, SA1635, SA1636, SA1637, SA1638, SA1640 and SA1641. The rule does nothing until stylebro_file_header_company is set.

Example

root = true

[*.cs]
stylebro_file_header_company = Contoso

Before

// Order handling.

namespace Shop;

public class Order
{
}

After

// <copyright file="Example.cs" company="Contoso">
// Copyright (c) Contoso. All rights reserved.
// </copyright>

// Order handling.

namespace Shop;

public class Order
{
}

Before

// <copyright file="Orders.cs" company="Contoso Ltd">
//     Copyright (c) Contoso Ltd. All rights reserved.
// </copyright>
// <summary>Order handling.</summary>

namespace Shop;

public class Order
{
}

After

// <copyright file="Example.cs" company="Contoso">
// Copyright (c) Contoso. All rights reserved.
// </copyright>
// <summary>Order handling.</summary>

namespace Shop;

public class Order
{
}

Why

A team that wants a copyright notice in every file wants it to be the same notice, with the right file name after a file is renamed or copied. The SDK's IDE0073 writes a plain header (file_header_template) but not this XML form, which is StyleCop's default.

Teams with a plain header (StyleCop's xmlHeader: false) don't need this rule: use IDE0073 with file_header_template instead. Never turn on both. Each sees the other's header as a plain comment and writes its own above it, so every dotnet format run adds a header. stylebro-migrate turns on one of them (IDE0073 off with the XML header, BRO1615 off with a plain one or without a companyName), and stylebro-migrate init turns BRO1615 off when the repository has a file_header_template.

Configuration

[*.cs]
# Required: the rule is off until this is set. Written into company="...".
stylebro_file_header_company = Contoso
# The copyright text (default: StyleCop's). '\n' starts a new line; {companyName} and {fileName} are filled in.
stylebro_file_header_copyright = Copyright (c) {companyName}. All rights reserved.
# Optional: a line written above and below a new header (StyleCop's headerDecoration).
stylebro_file_header_decoration = -----------------------------------------------------------------------

StyleCop's custom variables from stylecop.json aren't supported as such; stylebro-migrate writes their values into the copyright text.

An .editorconfig value ends at a ; or # (also mid-line, in the .NET 10 SDK too) and loses the spaces at its ends. All three settings read escapes for those: \u003B for ;, \u0023 for #, \u0020 for a space (at either end), \u005C for a backslash, any other \uXXXX too. stylebro-migrate writes them:

stylebro_file_header_copyright = \u0020\u0020\u0020\u0020Copyright (c) {companyName}.\n\n    but WITHOUT ANY WARRANTY\u003B without even the implied warranty of

How the fix works

  • No header (code, a directive or a /// comment first): the header is added at the top, followed by a blank line.
  • A header that isn't XML (plain // comments): if its text is the configured copyright text, it becomes the XML header. Any other comment is kept: the new header goes above it, separated by a blank line. (StyleCop's fix deletes it.)
  • An XML header without a <copyright> tag: the tag is added at the top of the header, so a <summary> and any //----- border stay.
  • A wrong <copyright> tag (file name, company or text): only the tag's lines are rewritten; everything else in the header stays.

The text is compared like StyleCop does: line by line, ignoring whitespace at the start and end of each line, so // Copyright ... and a tag on one line are fine. The file name is compared case-sensitively.

Not reported

  • Files without code (empty or whitespace only), and generated files.
  • A header in a /* */ comment (rare; StyleCop checks it).
  • A broken XML header that already has a <copyright tag (for example a missing </copyright>): a person has to repair it, and adding a second header would only make it worse.
  • A <copyright> tag that shares its first or last line with other text, since only whole lines are rewritten.

Compared with StyleCop

  • The fix gives the same headers as StyleCop's, except that it never deletes a comment: StyleCop's fix replaces a plain comment header (license text, notes) with the XML header.
  • One rule instead of eight: StyleCop's SA1634-SA1641 each report one problem (sometimes three at the same place); the message here lists all of them.
  • A missing header is reported on the first line of code instead of at the start of the file, so a #pragma warning disable BRO1615 at the top of the file can suppress it.
  • StyleCop has the header rules on by default with the company PlaceholderCompany; this rule is off until you name the company, so nobody ends up with placeholder headers.
  • SA1639 (a <summary> in the header, off by default in StyleCop) isn't covered: the summary has to be written by a person.