使用代码格式化程序

存在代码格式化程序,以确保编写的代码样式在整个代码库中保持一致。这在许多大型项目中都得到过应用。从Android到OpenCV。团队可能希望在整个机器人代码中添加格式化程序,以确保代码库始终保持可读性和一致性。

For this article, we will highlight using Spotless for Java teams and wpiformat for C++ teams.

一尘不染

配置

为了实现Spotless功能,需要进行必要的build.gradle更改。在build.gradle的plugins {}块中,添加Spotless插件,使其看起来类似于以下内容。

plugins {
   id "java"
   id "edu.wpi.first.GradleRIO" version "2024.1.1"
   id 'com.diffplug.spotless' version '6.20.0'
}

然后确保您添加了一个必需的``spotless {}’’块以正确配置一尘不染。这可以放在build.gradle的末尾。

spotless {
   java {
      target fileTree('.') {
            include '**/*.java'
            exclude '**/build/**', '**/build-*/**', '**/bin/**'
      }
      toggleOffOn()
      googleJavaFormat()
      removeUnusedImports()
      trimTrailingWhitespace()
      endWithNewline()
   }
   groovyGradle {
      target fileTree('.') {
            include '**/*.gradle'
            exclude '**/build/**', '**/build-*/**'
      }
      greclipse()
      indentWithSpaces(4)
      trimTrailingWhitespace()
      endWithNewline()
   }
   format 'xml', {
      target fileTree('.') {
            include '**/*.xml'
            exclude '**/build/**', '**/build-*/**'
      }
      eclipseWtp('xml')
      trimTrailingWhitespace()
      indentWithSpaces(2)
      endWithNewline()
   }
   format 'misc', {
      target fileTree('.') {
            include '**/*.md', '**/.gitignore'
            exclude '**/build/**', '**/build-*/**'
      }
      trimTrailingWhitespace()
      indentWithSpaces(2)
      endWithNewline()
   }
}

Running Spotless

可以使用../gradlew spotlessApply来运行Spotless,这将应用所有格式选项。您还可以仅通过添加格式化程序的名称来指定特定任务。一个示例是``./gradlew spotlessmiscApply’’。

In addition to formatting code, Spotless can also ensure the code is correctly formatted; this can be used by running ./gradlew spotlessCheck. Thus, Spotless can be used as a CI check, as shown in the following GitHub Actions workflow:

on: [push]
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  spotless:
    # The type of runner that the job will run on
    runs-on: ubuntu-22.04
    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0
      - uses: actions/setup-java@v5
        with:
          distribution: 'temurin'
          java-version: 17
      - run: ./gradlew spotlessCheck

选项说明

每个``格式’’部分突出显示项目中自定义文件的格式。 Java和GroovyGradle本身受Spotless的支持,因此它们的定义有所不同。

分解这一点,我们可以将其分为多个部分。

  • 格式化Java

  • 格式化Gradle文件

  • 格式化XML文件

  • 格式化其他文件

它们都是相似的,除了一些小的差异将被解释。下面的示例将突出显示“ java {}”块。

java {
   target fileTree('.') {
      include '**/*.java'
      exclude '**/build/**', '**/build-*/**'
   }
   toggleOffOn()
   googleJavaFormat()
   removeUnusedImports()
   trimTrailingWhitespace()
   endWithNewline()
}

让我们解释每个选项的含义。

target fileTree('.') {
   include '**/*.java'
   exclude '**/build/**', '**/build-*/**'
}

上面的例子告诉我们Java类在哪里,并排除了build目录。其余选项都不言自明。

  • toggleOffOn()增加了使项目Spotless的能力。用法如下所示

// format:off
public void myWeirdFunction() {
}
// format:on
  • ``googleJavaFormat()``告诉Spotless地根据`Google样式指南<https://google.github.io/styleguide/javaguide.html>`__

  • removeUnusedImports() will remove any unused imports from any of your Java classes

  • ``trimTrailingWhitespace()``将删除行尾的所有多余空格

  • ``endWithNewline()``将在课程末尾添加换行符

在groovyGradle块中,有一个Greclipse选项。这是一尘不染的格式程序,用于格式化gradle文件。

另外,在xml块中有一个“ eclipseWtp”选项。这代表“ Gradle Web工具平台”,并且是格式化“ xml”文件的格式化程序。不使用任何XML文件的团队可能希望不包括此配置。

备注

完整的配置列表位于`Spotless README <https://github.com/diffplug/spotless>`__

线尾问题

Spotless将尝试在每个OS上应用行尾,这意味着如果两个用户使用不同的OS(Unix与Windows),则Git差异将不断变化。建议从多个操作系统向同一存储库做出贡献的团队使用.gitattributes文件。以下内容足以处理行尾。

*.gradle text eol=lf
*.java text eol=lf
*.md text eol=lf
*.xml text eol=lf

WPI格式

要求

You can install wpiformat by typing pip3 install wpiformat into a terminal or command prompt.

用法

wpiformat can be ran by typing wpiformat in a console. This will format with clang-format. There are three configuration files one can place in the project root: .clang-format (optional), .wpiformat (optional), and .wpiformat-license (required).

An example .wpiformat-license is shown below:

// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.

You can turn this into a CI check by running git --no-pager diff --exit-code HEAD, as shown in the example GitHub Actions workflow below:

name: Lint and Format

on:
  pull_request:
  push:
jobs:
  wpiformat:
    name: "wpiformat"
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - name: Fetch all history and metadata
        run: |
          git checkout -b pr
          git branch -f main origin/main
      - name: Set up Python 3.12
        uses: actions/setup-python@v5
        with:
          python-version: '3.12'
      - name: Install wpiformat
        run: |
          python -m venv ${{ runner.temp }}/wpiformat
          ${{ runner.temp }}/wpiformat/bin/pip3 install wpiformat==2025.36
      - name: Run
        run: ${{ runner.temp }}/wpiformat/bin/wpiformat
      - name: Check output
        run: git --no-pager diff --exit-code HEAD