Switch to texttable

it seems to be well maintained and packages are available even for old distros.
This commit is contained in:
Alexander Kukushkin
2020-02-19 12:29:25 +01:00
parent ee79a390c2
commit 7c409f59d7
3 changed files with 65 additions and 14 deletions

View File

@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
'''
Patroni Control
'''
@@ -32,7 +33,7 @@ from patroni.utils import cluster_as_json, patch_config, polling_loop
from patroni.request import PatroniRequest
from patroni.version import __version__
from six.moves.urllib_parse import urlparse
from terminaltables import SingleTable
from texttable import Texttable
CONFIG_DIR_PATH = click.get_app_dir('patroni')
CONFIG_FILE_PATH = os.path.join(CONFIG_DIR_PATH, 'patronictl.yaml')
@@ -46,6 +47,44 @@ class PatroniCtlException(ClickException):
pass
class PatronictlTexttable(Texttable):
def __init__(self, header=None):
Texttable.__init__(self, 0)
self.__table_header = header
self.__hline_num = 0
if sys.platform != 'win32':
self._char_horiz = u''
self._char_vert = u''
self._hline_header = self._hline
self._char_header = self._char_horiz
def _is_first_hline(self):
return self.__hline_num == 0
def _is_last_hline(self):
return self.__hline_num > (len(self._rows) if self._has_hlines() else int(bool(self._header)))
def _hline(self):
if sys.platform == 'win32':
left = right = self._char_corner
elif self._is_first_hline():
left, self._char_corner, right = u'', u'', u''
elif not self._is_last_hline():
left, self._char_corner, right = u'', u'', u''
else:
left, self._char_corner, right = u'', u'', u''
line = self._build_hline()
if self._is_first_hline() and self.__table_header:
left += self.__table_header
self.__hline_num += 1
return left + line[len(left):-2] + right + '\n'
def parse_dcs(dcs):
if dcs is None:
return None
@@ -145,20 +184,25 @@ def print_output(columns, rows, alignment=None, fmt='pretty', header=None, delim
for row in rows:
if row[i]:
row[i] = format_config_for_editing(row[i], fmt == 'tsv').strip()
s = int(list_cluster and fmt == 'pretty') # skip cluster name if pretty-printing
table_data = ([columns[s:]] if columns else []) + [row[s:] for row in rows]
if list_cluster and fmt == 'pretty': # skip cluster name if pretty-printing
columns = columns[1:] if columns else []
rows = [row[1:] for row in rows]
if fmt == 'tsv':
for r in table_data:
for r in [columns] + rows:
click.echo(delimiter.join(map(str, r)))
else:
table = SingleTable(table_data, header)
table.inner_row_border = any(any(isinstance(c, six.string_types) and '\n' in c for c in r) for r in rows)
for i, name in enumerate(table_data[0]):
default = 'left'
jmap = {m[0]: m for m in ('center', default, 'right')}
table.justify_columns[i] = jmap.get((alignment or {}).get(name, default)[0], default)
click.echo(table.table)
table = PatronictlTexttable(header)
if not any(any(isinstance(c, six.string_types) and '\n' in c for c in r) for r in rows):
table.set_deco(Texttable.VLINES | Texttable.BORDER | Texttable.HEADER)
if rows:
if columns:
table.header(columns)
table.set_cols_align([(alignment or {}).get(c, 'l') for c in columns])
table.add_rows(rows, header=False)
else:
table.add_rows([columns], header=False)
click.echo(table.draw())
def watching(w, watch, max_count=None, clear=True):

View File

@@ -6,7 +6,7 @@ kazoo>=1.3.1
python-etcd>=0.4.3,<0.5
python-consul>=0.7.1
click>=4.1
terminaltables>=3.1.0
texttable
python-dateutil
psutil>=2.0.0
cdiff

View File

@@ -7,7 +7,7 @@ from datetime import datetime, timedelta
from mock import patch, Mock
from patroni.ctl import ctl, store_config, load_config, output_members, get_dcs, parse_dcs, \
get_all_members, get_any_member, get_cursor, query_member, configure, PatroniCtlException, apply_config_changes, \
format_config_for_editing, show_diff, invoke_editor, format_pg_version, find_executable
format_config_for_editing, show_diff, invoke_editor, format_pg_version, find_executable, print_output
from patroni.dcs.etcd import Client, Failover
from patroni.utils import tzutc
from psycopg2 import OperationalError
@@ -32,7 +32,8 @@ def test_rw_config():
@patch('patroni.ctl.load_config',
Mock(return_value={'scope': 'alpha', 'postgresql': {'data_dir': '.', 'pgpass': './pgpass', 'parameters': {}, 'retry_timeout': 5},
Mock(return_value={'scope': 'alpha', 'postgresql': {'data_dir': '.', 'pgpass': './pgpass',
'parameters': {}, 'retry_timeout': 5},
'restapi': {'listen': '::', 'certfile': 'a'}, 'etcd': {'host': 'localhost:2379'}}))
class TestCtl(unittest.TestCase):
@@ -161,6 +162,12 @@ class TestCtl(unittest.TestCase):
def test_get_dcs(self):
self.assertRaises(PatroniCtlException, get_dcs, {'dummy': {}}, 'dummy')
@patch('sys.platform', 'win32')
@patch('click.echo')
def test_print_output(self, mock_click_echo):
print_output(['a'], [])
mock_click_echo.assert_called_once_with('+---+\n| a |\n+---+')
@patch('psycopg2.connect', psycopg2_connect)
@patch('patroni.ctl.query_member', Mock(return_value=([['mock column']], None)))
@patch('patroni.ctl.get_dcs')