Releases: belav/csharpier
1.1.1
1.1.0
What's Changed
.gitignore from parent folders impacts formatting of children #1627
CSharpier will no longer consider .gitignore
files located above the root of the current git repository.
Changes to stdin formatting #288 #1657
There is a new option --stdin-filepath
that is used to specify the filepath CSharpier should use for resolving options and ignore files.
When no path is specified via stdin-path
- No ignore files are considered.
- The current directory is considered when locating options
- The file is assumed to be c# unless the first non-whitespace character is
<
in which case it is assumed to be xml.
Support for C# 14 and .NET 10 #1654 #1646
Changes were required to support the following
- Extension Declarations
- File level directives in file based C# Apps
Support --ignore-path CLI option #1585
It is now possible to specify the path to an ignore file
dotnet csharpier format . --ignore-path .config/.csharpierignore
Format xaml and slnx by default #1628 #1604
CSharpier now formats xaml
and slnx
by default without the need for configuration changes.
XML formatting is not taking into account EOL configuration on multiline comments #1660
When formatting the following XML, CSharpier would always use the system system default for ending lines within the comment instead of the respecting the configured EOL setting.
<Element>
<!--
Comment with EOL
-->
</Element>
Error when no read access to intermediate containing folder #1656
In the case that CSharpier had access to a sub directory but not the parent of that sub directory, it was failing with an exception. That has been resolved.
Misleading message after "csharpier check" #1645
Previously the format
and check
commands both used the same output message. The check
command now correctly reports that it checked files and did not format them.
# 1.0.3
dotnet csharpier check .
Formatted 13226 files in 21986ms.
# 1.1.0
dotnet csharpier check .
Checked 13226 files in 21986ms.
Multiline collection expressions should not be indented #1635
CSharpier now formats collection expressions consistently when they are in a property
// input & expected output
public class ClassName
{
public SomeObject LongValue = new
{
One = "One",
Two = "Two",
ThreeThreeThree = "ThreeThreeThree",
};
public SomeObject LongValue { get; } = new
{
One = "One",
Two = "Two",
ThreeThreeThree = "ThreeThreeThree",
};
}
// 1.0.3
public class ClassName
{
public SomeObject LongValue = new
{
One = "One",
Two = "Two",
ThreeThreeThree = "ThreeThreeThree",
};
public SomeObject LongValue { get; } =
new
{
One = "One",
Two = "Two",
ThreeThreeThree = "ThreeThreeThree",
};
}
.editorconfig is not considered, when its part of the .gitignore #1582
Previously if an .editorconfig
was in the .gitignore
it would not be considered when determining the configuration options for formatting a given file. That behavior has been changed so it will be considered.
Full Changelog: 1.0.3...1.1.0
1.0.3
What's Changed
Switch block case with conditionals adding newlines #1630
Switch blocks were breaking on conditions within patterns.
// input and expected output
switch ("")
{
case "" or "":
break;
}
// 1.0.2
switch ("")
{
case ""
or "":
break;
}
switch expression formatting adds odd newlines #1620
CSharpier was breaking after a discard with a when, resulting in extra new lines
// input and expected output
_ = someValue switch
{
_ when KeepWhenWithDiscard() => "",
_ when KeepWhenWithDiscard_________________(
SomeObject_______________________________________________
) => "",
_ when KeepWhenWithDiscard_________________(
SomeObject_______________________________________________
) => "LongString_____________________________________________________________________",
};
// 1.0.2
_ = someValue switch
{
_ when KeepWhenWithDiscard() => "",
_
when KeepWhenWithDiscard_________________(
SomeObject_______________________________________________
) => "",
_
when KeepWhenWithDiscard_________________(
SomeObject_______________________________________________
) => "LongString_____________________________________________________________________",
};
multi-line raw string in linq query causes a subsequent linq query to be printed on one line #1617
If a query syntax linq expression contained a raw string, it could result in method invocations not breaking.
// input and expected output
(
from x in SomeMethod()
select """
someString
"""
)
.CallMethod_____________________________________________()
.CallMethod_____________________________________________();
// 1.0.2
(
from x in SomeMethod()
select """
someString
"""
).CallMethod_____________________________________________().CallMethod_____________________________________________();
Full Changelog: 1.0.2...1.0.3
1.0.3
What's Changed
Switch block case with conditionals adding newlines #1630
Switch blocks were breaking on conditions within patterns.
// input and expected output
switch ("")
{
case "" or "":
break;
}
// 1.0.2
switch ("")
{
case ""
or "":
break;
}
switch expression formatting adds odd newlines #1620
CSharpier was breaking after a discard with a when, resulting in extra new lines
// input and expected output
_ = someValue switch
{
_ when KeepWhenWithDiscard() => "",
_ when KeepWhenWithDiscard_________________(
SomeObject_______________________________________________
) => "",
_ when KeepWhenWithDiscard_________________(
SomeObject_______________________________________________
) => "LongString_____________________________________________________________________",
};
// 1.0.2
_ = someValue switch
{
_ when KeepWhenWithDiscard() => "",
_
when KeepWhenWithDiscard_________________(
SomeObject_______________________________________________
) => "",
_
when KeepWhenWithDiscard_________________(
SomeObject_______________________________________________
) => "LongString_____________________________________________________________________",
};
multi-line raw string in linq query causes a subsequent linq query to be printed on one line #1617
If a query syntax linq expression contained a raw string, it could result in method invocations not breaking.
// input and expected output
(
from x in SomeMethod()
select """
someString
"""
)
.CallMethod_____________________________________________()
.CallMethod_____________________________________________();
// 1.0.2
(
from x in SomeMethod()
select """
someString
"""
).CallMethod_____________________________________________().CallMethod_____________________________________________();
Full Changelog: 1.0.2...1.0.3
1.0.2
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
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
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...
0.30.6
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
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
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