Зачем нам нужно форматировать код? Проще говоря, для того, чтобы код было легче читать, понимать и изменять.
Будучи проектом верхнего уровня 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).