Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ Contributors:
* Shayan Golshani (shgol)
* Tommi Kyntölä (kynde)
* Diego
* Chris (ChrisJr404)

Creator:
--------
Expand Down
7 changes: 7 additions & 0 deletions changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@ Upcoming (TBD)

Bug fixes:
----------
* Fix ``--list-dsn`` and ``-D``/``--dsn`` not finding ``[alias_dsn]`` entries.
Both read the config with a bare ``load_config`` that skips the packaged
default, so on a fresh install (no config written yet) ``--list-dsn`` printed
a misleading "Invalid DSNs found" error and ``-D`` could crash on the missing
``[main]`` section. They now load config the same way as the rest of pgcli
(``get_config``), which writes the default template if needed and always has
the expected sections ([issue 1489](https://github.com/dbcli/pgcli/issues/1489)).
* Restore cursor shape behaviour for Emacs mode
* Fix ``TypeError: cannot use a string pattern on a bytes-like object`` when
completion metadata comes back as bytes (e.g. ``SQL_ASCII`` client encoding).
Expand Down
4 changes: 2 additions & 2 deletions pgcli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -1575,7 +1575,7 @@ def cli(
)
if list_dsn:
try:
cfg = load_config(pgclirc, config_full_path)
cfg = get_config(pgclirc)
for alias in cfg["alias_dsn"]:
click.secho(alias + " : " + cfg["alias_dsn"][alias])
sys.exit(0)
Expand Down Expand Up @@ -1627,7 +1627,7 @@ def cli(
if list_databases or ping_database:
database = "postgres"

cfg = load_config(pgclirc, config_full_path)
cfg = get_config(pgclirc)
if dsn != "":
try:
dsn_config = cfg["alias_dsn"][dsn]
Expand Down
90 changes: 90 additions & 0 deletions tests/test_alias_dsn.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import pytest
from click.testing import CliRunner

from pgcli.main import cli, PGCli


def write_config(tmp_path, body):
cfg = tmp_path / "config"
cfg.write_text(body)
return cfg


@pytest.fixture
def isolate_config(monkeypatch, tmp_path):
# Keep the real config dir out of the picture. get_config() writes its
# default template under here when a config file does not exist yet.
monkeypatch.setenv("XDG_CONFIG_HOME", str(tmp_path))
return tmp_path


def test_list_dsn_fresh_config(isolate_config):
# No config file exists yet. --list-dsn used to read the not-yet-written
# config before PGCli() created it, hit a KeyError on the missing
# [alias_dsn] section, and print "Invalid DSNs found" with exit code 1.
# It should just report no aliases and exit cleanly.
cfg = isolate_config / "config"
runner = CliRunner()
result = runner.invoke(cli, ["--pgclirc", str(cfg), "--list-dsn"])
assert result.exit_code == 0
assert "Invalid DSNs" not in result.output
assert result.output.strip() == ""


def test_list_dsn_lists_aliases(isolate_config):
cfg = write_config(
isolate_config,
"[alias_dsn]\n"
"foo = postgres://u:p@localhost:5432/foo\n"
"bar = postgres://u:p@localhost:5432/bar\n",
)
runner = CliRunner()
result = runner.invoke(cli, ["--pgclirc", str(cfg), "--list-dsn"])
assert result.exit_code == 0
assert "foo : postgres://u:p@localhost:5432/foo" in result.output
assert "bar : postgres://u:p@localhost:5432/bar" in result.output


def test_dsn_alias_resolves(isolate_config, monkeypatch):
cfg = write_config(
isolate_config,
"[alias_dsn]\nfoo = postgres://u:p@localhost:5432/foo\n",
)
captured = {}

def fake_connect(self, *args, **kwargs):
# connect_uri() parses the alias URI and calls connect() with the
# resolved parts, so recording them proves the alias was found.
captured.update(kwargs)

class DummyExec:
def run(self, cmd):
return []

def get_timezone(self):
return "UTC"

def set_timezone(self, *a, **k):
pass

self.pgexecute = DummyExec()

monkeypatch.setattr(PGCli, "connect", fake_connect)

runner = CliRunner()
result = runner.invoke(cli, ["--pgclirc", str(cfg), "-D", "foo", "--ping"])
assert result.exit_code == 0
assert "Could not find a DSN" not in result.output
assert captured.get("database") == "foo"
assert captured.get("host") == "localhost"


def test_dsn_alias_missing(isolate_config):
cfg = write_config(
isolate_config,
"[alias_dsn]\nfoo = postgres://u:p@localhost:5432/foo\n",
)
runner = CliRunner()
result = runner.invoke(cli, ["--pgclirc", str(cfg), "-D", "does-not-exist"])
assert result.exit_code == 1
assert "Could not find a DSN with alias does-not-exist" in result.output
Loading