diff options
author | Georgy Frolov <gosha@fro.lv> | 2021-02-23 01:55:55 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-22 14:55:55 -0800 |
commit | c9fd72449e878b326b9335cb46fe6da716dc27c7 (patch) | |
tree | 5944a95fc870cb1425403a5c98379e6cb9f7a9f3 | |
parent | 30212c6fc68ccf19d794530819cda8e6d4edf74c (diff) |
skip initial comment in pg_session file (#1245)
* skip initial comment in pg_session file
* add test
-rw-r--r-- | changelog.rst | 1 | ||||
-rw-r--r-- | pgcli/config.py | 27 | ||||
-rw-r--r-- | pgcli/main.py | 13 | ||||
-rw-r--r-- | tests/test_config.py | 15 | ||||
-rw-r--r-- | tests/test_main.py | 7 |
5 files changed, 58 insertions, 5 deletions
diff --git a/changelog.rst b/changelog.rst index 18640252..ee94ae3f 100644 --- a/changelog.rst +++ b/changelog.rst @@ -6,6 +6,7 @@ Features: * Consider `update` queries destructive and issue a warning. Change `destructive_warning` setting to `all|moderate|off`, vs `true|false`. (#1239) +* Skip initial comment in .pg_session even if it doesn't start with '#' Bug fixes: ---------- diff --git a/pgcli/config.py b/pgcli/config.py index 0fc42dde..56eede53 100644 --- a/pgcli/config.py +++ b/pgcli/config.py @@ -3,6 +3,8 @@ import shutil import os import platform from os.path import expanduser, exists, dirname +import re +from typing import TextIO from configobj import ConfigObj @@ -62,3 +64,28 @@ def get_casing_file(config): if casing_file == "default": casing_file = config_location() + "casing" return casing_file + + +def skip_initial_comment(f_stream: TextIO) -> int: + """ + Initial comment in ~/.pg_service.conf is not always marked with '#' + which crashes the parser. This function takes a file object and + "rewinds" it to the beginning of the first section, + from where on it can be parsed safely + + :return: number of skipped lines + """ + section_regex = r"\s*\[" + pos = f_stream.tell() + lines_skipped = 0 + while True: + line = f_stream.readline() + if line == "": + break + if re.match(section_regex, line) is not None: + f_stream.seek(pos) + break + else: + pos += len(line) + lines_skipped += 1 + return lines_skipped diff --git a/pgcli/main.py b/pgcli/main.py index 40e2483a..4cf528d9 100644 --- a/pgcli/main.py +++ b/pgcli/main.py @@ -2,8 +2,9 @@ import platform import warnings from os.path import expanduser -from configobj import ConfigObj +from configobj import ConfigObj, ParseError from pgspecial.namedqueries import NamedQueries +from .config import skip_initial_comment warnings.filterwarnings("ignore", category=UserWarning, module="psycopg2") @@ -1508,10 +1509,16 @@ def parse_service_info(service): service_file = os.path.join(os.getenv("PGSYSCONFDIR"), ".pg_service.conf") else: service_file = expanduser("~/.pg_service.conf") - if not service: + if not service or not os.path.exists(service_file): # nothing to do return None, service_file - service_file_config = ConfigObj(service_file) + with open(service_file) as f: + skipped_lines = skip_initial_comment(f) + try: + service_file_config = ConfigObj(f) + except ParseError as err: + err.line_number += skipped_lines + raise err if service not in service_file_config: return None, service_file service_conf = service_file_config.get(service) diff --git a/tests/test_config.py b/tests/test_config.py index 48408141..08fe74e6 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1,9 +1,10 @@ +import io import os import stat import pytest -from pgcli.config import ensure_dir_exists +from pgcli.config import ensure_dir_exists, skip_initial_comment def test_ensure_file_parent(tmpdir): @@ -28,3 +29,15 @@ def test_ensure_other_create_error(tmpdir): with pytest.raises(OSError): ensure_dir_exists(str(rcfile)) + + +@pytest.mark.parametrize( + "text, skipped_lines", + ( + ("abc\n", 1), + ("#[section]\ndef\n[section]", 2), + ("[section]", 0), + ), +) +def test_skip_initial_comment(text, skipped_lines): + assert skip_initial_comment(io.StringIO(text)) == skipped_lines diff --git a/tests/test_main.py b/tests/test_main.py index 965ff8fa..c48accbe 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -288,7 +288,12 @@ def test_pg_service_file(tmpdir): cli = PGCli(pgclirc_file=str(tmpdir.join("rcfile"))) with open(tmpdir.join(".pg_service.conf").strpath, "w") as service_conf: service_conf.write( - """[myservice] + """File begins with a comment + that is not a comment + # or maybe a comment after all + because psql is crazy + + [myservice] host=a_host user=a_user port=5433 |