Project

General

Profile

Gradle » History » Version 9

Alexey Demakov, 11/30/2015 04:24 PM

1 1 Alexey Demakov
h1. Gradle-based build system.
2
3
h2. История
4
5
Предыдущая версия системы сборки использовала Ant для управления сборкой и Ivy для управления зависимостями.
6
Система сборки представляла собой библиотечный Ant файл, который подключался к проекту и предоставлял 
7
базовую функциональность по сборке Java проектов и управлению выпуском релизов.
8
Gradle реализует и расширяет эту функциональность, поэтому принято решение использовать этот инструмент для сборки проектов.
9
10
h2. Ресурсы
11
12
http://gradle.org
13
14
h2. Подключение Gradle к проекту
15
16
h3. 1. Установить gradle, определить переменную окружения GRADLE_HOME.
17
18
h3. 2. В каталоге проекта выполнить команду создания конфигурационных файлов для Java проекта:
19
20
@> gradle init --type java-library@
21
22
Другие доступные типы проектов: https://docs.gradle.org/current/userguide/build_init_plugin.html
23
24
Также будет создана обертка-запускач gradlew/gradlew.bat, которая избавляет от необходимости вручную
25
устанавливать gradle для сборки проекта - разработчику достаточно просто выкачать рабочую копию проекта из репозитория,
26
gradle будет установлен автоматически.
27
28 3 Alexey Demakov
Имя проекта будет записано в settings.gradle. Gradle предполагает, что имя проекта совпадает с именем каталога проекта.
29
Если это не так, необходимо исправить имя проекта в файле settings.gradle.
30
31 1 Alexey Demakov
Дополнительная информация: 
32
https://docs.gradle.org/current/userguide/gradle_wrapper.html
33
https://docs.gradle.org/current/userguide/wrapper_plugin.html
34
35
h3. 3. Привести структуру папок в соответствие с соглашениями gradle:
36
37
src/main/java - код проекта
38
src/main/resources - ресурсы проекта
39
src/test/java - код тестов
40
41
Дополнительная информация:
42
https://docs.gradle.org/current/userguide/java_plugin.html#N12323
43
44
h3. 4. Указать зависимости проекта в build.gradle:
45
46
compile - зависимость, необходимая для сборки проекта
47
testCompile - зависимость, необходимая для сборки тестов
48
группа:имя:версия - формат зависимости
49
50 2 Alexey Demakov
<pre>
51 1 Alexey Demakov
dependencies {
52
    // The production code uses the SLF4J logging API at compile time
53
    compile ''org.slf4j:slf4j-api:1.7.12''
54
55
    // Declare the dependency for your favourite test framework you want to use in your tests.
56
    // TestNG is also supported by the Gradle Test task. Just change the
57
    // testCompile dependency to testCompile ''org.testng:testng:6.8.1'' and add
58
    // ''test.useTestNG()'' to your build script.
59
    testCompile ''junit:junit:4.12''
60
}
61 2 Alexey Demakov
</pre>
62 1 Alexey Demakov
63
Дополнительная информация: https://docs.gradle.org/current/userguide/java_plugin.html#sec:java_plugin_and_dependency_management
64
65 3 Alexey Demakov
h3. 5. Указать репозитории, в которых ищутся зависимости
66 1 Alexey Demakov
67 3 Alexey Demakov
build.gradle:
68 2 Alexey Demakov
<pre>
69 1 Alexey Demakov
repositories {
70
    // репозиторий ИСП РАН, подключается, если есть зависимости от наших проектов
71
    ivy {
72
      url = ''http://forge.ispras.ru/repo''
73
      layout ''pattern'', {
74
        artifact ''[organization]/[ext]s/[artifact]-[revision](.[ext])''
75
      }
76
    }
77
    // Use ''jcenter'' for resolving your dependencies.
78
    // You can declare any Maven/Ivy/file repository here.
79
    jcenter()
80
}
81
82 2 Alexey Demakov
</pre>
83 1 Alexey Demakov
Дополнительная информация: https://docs.gradle.org/current/userguide/dependency_management.html#sec:repositories
84 3 Alexey Demakov
85
h3. 6. Настроить опции компиляции Java
86
87
build.gradle:
88
<pre>
89
sourceCompatibility = JavaVersion.VERSION_1_8
90
targetCompatibility = JavaVersion.VERSION_1_8
91
92
compileJava {
93
  options.encoding = "UTF-8"
94
}
95
</pre>
96
97
Команда компилцяии Java файлов:
98
<pre>
99
> gradlew compileJava
100
</pre>
101
102
Компиляция и прогон тестов:
103
<pre>
104
> gradlew test
105
</pre>
106
107
Дополнительная информация: https://docs.gradle.org/current/userguide/java_plugin.html#N1245A
108
109
h3. 7. Подключить плагин для сборки дистрибутива
110
111
Для приложений (дистрибутив содержит библиотеки и скрипты для запуска):
112
113
build.gradle:
114
<pre>
115
apply plugin: ''application''
116
...
117
mainClassName = "org.gradle.sample.Main"
118
</pre>
119
120
Для библиотек (application plugin подключает это автоматически):
121
build.gradle:
122
<pre>
123
apply plugin: ''distribution''
124
</pre>
125
126
Команда сборки дистрибутива
127
<pre>
128
> gradlew distZip
129
</pre>
130
или
131
<pre>
132
> gradlew distTar
133
</pre>
134
оба сразу:
135
<pre>
136
assembleDist
137
</pre>
138
139
Дополнительная информация: 
140
https://docs.gradle.org/current/userguide/distribution_plugin.html
141
https://docs.gradle.org/current/userguide/application_plugin.html
142
143
144
h3. 8. Подключить плагин для выпуска релизов
145
146
build.gradle:
147
<pre>
148
// в начало файла
149
import java.text.SimpleDateFormat
150
import java.util.regex.Matcher
151
152
plugins {
153
  id ''net.researchgate.release'' version ''2.3.4''
154
}
155
156
...
157
158
// в конец файла
159
release {
160
  failOnCommitNeeded = false
161
162
  versionPatterns = [
163
    // Increments build number: "0.2.5-alpha-150428" => "0.2.6-alpha-150428"
164
    /(^\d+\.\d+\.)(\d+)(-[^-]*)(-[^-]*$)/: 
165
    { Matcher m, Project p -> m.replaceAll("${ m[0][1] }${ (m[0][2] as int) + 1 }${ m[0][3] }" ) }
166
  ]
167
}
168 1 Alexey Demakov
169 9 Alexey Demakov
String getCurrentDateString()  {
170
  new SimpleDateFormat( "yyMMdd" ).format( new Date() )
171 1 Alexey Demakov
}
172
173 9 Alexey Demakov
task unSnapshotVersion.doLast {
174
  def version = project.version.toString()
175
  version += ''-'' + getCurrentDateString()
176
   project.plugins.getPlugin( net.researchgate.release.ReleasePlugin.class )
177
  .updateVersionProperty( version )
178
}
179 3 Alexey Demakov
</pre>
180
181
Готовящаяся к выпуску версия (вместо текущей даты SNAPSHOT) хранится в файле gradle.properties:
182
<pre>
183
version=0.1.28-alpha-SNAPSHOT
184
</pre>
185
186
Команда выпуска новой версии:
187
<pre>
188
> gradlew release
189
</pre>
190
191
Будет предложено подтвердить или изменить номер выпускаемой версии, а затем номер следующей готовящейся версии.
192
193
Дополнительная информация: https://github.com/researchgate/gradle-release
194
195
Хорошо бы согласовать систему нумерации версий с "семантическим версионированием":http://semver.org/lang/ru/.
196
Есть плагин, поддерживающий этот подход: https://plugins.gradle.org/plugin/de.gliderpilot.semantic-release
197
198 6 Alexey Demakov
h3. 9 Статический анализ кода
199
200
201
build.gradle:
202
<pre>
203
plugins {
204
  id "org.sonarqube" version "1.0"
205
}
206
207
sonarqube {
208
     properties {
209
        property "sonar.host.url", "http://forge.ispras.ru:9000"
210
        property "sonar.jdbc.url", "jdbc:mysql://localhost:3306/sonar"
211
        property "sonar.jdbc.driverClassName", "com.mysql.jdbc.Driver"
212
        property "sonar.jdbc.username", "sonar"
213
        property "sonar.jdbc.password", "sonar"
214
    }
215
}
216
217
</pre>
218
Дополнительная информация: http://docs.sonarqube.org/display/SONAR/Analyzing+with+SonarQube+Scanner+for+Gradle
219 4 Alexey Demakov
220 7 Alexey Demakov
<pre>
221
apply plugin: ''checkstyle''
222
apply plugin: ''findbugs''
223
apply plugin: ''pmd''
224
apply plugin: "jacoco"
225
226
dependencies {
227
  checkstyle ''com.puppycrawl.tools:checkstyle:6.12.1''
228
  pmd ''net.sourceforge.pmd:pmd-core:5.4.0''
229
  pmd ''net.sourceforge.pmd:pmd-java:5.4.0''
230
  findbugs ''com.google.code.findbugs:findbugs:3.0.1''
231
}
232
233
checkstyle {
234
  showViolations = false
235
  ignoreFailures = true
236
}
237
238
findbugs {
239
  ignoreFailures = true
240
}
241
242
pmd {
243
  ignoreFailures = true
244 8 Alexey Demakov
  ruleSets = [ "java-android,java-basic,java-braces,java-comments,java-clone,java-codesize,java-controversial,"
245
             + "java-coupling,java-design,java-empty,java-finalizers,java-imports,java-j2ee,"
246
             + "java-javabeans,java-junit,java-logging-jakarta-commons,java-logging-java,"
247
             + "java-migrating,java-migrating_to_13,java-migrating_to_14,java-migrating_to_15,"
248
             + "java-migrating_to_junit4,java-naming,java-optimizations,java-strictexception,"
249
             + "java-strings,java-sunsecure,java-typeresolution,java-unnecessary,java-unusedcode"]
250 7 Alexey Demakov
}
251
252
jacoco {
253
    toolVersion = "0.7.5.201505241946"
254
}
255
256
jacocoTestReport {
257
    reports {
258
        xml.enabled true
259
        csv.enabled false
260
    }
261
}
262
</pre>
263
264 3 Alexey Demakov
Компиляция, прогон тестов и запуск инструментов статического анализа кода:
265
<pre>
266
> gradlew check</pre>
267 4 Alexey Demakov
268
h3. 10. Копирование зависимостей в подкаталог ''libs''
269
270
gradle скачивает зависимости куда-то в свой кэш.
271
Это неудобно при использовании eclipse.
272
Мы привыкли, что библиотеки лежат рядом.
273
Копировать их в подкаталог ''libs'' проекта можно так:
274
275
build.gradle
276
<pre>
277
//copying all dependencies attached to ''compile'' into a specific folder
278
task copylibs(type: Copy) {
279
  //referring to the ''compile'' configuration
280
  from configurations.compile, configurations.testCompile
281
  into ''libs''
282
}
283
</pre>
284
285
Запускать при изменении зависимостей:
286
<pre>
287
> gradlew copylibs
288
</pre>
289
290
В source code repository не класть!
291 5 Alexey Demakov
292
Альтернатива - "gradle eclipse plugin":https://docs.gradle.org/current/userguide/eclipse_plugin.html
293
Но .classpath генерируется не переносимый, в source code repository его не положишь.