jolt 0.9.172__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 (185) 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 +596 -252
  6. jolt/chroot.py +36 -11
  7. jolt/cli.py +143 -130
  8. jolt/common_pb2.py +45 -45
  9. jolt/config.py +76 -40
  10. jolt/error.py +19 -4
  11. jolt/filesystem.py +2 -6
  12. jolt/graph.py +400 -82
  13. jolt/influence.py +110 -3
  14. jolt/loader.py +338 -174
  15. jolt/log.py +127 -31
  16. jolt/manifest.py +13 -46
  17. jolt/options.py +35 -11
  18. jolt/pkgs/abseil.py +42 -0
  19. jolt/pkgs/asio.py +25 -0
  20. jolt/pkgs/autoconf.py +41 -0
  21. jolt/pkgs/automake.py +41 -0
  22. jolt/pkgs/b2.py +31 -0
  23. jolt/pkgs/boost.py +111 -0
  24. jolt/pkgs/boringssl.py +32 -0
  25. jolt/pkgs/busybox.py +39 -0
  26. jolt/pkgs/bzip2.py +43 -0
  27. jolt/pkgs/cares.py +29 -0
  28. jolt/pkgs/catch2.py +36 -0
  29. jolt/pkgs/cbindgen.py +17 -0
  30. jolt/pkgs/cista.py +19 -0
  31. jolt/pkgs/clang.py +44 -0
  32. jolt/pkgs/cli11.py +24 -0
  33. jolt/pkgs/cmake.py +48 -0
  34. jolt/pkgs/cpython.py +196 -0
  35. jolt/pkgs/crun.py +29 -0
  36. jolt/pkgs/curl.py +38 -0
  37. jolt/pkgs/dbus.py +18 -0
  38. jolt/pkgs/double_conversion.py +24 -0
  39. jolt/pkgs/fastfloat.py +21 -0
  40. jolt/pkgs/ffmpeg.py +28 -0
  41. jolt/pkgs/flatbuffers.py +29 -0
  42. jolt/pkgs/fmt.py +27 -0
  43. jolt/pkgs/fstree.py +20 -0
  44. jolt/pkgs/gflags.py +18 -0
  45. jolt/pkgs/glib.py +18 -0
  46. jolt/pkgs/glog.py +25 -0
  47. jolt/pkgs/glslang.py +21 -0
  48. jolt/pkgs/golang.py +16 -11
  49. jolt/pkgs/googlebenchmark.py +18 -0
  50. jolt/pkgs/googletest.py +46 -0
  51. jolt/pkgs/gperf.py +15 -0
  52. jolt/pkgs/grpc.py +73 -0
  53. jolt/pkgs/hdf5.py +19 -0
  54. jolt/pkgs/help2man.py +14 -0
  55. jolt/pkgs/inja.py +28 -0
  56. jolt/pkgs/jsoncpp.py +31 -0
  57. jolt/pkgs/libarchive.py +43 -0
  58. jolt/pkgs/libcap.py +44 -0
  59. jolt/pkgs/libdrm.py +44 -0
  60. jolt/pkgs/libedit.py +42 -0
  61. jolt/pkgs/libevent.py +31 -0
  62. jolt/pkgs/libexpat.py +27 -0
  63. jolt/pkgs/libfastjson.py +21 -0
  64. jolt/pkgs/libffi.py +16 -0
  65. jolt/pkgs/libglvnd.py +30 -0
  66. jolt/pkgs/libogg.py +28 -0
  67. jolt/pkgs/libpciaccess.py +18 -0
  68. jolt/pkgs/libseccomp.py +21 -0
  69. jolt/pkgs/libtirpc.py +24 -0
  70. jolt/pkgs/libtool.py +42 -0
  71. jolt/pkgs/libunwind.py +35 -0
  72. jolt/pkgs/libva.py +18 -0
  73. jolt/pkgs/libvorbis.py +33 -0
  74. jolt/pkgs/libxml2.py +35 -0
  75. jolt/pkgs/libxslt.py +17 -0
  76. jolt/pkgs/libyajl.py +16 -0
  77. jolt/pkgs/llvm.py +81 -0
  78. jolt/pkgs/lua.py +54 -0
  79. jolt/pkgs/lz4.py +26 -0
  80. jolt/pkgs/m4.py +14 -0
  81. jolt/pkgs/make.py +17 -0
  82. jolt/pkgs/mesa.py +81 -0
  83. jolt/pkgs/meson.py +17 -0
  84. jolt/pkgs/mstch.py +28 -0
  85. jolt/pkgs/mysql.py +60 -0
  86. jolt/pkgs/nasm.py +49 -0
  87. jolt/pkgs/ncurses.py +30 -0
  88. jolt/pkgs/ng_log.py +25 -0
  89. jolt/pkgs/ninja.py +45 -0
  90. jolt/pkgs/nlohmann_json.py +25 -0
  91. jolt/pkgs/nodejs.py +19 -11
  92. jolt/pkgs/opencv.py +24 -0
  93. jolt/pkgs/openjdk.py +26 -0
  94. jolt/pkgs/openssl.py +103 -0
  95. jolt/pkgs/paho.py +76 -0
  96. jolt/pkgs/patchelf.py +16 -0
  97. jolt/pkgs/perl.py +42 -0
  98. jolt/pkgs/pkgconfig.py +64 -0
  99. jolt/pkgs/poco.py +39 -0
  100. jolt/pkgs/protobuf.py +77 -0
  101. jolt/pkgs/pugixml.py +27 -0
  102. jolt/pkgs/python.py +19 -0
  103. jolt/pkgs/qt.py +35 -0
  104. jolt/pkgs/rapidjson.py +26 -0
  105. jolt/pkgs/rapidyaml.py +28 -0
  106. jolt/pkgs/re2.py +30 -0
  107. jolt/pkgs/re2c.py +17 -0
  108. jolt/pkgs/readline.py +15 -0
  109. jolt/pkgs/rust.py +41 -0
  110. jolt/pkgs/sdl.py +28 -0
  111. jolt/pkgs/simdjson.py +27 -0
  112. jolt/pkgs/soci.py +46 -0
  113. jolt/pkgs/spdlog.py +29 -0
  114. jolt/pkgs/spirv_llvm.py +21 -0
  115. jolt/pkgs/spirv_tools.py +24 -0
  116. jolt/pkgs/sqlite.py +83 -0
  117. jolt/pkgs/ssl.py +12 -0
  118. jolt/pkgs/texinfo.py +15 -0
  119. jolt/pkgs/tomlplusplus.py +22 -0
  120. jolt/pkgs/wayland.py +26 -0
  121. jolt/pkgs/x11.py +58 -0
  122. jolt/pkgs/xerces_c.py +20 -0
  123. jolt/pkgs/xorg.py +360 -0
  124. jolt/pkgs/xz.py +29 -0
  125. jolt/pkgs/yamlcpp.py +30 -0
  126. jolt/pkgs/zeromq.py +47 -0
  127. jolt/pkgs/zlib.py +87 -0
  128. jolt/pkgs/zstd.py +33 -0
  129. jolt/plugins/alias.py +3 -0
  130. jolt/plugins/allure.py +2 -2
  131. jolt/plugins/autotools.py +66 -0
  132. jolt/plugins/cache.py +1 -1
  133. jolt/plugins/cmake.py +74 -6
  134. jolt/plugins/conan.py +238 -0
  135. jolt/plugins/cxxinfo.py +7 -0
  136. jolt/plugins/docker.py +76 -19
  137. jolt/plugins/email.xslt +141 -118
  138. jolt/plugins/environ.py +11 -0
  139. jolt/plugins/fetch.py +141 -0
  140. jolt/plugins/gdb.py +33 -14
  141. jolt/plugins/gerrit.py +0 -13
  142. jolt/plugins/git.py +248 -66
  143. jolt/plugins/googletest.py +1 -1
  144. jolt/plugins/http.py +1 -1
  145. jolt/plugins/libtool.py +63 -0
  146. jolt/plugins/linux.py +990 -0
  147. jolt/plugins/logstash.py +4 -4
  148. jolt/plugins/meson.py +61 -0
  149. jolt/plugins/ninja-compdb.py +96 -28
  150. jolt/plugins/ninja.py +424 -150
  151. jolt/plugins/paths.py +11 -1
  152. jolt/plugins/pkgconfig.py +219 -0
  153. jolt/plugins/podman.py +131 -87
  154. jolt/plugins/python.py +137 -0
  155. jolt/plugins/remote_execution/administration_pb2.py +27 -19
  156. jolt/plugins/remote_execution/log_pb2.py +12 -12
  157. jolt/plugins/remote_execution/scheduler_pb2.py +23 -23
  158. jolt/plugins/remote_execution/worker_pb2.py +19 -19
  159. jolt/plugins/report.py +7 -2
  160. jolt/plugins/rust.py +25 -0
  161. jolt/plugins/scheduler.py +135 -86
  162. jolt/plugins/selfdeploy/setup.py +6 -6
  163. jolt/plugins/selfdeploy.py +49 -31
  164. jolt/plugins/strings.py +35 -22
  165. jolt/plugins/symlinks.py +11 -4
  166. jolt/plugins/telemetry.py +1 -2
  167. jolt/plugins/timeline.py +13 -3
  168. jolt/scheduler.py +467 -165
  169. jolt/tasks.py +427 -111
  170. jolt/templates/timeline.html.template +44 -47
  171. jolt/timer.py +22 -0
  172. jolt/tools.py +527 -188
  173. jolt/utils.py +183 -3
  174. jolt/version.py +1 -1
  175. jolt/xmldom.py +12 -2
  176. {jolt-0.9.172.dist-info → jolt-0.9.435.dist-info}/METADATA +97 -41
  177. jolt-0.9.435.dist-info/RECORD +207 -0
  178. {jolt-0.9.172.dist-info → jolt-0.9.435.dist-info}/WHEEL +1 -1
  179. jolt/plugins/amqp.py +0 -855
  180. jolt/plugins/debian.py +0 -338
  181. jolt/plugins/repo.py +0 -253
  182. jolt/plugins/snap.py +0 -122
  183. jolt-0.9.172.dist-info/RECORD +0 -92
  184. {jolt-0.9.172.dist-info → jolt-0.9.435.dist-info}/entry_points.txt +0 -0
  185. {jolt-0.9.172.dist-info → jolt-0.9.435.dist-info}/top_level.txt +0 -0
jolt/log.py CHANGED
@@ -26,9 +26,10 @@ from jolt.error import JoltError
26
26
  from jolt import filesystem as fs
27
27
  from jolt import colors
28
28
  from jolt import common_pb2 as common_pb
29
+ from jolt import utils
29
30
 
30
31
 
31
- current_time = datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f")
32
+ current_time = datetime.now().strftime("%Y-%m-%dT%H%M%S.%f")
32
33
  logpath = config.get_logpath()
33
34
  logfile = fs.path.join(logpath, f"{current_time}.log")
34
35
  logcount = config.getint("jolt", "logcount", os.environ.get("JOLT_LOGCOUNT", 100))
@@ -40,15 +41,15 @@ if not fs.path.exists(dirpath):
40
41
 
41
42
  ################################################################################
42
43
 
43
- ERROR = common_pb.LogLevel.ERROR
44
- WARNING = common_pb.LogLevel.WARNING
45
- INFO = common_pb.LogLevel.INFO
46
- VERBOSE = common_pb.LogLevel.VERBOSE
47
- DEBUG = common_pb.LogLevel.DEBUG
48
- EXCEPTION = common_pb.LogLevel.EXCEPTION
49
- STDOUT = common_pb.LogLevel.STDOUT
50
- STDERR = common_pb.LogLevel.STDERR
51
- SILENCE = STDERR + 1
44
+ ERROR = common_pb.LogLevel.ERROR + 1
45
+ WARNING = common_pb.LogLevel.WARNING + 1
46
+ INFO = common_pb.LogLevel.INFO + 1
47
+ VERBOSE = common_pb.LogLevel.VERBOSE + 1
48
+ DEBUG = common_pb.LogLevel.DEBUG + 1
49
+ EXCEPTION = common_pb.LogLevel.EXCEPTION + 1
50
+ STDOUT = common_pb.LogLevel.STDOUT + 1
51
+ STDERR = common_pb.LogLevel.STDERR + 1
52
+ SILENCE = STDERR + 2
52
53
 
53
54
  logging.addLevelName(VERBOSE, "VERBOSE")
54
55
  logging.addLevelName(STDOUT, "STDOUT")
@@ -142,13 +143,37 @@ class TqdmStream(object):
142
143
  getattr(self.stream, 'flush', lambda: None)()
143
144
 
144
145
 
146
+ class ThreadPrefix(logging.LoggerAdapter):
147
+ thread_prefix = {}
148
+
149
+ def process(self, msg, kwargs):
150
+ tid = threading.current_thread()
151
+ if tid in self.thread_prefix:
152
+ msg = f"[{self.thread_prefix[tid]}] {msg}"
153
+ return msg, kwargs
154
+
155
+ def set_thread_prefix(self, prefix):
156
+ tid = threading.current_thread()
157
+ self.thread_prefix[tid] = prefix
158
+
159
+ def clear_thread_prefix(self):
160
+ tid = threading.current_thread()
161
+ if tid in self.thread_prefix:
162
+ del self.thread_prefix[tid]
163
+
164
+
145
165
  # silence root logger
146
166
  _root = logging.getLogger()
147
167
  _root.setLevel(logging.CRITICAL)
148
168
 
149
- # create jolt logger
169
+ # create jolt logger and protect it's methods against interrupts
150
170
  _logger = logging.getLogger('jolt')
151
- _logger.setLevel(DEBUG)
171
+ _logger.setLevel(EXCEPTION)
172
+ _logger.handle = utils.delay_interrupt(_logger.handle)
173
+ _logger.log = utils.delay_interrupt(_logger.log)
174
+ _logger.addHandler = utils.delay_interrupt(_logger.addHandler)
175
+ _logger.removeHandler = utils.delay_interrupt(_logger.removeHandler)
176
+
152
177
 
153
178
  _console_formatter = ConsoleFormatter('[{levelname:>7}] {message}', '{message}')
154
179
 
@@ -158,17 +183,18 @@ else:
158
183
  _stdout = logging.StreamHandler(sys.stdout)
159
184
  _stdout.setFormatter(_console_formatter)
160
185
  _stdout.addFilter(Filter(lambda r: r.levelno < ERROR))
186
+ _stdout.addFilter(Filter(lambda r: r.levelno != EXCEPTION))
161
187
 
162
188
  if sys.stdout.isatty() and sys.stderr.isatty():
163
189
  _stderr = logging.StreamHandler(TqdmStream(sys.stdout))
164
190
  else:
165
191
  _stderr = logging.StreamHandler(sys.stderr)
166
192
  _stderr.setFormatter(_console_formatter)
167
- _stderr.addFilter(Filter(lambda r: r.levelno >= ERROR))
168
- _stderr.addFilter(Filter(lambda r: r.levelno != EXCEPTION))
193
+ _stderr.addFilter(Filter(lambda r: r.levelno >= ERROR or r.levelno == EXCEPTION))
169
194
 
170
195
  _logger.addHandler(_stdout)
171
196
  _logger.addHandler(_stderr)
197
+ _logger_frontend = ThreadPrefix(_logger, {})
172
198
 
173
199
  _file_formatter = Formatter('{asctime} [{levelname:>7}] {message}')
174
200
 
@@ -183,7 +209,7 @@ def start_file_log():
183
209
  os.unlink(file)
184
210
 
185
211
  _file = logging.FileHandler(logfile)
186
- _file.setLevel(DEBUG)
212
+ _file.setLevel(EXCEPTION)
187
213
  _file.setFormatter(_file_formatter)
188
214
  _logger.addHandler(_file)
189
215
 
@@ -206,35 +232,35 @@ def log(level, message, created=None, context=None, prefix=False):
206
232
 
207
233
 
208
234
  def info(fmt, *args, **kwargs):
209
- _logger.log(INFO, fmt, *args, **kwargs)
235
+ _logger_frontend.log(INFO, fmt, *args, **kwargs)
210
236
 
211
237
 
212
238
  def warning(fmt, *args, **kwargs):
213
- _logger.log(WARNING, fmt, *args, **kwargs)
239
+ _logger_frontend.log(WARNING, fmt, *args, **kwargs)
214
240
 
215
241
 
216
242
  def verbose(fmt, *args, **kwargs):
217
- _logger.log(VERBOSE, fmt, *args, **kwargs)
243
+ _logger_frontend.log(VERBOSE, fmt, *args, **kwargs)
218
244
 
219
245
 
220
246
  def debug(fmt, *args, **kwargs):
221
- _logger.log(DEBUG, fmt, *args, **kwargs)
247
+ _logger_frontend.log(DEBUG, fmt, *args, **kwargs)
222
248
 
223
249
 
224
250
  def error(fmt, *args, **kwargs):
225
- _logger.log(ERROR, fmt, *args, **kwargs)
251
+ _logger_frontend.log(ERROR, fmt, *args, **kwargs)
226
252
 
227
253
 
228
254
  def stdout(line, **kwargs):
229
255
  line = line.replace("{", "{{")
230
256
  line = line.replace("}", "}}")
231
- _logger.log(STDOUT, line, extra=kwargs)
257
+ _logger_frontend.log(STDOUT, line, extra=kwargs)
232
258
 
233
259
 
234
260
  def stderr(line, **kwargs):
235
261
  line = line.replace("{", "{{")
236
262
  line = line.replace("}", "}}")
237
- _logger.log(STDERR, line, extra=kwargs)
263
+ _logger_frontend.log(STDERR, line, extra=kwargs)
238
264
 
239
265
 
240
266
  def format_exception_msg(exc):
@@ -264,10 +290,17 @@ def format_exception_msg(exc):
264
290
  te.stack[-1].name)
265
291
 
266
292
 
267
- def exception(exc=None):
293
+ def exception(exc=None, error=True):
268
294
  if exc:
269
- _logger.error(format_exception_msg(exc))
270
- backtrace = traceback.format_exc().splitlines()
295
+ if error:
296
+ _logger_frontend.log(ERROR, format_exception_msg(exc))
297
+
298
+ tb = traceback.format_exception(type(exc), value=exc, tb=exc.__traceback__)
299
+ installdir = fs.path.dirname(__file__)
300
+ if any(map(lambda frame: installdir not in frame, tb[1:-1])):
301
+ while len(tb) > 2 and installdir in tb[1]:
302
+ del tb[1]
303
+ backtrace = "".join(tb).splitlines()
271
304
  else:
272
305
  backtrace = traceback.format_exc().splitlines()
273
306
 
@@ -275,7 +308,7 @@ def exception(exc=None):
275
308
  line = line.replace("{", "{{")
276
309
  line = line.replace("}", "}}")
277
310
  line = line.strip()
278
- _logger.log(EXCEPTION, line)
311
+ _logger_frontend.log(EXCEPTION, line)
279
312
 
280
313
 
281
314
  def transfer(line, context):
@@ -295,7 +328,7 @@ def transfer(line, context):
295
328
  elif line.startswith("[ EXCEPT]"):
296
329
  outline1 = outline1.replace("{", "{{")
297
330
  outline1 = outline1.replace("}", "}}")
298
- _logger.log(EXCEPTION, outline1)
331
+ _logger_frontend.log(EXCEPTION, outline1)
299
332
  elif line.startswith("[ STDERR]"):
300
333
  stderr(outline1, prefix=True)
301
334
  elif line.startswith("[ STDOUT]"):
@@ -325,17 +358,36 @@ class _Progress(object):
325
358
  def update(self, *args, **kwargs):
326
359
  pass
327
360
 
361
+ def refresh(self, *args, **kwargs):
362
+ pass
363
+
364
+ def reset(self, *args, **kwargs):
365
+ pass
366
+
367
+ def set_description(self, *args, **kwargs):
368
+ pass
369
+
328
370
 
329
371
  def progress_log(desc, count, unit):
330
372
  return _Progress(desc)
331
373
 
332
374
 
333
375
  def progress(desc, count, unit, estimates=True, debug=False):
334
- bar_format = '{l_bar}{bar}| {n_fmt}/{total_fmt} [{elapsed}]' \
335
- if not estimates else None
376
+ if count:
377
+ bar_format = '{l_bar}{bar}| {n_fmt}/{total_fmt} [{elapsed}]' \
378
+ if not estimates else None
379
+ else:
380
+ bar_format = '{desc}{n_fmt}{unit} [{elapsed}]'
336
381
  if not debug and is_interactive() and not is_verbose():
337
- p = tqdm.tqdm(total=count, unit=unit, unit_scale=True, bar_format=bar_format, dynamic_ncols=True)
338
- p.set_description("[ INFO] " + desc)
382
+ class ProgressTqdm(tqdm.tqdm):
383
+ def __init__(self, *args, **kwargs):
384
+ super(ProgressTqdm, self).__init__(*args, **kwargs)
385
+
386
+ def set_description(self, desc=None, refresh=True):
387
+ return super().set_description("[ INFO] " + desc, refresh)
388
+
389
+ p = ProgressTqdm(total=count, unit=unit, unit_scale=True, bar_format=bar_format, dynamic_ncols=True)
390
+ p.set_description(desc)
339
391
  return p
340
392
  return progress_log(desc, count, unit)
341
393
 
@@ -343,18 +395,53 @@ def progress(desc, count, unit, estimates=True, debug=False):
343
395
  _level = INFO
344
396
 
345
397
 
398
+ def level_to_pb(level):
399
+ """ Convert a log level to a protobuf enum value. """
400
+ return level - 1
401
+
402
+
403
+ def pb_to_level(level):
404
+ """ Convert a protobuf enum value to a log level. """
405
+ return level + 1
406
+
407
+
346
408
  def set_level(level):
409
+ """ Set the log level for terminal output. """
410
+
411
+ if level not in [
412
+ DEBUG,
413
+ ERROR,
414
+ EXCEPTION,
415
+ INFO,
416
+ SILENCE,
417
+ STDERR,
418
+ STDOUT,
419
+ VERBOSE,
420
+ WARNING,
421
+ ]:
422
+ raise ValueError("invalid log level")
423
+
347
424
  global _level
348
425
  _level = level
349
426
  _stdout.setLevel(level)
350
427
  _stderr.setLevel(level)
351
428
 
352
429
 
430
+ def set_level_pb(level):
431
+ """ Set the log level from a protobuf enum value. """
432
+ set_level(pb_to_level(level))
433
+
434
+
353
435
  def get_level():
354
436
  global _level
355
437
  return _level
356
438
 
357
439
 
440
+ def get_level_pb():
441
+ """ Get the log level as a protobuf enum value. """
442
+ return level_to_pb(_level)
443
+
444
+
358
445
  def set_worker():
359
446
  _console_formatter.enable_prefixes()
360
447
 
@@ -434,6 +521,15 @@ def map_thread(thread_from, thread_to):
434
521
  _thread_map.unmap(tid)
435
522
 
436
523
 
524
+ @contextmanager
525
+ def thread_prefix(prefix):
526
+ try:
527
+ _logger_frontend.set_thread_prefix(prefix)
528
+ yield
529
+ finally:
530
+ _logger_frontend.clear_thread_prefix()
531
+
532
+
437
533
  class _LogStream(object):
438
534
  def __init__(self):
439
535
  self.buf = ""
jolt/manifest.py CHANGED
@@ -113,7 +113,9 @@ class _JoltNetworkParameter(SubElement):
113
113
  @Attribute("stderr", child=True, zlib=True)
114
114
  @Attribute("result", child=True)
115
115
  @Attribute("duration", child=True)
116
+ @Attribute("name")
116
117
  @Attribute("workspace")
118
+ @Attribute("build")
117
119
  @Attribute("version")
118
120
  @Composition(_JoltRecipe, "recipe")
119
121
  @Composition(_JoltTask, "task")
@@ -127,8 +129,10 @@ class JoltManifest(ElementTree):
127
129
  self._elem = self.getroot()
128
130
  self.path = None
129
131
 
130
- @property
131
- def joltdir(self):
132
+ def is_valid(self):
133
+ return self.path is not None
134
+
135
+ def get_workspace_path(self):
132
136
  if self.path is None:
133
137
  return None
134
138
  joltdir = fs.path.dirname(self.path)
@@ -136,6 +140,13 @@ class JoltManifest(ElementTree):
136
140
  joltdir = fs.path.normpath(fs.path.join(joltdir, self.workspace))
137
141
  return joltdir
138
142
 
143
+ def get_workspace_name(self):
144
+ if self.name:
145
+ return self.name
146
+ if self.path is None:
147
+ return None
148
+ return fs.path.basename(fs.path.dirname(self.path))
149
+
139
150
  @property
140
151
  def attrib(self):
141
152
  return self.getroot().attrib
@@ -230,47 +241,3 @@ class JoltManifest(ElementTree):
230
241
  for manifest_task in self.tasks:
231
242
  self._identities[manifest_task.name] = manifest_task.identity
232
243
  return self._identities
233
-
234
- @staticmethod
235
- def export(task):
236
- manifest = JoltManifest()
237
- ManifestExtensionRegistry.export_manifest(manifest, task)
238
- return manifest
239
-
240
- def process_import(self):
241
- ManifestExtensionRegistry.import_manifest(self)
242
-
243
-
244
- class ManifestExtensionRegistry(object):
245
- extensions = []
246
-
247
- @staticmethod
248
- def add(extension, priority=0):
249
- ManifestExtensionRegistry.extensions.append((extension, priority))
250
- ManifestExtensionRegistry.extensions.sort(key=lambda x: x[1])
251
-
252
- @staticmethod
253
- def export_manifest(manifest, task):
254
- for extension, _ in ManifestExtensionRegistry.extensions:
255
- extension.export_manifest(manifest, task)
256
-
257
- @staticmethod
258
- def import_manifest(manifest):
259
- for extension, _ in ManifestExtensionRegistry.extensions:
260
- extension.import_manifest(manifest)
261
-
262
- @staticmethod
263
- def import_protobuf(pb):
264
- for extension, _ in ManifestExtensionRegistry.extensions:
265
- extension.import_protobuf(pb)
266
-
267
-
268
- class ManifestExtension(object):
269
- def export_manifest(self, manifest, task):
270
- pass
271
-
272
- def import_manifest(self, manifest):
273
- pass
274
-
275
- def import_protobuf(self, pb):
276
- pass
jolt/options.py CHANGED
@@ -1,15 +1,39 @@
1
1
 
2
2
  class JoltOptions(object):
3
+ """ Jolt options that control the behavior of builds. """
4
+
5
+ debug = False
6
+ """ Enable debug mode. Break into debugger on exceptions. """
7
+
8
+ download = True
9
+ """ Enable downloading of remote artifacts, both session and persistent. """
10
+
11
+ download_session = True
12
+ """ Enable downloading of remote session artifacts. """
13
+
14
+ keep_going = False
15
+ """ Keep going with the build after a task fails. """
16
+
17
+ local = False
18
+ """ Disable network access. """
19
+
20
+ network = False
21
+ """ Distribute tasks to workers. """
22
+
23
+ upload = True
24
+ """ Enable uploading of artifacts. """
25
+
26
+ worker = False
27
+ """ Running as a worker. """
28
+
29
+ salt = None
30
+ """ Salt for hashing (--salt). """
31
+
32
+ jobs = 1
33
+ """ Number of concurrent local tasks to run (1). """
34
+
35
+ mute = False
36
+ """ Mute task output, until a task fails. """
37
+
3
38
  def __init__(self, **kwargs):
4
- self.debug = False
5
- self.default = []
6
- self.download = True
7
- self.keep_going = False
8
- self.local = False
9
- self.network = False
10
- self.upload = True
11
- self.worker = False
12
- self.salt = None
13
- self.jobs = 1
14
- self.mute = False
15
39
  self.__dict__.update(kwargs)
jolt/pkgs/abseil.py ADDED
@@ -0,0 +1,42 @@
1
+ from jolt import attributes, BooleanParameter, Parameter, Task
2
+ from jolt.plugins import cmake, git
3
+ from jolt.tasks import TaskRegistry
4
+ import os
5
+
6
+
7
+ @attributes.requires("requires_git")
8
+ @attributes.system
9
+ @cmake.requires()
10
+ @cmake.use_ninja()
11
+ class Abseil(cmake.CMake):
12
+ """ Abseil C++ Common Libraries """
13
+
14
+ name = "abseil"
15
+ version = Parameter("20250814.1")
16
+ shared = BooleanParameter(False, help="Build shared libraries")
17
+ requires_git = ["git:url=https://github.com/abseil/abseil-cpp.git,rev={version}"]
18
+ srcdir = "{git[abseil-cpp]}"
19
+ options = [
20
+ "ABSL_MSVC_STATIC_RUNTIME=OFF",
21
+ "BUILD_SHARED_LIBS={shared[ON,OFF]}",
22
+ "CMAKE_CXX_STANDARD=17",
23
+ ]
24
+
25
+ def publish(self, artifact, tools):
26
+ super().publish(artifact, tools)
27
+ artifact.cxxinfo.crt = "Dynamic"
28
+ artifact.cxxinfo.incpaths.append("include")
29
+ artifact.cxxinfo.libpaths.append("lib")
30
+ if self.shared:
31
+ artifact.environ.LD_LIBRARY_PATH.append("lib")
32
+
33
+ with tools.cwd(artifact.path, "lib"):
34
+ for libfile in tools.glob("*.lib"):
35
+ libname, _ = os.path.splitext(libfile)
36
+ artifact.cxxinfo.libraries.append(libname)
37
+ for libfile in tools.glob("lib*.a"):
38
+ libname, _ = os.path.splitext(libfile)
39
+ artifact.cxxinfo.libraries.append(libname[3:])
40
+
41
+
42
+ TaskRegistry.get().add_task_class(Abseil)
jolt/pkgs/asio.py ADDED
@@ -0,0 +1,25 @@
1
+ from jolt import attributes, Parameter
2
+ from jolt.plugins import cmake, git, autotools, pkgconfig
3
+ from jolt.tasks import TaskRegistry
4
+
5
+
6
+ @attributes.requires("requires_git")
7
+ @autotools.requires()
8
+ @pkgconfig.requires()
9
+ @pkgconfig.to_cxxinfo("asio")
10
+ class Asio(autotools.Autotools):
11
+ name = "asio"
12
+ version = Parameter("1.36.0", help="asio version.")
13
+ requires_git = ["git:url=https://github.com/chriskohlhoff/asio.git,rev=asio-{_version}"]
14
+ srcdir = "{git[asio]}/asio"
15
+
16
+ @property
17
+ def _version(self):
18
+ return str(self.version).replace(".", "-")
19
+
20
+ def publish(self, artifact, tools):
21
+ super().publish(artifact, tools)
22
+ artifact.environ.CMAKE_PREFIX_PATH.append(".")
23
+
24
+
25
+ TaskRegistry.get().add_task_class(Asio)
jolt/pkgs/autoconf.py ADDED
@@ -0,0 +1,41 @@
1
+ from jolt import attributes, Parameter
2
+ from jolt.pkgs import help2man, m4, texinfo
3
+ from jolt.plugins import git, autotools
4
+ from jolt.tasks import TaskRegistry
5
+
6
+
7
+ @attributes.requires("requires_git")
8
+ @attributes.requires("requires_help2man")
9
+ @attributes.requires("requires_m4")
10
+ @attributes.requires("requires_texinfo")
11
+ class Autoconf(autotools.Autotools):
12
+ name = "autoconf"
13
+ version = Parameter("2.72", help="Autoconf version.")
14
+ requires_git = ["fetch:alias=src,url=https://ftpmirror.gnu.org/gnu/autoconf/autoconf-{version}.tar.gz"]
15
+ requires_help2man = ["help2man"]
16
+ requires_m4 = ["m4"]
17
+ requires_texinfo = ["texinfo"]
18
+ srcdir = "{fetch[src]}/autoconf-{version}"
19
+
20
+ def publish(self, artifact, tools):
21
+ super().publish(artifact, tools)
22
+ self.unpack(artifact, tools)
23
+
24
+ def unpack(self, artifact, tools):
25
+ with tools.cwd(artifact.path, "bin"):
26
+ for file in tools.glob("*"):
27
+ tools.replace_in_file(
28
+ file,
29
+ artifact.strings.install_prefix,
30
+ artifact.final_path)
31
+
32
+ with tools.cwd(artifact.path, "share/autoconf"):
33
+ tools.replace_in_file(
34
+ "autom4te.cfg",
35
+ artifact.strings.install_prefix,
36
+ artifact.final_path)
37
+
38
+ artifact.strings.install_prefix = artifact.final_path
39
+
40
+
41
+ TaskRegistry.get().add_task_class(Autoconf)
jolt/pkgs/automake.py ADDED
@@ -0,0 +1,41 @@
1
+ from jolt import attributes, Parameter, Task
2
+ from jolt.plugins import git, autotools
3
+ from jolt.tasks import TaskRegistry
4
+
5
+
6
+ @attributes.requires("requires_git")
7
+ @attributes.requires("requires_texinfo")
8
+ @autotools.requires(automake=False, libtool=False)
9
+ class Automake(autotools.Autotools):
10
+ name = "automake"
11
+ version = Parameter("1.18.1", help="Automake version.")
12
+ requires_git = ["fetch:alias=src,url=https://ftpmirror.gnu.org/gnu/automake/automake-{version}.tar.xz"]
13
+ requires_texinfo = ["texinfo"]
14
+ srcdir = "{fetch[src]}/automake-{version}"
15
+
16
+ def publish(self, artifact, tools):
17
+ super().publish(artifact, tools)
18
+ self.unpack(artifact, tools)
19
+
20
+ def unpack(self, artifact, tools):
21
+ with tools.cwd(artifact.path, "bin"):
22
+ for file in tools.glob("*"):
23
+ tools.replace_in_file(
24
+ file,
25
+ artifact.strings.install_prefix,
26
+ artifact.final_path)
27
+
28
+ for file in tools.glob(artifact.path + "/share/automake-*/Automake/Config.pm"):
29
+ tools.replace_in_file(
30
+ file,
31
+ artifact.strings.install_prefix,
32
+ artifact.final_path)
33
+
34
+ with tools.cwd(artifact.path):
35
+ for file in tools.glob("share/aclocal-*"):
36
+ artifact.environ.ACLOCAL_PATH.append(file)
37
+
38
+ artifact.strings.install_prefix = artifact.final_path
39
+
40
+
41
+ TaskRegistry.get().add_task_class(Automake)
jolt/pkgs/b2.py ADDED
@@ -0,0 +1,31 @@
1
+ import os
2
+ from jolt import attributes, Parameter
3
+ from jolt.plugins import git
4
+ from jolt.tasks import Task, TaskRegistry
5
+
6
+
7
+ @attributes.common_metadata()
8
+ @attributes.requires("requires_git")
9
+ @attributes.system
10
+ class B2(Task):
11
+ name = "b2"
12
+ version = Parameter("5.4.2", help="B2 version.")
13
+ requires_git = ["git:url=https://github.com/bfgroup/b2.git"]
14
+
15
+ def run(self, artifact, tools):
16
+ self.builddir = tools.builddir("build", incremental=True)
17
+ self.installdir = tools.builddir("install")
18
+ with tools.cwd("{git[b2]}"):
19
+ if self.system == "windows":
20
+ tools.run(".\\bootstrap.bat")
21
+ tools.run(".\\b2 install --prefix={installdir} --build-dir={builddir} -j{}", tools.cpu_count())
22
+ else:
23
+ tools.run("./bootstrap.sh")
24
+ tools.run("./b2 install --prefix={installdir} --build-dir={builddir} -j{}", tools.cpu_count())
25
+
26
+ def publish(self, artifact, tools):
27
+ with tools.cwd(self.installdir):
28
+ artifact.collect("*", symlinks=True)
29
+
30
+
31
+ TaskRegistry.get().add_task_class(B2)