Как Apache ShardingSphere стандартизирует и форматирует код? Мы используем Spotless

Зачем нам нужно форматировать код? Проще говоря, для того, чтобы код было легче читать, понимать и изменять.

Будучи проектом верхнего уровня Apache с открытым исходным кодом, ShardingSphere на сегодняшний день имеет 400 участников. Поскольку большинство разработчиков не имеют одинакового стиля кодирования, нелегко стандартизировать общий формат кода проекта в модели открытого сотрудничества GitHub. Чтобы решить эту проблему, ShardingSphere использует Spotless для унификации форматирования кода.

Что такое Spotless?

Spotless — это многоязычный инструмент форматирования кода, который поддерживает сборку Maven и Gradle с помощью плагина.

Разработчики могут использовать Spotless двумя способами: проверять код на наличие проблем, связанных с форматом, и форматировать код.

Сообщество ShardingSphere использует Maven для сборки своих проектов — и Spotless использует Maven для своих демонстраций.

Как его использовать?

Давайте посмотрим официальную демонстрацию ниже:

user@machine repo % mvn spotless:check
[ERROR]  > The following files had format violations:
[ERROR]  srcmainjavacomdiffpluggradlespotlessFormatExtension.java
[ERROR]    -tt····if·(targets.length·==·0)·{
[ERROR]    +ttif·(targets.length·==·0)·{
[ERROR]  Run 'mvn spotless:apply' to fix these violations.
user@machine repo % mvn spotless:apply
[INFO] BUILD SUCCESS
user@machine repo % mvn spotless:check
[INFO] BUILD SUCCESS
Войти в полноэкранный режим Выйти из полноэкранного режима

Когда вы проверяете код проекта с помощью mvn spotless:check, возникает ошибка, тогда вы форматируете код с помощью mvn spotless:apply. И когда вы проверяете его снова, ошибка форматирования волшебным образом исчезает.

1. Подготовка окружения
ShardingSphere использует Spotless для добавления Java-файла licenseHeader и форматирования Java-кода.

Spotless имеет несколько методов форматирования Java-кода, таких как: googleJavaFormat, eclipse, prettier и т.д.

Из соображений настройки мы выбрали eclipse для форматирования Java-кода.

**a) Add `licenseHeader` according to project requirements**

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Вход в полноэкранный режим Выход из полноэкранного режима

Примечание: не забудьте включить пробел в конце licenseHeader. В противном случае между licenseHeader и пакетом не будет пробела.

b) Добавьте shardingsphereeclipseformatter.xml.

?xml version="1.0" encoding="UTF-8" standalone="no"?>
<profiles version="13">
    <profile kind="CodeFormatterProfile" name="'ShardingSphere Apache Current'" version="13">
        <setting id="org.eclipse.jdt.core.compiler.source" value="1.8"/>
        <setting id="org.eclipse.jdt.core.compiler.compliance" value="1.8"/>
        <setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.8"/>
        <setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="true"/>
        <setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
        <setting id="org.eclipse.jdt.core.formatter.lineSplit" value="200"/>
        <setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="200"/>
        <setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
        <setting id="org.eclipse.jdt.core.formatter.indentation.size" value="1"/>
        <setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="false"/>
        <setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="false"/>
        <setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
        <setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
        <setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="16"/>
        <setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
        <setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
        <setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
        <setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="16"/>
        <setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
        <setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
        <setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="160"/>
        <setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="10"/>
        <setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="106"/>
        <setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="106"/>
        <setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="106"/>
        <setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call.count_dependent" value="16|5|80"/>
    </profile>
</profiles>
Вход в полноэкранный режим Выйти из полноэкранного режима

Последние правила ShardingSphere смотрите в [shardingsphereeclipseformatter.xml](https://github.com/apache/shardingsphere/blob/master/src/resources/shardingsphere_eclipse_formatter.xml). Ссылки смотрите в файле [eclipse-java-google-style.xml](https://github.com/google/styleguide/blob/gh-pages/eclipse-java-google-style.xml).

Содержание shardingsphereeclipseformatter.xml создано в соответствии со спецификацией кода ShardingSphere и может быть гибко изменено.

c) Добавьте плагин Maven

<plugin>
    <groupId>com.diffplug.spotless</groupId>
    <artifactId>spotless-maven-plugin</artifactId>
    <version>2.22.1</version>
    <configuration>
        <java>
            <eclipse>
                <file>${maven.multiModuleProjectDirectory}/src/resources/shardingsphere_eclipse_formatter.xml</file>
            </eclipse>
            <licenseHeader>
                <file>${maven.multiModuleProjectDirectory}/src/resources/license-header</file>
            </licenseHeader>
        </java>
    </configuration>
</plugin>
Вход в полноэкранный режим Выйти из полноэкранного режима

Spotless поддерживает указанные директории форматирования и исключение указанных директорий. Для получения дополнительной информации смотрите plugin-maven#java. Если не указано, то при выполнении check или apply по умолчанию будет затронут весь код проекта.

d) Выполнение форматирования кода

После выполнения вышеуказанных трех шагов вы можете выполнить команды в своем проекте для проверки кода Java на соответствие спецификации, а также возможности форматирования кода.

user@machine repo % mvn spotless:apply
[INFO] BUILD SUCCESS
user@machine repo % mvn spotless:check
[INFO] BUILD SUCCESS
Войти в полноэкранный режим Выйти из полноэкранного режима

2. Привязка жизненного цикла Maven

В реальном приложении ShardingSphere вы можете привязать Spotless apply к фазе компиляции, чтобы код автоматически форматировался при локальном выполнении mvn install.

<plugin>
    <groupId>com.diffplug.spotless</groupId>
    <artifactId>spotless-maven-plugin</artifactId>
    <version>2.22.1</version>
    <configuration>
        <java>
            <eclipse>
                <file>${maven.multiModuleProjectDirectory}/src/resources/shardingsphere_eclipse_formatter.xml</file>
            </eclipse>
            <licenseHeader>
                <file>${maven.multiModuleProjectDirectory}/src/resources/license-header</file>
            </licenseHeader>
        </java>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>apply</goal>
            </goals>
            <phase>compile</phase>
        </execution>
    </executions>
</plugin>

Вход в полноэкранный режим Выход из полноэкранного режима

3. Форматирование в IDEA

Если вы хотите проверить один файл на соответствие требованиям при написании кода, выполнение mvn spotless:check или mvn spotless:apply будет немного громоздким, так как по умолчанию областью форматирования является весь проект.

Встроенные функции форматирования IntelliJ IDEA можно заменить на shardingsphereeclipseformatter.xml.

Таким образом, вы можете форматировать код в любой момент в процессе написания, что значительно повышает эффективность работы.

Версия IDEA: 2019.3.4

*a) Установите плагин Eclipse Code Formatter.
*

b) Выберите shardingsphereeclipseformatter.xml в качестве шаблона форматирования по умолчанию.

Точное форматирование кода можно выполнить с помощью ярлыков форматирования кода IDEA.

ЧАСТО ЗАДАВАЕМЫЕ ВОПРОСЫ

1. Конфликты между Spotless и Checkstyle
Checkstyle — это инструмент для проверки исходного кода Java на соответствие стандартам кода или набору правил валидации (лучших практик).

В экстремальных ситуациях код, отформатированный Spotless, не может пройти проверку Checkstyle.

Причиной является конфликт между механизмом проверки и конфигурациями форматирования, установленными обоими механизмами. Например, Spotless форматирует новую строку с отступом в 16 пробелов, а Checkstyle проверяет наличие 12 пробелов.

private static Collection<PreciseHintShadowValue<Comparable<?>>> createNoteShadowValues(final ShadowDetermineCondition shadowDetermineCondition) {
    // format that can pass Checkstyle
    return shadowDetermineCondition.getSqlComments().stream().<PreciseHintShadowValue<Comparable<?>>>map(
        each -> new PreciseHintShadowValue<>(tableName, shadowOperationType, each)).collect(Collectors.toList());
    // After being formatted by Spotless
    return shadowDetermineCondition.getSqlComments().stream().<PreciseHintShadowValue<Comparable<?>>>map(
           each -> new PreciseHintShadowValue<>(tableName, shadowOperationType, each)).collect(Collectors.toList());
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Этот случай требует от разработчиков взвешивания компромиссов. Есть два решения: изменить правила форматирования Spotless или изменить правила проверки Checkstyle.

2. Конфликт форматирования между CRLF & LF

См. https://github.com/diffplug/spotless/issues/1171

Резюме

Apache ShardingSphere использует Spotless для форматирования унаследованного кода и последующей стандартизации форматирования кода, что помогает поддерживать код проекта в опрятном состоянии.

Конечно, Spotless не ограничивается форматированием Java-кода, но также включает форматирование таких типов файлов, как Pom и Markdown, которые вскоре будут применены в ShardingSphere.

Автор

Longtai

Github ID: longtai-cn

Контрибьютор Apache ShardingSphere; автор hippo4j (2.2K звезд на GitHub).

Оцените статью
Procodings.ru
Добавить комментарий