|
22 | 22 | import click |
23 | 23 |
|
24 | 24 | from .profile import Profile |
25 | | -from ..types import _Scope |
| 25 | +from ..types import _Scope, _ElementKind, _ElementState |
26 | 26 | from .. import _yaml |
27 | 27 | from .. import __version__ as bst_version |
28 | 28 | from .. import FileType |
@@ -327,6 +327,120 @@ def __init__( |
327 | 327 | logfile_tokens = self._parse_logfile_format(context.log_message_format, content_profile, format_profile) |
328 | 328 | self._columns.extend(logfile_tokens) |
329 | 329 |
|
| 330 | + def _read_state(self, element): |
| 331 | + try: |
| 332 | + if not element._has_all_sources_resolved(): |
| 333 | + return _ElementState.NO_REFERENCE |
| 334 | + else: |
| 335 | + if element.get_kind() == "junction": |
| 336 | + return _ElementState.JUNCTION |
| 337 | + elif not element._can_query_cache(): |
| 338 | + return _ElementState.WAITING |
| 339 | + elif element._cached_failure(): |
| 340 | + return _ElementState.FAILED |
| 341 | + elif element._cached_success(): |
| 342 | + return _ElementState.CACHED |
| 343 | + elif not element._can_query_source_cache(): |
| 344 | + return _ElementState.WAITING |
| 345 | + elif element._fetch_needed(): |
| 346 | + return _ElementState.FETCH_NEEDED |
| 347 | + elif element._buildable(): |
| 348 | + return _ElementState.BUILDABLE |
| 349 | + else: |
| 350 | + return _ElementState.WAITING |
| 351 | + except BstError as e: |
| 352 | + # Provide context to plugin error |
| 353 | + e.args = ("Failed to determine state for {}: {}".format(element._get_full_name(), str(e)),) |
| 354 | + raise e |
| 355 | + |
| 356 | + # Dump the pipeline as a serializable object |
| 357 | + def dump_pipeline(self, dependencies, kinds=[]): |
| 358 | + |
| 359 | + show_all = _ElementKind.ALL in kinds |
| 360 | + |
| 361 | + elements = [] |
| 362 | + |
| 363 | + for element in dependencies: |
| 364 | + |
| 365 | + # Default values always output |
| 366 | + serialized_element = { |
| 367 | + "name": element._get_full_name(), |
| 368 | + } |
| 369 | + |
| 370 | + description = " ".join(element._description.splitlines()) |
| 371 | + if description: |
| 372 | + serialized_element["description"] = description |
| 373 | + |
| 374 | + workspace = element._get_workspace() |
| 375 | + if workspace: |
| 376 | + serialized_element["workspace"] = workspace |
| 377 | + |
| 378 | + if show_all or _ElementKind.STATE in kinds: |
| 379 | + serialized_element["state"] = self._read_state(element).value |
| 380 | + |
| 381 | + if show_all or _ElementKind.KEY in kinds: |
| 382 | + serialized_element["key"] = element._get_display_key().brief |
| 383 | + |
| 384 | + if show_all or _ElementKind.KEY_FULL in kinds: |
| 385 | + serialized_element["key_full"] = element._get_display_key().full |
| 386 | + |
| 387 | + if show_all or _ElementKind.VARIABLES in kinds: |
| 388 | + serialized_element["variables"] = dict(element._Element__variables) |
| 389 | + |
| 390 | + if show_all or _ElementKind.ENVIRONMENT in kinds: |
| 391 | + serialized_element["environment"] = dict(element._Element__environment) |
| 392 | + |
| 393 | + if show_all or _ElementKind.CAS_ARTIFACTS in kinds: |
| 394 | + # BUG: Due to the assersion within .get_artifact this will |
| 395 | + # error but there is no other way to determine if an artifact |
| 396 | + # exists and we only want to show this value for informational |
| 397 | + # purposes. |
| 398 | + try: |
| 399 | + artifact = element._get_artifact() |
| 400 | + if artifact.cached(): |
| 401 | + serialized_element["artifact"] = { |
| 402 | + "files": artifact.get_files(), |
| 403 | + "digest": artifact_files._get_digest(), |
| 404 | + } |
| 405 | + except: |
| 406 | + pass |
| 407 | + |
| 408 | + if show_all or _ElementKind.SOURCES in kinds: |
| 409 | + all_source_infos = [] |
| 410 | + for source in element.sources(): |
| 411 | + source_infos = source.collect_source_info() |
| 412 | + |
| 413 | + if source_infos is not None: |
| 414 | + serialized_sources = [] |
| 415 | + for s in source_infos: |
| 416 | + serialized = s.serialize() |
| 417 | + serialized_sources.append(serialized) |
| 418 | + |
| 419 | + all_source_infos += serialized_sources |
| 420 | + serialized_element["sources"] = all_source_infos |
| 421 | + |
| 422 | + # Show dependencies |
| 423 | + if show_all or _ElementKind.DEPENDENCIES in kinds: |
| 424 | + serialized_element["dependencies"] = [ |
| 425 | + e._get_full_name() for e in element._dependencies(_Scope.ALL, recurse=False) |
| 426 | + ] |
| 427 | + |
| 428 | + # Show build dependencies |
| 429 | + if show_all or _ElementKind.BUILD_DEPENDENCIES in kinds: |
| 430 | + serialized_element["build-dependencies"] = [ |
| 431 | + e._get_full_name() for e in element._dependencies(_Scope.BUILD, recurse=False) |
| 432 | + ] |
| 433 | + |
| 434 | + # Show runtime dependencies |
| 435 | + if show_all or _ElementKind.RUNTIME_DEPENDENCIES in kinds: |
| 436 | + serialized_element["runtime-dependencies"] = [ |
| 437 | + e._get_full_name() for e in element._dependencies(_Scope.RUN, recurse=False) |
| 438 | + ] |
| 439 | + |
| 440 | + elements.append(serialized_element) |
| 441 | + |
| 442 | + return elements |
| 443 | + |
330 | 444 | # show_pipeline() |
331 | 445 | # |
332 | 446 | # Display a list of elements in the specified format. |
@@ -359,30 +473,23 @@ def show_pipeline(self, dependencies, format_): |
359 | 473 | line = p.fmt_subst(line, "full-key", key.full, fg="yellow", dim=dim_keys) |
360 | 474 | line = p.fmt_subst(line, "description", description, fg="yellow", dim=dim_keys) |
361 | 475 |
|
362 | | - try: |
363 | | - if not element._has_all_sources_resolved(): |
364 | | - line = p.fmt_subst(line, "state", "no reference", fg="red") |
365 | | - else: |
366 | | - if element.get_kind() == "junction": |
367 | | - line = p.fmt_subst(line, "state", "junction", fg="magenta") |
368 | | - elif not element._can_query_cache(): |
369 | | - line = p.fmt_subst(line, "state", "waiting", fg="blue") |
370 | | - elif element._cached_failure(): |
371 | | - line = p.fmt_subst(line, "state", "failed", fg="red") |
372 | | - elif element._cached_success(): |
373 | | - line = p.fmt_subst(line, "state", "cached", fg="magenta") |
374 | | - elif not element._can_query_source_cache(): |
375 | | - line = p.fmt_subst(line, "state", "waiting", fg="blue") |
376 | | - elif element._fetch_needed(): |
377 | | - line = p.fmt_subst(line, "state", "fetch needed", fg="red") |
378 | | - elif element._buildable(): |
379 | | - line = p.fmt_subst(line, "state", "buildable", fg="green") |
380 | | - else: |
381 | | - line = p.fmt_subst(line, "state", "waiting", fg="blue") |
382 | | - except BstError as e: |
383 | | - # Provide context to plugin error |
384 | | - e.args = ("Failed to determine state for {}: {}".format(element._get_full_name(), str(e)),) |
385 | | - raise e |
| 476 | + element_state = self._read_state(element) |
| 477 | + if element_state == _ElementState.NO_REFERENCE: |
| 478 | + line = p.fmt_subst(line, "state", "no reference", fg="red") |
| 479 | + elif element_state == _ElementState.JUNCTION: |
| 480 | + line = p.fmt_subst(line, "state", "junction", fg="magenta") |
| 481 | + elif element_state == _ElementState.FAILED: |
| 482 | + line = p.fmt_subst(line, "state", "failed", fg="red") |
| 483 | + elif element_state == _ElementState.CACHED: |
| 484 | + line = p.fmt_subst(line, "state", "cached", fg="magenta") |
| 485 | + elif element_state == _ElementState.WAITING: |
| 486 | + line = p.fmt_subst(line, "state", "waiting", fg="blue") |
| 487 | + elif element_state == _ElementState.FETCH_NEEDED: |
| 488 | + line = p.fmt_subst(line, "state", "fetch needed", fg="red") |
| 489 | + elif element_state == _ElementState.BUILDABLE: |
| 490 | + line = p.fmt_subst(line, "state", "buildable", fg="green") |
| 491 | + else: |
| 492 | + raise BstError(f"Unreachable State: {element_state}") |
386 | 493 |
|
387 | 494 | # Element configuration |
388 | 495 | if "%{config" in format_: |
|
0 commit comments