Skip to content

Commit 8e59f1d

Browse files
committed
Auto-detect --format=strict when output is piped (#131)
Automatically detect when output is piped and use strict YAML format instead of rich formatted output. This makes piping to tools like yq, jq, or phabfive edit seamless without needing --format=strict flag. Changes: - Add _get_auto_format() method to Phabfive class that uses sys.stdout.isatty() to detect if output is a terminal or piped - Update CLI to auto-detect format when --format not explicitly specified - Update help text to document auto-detection behavior - Add tests for auto-format detection (terminal vs piped) Behavior: - Terminal output: Uses 'rich' format (colored, formatted, hyperlinks) - Piped output: Uses 'strict' format (pure YAML) - Explicit --format=X: Overrides auto-detection This aligns with existing --ascii=auto and --hyperlink=auto patterns and follows industry standards from git, ripgrep, ls, etc. Fixes #131
1 parent d57deda commit 8e59f1d

3 files changed

Lines changed: 50 additions & 2 deletions

File tree

phabfive/cli.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@
3434
3535
Options:
3636
--log-level=LEVEL Set loglevel [default: INFO]
37-
--format=FORMAT Output format: rich (default), tree, or strict [default: rich]
37+
--format=FORMAT Output format: rich, tree, or strict. Auto-detects based on TTY:
38+
terminal=rich (colored/formatted), piped=strict (pure YAML).
39+
Explicitly specify to override auto-detection.
3840
--ascii=WHEN Use ASCII instead of Unicode (always/auto/never) [default: auto]
3941
--hyperlink=WHEN Enable terminal hyperlinks (always/auto/never) [default: auto]
4042
-h, --help Show this help message and exit
@@ -398,7 +400,14 @@ def run(cli_args, sub_args):
398400
# Validate and process output options
399401
valid_modes = ("always", "auto", "never")
400402
valid_formats = ("rich", "tree", "strict")
401-
output_format = cli_args.get("--format", "rich")
403+
404+
# Auto-detect format based on TTY if not explicitly specified
405+
format_arg = cli_args.get("--format")
406+
if format_arg is None:
407+
output_format = Phabfive._get_auto_format()
408+
else:
409+
output_format = format_arg
410+
402411
ascii_when = cli_args.get("--ascii", "never")
403412
hyperlink_when = cli_args.get("--hyperlink", "never")
404413

phabfive/core.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,22 @@ def _should_use_hyperlink():
128128

129129
return False
130130

131+
@staticmethod
132+
def _get_auto_format():
133+
"""Determine default output format based on whether stdout is a TTY.
134+
135+
Returns:
136+
str: "rich" if stdout is a terminal, "strict" if piped/redirected
137+
"""
138+
import sys
139+
140+
# If output is piped or redirected, use strict format for machine processing
141+
if not sys.stdout.isatty():
142+
return "strict"
143+
144+
# If output is to a terminal, use rich format for human readability
145+
return "rich"
146+
131147
def _is_ascii_enabled(self):
132148
"""Check if ASCII mode is currently enabled."""
133149
if self._ascii_when == "always":

tests/test_phabfive.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# -*- coding: utf-8 -*-
22

3+
# python std lib
4+
from unittest import mock
5+
36
# 3rd party imports
47
import pytest
58

@@ -16,3 +19,23 @@ def test_import_phabfive():
1619
from phabfive.core import Phabfive # noqa
1720
except ImportError:
1821
pytest.fail("Unexpected ImportError")
22+
23+
24+
class TestAutoFormatDetection:
25+
"""Tests for automatic format detection based on TTY status."""
26+
27+
def test_get_auto_format_terminal(self):
28+
"""Test auto-format returns 'rich' when stdout is a TTY."""
29+
from phabfive.core import Phabfive
30+
31+
with mock.patch('sys.stdout.isatty', return_value=True):
32+
result = Phabfive._get_auto_format()
33+
assert result == "rich"
34+
35+
def test_get_auto_format_piped(self):
36+
"""Test auto-format returns 'strict' when stdout is piped/redirected."""
37+
from phabfive.core import Phabfive
38+
39+
with mock.patch('sys.stdout.isatty', return_value=False):
40+
result = Phabfive._get_auto_format()
41+
assert result == "strict"

0 commit comments

Comments
 (0)