Если вы вводите правила форматирования кода задним числом, вам придется решить проблему, как отформатировать существующую базу кода в соответствии с новыми правилами форматирования. Вы можете проверить каждый репозиторий кода один за другим в вашей IDE и нажать кнопку Автоформат всего проекта. Но это скучно и трата времени.
К счастью, Intellij IDEA имеет инструмент CLI формата в своей установке. Вы можете найти его по пути <ваша установка Intellij IDEA> / bin . Это называется format.sh .
В следующем разделе я хотел бы показать вам, как можно автоматизировать форматирование большой базы кода. Сначала я покажу подготовительные шаги, такие как экспорт настроек правила форматирования кода из IDE. Затем я продемонстрирую, как использовать CLI-Tool format.sh. В конце я покажу небольшой скрипт Groovy, который запрашивает все репозитории (в данном случае это репозитории Git), форматирует код и передает его обратно в удаленный SCM.
Препараты
Во-первых, нам нужна настройка правила форматирования кода, экспортированная из Intellij IDEA. В вашей Intellij IDEA следуйте следующему шагу
- Открыть файл -> Настройки — Редактор -> Стиль кода
- Нажмите на экспорт …
- Выберите имя для файла XML (например, Default.xml ) и место, где этот файл должен быть сохранен (например, / home / foo ).
Затем извлеките или клонируйте свой репозиторий SCM и запомните место, где вы извлекаете / клонируйте его (например, / home / foo / myrepository ).
Форматирование кода базы с помощью инструмента CLI format.sh
Для format.sh важны три параметра :
- -s: установить путь к XML-файлу настроек стиля кода Intellij IDEA (в нашем примере: /home/foo/Default.xml ).
- -r: установить, что каталоги должны проверяться рекурсивно.
- путь <n>: укажите путь к файлу или каталогу, который должен быть отформатирован (в нашем примере: / home / foo / myrepository ).
01
02
03
04
05
06
07
08
09
10
|
> . /format .sh IntelliJ IDEA 2018.2.4, build IC-182.4505.22 Formatter Usage: format [-h] [-r|-R] [-s|-settings settingsPath] path1 path2... -h|-help Show a help message and exit . -s|-settings A path to Intellij IDEA code style settings .xml file . -r|-R Scan directories recursively. -m|-mask A comma-separated list of file masks. path<n> A path to a file or a directory. > /format .sh -r -s ~ /Default .xml ~ /myrepository |
Возможно, что инструмент отменяет сканирование из-за java.lang.OutOfMemoryError: пространства кучи Java. Затем вам нужно увеличить максимальный объем памяти Java (-Xmx) в <ваша установка Intellij IDEA> / bin / idea64.vmoptions.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
> nano idea64.vmoptions -Xms128m -Xmx750m // <- here increase the maximum memory size -XX:ReservedCodeCacheSize=240m -XX:+UseConcMarkSweepGC -XX:SoftRefLRUPolicyMSPerMB=50 -ea -Dsun.io.useCanonCaches= false -Djava.net.preferIPv4Stack= true -Djdk.http.auth.tunneling.disabledSchemes= "" -XX:+HeapDumpOnOutOfMemoryError -XX:-OmitStackTraceInFastThrow -Dawt.useSystemAAFontSettings=lcd -Dsun.java2d.renderer=sun.java2d.marlin.MarlinRenderingEngine |
Groovy-скрипт для форматирования множества репозиториев подряд
Теперь мы хотим собрать все вместе. Скрипт должен делать четыре вещи:
- Найдите все URL репозитория, код которых должен быть отформатирован.
- Проверить / клонировать репозитории.
- Отформатируйте код во всех ветках каждого репозитория.
- Зафиксируйте и отправьте изменения в удаленный SCM.
Я выбираю Git в качестве SCM в моем примере. Поиск URL репозитория зависит от используемой вами системы управления Git (например, BitBucket, Gitlab, SCM Manager и т. Д.). Но подход во всей системе один и тот же:
- Вызовите RESTful API вашей системы управления Git.
- Разобрать объект JSON в ответе после URL.
Например, в BitBucket это так:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
@Grab ( 'org.codehaus.groovy.modules.http-builder:http-builder:0.7.1' ) import groovyx.net.http.* import static groovyx.net.http.ContentType.* import static groovyx.net.http.Method.* def cloneUrlsForProject() { def token = "BITBUCKET_TOKEN" def projects = [] def cloneUrls = [] def http = new HTTPBuilder(projectUrl) http.request(GET) { headers. "Accept" = "application/json" headers. "Authorization" = "Bearer ${token}" response.success = { resp -> projects = new JsonSlurper().parseText(resp.entity.content.text)} response.failure = { resp -> throw new RuntimeException( "Error fetching clone urls for '${projectKey}': ${resp.statusLine}" ) } } projects.values.each { value -> def cloneLink = value.links.clone.find { it.name == "ssh" } cloneUrls.add(cloneLink.href) } return cloneUrls } |
Затем мы должны клонировать репозитории и оформить каждую ветку. В каждой ветке должен быть вызван формат .sh . Для операции git мы используем библиотеку jgit, а для вызова format.sh мы используем функцию Groovy для вызова процесса. В Groovy можно определить команду как строку, а затем вызвать метод execute () для этой строки, например «ls -l» .execute (). Таким образом, скрипт Groovy для трех последних задач будет выглядеть так:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
#!/usr/bin/env groovy @Grab ( 'org.eclipse.jgit:org.eclipse.jgit:5.1.2.201810061102-r' ) import jgit.* import org.eclipse.jgit.api.CreateBranchCommand import org.eclipse.jgit.api.Git import org.eclipse.jgit.api.ListBranchCommand import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider import java.nio.file.Files def intellijHome = 'path to your idea home folder' def codeFormatterSetting = 'path to your exported code formatter setting file' allRepositoriesUrls.each { repository -> def repositoryName = repository.split( '/' ).flatten().findAll { it != null }.last() File localPath = Files.createTempDirectory( "${repositoryName}-" ).toFile() println "Clone ${repository} to ${localPath}" Git.cloneRepository() .setURI(repository) .setDirectory(localPath) .setNoCheckout( true ) .setCredentialsProvider( new UsernamePasswordCredentialsProvider( "user" , "password" )) // only needed when clone url is https / http .call() .withCloseable { git -> def remoteBranches = git.branchList().setListMode(ListBranchCommand.ListMode.REMOTE).call() def remoteBranchNames = remoteBranches.collect { it.name.replace( 'refs/remotes/origin/' , '' ) } println "Found the following branches: ${remoteBranchNames}" remoteBranchNames.each { remoteBranch -> println "Checkout branch $remoteBranch" git.checkout() .setName(remoteBranch) .setCreateBranch( true ) .setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.TRACK) .setStartPoint( "origin/" + remoteBranch) .call() def formatCommand = "$intellijHome/bin/format.sh -r -s $codeFormatterSetting $localPath" println formatCommand.execute().text git.add() .addFilepattern( '.' ) .call() git.commit() .setMessage( 'Format code according to IntelliJ setting.' ) .call() println "Commit successful!" } git.push() .setCredentialsProvider( new UsernamePasswordCredentialsProvider( "user" , "password" )) // only needed when clone url is https / http .setPushAll() .call() println "Push is done" } } |
У вас есть другой подход? Дайте мне знать и напишите комментарий ниже.
Опубликовано на Java Code Geeks с разрешения Сандры Парсик, партнера нашей программы JCG. Смотрите оригинальную статью здесь: Как автоматически форматировать большую кодовую базу
Мнения, высказанные участниками Java Code Geeks, являются их собственными. |