summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorgy Frolov <gosha@fro.lv>2021-02-23 01:55:55 +0300
committerGitHub <noreply@github.com>2021-02-22 14:55:55 -0800
commitc9fd72449e878b326b9335cb46fe6da716dc27c7 (patch)
tree5944a95fc870cb1425403a5c98379e6cb9f7a9f3
parent30212c6fc68ccf19d794530819cda8e6d4edf74c (diff)
skip initial comment in pg_session file (#1245)
* skip initial comment in pg_session file * add test
-rw-r--r--changelog.rst1
-rw-r--r--pgcli/config.py27
-rw-r--r--pgcli/main.py13
-rw-r--r--tests/test_config.py15
-rw-r--r--tests/test_main.py7
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