bin/ci: crnm: format in columns when listing

When we are printing a long list, and it needs more than one line, it gets
hard to review the content. This is an idea to group the elements to be
printed in columns to make it easier to identify individual elements in
the output.

Signed-off-by: Sergi Blanch Torne <sergi.blanch.torne@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34856>
This commit is contained in:
Sergi Blanch Torne 2025-05-06 11:23:02 +02:00 committed by Marge Bot
parent 611772af45
commit e504d226ce
2 changed files with 46 additions and 12 deletions

View file

@ -13,6 +13,7 @@ and show the job(s) logs.
""" """
import argparse import argparse
import os
import re import re
import sys import sys
import time import time
@ -37,7 +38,7 @@ from gitlab_common import (
read_token, read_token,
wait_for_pipeline, wait_for_pipeline,
) )
from gitlab_gql import GitlabGQL, create_job_needs_dag, filter_dag, print_dag from gitlab_gql import GitlabGQL, create_job_needs_dag, filter_dag, print_dag, print_formatted_list
if TYPE_CHECKING: if TYPE_CHECKING:
from gitlab_gql import Dag from gitlab_gql import Dag
@ -494,16 +495,14 @@ def print_detected_jobs(
target_jobs: Iterable[str], target_jobs: Iterable[str],
) -> None: ) -> None:
def print_job_set(color: str, kind: str, job_set: Iterable[str]): def print_job_set(color: str, kind: str, job_set: Iterable[str]):
print( job_list = list(job_set)
color + f"Running {len(job_set)} {kind} jobs: ", print(color + f"Running {len(job_list)} {kind} jobs:")
"\n\t", print_formatted_list(job_list, indentation=8)
", ".join(sorted(job_set)), print(Style.RESET_ALL)
Fore.RESET,
"\n",
)
print(Fore.YELLOW + "Detected target job and its dependencies:", "\n") print(Fore.YELLOW + "Detected target job and its dependencies:")
print_dag(target_dep_dag) print_dag(target_dep_dag, indentation=8)
print(Style.RESET_ALL)
print_job_set(Fore.MAGENTA, "dependency", dependency_jobs) print_job_set(Fore.MAGENTA, "dependency", dependency_jobs)
print_job_set(Fore.BLUE, "target", target_jobs) print_job_set(Fore.BLUE, "target", target_jobs)

View file

@ -3,12 +3,14 @@
import logging import logging
import re import re
import sys
import traceback import traceback
from argparse import ArgumentDefaultsHelpFormatter, ArgumentParser, Namespace from argparse import ArgumentDefaultsHelpFormatter, ArgumentParser, Namespace
from collections import OrderedDict from collections import OrderedDict
from copy import deepcopy from copy import deepcopy
from dataclasses import dataclass, field from dataclasses import dataclass, field
from itertools import accumulate from itertools import accumulate
from os import get_terminal_size
from pathlib import Path from pathlib import Path
from subprocess import check_output from subprocess import check_output
from textwrap import dedent from textwrap import dedent
@ -21,6 +23,8 @@ from gql import Client, gql
from gql.transport.requests import RequestsHTTPTransport from gql.transport.requests import RequestsHTTPTransport
from graphql import DocumentNode from graphql import DocumentNode
DEFAULT_TERMINAL_SIZE: int = 80 # columns
class DagNode(TypedDict): class DagNode(TypedDict):
needs: set[str] needs: set[str]
@ -340,9 +344,40 @@ def filter_dag(
return filtered_jobs return filtered_jobs
def print_dag(dag: Dag) -> None: def print_dag(dag: Dag, indentation: int = 0) -> None:
for job, data in sorted(dag.items()): for job, data in sorted(dag.items()):
print(f"{job}:\n\t{' '.join(data['needs'])}\n") print(f"{' '*indentation}{job}:")
print_formatted_list(list(data['needs']), indentation=indentation+8)
def print_formatted_list(elements: list[str], indentation: int = 0) -> None:
"""
When a list of elements is going to be printed, if it is longer than one line, reformat it to be multiple
lines with a 'ls' command style.
:param elements: list of elements to be printed
:param indentation: number of spaces to be injected in front of each line
"""
if len(elements) == 0:
return
elements.sort()
try:
h_size = get_terminal_size().columns if sys.stdin.isatty() else DEFAULT_TERMINAL_SIZE
except OSError:
h_size = DEFAULT_TERMINAL_SIZE
if indentation + sum(len(element) for element in elements) + (len(elements)*2) < h_size: # fits in one line
print(f"{' '*indentation}{', '.join([element for element in elements])}")
return
column_separator_size = 2
column_width: int = len(max(elements, key=len)) + column_separator_size
n_columns: int = (h_size - indentation) // column_width
step = (len(elements) // n_columns) + 1
rows = [elements[i::step] for i in range(step)]
for line in rows:
print(' '*indentation, end='')
for column in range(len(line)):
if line[column] is not None:
print(f"{line[column]:<{column_width}}", end='')
print()
def fetch_merged_yaml(gl_gql: GitlabGQL, params) -> dict[str, Any]: def fetch_merged_yaml(gl_gql: GitlabGQL, params) -> dict[str, Any]: