kodit 0.2.7__tar.gz → 0.2.8__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.

Potentially problematic release.


This version of kodit might be problematic. Click here for more details.

Files changed (192) hide show
  1. {kodit-0.2.7 → kodit-0.2.8}/PKG-INFO +1 -1
  2. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/_version.py +2 -2
  3. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/cloning/git/working_copy.py +5 -2
  4. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/cloning/git/working_copy_test.py +62 -27
  5. {kodit-0.2.7 → kodit-0.2.8}/.cursor/rules/kodit.mdc +0 -0
  6. {kodit-0.2.7 → kodit-0.2.8}/.dockerignore +0 -0
  7. {kodit-0.2.7 → kodit-0.2.8}/.github/CODE_OF_CONDUCT.md +0 -0
  8. {kodit-0.2.7 → kodit-0.2.8}/.github/CONTRIBUTING.md +0 -0
  9. {kodit-0.2.7 → kodit-0.2.8}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  10. {kodit-0.2.7 → kodit-0.2.8}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  11. {kodit-0.2.7 → kodit-0.2.8}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  12. {kodit-0.2.7 → kodit-0.2.8}/.github/dependabot.yml +0 -0
  13. {kodit-0.2.7 → kodit-0.2.8}/.github/workflows/docker.yaml +0 -0
  14. {kodit-0.2.7 → kodit-0.2.8}/.github/workflows/docs.yaml +0 -0
  15. {kodit-0.2.7 → kodit-0.2.8}/.github/workflows/pull_request.yaml +0 -0
  16. {kodit-0.2.7 → kodit-0.2.8}/.github/workflows/pypi-test.yaml +0 -0
  17. {kodit-0.2.7 → kodit-0.2.8}/.github/workflows/pypi.yaml +0 -0
  18. {kodit-0.2.7 → kodit-0.2.8}/.github/workflows/test.yaml +0 -0
  19. {kodit-0.2.7 → kodit-0.2.8}/.gitignore +0 -0
  20. {kodit-0.2.7 → kodit-0.2.8}/.python-version +0 -0
  21. {kodit-0.2.7 → kodit-0.2.8}/.vscode/launch.json +0 -0
  22. {kodit-0.2.7 → kodit-0.2.8}/.vscode/settings.json +0 -0
  23. {kodit-0.2.7 → kodit-0.2.8}/Dockerfile +0 -0
  24. {kodit-0.2.7 → kodit-0.2.8}/LICENSE +0 -0
  25. {kodit-0.2.7 → kodit-0.2.8}/README.md +0 -0
  26. {kodit-0.2.7 → kodit-0.2.8}/alembic.ini +0 -0
  27. {kodit-0.2.7 → kodit-0.2.8}/docs/_index.md +0 -0
  28. {kodit-0.2.7 → kodit-0.2.8}/docs/demos/_index.md +0 -0
  29. {kodit-0.2.7 → kodit-0.2.8}/docs/demos/go-simple-microservice/index.md +0 -0
  30. {kodit-0.2.7 → kodit-0.2.8}/docs/demos/knock-knock-auth/index.md +0 -0
  31. {kodit-0.2.7 → kodit-0.2.8}/docs/developer/index.md +0 -0
  32. {kodit-0.2.7 → kodit-0.2.8}/docs/getting-started/_index.md +0 -0
  33. {kodit-0.2.7 → kodit-0.2.8}/docs/getting-started/installation/index.md +0 -0
  34. {kodit-0.2.7 → kodit-0.2.8}/docs/getting-started/integration/index.md +0 -0
  35. {kodit-0.2.7 → kodit-0.2.8}/docs/getting-started/quick-start/index.md +0 -0
  36. {kodit-0.2.7 → kodit-0.2.8}/docs/reference/_index.md +0 -0
  37. {kodit-0.2.7 → kodit-0.2.8}/docs/reference/configuration/index.md +0 -0
  38. {kodit-0.2.7 → kodit-0.2.8}/docs/reference/deployment/docker-compose.yaml +0 -0
  39. {kodit-0.2.7 → kodit-0.2.8}/docs/reference/deployment/index.md +0 -0
  40. {kodit-0.2.7 → kodit-0.2.8}/docs/reference/deployment/kubernetes.yaml +0 -0
  41. {kodit-0.2.7 → kodit-0.2.8}/docs/reference/indexing/index.md +0 -0
  42. {kodit-0.2.7 → kodit-0.2.8}/docs/reference/telemetry/index.md +0 -0
  43. {kodit-0.2.7 → kodit-0.2.8}/pyproject.toml +0 -0
  44. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/.gitignore +0 -0
  45. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/__init__.py +0 -0
  46. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/app.py +0 -0
  47. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/application/__init__.py +0 -0
  48. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/application/commands/__init__.py +0 -0
  49. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/application/commands/snippet_commands.py +0 -0
  50. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/application/services/__init__.py +0 -0
  51. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/application/services/indexing_application_service.py +0 -0
  52. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/application/services/snippet_application_service.py +0 -0
  53. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/cli.py +0 -0
  54. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/config.py +0 -0
  55. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/database.py +0 -0
  56. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/domain/__init__.py +0 -0
  57. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/domain/entities.py +0 -0
  58. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/domain/enums.py +0 -0
  59. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/domain/errors.py +0 -0
  60. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/domain/interfaces.py +0 -0
  61. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/domain/repositories.py +0 -0
  62. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/domain/services/__init__.py +0 -0
  63. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/domain/services/bm25_service.py +0 -0
  64. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/domain/services/embedding_service.py +0 -0
  65. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/domain/services/enrichment_service.py +0 -0
  66. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/domain/services/ignore_service.py +0 -0
  67. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/domain/services/indexing_service.py +0 -0
  68. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/domain/services/snippet_extraction_service.py +0 -0
  69. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/domain/services/source_service.py +0 -0
  70. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/domain/value_objects.py +0 -0
  71. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/__init__.py +0 -0
  72. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/bm25/__init__.py +0 -0
  73. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/bm25/bm25_factory.py +0 -0
  74. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/bm25/local_bm25_repository.py +0 -0
  75. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/bm25/vectorchord_bm25_repository.py +0 -0
  76. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/cloning/__init__.py +0 -0
  77. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/cloning/folder/__init__.py +0 -0
  78. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/cloning/folder/factory.py +0 -0
  79. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/cloning/folder/working_copy.py +0 -0
  80. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/cloning/git/__init__.py +0 -0
  81. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/cloning/git/factory.py +0 -0
  82. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/cloning/metadata.py +0 -0
  83. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/embedding/__init__.py +0 -0
  84. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/embedding/embedding_factory.py +0 -0
  85. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/embedding/embedding_providers/__init__.py +0 -0
  86. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/embedding/embedding_providers/batching.py +0 -0
  87. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/embedding/embedding_providers/hash_embedding_provider.py +0 -0
  88. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/embedding/embedding_providers/local_embedding_provider.py +0 -0
  89. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/embedding/embedding_providers/openai_embedding_provider.py +0 -0
  90. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/embedding/local_vector_search_repository.py +0 -0
  91. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/embedding/vectorchord_vector_search_repository.py +0 -0
  92. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/enrichment/__init__.py +0 -0
  93. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/enrichment/enrichment_factory.py +0 -0
  94. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/enrichment/legacy_enrichment_models.py +0 -0
  95. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/enrichment/local_enrichment_provider.py +0 -0
  96. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/enrichment/null_enrichment_provider.py +0 -0
  97. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/enrichment/openai_enrichment_provider.py +0 -0
  98. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/git/__init__.py +0 -0
  99. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/git/git_utils.py +0 -0
  100. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/ignore/__init__.py +0 -0
  101. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/ignore/ignore_pattern_provider.py +0 -0
  102. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/indexing/__init__.py +0 -0
  103. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/indexing/fusion_service.py +0 -0
  104. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/indexing/index_repository.py +0 -0
  105. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/indexing/indexing_factory.py +0 -0
  106. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/snippet_extraction/__init__.py +0 -0
  107. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/snippet_extraction/language_detection_service.py +0 -0
  108. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/snippet_extraction/languages/csharp.scm +0 -0
  109. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/snippet_extraction/languages/go.scm +0 -0
  110. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/snippet_extraction/languages/javascript.scm +0 -0
  111. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/snippet_extraction/languages/python.scm +0 -0
  112. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/snippet_extraction/languages/typescript.scm +0 -0
  113. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/snippet_extraction/snippet_extraction_factory.py +0 -0
  114. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/snippet_extraction/snippet_query_provider.py +0 -0
  115. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/snippet_extraction/tree_sitter_snippet_extractor.py +0 -0
  116. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/sqlalchemy/__init__.py +0 -0
  117. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/sqlalchemy/embedding_repository.py +0 -0
  118. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/sqlalchemy/file_repository.py +0 -0
  119. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/sqlalchemy/repository.py +0 -0
  120. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/sqlalchemy/snippet_repository.py +0 -0
  121. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/ui/__init__.py +0 -0
  122. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/ui/progress.py +0 -0
  123. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/infrastructure/ui/spinner.py +0 -0
  124. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/log.py +0 -0
  125. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/mcp.py +0 -0
  126. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/middleware.py +0 -0
  127. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/migrations/README +0 -0
  128. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/migrations/__init__.py +0 -0
  129. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/migrations/env.py +0 -0
  130. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/migrations/script.py.mako +0 -0
  131. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/migrations/versions/7c3bbc2ab32b_add_embeddings_table.py +0 -0
  132. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/migrations/versions/85155663351e_initial.py +0 -0
  133. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/migrations/versions/9e53ea8bb3b0_add_authors.py +0 -0
  134. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/migrations/versions/__init__.py +0 -0
  135. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/migrations/versions/c3f5137d30f5_index_all_the_things.py +0 -0
  136. {kodit-0.2.7 → kodit-0.2.8}/src/kodit/reporting.py +0 -0
  137. {kodit-0.2.7 → kodit-0.2.8}/tests/__init__.py +0 -0
  138. {kodit-0.2.7 → kodit-0.2.8}/tests/conftest.py +0 -0
  139. {kodit-0.2.7 → kodit-0.2.8}/tests/docker-smoke.sh +0 -0
  140. {kodit-0.2.7 → kodit-0.2.8}/tests/experiments/cline-prompt-regression-tests/cline_prompt.txt +0 -0
  141. {kodit-0.2.7 → kodit-0.2.8}/tests/experiments/cline-prompt-regression-tests/cline_prompt_test.py +0 -0
  142. {kodit-0.2.7 → kodit-0.2.8}/tests/experiments/embedding.py +0 -0
  143. {kodit-0.2.7 → kodit-0.2.8}/tests/experiments/similarity_test.py +0 -0
  144. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/__init__.py +0 -0
  145. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/application/__init__.py +0 -0
  146. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/application/indexing_application_service_test.py +0 -0
  147. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/application/snippet_application_service_test.py +0 -0
  148. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/cli_test.py +0 -0
  149. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/domain/__init__.py +0 -0
  150. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/domain/bm25_domain_service_test.py +0 -0
  151. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/domain/enrichment_domain_service_test.py +0 -0
  152. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/domain/snippet_extraction_domain_service_test.py +0 -0
  153. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/domain/test_embedding_service.py +0 -0
  154. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/domain/test_models.py +0 -0
  155. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/e2e.py +0 -0
  156. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/__init__.py +0 -0
  157. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/cloning/git/factory_test.py +0 -0
  158. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/embedding/__init__.py +0 -0
  159. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/embedding/embedding_factory_test.py +0 -0
  160. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/embedding/embedding_provider/test_hash_embedding_provider.py +0 -0
  161. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/embedding/embedding_provider/test_local_embedding_provider.py +0 -0
  162. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/embedding/embedding_provider/test_openai_embedding_provider.py +0 -0
  163. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/embedding/test_batching.py +0 -0
  164. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/embedding/test_embedding_integration.py +0 -0
  165. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/embedding/test_local_vector_search_repository.py +0 -0
  166. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/embedding/test_vectorchord_vector_search_repository.py +0 -0
  167. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/enrichment/__init__.py +0 -0
  168. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/enrichment/enrichment_provider/__init__.py +0 -0
  169. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/enrichment/enrichment_provider/test_local_enrichment_provider.py +0 -0
  170. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/enrichment/enrichment_provider/test_null_enrichment_provider.py +0 -0
  171. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/enrichment/enrichment_provider/test_openai_enrichment_provider.py +0 -0
  172. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/enrichment/test_enrichment_factory.py +0 -0
  173. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/enrichment/test_enrichment_integration.py +0 -0
  174. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/git/test_git_utils.py +0 -0
  175. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/indexing/__init__.py +0 -0
  176. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/indexing/indexing_repository_test.py +0 -0
  177. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/snippets/__init__.py +0 -0
  178. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/snippets/csharp.cs +0 -0
  179. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/snippets/golang.go +0 -0
  180. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/snippets/javascript.js +0 -0
  181. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/snippets/knock-knock-server.py +0 -0
  182. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/snippets/python.py +0 -0
  183. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/snippets/typescript.tsx +0 -0
  184. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/source/__init__.py +0 -0
  185. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/source/source_service_test.py +0 -0
  186. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/infrastructure/sqlalchemy/test_embedding_repository.py +0 -0
  187. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/log_test.py +0 -0
  188. {kodit-0.2.7 → kodit-0.2.8}/tests/kodit/mcp_test.py +0 -0
  189. {kodit-0.2.7 → kodit-0.2.8}/tests/performance/similarity.py +0 -0
  190. {kodit-0.2.7 → kodit-0.2.8}/tests/smoke.sh +0 -0
  191. {kodit-0.2.7 → kodit-0.2.8}/tests/vectorchord-smoke.sh +0 -0
  192. {kodit-0.2.7 → kodit-0.2.8}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kodit
3
- Version: 0.2.7
3
+ Version: 0.2.8
4
4
  Summary: Code indexing for better AI code generation
5
5
  Project-URL: Homepage, https://docs.helixml.tech/kodit/
6
6
  Project-URL: Documentation, https://docs.helixml.tech/kodit/
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '0.2.7'
21
- __version_tuple__ = version_tuple = (0, 2, 7)
20
+ __version__ = version = '0.2.8'
21
+ __version_tuple__ = version_tuple = (0, 2, 8)
@@ -1,5 +1,6 @@
1
1
  """Working copy provider for git-based sources."""
2
2
 
3
+ import hashlib
3
4
  from pathlib import Path
4
5
 
5
6
  import git
@@ -21,8 +22,10 @@ class GitWorkingCopyProvider:
21
22
  # Sanitize the URI for directory name to prevent credential leaks
22
23
  sanitized_uri = sanitize_git_url(uri)
23
24
 
24
- # Create a unique directory name for the clone using the sanitized URI
25
- clone_path = self.clone_dir / sanitized_uri.replace("/", "_").replace(":", "_")
25
+ # Use a repeatable, short sha256 hash of the sanitized URI for the directory
26
+ dir_hash = hashlib.sha256(sanitized_uri.encode("utf-8")).hexdigest()[:16]
27
+ dir_name = f"repo-{dir_hash}"
28
+ clone_path = self.clone_dir / dir_name
26
29
  clone_path.mkdir(parents=True, exist_ok=True)
27
30
 
28
31
  try:
@@ -1,5 +1,6 @@
1
1
  """Tests for the git working copy provider module."""
2
2
 
3
+ import hashlib
3
4
  from pathlib import Path
4
5
  from unittest.mock import patch
5
6
 
@@ -7,6 +8,7 @@ import git
7
8
  import pytest
8
9
 
9
10
  from kodit.infrastructure.cloning.git.working_copy import GitWorkingCopyProvider
11
+ from kodit.infrastructure.git.git_utils import sanitize_git_url
10
12
 
11
13
 
12
14
  @pytest.fixture
@@ -15,6 +17,13 @@ def working_copy(tmp_path: Path) -> GitWorkingCopyProvider:
15
17
  return GitWorkingCopyProvider(tmp_path)
16
18
 
17
19
 
20
+ def get_expected_directory_name(uri: str) -> str:
21
+ """Get the expected directory name for a given URI."""
22
+ sanitized_uri = sanitize_git_url(uri)
23
+ dir_hash = hashlib.sha256(sanitized_uri.encode("utf-8")).hexdigest()[:16]
24
+ return f"repo-{dir_hash}"
25
+
26
+
18
27
  @pytest.mark.asyncio
19
28
  async def test_prepare_should_not_leak_credentials_in_directory_name(
20
29
  working_copy: GitWorkingCopyProvider, tmp_path: Path
@@ -28,14 +37,7 @@ async def test_prepare_should_not_leak_credentials_in_directory_name(
28
37
  "https://user:pass@gitlab.com/user/repo.git",
29
38
  ]
30
39
 
31
- expected_safe_directories = [
32
- "https___dev.azure.com_winderai_private-test__git_private-test",
33
- "https___dev.azure.com_winderai_private-test__git_private-test",
34
- "https___github.com_username_repo.git",
35
- "https___gitlab.com_user_repo.git",
36
- ]
37
-
38
- for i, pat_url in enumerate(pat_urls):
40
+ for pat_url in pat_urls:
39
41
  # Mock git.Repo.clone_from to avoid actual cloning
40
42
  with patch("git.Repo.clone_from") as mock_clone:
41
43
  # Call the prepare method
@@ -43,8 +45,9 @@ async def test_prepare_should_not_leak_credentials_in_directory_name(
43
45
 
44
46
  # Verify that the directory name doesn't contain credentials
45
47
  directory_name = result_path.name
46
- assert directory_name == expected_safe_directories[i], (
47
- f"Directory name should not contain credentials: {directory_name}"
48
+ expected_name = get_expected_directory_name(pat_url)
49
+ assert directory_name == expected_name, (
50
+ f"Directory name should match expected hash: {directory_name}"
48
51
  )
49
52
 
50
53
  # Verify that the directory name doesn't contain the PAT/token
@@ -63,6 +66,47 @@ async def test_prepare_should_not_leak_credentials_in_directory_name(
63
66
  assert result_path.is_dir()
64
67
 
65
68
 
69
+ @pytest.mark.asyncio
70
+ async def test_prepare_should_not_exceed_windows_path_limit(
71
+ working_copy: GitWorkingCopyProvider, tmp_path: Path
72
+ ) -> None:
73
+ """Test that directory names never exceed Windows 256 character path limit."""
74
+ # Create a URL that, when sanitized and converted to directory name, would exceed 256 characters
75
+ # This URL is designed to be extremely long to trigger the Windows path limit issue
76
+ long_url = (
77
+ "https://extremely-long-domain-name-that-will-definitely-exceed-windows-path-limits-and-cause-issues.com/"
78
+ "very-long-organization-name-with-many-words-and-descriptive-text/"
79
+ "very-long-project-name-with-additional-descriptive-text/"
80
+ "_git/"
81
+ "extremely-long-repository-name-with-many-subdirectories-and-deeply-nested-paths-that-cause-issues-on-windows-systems-and-this-is-just-the-beginning-of-the-very-long-name-that-continues-for-many-more-characters-to-ensure-we-hit-the-limit"
82
+ )
83
+
84
+ # Mock git.Repo.clone_from to avoid actual cloning
85
+ with patch("git.Repo.clone_from") as mock_clone:
86
+ # Call the prepare method
87
+ result_path = await working_copy.prepare(long_url)
88
+
89
+ # Get the directory name that would be created
90
+ directory_name = result_path.name
91
+
92
+ # Print the actual directory name and its length for debugging
93
+ print(f"Directory name: {directory_name}")
94
+ print(f"Directory name length: {len(directory_name)}")
95
+
96
+ # This test should PASS because the directory name is now a short hash
97
+ # The directory name should be in format "repo-<16-char-hash>" (21 characters total)
98
+ assert len(directory_name) <= 256, (
99
+ f"Directory name exceeds Windows 256 character path limit: "
100
+ f"{len(directory_name)} characters: {directory_name}"
101
+ )
102
+ assert directory_name.startswith("repo-"), (
103
+ f"Directory name should start with 'repo-': {directory_name}"
104
+ )
105
+ assert len(directory_name) == 21, (
106
+ f"Directory name should be exactly 21 characters: {directory_name}"
107
+ )
108
+
109
+
66
110
  @pytest.mark.asyncio
67
111
  async def test_prepare_clean_urls_should_work_normally(
68
112
  working_copy: GitWorkingCopyProvider, tmp_path: Path
@@ -74,13 +118,7 @@ async def test_prepare_clean_urls_should_work_normally(
74
118
  "git@github.com:username/repo.git",
75
119
  ]
76
120
 
77
- expected_directories = [
78
- "https___github.com_username_repo.git",
79
- "https___dev.azure.com_winderai_public-test__git_public-test",
80
- "git@github.com_username_repo.git",
81
- ]
82
-
83
- for i, clean_url in enumerate(clean_urls):
121
+ for clean_url in clean_urls:
84
122
  # Mock git.Repo.clone_from to avoid actual cloning
85
123
  with patch("git.Repo.clone_from") as mock_clone:
86
124
  # Call the prepare method
@@ -88,8 +126,9 @@ async def test_prepare_clean_urls_should_work_normally(
88
126
 
89
127
  # Verify that the directory name is as expected
90
128
  directory_name = result_path.name
91
- assert directory_name == expected_directories[i], (
92
- f"Directory name should match expected: {directory_name}"
129
+ expected_name = get_expected_directory_name(clean_url)
130
+ assert directory_name == expected_name, (
131
+ f"Directory name should match expected hash: {directory_name}"
93
132
  )
94
133
 
95
134
  # Verify that the directory was created
@@ -107,12 +146,7 @@ async def test_prepare_ssh_urls_should_work_normally(
107
146
  "ssh://git@github.com:2222/username/repo.git",
108
147
  ]
109
148
 
110
- expected_directories = [
111
- "git@github.com_username_repo.git",
112
- "ssh___git@github.com_2222_username_repo.git",
113
- ]
114
-
115
- for i, ssh_url in enumerate(ssh_urls):
149
+ for ssh_url in ssh_urls:
116
150
  # Mock git.Repo.clone_from to avoid actual cloning
117
151
  with patch("git.Repo.clone_from") as mock_clone:
118
152
  # Call the prepare method
@@ -120,8 +154,9 @@ async def test_prepare_ssh_urls_should_work_normally(
120
154
 
121
155
  # Verify that the directory name is as expected
122
156
  directory_name = result_path.name
123
- assert directory_name == expected_directories[i], (
124
- f"Directory name should match expected: {directory_name}"
157
+ expected_name = get_expected_directory_name(ssh_url)
158
+ assert directory_name == expected_name, (
159
+ f"Directory name should match expected hash: {directory_name}"
125
160
  )
126
161
 
127
162
  # Verify that the directory was created
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes