Skip to content

Releases: belav/csharpier

1.0.2

24 May 16:27
07491be
Compare
Choose a tag to compare

What's Changed

Performance issues when supporting .gitignore. #1588

CSharpier was using a naive algorithm for parsing and evaluating gitignore rules that caused significant perfomance issues. @kevinboss reworked the implementation to drastically increate performance.

Exclude bin/ and obj/ directory content from xml formatting #1600

CSharpier now excludes all files in bin/ and obj/ by default.

Error on syntactically valid conditional with is #1612

The following c# is valid and compiles with 9.0.300+. CSharpier was updated to properly parse it.

var x = y is y ? [] : z ?? [];

Xml formatting with comments in text element inserts extra new lines #1607

CSharpier has some issues with formatting text that contained xml comments. That has been improved.

Input & expected output

<NoWarn>
  CA1031; <!-- Since this is not a library project, catching general exceptions is OK -->
  IDE0005; <!-- Allow unused usings -->
</NoWarn>

1.0.1

<NoWarn
    >
      CA1031;
    <!-- Since this is not a library project, catching general exceptions is OK -->

    
      IDE0005;
    <!-- Allow unused usings -->
</NoWarn>

Inconsistent formatting of single-line lambda expressions #1594

CSharpier 1.0.0 introduced a regression that caused the following formatting. This is now working as expected.

// input & expected output
        CallMethod(() => CallAnotherMethod______________________________________________________());
        CallMethod(() =>
            CallAnotherMethod______________________________________________________1()
        );
        CallMethod(() =>
            CallAnotherMethod______________________________________________________12()
        );
        CallMethod(() =>
            CallAnotherMethod______________________________________________________123()
        );

// 1.0.0
        CallMethod(() => CallAnotherMethod______________________________________________________());
        CallMethod(() => CallAnotherMethod______________________________________________________1()
        );
        CallMethod(() => CallAnotherMethod______________________________________________________12()
        );
        CallMethod(() =>
            CallAnotherMethod______________________________________________________123()
        );

Full Changelog: 1.0.1...1.0.2

1.0.1

26 Apr 02:05
4886792
Compare
Choose a tag to compare

What's Changed

CSharpier's support for .gitignore is causing performance issues #1584

The support for .gitignore has some major performance problems when there are a large number of .gitignore files and/or ignore rules. The feature has been disabled for now until it can be fixed.

CSharpier.MsBuild issues #1586

CSharpier.MsBuild was not properly logging errors when performing a formatting check. This would result in the build passing when files were not formatted.
Setting CSharpier_LogLevel was passing an invalid parameter of --loglevel to CSharpier, resulting in a build failure

Full Changelog: 1.0.0...1.0.1

1.0.0

22 Apr 13:11
d7d791e
Compare
Choose a tag to compare

Major Changes

Support for formatting XML #819

CSharpier now formats xml files by default. It will try to format ".csproj", ".props", ".targets", ".xml", ".config" as if they were xml.
If a file is not valid xml it will be treated as a warning.
The default indent size is 2 instead of 4

Performance Improvements

@TimothyMakkison put a lot of effort into improving the performance of CSharpier. These benchmark numbers show drastic improvement for both speed and memory usage.

Baseline

| Method                        | Mean     | Error   | StdDev  | Median   | Gen0       | Gen1      | Gen2      | Allocated |
|------------------------------ |---------:|--------:|--------:|---------:|-----------:|----------:|----------:|----------:|
| Default_CodeFormatter_Tests   | 233.3 ms | 4.63 ms | 8.23 ms | 229.7 ms | 11000.0000 | 4000.0000 | 1000.0000 | 101.41 MB |
| Default_CodeFormatter_Complex | 433.7 ms | 8.53 ms | 7.56 ms | 433.4 ms | 20000.0000 | 5000.0000 | 1000.0000 | 182.44 MB |

After Improvements

| Method                        | Mean      | Error    | StdDev   | Gen0      | Gen1      | Allocated |
|------------------------------ |----------:|---------:|---------:|----------:|----------:|----------:|
| Default_CodeFormatter_Tests   |  64.72 ms | 0.548 ms | 0.512 ms | 1666.6667 | 1000.0000 |  18.33 MB |
| Default_CodeFormatter_Complex | 137.83 ms | 2.730 ms | 4.708 ms | 3000.0000 | 1000.0000 |  30.78 MB |

Breaking Changes

ConfigurationFile - rename TabWidth to IndentSize #1377

In order to get consistency between an .editorconfig and .csharpierconfig the option TabWidth has been renamed to IndentSize. This is also a more accurate name considering by default indentation is done with spaces and not tabs.

Rework the CLI to use commands and arguments. #1321

The CLI has been reworked to use commands. This helps make it clear which arguments apply to which commands. The two common commands are below, see https://csharpier.com/docs/CLI for more details.

dotnet csharpier format .
dotnet csharpier check .

Changing the tool command to csharpier. Changing the assembly/exe to CSharpier #1418

Prior to 1.0.0 the tool command was dotnet-csharpier and assembly/exe were named dotnet_csharpier.
The tool command name was changed to just csharpier

  • Running a local tool remains the same dotnet csharpier --version
  • Running a global tool is changed to csharpier --version

The assembly/exe names have changed to just CSharpier

Support for ignoring files via a .gitignore #631

CSharpier now works as follows when determining if a file should be ignored.

  • .gitignore files are considered when determining if a file will be ignored. A .gitignore file at the same level as a given file will take priority over a .gitignore file above it in the directory tree.
  • If a .csharpierignore file is present at the same level or anywhere above the given file in the tree and it contains a pattern for a given file, that will take priority.
  • The patterns within .csharpierignore work the same as a .gitignore, with patterns lower in the file taking priority over patterns above
  • CSharpier does not currently look further up the directory tree for additional .csharpierignore files if it finds one. But it does look for .gitignore files. If there is demand this could be added later.

What's Changed

Add logging format argument and support for msbuild logs #1517

CSharpier now supports a --log-format argument. By default it will log with a console format.
With --log-format MsBuild CSharpier will produce logs in a format that allow jumping to files in the VisualStudio error list.

Thanks go to @moormaster for the contribution

Allow passing an .editorconfig file path into --config-path #1456

CSharpier now supports passing a path to an .editorconfig file when using the --config-path argument.

Always ignore any files in .git folder #1438

CSharpier will now ignore any files that are in a .git folder. Previously if the .git folder happened to contain an invalid c# file CSharpier would attempt to format it and report an error.

Avoid excessive file system watches for --server #1465

When CSharpier server was started, it would create file watches for all of the files within the directory the tool existed in. This can lead to some systems running out of the ability to monitor more files.

CSharpier server now uses a temporary empty content root to avoid creating all file watches.

Thanks go to @chklauser for the contribution

Smarter EditorConfig parsing #1228

Previously CSharpier was eagerly loading all .editorconfig files within a directory that it was asked to format. It now lazy loads them in a way that is performant and avoids loading and parsing editorconfigs that aren't needed.

Extra blank line before local scope block in global statement #1566

// input & expected output
int x = 1;

{
    int x = 2;
}

// 0.30.6
int x = 1;


{
    int x = 2;
}

Inconsistent indentation for parenthesis expression #1562

A statement being surrounded by parentheses affected the indentation in an inconsistent way.

// input & expected output
var b2 = 
    System.Environment.SpecialFolder.AdminTools
        is System.Environment.SpecialFolder.AdminTools
            or System.Environment.SpecialFolder.AdminTools
            or System.Environment.SpecialFolder.AdminTools;

var b2 = (
    System.Environment.SpecialFolder.AdminTools
        is System.Environment.SpecialFolder.AdminTools
            or System.Environment.SpecialFolder.AdminTools
            or System.Environment.SpecialFolder.AdminTools
);

// 0.30.6
var b2 =
    System.Environment.SpecialFolder.AdminTools
        is System.Environment.SpecialFolder.AdminTools
            or System.Environment.SpecialFolder.AdminTools
            or System.Environment.SpecialFolder.AdminTools;

var b2 = (
    System.Environment.SpecialFolder.AdminTools
    is System.Environment.SpecialFolder.AdminTools
        or System.Environment.SpecialFolder.AdminTools
        or System.Environment.SpecialFolder.AdminTools
);

Attribute on property accessor causes unnecessary newlines in formatting #1558

The logic around when to break properties with attributes has been adjusted. See the example for more details

public class ClassName
{
    [Obsolete]
    public string Property { [Obsolete] get; [Obsolete] set; }

    public int ShortProperty { get; [SomeAttribute] init; } = 20;

    public int CommandTimeout
    {
        get;
        [SomeAttribute]
        [SomeOtherAttribute]
        set;
    }

    public int CommandTimeout
    {
        [SomeAttribute(someValue)]
        get;
    }
}

Fluent multiline with comment re-formats incorrectly. #1556

When a single method in a fluent chain was commented out, csharpier would try to collapse the chain to a single line.

// input & expected output
builder
    .CallMethod()
    .CallMethod()
    .CallMethod()
    //.CallMethod()
;

// 0.30.6
builder.CallMethod().CallMethod().CallMethod()
//.CallMethod()
;

Comments on an invocation chain that began with a generic where breaking when they should not #1555

In some cases CSharpier was breaking an invocation chain when it should not.

// input & expected output

// CommentOnGenericDoesNotBreakChain
SomeObject<SomeThing>.SomeProperty.SomeOtherProperty = 1;

// CommentOnGenericDoesNotBreakChain
SomeObject<SomeThing>.SomeProperty.CallMethod();

// 0.30.6

// CommentOnGenericDoesNotBreakChain
SomeObject<SomeThing>
    .SomeProperty
    .SomeOtherProperty = 1;

// CommentOnGenericDoesNotBreakChain
SomeObject<SomeThing>.SomeProperty.CallMethod();

Comment in line before attribute causes unexpected line break after attribute #1553

CSharpier was breaking and indenting a parameter when it had a comment

// input & expected output
    public void SomeMethod(
        // Some Comment does not indent parameter
        [SomeAttribute] string someParameter
    ) { }

// 0.30.6
    public void SomeMethod(
        // Some Comment does not indent parameter
        [SomeAttribute]
            string someParameter
    ) { }

Huge oneliner with switch expression followed my method invocations #1546

CSharpier was keeping a method chain on a single line if it was invoked on a switch expression within parentheses.

// input & expected output
(
    someValue switch
    {
        someValue => 1,
        _ => 2,
    }
)
    .SomeLongMethodCall______________________________()
    .SomeLongMethodCall______________________________()
    .SomeLongMethodCall______________________________();

// 0.30.6
(
    someValue switch
    {
        someValue => 1,
        _ => 2,
    }
).SomeLongMethodCall______________________________().SomeLongMethodCall______________________________().SomeLongMethodCall______________________________();

Inconsisten...

Read more

0.30.6

10 Jan 16:57
ccaca15
Compare
Choose a tag to compare

What's Changed

Trailing comma is placed on new line if last enum value is followed by a comment #1429

// input
enum MyEnum
{
    First,
    Second // the second value
}

// 0.30.5
enum MyEnum
{
    First,
    Second // the second value
    ,
}

// 0.30.6
enum MyEnum
{
    First,
    Second, // the second value
}

Full Changelog: 0.30.5...0.30.6

0.30.5

03 Jan 17:26
Compare
Choose a tag to compare

What's Changed

Extra blank line added to file each time csharpier runs on this file #1426

When a file ended in a comment and that comment had multiple blank lines before it, a new blank line was being added each time it was formatted.
// input

// input
namespace MyCompany.MyNamespace;


// Comment block

// 0.30.4
namespace MyCompany.MyNamespace;



// Comment block

// 0.30.5
namespace MyCompany.MyNamespace;

// Comment block

**Full Changelog**: https://github.com/belav/csharpier/compare/0.30.4...0.30.5

0.30.4

28 Dec 02:41
064d35f
Compare
Choose a tag to compare

0.30.4

What's Changed

Formatting deletes unsafe modifier #1416

Formatting a using directive with an unsafe modifier resulted in the lose of the unsafe keyword

// input & expected output
using unsafe NvapiQueryInterface = delegate* unmanaged[Cdecl]<uint, nint>;

// 0.30.3
using NvapiQueryInterface = delegate* unmanaged[Cdecl]<uint, nint>;

CSharpier keeps adding a newline every time a file is formatted #1408

In some cases if a file ended with a comment, CSharpier would add a new extra blank line above the comment each time it formatted the file

// input & expected outpet
using System;

namespace MyCompany.MyNamespace;

// Comment block

// 0.30.3
using System;

namespace MyCompany.MyNamespace;


// Comment block

Full Changelog: 0.30.3...0.30.4

0.30.3

07 Dec 19:56
0bec7d2
Compare
Choose a tag to compare

What's Changed

CSharpier.MsBuild doesn't fail the github action anymore #1357

The changes for 1311 caused CSharpier.MsBuild to not report unformatted files as errors on linux.

Thanks go to @PetSerAl for the fix

0.30.2

22 Nov 16:56
384f7a1
Compare
Choose a tag to compare

What's Changed

CSharpier.MsBuild now uses DOTNET_HOST_PATH instead of just dotnet #1387

Use current dotnet binary from DOTNET_HOST_PATH instead of just dotnet.

Collection expression inside a dictionary adds unexpected new line #1390

// input & expected output
Dictionary<string, string[]> dictionary = new()
{
    {
        "Key",
        [
            "SomeValue__________________________________________",
            "SomeValue__________________________________________",
        ]
    },
};

// 0.30.1
Dictionary<string, string[]> dictionary = new()
{
    {
        "Key",

        [
            "SomeValue__________________________________________",
            "SomeValue__________________________________________",
        ]
    },
};

Failed syntax tree validation reported when trailing comma added before a trailing comment #1388

With the following code, CSharpier will add a trailing comma before the trailing comment.
CSharpier's syntax tree validation was incorrectly reporting this as a failure.

// input
var someObject = new SomeObject()
{
    Property1 = 1,
    Property2 = 2 // Trailing Comment
};

// output
var someObject = new SomeObject()
{
    Property1 = 1,
    Property2 = 2, // Trailing Comment
};

Full Changelog: 0.30.1...0.30.2

0.30.0

17 Nov 17:13
0425539
Compare
Choose a tag to compare

Breaking Changes

The CSharpier dotnet tool no longer supports net6 & net7.

What's Changed

Support C# 13 & dotnet 9. #1318

CSharpier now supports dotnet 9 along with formatting all C# 13 language features.

Inconsistent Formatting for new() Operator Compared to Explicit Object Constructors #1364

Implicit and explicit object initialization with constructors was not formatted consistently

// input & expected output
SomeObject someObject = new(
    someLongParameter___________________,
    someLongParameter___________________
)
{
    Property = longValue_______________________________________________________________________,
};

SomeObject someObject = new SomeObject(
    someLongParameter___________________,
    someLongParameter___________________
)
{
    Property = longValue_______________________________________________________________________,
};

// 0.29.2
SomeObject someObject =
    new(someLongParameter___________________, someLongParameter___________________)
    {
        Property = longValue_______________________________________________________________________,
    };

SomeObject someObject = new SomeObject(
    someLongParameter___________________,
    someLongParameter___________________
)
{
    Property = longValue_______________________________________________________________________,
};

Adds additional space before each member access in verbatim interpolated multiline string #1358

When an interpolated verbatim string contained line breaks, the code within the interpolations would contain extra spaces.

// input & expected output
var someStringWithLineBreakAndLongValue =
    $@"
{someValue.GetValue().Name} someLongText________________________________________________________________";

// 0.29.2
var someStringWithLineBreakAndLongValue =
    $@"
        {someValue .GetValue() .Name} someLongText________________________________________________________________";

Inserting trailing comma with trailing comment causes problems. #1354

CSharpier would insert a trailing comma after a trailing comment and format the end result poorly.

// input
var someObject = new SomeObject()
{
    Property1 = 1,
    Property2 = 2 // Trailing Comment
};

// 0.29.2
var someObject = new SomeObject()
{
    Property1 = 1,
    Property2 =
        2 // Trailing Comment
    ,
};

// 0.30.0
var someObject = new SomeObject()
{
    Property1 = 1,
    Property2 = 2, // Trailing Comment
};

Double line break before collection expression in field #1351

CSharpier was inserting an extra line break on a long field name followed by a collection expression to initialize it.

// input & expected output
class ClassName
{
    public SomeType[] LongName____________________________________________________________________________ =
    [
        someLongValue___________________________________________________,
        someLongValue___________________________________________________,
    ];
}

// 0.29.2
class ClassName
{
    public SomeType[] LongName____________________________________________________________________________ =

        [
            someLongValue___________________________________________________,
            someLongValue___________________________________________________,
        ];
}

Full Changelog: 0.29.2...0.30.0

0.29.2

15 Sep 17:55
57c3ca1
Compare
Choose a tag to compare

What's Changed

Comments don't follow tabs indent style #1343

Prior to 0.29.2 CSharpier was converting any tabs within the block of a multiline comment to spaces.

public void SomeFunction()
{
	/*
	The following line is an example with an indent:
		This line is indented by one tab. (prior to 0.29.2 this would end up as a tab followed by 4 spaces)
	*/
	/*
	The following line is an example with an indent:
		This line is indented by 4 spaces but will be converted to 1 tab (prior to 0.29.2 this would end up as a tab followed by 4 spaces)
	*/
	/*
	The following line is an example with an indent:
	   This line is indented by 3 spaces but will be left as 3 spaces
	*/
}

csharpier-ignore-start now supported in object initializers #1342

// input & expected output
return new SomeClass
{
    // csharpier-ignore-start
    SomeProperty =     someValue,
    SomeProperty2 =     someValue
    // csharpier-ignore-end
};

// 0.29.1
return new SomeClass
{
    // csharpier-ignore-start
    SomeProperty = someValue,
    SomeProperty2 = someValue
    // csharpier-ignore-end
};

Fixed extra new line between cast and collection expression. #1334

// input & expected output
CallMethod(
    (string[])
        [
            longerValue_____________________________________________,
            longerValue_____________________________________________,
        ]
);

// 0.29.1
CallMethod(
    (string[])

        [
            longerValue_____________________________________________,
            longerValue_____________________________________________,
        ]
);

Support custom extensions in .editorconfig #1273

As of 0.29.0 CSharpier could format non-standard file extensions, but only if configured in the csharpierrc file. This is now supported with an .editorconfig

[*.cst]
csharpier_formatter = csharp
indent_style = space
indent_size = 2
max_line_length = 80

Full Changelog: 0.29.1...0.29.2