belav / csharpier

CSharpier is an opinionated code formatter for c#.
https://csharpier.com
MIT License
1.39k stars 96 forks source link

CSharpier strips intentional empty lines between `using` groups #1305

Open tvanantwerp opened 3 months ago

tvanantwerp commented 3 months ago

I'm upgrading a project from .NET 6 to 8, and also CSharpier as part of that. Previously, we sorted using directives with dotnet format style and the dotnet_separate_import_directive_groups option in .editorconfig set to true.

Since upgrading from 0.25.0 to 0.28.2, I see that CSharpier also now supports sorting using. But, it is not configurable. It does not respect the dotnet_separate_import_directive_groups setting, and keeps trying to strip out the empty lines between using groups that we intentionally kept for clarity. This change in default behavior is causing our git hooks and our CI/CD to fail, since CSharpier and dotnet format style now create conflicting outputs.

Input:

using System;

using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;

using Moq;

using Newtonsoft.Json;

Output:

using System;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Moq;
using Newtonsoft.Json;

Expected behavior:

using System;

using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;

using Moq;

using Newtonsoft.Json;
belav commented 3 months ago

I had intended to keep existing blank lines between usings when implementing sorting but it proved difficult and didn't seem worth the effort. I'd be happy to add that feature to the backlog but is is unlikely to be implemented any time soon.

Otherwise I suggest turning off dotnet_separate_import_directive_groups and/or just not using dotnet format style. I'm not familiar enough with dotnet format to know what else the style option may provide.

tvanantwerp commented 3 months ago

If it's too hard to enable empty line separation between using directive groups, I'd be perfectly happy to just turn off using sorting in CSharpier. It took quite a while to even figure out what my issue was, because the sorting added in 0.26.0 isn't mentioned anywhere in the docs that I could see—I had to read through the release notes until I found it. This feels like a feature that should really be configurable, or at least explicitly mentioned in the docs as a non-configurable default behavior.

tvanantwerp commented 3 months ago

I was thinking it might be possible to just check how Roslyn handles breaking up using groups when dotnet format runs and implement a version of that. The docs for it point here, but that's mostly the API around invoking it. The actual service is defined here, and I think the implementation is here, but that's still using a lot of other dependencies specific to Roslyn and would certainly require time to read and understand. It might be an approach fundamentally incompatible with how CSharpier does things. But I thought it was worth making note of it in case it's useful. I'm more of a TypeScript dev than C#, and I'm reaching the limits of understanding what I'm looking at.