Bot releases are hidden (Show)
Published by belav about 1 month ago
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
};
// input & expected output
CallMethod(
(string[])
[
longerValue_____________________________________________,
longerValue_____________________________________________,
]
);
// 0.29.1
CallMethod(
(string[])
[
longerValue_____________________________________________,
longerValue_____________________________________________,
]
);
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: https://github.com/belav/csharpier/compare/0.29.1...0.29.2
CSharpier now sorts _
to the bottom of usings.
using SomeCompany.MWord;
using SomeCompany.ZWord;
using SomeCompany._Word;
CSharpier Server now uses a log file name based on the port that it is starting on to avoid concurrency issues trying to access the same log file
Full Changelog: https://github.com/belav/csharpier/compare/0.29.0...0.29.1
Published by belav 2 months ago
Prior to 0.29.0 if csharpier encountered a file that could not be compiled it would treat it as a warning and exit with a code of 0.
As of 0.29.0 a file that cannot be compiled is now treated as an error and csharpier will exit with code 1
CSharpier will now add trailing commas automatically where appropriate. It will collapse to a single line and remove the trailing comma in cases where everything fits on one line.
// input
public enum SomeEnum
{
Value1,
Value2
}
string[] someArray = new string[]
{
someLongValue_____________________________________________,
someLongValue_____________________________________________
};
string[] someArray = new string[]
{
someValue,
someValue,
};
// 0.29.0
public enum SomeEnum
{
Value1,
Value2,
}
string[] someArray = new string[]
{
someLongValue_____________________________________________,
someLongValue_____________________________________________,
}
string[] someArray = new string[] { someValue, someValue };
Many thanks go to @dawust for the contribution.
Prior to 0.29.0 csharpier would only format files with an extension of .cs or .csx. It is now possible to configure csharpier to format other files extensions, and to specify configuration options per file extension.
See https://csharpier.com/docs/Configuration#configuration-overrides for more details.
// input & expected output
CallMethod(_ =>
[
LongValue________________________________________________,
LongValue________________________________________________,
]
);
// 0.28.2
CallMethod(_ =>
[
LongValue________________________________________________,
LongValue________________________________________________,
]
);
Prior to 0.29.0 csharpier would break before the =>
in switch expression arms. It now breaks after them to be consistent with other lambda expressions.
// 0.28.2
return someEnum switch
{
Value1 => someOtherValue,
Value2
or Value3
=> someValue________________________________________________________________________,
Value4
=> someValue_____________________________________________________________________________,
};
// 0.29.0
return someEnum switch
{
Value1 => someOtherValue,
Value2 or Value3 =>
someValue________________________________________________________________________,
Value4 =>
someValue_____________________________________________________________________________,
};
Empty collection expression initializers formatting was including a break plus indentation resulting in poor formatting.
// 0.28.2
var someObject = new List<(
int Field1__________________________________,
int Field2__________________________________
)>
{
};
// 0.29.0
var someObject = new List<(
int Field1__________________________________,
int Field2__________________________________
)>
{ };
Thanks go to @Rudomitori for the contribution
Improved formatting for short expression arms that have a leading comment.
// 0.28.2
return someValue switch
{
// comment
Some.One
=> 1,
Some.Two => 2,
};
return someValue switch
{
Some.One => 1,
// comment
Some.Two
=> 2,
};
// 0.29.0
return someValue switch
{
// comment
Some.One => 1,
Some.Two => 2,
};
return someValue switch
{
Some.One => 1,
// comment
Some.Two => 2,
};
Fixed bug with comments on a ternary expression that resulted in invalid code.
// input & expected output
public string TrailingComment = someCondition
? $"empty" // trailing comment
: someString;
// 0.28.2
public string TrailingComment = someCondition ? $"empty" // trailing comment : someString;
Improved formatting of indexed properties that contained attributes.
// input & expected output
public class ClassName
{
public string this[
[SomeAttribute] int a________________________________,
[SomeAttribute] int b________________________________
] => someValue;
}
// 0.28.2
public class ClassName
{
public string this[[SomeAttribute] int a________________________________, [SomeAttribute]
int b________________________________] => someValue;
}
CSharpier_Check
when already set. #1314
Fixed a bug with csharpier.msbuild where it would overwrite the CSharpier_Check
value in some cases.
Thanks go to @PetSerAl for the contribution
The help text for the cli has been improved to better indicate when directoryOrFile
is required.
Thanks go to @marcinjahn for the contribution
CSharpier now considers full width unicode characters such as 가
to be 2 spaces wide when determining how to format code.
Full Changelog: https://github.com/belav/csharpier/compare/0.28.2...0.29.0
Published by belav 6 months ago
dotnet csharpier
fails when subdirectory is inaccessible #1240
When running the following CSharpier would look for config files in subdirectories of the pwd
. This could lead to exceptions if some of those directories were inaccessible.
echo "namespace Foo { public class Bar { public string Baz {get;set;}}}" | dotnet csharpier
Thanks go to @jamesfoster for reporting the issue.
Full Changelog: https://github.com/belav/csharpier/compare/0.28.1...0.28.2
Published by belav 6 months ago
Published by belav 6 months ago
When CSharpier encountered an invalid .editorconfig
file, it would throw an exception and not format files. These files could appear in 3rd party code (for example within node_modules). CSharpier now ignores invalid lines in .editorconfigs
Thanks go to @K0Te for reporting the issue
Full Changelog: https://github.com/belav/csharpier/compare/0.28.0...0.28.1
Published by belav 7 months ago
In some cases of method chains, the first invocation would end up dedented.
// 0.27.3
o.Property.CallMethod(
someParameter_____________________________,
someParameter_____________________________
)
.CallMethod()
.CallMethod();
// 0.28.0
o.Property.CallMethod(
someParameter_____________________________,
someParameter_____________________________
)
.CallMethod()
.CallMethod();
If a case statement started with a block it would get an extra new line
// 0.27.3
switch (someValue)
{
case 0:
{
// dedented because the only statement is a block
break;
}
case 1:
{
// indented because there are two statements, a block then a break
}
break;
}
// 0.28.0
// 0.27.3
switch (someValue)
{
case 0:
{
// dedented because the only statement is a block
break;
}
case 1:
{
// indented because there are two statements, a block then a break
}
break;
}
Thanks go to @emberTrev for reporting the bug.
The editorconfig parsing was not handling glob patterns that contained braces.
# worked in 0.27.3
[*.cs]
indent_size = 4
tab_width = 4
# did not work in 0.27.3
[*.{cs,csx}]
indent_size = 4
tab_width = 4
# did not work in 0.27.3
[*.{cs}]
indent_size = 4
tab_width = 4
Thanks go to @kada-v for reporting the bug
The following code would throw an exception, it is now working as expected.
class ClassName
{
#region Region
// csharpier-ignore-start
public string Field;
// csharpier-ignore-end
#endregion
}
Thanks go to @davidescapolan01 for reporting the bug
On some OSs the following would cause an exception.
dotnet new console -n foo
cd foo
dotnet new editorconfig
dotnet csharpier ./
Thanks go to @hashitaku for contributing the fix.
CodeFormatterOptions.IncludeGenerated
is now available for the SDK.
Improved the http server that CSharpier will soon use to facilitate formatting by plugins. The formatting request now returns errors and a status for each file formatted.
This allows the plugin to provide more information to the user when they attempt to format a file. The plugins will be updated to use the http server option for CSharpier 0.28.0+
Full Changelog: https://github.com/belav/csharpier/compare/0.27.3...0.28.0
Published by belav 8 months ago
PATH
Published by belav 8 months ago
Published by belav 8 months ago
Better support for dotnet commands.
The API for CSharpier was only exposing CodeFormatterOptions.PrintWidth
. It is now in sync with the CLI and exposes all of the available options
public class CodeFormatterOptions
{
public int Width { get; init; } = 100;
public IndentStyle IndentStyle { get; init; } = IndentStyle.Spaces;
public int IndentSize { get; init; } = 4;
public EndOfLine EndOfLine { get; init; } = EndOfLine.Auto;
}
Thanks go to @Phault for the contribution
When a raw string literal was the first argument to a method call, it was getting an extra indent.
// input & expected output
CallMethod(
"""
SomeRawString
""".CallMethod()
);
// 0.27.2
CallMethod(
"""
SomeRawString
""".CallMethod()
);
Thanks go to @Rudomitori for reporting the bug.
Using aliases were not sorting properly, resulting differing outputs and unstable formatting.
Inputs of
using A = string;
using B = string;
using C = string;
using D = string;
And
using D = string;
using C = string;
using B = string;
using A = string;
Now always result in properly sorted output of
using A = string;
using B = string;
using C = string;
using D = string;
Thanks go to @Araxor for reporting the bug.
The spread element was unformatted, and left as is. It is now formatted as follows.
int[] someArray = [.. someOtherArray];
int[] someOtherArray = [.. value1, .. value2, .. value3];
int[] someOtherArray =
[
.. value1________________________________,
.. value2________________________________,
.. value3________________________________
];
Thanks go to @jods4 for reporting the bug.
A collection expression in an attribute resulted in an extra line before the collection expression.
// input & expected output
[SomeAttribute(
[
someValue_______________________________________________,
someValue_______________________________________________,
]
)]
class ClassName { }
// 0.27.2
[SomeAttribute(
[
someValue_______________________________________________,
someValue_______________________________________________,
]
)]
class ClassName { }
Thanks go to @Rudomitori for reporting the bug.
Static usings were not following the rule that System.*
should be sorted to the top.
// input & expected output
using static System;
using static System.Web;
using static AWord;
using static ZWord;
// 0.27.2
using static AWord;
using static System;
using static System.Web;
using static ZWord;
When .net8
support was added, CSharpier started including a commit hash in the version number output. This was due to a breaking change in the sdk.
> dotnet csharpier --version
0.27.2+b456544aad8957d0e2026afe1a37544bb74552ba
CSharpier no longer includes the commit hash
> dotnet csharpier --version
0.27.3
Published by belav 8 months ago
This adds better support for dotnet commands by
dotnet.dotnetPath
if it existsomnisharp.dotNetCliPaths
if it existsdotnet
on the PATH by running dotnet --info
dotnet
on the PATH by running sh -c "dotnet --info"
Published by belav 9 months ago
0.27.1 introduced the following formatting regression, resulting in short variables being orphaned on a line
// 0.27.1
o
.Property.CallMethod(
someParameter_____________________________,
someParameter_____________________________
)
.CallMethod()
.CallMethod();
// 0.27.2
o.Property.CallMethod(
someParameter_____________________________,
someParameter_____________________________
)
.CallMethod()
.CallMethod();
Thanks go to @aurnoi1 for reporting the bug
Version 0.27.1 parsed .csx
files as if they were C#, so it could only format simple ones. It now parses them as CSharpScript files so it can format them properly.
Thanks go to @Eptagone for reporting the bug.
Full Changelog: https://github.com/belav/csharpier/compare/0.27.1...0.27.2
Published by belav 9 months ago
Previously CSharpier would only format files matching *.cs
which prevented it from formatting C# script files. It now formats *.{cs,csx}
Thanks go to @Eptagone for the suggestion
Invocation chains that started with an identifier <= 4 characters were causing a strange break in the first method call. There were other edge cases cleaned up while working on the fix.
// 0.27.0
var something________________________________________ = x.SomeProperty.CallMethod(
longParameter_____________,
longParameter_____________
)
.CallMethod();
// 0.27.1
var something________________________________________ = x
.SomeProperty.CallMethod(longParameter_____________, longParameter_____________)
.CallMethod();
// 0.27.0
var someLongValue_________________ = memberAccessExpression[
elementAccessExpression
].theMember______________________________();
// 0.27.1
var someLongValue_________________ = memberAccessExpression[elementAccessExpression]
.theMember______________________________();
// 0.27.0
someThing_______________________
?.Property
.CallMethod__________________()
.CallMethod__________________();
// 0.27.1
someThing_______________________
?.Property.CallMethod__________________()
.CallMethod__________________();
Thanks go to @Rudomitori for reporting the issue
When an interpolated raw string changed indentation due to CSharpier formatting, CSharpier was incorrectly reporting it as failing syntax tree validation.
// input
CallMethod(CallMethod(
$$"""
SomeString
""", someValue));
// output
CallMethod(
CallMethod(
$$"""
SomeString
""",
someValue
)
);
Thanks go to @Rudomitori for reporting the issue
The GRPC support added in 0.27.0 increased the size of the nuget package significantly and has been removed.
CSharpier can now start a kestrel web server to support communication with the extensions once they are all updated.
Full Changelog: https://github.com/belav/csharpier/compare/0.27.0...0.27.1
Published by belav 9 months ago
Many thanks go to @Rudomitori for contributing a number of improvements to the formatting of lambda expressions.
Some examples of the improvements.
// input
var affectedRows = await _dbContext.SomeEntities
.ExecuteUpdateAsync(
x =>
x.SetProperty(x => x.Name, x => command.NewName)
.SetProperty(x => x.Title, x => command.NewTItle)
.SetProperty(x => x.Count, x => x.Command.NewCount)
);
// 0.27.0
var affectedRows = await _dbContext.SomeEntities
.ExecuteUpdateAsync(x =>
x.SetProperty(x => x.Name, x => command.NewName)
.SetProperty(x => x.Title, x => command.NewTItle)
.SetProperty(x => x.Count, x => x.Command.NewCount)
);
// input
builder.Entity<IdentityUserToken<string>>(b =>
{
b.HasKey(
l =>
new
{
l.UserId,
l.LoginProvider,
l.Name
}
);
b.ToTable("AspNetUserTokens");
});
// 0.27.0
builder.Entity<IdentityUserToken<string>>(b =>
{
b.HasKey(l => new
{
l.UserId,
l.LoginProvider,
l.Name
});
b.ToTable("AspNetUserTokens");
});
// input
table.PrimaryKey(
"PK_AspNetUserTokens",
x =>
new
{
x.UserId,
x.LoginProvider,
x.Name
}
);
// 0.27.0
table.PrimaryKey(
"PK_AspNetUserTokens",
x => new
{
x.UserId,
x.LoginProvider,
x.Name
}
);
readonly ref
is changed to ref readonly
causing error CS9190 #1123
CSharpier was sorting modifiers in all places they occurred. Resulting the following change that led to code that would not compile.
// input
void Method(ref readonly int someParameter) { }
// 0.26.7
void Method(readonly ref int someParameter) { }
// 0.27.0
void Method(ref readonly int someParameter) { }
Thanks go to @aurnoi1 for reporting the bug
When a collection expression contained a directive immediately before the closing bracket, that directive was not included in the output.
// input
int[] someArray =
[
1
#if DEBUG
,
2
#endif
];
// 0.26.7
int[] someArray = [1];
// 0.27.0
int[] someArray =
[
1
#if DEBUG
,
2
#endif
];
Thanks go to @Meowtimer for reporting the bug
CSharpier.MsBuild made an assumption that the project being built would be built using net6-net8 and failed when the project was built with earlier versions of dotnet.
It now falls back to trying to use net8
Thanks go to @samtrion for the contribution
Large object initializers now retain single empty lines between initializers.
vvar someObject = new SomeObject
{
NoLineAllowedAboveHere = 1,
ThisLineIsOkay = 2,
// comment
AndThisLine = 3,
DontAddLines = 4,
};
Thanks go to @Qtax for the suggestion
By default CSharpier will not format files that were generated by the SDK, or files that begin with <autogenerated />
comments.
Passing the option --include-generated
to the CLI will cause those files to be formatted.
CSharpier now adjusts the indentation of raw string literals if the end delimiter is indented.
// input
var someString = """
Indent based on previous line
""";
var doNotIndentIfEndDelimiterIsAtZero = """
Keep This
Where It
Is
""";
// 0.26.7
var someString = """
Indent based on previous line
""";
var doNotIndentIfEndDelimiterIsAtZero = """
Keep This
Where It
Is
""";
// 0.27.0
var someString = """
Indent based on previous line
""";
var doNotIndentIfEndDelimiterIsAtZero = """
Keep This
Where It
Is
""";
Thanks go to @jods4 for reporting the issue
CSharpier was not properly indenting an invocation chain when it was being split by comments.
// input
var someValue =
// Some Comment
CallSomeMethod()
// Another Comment
.CallSomeMethod();
// 0.26.7
var someValue =
// Some Comment
CallSomeMethod()
// Another Comment
.CallSomeMethod();
// 0.27.0
var someValue =
// Some Comment
CallSomeMethod()
// Another Comment
.CallSomeMethod();
Thanks go to @tyrrrz for reporting the issue
Currently the extensions for CSharpier send data to a running instance of CSharpier by piping stdin/stdout back and forth. This approach has proved problematic and hard to extend.
As of 0.27.0, CSharpier can run a GRPC server to allow communication with the extensions once they are all updated.
Full Changelog: https://github.com/belav/csharpier/compare/0.26.7...0.27.0
Published by belav 10 months ago
0.26.0 introduced changes that broke long invocation chains on fields/properties as well as methods. That change has been reverted after community feedback.
// 0.26.0
var loggerConfiguration = new LoggerConfiguration()
.Enrich
.FromLogContext()
.Enrich
.WithProperty("key", "value")
.Enrich
.WithProperty("key", "value")
.Enrich
.WithProperty("key", "value")
.Enrich
.WithProperty("key", "value")
.WriteTo
.Console(outputTemplate: "template");
// 0.26.7
var loggerConfiguration = new LoggerConfiguration()
.Enrich.FromLogContext()
.Enrich.WithProperty("key", "value")
.Enrich.WithProperty("key", "value")
.Enrich.WithProperty("key", "value")
.Enrich.WithProperty("key", "value")
.WriteTo.Console(outputTemplate: "template");
Full Changelog: https://github.com/belav/csharpier/compare/0.26.6...0.26.7
Published by belav 10 months ago
If CSharpier was validating that a file was formatted, and that file contained only \n
but CSharpier was configured to use \r\n
, then it would report the problem as The file did not end with a single newline
CSharpier added support for reading line ending configuration from an .editorconfig
which could contain end_of_line = crlf
so some users were unknowingly configuring CSharpier to use \r\n
CSharpier now correctly reports the problem as The file contained different line endings than formatting it would result in.
Full Changelog: https://github.com/belav/csharpier/compare/0.26.5...0.26.6
Published by belav 10 months ago
NSubstitute
before Newtonsoft.Json
#1061
The using sorting in 0.26.4
was taking into account case.
// 0.26.4
using System;
using NSubstitute;
using Newtonsoft.Json;
// 0.26.5
using System;
using Newtonsoft.Json;
using NSubstitute;
Thanks go to @loraderon for contributing the fix.
A collection expression in a property initializer was including an extra new line.
// 0.26.4
public class ClassName
{
public List<DayOfWeek> DaysOfWeek { get; } =
[
DayOfWeek.Sunday,
// snip
DayOfWeek.Saturday
];
}
// 0.26.5
public class ClassName
{
public List<DayOfWeek> DaysOfWeek { get; } =
[
DayOfWeek.Sunday,
// snip
DayOfWeek.Saturday
];
}
Thanks go to @SapiensAnatis for contributing the fix.
When the close bracket on a collection expression had a leading comment, it had the same indentation as the bracket.
// 0.26.4
host.AddSection(
name: "Kontakt Libraries (Third Party)",
tags: Tags.SamplesUsed,
tasks:
[
// TODO: Add any used third party instruments below as you discover them.
]
);
// 0.26.5
host.AddSection(
name: "Kontakt Libraries (Third Party)",
tags: Tags.SamplesUsed,
tasks:
[
// TODO: Add any used third party instruments below as you discover them.
]
);
Thanks go to @fgimian for reporting the problem
Full Changelog: https://github.com/belav/csharpier/compare/0.26.4...0.26.5
Published by belav 11 months ago
There were a number of cases where CSharpier was including extra blank lines, an extra space, or not formatting contents of collection expressions.
// 0.26.3
var a = new A { B = [1, 2, 3] };
List<string> items = [// My item
"Hello",];
items.AddRange(
[
LongValue________________________________________________,
LongValue________________________________________________
]
);
items = [];
items ??= [];
class SomeClass
{
public SomeValue SomeProperty =>
[
LongValue________________________________________________,
LongValue________________________________________________
];
public SomeValue Method() =>
[
LongValue________________________________________________,
LongValue________________________________________________
];
}
// 0.26.4
var a = new A { B = [1, 2, 3] };
List<string> items =
[
// My item
"Hello",
];
items.AddRange(
[
LongValue________________________________________________,
LongValue________________________________________________
]
);
items = [];
items ??= [];
class SomeClass
{
public SomeValue SomeProperty =>
[
LongValue________________________________________________,
LongValue________________________________________________
];
public SomeValue Method() =>
[
LongValue________________________________________________,
LongValue________________________________________________
];
}
Thanks go to @fgimian and @JoshWoodArup for reporting the issues
The sorting of Usings was done in a culture specific manner, resulting in unexpected behavior.
In Czech (cs-CZ) the ch
is a "single letter" which is placed between h
and i
, which resulted in the following sorting behavior.
// 0.26.3
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.Channel;
// 0.26.4
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.ApplicationInsights.Extensibility;
Thanks go to @davidkudera for the contribution
Published by belav 11 months ago
// 0.26.0
List<int> ids = [];
// 0.26.3
List<int> ids = [];
Thanks go to @Jackenmen for reporting the problem.
// 0.26.0
List<int> ids = [ ];
List<int> ids = [ 1, 2, 3 ];
// 0.26.3
List<int> ids = [];
List<int> ids = [1, 2, 3];
Thanks go to @golavr for reporting the problem.
When piping a file to csharpier via stdin, CSharpier uses the working directory to locate any configuration files. This was broken with 0.26.0
.
Thanks go to @kikniknik for reporting the problem.
Previously CSharpier.MSBuild was using targetFramework
to determine which version of CSharpier to run. This was problematic when there were multiple target frameworks, or the project was targeting a superset such as net8.0-windows
It now makes use of NETCoreSdkVersion
to determine which version of CSharpier to run.
Thanks go to @Tyrrrz for the suggestion and to @Cjewett for the contribution to make it work
When looking for .editorconfig
files, CSharpier looks for them recursively in the current directory. This logic was not taking into account any files or directories ignored by a .csharpierignore
.
Thanks go to @sebastieng84 for the contribution.
CSharpier now only looks for an .editorconfig
for the file being piped to CSharpier. Under normal usage it recursively looks for all possible .editorconfig
files for the given directory.
Full Changelog: https://github.com/belav/csharpier/compare/0.26.2...0.26.3