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.
Files changed (215) hide show
  1. {mycli-2.24.4 → mycli-2.28.0}/.github/dependabot.yml +2 -0
  2. {mycli-2.24.4 → mycli-2.28.0}/.github/workflows/ci.yml +55 -15
  3. {mycli-2.24.4 → mycli-2.28.0}/.github/workflows/publish.yml +44 -21
  4. {mycli-2.24.4 → mycli-2.28.0}/.github/workflows/typecheck.yml +2 -2
  5. mycli-2.28.0/AGENTS.md +152 -0
  6. mycli-2.28.0/AUTHORS.md +1 -0
  7. mycli-2.28.0/CONTRIBUTING.md +152 -0
  8. {mycli-2.24.4/mycli.egg-info → mycli-2.28.0}/PKG-INFO +69 -43
  9. {mycli-2.24.4 → mycli-2.28.0}/README.md +65 -37
  10. mycli-2.28.0/SPONSORS.md +1 -0
  11. {mycli-2.24.4 → mycli-2.28.0}/changelog.md +295 -159
  12. mycli-2.28.0/doc/cookbook.md +71 -0
  13. mycli-2.24.4/doc/key_bindings.rst → mycli-2.28.0/doc/key_bindings.md +24 -44
  14. mycli-2.28.0/doc/known_bugs.md +61 -0
  15. mycli-2.28.0/doc/screenshots/polars_describe.png +0 -0
  16. mycli-2.28.0/doc/screenshots/polars_group_by.png +0 -0
  17. mycli-2.28.0/doc/screenshots/polars_histogram.png +0 -0
  18. mycli-2.28.0/doc/screenshots/polars_pivot.png +0 -0
  19. {mycli-2.24.4 → mycli-2.28.0}/doc/transforms.md +30 -12
  20. {mycli-2.24.4 → mycli-2.28.0}/docker/resources/test_db-1.0.7.tar.gz +1 -1
  21. mycli-2.28.0/docker/resources/test_db_license.md +18 -0
  22. {mycli-2.24.4 → mycli-2.28.0}/mycli/TIPS +2 -0
  23. {mycli-2.24.4 → mycli-2.28.0}/mycli/boundary_tunnel.py +3 -7
  24. {mycli-2.24.4 → mycli-2.28.0}/mycli/client_connection.py +9 -26
  25. {mycli-2.24.4 → mycli-2.28.0}/mycli/constants.py +21 -0
  26. {mycli-2.24.4 → mycli-2.28.0}/mycli/key_bindings.py +21 -3
  27. mycli-2.28.0/mycli/keyring_utils.py +34 -0
  28. mycli-2.28.0/mycli/macos_keychain.py +80 -0
  29. {mycli-2.24.4 → mycli-2.28.0}/mycli/main_modes/checkup.py +3 -3
  30. {mycli-2.24.4 → mycli-2.28.0}/mycli/main_modes/repl.py +96 -49
  31. {mycli-2.24.4 → mycli-2.28.0}/mycli/myclirc +6 -0
  32. {mycli-2.24.4 → mycli-2.28.0}/mycli/output.py +19 -1
  33. {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/completion_engine.py +68 -1
  34. mycli-2.28.0/mycli/packages/fzf.py +78 -0
  35. {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/hybrid_redirection.py +75 -27
  36. {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/key_binding_utils.py +9 -0
  37. {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/polars_completion.py +3 -0
  38. {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/polars_transform.py +36 -1
  39. mycli-2.24.4/mycli/packages/ptoolkit/fzf.py → mycli-2.28.0/mycli/packages/ptoolkit/fzf_history.py +5 -15
  40. {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/special/__init__.py +0 -8
  41. {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/special/dbcommands.py +1 -1
  42. {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/special/iocommands.py +110 -26
  43. {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/sqlresult.py +9 -1
  44. mycli-2.28.0/mycli/query_runner.py +370 -0
  45. {mycli-2.24.4 → mycli-2.28.0}/mycli/sqlcompleter.py +24 -1
  46. {mycli-2.24.4 → mycli-2.28.0}/mycli/sqlexecute.py +73 -25
  47. {mycli-2.24.4 → mycli-2.28.0/mycli.egg-info}/PKG-INFO +69 -43
  48. {mycli-2.24.4 → mycli-2.28.0}/mycli.egg-info/SOURCES.txt +20 -6
  49. {mycli-2.24.4 → mycli-2.28.0}/mycli.egg-info/requires.txt +1 -2
  50. {mycli-2.24.4 → mycli-2.28.0}/mycli.egg-info/scm_file_list.json +20 -6
  51. mycli-2.28.0/mycli.egg-info/scm_version.json +8 -0
  52. {mycli-2.24.4 → mycli-2.28.0}/pyproject.toml +9 -7
  53. {mycli-2.24.4 → mycli-2.28.0}/test/features/basic_commands.feature +2 -2
  54. {mycli-2.24.4 → mycli-2.28.0}/test/features/iocommands.feature +3 -3
  55. {mycli-2.24.4 → mycli-2.28.0}/test/features/steps/basic_commands.py +4 -4
  56. {mycli-2.24.4 → mycli-2.28.0}/test/features/steps/iocommands.py +1 -1
  57. {mycli-2.24.4 → mycli-2.28.0}/test/features/steps/named_queries.py +17 -17
  58. {mycli-2.24.4 → mycli-2.28.0}/test/myclirc +6 -0
  59. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_boundary_tunnel.py +73 -70
  60. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_checkup.py +2 -2
  61. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_client.py +15 -3
  62. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_client_commands.py +1 -1
  63. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_client_connection.py +50 -17
  64. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_completion_engine.py +128 -23
  65. mycli-2.28.0/test/pytests/test_fzf.py +126 -0
  66. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_hybrid_redirection.py +74 -0
  67. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_key_binding_utils.py +33 -0
  68. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_key_bindings.py +63 -2
  69. mycli-2.28.0/test/pytests/test_keyring_utils.py +105 -0
  70. mycli-2.28.0/test/pytests/test_macos_keychain.py +160 -0
  71. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_main.py +6 -6
  72. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_main_modes_repl.py +403 -23
  73. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_output.py +121 -1
  74. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_polars_completion.py +5 -0
  75. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_polars_transform.py +80 -0
  76. mycli-2.24.4/test/pytests/test_ptoolkit_fzf.py → mycli-2.28.0/test/pytests/test_ptoolkit_fzf_history.py +35 -37
  77. mycli-2.28.0/test/pytests/test_query_runner.py +983 -0
  78. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_smart_completion_public_schema_only.py +104 -18
  79. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_special_dbcommands.py +7 -12
  80. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_special_init.py +1 -1
  81. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_special_iocommands.py +321 -38
  82. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_special_llm.py +20 -20
  83. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_special_main.py +12 -12
  84. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_sql_utils.py +8 -8
  85. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_sqlcompleter.py +97 -0
  86. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_sqlexecute.py +288 -14
  87. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_sqlresult.py +24 -0
  88. {mycli-2.24.4 → mycli-2.28.0}/test/utils.py +13 -1
  89. mycli-2.24.4/AGENTS.md +0 -141
  90. mycli-2.24.4/AUTHORS.rst +0 -3
  91. mycli-2.24.4/CONTRIBUTING.md +0 -118
  92. mycli-2.24.4/SPONSORS.rst +0 -3
  93. mycli-2.24.4/doc/screenshots/total_histogram.png +0 -0
  94. mycli-2.24.4/mycli.egg-info/scm_version.json +0 -8
  95. {mycli-2.24.4 → mycli-2.28.0}/.git-blame-ignore-revs +0 -0
  96. {mycli-2.24.4 → mycli-2.28.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  97. {mycli-2.24.4 → mycli-2.28.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  98. {mycli-2.24.4 → mycli-2.28.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  99. {mycli-2.24.4 → mycli-2.28.0}/.github/workflows/lint.yml +0 -0
  100. {mycli-2.24.4 → mycli-2.28.0}/.gitignore +0 -0
  101. {mycli-2.24.4 → mycli-2.28.0}/LICENSE.txt +0 -0
  102. {mycli-2.24.4 → mycli-2.28.0}/MANIFEST.in +0 -0
  103. {mycli-2.24.4 → mycli-2.28.0}/doc/llm.md +0 -0
  104. {mycli-2.24.4 → mycli-2.28.0}/doc/screenshots/main.gif +0 -0
  105. {mycli-2.24.4 → mycli-2.28.0}/doc/screenshots/tables.png +0 -0
  106. {mycli-2.24.4 → mycli-2.28.0}/docker/Dockerfile +0 -0
  107. {mycli-2.24.4 → mycli-2.28.0}/mycli/AUTHORS +0 -0
  108. {mycli-2.24.4 → mycli-2.28.0}/mycli/SPONSORS +0 -0
  109. {mycli-2.24.4 → mycli-2.28.0}/mycli/__init__.py +0 -0
  110. {mycli-2.24.4 → mycli-2.28.0}/mycli/app_state.py +0 -0
  111. {mycli-2.24.4 → mycli-2.28.0}/mycli/cli_runner.py +0 -0
  112. {mycli-2.24.4 → mycli-2.28.0}/mycli/clibuffer.py +0 -0
  113. {mycli-2.24.4 → mycli-2.28.0}/mycli/client.py +0 -0
  114. {mycli-2.24.4 → mycli-2.28.0}/mycli/client_commands.py +0 -0
  115. {mycli-2.24.4 → mycli-2.28.0}/mycli/client_query.py +0 -0
  116. {mycli-2.24.4 → mycli-2.28.0}/mycli/clistyle.py +0 -0
  117. {mycli-2.24.4 → mycli-2.28.0}/mycli/clitoolbar.py +0 -0
  118. {mycli-2.24.4 → mycli-2.28.0}/mycli/compat.py +0 -0
  119. {mycli-2.24.4 → mycli-2.28.0}/mycli/completion_refresher.py +0 -0
  120. {mycli-2.24.4 → mycli-2.28.0}/mycli/config.py +0 -0
  121. {mycli-2.24.4 → mycli-2.28.0}/mycli/kubectl_tunnel.py +0 -0
  122. {mycli-2.24.4 → mycli-2.28.0}/mycli/lexer.py +0 -0
  123. {mycli-2.24.4 → mycli-2.28.0}/mycli/main.py +0 -0
  124. {mycli-2.24.4 → mycli-2.28.0}/mycli/main_modes/batch.py +0 -0
  125. {mycli-2.24.4 → mycli-2.28.0}/mycli/main_modes/completions.py +0 -0
  126. {mycli-2.24.4 → mycli-2.28.0}/mycli/main_modes/execute.py +0 -0
  127. {mycli-2.24.4 → mycli-2.28.0}/mycli/main_modes/list_dsn.py +0 -0
  128. {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/__init__.py +0 -0
  129. {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/batch_utils.py +0 -0
  130. {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/cli_utils.py +0 -0
  131. {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/filepaths.py +0 -0
  132. {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/interactive_utils.py +0 -0
  133. {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/ptoolkit/__init__.py +0 -0
  134. {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/ptoolkit/history.py +0 -0
  135. {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/ptoolkit/utils.py +0 -0
  136. {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/special/delimitercommand.py +0 -0
  137. {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/special/dsn_aliases.py +0 -0
  138. {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/special/favoritequeries.py +0 -0
  139. {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/special/llm.py +0 -0
  140. {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/special/main.py +0 -0
  141. {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/special/source.py +0 -0
  142. {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/special/utils.py +0 -0
  143. {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/sql_utils.py +0 -0
  144. {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/string_utils.py +0 -0
  145. {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/tabular_output/__init__.py +0 -0
  146. {mycli-2.24.4 → mycli-2.28.0}/mycli/packages/tabular_output/sql_format.py +0 -0
  147. {mycli-2.24.4 → mycli-2.28.0}/mycli/password_sources.py +0 -0
  148. {mycli-2.24.4 → mycli-2.28.0}/mycli/resources/completions/bash/mycli +0 -0
  149. {mycli-2.24.4 → mycli-2.28.0}/mycli/resources/completions/fish/mycli.fish +0 -0
  150. {mycli-2.24.4 → mycli-2.28.0}/mycli/resources/completions/zsh/_mycli +0 -0
  151. {mycli-2.24.4 → mycli-2.28.0}/mycli/schema_prefetcher.py +0 -0
  152. {mycli-2.24.4 → mycli-2.28.0}/mycli/ssh_tunnel.py +0 -0
  153. {mycli-2.24.4 → mycli-2.28.0}/mycli/types.py +0 -0
  154. {mycli-2.24.4 → mycli-2.28.0}/mycli/vault.py +0 -0
  155. {mycli-2.24.4 → mycli-2.28.0}/mycli.egg-info/dependency_links.txt +0 -0
  156. {mycli-2.24.4 → mycli-2.28.0}/mycli.egg-info/entry_points.txt +0 -0
  157. {mycli-2.24.4 → mycli-2.28.0}/mycli.egg-info/top_level.txt +0 -0
  158. {mycli-2.24.4 → mycli-2.28.0}/setup.cfg +0 -0
  159. {mycli-2.24.4 → mycli-2.28.0}/test/__init__.py +0 -0
  160. {mycli-2.24.4 → mycli-2.28.0}/test/features/__init__.py +0 -0
  161. {mycli-2.24.4 → mycli-2.28.0}/test/features/auto_vertical.feature +0 -0
  162. {mycli-2.24.4 → mycli-2.28.0}/test/features/connection.feature +0 -0
  163. {mycli-2.24.4 → mycli-2.28.0}/test/features/crud_database.feature +0 -0
  164. {mycli-2.24.4 → mycli-2.28.0}/test/features/crud_table.feature +0 -0
  165. {mycli-2.24.4 → mycli-2.28.0}/test/features/db_utils.py +0 -0
  166. {mycli-2.24.4 → mycli-2.28.0}/test/features/environment.py +0 -0
  167. {mycli-2.24.4 → mycli-2.28.0}/test/features/fixture_data/help_commands.txt +0 -0
  168. {mycli-2.24.4 → mycli-2.28.0}/test/features/fixture_utils.py +0 -0
  169. {mycli-2.24.4 → mycli-2.28.0}/test/features/named_queries.feature +0 -0
  170. {mycli-2.24.4 → mycli-2.28.0}/test/features/specials.feature +0 -0
  171. {mycli-2.24.4 → mycli-2.28.0}/test/features/steps/__init__.py +0 -0
  172. {mycli-2.24.4 → mycli-2.28.0}/test/features/steps/auto_vertical.py +0 -0
  173. {mycli-2.24.4 → mycli-2.28.0}/test/features/steps/connection.py +0 -0
  174. {mycli-2.24.4 → mycli-2.28.0}/test/features/steps/crud_database.py +0 -0
  175. {mycli-2.24.4 → mycli-2.28.0}/test/features/steps/crud_table.py +0 -0
  176. {mycli-2.24.4 → mycli-2.28.0}/test/features/steps/specials.py +0 -0
  177. {mycli-2.24.4 → mycli-2.28.0}/test/features/steps/utils.py +0 -0
  178. {mycli-2.24.4 → mycli-2.28.0}/test/features/steps/wrappers.py +0 -0
  179. {mycli-2.24.4 → mycli-2.28.0}/test/features/wrappager.py +0 -0
  180. {mycli-2.24.4 → mycli-2.28.0}/test/mylogin.cnf +0 -0
  181. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/conftest.py +0 -0
  182. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_app_state.py +0 -0
  183. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_bash_completion.py +0 -0
  184. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_batch_utils.py +0 -0
  185. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_cli_runner.py +0 -0
  186. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_cli_utils.py +0 -0
  187. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_clibuffer.py +0 -0
  188. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_client_query.py +0 -0
  189. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_clistyle.py +0 -0
  190. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_clitoolbar.py +0 -0
  191. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_completer_use_switch.py +0 -0
  192. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_completion_refresher.py +0 -0
  193. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_config.py +0 -0
  194. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_delimitercommand.py +0 -0
  195. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_dsn_aliases.py +0 -0
  196. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_favoritequeries.py +0 -0
  197. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_filepaths.py +0 -0
  198. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_fish_completion.py +0 -0
  199. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_interactive_utils.py +0 -0
  200. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_kubectl_tunnel.py +0 -0
  201. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_main_modes_batch.py +0 -0
  202. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_main_modes_execute.py +0 -0
  203. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_main_modes_list_dsn.py +0 -0
  204. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_naive_completion.py +0 -0
  205. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_password_sources.py +0 -0
  206. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_ptoolkit_history.py +0 -0
  207. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_ptoolkit_utils.py +0 -0
  208. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_schema_prefetcher.py +0 -0
  209. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_special_source.py +0 -0
  210. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_special_utils.py +0 -0
  211. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_ssh_tunnel.py +0 -0
  212. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_string_utils.py +0 -0
  213. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_tabular_output.py +0 -0
  214. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_vault.py +0 -0
  215. {mycli-2.24.4 → mycli-2.28.0}/test/pytests/test_zsh_completion.py +0 -0
@@ -1,6 +1,8 @@
1
1
  version: 2
2
2
  updates:
3
3
  - package-ecosystem: "github-actions"
4
+ cooldown:
5
+ default-days: 7
4
6
  directory: "/"
5
7
  schedule:
6
8
  interval: "daily"
@@ -19,12 +19,12 @@ jobs:
19
19
  strategy:
20
20
  fail-fast: false
21
21
  matrix:
22
- python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
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@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
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 --all-extras -p ${{ matrix.python-version }}
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
- uv run tox -e py${{ matrix.python-version }}
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@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
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 --all-extras -p ${{ matrix.python-version }}
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
- uv run tox -e py${{ matrix.python-version }}
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@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
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 --all-extras -p ${{ matrix.python-version }}
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@62da9377d83991fce27b6ed2a397d3306121e41d # v1.53.1
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 --all-extras --python 3.14
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@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
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
- uv run tox -e py3.14
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 Python Package
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.10", "3.11", "3.12", "3.13", "3.14"]
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@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
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 --all-extras -p ${{ matrix.python-version }}
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
- uv run tox -e py${{ matrix.python-version }}
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@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
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 --all-extras -p ${{ matrix.python-version }}
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
- uv run tox -e py${{ matrix.python-version }}
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@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
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 --all-extras -p ${{ matrix.python-version }}
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@62da9377d83991fce27b6ed2a397d3306121e41d # v1.53.1
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 --all-extras --python 3.14
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@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
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 --all-extras -p 3.14
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@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
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@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
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 --all-extras
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`.
@@ -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".