mycli 2.24.4__tar.gz → 2.28.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.
- {mycli-2.24.4 → mycli-2.28.0}/.github/dependabot.yml +2 -0
- {mycli-2.24.4 → mycli-2.28.0}/.github/workflows/ci.yml +55 -15
- {mycli-2.24.4 → mycli-2.28.0}/.github/workflows/publish.yml +44 -21
- {mycli-2.24.4 → mycli-2.28.0}/.github/workflows/typecheck.yml +2 -2
- mycli-2.28.0/AGENTS.md +152 -0
- mycli-2.28.0/AUTHORS.md +1 -0
- mycli-2.28.0/CONTRIBUTING.md +152 -0
- {mycli-2.24.4/mycli.egg-info → mycli-2.28.0}/PKG-INFO +69 -43
- {mycli-2.24.4 → mycli-2.28.0}/README.md +65 -37
- mycli-2.28.0/SPONSORS.md +1 -0
- {mycli-2.24.4 → mycli-2.28.0}/changelog.md +295 -159
- mycli-2.28.0/doc/cookbook.md +71 -0
- mycli-2.24.4/doc/key_bindings.rst → mycli-2.28.0/doc/key_bindings.md +24 -44
- mycli-2.28.0/doc/known_bugs.md +61 -0
- mycli-2.28.0/doc/screenshots/polars_describe.png +0 -0
- mycli-2.28.0/doc/screenshots/polars_group_by.png +0 -0
- mycli-2.28.0/doc/screenshots/polars_histogram.png +0 -0
- mycli-2.28.0/doc/screenshots/polars_pivot.png +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/doc/transforms.md +30 -12
- {mycli-2.24.4 → mycli-2.28.0}/docker/resources/test_db-1.0.7.tar.gz +1 -1
- mycli-2.28.0/docker/resources/test_db_license.md +18 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/TIPS +2 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/boundary_tunnel.py +3 -7
- {mycli-2.24.4 → mycli-2.28.0}/mycli/client_connection.py +9 -26
- {mycli-2.24.4 → mycli-2.28.0}/mycli/constants.py +21 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/key_bindings.py +21 -3
- mycli-2.28.0/mycli/keyring_utils.py +34 -0
- mycli-2.28.0/mycli/macos_keychain.py +80 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/main_modes/checkup.py +3 -3
- {mycli-2.24.4 → mycli-2.28.0}/mycli/main_modes/repl.py +96 -49
- {mycli-2.24.4 → mycli-2.28.0}/mycli/myclirc +6 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/output.py +19 -1
- {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/completion_engine.py +68 -1
- mycli-2.28.0/mycli/packages/fzf.py +78 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/hybrid_redirection.py +75 -27
- {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/key_binding_utils.py +9 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/polars_completion.py +3 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/polars_transform.py +36 -1
- mycli-2.24.4/mycli/packages/ptoolkit/fzf.py → mycli-2.28.0/mycli/packages/ptoolkit/fzf_history.py +5 -15
- {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/special/__init__.py +0 -8
- {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/special/dbcommands.py +1 -1
- {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/special/iocommands.py +110 -26
- {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/sqlresult.py +9 -1
- mycli-2.28.0/mycli/query_runner.py +370 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/sqlcompleter.py +24 -1
- {mycli-2.24.4 → mycli-2.28.0}/mycli/sqlexecute.py +73 -25
- {mycli-2.24.4 → mycli-2.28.0/mycli.egg-info}/PKG-INFO +69 -43
- {mycli-2.24.4 → mycli-2.28.0}/mycli.egg-info/SOURCES.txt +20 -6
- {mycli-2.24.4 → mycli-2.28.0}/mycli.egg-info/requires.txt +1 -2
- {mycli-2.24.4 → mycli-2.28.0}/mycli.egg-info/scm_file_list.json +20 -6
- mycli-2.28.0/mycli.egg-info/scm_version.json +8 -0
- {mycli-2.24.4 → mycli-2.28.0}/pyproject.toml +9 -7
- {mycli-2.24.4 → mycli-2.28.0}/test/features/basic_commands.feature +2 -2
- {mycli-2.24.4 → mycli-2.28.0}/test/features/iocommands.feature +3 -3
- {mycli-2.24.4 → mycli-2.28.0}/test/features/steps/basic_commands.py +4 -4
- {mycli-2.24.4 → mycli-2.28.0}/test/features/steps/iocommands.py +1 -1
- {mycli-2.24.4 → mycli-2.28.0}/test/features/steps/named_queries.py +17 -17
- {mycli-2.24.4 → mycli-2.28.0}/test/myclirc +6 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_boundary_tunnel.py +73 -70
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_checkup.py +2 -2
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_client.py +15 -3
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_client_commands.py +1 -1
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_client_connection.py +50 -17
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_completion_engine.py +128 -23
- mycli-2.28.0/test/pytests/test_fzf.py +126 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_hybrid_redirection.py +74 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_key_binding_utils.py +33 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_key_bindings.py +63 -2
- mycli-2.28.0/test/pytests/test_keyring_utils.py +105 -0
- mycli-2.28.0/test/pytests/test_macos_keychain.py +160 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_main.py +6 -6
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_main_modes_repl.py +403 -23
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_output.py +121 -1
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_polars_completion.py +5 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_polars_transform.py +80 -0
- mycli-2.24.4/test/pytests/test_ptoolkit_fzf.py → mycli-2.28.0/test/pytests/test_ptoolkit_fzf_history.py +35 -37
- mycli-2.28.0/test/pytests/test_query_runner.py +983 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_smart_completion_public_schema_only.py +104 -18
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_special_dbcommands.py +7 -12
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_special_init.py +1 -1
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_special_iocommands.py +321 -38
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_special_llm.py +20 -20
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_special_main.py +12 -12
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_sql_utils.py +8 -8
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_sqlcompleter.py +97 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_sqlexecute.py +288 -14
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_sqlresult.py +24 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/utils.py +13 -1
- mycli-2.24.4/AGENTS.md +0 -141
- mycli-2.24.4/AUTHORS.rst +0 -3
- mycli-2.24.4/CONTRIBUTING.md +0 -118
- mycli-2.24.4/SPONSORS.rst +0 -3
- mycli-2.24.4/doc/screenshots/total_histogram.png +0 -0
- mycli-2.24.4/mycli.egg-info/scm_version.json +0 -8
- {mycli-2.24.4 → mycli-2.28.0}/.git-blame-ignore-revs +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/.github/workflows/lint.yml +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/.gitignore +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/LICENSE.txt +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/MANIFEST.in +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/doc/llm.md +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/doc/screenshots/main.gif +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/doc/screenshots/tables.png +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/docker/Dockerfile +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/AUTHORS +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/SPONSORS +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/__init__.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/app_state.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/cli_runner.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/clibuffer.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/client.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/client_commands.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/client_query.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/clistyle.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/clitoolbar.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/compat.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/completion_refresher.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/config.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/kubectl_tunnel.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/lexer.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/main.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/main_modes/batch.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/main_modes/completions.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/main_modes/execute.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/main_modes/list_dsn.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/__init__.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/batch_utils.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/cli_utils.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/filepaths.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/interactive_utils.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/ptoolkit/__init__.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/ptoolkit/history.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/ptoolkit/utils.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/special/delimitercommand.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/special/dsn_aliases.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/special/favoritequeries.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/special/llm.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/special/main.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/special/source.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/special/utils.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/sql_utils.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/string_utils.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/tabular_output/__init__.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/tabular_output/sql_format.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/password_sources.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/resources/completions/bash/mycli +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/resources/completions/fish/mycli.fish +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/resources/completions/zsh/_mycli +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/schema_prefetcher.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/ssh_tunnel.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/types.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli/vault.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli.egg-info/dependency_links.txt +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli.egg-info/entry_points.txt +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/mycli.egg-info/top_level.txt +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/setup.cfg +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/__init__.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/features/__init__.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/features/auto_vertical.feature +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/features/connection.feature +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/features/crud_database.feature +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/features/crud_table.feature +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/features/db_utils.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/features/environment.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/features/fixture_data/help_commands.txt +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/features/fixture_utils.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/features/named_queries.feature +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/features/specials.feature +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/features/steps/__init__.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/features/steps/auto_vertical.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/features/steps/connection.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/features/steps/crud_database.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/features/steps/crud_table.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/features/steps/specials.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/features/steps/utils.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/features/steps/wrappers.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/features/wrappager.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/mylogin.cnf +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/conftest.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_app_state.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_bash_completion.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_batch_utils.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_cli_runner.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_cli_utils.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_clibuffer.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_client_query.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_clistyle.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_clitoolbar.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_completer_use_switch.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_completion_refresher.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_config.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_delimitercommand.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_dsn_aliases.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_favoritequeries.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_filepaths.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_fish_completion.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_interactive_utils.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_kubectl_tunnel.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_main_modes_batch.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_main_modes_execute.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_main_modes_list_dsn.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_naive_completion.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_password_sources.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_ptoolkit_history.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_ptoolkit_utils.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_schema_prefetcher.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_special_source.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_special_utils.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_ssh_tunnel.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_string_utils.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_tabular_output.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_vault.py +0 -0
- {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_zsh_completion.py +0 -0
|
@@ -19,12 +19,12 @@ jobs:
|
|
|
19
19
|
strategy:
|
|
20
20
|
fail-fast: false
|
|
21
21
|
matrix:
|
|
22
|
-
python-version: ["3.
|
|
22
|
+
python-version: ["3.11", "3.12", "3.13", "3.14"]
|
|
23
23
|
|
|
24
24
|
steps:
|
|
25
25
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
26
26
|
|
|
27
|
-
- uses: astral-sh/setup-uv@
|
|
27
|
+
- uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
|
|
28
28
|
with:
|
|
29
29
|
version: "latest"
|
|
30
30
|
|
|
@@ -38,7 +38,7 @@ jobs:
|
|
|
38
38
|
sudo /etc/init.d/mysql start
|
|
39
39
|
|
|
40
40
|
- name: Install dependencies
|
|
41
|
-
run: uv sync --
|
|
41
|
+
run: uv sync --extra dev,llm,dataframe -p ${{ matrix.python-version }}
|
|
42
42
|
|
|
43
43
|
- name: Wait for MySQL connection
|
|
44
44
|
run: |
|
|
@@ -52,7 +52,7 @@ jobs:
|
|
|
52
52
|
PYTEST_HOST: 127.0.0.1
|
|
53
53
|
TERM: xterm
|
|
54
54
|
run: |
|
|
55
|
-
|
|
55
|
+
./.venv/bin/tox -e py${{ matrix.python-version }}
|
|
56
56
|
|
|
57
57
|
tests-macos:
|
|
58
58
|
name: Tests macOS
|
|
@@ -66,7 +66,7 @@ jobs:
|
|
|
66
66
|
steps:
|
|
67
67
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
68
68
|
|
|
69
|
-
- uses: astral-sh/setup-uv@
|
|
69
|
+
- uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
|
|
70
70
|
with:
|
|
71
71
|
version: "latest"
|
|
72
72
|
|
|
@@ -84,7 +84,7 @@ jobs:
|
|
|
84
84
|
brew services start mysql
|
|
85
85
|
|
|
86
86
|
- name: Install dependencies
|
|
87
|
-
run: uv sync --
|
|
87
|
+
run: uv sync --extra dev,llm,dataframe -p ${{ matrix.python-version }}
|
|
88
88
|
|
|
89
89
|
- name: Wait for MySQL connection
|
|
90
90
|
run: |
|
|
@@ -102,7 +102,7 @@ jobs:
|
|
|
102
102
|
PYTEST_HOST: 127.0.0.1
|
|
103
103
|
TERM: xterm
|
|
104
104
|
run: |
|
|
105
|
-
|
|
105
|
+
./.venv/bin/tox -e py${{ matrix.python-version }}
|
|
106
106
|
|
|
107
107
|
tests-windows:
|
|
108
108
|
name: Tests Windows
|
|
@@ -116,7 +116,7 @@ jobs:
|
|
|
116
116
|
steps:
|
|
117
117
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
118
118
|
|
|
119
|
-
- uses: astral-sh/setup-uv@
|
|
119
|
+
- uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
|
|
120
120
|
with:
|
|
121
121
|
version: 'latest'
|
|
122
122
|
|
|
@@ -127,10 +127,10 @@ jobs:
|
|
|
127
127
|
|
|
128
128
|
- name: Install dependencies
|
|
129
129
|
shell: cmd
|
|
130
|
-
run: uv sync --
|
|
130
|
+
run: uv sync --extra dev,llm,dataframe -p ${{ matrix.python-version }}
|
|
131
131
|
|
|
132
132
|
- name: Set up MySQL
|
|
133
|
-
uses: shogo82148/actions-setup-mysql@
|
|
133
|
+
uses: shogo82148/actions-setup-mysql@083ec148d28e62f2b24b8f4541693dfe1d50488d # v1.54.0
|
|
134
134
|
with:
|
|
135
135
|
mysql-version: '9.7'
|
|
136
136
|
root-password: root
|
|
@@ -144,7 +144,7 @@ jobs:
|
|
|
144
144
|
uv run -- coverage report -m --sort=Miss --skip-covered --skip-empty
|
|
145
145
|
|
|
146
146
|
tests-wsl:
|
|
147
|
-
name: Tests WSL
|
|
147
|
+
name: Tests WSL (3.14)
|
|
148
148
|
runs-on: windows-latest
|
|
149
149
|
|
|
150
150
|
steps:
|
|
@@ -182,7 +182,7 @@ jobs:
|
|
|
182
182
|
run: |
|
|
183
183
|
export PATH="$HOME/.local/bin:$PATH"
|
|
184
184
|
cd /root/mycli
|
|
185
|
-
uv sync --
|
|
185
|
+
uv sync --extra dev,llm,dataframe --python 3.14
|
|
186
186
|
|
|
187
187
|
- name: Start MySQL in WSL
|
|
188
188
|
shell: wsl-bash {0}
|
|
@@ -214,13 +214,13 @@ jobs:
|
|
|
214
214
|
uv run --python 3.14 -- coverage report -m --sort=Miss --skip-covered --skip-empty
|
|
215
215
|
|
|
216
216
|
test-no-extras:
|
|
217
|
-
name: Tests Without Extras
|
|
217
|
+
name: Tests Without Extras (3.14)
|
|
218
218
|
runs-on: ubuntu-latest
|
|
219
219
|
|
|
220
220
|
steps:
|
|
221
221
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
222
222
|
|
|
223
|
-
- uses: astral-sh/setup-uv@
|
|
223
|
+
- uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
|
|
224
224
|
with:
|
|
225
225
|
version: "latest"
|
|
226
226
|
|
|
@@ -248,4 +248,44 @@ jobs:
|
|
|
248
248
|
PYTEST_HOST: 127.0.0.1
|
|
249
249
|
TERM: xterm
|
|
250
250
|
run: |
|
|
251
|
-
|
|
251
|
+
./.venv/bin/tox -e py3.14
|
|
252
|
+
|
|
253
|
+
docker-x86-build:
|
|
254
|
+
name: Build x86 Docker Image
|
|
255
|
+
runs-on: ubuntu-latest
|
|
256
|
+
|
|
257
|
+
permissions:
|
|
258
|
+
contents: read
|
|
259
|
+
|
|
260
|
+
# simpler than the steps in publish.yml, because we don't do the slow buildx multiarch
|
|
261
|
+
steps:
|
|
262
|
+
- name: Checkout repository
|
|
263
|
+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
264
|
+
|
|
265
|
+
- name: Build Docker image
|
|
266
|
+
id: build
|
|
267
|
+
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
|
|
268
|
+
with:
|
|
269
|
+
context: .
|
|
270
|
+
file: docker/Dockerfile
|
|
271
|
+
push: false
|
|
272
|
+
|
|
273
|
+
docker-arm-build:
|
|
274
|
+
name: Build ARM Docker Image
|
|
275
|
+
runs-on: ubuntu-24.04-arm
|
|
276
|
+
|
|
277
|
+
permissions:
|
|
278
|
+
contents: read
|
|
279
|
+
|
|
280
|
+
# simpler than the steps in publish.yml, because we don't do the slow buildx multiarch
|
|
281
|
+
steps:
|
|
282
|
+
- name: Checkout repository
|
|
283
|
+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
284
|
+
|
|
285
|
+
- name: Build Docker image
|
|
286
|
+
id: build
|
|
287
|
+
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
|
|
288
|
+
with:
|
|
289
|
+
context: .
|
|
290
|
+
file: docker/Dockerfile
|
|
291
|
+
push: false
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
name: Publish
|
|
1
|
+
name: Publish Packages
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
4
|
release:
|
|
@@ -28,11 +28,11 @@ jobs:
|
|
|
28
28
|
|
|
29
29
|
strategy:
|
|
30
30
|
matrix:
|
|
31
|
-
python-version: ["3.
|
|
31
|
+
python-version: ["3.11", "3.12", "3.13", "3.14"]
|
|
32
32
|
|
|
33
33
|
steps:
|
|
34
34
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
35
|
-
- uses: astral-sh/setup-uv@
|
|
35
|
+
- uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
|
|
36
36
|
with:
|
|
37
37
|
version: "latest"
|
|
38
38
|
|
|
@@ -46,7 +46,7 @@ jobs:
|
|
|
46
46
|
sudo /etc/init.d/mysql start
|
|
47
47
|
|
|
48
48
|
- name: Install dependencies
|
|
49
|
-
run: uv sync --
|
|
49
|
+
run: uv sync --extra dev,llm,dataframe -p ${{ matrix.python-version }}
|
|
50
50
|
|
|
51
51
|
- name: Wait for MySQL connection
|
|
52
52
|
run: |
|
|
@@ -54,16 +54,22 @@ jobs:
|
|
|
54
54
|
sleep 5
|
|
55
55
|
done
|
|
56
56
|
|
|
57
|
+
# arguably this should be made identical to CI for PRs
|
|
58
|
+
# better would be a composite GH action
|
|
59
|
+
- name: Run Style Checks
|
|
60
|
+
run: ./.venv/bin/tox -e style
|
|
61
|
+
|
|
62
|
+
# arguably this should be made identical to CI for PRs
|
|
63
|
+
# better would be a composite GH action
|
|
64
|
+
- name: Run Typechecker
|
|
65
|
+
run: ./.venv/bin/tox -e typecheck
|
|
66
|
+
|
|
57
67
|
- name: Pytest / behave
|
|
58
68
|
env:
|
|
59
69
|
PYTEST_PASSWORD: root
|
|
60
70
|
PYTEST_HOST: 127.0.0.1
|
|
61
71
|
run: |
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
# arguably this should be made identical to CI for PRs
|
|
65
|
-
- name: Run Style Checks
|
|
66
|
-
run: uv run tox -e style
|
|
72
|
+
./.venv/bin/tox -e py${{ matrix.python-version }}
|
|
67
73
|
|
|
68
74
|
tests-macos:
|
|
69
75
|
name: Tests macOS
|
|
@@ -77,7 +83,7 @@ jobs:
|
|
|
77
83
|
steps:
|
|
78
84
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
79
85
|
|
|
80
|
-
- uses: astral-sh/setup-uv@
|
|
86
|
+
- uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
|
|
81
87
|
with:
|
|
82
88
|
version: "latest"
|
|
83
89
|
|
|
@@ -95,7 +101,7 @@ jobs:
|
|
|
95
101
|
brew services start mysql
|
|
96
102
|
|
|
97
103
|
- name: Install dependencies
|
|
98
|
-
run: uv sync --
|
|
104
|
+
run: uv sync --extra dev,llm,dataframe -p ${{ matrix.python-version }}
|
|
99
105
|
|
|
100
106
|
- name: Wait for MySQL connection
|
|
101
107
|
run: |
|
|
@@ -113,7 +119,7 @@ jobs:
|
|
|
113
119
|
PYTEST_HOST: 127.0.0.1
|
|
114
120
|
TERM: xterm
|
|
115
121
|
run: |
|
|
116
|
-
|
|
122
|
+
./.venv/bin/tox -e py${{ matrix.python-version }}
|
|
117
123
|
|
|
118
124
|
tests-windows:
|
|
119
125
|
name: Tests Windows
|
|
@@ -127,7 +133,7 @@ jobs:
|
|
|
127
133
|
steps:
|
|
128
134
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
129
135
|
|
|
130
|
-
- uses: astral-sh/setup-uv@
|
|
136
|
+
- uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
|
|
131
137
|
with:
|
|
132
138
|
version: 'latest'
|
|
133
139
|
|
|
@@ -138,10 +144,10 @@ jobs:
|
|
|
138
144
|
|
|
139
145
|
- name: Install dependencies
|
|
140
146
|
shell: cmd
|
|
141
|
-
run: uv sync --
|
|
147
|
+
run: uv sync --extra dev,llm,dataframe -p ${{ matrix.python-version }}
|
|
142
148
|
|
|
143
149
|
- name: Set up MySQL
|
|
144
|
-
uses: shogo82148/actions-setup-mysql@
|
|
150
|
+
uses: shogo82148/actions-setup-mysql@083ec148d28e62f2b24b8f4541693dfe1d50488d # v1.54.0
|
|
145
151
|
with:
|
|
146
152
|
mysql-version: '9.7'
|
|
147
153
|
root-password: root
|
|
@@ -193,7 +199,7 @@ jobs:
|
|
|
193
199
|
run: |
|
|
194
200
|
export PATH="$HOME/.local/bin:$PATH"
|
|
195
201
|
cd /root/mycli
|
|
196
|
-
uv sync --
|
|
202
|
+
uv sync --extra dev,llm,dataframe --python 3.14
|
|
197
203
|
|
|
198
204
|
- name: Start MySQL in WSL
|
|
199
205
|
shell: wsl-bash {0}
|
|
@@ -230,7 +236,7 @@ jobs:
|
|
|
230
236
|
|
|
231
237
|
steps:
|
|
232
238
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
233
|
-
- uses: astral-sh/setup-uv@
|
|
239
|
+
- uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
|
|
234
240
|
with:
|
|
235
241
|
version: "latest"
|
|
236
242
|
|
|
@@ -240,7 +246,7 @@ jobs:
|
|
|
240
246
|
python-version: '3.14'
|
|
241
247
|
|
|
242
248
|
- name: Install dependencies
|
|
243
|
-
run: uv sync --
|
|
249
|
+
run: uv sync --extra llm,dataframe -p 3.14
|
|
244
250
|
|
|
245
251
|
- name: Build
|
|
246
252
|
run: uv build
|
|
@@ -252,7 +258,7 @@ jobs:
|
|
|
252
258
|
path: dist/
|
|
253
259
|
|
|
254
260
|
publish-pypi:
|
|
255
|
-
name: Publish to PyPI
|
|
261
|
+
name: Publish Wheel to PyPI
|
|
256
262
|
runs-on: ubuntu-latest
|
|
257
263
|
if: startsWith(github.ref, 'refs/tags/')
|
|
258
264
|
needs: [build]
|
|
@@ -269,12 +275,16 @@ jobs:
|
|
|
269
275
|
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
|
|
270
276
|
|
|
271
277
|
publish-image:
|
|
272
|
-
name: Publish to ghcr.io
|
|
278
|
+
name: Publish Image to ghcr.io
|
|
273
279
|
runs-on: ubuntu-latest
|
|
274
280
|
if: startsWith(github.ref, 'refs/tags/')
|
|
281
|
+
# doesn't actually need the results of build, but it makes sense to run this
|
|
282
|
+
# concurrently with publish-pypi
|
|
275
283
|
needs: [build]
|
|
276
284
|
environment: release
|
|
277
285
|
|
|
286
|
+
# some of these permissions are probably not needed since attestations
|
|
287
|
+
# were removed
|
|
278
288
|
permissions:
|
|
279
289
|
contents: read
|
|
280
290
|
packages: write
|
|
@@ -293,18 +303,31 @@ jobs:
|
|
|
293
303
|
username: ${{ github.actor }}
|
|
294
304
|
password: ${{ secrets.GITHUB_TOKEN }}
|
|
295
305
|
|
|
306
|
+
# should be needed for multi-arch images
|
|
307
|
+
- name: Set up Docker Buildx
|
|
308
|
+
id: buildx
|
|
309
|
+
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
|
|
310
|
+
|
|
296
311
|
- name: Extract metadata (tags, labels) for Docker
|
|
297
312
|
id: meta
|
|
298
313
|
uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
|
|
299
314
|
with:
|
|
300
315
|
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
|
316
|
+
env:
|
|
317
|
+
# despite this setting, annotations only seem to appear at the index level
|
|
318
|
+
# on "docker buildx imagetools inspect"
|
|
319
|
+
DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index
|
|
301
320
|
|
|
302
321
|
- name: Build and push Docker image
|
|
303
322
|
id: push
|
|
304
|
-
uses: docker/build-push-action@
|
|
323
|
+
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
|
|
305
324
|
with:
|
|
306
325
|
context: .
|
|
307
326
|
file: docker/Dockerfile
|
|
308
327
|
push: true
|
|
328
|
+
# the linux/arm64 arch will be very slow to build, so it is only made for
|
|
329
|
+
# publication, not testing
|
|
330
|
+
platforms: linux/amd64,linux/arm64
|
|
309
331
|
tags: ${{ steps.meta.outputs.tags }}
|
|
310
332
|
labels: ${{ steps.meta.outputs.labels }}
|
|
333
|
+
annotations: ${{ steps.meta.outputs.annotations }}
|
|
@@ -25,12 +25,12 @@ jobs:
|
|
|
25
25
|
with:
|
|
26
26
|
python-version: '3.14'
|
|
27
27
|
|
|
28
|
-
- uses: astral-sh/setup-uv@
|
|
28
|
+
- uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
|
|
29
29
|
with:
|
|
30
30
|
version: 'latest'
|
|
31
31
|
|
|
32
32
|
- name: Install dependencies
|
|
33
|
-
run: uv sync --
|
|
33
|
+
run: uv sync --extra dev,llm,dataframe
|
|
34
34
|
|
|
35
35
|
- name: Run mypy
|
|
36
36
|
run: |
|
mycli-2.28.0/AGENTS.md
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# Mycli
|
|
2
|
+
|
|
3
|
+
A command line client for MySQL with auto-completion and syntax highlighting.
|
|
4
|
+
|
|
5
|
+
## Project Structure
|
|
6
|
+
|
|
7
|
+
/ # repository root
|
|
8
|
+
├── .github/ # GitHub Actions and configuration
|
|
9
|
+
├── pyproject.toml # project configuration
|
|
10
|
+
├── doc/ # documentation
|
|
11
|
+
├── doc/cookbook.md # recipes for how to configure and use mycli
|
|
12
|
+
├── doc/key_bindings.md # documentation of key binding behaviors
|
|
13
|
+
├── doc/known_bugs.md # documentation of known bugs and limitations
|
|
14
|
+
├── doc/llm.md # documentation on how to use LLM features
|
|
15
|
+
├── doc/transforms.md # documentation on how to use dataframe transform/plot features
|
|
16
|
+
├── doc/screenshots/ # screenshots for documentation
|
|
17
|
+
├── mycli/ # application source
|
|
18
|
+
├── mycli/__init__.py # provides version number
|
|
19
|
+
├── mycli/app_state.py # `AppStateMixin` application state mixin and related functions
|
|
20
|
+
├── mycli/boundary_tunnel.py # connection over Boundary tunnel
|
|
21
|
+
├── mycli/cli_runner.py # connects and dispatches main modes based on CLI arguments
|
|
22
|
+
├── mycli/clibuffer.py # prompt_toolkit buffer utilities
|
|
23
|
+
├── mycli/client_commands.py # special commands which must be registered separately
|
|
24
|
+
├── mycli/client_connection.py # `ClientConnectionMixin` mixin for establishing the database connection
|
|
25
|
+
├── mycli/client_query.py # `ClientQueryMixin` mixin for running queries and refreshing completions
|
|
26
|
+
├── mycli/client.py # the `MyCli` "god class"
|
|
27
|
+
├── mycli/clistyle.py # prompt_toolkit style utilities
|
|
28
|
+
├── mycli/clitoolbar.py # prompt_toolkit toolbar utilities
|
|
29
|
+
├── mycli/compat.py # OS compatibility helpers
|
|
30
|
+
├── mycli/completion_refresher.py # populates a `SQLCompleter` object in a background thread
|
|
31
|
+
├── mycli/config.py # configuration file readers and utilities
|
|
32
|
+
├── mycli/constants.py # shared constants
|
|
33
|
+
├── mycli/key_bindings.py # prompt_toolkit key binding utilities
|
|
34
|
+
├── mycli/keyring_utils.py # saved credential utilities
|
|
35
|
+
├── mycli/kubectl_tunnel.py # connection over kubectl tunnel
|
|
36
|
+
├── mycli/lexer.py # extends `MySqlLexer` from Pygments
|
|
37
|
+
├── mycli/macos_keychain.py # macOS Keychain credentials preserving access controls
|
|
38
|
+
├── mycli/main.py # processes CLI arguments
|
|
39
|
+
├── mycli/main_modes/ # main execution paths
|
|
40
|
+
├── mycli/main_modes/batch.py # `--batch` mode
|
|
41
|
+
├── mycli/main_modes/checkup.py # `--checkup` mode
|
|
42
|
+
├── mycli/main_modes/completions.py # `--completions` mode
|
|
43
|
+
├── mycli/main_modes/execute.py # `--execute` mode
|
|
44
|
+
├── mycli/main_modes/list_dsn.py # `--list-dsn` mode
|
|
45
|
+
├── mycli/main_modes/repl.py # interactive REPL mode
|
|
46
|
+
├── mycli/myclirc # project-level configuration file
|
|
47
|
+
├── mycli/output.py # `OutputMixin` mixin for feedback and output of query results
|
|
48
|
+
├── mycli/packages/ # application packages
|
|
49
|
+
├── mycli/packages/batch_utils.py # utilities for `--batch` mode
|
|
50
|
+
├── mycli/packages/cli_utils.py # utilities for parsing CLI arguments
|
|
51
|
+
├── mycli/packages/completion_engine.py # implementation of completion suggestions
|
|
52
|
+
├── mycli/packages/filepaths.py # utilities for files, including completion suggestions
|
|
53
|
+
├── mycli/packages/fzf.py # general interface to fzf chooser
|
|
54
|
+
├── mycli/packages/hybrid_redirection.py # implementation of shell-style redirects
|
|
55
|
+
├── mycli/packages/interactive_utils.py # utilities for confirming on destructive statements
|
|
56
|
+
├── mycli/packages/key_binding_utils.py # handlers for key bindings and related special commands
|
|
57
|
+
├── mycli/packages/polars_completion.py # completions for `.|` transforms
|
|
58
|
+
├── mycli/packages/polars_transform.py # implements `.|` transforms
|
|
59
|
+
├── mycli/packages/ptoolkit/ # extends prompt_toolkit
|
|
60
|
+
├── mycli/packages/special/ # implementation of mycli special commands
|
|
61
|
+
├── mycli/packages/sql_utils.py # utilities for parsing SQL statements
|
|
62
|
+
├── mycli/packages/sqlresult.py # the `SQLResult` dataclass for holding responses
|
|
63
|
+
├── mycli/packages/string_utils.py # generic string utilities
|
|
64
|
+
├── mycli/packages/tabular_output/ # extends cli_helper with additional output formats
|
|
65
|
+
├── mycli/password_sources.py # password sources and precedence
|
|
66
|
+
├── mycli/query_runner.py # run queries with query state and timing updates
|
|
67
|
+
├── mycli/resources/completions/ # shell completions for CLI interface
|
|
68
|
+
├── mycli/ssh_tunnel.py # connecting over a tunnel with `--ssh-jump`
|
|
69
|
+
├── mycli/schema_prefetcher.py # background prefetcher for multi-schema auto-completion
|
|
70
|
+
├── mycli/sqlcompleter.py # offers SQL completions
|
|
71
|
+
├── mycli/sqlexecute.py # runs SQL queries
|
|
72
|
+
├── mycli/types.py # shared types
|
|
73
|
+
├── mycli/vault.py # Vault integration
|
|
74
|
+
├── test/features/ # behave tests
|
|
75
|
+
├── test/myclirc # mycli configuration used for tests
|
|
76
|
+
├── test/mylogin.cnf # `mylogin.cnf` example used for tests
|
|
77
|
+
├── test/pytests/ # pytest tests
|
|
78
|
+
├── test/pytests/conftest.py # pytest configuration
|
|
79
|
+
└── test/utils.py # shared utilities for tests
|
|
80
|
+
|
|
81
|
+
## Development
|
|
82
|
+
|
|
83
|
+
### Python
|
|
84
|
+
|
|
85
|
+
#### Python Dependency Management
|
|
86
|
+
|
|
87
|
+
This repo uses `uv` for dependency management. **Always** prefix Python
|
|
88
|
+
commands with `uv run`. Example:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
env -u PYTHONPATH uv run -- python script.py
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
#### Python Typing
|
|
95
|
+
|
|
96
|
+
This repo uses type annotations which are checked by `mypy`. **Always** add
|
|
97
|
+
type annotations, and always check new code with `env -u PYTHONPATH uv run -- mypy --install-types --non-interactive script.py`.
|
|
98
|
+
|
|
99
|
+
Use lower-case type annotations such as `tuple`, not upper-case type
|
|
100
|
+
annotations such as `Tuple`.
|
|
101
|
+
|
|
102
|
+
Use `Type | None` instead of `Optional[Type]`.
|
|
103
|
+
|
|
104
|
+
#### Python Testing
|
|
105
|
+
|
|
106
|
+
Tests are coordinated by `tox`, and include both `pytest` and `behave` tests.
|
|
107
|
+
To run the full test suite, execute `env -u PYTHONPATH uv run -- tox`.
|
|
108
|
+
|
|
109
|
+
#### Python Compatibility
|
|
110
|
+
|
|
111
|
+
Use Python features available from Python 3.11 through Python 3.14.
|
|
112
|
+
Compatibility with Python 3.9 is not needed. Compatibility with Python
|
|
113
|
+
3.10 is not needed.
|
|
114
|
+
|
|
115
|
+
#### Python Style
|
|
116
|
+
|
|
117
|
+
Import style: prefer `from package import name` over `import package.name as name`.
|
|
118
|
+
|
|
119
|
+
Quoting style: prefer single quotes for new code, but do not remove double quotes
|
|
120
|
+
from existing code.
|
|
121
|
+
|
|
122
|
+
#### Python Environment
|
|
123
|
+
|
|
124
|
+
* Package manager: `uv` (not pip)
|
|
125
|
+
* Formatter: `env -u PYTHONPATH uv run -- ruff format`
|
|
126
|
+
* Linter: `env -u PYTHONPATH uv run -- ruff check`
|
|
127
|
+
* Type checker: `env -u PYTHONPATH uv run -- mypy --install-types --non-interactive`
|
|
128
|
+
|
|
129
|
+
### Git Workflows
|
|
130
|
+
|
|
131
|
+
#### Git Commit Messages
|
|
132
|
+
|
|
133
|
+
* Use the present tense.
|
|
134
|
+
* Keep the first line under 50 characters in length.
|
|
135
|
+
* Keep the second line blank.
|
|
136
|
+
* Keep all other lines under 72 characters in length.
|
|
137
|
+
* Reference issue numbers when available.
|
|
138
|
+
|
|
139
|
+
#### Generating PRs
|
|
140
|
+
|
|
141
|
+
When generating a PR, follow the instructions in `.github/PULL_REQUEST_TEMPLATE.md`:
|
|
142
|
+
|
|
143
|
+
* Add new author names to `mycli/AUTHORS`.
|
|
144
|
+
* Add a new entry to `changelog.md`.
|
|
145
|
+
|
|
146
|
+
### Code Comments
|
|
147
|
+
|
|
148
|
+
Keep comments concise and direct. Use full sentences, ending with a period.
|
|
149
|
+
|
|
150
|
+
### See Also
|
|
151
|
+
|
|
152
|
+
See also the file `CONTRIBUTING.md`.
|
mycli-2.28.0/AUTHORS.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
See [AUTHORS](mycli/AUTHORS)
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# Development Guide
|
|
2
|
+
|
|
3
|
+
This is a guide for developers who would like to contribute to the project.
|
|
4
|
+
|
|
5
|
+
If you're interested in contributing to mycli, thank you. We'd love your help!
|
|
6
|
+
You'll always get credit and appreciation for your work.
|
|
7
|
+
|
|
8
|
+
## GitHub Workflow
|
|
9
|
+
|
|
10
|
+
1. [Fork the repository](https://github.com/dbcli/mycli) on GitHub.
|
|
11
|
+
|
|
12
|
+
2. Clone your fork locally:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
git clone <url-for-your-fork>
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
3. Add the official repository (`upstream`) as a remote repository:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
git remote add upstream git@github.com:dbcli/mycli.git
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
4. Once you have added upstream, the following command will pull the latest changes to your local `main`:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
git pull upstream main
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
5. Set up [uv](https://docs.astral.sh/uv/getting-started/installation/)
|
|
31
|
+
for development:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
cd mycli
|
|
35
|
+
uv sync --all-extras
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
We've just created a virtual environment and installed all the dependencies
|
|
39
|
+
and tools we need to work on mycli.
|
|
40
|
+
|
|
41
|
+
6. Create a branch for your bugfix or feature based off the `main` branch:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
git checkout -b <name-of-bugfix-or-feature> main
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
7. When your work is ready for the mycli team to review it, push your branch to your fork:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
git push origin <name-of-bugfix-or-feature>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
8. [Create a pull request](https://help.github.com/articles/creating-a-pull-request-from-a-fork/)
|
|
54
|
+
on GitHub.
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
## Running Mycli with Changes
|
|
58
|
+
|
|
59
|
+
To run mycli with your local changes:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
uv run mycli
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
## Running the Tests
|
|
67
|
+
|
|
68
|
+
While you work on mycli, it's important to run the tests to make sure your code
|
|
69
|
+
hasn't broken any existing functionality. To run the tests, just run:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
uv run tox
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Test Database Credentials
|
|
76
|
+
|
|
77
|
+
Some tests require a database connection to work. You can tell the tests which
|
|
78
|
+
credentials to use by setting the applicable environment variables:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
export PYTEST_HOST=localhost
|
|
82
|
+
export PYTEST_USER=mycli
|
|
83
|
+
export PYTEST_PASSWORD=myclirocks
|
|
84
|
+
export PYTEST_PORT=3306
|
|
85
|
+
export PYTEST_CHARSET=utf8mb4
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Since the default values are
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
export PYTEST_HOST=localhost
|
|
92
|
+
export PYTEST_USER=root
|
|
93
|
+
export PYTEST_PASSWORD=<no password>
|
|
94
|
+
export PYTEST_PORT=3306
|
|
95
|
+
export PYTEST_CHARSET=utf8mb4
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
for most cases you only need to set the values which differ from the defaults:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
export PYTEST_USER=mycli
|
|
102
|
+
export PYTEST_PASSWORD=myclirocks
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
If you would like to run the tests as a user with only the necessary privileges,
|
|
106
|
+
create a `mycli` user on your MySQL server and run the following GRANT statements:
|
|
107
|
+
|
|
108
|
+
```sql
|
|
109
|
+
GRANT ALL PRIVILEGES ON `mycli_%`.* TO 'mycli'@'localhost';
|
|
110
|
+
GRANT SELECT ON mysql.* TO 'mycli'@'localhost';
|
|
111
|
+
GRANT SELECT ON performance_schema.* TO 'mycli'@'localhost';
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Editor Tests
|
|
115
|
+
|
|
116
|
+
Some tests expect the program `ex` to be a symbolic link to `vim`.
|
|
117
|
+
|
|
118
|
+
In some systems (e.g. Arch Linux) `ex` is a symbolic link to `vi`, which will
|
|
119
|
+
change the output and therefore make some tests fail.
|
|
120
|
+
|
|
121
|
+
You can check this by running:
|
|
122
|
+
```bash
|
|
123
|
+
readlink -f $(which ex)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
# GitHub PR checklist
|
|
127
|
+
|
|
128
|
+
* add the contribution to `changelog.md`
|
|
129
|
+
* add your name to the `AUTHORS` file (or make sure it is already there)
|
|
130
|
+
* run
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
uv run ruff check && uv run ruff format && uv run mypy --install-types .
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
## Releasing a New Version of Mycli (For Maintainers)
|
|
138
|
+
|
|
139
|
+
We create a new [release](https://github.com/dbcli/mycli/releases) in GitHub. This triggers a GitHub Action which will
|
|
140
|
+
|
|
141
|
+
* run all the tests
|
|
142
|
+
* build a wheel and upload it to PyPI
|
|
143
|
+
* build a Docker image and upload it to ghcr.io
|
|
144
|
+
|
|
145
|
+
Steps to create a release:
|
|
146
|
+
|
|
147
|
+
* Update `changelog.md`, setting the release version and date at the top. Bump the feature version if there are new features in the changelog, otherwise only bump the patch version. Merge this change.
|
|
148
|
+
* Navigate to https://github.com/dbcli/mycli/releases/new .
|
|
149
|
+
* Press "Select Tag" and enter the new version number. It should be the same as in `changelog.md` but with a leading `v`. It should not already exist.
|
|
150
|
+
* Press "Generate Release Notes", which will fill in the notes and the title.
|
|
151
|
+
* Sanity check the generated release notes.
|
|
152
|
+
* Press "Publish Release".
|