Epsitec.Tool.Format 0.9.3.2624

Prefix Reserved
dotnet tool install --global Epsitec.Tool.Format --version 0.9.3.2624
                    
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest
                    
if you are setting up this repo
dotnet tool install --local Epsitec.Tool.Format --version 0.9.3.2624
                    
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=Epsitec.Tool.Format&version=0.9.3.2624
                    
nuke :add-package Epsitec.Tool.Format --version 0.9.3.2624
                    

author: Pierre Arnaud maintainer: Pierre Arnaud tags:

  • technical

Epsitec Source Format Tool

epsitec-format is a dotnet tool that reformats C# source text according to advanced, line-based rules. It is a faithful port of the Python scripts in briefcases/_tools (check_comment_truncation.py, fix_cs_indentation.py, check_initializer_indent.py), validated against a checked-in golden oracle.

The tool is purely line/text based (regex plus greedy word wrapping). It does not use Roslyn syntax trees, semantic analysis, or MSBuild, so it starts fast and has a minimal dependency surface. It is intentionally not part of the Symbolic.* family.

Installation

dotnet pack build-tools/Tool.Format/Tool.Format.csproj
dotnet tool install --global --add-source build-tools/Tool.Format/.nupkg epsitec-format

To uninstall:

dotnet tool uninstall --global epsitec-format

Publishing

Run zou-nuget.ps1 (beside this README) to pack the tool in Release and optionally publish it to nuget.org:

build-tools/Tool.Format/zou-nuget.ps1

It packs Tool.Format.csproj (a PackAsTool project) to build-tools/Tool.Format/.nupkg/, prints the resulting Epsitec.Tool.Format package (the dotnet tool exposing the epsitec-format command), and prompts before pushing with dotnet nuget push (API key from $env:NUGET_API_KEY). It mirrors the zou-nuget.ps1 scripts used by the other Epsitec NuGet packages.

Usage

epsitec-format [<targets>...]
               [--fix]
               [--rules comments,indent,initializers]
               [--max-columns <N>]
               [--json]

Options

  • <targets> — zero or more files, directories, or glob patterns (*, **). Defaults to the current directory (.). Directories are scanned recursively for *.cs; the bin, obj, and .git directories are skipped. Glob expansion uses Microsoft.Extensions.FileSystemGlobbing.
  • --fix — apply fixable rules in place. Absent means check mode (no writes).
  • --rules — comma-separated subset of comments, indent, initializers. Matching is case-insensitive; duplicates are collapsed preserving first-seen order. Absent means all three in canonical order. An unknown token, or an empty value, is an input error.
  • --max-columns — positive integer wrap width. Defaults to 79. Affects comment prose reflow only; separator normalization always targets 79 columns.
  • --json — emit the structured JSON report on stdout. Absent means a human-readable summary.

Examples

Check the current directory and print a human summary:

epsitec-format .

Emit the JSON report for one project:

epsitec-format MyProject --json

Apply fixes in place across a glob, then re-check (idempotent):

epsitec-format "MyProject/**/*.cs" --fix
epsitec-format "MyProject/**/*.cs"

Rule catalog

comments

Reflows contiguous // and /// comment prose runs so each line is as full as possible without exceeding the configured width, and normalizes /*****…*****/ separator lines to exactly 79 visual columns. Produces two issue kinds: comment_prose_reflow and separator_reflow.

The following comment shapes are deliberately preserved (never reflowed):

  • the file's first-line copyright block (the topmost block starting at line 1);
  • any block containing an XML <code> … </code> snippet;
  • ASCII-table and drawing blocks (aligned columns, rulers, spacious layouts);
  • JSON-style comment snippets delimited by { … };
  • standalone and inline XML-doc element lines (/// <summary>, /// <param …>…</param>);
  • // var … code-like comment lines;
  • decorative separators, bare labels, list markers, AAA markers (// Arrange), headers (Copyright, Author:), and lines containing a URL;
  • oversized lines whose final token is an XML element (optionally followed by . or ,) or that end with ;.

In addition, reflows are suppressed when they are negligible (every break column moves by 4 columns or less) or when every existing line already fits within the configured width plus a 10-column relaxed margin. Files whose first line contains <auto-generated are skipped entirely.

indent

Replaces tab-based leading indentation with spaces, using a tab width of 4 (next-multiple-of-4 tab stops). Only the leading whitespace run is expanded; tabs elsewhere on the line are left untouched. Each changed line is one tab_indentation issue.

initializers

Reports object-initializer braces indented deeper than their owning var … = new … line. Report-only: these issues are never auto-fixed, even with --fix. Each issue is one initializer_indent finding carrying a brace indent N, expected M detail. Gate CI on these with check mode.

Exit codes

Exit code Meaning
0 Check mode with zero issues, or a fix run that completed (including the no-change case).
1 Check mode only: at least one issue was found (nothing was written). The CI lint-gate signal.
2 Bad usage, unknown or empty --rules, non-positive --max-columns, or a literal target path that does not exist. A glob or directory matching zero .cs files is not an error (exits 0).
3 A fix-time safety check failed (file changed under the tool) or a read/write error occurred.

In fix mode, report-only initializers issues do not affect the exit code: a fix run that surfaces unfixable initializer issues still exits 0. Gate CI on those with check mode, which returns 1.

JSON report schema

--json emits a single UTF-8 JSON object on stdout with stable camelCase fields:

{
  "root": "<absolute run root>",
  "targets": ["..."],
  "maxColumns": 79,
  "fixMode": false,
  "rules": ["comments", "indent", "initializers"],
  "matchedFileCount": 0,
  "matchedFiles": ["..."],
  "issueCount": 0,
  "fixedIssueCount": 0,
  "modifiedFiles": ["..."],
  "issues": [
    {
      "rule": "comments",
      "kind": "comment_prose_reflow",
      "file": "Path/To/File.cs",
      "startLine": 12,
      "endLine": 14,
      "originalLines": ["..."],
      "proposedLines": ["..."],
      "fixable": true,
      "fixed": false,
      "detail": null
    }
  ]
}

detail is always present (serialized as JSON null when there is no note). originalLines and proposedLines are always arrays (single-element for separator_reflow). Integer fields are culture-invariant.

I/O contract

  • Read: files are decoded as UTF-8 (a leading BOM is tolerated and remembered). Lines are split on \n, with a trailing \r treated as part of the terminator, so both CRLF and LF split cleanly.
  • Write (only files the tool rewrites): UTF-8 without BOM, lines joined with \n (LF), and exactly one trailing \n. This matches .editorconfig (end_of_line = lf, charset = utf-8, insert_final_newline = true) and the Python reference.
  • Replacement lines never carry trailing whitespace. The tool does not trim trailing whitespace on lines it does not otherwise rewrite, and files with no applied fix are left byte-identical.

Relationship to the Python reference

The three rules are a faithful, line-based port of the briefcases/_tools Python scripts. The comments rule is validated by a golden-oracle parity test that compares the C# output against reference output captured from check_comment_truncation.py over a checked-in corpus. Where this document and the scripts disagree on a fine-grained detail, the scripts (and the golden oracle) are authoritative.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last Updated
0.9.3.2624 112 6/21/2026