Skip to content

topmark.presentation.text.pipeline

TEXT pipeline renderers for the TopMark CLI.

This module renders human-facing TEXT output for pipeline-oriented commands such as topmark check and topmark strip.

TEXT output is console-oriented: it may use verbosity_level for progressive disclosure, styled for ANSI-capable semantic styling, and compact hints that refer to -v / -vv. Markdown and machine-readable output are rendered by separate presentation and machine-readable output layers.

Notes

render_pipeline_diffs_text

render_pipeline_diffs_text(
    *, results, styled, show_line_numbers=False
)

Render standalone TEXT diff payload output for a pipeline command.

This output is separate from the human per-file report. Commands use it for --diff stdout payloads while routing guidance and summaries through the regular human report path. Unlike report-embedded diff sections, this payload intentionally omits human-facing section fences so STDOUT remains a patch-like stream.

Parameters:

Name Type Description Default
results Sequence[ProcessingResult]

Durable processing results to inspect for retained diffs.

required
styled bool

Whether ANSI-capable styling is enabled.

required
show_line_numbers bool

Whether to prepend line numbers.

False

Returns:

Type Description
str

TEXT diff payload output, or an empty string when no diff is available.

Source code in src/topmark/presentation/text/pipeline.py
def render_pipeline_diffs_text(
    *,
    results: Sequence[ProcessingResult],
    styled: bool,
    show_line_numbers: bool = False,
) -> str:
    """Render standalone TEXT diff payload output for a pipeline command.

    This output is separate from the human per-file report. Commands use it for
    `--diff` stdout payloads while routing guidance and summaries through the
    regular human report path. Unlike report-embedded diff sections, this
    payload intentionally omits human-facing section fences so STDOUT remains a
    patch-like stream.

    Args:
        results: Durable processing results to inspect for retained diffs.
        styled: Whether ANSI-capable styling is enabled.
        show_line_numbers: Whether to prepend line numbers.

    Returns:
        TEXT diff payload output, or an empty string when no diff is available.
    """
    rendered_patches: list[str] = []
    for result in results:
        patch: str | None = _render_diff_text(
            result.detail.diff_text,
            styled=styled,
            show_line_numbers=show_line_numbers,
        )
        if patch:
            rendered_patches.append(patch.rstrip("\n"))

    if not rendered_patches:
        return ""

    return "\n\n".join(rendered_patches)

render_pipeline_output_text

render_pipeline_output_text(report)

Render human-facing TEXT output for a pipeline command.

Parameters:

Name Type Description Default
report PipelineCommandHumanReport

Prepared human report for the pipeline command.

required

Returns:

Type Description
str

Rendered TEXT output for the prepared pipeline report.

Raises:

Type Description
RuntimeError

If an invalid pipeline kind was selected.

Source code in src/topmark/presentation/text/pipeline.py
def render_pipeline_output_text(
    report: PipelineCommandHumanReport,
) -> str:
    """Render human-facing TEXT output for a pipeline command.

    Args:
        report: Prepared human report for the pipeline command.

    Returns:
        Rendered TEXT output for the prepared pipeline report.

    Raises:
        RuntimeError: If an invalid pipeline kind was selected.
    """
    make_message: Callable[[ProcessingResult], str | None] | None = None
    if report.pipeline_kind == "check":
        make_message = _render_check_guidance_message_text
    elif report.pipeline_kind == "strip":
        make_message = _render_strip_guidance_message_text
    else:
        # Defensive guard.
        raise RuntimeError(f"Invalid pipeline kind selected: {report.pipeline_kind}")

    # Style helpers already respect the selected color policy.
    warning_styler: TextStyler = style_for_role(
        StyleRole.WARNING,
        styled=report.styled,
    )

    parts: list[str] = []

    # TEXT banner is shown at -v and above.
    if report.verbosity_level > 0:
        parts.append(
            _render_pipeline_banner_text(
                pipeline_kind=report.pipeline_kind,
                n_files=report.file_list_total,
                styled=report.styled,
            )
        )

    # Summary mode (grouped by `(outcome, reason)`)
    if report.summary_mode:
        if report.show_diffs:
            parts.append(
                _render_pipeline_diffs_text(
                    results=report.view_results,
                    styled=report.styled,
                )
            )
        parts.append(
            _render_summary_counts_text(
                view_results=report.view_results,
                total=report.file_list_total,
                styled=report.styled,
            )
        )
    else:
        # Per-file check/strip guidance.
        parts.append(
            _render_per_file_guidance_text(
                results=report.view_results,
                make_message=make_message,
                show_diffs=report.show_diffs,
                verbosity_level=report.verbosity_level,
                styled=report.styled,
            )
        )

    # In actionable mode, unsupported files are hidden from the per-file listing but summarized
    # for visibility.

    if (
        (not report.summary_mode)
        and (report.report_scope == ReportScope.ACTIONABLE)
        and (report.unsupported_count > 0)
    ):
        parts.append(
            warning_styler(
                f"⚠️  Unsupported: {report.unsupported_count} file(s) "
                f"(use {CliOpt.REPORT}={ReportScope.NONCOMPLIANT.value} to list)"
            )
        )

    return "\n".join(parts)

render_pipeline_apply_summary_text

render_pipeline_apply_summary_text(
    *, command_path, written, failed, styled
)

Render the apply-summary footer for TEXT output.

Parameters:

Name Type Description Default
command_path str

Command path, such as topmark check.

required
written int

Number of files written.

required
failed int

Number of files that failed to write.

required
styled bool

Whether ANSI-capable styling is enabled.

required

Returns:

Type Description
str

Rendered TEXT footer.

Source code in src/topmark/presentation/text/pipeline.py
def render_pipeline_apply_summary_text(
    *,
    command_path: str,
    written: int,
    failed: int,
    styled: bool,
) -> str:
    """Render the apply-summary footer for TEXT output.

    Args:
        command_path: Command path, such as `topmark check`.
        written: Number of files written.
        failed: Number of files that failed to write.
        styled: Whether ANSI-capable styling is enabled.

    Returns:
        Rendered TEXT footer.
    """
    parts: list[str] = []
    # Style helpers already respect the selected color policy.
    changed_styler: TextStyler = style_for_role(
        StyleRole.CHANGED,
        styled=styled,
    )
    warning_styler: TextStyler = style_for_role(
        StyleRole.WARNING,
        styled=styled,
    )

    if written:
        msg: str = f"\n✅ {command_path}: applied changes to {written} file(s)."
    else:
        msg = f"\n✅ {command_path}: no changes to apply."
    parts.append(changed_styler(msg))

    if failed:
        parts.append(
            warning_styler(
                f"\n⚠️ {command_path}: failed to write {failed} file(s). See log for details.",
            )
        )

    return "\n".join(parts)