jolt 0.9.123__py3-none-any.whl → 0.9.435__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (196) hide show
  1. jolt/__init__.py +80 -7
  2. jolt/__main__.py +9 -1
  3. jolt/bin/fstree-darwin-x86_64 +0 -0
  4. jolt/bin/fstree-linux-x86_64 +0 -0
  5. jolt/cache.py +832 -362
  6. jolt/chroot.py +156 -0
  7. jolt/cli.py +281 -162
  8. jolt/common_pb2.py +63 -0
  9. jolt/common_pb2_grpc.py +4 -0
  10. jolt/config.py +98 -41
  11. jolt/error.py +19 -4
  12. jolt/filesystem.py +2 -6
  13. jolt/graph.py +705 -117
  14. jolt/hooks.py +43 -0
  15. jolt/influence.py +122 -3
  16. jolt/loader.py +369 -121
  17. jolt/log.py +225 -63
  18. jolt/manifest.py +28 -38
  19. jolt/options.py +35 -10
  20. jolt/pkgs/abseil.py +42 -0
  21. jolt/pkgs/asio.py +25 -0
  22. jolt/pkgs/autoconf.py +41 -0
  23. jolt/pkgs/automake.py +41 -0
  24. jolt/pkgs/b2.py +31 -0
  25. jolt/pkgs/boost.py +111 -0
  26. jolt/pkgs/boringssl.py +32 -0
  27. jolt/pkgs/busybox.py +39 -0
  28. jolt/pkgs/bzip2.py +43 -0
  29. jolt/pkgs/cares.py +29 -0
  30. jolt/pkgs/catch2.py +36 -0
  31. jolt/pkgs/cbindgen.py +17 -0
  32. jolt/pkgs/cista.py +19 -0
  33. jolt/pkgs/clang.py +44 -0
  34. jolt/pkgs/cli11.py +24 -0
  35. jolt/pkgs/cmake.py +48 -0
  36. jolt/pkgs/cpython.py +196 -0
  37. jolt/pkgs/crun.py +29 -0
  38. jolt/pkgs/curl.py +38 -0
  39. jolt/pkgs/dbus.py +18 -0
  40. jolt/pkgs/double_conversion.py +24 -0
  41. jolt/pkgs/fastfloat.py +21 -0
  42. jolt/pkgs/ffmpeg.py +28 -0
  43. jolt/pkgs/flatbuffers.py +29 -0
  44. jolt/pkgs/fmt.py +27 -0
  45. jolt/pkgs/fstree.py +20 -0
  46. jolt/pkgs/gflags.py +18 -0
  47. jolt/pkgs/glib.py +18 -0
  48. jolt/pkgs/glog.py +25 -0
  49. jolt/pkgs/glslang.py +21 -0
  50. jolt/pkgs/golang.py +16 -11
  51. jolt/pkgs/googlebenchmark.py +18 -0
  52. jolt/pkgs/googletest.py +46 -0
  53. jolt/pkgs/gperf.py +15 -0
  54. jolt/pkgs/grpc.py +73 -0
  55. jolt/pkgs/hdf5.py +19 -0
  56. jolt/pkgs/help2man.py +14 -0
  57. jolt/pkgs/inja.py +28 -0
  58. jolt/pkgs/jsoncpp.py +31 -0
  59. jolt/pkgs/libarchive.py +43 -0
  60. jolt/pkgs/libcap.py +44 -0
  61. jolt/pkgs/libdrm.py +44 -0
  62. jolt/pkgs/libedit.py +42 -0
  63. jolt/pkgs/libevent.py +31 -0
  64. jolt/pkgs/libexpat.py +27 -0
  65. jolt/pkgs/libfastjson.py +21 -0
  66. jolt/pkgs/libffi.py +16 -0
  67. jolt/pkgs/libglvnd.py +30 -0
  68. jolt/pkgs/libogg.py +28 -0
  69. jolt/pkgs/libpciaccess.py +18 -0
  70. jolt/pkgs/libseccomp.py +21 -0
  71. jolt/pkgs/libtirpc.py +24 -0
  72. jolt/pkgs/libtool.py +42 -0
  73. jolt/pkgs/libunwind.py +35 -0
  74. jolt/pkgs/libva.py +18 -0
  75. jolt/pkgs/libvorbis.py +33 -0
  76. jolt/pkgs/libxml2.py +35 -0
  77. jolt/pkgs/libxslt.py +17 -0
  78. jolt/pkgs/libyajl.py +16 -0
  79. jolt/pkgs/llvm.py +81 -0
  80. jolt/pkgs/lua.py +54 -0
  81. jolt/pkgs/lz4.py +26 -0
  82. jolt/pkgs/m4.py +14 -0
  83. jolt/pkgs/make.py +17 -0
  84. jolt/pkgs/mesa.py +81 -0
  85. jolt/pkgs/meson.py +17 -0
  86. jolt/pkgs/mstch.py +28 -0
  87. jolt/pkgs/mysql.py +60 -0
  88. jolt/pkgs/nasm.py +49 -0
  89. jolt/pkgs/ncurses.py +30 -0
  90. jolt/pkgs/ng_log.py +25 -0
  91. jolt/pkgs/ninja.py +45 -0
  92. jolt/pkgs/nlohmann_json.py +25 -0
  93. jolt/pkgs/nodejs.py +19 -11
  94. jolt/pkgs/opencv.py +24 -0
  95. jolt/pkgs/openjdk.py +26 -0
  96. jolt/pkgs/openssl.py +103 -0
  97. jolt/pkgs/paho.py +76 -0
  98. jolt/pkgs/patchelf.py +16 -0
  99. jolt/pkgs/perl.py +42 -0
  100. jolt/pkgs/pkgconfig.py +64 -0
  101. jolt/pkgs/poco.py +39 -0
  102. jolt/pkgs/protobuf.py +77 -0
  103. jolt/pkgs/pugixml.py +27 -0
  104. jolt/pkgs/python.py +19 -0
  105. jolt/pkgs/qt.py +35 -0
  106. jolt/pkgs/rapidjson.py +26 -0
  107. jolt/pkgs/rapidyaml.py +28 -0
  108. jolt/pkgs/re2.py +30 -0
  109. jolt/pkgs/re2c.py +17 -0
  110. jolt/pkgs/readline.py +15 -0
  111. jolt/pkgs/rust.py +41 -0
  112. jolt/pkgs/sdl.py +28 -0
  113. jolt/pkgs/simdjson.py +27 -0
  114. jolt/pkgs/soci.py +46 -0
  115. jolt/pkgs/spdlog.py +29 -0
  116. jolt/pkgs/spirv_llvm.py +21 -0
  117. jolt/pkgs/spirv_tools.py +24 -0
  118. jolt/pkgs/sqlite.py +83 -0
  119. jolt/pkgs/ssl.py +12 -0
  120. jolt/pkgs/texinfo.py +15 -0
  121. jolt/pkgs/tomlplusplus.py +22 -0
  122. jolt/pkgs/wayland.py +26 -0
  123. jolt/pkgs/x11.py +58 -0
  124. jolt/pkgs/xerces_c.py +20 -0
  125. jolt/pkgs/xorg.py +360 -0
  126. jolt/pkgs/xz.py +29 -0
  127. jolt/pkgs/yamlcpp.py +30 -0
  128. jolt/pkgs/zeromq.py +47 -0
  129. jolt/pkgs/zlib.py +87 -0
  130. jolt/pkgs/zstd.py +33 -0
  131. jolt/plugins/alias.py +3 -0
  132. jolt/plugins/allure.py +5 -2
  133. jolt/plugins/autotools.py +66 -0
  134. jolt/plugins/cache.py +133 -0
  135. jolt/plugins/cmake.py +74 -6
  136. jolt/plugins/conan.py +238 -0
  137. jolt/plugins/cxx.py +698 -0
  138. jolt/plugins/cxxinfo.py +7 -0
  139. jolt/plugins/dashboard.py +1 -1
  140. jolt/plugins/docker.py +80 -23
  141. jolt/plugins/email.py +2 -2
  142. jolt/plugins/email.xslt +144 -101
  143. jolt/plugins/environ.py +11 -0
  144. jolt/plugins/fetch.py +141 -0
  145. jolt/plugins/gdb.py +39 -19
  146. jolt/plugins/gerrit.py +1 -14
  147. jolt/plugins/git.py +283 -85
  148. jolt/plugins/googletest.py +2 -1
  149. jolt/plugins/http.py +36 -38
  150. jolt/plugins/libtool.py +63 -0
  151. jolt/plugins/linux.py +990 -0
  152. jolt/plugins/logstash.py +4 -4
  153. jolt/plugins/meson.py +61 -0
  154. jolt/plugins/ninja-compdb.py +99 -30
  155. jolt/plugins/ninja.py +468 -166
  156. jolt/plugins/paths.py +11 -1
  157. jolt/plugins/pkgconfig.py +219 -0
  158. jolt/plugins/podman.py +136 -92
  159. jolt/plugins/python.py +137 -0
  160. jolt/plugins/remote_execution/__init__.py +0 -0
  161. jolt/plugins/remote_execution/administration_pb2.py +46 -0
  162. jolt/plugins/remote_execution/administration_pb2_grpc.py +170 -0
  163. jolt/plugins/remote_execution/log_pb2.py +32 -0
  164. jolt/plugins/remote_execution/log_pb2_grpc.py +68 -0
  165. jolt/plugins/remote_execution/scheduler_pb2.py +41 -0
  166. jolt/plugins/remote_execution/scheduler_pb2_grpc.py +141 -0
  167. jolt/plugins/remote_execution/worker_pb2.py +38 -0
  168. jolt/plugins/remote_execution/worker_pb2_grpc.py +112 -0
  169. jolt/plugins/report.py +12 -2
  170. jolt/plugins/rust.py +25 -0
  171. jolt/plugins/scheduler.py +710 -0
  172. jolt/plugins/selfdeploy/setup.py +8 -4
  173. jolt/plugins/selfdeploy.py +138 -88
  174. jolt/plugins/strings.py +35 -22
  175. jolt/plugins/symlinks.py +26 -11
  176. jolt/plugins/telemetry.py +5 -2
  177. jolt/plugins/timeline.py +13 -3
  178. jolt/plugins/volume.py +46 -48
  179. jolt/scheduler.py +589 -192
  180. jolt/tasks.py +625 -121
  181. jolt/templates/timeline.html.template +44 -47
  182. jolt/timer.py +22 -0
  183. jolt/tools.py +638 -282
  184. jolt/utils.py +211 -7
  185. jolt/version.py +1 -1
  186. jolt/xmldom.py +12 -2
  187. {jolt-0.9.123.dist-info → jolt-0.9.435.dist-info}/METADATA +97 -38
  188. jolt-0.9.435.dist-info/RECORD +207 -0
  189. {jolt-0.9.123.dist-info → jolt-0.9.435.dist-info}/WHEEL +1 -1
  190. jolt/plugins/amqp.py +0 -834
  191. jolt/plugins/debian.py +0 -338
  192. jolt/plugins/ftp.py +0 -181
  193. jolt/plugins/repo.py +0 -253
  194. jolt-0.9.123.dist-info/RECORD +0 -77
  195. {jolt-0.9.123.dist-info → jolt-0.9.435.dist-info}/entry_points.txt +0 -0
  196. {jolt-0.9.123.dist-info → jolt-0.9.435.dist-info}/top_level.txt +0 -0
jolt/plugins/cxxinfo.py CHANGED
@@ -1,4 +1,5 @@
1
1
  from jolt.cache import ArtifactListAttribute
2
+ from jolt.cache import ArtifactStringAttribute
2
3
  from jolt.cache import ArtifactAttributeSet
3
4
  from jolt.cache import ArtifactAttributeSetProvider
4
5
 
@@ -7,6 +8,10 @@ class CppInfoListVariable(ArtifactListAttribute):
7
8
  pass
8
9
 
9
10
 
11
+ class CppInfoStringVariable(ArtifactStringAttribute):
12
+ pass
13
+
14
+
10
15
  class CppInfoDictVariable(ArtifactListAttribute):
11
16
  def __init__(self, artifact, name):
12
17
  super(CppInfoDictVariable, self).__init__(artifact, name)
@@ -26,6 +31,8 @@ class CppInfo(ArtifactAttributeSet):
26
31
  return CppInfoListVariable(self._artifact, "asflags")
27
32
  if name == "cflags":
28
33
  return CppInfoListVariable(self._artifact, "cflags")
34
+ if name == "msvcrt":
35
+ return CppInfoStringVariable(self._artifact, "msvcrt")
29
36
  if name == "cxxflags":
30
37
  return CppInfoListVariable(self._artifact, "cxxflags")
31
38
  if name == "incpaths":
jolt/plugins/dashboard.py CHANGED
@@ -10,7 +10,7 @@ log.verbose("[Dashboard] Loaded")
10
10
 
11
11
  class DashboardHooks(telemetry.TelemetryHooks):
12
12
  def __init__(self, uri=None):
13
- uri = config.get("dashboard", "uri", "http://dashboard")
13
+ uri = config.get("dashboard", "uri", "http://dashboard.")
14
14
  error.raise_error_if(not uri, "dashboard.uri not configured")
15
15
  super().__init__(plugin="dashboard", uri=uri + "/api/v1/tasks", local=False)
16
16
 
jolt/plugins/docker.py CHANGED
@@ -25,8 +25,6 @@ class DockerListVariable(ArtifactListAttribute):
25
25
 
26
26
  class DockerLoadListVariable(DockerListVariable):
27
27
  def apply(self, task, artifact):
28
- if isinstance(task, Resource):
29
- return
30
28
  for image in self.items():
31
29
  task.tools.run(
32
30
  "docker load -i {}",
@@ -35,16 +33,12 @@ class DockerLoadListVariable(DockerListVariable):
35
33
 
36
34
  class DockerPullListVariable(DockerListVariable):
37
35
  def apply(self, task, artifact):
38
- if isinstance(task, Resource):
39
- return
40
36
  for image in self.items():
41
37
  task.tools.run("docker pull {}", image, output_on_error=True)
42
38
 
43
39
 
44
40
  class DockerRmiListVariable(DockerListVariable):
45
41
  def unapply(self, task, artifact):
46
- if isinstance(task, Resource):
47
- return
48
42
  for image in self.items():
49
43
  task.tools.run("docker rmi -f {}", image, output_on_error=True)
50
44
 
@@ -109,8 +103,8 @@ class DockerClient(Download):
109
103
  url = "https://download.docker.com/{host}/static/stable/{arch}/docker-{version}.tgz"
110
104
  """ URL of binaries """
111
105
 
112
- version = Parameter("20.10.13", help="Docker version")
113
- """ Docker version [20.10.13] """
106
+ version = Parameter("27.4.1", help="Docker version")
107
+ """ Docker version [27.4.1] """
114
108
 
115
109
  def publish(self, artifact, tools):
116
110
  super().publish(artifact, tools)
@@ -173,6 +167,40 @@ class DockerContainer(Resource):
173
167
  Alternatively, assign ``True`` to publish all exposed ports to random ports.
174
168
  """
175
169
 
170
+ release_on_error = True
171
+ """ Stop and remove container on error to avoid resource leaks. """
172
+
173
+ security_opts = []
174
+ """
175
+ A list of security options.
176
+
177
+ By default, the container is started with the default security profile.
178
+
179
+ Example:
180
+
181
+ .. code-block:: python
182
+
183
+ security_opts = [
184
+ "seccomp:unconfined",
185
+ ]
186
+
187
+ """
188
+
189
+ stop_timeout = 10
190
+ """ Timeout in seconds for stopping the container .
191
+
192
+ When stopping the container, the task will wait for the container to stop
193
+ for the specified number of seconds before forcefully killing it.
194
+
195
+ Default: 10 seconds.
196
+ """
197
+
198
+ stop_signal = "SIGTERM"
199
+ """ Signal to send to the container when stopping it.
200
+
201
+ Default: ``SIGTERM``.
202
+ """
203
+
176
204
  volumes = []
177
205
  """
178
206
  A list of volumes to mount.
@@ -199,6 +227,9 @@ class DockerContainer(Resource):
199
227
  Defaults to the current user.
200
228
  """
201
229
 
230
+ workdir = None
231
+ """ The container working directory. """
232
+
202
233
  @property
203
234
  def _arguments(self):
204
235
  return " ".join(self.arguments)
@@ -223,7 +254,7 @@ class DockerContainer(Resource):
223
254
  def _image(self):
224
255
  registry = TaskRegistry.get()
225
256
  tool = tools.Tools(self)
226
- if registry.get_task_class(tool.expand(self.image)):
257
+ if registry.has_task(tool.expand(self.image)):
227
258
  return [self.image]
228
259
  return []
229
260
 
@@ -248,6 +279,14 @@ class DockerContainer(Resource):
248
279
  return "-P"
249
280
  return " ".join([utils.option("-p ", self.tools.expand(port)) for port in self.ports])
250
281
 
282
+ @property
283
+ def _security_opts(self):
284
+ return " ".join([utils.option("--security-opt ", self.tools.expand(opt)) for opt in self.security_opts])
285
+
286
+ @property
287
+ def _stop_signal(self):
288
+ return f" -s {self.stop_signal}" if self.stop_signal else ""
289
+
251
290
  @property
252
291
  def _user(self):
253
292
  if self.user:
@@ -263,7 +302,13 @@ class DockerContainer(Resource):
263
302
  return " ".join([utils.option("-v ", self.tools.expand(vol))
264
303
  for vol in self.volumes_default + self.volumes])
265
304
 
305
+ @property
306
+ def _workdir(self):
307
+ return "--workdir " + self.tools.expand(self.workdir) if self.workdir else ""
308
+
266
309
  def acquire(self, artifact, deps, tools, owner):
310
+ self._context_stack = None
311
+ self.container = None
267
312
  self.joltcachedir = config.get_cachedir()
268
313
  try:
269
314
  image = deps[self.image]
@@ -272,9 +317,10 @@ class DockerContainer(Resource):
272
317
  image = tools.expand(self.image)
273
318
 
274
319
  self._info(f"Creating container from image '{image}'")
275
- self.container = tools.run(
276
- "docker run -i -d {_cap_adds} {_cap_drops} {_entrypoint} {_labels} {_ports} {_privileged} {_user} {_environment} {_volumes} {image} {_arguments}",
277
- image=image, output_on_error=True)
320
+ with utils.delayed_interrupt():
321
+ self.container = tools.run(
322
+ "docker run -i -d {_cap_adds} {_cap_drops} {_entrypoint} {_labels} {_ports} {_privileged} {_security_opts} {_user} {_environment} {_volumes} {_workdir} {image} {_arguments}",
323
+ image=image, output_on_error=True)
278
324
 
279
325
  self._info("Created container '{container}'")
280
326
  info = tools.run("docker inspect {container}", output_on_error=True)
@@ -287,14 +333,18 @@ class DockerContainer(Resource):
287
333
  owner.tools.runprefix(f"docker exec -i {artifact.container}"))
288
334
 
289
335
  def release(self, artifact, deps, tools, owner):
290
- if self.chroot:
336
+ if self.chroot and self._context_stack:
291
337
  self._context_stack.close()
292
338
 
293
- self._info("Stopping container '{container}'")
294
- tools.run("docker stop {container}", output_on_error=True)
339
+ if not self.container:
340
+ return
295
341
 
296
- self._info("Deleting container '{container}'")
297
- tools.run("docker rm {container}", output_on_error=True)
342
+ try:
343
+ self._info("Stopping container '{container}'")
344
+ tools.run("docker stop{_stop_signal} -t {stop_timeout} {container}", output_on_error=True)
345
+ finally:
346
+ self._info("Deleting container '{container}'")
347
+ tools.run("docker rm -f {container}", output_on_error=True)
298
348
 
299
349
 
300
350
  class DockerLogin(Resource):
@@ -443,6 +493,9 @@ class DockerImage(Task):
443
493
  """
444
494
  abstract = True
445
495
 
496
+ annotations = []
497
+ """ A list of image annotations """
498
+
446
499
  autoload = True
447
500
  """
448
501
  Automatically load image file into local registry when the artifact is
@@ -495,9 +548,6 @@ class DockerImage(Task):
495
548
  labels = []
496
549
  """ A list of image metadata labels """
497
550
 
498
- platform = None
499
- """ Target platform, e.g. linux/arm/v7. """
500
-
501
551
  pull = True
502
552
  """
503
553
  Always pull images when building.
@@ -519,6 +569,9 @@ class DockerImage(Task):
519
569
  tags = ["{canonical_name}:{identity}"]
520
570
  """ Optional list of image tags. Defaults to task's canonical name. """
521
571
 
572
+ target = None
573
+ """ Target platform, e.g. linux/arm/v7. """
574
+
522
575
  def __init__(self, *args, **kwargs):
523
576
  super().__init__(*args, **kwargs)
524
577
 
@@ -529,6 +582,10 @@ class DockerImage(Task):
529
582
  with _Tarfile.open(layerpath, 'r') as tar:
530
583
  tar.extractall(targetpath)
531
584
 
585
+ @property
586
+ def _annotations(self):
587
+ return " ".join([utils.option("--annotation ", self.tools.expand(an)) for an in self.annotations])
588
+
532
589
  @property
533
590
  def _buildargs(self):
534
591
  return " ".join([utils.option("--build-arg ", self.tools.expand(ba)) for ba in self.buildargs])
@@ -539,7 +596,7 @@ class DockerImage(Task):
539
596
 
540
597
  @property
541
598
  def _platform(self):
542
- platform = self.tools.expand(self.platform) if self.platform else None
599
+ platform = self.tools.expand(self.target) if self.target else None
543
600
  return utils.option("--platform ", platform)
544
601
 
545
602
  @property
@@ -570,7 +627,7 @@ class DockerImage(Task):
570
627
  tools.expand_relpath(context))
571
628
 
572
629
  with tools.cwd(context):
573
- tools.run("docker build {_platform} . -f {} {_buildargs} {_labels} {_tags} {pull}{squash}",
630
+ tools.run("docker build {_platform} . -f {} {_annotations} {_buildargs} {_labels} {_tags} {pull}{squash}",
574
631
  utils.quote(dockerfile), pull=pull, squash=squash)
575
632
 
576
633
  try:
@@ -620,4 +677,4 @@ class DockerImage(Task):
620
677
  if self._autoload:
621
678
  artifact.docker.load.append("{_imagefile}")
622
679
  if self._autoload:
623
- artifact.docker.rmi.append(artifact.strings.tag.get_value())
680
+ artifact.docker.rmi.append(artifact.strings.tag)
jolt/plugins/email.py CHANGED
@@ -56,11 +56,11 @@ class EmailHooks(CliHook):
56
56
  with open(self._artifact, "w") as f:
57
57
  f.write(report.transform(self._stylesheet))
58
58
 
59
- if report.has_failure():
59
+ if report.has_failure() or report.has_unstable():
60
60
  if not self._failure:
61
61
  return
62
62
  else:
63
- if not self._success:
63
+ if not self._success or not report.has_tasks():
64
64
  return
65
65
 
66
66
  msg = EmailMessage()
jolt/plugins/email.xslt CHANGED
@@ -1,13 +1,18 @@
1
1
  <?xml version="1.0"?>
2
2
  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
3
3
 
4
- <xsl:variable name="Failures" select="jolt-manifest/task[result='FAILED']"/>
5
- <xsl:variable name="Successful" select="jolt-manifest/task[result='SUCCESS']"/>
6
- <xsl:variable name="Tasks" select="jolt-manifest/task"/>
7
- <xsl:variable name="Goals" select="jolt-manifest/task[goal='true']"/>
8
- <xsl:variable name="Hours" select="floor(jolt-manifest/duration div 3600)"/>
9
- <xsl:variable name="Minutes" select="floor((jolt-manifest/duration mod 3600) div 60)"/>
10
- <xsl:variable name="Seconds" select="floor(jolt-manifest/duration mod 60)"/>
4
+ <xsl:variable name="Failures" select="jolt-manifest/task[result='FAILED']" />
5
+ <xsl:variable name="Unstable" select="jolt-manifest/task[result='UNSTABLE']" />
6
+ <xsl:variable name="FailuresAndUnstable"
7
+ select="jolt-manifest/task[result='UNSTABLE' or result='FAILED']" />
8
+ <xsl:variable name="Executed"
9
+ select="jolt-manifest/task[result!='CANCELLED' and result!='SKIPPED']" />
10
+ <xsl:variable name="Successful" select="jolt-manifest/task[result='SUCCESS']" />
11
+ <xsl:variable name="Tasks" select="jolt-manifest/task" />
12
+ <xsl:variable name="Goals" select="jolt-manifest/task[goal='true']" />
13
+ <xsl:variable name="Hours" select="floor(jolt-manifest/duration div 3600)" />
14
+ <xsl:variable name="Minutes" select="floor((jolt-manifest/duration mod 3600) div 60)" />
15
+ <xsl:variable name="Seconds" select="floor(jolt-manifest/duration mod 60)" />
11
16
 
12
17
  <xsl:template match="/">
13
18
  <html>
@@ -15,25 +20,26 @@
15
20
  <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css" />
16
21
  <style type="text/css">
17
22
  pre {
18
- margin-bottom: 0px;
19
- margin-top: 0px;
20
- overflow-x: auto;
21
- white-space: pre-wrap;
22
- white-space: -moz-pre-wrap;
23
- white-space: -pre-wrap;
24
- white-space: -o-pre-wrap;
25
- word-wrap: break-word;
23
+ margin-bottom: 0px;
24
+ margin-top: 0px;
25
+ overflow-x: auto;
26
+ white-space: pre-wrap;
27
+ white-space: -moz-pre-wrap;
28
+ white-space: -pre-wrap;
29
+ white-space: -o-pre-wrap;
30
+ word-wrap: break-word;
26
31
  }
27
32
  a {
28
- color: #f44336;
33
+ color: #f44336;
29
34
  }
30
35
  a.log {
31
- color: white;
36
+ color: white;
32
37
  }
33
38
  </style>
34
39
  </head>
35
40
  <body>
36
- <table width="100%" bgcolor="#f1f1f1" style="border-bottom: 1px solid #c1c1c1; border-top: 1px solid #c1c1c1; fixed">
41
+ <table width="100%" bgcolor="#f1f1f1"
42
+ style="border-bottom: 1px solid #c1c1c1; border-top: 1px solid #c1c1c1; fixed">
37
43
  <tr>
38
44
  <td>
39
45
  <table width="720" cellpadding="10px">
@@ -50,30 +56,46 @@
50
56
  </td>
51
57
  <td width="25%" align="center" style="border-left: 1px solid #c0c0c0">
52
58
  <table>
53
- <tr><td width="100%" align="center">Completed</td></tr>
54
- <tr><td align="center"><h2><xsl:value-of select="count($Tasks)"/></h2></td></tr>
59
+ <tr>
60
+ <td width="100%" align="center">Completed</td>
61
+ </tr>
62
+ <tr>
63
+ <td align="center">
64
+ <h2>
65
+ <xsl:value-of select="count($Executed)" />
66
+ </h2>
67
+ </td>
68
+ </tr>
55
69
  </table>
56
70
  </td>
57
71
  <td width="25%" align="center" style="border-left: 1px solid #c0c0c0">
58
72
  <table>
59
- <tr><td width="100%" align="center">Failed</td></tr>
60
- <tr><td align="center"><h2><xsl:value-of select="count($Failures)"/></h2></td></tr>
73
+ <tr>
74
+ <td width="100%" align="center">Failed</td>
75
+ </tr>
76
+ <tr>
77
+ <td align="center">
78
+ <h2>
79
+ <xsl:value-of select="count($FailuresAndUnstable)" />
80
+ </h2>
81
+ </td>
82
+ </tr>
61
83
  </table>
62
84
  </td>
63
85
  <td width="25%" align="center" style="border-left: 1px solid #c0c0c0">
64
86
  <table>
65
- <tr><td width="100%" align="center">Duration</td></tr>
87
+ <tr>
88
+ <td width="100%" align="center">Duration</td>
89
+ </tr>
66
90
  <tr>
67
91
  <td align="center">
68
92
  <h2>
69
93
  <xsl:if test="$Hours > 0">
70
- <xsl:value-of select="$Hours"/>h
71
- </xsl:if>
94
+ <xsl:value-of select="$Hours" />h </xsl:if>
72
95
  <xsl:if test="$Minutes > 0">
73
- <xsl:value-of select="$Minutes"/>min
74
- </xsl:if>
75
- <xsl:value-of select="$Seconds"/>s
76
- </h2>
96
+ <xsl:value-of select="$Minutes" />min </xsl:if>
97
+ <xsl:value-of
98
+ select="$Seconds" />s </h2>
77
99
  </td>
78
100
  </tr>
79
101
  </table>
@@ -86,101 +108,122 @@
86
108
 
87
109
  <xsl:choose>
88
110
  <xsl:when test="count($Failures) > 0">
89
- <p>
90
- This is an automated build report from Jolt. The build failed.
91
- <xsl:call-template name="jenkins-url" />
111
+ <p> This is an automated build report from Jolt. The build failed. <xsl:call-template
112
+ name="jenkins-url" />
92
113
  <xsl:call-template name="gerrit-url" />
93
114
  </p>
94
115
  </xsl:when>
116
+ <xsl:when test="count($Unstable) > 0 and count($Failures) = 0">
117
+ <p> This is an automated build report from Jolt. The build was successful, but unstable
118
+ task failures were ignored. <xsl:call-template name="jenkins-url" />
119
+ <xsl:call-template
120
+ name="gerrit-url" />
121
+ </p>
122
+ </xsl:when>
95
123
  <xsl:otherwise>
96
- <p>
97
- This is an automated build report from Jolt. The build was successful.
98
- <xsl:call-template name="jenkins-url" />
124
+ <p> This is an automated build report from Jolt. The build was successful. <xsl:call-template
125
+ name="jenkins-url" />
99
126
  <xsl:call-template name="gerrit-url" />
100
127
  </p>
101
128
  </xsl:otherwise>
102
129
  </xsl:choose>
103
130
 
104
131
  <xsl:for-each select="$Failures">
105
- <table width="100%" cellspacing="0" cellpadding="0" bgcolor="#f1f1f1">
106
- <tr bgcolor="#f44336">
107
- <td style="padding: 10px">
108
- <table cellpadding="0" cellspacing="0">
109
- <tr>
110
- <td width="100%" style="font-size: 16pt; color: white;">
111
- <xsl:value-of select="@name"/>
112
- </td>
113
- <td>
114
- <xsl:if test="logstash != ''">
115
- <xsl:element name="a">
116
- <xsl:attribute name="class">log</xsl:attribute>
117
- <xsl:attribute name="href">
118
- <xsl:value-of select="logstash"/>
119
- </xsl:attribute>
120
- Log
121
- </xsl:element>
122
- </xsl:if>
123
- </td>
124
- </tr>
125
- </table>
126
- </td>
127
- </tr>
128
- <xsl:for-each select="error">
129
- <tr>
130
- <td>
131
- <table width="100%">
132
- <tr>
133
- <td width="10%" style="padding: 5px; border-bottom: 1px solid #c1c1c1;"><xsl:value-of select="type"/></td>
134
- <td width="90%" style="padding: 5px; border-left: 1px solid #c1c1c1; border-bottom: 1px solid #c1c1c1;"><xsl:value-of select="location"/></td>
135
- </tr>
136
- </table>
137
- </td>
138
- </tr>
139
- <tr>
140
- <td style="padding: 5px; border-bottom: 1px solid #c1c1c1;"><pre><xsl:value-of select="message"/></pre></td>
141
- </tr>
142
- <xsl:if test="details != ''">
143
- <tr>
144
- <td style="padding: 5px;">
145
- <pre><xsl:value-of select="details"/></pre>
146
- </td>
147
- </tr>
148
- </xsl:if>
149
- <tr>
150
- <td style="padding: 0px; border-bottom: 2px solid #f44336;"></td>
151
- </tr>
152
- </xsl:for-each>
153
- </table>
154
- <br/>
132
+ <xsl:call-template name="task" />
133
+ </xsl:for-each>
134
+
135
+ <xsl:for-each select="$Unstable">
136
+ <xsl:call-template name="task" />
155
137
  </xsl:for-each>
138
+
156
139
  </body>
157
140
  </html>
158
141
  </xsl:template>
159
142
 
160
143
  <xsl:template name="jenkins-url">
161
- <xsl:if test="jolt-manifest/parameter[@key='BUILD_URL']/@value != ''">
162
- See
163
- <xsl:element name="a">
144
+ <xsl:if test="jolt-manifest/parameter[@key='BUILD_URL']/@value != ''"> See <xsl:element name="a">
164
145
  <xsl:attribute name="href">
165
- <xsl:value-of select="jolt-manifest/parameter[@key='BUILD_URL']/@value"/>
146
+ <xsl:value-of select="jolt-manifest/parameter[@key='BUILD_URL']/@value" />
166
147
  </xsl:attribute>
167
- full build log
168
- </xsl:element>
169
- for details.
170
- </xsl:if>
148
+ full build log </xsl:element> for details. </xsl:if>
171
149
  </xsl:template>
172
150
 
173
151
  <xsl:template name="gerrit-url">
174
- <xsl:if test="jolt-manifest/parameter[@key='GERRIT_URL']/@value != ''">
175
- This
176
- <xsl:element name="a">
152
+ <xsl:if test="jolt-manifest/parameter[@key='GERRIT_URL']/@value != ''"> This <xsl:element
153
+ name="a">
177
154
  <xsl:attribute name="href">
178
- <xsl:value-of select="jolt-manifest/parameter[@key='GERRIT_URL']/@value"/>
155
+ <xsl:value-of select="jolt-manifest/parameter[@key='GERRIT_URL']/@value" />
179
156
  </xsl:attribute>
180
- Gerrit change
157
+ Gerrit change </xsl:element> was built. </xsl:if>
158
+ </xsl:template>
159
+
160
+ <xsl:template name="task">
161
+ <table width="100%" cellspacing="0" cellpadding="0" bgcolor="#f1f1f1">
162
+ <xsl:element name="tr">
163
+ <xsl:choose>
164
+ <xsl:when test="result='FAILED'">
165
+ <xsl:attribute name="bgcolor">#f44336</xsl:attribute>
166
+ </xsl:when>
167
+ <xsl:otherwise>
168
+ <xsl:attribute name="bgcolor">#FF7E00</xsl:attribute>
169
+ </xsl:otherwise>
170
+ </xsl:choose>
181
171
  </xsl:element>
182
- was built.
183
- </xsl:if>
172
+ <td style="padding: 10px">
173
+ <table cellpadding="0" cellspacing="0">
174
+ <tr>
175
+ <td width="100%" style="font-size: 16pt; color: white;">
176
+ <xsl:value-of select="@name" />
177
+ </td>
178
+ <td>
179
+ <xsl:if test="logstash != ''">
180
+ <xsl:element name="a">
181
+ <xsl:attribute name="class">log</xsl:attribute>
182
+ <xsl:attribute name="href">
183
+ <xsl:value-of select="logstash" />
184
+ </xsl:attribute> Log </xsl:element>
185
+ </xsl:if>
186
+ </td>
187
+ </tr>
188
+ </table>
189
+ </td>
190
+ <xsl:element name="tr" />
191
+
192
+ <xsl:for-each select="error">
193
+ <tr>
194
+ <td>
195
+ <table width="100%">
196
+ <tr>
197
+ <td width="10%" style="padding: 5px; border-bottom: 1px solid #c1c1c1;">
198
+ <xsl:value-of select="type" />
199
+ </td>
200
+ <td width="90%"
201
+ style="padding: 5px; border-left: 1px solid #c1c1c1; border-bottom: 1px solid #c1c1c1;">
202
+ <xsl:value-of select="location" />
203
+ </td>
204
+ </tr>
205
+ </table>
206
+ </td>
207
+ </tr>
208
+ <tr>
209
+ <td style="padding: 5px; border-bottom: 1px solid #c1c1c1;">
210
+ <pre><xsl:value-of select="message"/></pre>
211
+ </td>
212
+ </tr>
213
+ <xsl:if test="details != ''">
214
+ <tr>
215
+ <td style="padding: 5px;">
216
+ <pre><xsl:value-of select="details"/></pre>
217
+ </td>
218
+ </tr>
219
+ </xsl:if>
220
+ <tr>
221
+ <td style="padding: 0px; border-bottom: 2px solid #f44336;"></td>
222
+ </tr>
223
+ </xsl:for-each>
224
+
225
+ </table>
226
+ <br />
184
227
  </xsl:template>
185
228
 
186
- </xsl:stylesheet>
229
+ </xsl:stylesheet>
jolt/plugins/environ.py CHANGED
@@ -55,6 +55,17 @@ class PathEnvironmentVariable(EnvironmentVariable):
55
55
 
56
56
 
57
57
  class EnvironmentVariableSet(ArtifactAttributeSet):
58
+ """ A set of environment variables for an artifact.
59
+
60
+ Example:
61
+
62
+ .. code-block:: python
63
+
64
+ artifact.environ.FOO = "bar"
65
+ artifact.environ.PATH.append("bin")
66
+
67
+ """
68
+
58
69
  def __init__(self, artifact):
59
70
  super(EnvironmentVariableSet, self).__init__()
60
71
  super(ArtifactAttributeSet, self).__setattr__("_artifact", artifact)