teridex 0.1.0__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.
- teridex-0.1.0/.editorconfig +15 -0
- teridex-0.1.0/.github/ISSUE_TEMPLATE//342/234/250-feature-request.md +23 -0
- teridex-0.1.0/.github/ISSUE_TEMPLATE//360/237/220/233-bug-report.md +30 -0
- teridex-0.1.0/.github/ISSUE_TEMPLATE//360/237/233/240-task---improvement.md +20 -0
- teridex-0.1.0/.github/PULL_REQUEST_TEMPLATE/PULL_REQUEST_TEMPLATE.md +30 -0
- teridex-0.1.0/.github/workflows/ci.yml +56 -0
- teridex-0.1.0/.github/workflows/release.yml +87 -0
- teridex-0.1.0/.gitignore +110 -0
- teridex-0.1.0/.python-version +1 -0
- teridex-0.1.0/CHANGELOG.md +12 -0
- teridex-0.1.0/CONTRIBUTING.md +152 -0
- teridex-0.1.0/CONTRIBUTORS.md +11 -0
- teridex-0.1.0/LICENSE +21 -0
- teridex-0.1.0/PKG-INFO +262 -0
- teridex-0.1.0/README.md +227 -0
- teridex-0.1.0/SECURITY.md +17 -0
- teridex-0.1.0/config.example.toml +51 -0
- teridex-0.1.0/docker/Dockerfile +44 -0
- teridex-0.1.0/docker/docker-compose.yml +35 -0
- teridex-0.1.0/docker/seeds/mysql/01-demo.sql +10 -0
- teridex-0.1.0/docker/seeds/postgres/01-demo.sql +18 -0
- teridex-0.1.0/mypy.ini +40 -0
- teridex-0.1.0/pyproject.toml +101 -0
- teridex-0.1.0/ruff.toml +33 -0
- teridex-0.1.0/scripts/check.sh +10 -0
- teridex-0.1.0/scripts/dev.sh +9 -0
- teridex-0.1.0/scripts/fmt.sh +7 -0
- teridex-0.1.0/scripts/lint.sh +13 -0
- teridex-0.1.0/scripts/test.sh +7 -0
- teridex-0.1.0/src/teridex_adapters/__init__.py +17 -0
- teridex-0.1.0/src/teridex_adapters/_introspect.py +97 -0
- teridex-0.1.0/src/teridex_adapters/_typeinfer.py +72 -0
- teridex-0.1.0/src/teridex_adapters/base.py +160 -0
- teridex-0.1.0/src/teridex_adapters/duckdb_adapter.py +298 -0
- teridex-0.1.0/src/teridex_adapters/mysql_adapter.py +382 -0
- teridex-0.1.0/src/teridex_adapters/postgres_adapter.py +420 -0
- teridex-0.1.0/src/teridex_adapters/py.typed +0 -0
- teridex-0.1.0/src/teridex_adapters/registry.py +102 -0
- teridex-0.1.0/src/teridex_adapters/sqlite_adapter.py +287 -0
- teridex-0.1.0/src/teridex_cli/__init__.py +5 -0
- teridex-0.1.0/src/teridex_cli/__main__.py +4 -0
- teridex-0.1.0/src/teridex_cli/main.py +222 -0
- teridex-0.1.0/src/teridex_cli/py.typed +0 -0
- teridex-0.1.0/src/teridex_core/__init__.py +25 -0
- teridex-0.1.0/src/teridex_core/config.py +133 -0
- teridex-0.1.0/src/teridex_core/di.py +102 -0
- teridex-0.1.0/src/teridex_core/errors.py +73 -0
- teridex-0.1.0/src/teridex_core/events.py +275 -0
- teridex-0.1.0/src/teridex_core/logging.py +122 -0
- teridex-0.1.0/src/teridex_core/models/__init__.py +33 -0
- teridex-0.1.0/src/teridex_core/models/connection.py +111 -0
- teridex-0.1.0/src/teridex_core/models/query.py +66 -0
- teridex-0.1.0/src/teridex_core/models/result.py +53 -0
- teridex-0.1.0/src/teridex_core/models/schema.py +83 -0
- teridex-0.1.0/src/teridex_core/protocols/__init__.py +11 -0
- teridex-0.1.0/src/teridex_core/protocols/adapter.py +58 -0
- teridex-0.1.0/src/teridex_core/protocols/plugin.py +28 -0
- teridex-0.1.0/src/teridex_core/py.typed +0 -0
- teridex-0.1.0/src/teridex_core/result.py +69 -0
- teridex-0.1.0/src/teridex_engine/__init__.py +14 -0
- teridex-0.1.0/src/teridex_engine/executor.py +161 -0
- teridex-0.1.0/src/teridex_engine/history.py +151 -0
- teridex-0.1.0/src/teridex_engine/introspector.py +86 -0
- teridex-0.1.0/src/teridex_engine/pool.py +168 -0
- teridex-0.1.0/src/teridex_engine/py.typed +0 -0
- teridex-0.1.0/src/teridex_engine/transaction.py +23 -0
- teridex-0.1.0/src/teridex_plugins/__init__.py +16 -0
- teridex-0.1.0/src/teridex_plugins/api.py +100 -0
- teridex-0.1.0/src/teridex_plugins/context.py +72 -0
- teridex-0.1.0/src/teridex_plugins/loader.py +199 -0
- teridex-0.1.0/src/teridex_plugins/py.typed +0 -0
- teridex-0.1.0/src/teridex_plugins/registry.py +80 -0
- teridex-0.1.0/src/teridex_tui/__init__.py +5 -0
- teridex-0.1.0/src/teridex_tui/app.py +543 -0
- teridex-0.1.0/src/teridex_tui/builtin_commands.py +104 -0
- teridex-0.1.0/src/teridex_tui/events.py +11 -0
- teridex-0.1.0/src/teridex_tui/keymaps/__init__.py +6 -0
- teridex-0.1.0/src/teridex_tui/keymaps/default.py +18 -0
- teridex-0.1.0/src/teridex_tui/keymaps/vim.py +12 -0
- teridex-0.1.0/src/teridex_tui/py.typed +0 -0
- teridex-0.1.0/src/teridex_tui/screens/__init__.py +7 -0
- teridex-0.1.0/src/teridex_tui/screens/command_palette.py +97 -0
- teridex-0.1.0/src/teridex_tui/screens/connection.py +90 -0
- teridex-0.1.0/src/teridex_tui/screens/help.py +57 -0
- teridex-0.1.0/src/teridex_tui/screens/history.py +79 -0
- teridex-0.1.0/src/teridex_tui/screens/main.py +44 -0
- teridex-0.1.0/src/teridex_tui/state.py +37 -0
- teridex-0.1.0/src/teridex_tui/teridex.tcss +210 -0
- teridex-0.1.0/src/teridex_tui/themes/__init__.py +8 -0
- teridex-0.1.0/src/teridex_tui/themes/_base.py +30 -0
- teridex-0.1.0/src/teridex_tui/themes/monokai.py +13 -0
- teridex-0.1.0/src/teridex_tui/themes/nord.py +13 -0
- teridex-0.1.0/src/teridex_tui/widgets/__init__.py +10 -0
- teridex-0.1.0/src/teridex_tui/widgets/action_bar.py +45 -0
- teridex-0.1.0/src/teridex_tui/widgets/query_tabs.py +44 -0
- teridex-0.1.0/src/teridex_tui/widgets/results_table.py +113 -0
- teridex-0.1.0/src/teridex_tui/widgets/schema_tree.py +125 -0
- teridex-0.1.0/src/teridex_tui/widgets/sql_editor.py +17 -0
- teridex-0.1.0/src/teridex_tui/widgets/status_bar.py +71 -0
- teridex-0.1.0/tests/__init__.py +0 -0
- teridex-0.1.0/tests/adapters/__init__.py +0 -0
- teridex-0.1.0/tests/adapters/_conformance.py +56 -0
- teridex-0.1.0/tests/adapters/test_cancellation_inflight.py +101 -0
- teridex-0.1.0/tests/adapters/test_duckdb_adapter.py +111 -0
- teridex-0.1.0/tests/adapters/test_introspect.py +114 -0
- teridex-0.1.0/tests/adapters/test_mysql_adapter.py +70 -0
- teridex-0.1.0/tests/adapters/test_mysql_adapter_unit.py +37 -0
- teridex-0.1.0/tests/adapters/test_postgres_adapter.py +74 -0
- teridex-0.1.0/tests/adapters/test_postgres_adapter_unit.py +66 -0
- teridex-0.1.0/tests/adapters/test_registry.py +26 -0
- teridex-0.1.0/tests/adapters/test_sqlite_adapter.py +138 -0
- teridex-0.1.0/tests/adapters/test_typeinfer.py +50 -0
- teridex-0.1.0/tests/cli/__init__.py +0 -0
- teridex-0.1.0/tests/cli/test_main.py +75 -0
- teridex-0.1.0/tests/conftest.py +29 -0
- teridex-0.1.0/tests/core/__init__.py +0 -0
- teridex-0.1.0/tests/core/test_config.py +51 -0
- teridex-0.1.0/tests/core/test_di.py +65 -0
- teridex-0.1.0/tests/core/test_events.py +239 -0
- teridex-0.1.0/tests/core/test_logging.py +78 -0
- teridex-0.1.0/tests/core/test_models.py +52 -0
- teridex-0.1.0/tests/core/test_result.py +48 -0
- teridex-0.1.0/tests/engine/__init__.py +0 -0
- teridex-0.1.0/tests/engine/test_executor.py +123 -0
- teridex-0.1.0/tests/engine/test_history.py +58 -0
- teridex-0.1.0/tests/engine/test_introspector.py +100 -0
- teridex-0.1.0/tests/engine/test_pool.py +135 -0
- teridex-0.1.0/tests/engine/test_transaction.py +60 -0
- teridex-0.1.0/tests/fixtures/__init__.py +0 -0
- teridex-0.1.0/tests/fixtures/sample_plugin.py +39 -0
- teridex-0.1.0/tests/plugins/__init__.py +0 -0
- teridex-0.1.0/tests/plugins/test_api.py +70 -0
- teridex-0.1.0/tests/plugins/test_loader.py +227 -0
- teridex-0.1.0/tests/plugins/test_loader_discovery.py +92 -0
- teridex-0.1.0/tests/plugins/test_panels.py +78 -0
- teridex-0.1.0/tests/plugins/test_registry.py +53 -0
- teridex-0.1.0/tests/tui/__init__.py +0 -0
- teridex-0.1.0/tests/tui/test_app_smoke.py +138 -0
- teridex-0.1.0/tests/tui/test_help_modal.py +27 -0
- teridex-0.1.0/tests/tui/test_history_panel.py +55 -0
- teridex-0.1.0/tests/tui/test_pool_in_app.py +48 -0
- teridex-0.1.0/tests/tui/test_results_pane.py +88 -0
- teridex-0.1.0/tests/tui/test_schema_tree.py +99 -0
- teridex-0.1.0/tests/tui/test_vim_keymap.py +43 -0
- teridex-0.1.0/tests/tui/test_widgets.py +84 -0
- teridex-0.1.0/uv.lock +1239 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
root = true
|
|
2
|
+
|
|
3
|
+
[*]
|
|
4
|
+
charset = utf-8
|
|
5
|
+
end_of_line = lf
|
|
6
|
+
indent_style = space
|
|
7
|
+
indent_size = 4
|
|
8
|
+
insert_final_newline = true
|
|
9
|
+
trim_trailing_whitespace = true
|
|
10
|
+
|
|
11
|
+
[*.{yml,yaml,toml,json}]
|
|
12
|
+
indent_size = 2
|
|
13
|
+
|
|
14
|
+
[*.md]
|
|
15
|
+
trim_trailing_whitespace = false
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: 'โจ Feature Request'
|
|
3
|
+
about: Suggest an idea or a new functionality
|
|
4
|
+
title: '[FEATURE]: '
|
|
5
|
+
labels: enhancement
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
### Is your feature request related to a problem?
|
|
10
|
+
|
|
11
|
+
A clear and concise description of what the problem is (e.g. I'm always frustrated when...).
|
|
12
|
+
|
|
13
|
+
### Describe the solution you'd like
|
|
14
|
+
|
|
15
|
+
A clear and concise description of what you want to happen.
|
|
16
|
+
|
|
17
|
+
### Describe alternatives you've considered
|
|
18
|
+
|
|
19
|
+
A clear and concise description of any alternative solutions or features you've considered.
|
|
20
|
+
|
|
21
|
+
### Additional context
|
|
22
|
+
|
|
23
|
+
Add any other context or screenshots about the feature request here.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "\U0001F41B Bug Report"
|
|
3
|
+
about: Report an error or unexpected behavior
|
|
4
|
+
title: '[BUG]: '
|
|
5
|
+
labels: bug
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
### Bug Description
|
|
10
|
+
|
|
11
|
+
A clear and concise description of what the bug is.
|
|
12
|
+
|
|
13
|
+
### Steps to Reproduce
|
|
14
|
+
|
|
15
|
+
1. Go to '...'
|
|
16
|
+
2. Click on '....'
|
|
17
|
+
3. Scroll down to '....'
|
|
18
|
+
4. See error
|
|
19
|
+
|
|
20
|
+
### Expected Behavior
|
|
21
|
+
|
|
22
|
+
A clear and concise description of what you expected to happen.
|
|
23
|
+
|
|
24
|
+
### Screenshots / Logs
|
|
25
|
+
|
|
26
|
+
If applicable, add screenshots or paste console logs to help explain your problem.
|
|
27
|
+
|
|
28
|
+
### Environment
|
|
29
|
+
|
|
30
|
+
- **Version:**
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "\U0001F6E0 Task / Improvement"
|
|
3
|
+
about: Maintenance, refactoring, or small improvements
|
|
4
|
+
title: '[TASK]: '
|
|
5
|
+
labels: maintenance
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
### Description
|
|
10
|
+
|
|
11
|
+
A clear and concise description of what needs to be done.
|
|
12
|
+
|
|
13
|
+
### Motivation
|
|
14
|
+
|
|
15
|
+
Why is this task necessary or beneficial for the project?
|
|
16
|
+
|
|
17
|
+
### Checklist
|
|
18
|
+
|
|
19
|
+
- [ ] Task 1
|
|
20
|
+
- [ ] Task 2
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
## Description
|
|
2
|
+
|
|
3
|
+
<!-- Provide a brief summary of the changes and the motivation behind them. -->
|
|
4
|
+
|
|
5
|
+
## Related Issue
|
|
6
|
+
|
|
7
|
+
<!-- Link the issue here using the syntax: Fixes #123 or Related to #123 -->
|
|
8
|
+
|
|
9
|
+
## Type of Change
|
|
10
|
+
|
|
11
|
+
- [ ] ๐ Bug fix (non-breaking change which fixes an issue)
|
|
12
|
+
- [ ] โจ New feature (non-breaking change which adds functionality)
|
|
13
|
+
- [ ] ๐ฅ Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
|
14
|
+
- [ ] ๐ Maintenance / Refactoring
|
|
15
|
+
|
|
16
|
+
## How Has This Been Tested?
|
|
17
|
+
|
|
18
|
+
<!-- Describe the tests that you ran to verify your changes. -->
|
|
19
|
+
|
|
20
|
+
- [ ] Manual testing (please describe)
|
|
21
|
+
- [ ] Unit tests added/updated
|
|
22
|
+
- [ ] Integration tests added/updated
|
|
23
|
+
|
|
24
|
+
## Checklist
|
|
25
|
+
|
|
26
|
+
- [ ] My code follows the style guidelines of this project
|
|
27
|
+
- [ ] I have performed a self-review of my code
|
|
28
|
+
- [ ] I have commented my code, particularly in hard-to-understand areas
|
|
29
|
+
- [ ] I have made corresponding changes to the documentation
|
|
30
|
+
- [ ] My changes generate no new warnings
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
concurrency:
|
|
10
|
+
group: ci-${{ github.ref }}
|
|
11
|
+
cancel-in-progress: true
|
|
12
|
+
|
|
13
|
+
permissions:
|
|
14
|
+
contents: read
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
lint:
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v5
|
|
21
|
+
|
|
22
|
+
- name: Install uv
|
|
23
|
+
uses: astral-sh/setup-uv@v8.1.0
|
|
24
|
+
with:
|
|
25
|
+
enable-cache: true
|
|
26
|
+
python-version: "3.13"
|
|
27
|
+
|
|
28
|
+
- name: Sync workspace
|
|
29
|
+
run: uv sync --all-extras --dev --frozen
|
|
30
|
+
|
|
31
|
+
- name: Lint (ruff format + check + mypy)
|
|
32
|
+
run: ./scripts/lint.sh
|
|
33
|
+
|
|
34
|
+
test:
|
|
35
|
+
runs-on: ${{ matrix.os }}
|
|
36
|
+
defaults:
|
|
37
|
+
run:
|
|
38
|
+
shell: bash
|
|
39
|
+
strategy:
|
|
40
|
+
matrix:
|
|
41
|
+
os: [ubuntu-latest, macos-latest]
|
|
42
|
+
fail-fast: false
|
|
43
|
+
steps:
|
|
44
|
+
- uses: actions/checkout@v5
|
|
45
|
+
|
|
46
|
+
- name: Install uv
|
|
47
|
+
uses: astral-sh/setup-uv@v8.1.0
|
|
48
|
+
with:
|
|
49
|
+
enable-cache: true
|
|
50
|
+
python-version: "3.13"
|
|
51
|
+
|
|
52
|
+
- name: Sync workspace
|
|
53
|
+
run: uv sync --all-extras --dev --frozen
|
|
54
|
+
|
|
55
|
+
- name: Test (pytest + coverage gate)
|
|
56
|
+
run: ./scripts/test.sh
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: write
|
|
11
|
+
id-token: write
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
release:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
environment: release
|
|
17
|
+
steps:
|
|
18
|
+
# โโ checkout & toolchain โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
19
|
+
- uses: actions/checkout@v5
|
|
20
|
+
|
|
21
|
+
- name: Install uv
|
|
22
|
+
uses: astral-sh/setup-uv@v8.1.0
|
|
23
|
+
with:
|
|
24
|
+
enable-cache: true
|
|
25
|
+
python-version: "3.13"
|
|
26
|
+
|
|
27
|
+
# โโ test gate โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
28
|
+
- name: Sync workspace
|
|
29
|
+
run: uv sync --all-extras --dev --frozen
|
|
30
|
+
|
|
31
|
+
- name: Lint
|
|
32
|
+
run: ./scripts/lint.sh
|
|
33
|
+
|
|
34
|
+
- name: Test
|
|
35
|
+
run: ./scripts/test.sh
|
|
36
|
+
|
|
37
|
+
# โโ Build Packages โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
38
|
+
- name: Build packages
|
|
39
|
+
run: uv build --out-dir dist
|
|
40
|
+
|
|
41
|
+
- name: Generate Checksums
|
|
42
|
+
run: |
|
|
43
|
+
sha256sum dist/* > SHA256SUMS
|
|
44
|
+
|
|
45
|
+
- name: Extract Changelog Entry
|
|
46
|
+
id: extract_changelog
|
|
47
|
+
env:
|
|
48
|
+
GITHUB_REF_NAME: ${{ github.ref_name }}
|
|
49
|
+
run: |
|
|
50
|
+
uv run python -c '
|
|
51
|
+
import os, re, uuid
|
|
52
|
+
version = os.environ["GITHUB_REF_NAME"].lstrip("v")
|
|
53
|
+
with open("CHANGELOG.md") as f:
|
|
54
|
+
content = f.read()
|
|
55
|
+
pattern = rf"(?m)^##\s+\[?{re.escape(version)}\]?(.*?)(?=^##\s+\[?|\Z)"
|
|
56
|
+
match = re.search(pattern, content, re.DOTALL)
|
|
57
|
+
notes = ""
|
|
58
|
+
if match:
|
|
59
|
+
raw_notes = match.group(1).strip()
|
|
60
|
+
lines = raw_notes.splitlines()
|
|
61
|
+
if lines and (re.search(r"\d{4}-\d{1,2}-\d{1,2}", lines[0]) or not lines[0].strip()):
|
|
62
|
+
notes = "\n".join(lines[1:]).strip()
|
|
63
|
+
else:
|
|
64
|
+
notes = raw_notes
|
|
65
|
+
if not notes:
|
|
66
|
+
notes = "No changelog entry found for this release."
|
|
67
|
+
github_output = os.environ.get("GITHUB_OUTPUT")
|
|
68
|
+
if github_output:
|
|
69
|
+
delimiter = f"EOF_{uuid.uuid4().hex}"
|
|
70
|
+
with open(github_output, "a") as f:
|
|
71
|
+
f.write(f"body<<{delimiter}\n{notes}\n{delimiter}\n")
|
|
72
|
+
'
|
|
73
|
+
|
|
74
|
+
# โโ GitHub Release โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
75
|
+
- name: Create GitHub Release
|
|
76
|
+
uses: softprops/action-gh-release@v3
|
|
77
|
+
with:
|
|
78
|
+
name: Teridex ${{ github.ref_name }}
|
|
79
|
+
body: ${{ steps.extract_changelog.outputs.body }}
|
|
80
|
+
files: |
|
|
81
|
+
dist/*
|
|
82
|
+
SHA256SUMS
|
|
83
|
+
generate_release_notes: false
|
|
84
|
+
|
|
85
|
+
# โโ PyPI Publish โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
86
|
+
- name: Publish package distributions to PyPI
|
|
87
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
teridex-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# โโ OS / System โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
2
|
+
.DS_Store
|
|
3
|
+
.DS_Store?
|
|
4
|
+
._*
|
|
5
|
+
.Spotlight-V100
|
|
6
|
+
.Trashes
|
|
7
|
+
ehthumbs.db
|
|
8
|
+
Thumbs.db
|
|
9
|
+
desktop.ini
|
|
10
|
+
|
|
11
|
+
# โโ IDEs and Editors โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
12
|
+
.vscode/
|
|
13
|
+
.idea/
|
|
14
|
+
*.swp
|
|
15
|
+
*.swo
|
|
16
|
+
*~
|
|
17
|
+
*.bak
|
|
18
|
+
*.sublime-project
|
|
19
|
+
*.sublime-workspace
|
|
20
|
+
|
|
21
|
+
# โโ Python bytecode / runtime โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
22
|
+
__pycache__/
|
|
23
|
+
*.py[cod]
|
|
24
|
+
*$py.class
|
|
25
|
+
*.so
|
|
26
|
+
.Python
|
|
27
|
+
|
|
28
|
+
# โโ Distribution / Packaging โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
29
|
+
build/
|
|
30
|
+
develop-eggs/
|
|
31
|
+
dist/
|
|
32
|
+
downloads/
|
|
33
|
+
eggs/
|
|
34
|
+
.eggs/
|
|
35
|
+
lib/
|
|
36
|
+
lib64/
|
|
37
|
+
parts/
|
|
38
|
+
sdist/
|
|
39
|
+
var/
|
|
40
|
+
wheels/
|
|
41
|
+
share/python-wheels/
|
|
42
|
+
*.egg-info/
|
|
43
|
+
.installed.cfg
|
|
44
|
+
*.egg
|
|
45
|
+
MANIFEST
|
|
46
|
+
|
|
47
|
+
# โโ Virtual Environments and uv โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
48
|
+
.venv/
|
|
49
|
+
venv/
|
|
50
|
+
env/
|
|
51
|
+
.uv-cache/
|
|
52
|
+
pip-wheel-metadata/
|
|
53
|
+
|
|
54
|
+
# โโ Linting / Type-checking / Testing โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
55
|
+
.mypy_cache/
|
|
56
|
+
.ruff_cache/
|
|
57
|
+
.pytest_cache/
|
|
58
|
+
.hypothesis/
|
|
59
|
+
.nox/
|
|
60
|
+
.tox/
|
|
61
|
+
.dmypy.json
|
|
62
|
+
dmypy.json
|
|
63
|
+
.pre-commit-cache/
|
|
64
|
+
|
|
65
|
+
# โโ Coverage โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
66
|
+
.coverage
|
|
67
|
+
.coverage.*
|
|
68
|
+
htmlcov/
|
|
69
|
+
coverage.xml
|
|
70
|
+
*.cover
|
|
71
|
+
|
|
72
|
+
# โโ Jupyter / Notebooks โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
73
|
+
.ipynb_checkpoints/
|
|
74
|
+
|
|
75
|
+
# โโ Environment / Secrets โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
76
|
+
.env
|
|
77
|
+
.env.*
|
|
78
|
+
!.env.example
|
|
79
|
+
!.env.template
|
|
80
|
+
config.toml
|
|
81
|
+
!config.example.toml
|
|
82
|
+
|
|
83
|
+
# โโ Docker (local overrides) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
84
|
+
docker-compose.override.yml
|
|
85
|
+
|
|
86
|
+
# โโ Teridex (project-specific) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
87
|
+
*.db
|
|
88
|
+
*.sqlite
|
|
89
|
+
*.sqlite3
|
|
90
|
+
*.duckdb
|
|
91
|
+
*.log
|
|
92
|
+
teridex.log
|
|
93
|
+
.teridex/
|
|
94
|
+
scratch/
|
|
95
|
+
|
|
96
|
+
# โโ AI Tools โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
97
|
+
.openai/
|
|
98
|
+
.chatgpt/
|
|
99
|
+
gpt-config.json
|
|
100
|
+
openai.config.json
|
|
101
|
+
.anthropic/
|
|
102
|
+
.claude/
|
|
103
|
+
claude.config.json
|
|
104
|
+
claude-settings.json
|
|
105
|
+
.prompts/
|
|
106
|
+
.prompt-cache/
|
|
107
|
+
.ai/
|
|
108
|
+
.antigravitycli/
|
|
109
|
+
.gemini/
|
|
110
|
+
CLAUDE.md
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.13
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0] - 2026-06-10
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- First implementation of Teridex.
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# Contributing to Teridex ๐
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing to **Teridex**! We welcome and appreciate contributions of all kinds, whether you are fixing a bug, adding database drivers, improving the TUI/CLI, or updating documentation.
|
|
4
|
+
|
|
5
|
+
This guide details our local development setup, code standards, test architecture, and submission workflow.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## ๐ Setup & Installation
|
|
10
|
+
|
|
11
|
+
To develop Teridex locally, you will need:
|
|
12
|
+
- **Python >= 3.13**
|
|
13
|
+
- The [**`uv`**](https://docs.astral.sh/uv/) package manager (`brew install uv` or see [uv installation guide](https://docs.astral.sh/uv/))
|
|
14
|
+
|
|
15
|
+
Clone the repository and sync the workspace virtual environment and dependencies:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
git clone https://github.com/salvatorecorvaglia/teridex.git
|
|
19
|
+
cd teridex
|
|
20
|
+
./scripts/dev.sh
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
> [!NOTE]
|
|
24
|
+
> The `./scripts/dev.sh` script runs `uv sync --all-extras --dev` under the hood.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## ๐ ๏ธ Day-to-Day Commands
|
|
29
|
+
|
|
30
|
+
We provide utility scripts inside the `scripts/` directory to run formatting, type checks, and test suites.
|
|
31
|
+
|
|
32
|
+
| Task | Command | Description |
|
|
33
|
+
| :--- | :--- | :--- |
|
|
34
|
+
| **All Gates** | `./scripts/check.sh` | Runs formatting check, lint check, type check, and unit tests in one command. |
|
|
35
|
+
| **Format & Autofix** | `./scripts/fmt.sh` | Formats Python code and autofixes auto-resolvable lint issues. |
|
|
36
|
+
| **Lint & Type Check** | `./scripts/lint.sh` | Performs formatting checks, Ruff lint checks, and strict Mypy checks. |
|
|
37
|
+
| **Unit Tests** | `./scripts/test.sh` | Runs the offline test suite and outputs terminal coverage. |
|
|
38
|
+
| **Start Docker DBs** | `docker compose -f docker/docker-compose.yml up -d` | Spins up PostgreSQL and MySQL instances for integration tests. |
|
|
39
|
+
| **Integration Tests** | `TERIDEX_PG_DSN=... TERIDEX_MYSQL_DSN=... TERIDEX_TEST_MARKERS=integration ./scripts/test.sh` | Executes integration test suite against the Docker DB instances. |
|
|
40
|
+
|
|
41
|
+
> [!TIP]
|
|
42
|
+
> The `./scripts/check.sh` script forwards additional arguments directly to `pytest`.
|
|
43
|
+
> For example: `./scripts/check.sh -k schema_tree -v` will run the full lint and type stacks, and then execute only the tests matching `schema_tree` in verbose mode.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## ๐ Package Architecture & Layering
|
|
48
|
+
|
|
49
|
+
Teridex follows a clean, layered architecture with strict dependency boundaries:
|
|
50
|
+
|
|
51
|
+
```mermaid
|
|
52
|
+
graph TD
|
|
53
|
+
core["teridex-core (Pure Domain)"]
|
|
54
|
+
adapters["teridex-adapters (DB Drivers)"]
|
|
55
|
+
plugins["teridex-plugins (Plugin API)"]
|
|
56
|
+
engine["teridex-engine (Orchestration)"]
|
|
57
|
+
tui["teridex-tui (Textual TUI)"]
|
|
58
|
+
cli["teridex-cli (Typer CLI)"]
|
|
59
|
+
|
|
60
|
+
adapters --> core
|
|
61
|
+
plugins --> core
|
|
62
|
+
engine --> adapters
|
|
63
|
+
engine --> plugins
|
|
64
|
+
tui --> engine
|
|
65
|
+
cli --> engine
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
> [!IMPORTANT]
|
|
69
|
+
> **Layering Rule**: Inner packages must never depend on outer packages. Specifically, `teridex_core` must depend on zero internal packages. Outer packages (like `teridex-tui` and `teridex-cli`) may depend on inner packages, but never vice versa. This boundary is strictly enforced by `mypy --strict`.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## ๐งช Test Architecture & Coverage
|
|
74
|
+
|
|
75
|
+
The test suite mirrors our layered package structure:
|
|
76
|
+
|
|
77
|
+
* **TUI & UI Component Tests** (`tests/tui/`): Covers screen and widget behavior, rendering states, help modals, schema tree displays, and vim keymap behavior (e.g., `test_app_smoke.py`, `test_schema_tree.py`, `test_results_pane.py`).
|
|
78
|
+
* **Adapter Conformance Tests** (`tests/adapters/`): Verifies database driver implementations. All adapters must pass the shared conformance scenarios located in `tests/adapters/_conformance.py`.
|
|
79
|
+
* **Engine Execution & Pool Orchestration** (`tests/engine/`): Tests transaction boundaries, `QueryExecutor` flow, `ConnectionPool` concurrency, and `QueryHistory` persistence.
|
|
80
|
+
* **Core Logic & Infrastructure** (`tests/core/`): Tests dependency injection (`test_di.py`), JSON/structured logging formatters, custom configuration layers (`test_config.py`), and the event bus (`test_events.py`).
|
|
81
|
+
* **Plugin Lifecycle** (`tests/plugins/`): Verifies API hooks, plugin load discovery, and context isolation.
|
|
82
|
+
|
|
83
|
+
### Code Coverage
|
|
84
|
+
|
|
85
|
+
> [!WARNING]
|
|
86
|
+
> The project enforces a **minimum 70% branch coverage** gate (`fail_under = 70` in `pyproject.toml`).
|
|
87
|
+
> Running `./scripts/test.sh` locally generates a `term-missing` coverage report. Please ensure your contributions include tests that maintain or improve coverage.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## ๐จ Coding Standards
|
|
92
|
+
|
|
93
|
+
To maintain predictability, performance, and robustness, all code submissions must adhere to the following standards:
|
|
94
|
+
|
|
95
|
+
1. **Strict Static Typing**: Mypy strict mode is enabled across the codebase. All public and private functions must have complete type signatures.
|
|
96
|
+
2. **Formatting and Styling**: Standardized via **Ruff** (line length: 100). Run `./scripts/fmt.sh` before staging commits.
|
|
97
|
+
3. **Async-First Event Loop**: Never execute blocking I/O operations directly within the TUI event loop or database adapters.
|
|
98
|
+
4. **No Silent Exceptions**: Do not suppress exceptions silently. Every catch block must log, wrap, or re-raise appropriately.
|
|
99
|
+
5. **Plugin Event Subscriptions**: Always register handlers via `PluginContext.subscribe` (which tracks subscriptions locally) instead of calling the event bus directly. This prevents memory leaks and orphaned tasks when plugins are dynamically unloaded.
|
|
100
|
+
6. **Adapter Locking Guidelines**: When implementing or editing adapters with blocking interfaces (such as DuckDB), ensure all operations that touch connection handles are synchronized under the adapter's `self._lock` and offloaded using `asyncio.to_thread`.
|
|
101
|
+
7. **Database Statement Classification**: Inspect prepared statement attributes (e.g., `stmt.get_attributes()` in `asyncpg`) to differentiate query execution types (DQL/DML) instead of parsing raw string prefixes. This ensures robust handling of comments and `RETURNING` clauses.
|
|
102
|
+
8. **Small, Composed Modules**: Prefer composition over inheritance. Keep modules small and highly focused.
|
|
103
|
+
9. **EditorConfig**: We ship an `.editorconfig` specifying UTF-8, LF, and 4-space indentation (2-space for configuration formats like YAML, TOML, and JSON). Ensure your editor configuration honors these guidelines.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## ๐ Adding a Database Adapter
|
|
108
|
+
|
|
109
|
+
If you are implementing support for a new database, follow these steps:
|
|
110
|
+
|
|
111
|
+
1. Create a subclass of `AbstractAdapter` in `packages/teridex-adapters/src/teridex_adapters/<name>_adapter.py`.
|
|
112
|
+
2. Define the class variables `name: ClassVar[str]` and `schemes: ClassVar[tuple[str, ...]]`.
|
|
113
|
+
3. Implement the required methods: `_do_connect`, `_do_close`, `ping`, `execute`, `stream`, `begin`, and `introspect`.
|
|
114
|
+
4. Register your new adapter class in `teridex_adapters/registry.py::_build_default`.
|
|
115
|
+
5. Add a parametrized conformance test under `tests/adapters/` using the shared scenarios in `tests/adapters/_conformance.py`.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## ๐ Pull Request Workflow
|
|
120
|
+
|
|
121
|
+
1. **Fork & Branch**: Fork the repository and create a feature branch off of `main` (e.g., `feature/my-db-adapter`).
|
|
122
|
+
2. **Develop**: Implement your changes and write unit tests to cover them.
|
|
123
|
+
3. **Lint & Format**: Run `./scripts/fmt.sh` to tidy your code.
|
|
124
|
+
4. **Validate Locally**: Run `./scripts/check.sh` to ensure formatting, types, and tests all pass locally.
|
|
125
|
+
5. **Submit PR**: Open a pull request against the `main` branch. Provide a clear description of the problem solved and the implementation details.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## ๐ฆ Releasing
|
|
130
|
+
|
|
131
|
+
Releases are automated via GitHub Actions (`.github/workflows/release.yml`) when a version tag is pushed. To prepare and cut a release:
|
|
132
|
+
|
|
133
|
+
1. Update `CHANGELOG.md` (graduate the `[Unreleased]` stanza to the new version).
|
|
134
|
+
2. Bump `version = "x.y.z"` in the root `pyproject.toml` and `__version__` in `src/teridex_core/__init__.py`.
|
|
135
|
+
3. Run `uv sync --all-extras --dev` to refresh `uv.lock`.
|
|
136
|
+
4. Run `./scripts/check.sh` and ensure it exits `0`.
|
|
137
|
+
5. Commit changes to `main` and push.
|
|
138
|
+
6. Create and push a version tag:
|
|
139
|
+
```bash
|
|
140
|
+
git tag vx.y.z
|
|
141
|
+
git push origin vx.y.z
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## ๐ Code of Conduct
|
|
147
|
+
|
|
148
|
+
Please maintain a respectful, supportive, and professional tone in all communication (issues, PR reviews, commit logs).
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
Happy coding! ๐
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Contributors ๐ฅ
|
|
2
|
+
|
|
3
|
+
A huge thank you to everyone who has contributed to **Teridez**!
|
|
4
|
+
|
|
5
|
+
## โจ Lead Maintainer
|
|
6
|
+
|
|
7
|
+
- **Salvatore Corvaglia** ([@salvatorecorvaglia](https://github.com/salvatorecorvaglia))
|
|
8
|
+
|
|
9
|
+
## ๐ Contributors
|
|
10
|
+
|
|
11
|
+
_Want to contribute? Check out [CONTRIBUTING.md](./CONTRIBUTING.md) to get started!_
|
teridex-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 **salvatorecorvaglia** (https://github.com/salvatorecorvaglia)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|