-
Notifications
You must be signed in to change notification settings - Fork 0
/
build.xml
485 lines (359 loc) · 18.3 KB
/
build.xml
1
2
3
4
5
6
7
8
9
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
<?xml version="1.0" encoding="UTF-8"?>
<project name="Generic Ant Project" basedir="." default="help"
xmlns:if="ant:if" xmlns:unless="ant:unless">
<!-- Create project-name relative to basedir -->
<basename property="project.name" file="${basedir}"/>
<!-- ************************************ START CEYLON SETUP *************************************** -->
<condition property="batExt" value=".bat">
<os family="windows" />
</condition>
<property name="batExt" value=""/>
<exec executable="ceylon${batExt}" outputproperty="ceylon.home" failifexecutionfails="false">
<arg value="--show-home" />
</exec>
<property environment="env"/>
<condition property="ceylon.home" value="${env.CEYLON_HOME}"
else="${user.home}/.sdkman/candidates/ceylon/current">
<isset property="env.CEYLON_HOME" />
</condition>
<property name="ceylon.ant.lib" value="${ceylon.home}/lib/ceylon-ant.jar" />
<property name="source.encoding" value="UTF-8"/>
<path id="ant-tasks">
<pathelement location="${ceylon.ant.lib}"/>
</path>
<typedef resource="com/redhat/ceylon/ant/antlib.xml" classpathref="ant-tasks"/>
<!-- ********* INIT ANT LIBRARIES, including ceylon tasks, ant-contrib tasks and vizant task. ******* -->
<!--user ant-libs should be here -->
<property name="user.ant.lib" value="${user.home}/.ant/lib"/>
<mkdir dir="${user.ant.lib}"/>
<!--ant-contrib library-->
<property name="lib.ant-contrib.file" value="ant-contrib-1.0b3.jar"/>
<property name="lib.ant-contrib.path" value="${user.ant.lib}/${lib.ant-contrib.file}"/>
<available file="${lib.ant-contrib.path}" property="lib.ant-contrib.present"/>
<!--define tasks if lib exists-->
<taskdef resource="net/sf/antcontrib/antlib.xml"
classpath="lib.ant-contrib.path" if:set="lib.ant-contrib.present"/>
<!--vizant lib. needed for generating target dependency graph-->
<property name="lib.vizant.file" value="vizant-0.1.2.jar"/>
<property name="lib.vizant.path" value="${user.ant.lib}/${lib.vizant.file}"/>
<available file="${lib.vizant.path}" property="lib.vizant.present"/>
<!--define tasks if lib exists-->
<taskdef name="vizant" classname="net.sourceforge.vizant.Vizant"
classpath="${lib.vizant.path}" if:set="lib.vizant.present"/>
<!-- ********************************* INIT PROJECT PROPERTIES ************************************** -->
<!-- LOAD PROPERTIES FROM FILE for specific environment. (test, stage, prod, etc..)-->
<property file="${env.PROFILE}.properties" />
<echo message="--- Load '${env.PROFILE}' build profile ---" if:set="env.PROFILE"/>
<!-- LOAD PROPERTIES FROM FILE (all project specific properties should be here-->
<property name="build.properties.file" value="build.properties" />
<property file="${build.properties.file}" />
<!-- source dirs setup -->
<property name="source.dir" value="./source"/>
<property name="testsource.dir" value="./test"/>
<property name="source.dirs" value="${source.dir}${path.separator}${testsource.dir}"/>
<moduleset id="full.moduleset">
<sourcemodules/>
<sourcemodules dir="./test"/>
</moduleset>
<!-- repositories setup -->
<property name="user.repo" location="${user.home}/.ceylon/repo"/>
<property name="out.repo" location="modules" relative="true"/>
<property name="deps.repo" location="dependencies" relative="true"/>
<reposet id="local.reposet">
<repo url="${out.repo}"/>
<repo url="${deps.repo}"/>
</reposet>
<!-- ***************************************** TARGETS ********************************************** -->
<target name="help" description="Print ant projecthelp target">
<java classname="org.apache.tools.ant.Main">
<arg value="-projecthelp" />
</java>
</target>
<!-- ************************************************************************************************ -->
<!--configure proxy if it enabled in system-->
<target name="-init-proxy">
<condition property="proxy.enabled"><isset property="env.http_proxy"/></condition>
<script language="javascript" if:set="proxy.enabled">
var proxyHostPortPair = project.getProperty("env.http_proxy")
.replace(/https?:\/\/(.*[^:]):([0-9]+[^\/])\/?/, "$1:$2").split(":");
project.setProperty("proxy.host", proxyHostPortPair[0]);
project.setProperty("proxy.port", proxyHostPortPair[1]);
</script>
<setproxy proxyhost="${proxy.host}" proxyport="${proxy.port}" if:set="proxy.enabled"/>
</target>
<!-- ************************************************************************************************ -->
<target name="fetch" description="Fetches changes from remote repository">
<echo level="verbose">Fetching changes from repository</echo>
<exec executable="git" failonerror="false">
<arg value="pull"/>
</exec>
<echo level="verbose">Done</echo>
</target>
<!-- ************************************************************************************************ -->
<!-- finds changed modules and put to them build.info files in resource dir.
build info files contains:
1) timestamp
2) git revision number
3) git diff of current repo state and last commit
-->
<target name="-create-build-info">
<echo level="verbose">Generating build info</echo>
<!--create timestamp-->
<tstamp>
<format property="timestamp" pattern="YYYY-MM-dd'T'HH:mm:ss.SSS Z"/>
</tstamp>
<!--get git revision -->
<exec executable="git" outputproperty="git.rev">
<arg value="rev-parse"/>
<arg value="HEAD"/>
</exec>
<!-- get git-diff between commit and current repo state -->
<exec executable="bash" outputproperty="git.diff">
<arg value="-c"/>
<arg value="git diff --stat | tail -n1 "/>
</exec>
<!--define build.info -->
<property name="build.info"
value="snapshot=${timestamp}${line.separator}revision=${git.rev}${line.separator}diff=${git.diff}"/>
<echo level="verbose">build.info: ${build.info}</echo>
<!-- find all module paths in source dir-->
<echo level="verbose">Finding module sources</echo>
<pathconvert property="module.path">
<fileset dir="source" includes="**/module.ceylon"/>
<globmapper from="${basedir}/source/*/module.ceylon" to="*"/>
</pathconvert>
<!-- check if there are need to compile modules and create build.info file if so. -->
<echo level="verbose">Cheching module for changes and write build.info to them</echo>
<for param="module.dir" list="${module.path}" delimiter=":">
<sequential>
<!-- properties are immutable, 'local' makes them mutable -->
<local name="car.dir.present"/>
<local name="module.car.present"/>
<local name="is.car.actual"/>
<local name="build.info.needed"/>
<available file="modules/@{module.dir}" property="car.dir.present"/>
<!-- NOTE may be collisions if in modules dir one module have several versions. -->
<first id="module.car" if:set="car.dir.present">
<fileset dir="modules/@{module.dir}"
includes="**/*.car"/>
</first>
<available file="${toString:module.car}" property="module.car.present"
if:set="car.dir.present" />
<!-- check is sources more recent than compiled archive -->
<uptodate property="is.car.actual"
targetfile="${toString:module.car}"
if:set="module.car.present">
<srcfiles dir="source/@{module.dir}" includes="*"/>
</uptodate>
<condition property="build.info.needed" value="true" else="false">
<or>
<not><isset property="is.car.actual"/></not>
<isfalse value="${is.car.actual}"/>
</or>
</condition>
<!-- write build info to file if source changed -->
<echo message="Module '@{module.dir}' changed: writing 'build.info' file"
if:true="${build.info.needed}"/>
<echo message="${build.info}"
file="resource/@{module.dir}/build.info"
if:true="${build.info.needed}"/>
<property name="build.info.created" value="true"
if:true="${build.info.needed}"/>
</sequential>
</for>
<echo level="verbose">Done</echo>
</target>
<!-- ************************************************************************************************ -->
<target name="-delete-build-info">
<echo level="verbose">Delete build info files</echo>
<delete verbose="${verbose-output}">
<fileset dir="resource" includes="**/build.info"/>
</delete>
<echo level="verbose">Done</echo>
</target>
<!-- CODE TASKS -->
<!-- ************************************************************************************************ -->
<target name="compile">
<antcall target="-create-build-info"/>
<ceylon-compile encoding="${source.encoding}" src="${source.dir}">
<reposet refid="local.reposet"/>
<moduleset>
<sourcemodules/>
</moduleset>
</ceylon-compile>
<antcall target="-delete-build-info"/>
</target>
<!-- ************************************************************************************************ -->
<target name="compile-tests"
description="Compile tests sources">
<ceylon-compile encoding="${source.encoding}" src="${testsource.dir}">
<reposet refid="local.reposet"/>
<moduleset>
<sourcemodules dir="${testsource.dir}"/>
</moduleset>
</ceylon-compile>
</target>
<!-- ************************************************************************************************ -->
<!--Compiles all modules, including tests -->
<target name="compile-all" description="Compiles sources and tests">
<antcall target="-create-build-info"/>
<ceylon-compile encoding="${source.encoding}"
nomtimecheck="false"
src="${source.dirs}">
<reposet refid="local.reposet"/>
<moduleset refid="full.moduleset"/>
</ceylon-compile>
<antcall target="-delete-build-info"/>
</target>
<!-- ************************************************************************************************ -->
<target name="test" depends="compile-all"
description="Runs test on modules, specified in build.properties file">
<exec executable="ceylon" failonerror="true">
<arg line="test --rep=${deps.repo} --rep=${out.repo} ${test.module.names}"/>
</exec>
</target>
<!-- ************************************************************************************************ -->
<target name="doc">
<ceylon-doc encoding="${source.encoding}">
<sourcemodules/>
</ceylon-doc>
</target>
<!-- ************************************************************************************************ -->
<target name="clean"
description="Cleans ./modules dir">
<echo>Deleting compiled modules</echo>
<delete dir="${out.repo}"/>
<echo>Done</echo>
</target>
<!-- ************************************************************************************************ -->
<!-- checks if there are need to copy dependencies or not.
It works by comparing module.ceylon files modify-date and
deps/copy.done file modify date.
NOTE: This approach does not work in 2 situations:
1) if some module in source dir has been deleted
2) some deps-dir contents has been deleted manually -->
<target name="install" depends="compile" description="Publishes modules to ceylon user-repo">
<echo>Publishing compiled modules to ${user.repo} repository</echo>
<ceylon-compile out="${user.repo}">
<sourcemodules/>
</ceylon-compile>
<echo>Installation completed</echo>
</target>
<!-- ************************************************************************************************ -->
<target name="publish-herd">
<condition property="herd.pass" value="${pass}">
<isset property="pass"/>
</condition>
<condition property="herd.upload" value="${upload}">
<isset property="upload"/>
</condition>
<fail message="specify herd password via -Dpass" unless:set="herd.pass"/>
<ceylon-compile out="https://modules.ceylon-lang.org/uploads/${herd.upload}/repo/" user="qdzo" pass="${herd.pass}">
<module name="${run.module.name}"/>
</ceylon-compile>
<ceylon-doc out="https://modules.ceylon-lang.org/uploads/${herd.upload}/repo/" user="qdzo" pass="${herd.pass}">
<module name="${run.module.name}"/>
</ceylon-doc>
</target>
<!-- ************************************************************************************************ -->
<target name="all-quick" description="Runs full cycle(without clean)">
<antcall target="fetch"/>
<antcall target="test"/>
</target>
<!-- ************************************************************************************************ -->
<target name="all"
description="Runs full cycle(clean/fetch/build/test)">
<antcall target="clean"/>
<antcall target="all-quick"/>
</target>
<!-- ************************************************************************************************ -->
<target name="setup-ant" depends="-init-proxy">
<!--INSTALL ANT-CONTRIB LIBRARY-->
<property name="lib.ant-contrib.distrib" value="ant-contrib-1.0b3-bin.zip"/>
<!--download and unzip it if not exists-->
<get src="https://netix.dl.sourceforge.net/project/ant-contrib/ant-contrib/1.0b3/${lib.ant-contrib.distrib}"
skipexisting="true"
ignoreerrors="false"
dest="${lib.ant-contrib.distrib}"
unless:set="lib.ant-contrib.present"/>
<unzip src="${lib.ant-contrib.distrib}" dest="${user.ant.lib}" unless:set="lib.ant-contrib.present">
<patternset includes="**/${lib.ant-contrib.file}"/>
<flattenmapper/>
</unzip>
<!--download lib to ant lib dir -->
<get src="https://netix.dl.sourceforge.net/project/vizant/Vizant%20Latest%20Jar/0.1.2/${lib.vizant.file}"
skipexisting="true"
ignoreerrors="false"
dest="${lib.vizant.path}"
unless:set="lib.vizant.present"/>
</target>
<!-- ************************************************************************************************ -->
<target name="setup-project"
description="Creates build properties file configured for project">
<echo>Checking project for setup</echo>
<!--Checking build.properties existence in project dir-->
<available file="${build.properties.file}" property="build.properties.present"/>
<fail message="Build properties file already present. I can't override it"
if:set="build.properties.present"/>
<!-- ant property -->
<property name="verbose-output" value="true"/>
<!-- guess run module -->
<echo>Searching main module</echo>
<first id="run.path">
<fileset dir="${source.dir}" includes="**/run.ceylon"/>
</first>
<property name="run.file" location="${toString:run.path}" relative="true" basedir="${source.dir}"/>
<script language="javascript">
var runModule = project.getProperty("run.file")
.replace("/run.ceylon","").replaceAll("/",".");
project.setProperty("guess.run.module", runModule);
</script>
<property name="run.module.name" value="${guess.run.module}"/>
<property name="run.module.version" value="1.0.0"/>
<!-- find test modules -->
<echo>Searching test modules</echo>
<pathconvert property="test.path">
<fileset dir="${testsource.dir}" includes="**/*test*/**/module.ceylon"/>
<globmapper from="${basedir}/test/*/module.ceylon" to="*"/>
</pathconvert>
<script language="javascript">
var testModules = project
.getProperty("test.path")
.replaceAll("/", ".")
.replaceAll(":", " ")
project.setProperty("guess.test.module.names", testModules);
</script>
<property name="test.module.names" value="${guess.test.module.names}"/>
<!--write properties to file-->
<echo>Creating ${build.properties.file} file</echo>
<echoproperties destfile="${build.properties.file}">
<propertyset>
<propertyref prefix="run.module."/>
<propertyref prefix="test.module.names"/>
<propertyref prefix="verbose-output"/>
</propertyset>
</echoproperties>
<echo>Done</echo>
</target>
<!-- ************************************************************************************************ -->
<target name="setup" depends="setup-ant, setup-project"
description="Setup ant and project">
</target>
<!-- ************************************************************************************************ -->
<!--generating ant target dependency graph-->
<target name="target-graph">
<!--check if grapviz installed-->
<available file="dot" filepath="${env.PATH}" property="dot.executable.present"/>
<fail message="You haven't graphViz application installed" unless="dot.executable.present"/>
<property name="build.graph.pic" value="target-graph.png"/>
<!-- build graph -->
<echo>Generating ${build.graph.pic}</echo>
<vizant antfile="build.xml" outfile="build.dot"/>
<exec executable="dot" failonerror="true">
<arg line="-Tpng build.dot -o ${build.graph.pic}"/>
</exec>
<!--clean from intermediate generated *.dot file-->
<delete file="build.dot" verbose="false"/>
<echo>Build-graph picture created: ${build.graph.pic}</echo>
</target>
</project>