plsqlwks 0.1.0__tar.gz → 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/PKG-INFO +1 -2
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/__init__.py +1 -1
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/config/__init__.py +2 -2
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/config/paths.py +102 -2
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks.egg-info/PKG-INFO +1 -2
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks.egg-info/requires.txt +0 -1
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/pyproject.toml +0 -1
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/tests/test_config_workspace.py +114 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/tests/test_packaging.py +11 -2
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/README.md +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/__main__.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/config/loader.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/config/models.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/config/session.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/config/settings.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/db/__init__.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/db/editing.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/db/execution.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/db/explain.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/db/health.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/db/metadata.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/db/models.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/db/session.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/db/sql_analysis.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/db/transactions.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/sqlbinds.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/sqlsplit.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/ui/__init__.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/ui/app.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/ui/app_db.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/ui/app_editor.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/ui/app_files.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/ui/app_input.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/ui/app_render.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/ui/app_results.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/ui/app_tabs_browser.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/ui/browser.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/ui/buffer.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/ui/clipboard.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/ui/commands.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/ui/completion.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/ui/constants.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/ui/display.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/ui/errors.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/ui/help.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/ui/keys.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/ui/menu.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/ui/results.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/ui/sql.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/ui/state.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/ui/syntax.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks/workspace.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks.egg-info/SOURCES.txt +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks.egg-info/dependency_links.txt +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks.egg-info/entry_points.txt +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/plsqlwks.egg-info/top_level.txt +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/setup.cfg +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/tests/test_db_editing.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/tests/test_db_helpers.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/tests/test_oracle_integration.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/tests/test_pty_keys.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/tests/test_rchar.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/tests/test_sqlbinds.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/tests/test_sqlsplit.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/tests/test_ui_flows.py +0 -0
- {plsqlwks-0.1.0 → plsqlwks-0.1.1}/tests/test_ui_keys.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plsqlwks
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1
|
|
4
4
|
Summary: An ncurses SQL and PL/SQL workspace for Oracle databases.
|
|
5
5
|
Classifier: Programming Language :: Python :: 3
|
|
6
6
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
@@ -8,7 +8,6 @@ Classifier: Topic :: Database
|
|
|
8
8
|
Requires-Python: >=3.10
|
|
9
9
|
Description-Content-Type: text/markdown
|
|
10
10
|
Requires-Dist: oracledb>=2.0
|
|
11
|
-
Requires-Dist: platformdirs>=4.0
|
|
12
11
|
Provides-Extra: dev
|
|
13
12
|
Requires-Dist: build>=1.2; extra == "dev"
|
|
14
13
|
Requires-Dist: mypy>=1.10; extra == "dev"
|
|
@@ -9,8 +9,6 @@ import stat
|
|
|
9
9
|
import tempfile
|
|
10
10
|
from typing import Sequence
|
|
11
11
|
|
|
12
|
-
from platformdirs import user_config_path, user_data_path
|
|
13
|
-
|
|
14
12
|
from .loader import DEFAULT_DSN, load_config
|
|
15
13
|
from .models import AppConfig, SessionTab
|
|
16
14
|
from .paths import (
|
|
@@ -28,6 +26,8 @@ from .paths import (
|
|
|
28
26
|
resolve_password_file,
|
|
29
27
|
resolve_workspace,
|
|
30
28
|
source_workspace_dir,
|
|
29
|
+
user_config_path,
|
|
30
|
+
user_data_path,
|
|
31
31
|
)
|
|
32
32
|
from .session import (
|
|
33
33
|
SESSION_TAB_PATH_PATTERN,
|
|
@@ -3,8 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import os
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
import stat
|
|
6
|
-
|
|
7
|
-
from platformdirs import user_config_path, user_data_path
|
|
6
|
+
import sys
|
|
8
7
|
|
|
9
8
|
|
|
10
9
|
APP_NAME = "plsqlwks"
|
|
@@ -47,6 +46,107 @@ def is_legacy_source_workspace(path: Path) -> bool:
|
|
|
47
46
|
return (path.parent / SOURCE_CHECKOUT_MARKER).is_file() and is_legacy_workspace(path)
|
|
48
47
|
|
|
49
48
|
|
|
49
|
+
def user_config_path(
|
|
50
|
+
appname: str | None = None,
|
|
51
|
+
appauthor: str | bool | None = None,
|
|
52
|
+
version: str | None = None,
|
|
53
|
+
roaming: bool = False,
|
|
54
|
+
ensure_exists: bool = False,
|
|
55
|
+
) -> Path:
|
|
56
|
+
return _user_path(
|
|
57
|
+
appname,
|
|
58
|
+
appauthor=appauthor,
|
|
59
|
+
version=version,
|
|
60
|
+
roaming=roaming,
|
|
61
|
+
ensure_exists=ensure_exists,
|
|
62
|
+
kind="config",
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def user_data_path(
|
|
67
|
+
appname: str | None = None,
|
|
68
|
+
appauthor: str | bool | None = None,
|
|
69
|
+
version: str | None = None,
|
|
70
|
+
roaming: bool = False,
|
|
71
|
+
ensure_exists: bool = False,
|
|
72
|
+
) -> Path:
|
|
73
|
+
return _user_path(
|
|
74
|
+
appname,
|
|
75
|
+
appauthor=appauthor,
|
|
76
|
+
version=version,
|
|
77
|
+
roaming=roaming,
|
|
78
|
+
ensure_exists=ensure_exists,
|
|
79
|
+
kind="data",
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _user_path(
|
|
84
|
+
appname: str | None,
|
|
85
|
+
*,
|
|
86
|
+
appauthor: str | bool | None,
|
|
87
|
+
version: str | None,
|
|
88
|
+
roaming: bool,
|
|
89
|
+
ensure_exists: bool,
|
|
90
|
+
kind: str,
|
|
91
|
+
) -> Path:
|
|
92
|
+
path = _user_path_root(kind, roaming=roaming)
|
|
93
|
+
if appname:
|
|
94
|
+
if sys.platform == "win32" and appauthor is not False:
|
|
95
|
+
author = appauthor if isinstance(appauthor, str) and appauthor else appname
|
|
96
|
+
path /= author
|
|
97
|
+
path /= appname
|
|
98
|
+
if version:
|
|
99
|
+
path /= version
|
|
100
|
+
if ensure_exists:
|
|
101
|
+
path.mkdir(parents=True, exist_ok=True)
|
|
102
|
+
return path
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def _user_path_root(kind: str, *, roaming: bool) -> Path:
|
|
106
|
+
if sys.platform == "win32":
|
|
107
|
+
known_folder = _windows_known_folder(roaming=roaming)
|
|
108
|
+
if known_folder is not None:
|
|
109
|
+
return known_folder
|
|
110
|
+
environment_name = "APPDATA" if roaming else "LOCALAPPDATA"
|
|
111
|
+
configured = _environment_path(environment_name)
|
|
112
|
+
if configured is not None:
|
|
113
|
+
return configured
|
|
114
|
+
folder = "Roaming" if roaming else "Local"
|
|
115
|
+
return _home_path() / "AppData" / folder
|
|
116
|
+
if sys.platform == "darwin":
|
|
117
|
+
return _home_path() / "Library" / "Application Support"
|
|
118
|
+
environment_name = "XDG_CONFIG_HOME" if kind == "config" else "XDG_DATA_HOME"
|
|
119
|
+
configured = _environment_path(environment_name)
|
|
120
|
+
if configured is not None:
|
|
121
|
+
return configured
|
|
122
|
+
suffix = (".config",) if kind == "config" else (".local", "share")
|
|
123
|
+
return _home_path().joinpath(*suffix)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def _environment_path(name: str) -> Path | None:
|
|
127
|
+
value = nonblank_environment_value(name)
|
|
128
|
+
return Path(value) if value is not None else None
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def _windows_known_folder(*, roaming: bool) -> Path | None:
|
|
132
|
+
if os.name != "nt":
|
|
133
|
+
return None
|
|
134
|
+
try:
|
|
135
|
+
import ctypes
|
|
136
|
+
|
|
137
|
+
buffer = ctypes.create_unicode_buffer(260)
|
|
138
|
+
shell32 = getattr(getattr(ctypes, "windll"), "shell32")
|
|
139
|
+
csidl = 26 if roaming else 28
|
|
140
|
+
result = shell32.SHGetFolderPathW(None, csidl, None, 0, buffer)
|
|
141
|
+
except (AttributeError, OSError):
|
|
142
|
+
return None
|
|
143
|
+
return Path(buffer.value) if result == 0 and buffer.value else None
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def _home_path() -> Path:
|
|
147
|
+
return Path.home()
|
|
148
|
+
|
|
149
|
+
|
|
50
150
|
def platform_workspace_dir() -> Path:
|
|
51
151
|
return user_data_path(APP_NAME, appauthor=False)
|
|
52
152
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plsqlwks
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1
|
|
4
4
|
Summary: An ncurses SQL and PL/SQL workspace for Oracle databases.
|
|
5
5
|
Classifier: Programming Language :: Python :: 3
|
|
6
6
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
@@ -8,7 +8,6 @@ Classifier: Topic :: Database
|
|
|
8
8
|
Requires-Python: >=3.10
|
|
9
9
|
Description-Content-Type: text/markdown
|
|
10
10
|
Requires-Dist: oracledb>=2.0
|
|
11
|
-
Requires-Dist: platformdirs>=4.0
|
|
12
11
|
Provides-Extra: dev
|
|
13
12
|
Requires-Dist: build>=1.2; extra == "dev"
|
|
14
13
|
Requires-Dist: mypy>=1.10; extra == "dev"
|
|
@@ -51,6 +51,120 @@ def test_config_facade_reexports_owning_module_symbols():
|
|
|
51
51
|
assert config_module.save_session_tabs is session.save_session_tabs
|
|
52
52
|
|
|
53
53
|
|
|
54
|
+
def test_user_paths_use_xdg_locations_on_linux(monkeypatch, tmp_path):
|
|
55
|
+
config_home = tmp_path / "xdg-config"
|
|
56
|
+
data_home = tmp_path / "xdg-data"
|
|
57
|
+
monkeypatch.setattr(config_paths.sys, "platform", "linux")
|
|
58
|
+
monkeypatch.setenv("XDG_CONFIG_HOME", str(config_home))
|
|
59
|
+
monkeypatch.setenv("XDG_DATA_HOME", str(data_home))
|
|
60
|
+
|
|
61
|
+
assert config_paths.user_config_path("worksheet", appauthor=False) == config_home / "worksheet"
|
|
62
|
+
assert config_paths.user_data_path("worksheet", appauthor=False) == data_home / "worksheet"
|
|
63
|
+
assert config_paths.platform_config_dir() == config_home / "plsqlwks"
|
|
64
|
+
assert config_paths.platform_workspace_dir() == data_home / "plsqlwks"
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@pytest.mark.parametrize("blank_value", ["", " ", "\t "])
|
|
68
|
+
def test_blank_xdg_locations_fall_back_to_linux_home(monkeypatch, tmp_path, blank_value):
|
|
69
|
+
home = tmp_path / "home"
|
|
70
|
+
monkeypatch.setattr(config_paths.sys, "platform", "linux")
|
|
71
|
+
monkeypatch.setattr(config_paths, "_home_path", lambda: home)
|
|
72
|
+
monkeypatch.setenv("XDG_CONFIG_HOME", blank_value)
|
|
73
|
+
monkeypatch.setenv("XDG_DATA_HOME", blank_value)
|
|
74
|
+
|
|
75
|
+
assert config_paths.user_config_path("worksheet") == home / ".config" / "worksheet"
|
|
76
|
+
assert config_paths.user_data_path("worksheet") == home / ".local" / "share" / "worksheet"
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def test_user_paths_use_application_support_on_macos(monkeypatch, tmp_path):
|
|
80
|
+
home = tmp_path / "home"
|
|
81
|
+
monkeypatch.setattr(config_paths.sys, "platform", "darwin")
|
|
82
|
+
monkeypatch.setattr(config_paths, "_home_path", lambda: home)
|
|
83
|
+
monkeypatch.setenv("XDG_CONFIG_HOME", str(tmp_path / "ignored-config"))
|
|
84
|
+
monkeypatch.setenv("XDG_DATA_HOME", str(tmp_path / "ignored-data"))
|
|
85
|
+
|
|
86
|
+
expected = home / "Library" / "Application Support" / "worksheet"
|
|
87
|
+
assert config_paths.user_config_path("worksheet") == expected
|
|
88
|
+
assert config_paths.user_data_path("worksheet") == expected
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def test_user_paths_use_windows_local_roaming_author_and_version(monkeypatch, tmp_path):
|
|
92
|
+
local = tmp_path / "Local"
|
|
93
|
+
roaming = tmp_path / "Roaming"
|
|
94
|
+
monkeypatch.setattr(config_paths.sys, "platform", "win32")
|
|
95
|
+
monkeypatch.setenv("LOCALAPPDATA", str(local))
|
|
96
|
+
monkeypatch.setenv("APPDATA", str(roaming))
|
|
97
|
+
|
|
98
|
+
data_path = config_paths.user_data_path(
|
|
99
|
+
"worksheet",
|
|
100
|
+
appauthor="Acme",
|
|
101
|
+
version="2",
|
|
102
|
+
ensure_exists=True,
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
assert data_path == local / "Acme" / "worksheet" / "2"
|
|
106
|
+
assert data_path.is_dir()
|
|
107
|
+
assert config_paths.user_data_path("worksheet") == local / "worksheet" / "worksheet"
|
|
108
|
+
assert config_paths.user_config_path("worksheet", appauthor=False) == local / "worksheet"
|
|
109
|
+
assert config_paths.user_config_path("worksheet", appauthor=False, roaming=True) == roaming / "worksheet"
|
|
110
|
+
assert config_paths.platform_config_dir() == local / "plsqlwks"
|
|
111
|
+
assert config_paths.platform_workspace_dir() == local / "plsqlwks"
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def test_blank_windows_locations_fall_back_to_platform_home(monkeypatch, tmp_path):
|
|
115
|
+
home = tmp_path / "home"
|
|
116
|
+
roaming = tmp_path / "Roaming"
|
|
117
|
+
monkeypatch.setattr(config_paths.sys, "platform", "win32")
|
|
118
|
+
monkeypatch.setattr(config_paths, "_home_path", lambda: home)
|
|
119
|
+
monkeypatch.setenv("LOCALAPPDATA", " ")
|
|
120
|
+
monkeypatch.setenv("APPDATA", str(roaming))
|
|
121
|
+
|
|
122
|
+
assert config_paths.user_data_path("worksheet", appauthor=False) == home / "AppData" / "Local" / "worksheet"
|
|
123
|
+
assert config_paths.user_data_path("worksheet", appauthor=False, roaming=True) == roaming / "worksheet"
|
|
124
|
+
|
|
125
|
+
monkeypatch.setenv("APPDATA", "\t")
|
|
126
|
+
|
|
127
|
+
assert config_paths.user_data_path("worksheet", appauthor=False) == home / "AppData" / "Local" / "worksheet"
|
|
128
|
+
assert config_paths.user_config_path("worksheet", appauthor=False, roaming=True) == (
|
|
129
|
+
home / "AppData" / "Roaming" / "worksheet"
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def test_windows_locations_use_known_folder_fallback(monkeypatch, tmp_path):
|
|
134
|
+
local = tmp_path / "KnownLocal"
|
|
135
|
+
roaming = tmp_path / "KnownRoaming"
|
|
136
|
+
monkeypatch.setattr(config_paths.sys, "platform", "win32")
|
|
137
|
+
monkeypatch.setattr(
|
|
138
|
+
config_paths,
|
|
139
|
+
"_windows_known_folder",
|
|
140
|
+
lambda *, roaming: (tmp_path / "KnownRoaming") if roaming else (tmp_path / "KnownLocal"),
|
|
141
|
+
)
|
|
142
|
+
monkeypatch.setenv("LOCALAPPDATA", "")
|
|
143
|
+
monkeypatch.setenv("APPDATA", "")
|
|
144
|
+
|
|
145
|
+
assert config_paths.user_data_path("worksheet", appauthor=False) == local / "worksheet"
|
|
146
|
+
assert config_paths.user_data_path("worksheet", appauthor=False, roaming=True) == roaming / "worksheet"
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def test_user_path_environment_values_remain_literal_and_overrides_expand_home(monkeypatch, tmp_path):
|
|
150
|
+
home = tmp_path / "home"
|
|
151
|
+
monkeypatch.setattr(config_paths.sys, "platform", "linux")
|
|
152
|
+
monkeypatch.setenv("HOME", str(home))
|
|
153
|
+
monkeypatch.setenv("XDG_CONFIG_HOME", "~/xdg-config")
|
|
154
|
+
monkeypatch.setenv("XDG_DATA_HOME", "~/xdg-data")
|
|
155
|
+
monkeypatch.setenv("ORACLE_PASSWORD_FILE", "~/secrets/orapass")
|
|
156
|
+
|
|
157
|
+
workspace, config_file, warnings = config_paths.resolve_workspace("~/oracle-work")
|
|
158
|
+
password_file, _ = config_paths.resolve_password_file(home / "unused-config")
|
|
159
|
+
|
|
160
|
+
assert config_paths.user_config_path("worksheet") == Path("~/xdg-config/worksheet")
|
|
161
|
+
assert config_paths.user_data_path("worksheet") == Path("~/xdg-data/worksheet")
|
|
162
|
+
assert workspace == home / "oracle-work"
|
|
163
|
+
assert config_file == home / "oracle-work" / "config.ini"
|
|
164
|
+
assert warnings == ()
|
|
165
|
+
assert password_file == home / "secrets" / "orapass"
|
|
166
|
+
|
|
167
|
+
|
|
54
168
|
def test_load_config_uses_environment_overrides(monkeypatch, tmp_path):
|
|
55
169
|
password_file = tmp_path / "secret.txt"
|
|
56
170
|
workspace = tmp_path / "workspace"
|
|
@@ -17,11 +17,16 @@ ROOT = Path(__file__).resolve().parents[1]
|
|
|
17
17
|
|
|
18
18
|
def test_pyproject_declares_runtime_package_and_console_script():
|
|
19
19
|
data = tomllib.loads((ROOT / "pyproject.toml").read_text(encoding="utf-8"))
|
|
20
|
+
requirements = {
|
|
21
|
+
line.strip().lower()
|
|
22
|
+
for line in (ROOT / "requirements.txt").read_text(encoding="utf-8").splitlines()
|
|
23
|
+
if line.strip() and not line.lstrip().startswith("#")
|
|
24
|
+
}
|
|
20
25
|
|
|
21
26
|
assert data["project"]["name"] == "plsqlwks"
|
|
22
27
|
assert data["project"]["scripts"]["plsqlwks"] == "plsqlwks.ui:main"
|
|
23
|
-
assert
|
|
24
|
-
assert "
|
|
28
|
+
assert data["project"]["dependencies"] == ["oracledb>=2.0"]
|
|
29
|
+
assert requirements == {"oracledb>=2.0"}
|
|
25
30
|
assert {"build>=1.2", "mypy>=1.10", "pytest>=8.0", "ruff>=0.8", "wheel>=0.43"} <= set(
|
|
26
31
|
data["project"]["optional-dependencies"]["dev"]
|
|
27
32
|
)
|
|
@@ -53,6 +58,8 @@ def test_built_wheel_contains_runtime_package_only(tmp_path):
|
|
|
53
58
|
|
|
54
59
|
with zipfile.ZipFile(wheel) as archive:
|
|
55
60
|
names = archive.namelist()
|
|
61
|
+
metadata_name = next(name for name in names if name.endswith(".dist-info/METADATA"))
|
|
62
|
+
metadata = archive.read(metadata_name).decode("utf-8")
|
|
56
63
|
|
|
57
64
|
expected_ui_modules = {
|
|
58
65
|
"__init__.py",
|
|
@@ -104,6 +111,8 @@ def test_built_wheel_contains_runtime_package_only(tmp_path):
|
|
|
104
111
|
assert any(name == "plsqlwks/db/__init__.py" for name in names)
|
|
105
112
|
assert "plsqlwks/db.py" not in names
|
|
106
113
|
assert any(name.endswith(".dist-info/METADATA") for name in names)
|
|
114
|
+
assert "Requires-Dist: oracledb>=2.0" in metadata
|
|
115
|
+
assert "requires-dist: platformdirs" not in metadata.lower()
|
|
107
116
|
assert not any(name.startswith("tests/") for name in names)
|
|
108
117
|
assert not any(name.startswith("tools/") for name in names)
|
|
109
118
|
assert not any(name.startswith("workspace/") for name in names)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|