使用 dotnet format 格式化代码
使用 dotnet format 格式化代码
Intro
dotnet-format 在之前的版本是一个独立的命令行工具,在 .NET 6 里已经成为了 SDK 的一部分,我们可以使用,使用 dotnet format 我们可以结合 editorconfig 保持代码风格的一致,我们也可以将 dotnet format 作为一个 CI 服务来运行,自动 format 我们的代码或验证代码是否符合我们的代码风格
Editorconfig
EditorConfig 有助于为跨各种编辑器和 IDE 处理同一项目的多个开发人员维护一致的编码风格
Editorconfig
是用来指定文件的格式的,在 .NET 里,微软扩充了 editorconfig 的用法,我们可以把 C# 的一些编码风格甚至一些错误的级别也加入其中,从而可以通过 editorconfig 来统一代码的风格。
很多编辑器和 IDE 都支持 Editorconfig,包括我们常用 VS,Rider、VS Code/Sublime 等
Sample
C# 10 开始支持了 file-scoped namespace,我们可以使用 editorconfig 来配置使用 file-scoped 风格的命名空间声明方式,在之前的文章中,我们曾经介绍过,可以在 editorconfig 中配置 csharp_style_namespace_declarations=file_scoped:suggestion
来使得 VS 创建项目的时候默认使用 file-scoped 风格,这里的 suggestion
是一个提示级别,我们也可以将此级别提高成 info
/warning
甚至 error
,dotnet format 默认自动 format 级别为 warning
及以上级别的规则
所以我们可以将上面的级别改成 warning
,然后在项目目录下运行 dotnet format
,然后我们项目中所有类型的命名空间风格就会从传统的风格变成新的 file-scoped 风格,可以参考这个 commit https://github.com/WeihanLi/WeihanLi.Npoi/commit/201427b95f2bc23e97e2be595bc103301b7898e3
下面这个变更就是由 dotnet format 更改的
一个命令迁移项目中所有文件的命名空间风格为新的 file-scoped 风格,是不是很方便呢~~
当然不仅仅是命名空间风格,我们还可以在 editorconfig 中定义其他很多的代码风格,甚至我们也可以定义一些第三方分析器的诊断级别,具体规则可以参考微软的这个文档:https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/code-style-rule-options?view=vs-2019
有一些代码格式在 VS 中也是可以配置的,但是个人更加推荐使用 editorconfig 的方式,这样别人要修改某个项目的时候,也不需要修改 VS 的配置,只需要遵循 editorconfig 的风格就可以了,配置即代码,在任何地方都是一样的,也不需要关注 IDE。
CI Service
我们可以把 dotnet format
做成一个 CI 服务来保证自己的代码风格始终是一致的,我们可以有多个选择
第一种方式,我们只做代码格式的验证,我们可以使用 dotnet format --verify-no-changes
来验证格式是否有问题,如果格式有问题,exitcode 将不会是 0,而是 2,也就意味着会 CI 失败
Github Actions CI 配置示例如下:
name: dotnet-format
on: [pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Setup .NET 6
uses: actions/setup-dotnet@v1
with:
dotnet-version: '6.0.x'
- name: build
run: dotnet build
- name: check format
run: dotnet format --verify-no-changes
第二种,我们可以直接提交一个 commit 来修复不正确的格式,运行 dotnet format
的时候会尝试修复项目的代码格式,修复之后我们把这些修复后的文件变成提交成一个 commit 然后推送到我们的代码库就可以了,Github Actions CI 示例如下:
name: dotnet-format
on:
push:
branches: [ dev ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Setup .NET 6
uses: actions/setup-dotnet@v1
with:
dotnet-version: '6.0.x'
include-prerelease: true
- name: build
run: dotnet build
- name: format
run: dotnet format
- name: check for changes
run: |
if git diff --exit-code; then
echo "has_changes=false" >> $GITHUB_ENV
else
echo "has_changes=true" >> $GITHUB_ENV
fi
- name: Commit and Push
if: ${{ env.has_changes == 'true' }}
shell: bash
run: |
git config --local user.name "github-actions[bot]"
git config --local user.email "weihanli@outlook.com"
git add -u
git commit -m "Automated dotnet-format update from commit ${GITHUB_SHA} on ${GITHUB_REF}"
git log -1
remote_repo="https://${GITHUB_ACTOR}:${{secrets.GITHUB_TOKEN}}@github.com/${GITHUB_REPOSITORY}.git"
git push "${remote_repo}" HEAD:${GITHUB_REF}
这里的 CI 直接运行了 dotnet format
命令,然后会通过 git 命令来检查是否有文件变更,如果有文件变更就会生成一个 commit 并推送到代码库
前面的变更就是 CI 自动提交的 commit 的一部分,当我提交代码时就会自动跑 dotnet format 如果有变更就会提交到仓库一个新的格式化的提交,下面两个commit 就是 CI 自动提交的一个示例
Github actions 可以参考
https://github.com/WeihanLi/WeihanLi.Npoi/blob/dev/.github/workflows/dotnet-format.yml https://github.com/WeihanLi/WeihanLi.Npoi/blob/dev/.github/workflows/dotnet-format-pr-validation.yml
More
除了上面的这些基本用法,dotnet format 还有更多的选项,可以通过 --severity
指定严重等级,默认是 warning
,也可以手动指定为 info
或者 error
,另外可以只 format 空格 dotnet format whitespace
、代码风格 dotnet format style
或者第三方的分析器 dotnet format analyzers
更多可以参考 dotnet format 的介绍:https://github.com/dotnet/format/blob/main/README.md
总体上使用下来,感觉还是挺不错的,但是目前有遇到两个问题,一个是在使用框架条件编译的时候
也就是代码里有 #if NET6_0
类似代码时格式可能会有问题,出现一段被注释的代码,这里有一个示例,但是手动改了以后似乎没有这个问题了,只遇到过一次,而且 review 了更改的代码也没什么问题
代码太多了截图了一部分,感兴趣的可以直接看对应 commit 的文件:https://github.com/WeihanLi/WeihanLi.Common/blob/3b080c08c87fa24d99a938a8b3173fb7ec3e92de/src/WeihanLi.Common/Helpers/SecurityHelper.cs
另外一个问题是项目中有 source generator 的时候会 format 失败,提了一个 issue,暂时还没有解决方案,感兴趣的可以参考:https://github.com/dotnet/format/issues/1461
References
https://github.com/dotnet/format https://github.com/dotnet/format/issues/1268 https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/code-style-rule-options?view=vs-2019 https://github.com/dotnet/format/blob/main/docs/Supported-.editorconfig-options.md https://github.com/WeihanLi/WeihanLi.Npoi/commit/201427b95f2bc23e97e2be595bc103301b7898e3 https://github.com/WeihanLi/WeihanLi.Npoi/blob/dev/.github/workflows/dotnet-format.yml https://github.com/WeihanLi/WeihanLi.Npoi/blob/dev/.github/workflows/dotnet-format-pr-validation.yml https://github.com/dotnet/format/issues/1461