dirsql 0.4.96__tar.gz → 0.4.97__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 (395) hide show
  1. {dirsql-0.4.96 → dirsql-0.4.97}/Cargo.lock +2 -2
  2. {dirsql-0.4.96 → dirsql-0.4.97}/PKG-INFO +1 -1
  3. {dirsql-0.4.96/packages/python → dirsql-0.4.97}/docs/reference/glob.md +13 -0
  4. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/Cargo.toml +1 -1
  5. dirsql-0.4.97/packages/python/changelog.d/2026-10-07-bracket-slash-literal.md +3 -0
  6. dirsql-0.4.97/packages/python/changelog.d/2026-10-07-dotdot-and-double-slashes.md +3 -0
  7. dirsql-0.4.97/packages/python/changelog.d/2026-10-07-fix-main-build.md +3 -0
  8. {dirsql-0.4.96/packages/rust → dirsql-0.4.97/packages/python}/docs/reference/glob.md +13 -0
  9. dirsql-0.4.97/packages/python/e2e-attestations/bot-1419-dotdot-slashes.json +7 -0
  10. dirsql-0.4.97/packages/python/e2e-attestations/bot-1420-bracket-slash.json +7 -0
  11. dirsql-0.4.97/packages/python/e2e-attestations/bot-1440-fix-main-build.json +7 -0
  12. dirsql-0.4.97/packages/python/migrations.d/2026-10-07-bracket-slash-literal.md +23 -0
  13. dirsql-0.4.97/packages/python/migrations.d/2026-10-07-dotdot-and-double-slashes.md +23 -0
  14. dirsql-0.4.97/packages/python/migrations.d/2026-10-07-fix-main-build.md +23 -0
  15. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/Cargo.toml +1 -1
  16. {dirsql-0.4.96 → dirsql-0.4.97/packages/rust}/docs/reference/glob.md +13 -0
  17. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/brace.rs +11 -2
  18. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/path_table.rs +54 -6
  19. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/scanner.rs +94 -20
  20. {dirsql-0.4.96 → dirsql-0.4.97}/Cargo.toml +0 -0
  21. {dirsql-0.4.96 → dirsql-0.4.97}/README.md +0 -0
  22. {dirsql-0.4.96 → dirsql-0.4.97}/dirsql/__init__.py +0 -0
  23. {dirsql-0.4.96 → dirsql-0.4.97}/dirsql/_async.py +0 -0
  24. {dirsql-0.4.96 → dirsql-0.4.97}/dirsql/_dirsql.pyi +0 -0
  25. {dirsql-0.4.96 → dirsql-0.4.97}/dirsql/cli/__init__.py +0 -0
  26. {dirsql-0.4.96 → dirsql-0.4.97}/dirsql/cli/discover_plugins/__init__.py +0 -0
  27. {dirsql-0.4.96 → dirsql-0.4.97}/dirsql/cli/discover_plugins/discovered_fragments.py +0 -0
  28. {dirsql-0.4.96 → dirsql-0.4.97}/dirsql/cli/discover_plugins/discovery_disabled.py +0 -0
  29. {dirsql-0.4.96 → dirsql-0.4.97}/dirsql/cli/discover_plugins/fragment_path.py +0 -0
  30. {dirsql-0.4.96 → dirsql-0.4.97}/dirsql/cli/discover_plugins/with_discovered_plugins.py +0 -0
  31. {dirsql-0.4.96 → dirsql-0.4.97}/dirsql/cli/main.py +0 -0
  32. {dirsql-0.4.96 → dirsql-0.4.97}/dirsql/cli/resolve_config_extensions.py +0 -0
  33. {dirsql-0.4.96 → dirsql-0.4.97}/dirsql/plan_entry_path.py +0 -0
  34. {dirsql-0.4.96 → dirsql-0.4.97}/dirsql/py.typed +0 -0
  35. {dirsql-0.4.96 → dirsql-0.4.97}/dirsql/read_config.py +0 -0
  36. {dirsql-0.4.96 → dirsql-0.4.97}/dirsql/resolve_configs_extension_specs.py +0 -0
  37. {dirsql-0.4.96 → dirsql-0.4.97}/dirsql/resolve_extension.py +0 -0
  38. {dirsql-0.4.96 → dirsql-0.4.97}/dirsql/resolve_package.py +0 -0
  39. {dirsql-0.4.96 → dirsql-0.4.97}/docs/.claude/CLAUDE.md +0 -0
  40. {dirsql-0.4.96 → dirsql-0.4.97}/docs/.vitepress/config.ts +0 -0
  41. {dirsql-0.4.96 → dirsql-0.4.97}/docs/.vitepress/theme/index.ts +0 -0
  42. {dirsql-0.4.96 → dirsql-0.4.97}/docs/.vitepress/theme/lang.ts +0 -0
  43. {dirsql-0.4.96 → dirsql-0.4.97}/docs/AGENTS.md +0 -0
  44. {dirsql-0.4.96 → dirsql-0.4.97}/docs/context/.gitattributes +0 -0
  45. {dirsql-0.4.96 → dirsql-0.4.97}/docs/context/recipes.md +0 -0
  46. {dirsql-0.4.96 → dirsql-0.4.97}/docs/context/troubleshooting.md +0 -0
  47. {dirsql-0.4.96 → dirsql-0.4.97}/docs/context/usage.md +0 -0
  48. {dirsql-0.4.96 → dirsql-0.4.97}/docs/explanation.md +0 -0
  49. {dirsql-0.4.96 → dirsql-0.4.97}/docs/getting-started.md +0 -0
  50. {dirsql-0.4.96 → dirsql-0.4.97}/docs/howto/agent-skill.md +0 -0
  51. {dirsql-0.4.96 → dirsql-0.4.97}/docs/howto/columns-from-paths.md +0 -0
  52. {dirsql-0.4.96 → dirsql-0.4.97}/docs/howto/define-tables.md +0 -0
  53. {dirsql-0.4.96 → dirsql-0.4.97}/docs/howto/embed.md +0 -0
  54. {dirsql-0.4.96 → dirsql-0.4.97}/docs/howto/extract-from-contents.md +0 -0
  55. {dirsql-0.4.96 → dirsql-0.4.97}/docs/howto/load-extension.md +0 -0
  56. {dirsql-0.4.96 → dirsql-0.4.97}/docs/howto/parse-files-into-columns.md +0 -0
  57. {dirsql-0.4.96 → dirsql-0.4.97}/docs/howto/persist.md +0 -0
  58. {dirsql-0.4.96 → dirsql-0.4.97}/docs/howto/query-json.md +0 -0
  59. {dirsql-0.4.96 → dirsql-0.4.97}/docs/howto/query-without-config.md +0 -0
  60. {dirsql-0.4.96 → dirsql-0.4.97}/docs/howto/react-to-changes.md +0 -0
  61. {dirsql-0.4.96 → dirsql-0.4.97}/docs/howto/search-by-meaning.md +0 -0
  62. {dirsql-0.4.96 → dirsql-0.4.97}/docs/howto/search-indexes.md +0 -0
  63. {dirsql-0.4.96 → dirsql-0.4.97}/docs/howto/skip-files.md +0 -0
  64. {dirsql-0.4.96 → dirsql-0.4.97}/docs/howto/write-a-plugin.md +0 -0
  65. {dirsql-0.4.96 → dirsql-0.4.97}/docs/index.md +0 -0
  66. {dirsql-0.4.96 → dirsql-0.4.97}/docs/package.json +0 -0
  67. {dirsql-0.4.96 → dirsql-0.4.97}/docs/plugins.md +0 -0
  68. {dirsql-0.4.96 → dirsql-0.4.97}/docs/pnpm-lock.yaml +0 -0
  69. {dirsql-0.4.96 → dirsql-0.4.97}/docs/pnpm-workspace.yaml +0 -0
  70. {dirsql-0.4.96 → dirsql-0.4.97}/docs/reference/cli.md +0 -0
  71. {dirsql-0.4.96 → dirsql-0.4.97}/docs/reference/columns.md +0 -0
  72. {dirsql-0.4.96 → dirsql-0.4.97}/docs/reference/config.md +0 -0
  73. {dirsql-0.4.96 → dirsql-0.4.97}/docs/reference/hooks.md +0 -0
  74. {dirsql-0.4.96 → dirsql-0.4.97}/docs/reference/http-api.md +0 -0
  75. {dirsql-0.4.96 → dirsql-0.4.97}/docs/reference/path-tables.md +0 -0
  76. {dirsql-0.4.96 → dirsql-0.4.97}/docs/reference/sdk.md +0 -0
  77. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/CHANGELOG.md +0 -0
  78. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/MIGRATIONS.md +0 -0
  79. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/README.md +0 -0
  80. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
  81. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-07-13-plugin-discovery.md +0 -0
  82. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-07-13-rename-extract-to-on-file.md +0 -0
  83. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-07-13-repeatable-config.md +0 -0
  84. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
  85. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-07-20-drop-implicit-files-table.md +0 -0
  86. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-07-21-remove-glob-captures.md +0 -0
  87. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-07-24-hookless-table-config-error.md +0 -0
  88. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-07-24-remove-stat-fact-injection.md +0 -0
  89. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-07-29-restore-python-310.md +0 -0
  90. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-08-02-release-profile.md +0 -0
  91. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-08-02-scan-failures.md +0 -0
  92. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-08-03-discovery-ext-resolution.md +0 -0
  93. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-08-03-manylinux-dynamic-binary.md +0 -0
  94. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-08-03-python-no-ignore.md +0 -0
  95. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-08-04-cast-lints.md +0 -0
  96. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-08-04-cli-in-process.md +0 -0
  97. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-08-20-curtaincall-dev-dependency.md +0 -0
  98. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-08-20-declared-table-name.md +0 -0
  99. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-09-04-config-paths-from-argv-module.md +0 -0
  100. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-09-05-config-extension-loader-split.md +0 -0
  101. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-09-05-resolve-config-extensions-split.md +0 -0
  102. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-09-05-resolve-extension-split.md +0 -0
  103. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-09-09-launcher-config-path-scan.md +0 -0
  104. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-09-17-extension-resolution-via-core.md +0 -0
  105. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-09-18-export-scan-failure.md +0 -0
  106. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-09-18-flatten-row-event-in-core.md +0 -0
  107. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-09-18-programmatic-extension-plan.md +0 -0
  108. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-09-20-sigint-ends-a-run-in-progress.md +0 -0
  109. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-09-24-query-rows-in-projection-order.md +0 -0
  110. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-10-02-readme-docs-host.md +0 -0
  111. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-10-03-one-glob-rule-for-config-globs.md +0 -0
  112. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-10-03-path-table-directory-one-level.md +0 -0
  113. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-10-04-path-table-dotfiles-hidden.md +0 -0
  114. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-10-05-brace-groups-follow-bash.md +0 -0
  115. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-10-05-cli-context.md +0 -0
  116. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-10-05-gitignore-requires-repo.md +0 -0
  117. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-10-05-path-table-node-modules-named.md +0 -0
  118. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-10-05-path-table-symlinks.md +0 -0
  119. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-10-05-path-table-trailing-slash.md +0 -0
  120. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-10-05-unbalanced-brackets-literal.md +0 -0
  121. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-10-06-config-braces.md +0 -0
  122. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-10-06-config-directory.md +0 -0
  123. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-10-06-config-dotnames.md +0 -0
  124. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-10-06-config-gitignore.md +0 -0
  125. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-10-06-config-globs-anchor-at-the-config.md +0 -0
  126. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-10-06-config-links.md +0 -0
  127. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-10-06-one-glob-compiler.md +0 -0
  128. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-10-06-plugin-no-default-records.md +0 -0
  129. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-10-06-watch-broadcast.md +0 -0
  130. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-10-06-zero-match-config-table-warning.md +0 -0
  131. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-10-07-glob-walks-node-modules.md +0 -0
  132. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/2026-10-07-persist-cache-outside-root.md +0 -0
  133. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/changelog.d/README.md +0 -0
  134. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/conftest.py +0 -0
  135. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/.claude/CLAUDE.md +0 -0
  136. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/.vitepress/config.ts +0 -0
  137. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/.vitepress/theme/index.ts +0 -0
  138. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
  139. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/AGENTS.md +0 -0
  140. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/context/.gitattributes +0 -0
  141. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/context/recipes.md +0 -0
  142. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/context/troubleshooting.md +0 -0
  143. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/context/usage.md +0 -0
  144. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/explanation.md +0 -0
  145. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/getting-started.md +0 -0
  146. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/howto/agent-skill.md +0 -0
  147. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/howto/columns-from-paths.md +0 -0
  148. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/howto/define-tables.md +0 -0
  149. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/howto/embed.md +0 -0
  150. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/howto/extract-from-contents.md +0 -0
  151. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/howto/load-extension.md +0 -0
  152. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/howto/parse-files-into-columns.md +0 -0
  153. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/howto/persist.md +0 -0
  154. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/howto/query-json.md +0 -0
  155. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/howto/query-without-config.md +0 -0
  156. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/howto/react-to-changes.md +0 -0
  157. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/howto/search-by-meaning.md +0 -0
  158. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/howto/search-indexes.md +0 -0
  159. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/howto/skip-files.md +0 -0
  160. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/howto/write-a-plugin.md +0 -0
  161. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/index.md +0 -0
  162. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/package.json +0 -0
  163. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/plugins.md +0 -0
  164. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/pnpm-lock.yaml +0 -0
  165. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/pnpm-workspace.yaml +0 -0
  166. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/reference/cli.md +0 -0
  167. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/reference/columns.md +0 -0
  168. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/reference/config.md +0 -0
  169. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/reference/hooks.md +0 -0
  170. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/reference/http-api.md +0 -0
  171. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/reference/path-tables.md +0 -0
  172. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/docs/reference/sdk.md +0 -0
  173. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/bot-1334-listing-exemptions.json +0 -0
  174. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/bot-1397-watch-broadcast.json +0 -0
  175. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/bot-1398-inotify-error.json +0 -0
  176. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/bot-1399-server-cors.json +0 -0
  177. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/bot-1401-watch-scope.json +0 -0
  178. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/bot-1407-child-place-depth.json +0 -0
  179. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/bot-1414-stat-speed.json +0 -0
  180. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/bot-1415-server-speed.json +0 -0
  181. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/bot-1418-node-modules.json +0 -0
  182. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/bot-1431-persist-cache-dir.json +0 -0
  183. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/cc-keen-knuth-f11gyq.json +0 -0
  184. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1056-py-ofpf9.json +0 -0
  185. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1066-p1-resolve-extension.json +0 -0
  186. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1078-argv-config-paths-core.json +0 -0
  187. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1079-p2-resolve-config-extensions.json +0 -0
  188. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1080-share-vtab-scaffolding.json +0 -0
  189. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1081-indicatif-progress.json +0 -0
  190. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1096-watch-moved-dir.json +0 -0
  191. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1109-watch-moved-out.json +0 -0
  192. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1119-ext-plan.json +0 -0
  193. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1120-py-ext.json +0 -0
  194. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1122-ext-cleanup.json +0 -0
  195. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1130-codec-crates.json +0 -0
  196. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1131-flatten-row-event.json +0 -0
  197. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1139-sse-flatten.json +0 -0
  198. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1140-scan-failure-export.json +0 -0
  199. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1148-clippy-all-targets.json +0 -0
  200. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1164-sigint-fatal.json +0 -0
  201. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1170-projection-order.json +0 -0
  202. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1172-on-file-path.json +0 -0
  203. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1173-py-projection-order.json +0 -0
  204. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1184-win-rel-paths.json +0 -0
  205. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1185-win-abs-table-names.json +0 -0
  206. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1186-win-test-harness.json +0 -0
  207. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1196-join-index.json +0 -0
  208. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1199-glob-prefix.json +0 -0
  209. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1201-single-walk.json +0 -0
  210. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1204-embed-batch.json +0 -0
  211. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1207-win-argv-quote.json +0 -0
  212. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1208-win-nonverbatim-paths.json +0 -0
  213. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1215-on-file-batch.json +0 -0
  214. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1216-on-file-cleanup.json +0 -0
  215. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1223-config-glob-rule.json +0 -0
  216. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1223-dir-one-level.json +0 -0
  217. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1225-plugin-no-default.json +0 -0
  218. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1226-stale-docs.json +0 -0
  219. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1232-anchor-plumbing.json +0 -0
  220. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1232-config-anchor.json +0 -0
  221. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1232-multi-watch.json +0 -0
  222. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1232-zero-match.json +0 -0
  223. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1238-parallel-walk.json +0 -0
  224. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1241-content-prefetch.json +0 -0
  225. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1243-ingest-perf.json +0 -0
  226. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1249-dotfiles.json +0 -0
  227. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1256-symlinks.json +0 -0
  228. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1257-trailing-slash.json +0 -0
  229. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1258-config-braces.json +0 -0
  230. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1258-config-directory.json +0 -0
  231. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1258-config-dotnames.json +0 -0
  232. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1258-config-gitignore.json +0 -0
  233. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1258-config-links.json +0 -0
  234. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1258-one-pattern.json +0 -0
  235. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1262-brace-literal.json +0 -0
  236. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1264-context.json +0 -0
  237. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1267-posix-classes.json +0 -0
  238. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1268-unbalanced-brackets.json +0 -0
  239. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1269-utf8-chars.json +0 -0
  240. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1271-node-modules-named.json +0 -0
  241. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1272-ancestor-gitignore.json +0 -0
  242. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1273-walk-prune.json +0 -0
  243. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1285-ingest-fast.json +0 -0
  244. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1286-nested-repo.json +0 -0
  245. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1305-glob-speed.json +0 -0
  246. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1308-glob-speed.json +0 -0
  247. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1310-glob-speed.json +0 -0
  248. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1311-glob-speed.json +0 -0
  249. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1312-glob-speed.json +0 -0
  250. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1318-lazy-stat.json +0 -0
  251. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1320-walk-speed.json +0 -0
  252. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1322-walk-readdir.json +0 -0
  253. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1325-parallel-walk.json +0 -0
  254. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1326-stream-rows.json +0 -0
  255. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1330-python-dirsql-patch.json +0 -0
  256. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1330-python-extensions-patch.json +0 -0
  257. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1330-scanner-effects.json +0 -0
  258. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1330-scanner-gitignore.json +0 -0
  259. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1330-vtab-prefetch-flag.json +0 -0
  260. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1330-vtab-read.json +0 -0
  261. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-1351-dot-dirs.json +0 -0
  262. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-819-oneshot-timeout.json +0 -0
  263. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-827-unquote-doubled-quotes.json +0 -0
  264. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-epic-953-slice2-reedline.json +0 -0
  265. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-epic-953-slice3-format.json +0 -0
  266. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-epic-953-stacked-prs-x59wm3.json +0 -0
  267. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-github-issue-825-e4mhhp.json +0 -0
  268. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-issue-951-0eease.json +0 -0
  269. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-issue-962-0jjrfv.json +0 -0
  270. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-issue-986-red-test-e7sjrb.json +0 -0
  271. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-tackle-1034-cachesplit.json +0 -0
  272. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-tackle-1042-py12.json +0 -0
  273. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-tackle-956-xzen74.json +0 -0
  274. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6-worker-calls.json +0 -0
  275. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6.json +0 -0
  276. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/e2e-attestations/claude-tackle-975-n8mc2h.json +0 -0
  277. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
  278. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-07-13-rename-extract-to-on-file.md +0 -0
  279. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
  280. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-07-20-drop-implicit-files-table.md +0 -0
  281. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-07-21-remove-glob-captures.md +0 -0
  282. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-07-24-hookless-table-config-error.md +0 -0
  283. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-07-24-remove-stat-fact-injection.md +0 -0
  284. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-07-29-restore-python-310.md +0 -0
  285. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-08-04-cli-in-process.md +0 -0
  286. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-08-20-declared-table-name.md +0 -0
  287. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-09-20-sigint-ends-a-run-in-progress.md +0 -0
  288. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-09-24-query-rows-in-projection-order.md +0 -0
  289. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-10-02-readme-docs-host.md +0 -0
  290. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-10-03-one-glob-rule-for-config-globs.md +0 -0
  291. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-10-03-path-table-directory-one-level.md +0 -0
  292. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-10-04-path-table-dotfiles-hidden.md +0 -0
  293. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-10-05-brace-groups-follow-bash.md +0 -0
  294. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-10-05-cli-context.md +0 -0
  295. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-10-05-gitignore-requires-repo.md +0 -0
  296. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-10-05-path-table-node-modules-named.md +0 -0
  297. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-10-05-path-table-symlinks.md +0 -0
  298. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-10-05-path-table-trailing-slash.md +0 -0
  299. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-10-05-unbalanced-brackets-literal.md +0 -0
  300. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-10-06-config-braces.md +0 -0
  301. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-10-06-config-directory.md +0 -0
  302. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-10-06-config-dotnames.md +0 -0
  303. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-10-06-config-gitignore.md +0 -0
  304. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-10-06-config-globs-anchor-at-the-config.md +0 -0
  305. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-10-06-config-links.md +0 -0
  306. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-10-06-one-glob-compiler.md +0 -0
  307. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-10-06-plugin-no-default-records.md +0 -0
  308. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-10-06-watch-broadcast.md +0 -0
  309. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-10-06-zero-match-config-table-warning.md +0 -0
  310. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-10-07-glob-walks-node-modules.md +0 -0
  311. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/2026-10-07-persist-cache-outside-root.md +0 -0
  312. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/migrations.d/README.md +0 -0
  313. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/src/lib.rs +0 -0
  314. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/testing-conventions.toml +0 -0
  315. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/tests/__init__.py +0 -0
  316. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/tests/conftest.py +0 -0
  317. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/tests/e2e/__init__.py +0 -0
  318. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/__init__.py +0 -0
  319. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/dirsql.toml +0 -0
  320. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/tests/e2e/speed_of_light.py +0 -0
  321. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/tests/integration/__init__.py +0 -0
  322. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/tests/integration/binding/__init__.py +0 -0
  323. {dirsql-0.4.96 → dirsql-0.4.97}/packages/python/tests/integration/hermetic/__init__.py +0 -0
  324. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/CHANGELOG.md +0 -0
  325. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/MIGRATIONS.md +0 -0
  326. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/README.md +0 -0
  327. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/benches/db_bench.rs +0 -0
  328. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/benches/differ_bench.rs +0 -0
  329. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/benches/matcher_bench.rs +0 -0
  330. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/benches/scanner_bench.rs +0 -0
  331. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/docs/context/.gitattributes +0 -0
  332. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/docs/context/recipes.md +0 -0
  333. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/docs/context/troubleshooting.md +0 -0
  334. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/docs/context/usage.md +0 -0
  335. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/docs/explanation.md +0 -0
  336. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/docs/getting-started.md +0 -0
  337. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/docs/howto/agent-skill.md +0 -0
  338. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/docs/howto/columns-from-paths.md +0 -0
  339. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/docs/howto/define-tables.md +0 -0
  340. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/docs/howto/embed.md +0 -0
  341. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/docs/howto/extract-from-contents.md +0 -0
  342. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/docs/howto/load-extension.md +0 -0
  343. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/docs/howto/parse-files-into-columns.md +0 -0
  344. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/docs/howto/persist.md +0 -0
  345. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/docs/howto/query-json.md +0 -0
  346. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/docs/howto/query-without-config.md +0 -0
  347. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/docs/howto/react-to-changes.md +0 -0
  348. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/docs/howto/search-by-meaning.md +0 -0
  349. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/docs/howto/search-indexes.md +0 -0
  350. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/docs/howto/skip-files.md +0 -0
  351. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/docs/howto/write-a-plugin.md +0 -0
  352. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/docs/index.md +0 -0
  353. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/docs/plugins.md +0 -0
  354. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/docs/reference/cli.md +0 -0
  355. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/docs/reference/columns.md +0 -0
  356. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/docs/reference/config.md +0 -0
  357. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/docs/reference/hooks.md +0 -0
  358. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/docs/reference/http-api.md +0 -0
  359. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/docs/reference/path-tables.md +0 -0
  360. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/docs/reference/sdk.md +0 -0
  361. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/bin/dirsql.rs +0 -0
  362. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/cli/context.rs +0 -0
  363. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/cli/execute.rs +0 -0
  364. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/cli/init.rs +0 -0
  365. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/cli/mod.rs +0 -0
  366. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/cli/repl.rs +0 -0
  367. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/cli/router.rs +0 -0
  368. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/cli/run.rs +0 -0
  369. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/cli/serialize.rs +0 -0
  370. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/cli/server.rs +0 -0
  371. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/cli/table.rs +0 -0
  372. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/command.rs +0 -0
  373. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/config.rs +0 -0
  374. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/db.rs +0 -0
  375. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/default_config.toml +0 -0
  376. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/differ.rs +0 -0
  377. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/extension_resolution.rs +0 -0
  378. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/functions.rs +0 -0
  379. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/infer.rs +0 -0
  380. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/launcher.rs +0 -0
  381. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/lib.rs +0 -0
  382. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/listing.rs +0 -0
  383. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/matcher.rs +0 -0
  384. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/on_file.rs +0 -0
  385. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/parsed_vtab.rs +0 -0
  386. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/persist.rs +0 -0
  387. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/posix_class.rs +0 -0
  388. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/progress.rs +0 -0
  389. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/row_event_flat.rs +0 -0
  390. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/sql_literal.rs +0 -0
  391. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/tree_walk.rs +0 -0
  392. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/vtab.rs +0 -0
  393. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/vtab_scaffold.rs +0 -0
  394. {dirsql-0.4.96 → dirsql-0.4.97}/packages/rust/src/watcher.rs +0 -0
  395. {dirsql-0.4.96 → dirsql-0.4.97}/pyproject.toml +0 -0
@@ -573,7 +573,7 @@ dependencies = [
573
573
 
574
574
  [[package]]
575
575
  name = "dirsql"
576
- version = "0.4.96"
576
+ version = "0.4.97"
577
577
  dependencies = [
578
578
  "assert_cmd",
579
579
  "axum",
@@ -625,7 +625,7 @@ dependencies = [
625
625
 
626
626
  [[package]]
627
627
  name = "dirsql-py-ext"
628
- version = "0.4.96"
628
+ version = "0.4.97"
629
629
  dependencies = [
630
630
  "dirsql",
631
631
  "pyo3",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dirsql
3
- Version: 0.4.96
3
+ Version: 0.4.97
4
4
  Requires-Dist: bin-shim>=0.1
5
5
  Summary: Ephemeral SQL index over a local directory
6
6
  Keywords: sql,filesystem,directory,sqlite,index
@@ -76,6 +76,9 @@ A test runs every row against dirsql as a path-table and, with the leading
76
76
  | `./[!a].md` | `1.md`, `2.md`, `3.md`, `4.md`, `b.md`, `c.md` | |
77
77
  | `./\[a\].md` | `[a].md` | |
78
78
  | `./[z.md` | `[z.md` | |
79
+ | `./[d/x]ocs/api.md` | none | |
80
+ | `./docs[/]api.md` | none | |
81
+ | `./[!/]*/api.md` | none | |
79
82
  | `./{a,b}.md` | `a.md`, `b.md` | |
80
83
  | `./{q}.md` | `{q}.md` | |
81
84
  | `./{a.md` | none | |
@@ -91,6 +94,16 @@ A test runs every row against dirsql as a path-table and, with the leading
91
94
  | `./*/r.md` | `linkdir/r.md`, `real/r.md` | |
92
95
  | `./**/r.md` | `linkdir/r.md`, `real/r.md` | |
93
96
  | `./real/**` | `real/r.md` | |
97
+ | `./docs//api.md` | `docs//api.md` | |
98
+ | `./docs//*.md` | `docs//api.md`, `docs//guide.md` | |
99
+ | `./*//api.md` | `docs/api.md` | |
100
+ | `./docs/./api.md` | `docs/./api.md` | |
101
+ | `./*/./api.md` | `docs/./api.md` | |
102
+ | `./docs/../top.md` | `docs/../top.md` | |
103
+ | `./docs/nested/../../top.md` | `docs/nested/../../top.md` | |
104
+ | `./[dlr]*/../top.md` | `docs/../top.md`, `linkdir/../top.md`, `real/../top.md` | |
105
+ | `./**/nested/../api.md` | `docs/nested/../api.md` | |
106
+ | `./docs/*/../api.md` | `docs/nested/../api.md` | |
94
107
  | `./docs` | `docs/api.md`, `docs/guide.md` | directory-name |
95
108
  | `./docs/` | `docs/api.md`, `docs/guide.md` | directory-name |
96
109
  | `./*/` | `docs/api.md`, `docs/guide.md`, `linkdir/r.md`, `real/r.md` | directory-name |
@@ -4,7 +4,7 @@ name = "dirsql-py-ext"
4
4
  # pypi/maturin handler can rewrite it via `write-version` before
5
5
  # `maturin build`. `pyproject.toml` declares `dynamic = ["version"]`
6
6
  # and maturin reads this field. Mirrors `packages/rust/Cargo.toml`.
7
- version = "0.4.96"
7
+ version = "0.4.97"
8
8
  # abi3 note: the `abi3-py310` pyo3 feature (below) builds ONE stable-ABI
9
9
  # `cp310-abi3` wheel per platform that loads on every CPython >= 3.10
10
10
  # (matching `pyproject.toml`'s `requires-python = ">=3.10"`), instead of
@@ -0,0 +1,3 @@
1
+ **Changed**
2
+
3
+ - A `/` inside `[...]` is literal and ends the component, as in bash: `./[b/c]/*` matches nothing instead of `b/c/*`.
@@ -0,0 +1,3 @@
1
+ **Changed**
2
+
3
+ - A relative path-table accepts `//`, `.` and `..` components and reports the path as written; `./docs//api.md` returns `docs//api.md`, and `./docs/../top.md` matches `top.md` through `docs/..`.
@@ -0,0 +1,3 @@
1
+ **Changed**
2
+
3
+ - No user-visible change.
@@ -76,6 +76,9 @@ A test runs every row against dirsql as a path-table and, with the leading
76
76
  | `./[!a].md` | `1.md`, `2.md`, `3.md`, `4.md`, `b.md`, `c.md` | |
77
77
  | `./\[a\].md` | `[a].md` | |
78
78
  | `./[z.md` | `[z.md` | |
79
+ | `./[d/x]ocs/api.md` | none | |
80
+ | `./docs[/]api.md` | none | |
81
+ | `./[!/]*/api.md` | none | |
79
82
  | `./{a,b}.md` | `a.md`, `b.md` | |
80
83
  | `./{q}.md` | `{q}.md` | |
81
84
  | `./{a.md` | none | |
@@ -91,6 +94,16 @@ A test runs every row against dirsql as a path-table and, with the leading
91
94
  | `./*/r.md` | `linkdir/r.md`, `real/r.md` | |
92
95
  | `./**/r.md` | `linkdir/r.md`, `real/r.md` | |
93
96
  | `./real/**` | `real/r.md` | |
97
+ | `./docs//api.md` | `docs//api.md` | |
98
+ | `./docs//*.md` | `docs//api.md`, `docs//guide.md` | |
99
+ | `./*//api.md` | `docs/api.md` | |
100
+ | `./docs/./api.md` | `docs/./api.md` | |
101
+ | `./*/./api.md` | `docs/./api.md` | |
102
+ | `./docs/../top.md` | `docs/../top.md` | |
103
+ | `./docs/nested/../../top.md` | `docs/nested/../../top.md` | |
104
+ | `./[dlr]*/../top.md` | `docs/../top.md`, `linkdir/../top.md`, `real/../top.md` | |
105
+ | `./**/nested/../api.md` | `docs/nested/../api.md` | |
106
+ | `./docs/*/../api.md` | `docs/nested/../api.md` | |
94
107
  | `./docs` | `docs/api.md`, `docs/guide.md` | directory-name |
95
108
  | `./docs/` | `docs/api.md`, `docs/guide.md` | directory-name |
96
109
  | `./*/` | `docs/api.md`, `docs/guide.md`, `linkdir/r.md`, `real/r.md` | directory-name |
@@ -0,0 +1,7 @@
1
+ {
2
+ "command": "uv run python -m pytest tests/e2e/glob_speed_recursive_test.py tests/e2e/glob_speed_one_level_test.py tests/e2e/glob_speed_matchers_test.py -x -q",
3
+ "ran_at": 1791392720,
4
+ "exit_code": 0,
5
+ "commit": "7ffc3f247a2b09c1a4788f680e7ab1e88342df94",
6
+ "branch": "bot/1419-dotdot-slashes"
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "command": "uv run python -m pytest tests/e2e/glob_speed_matchers_test.py -x -q",
3
+ "ran_at": 1791393896,
4
+ "exit_code": 0,
5
+ "commit": "10ba3a468aaa558480098ec45a7b52b802b681bd",
6
+ "branch": "bot/1420-bracket-slash"
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "command": "uv run python -m pytest tests/e2e/glob_speed_one_level_test.py -x -q",
3
+ "ran_at": 1791395806,
4
+ "exit_code": 0,
5
+ "commit": "a61af62fec489a0a0d45979d96fa045df52a8f60",
6
+ "branch": "bot/1440-fix-main-build"
7
+ }
@@ -0,0 +1,23 @@
1
+ ### A slash inside brackets is literal
2
+
3
+ #### Summary
4
+
5
+ A slash inside brackets ends the component, so the brackets are literal, as in bash.
6
+
7
+ #### Required changes
8
+
9
+ _None._
10
+
11
+ #### Deprecations removed
12
+
13
+ _None._
14
+
15
+ #### Behavior changes without code changes
16
+
17
+ - A `/` inside `[...]` is literal and ends the component, as in bash: `./[b/c]/*` matches nothing instead of `b/c/*`.
18
+
19
+ #### Verification
20
+
21
+ ```bash
22
+ dirsql query "SELECT path FROM './[d/x]ocs/api.md'"
23
+ ```
@@ -0,0 +1,23 @@
1
+ ### Relative globs accept //, . and .. components
2
+
3
+ #### Summary
4
+
5
+ Relative path-table and config globs now accept `//`, `.` and `..` components as bash does.
6
+
7
+ #### Required changes
8
+
9
+ _None._
10
+
11
+ #### Deprecations removed
12
+
13
+ _None._
14
+
15
+ #### Behavior changes without code changes
16
+
17
+ - A relative path-table accepts `//`, `.` and `..` components and reports the path as written; `./docs//api.md` returns `docs//api.md`, and `./docs/../top.md` matches `top.md` through `docs/..`.
18
+
19
+ #### Verification
20
+
21
+ ```bash
22
+ dirsql query "SELECT path FROM './docs/../*.md'"
23
+ ```
@@ -0,0 +1,23 @@
1
+ ### Build fix
2
+
3
+ #### Summary
4
+
5
+ Fixes the build break from two merged changes.
6
+
7
+ #### Required changes
8
+
9
+ _None._
10
+
11
+ #### Deprecations removed
12
+
13
+ _None._
14
+
15
+ #### Behavior changes without code changes
16
+
17
+ - No user-visible change.
18
+
19
+ #### Verification
20
+
21
+ ```bash
22
+ dirsql query "SELECT path FROM './docs/../*.md'"
23
+ ```
@@ -6,7 +6,7 @@ description = "Ephemeral SQL index over a local directory"
6
6
  # version stays for the binding crates (publish = false). The literal
7
7
  # intentionally lags the published version: putitoutthere rewrites it to
8
8
  # the planned release version at build time and never commits it back.
9
- version = "0.4.96"
9
+ version = "0.4.97"
10
10
  edition.workspace = true
11
11
  # Literal `license` (not `license.workspace = true`) because
12
12
  # putitoutthere's preflight check reads `[package].license` directly
@@ -76,6 +76,9 @@ A test runs every row against dirsql as a path-table and, with the leading
76
76
  | `./[!a].md` | `1.md`, `2.md`, `3.md`, `4.md`, `b.md`, `c.md` | |
77
77
  | `./\[a\].md` | `[a].md` | |
78
78
  | `./[z.md` | `[z.md` | |
79
+ | `./[d/x]ocs/api.md` | none | |
80
+ | `./docs[/]api.md` | none | |
81
+ | `./[!/]*/api.md` | none | |
79
82
  | `./{a,b}.md` | `a.md`, `b.md` | |
80
83
  | `./{q}.md` | `{q}.md` | |
81
84
  | `./{a.md` | none | |
@@ -91,6 +94,16 @@ A test runs every row against dirsql as a path-table and, with the leading
91
94
  | `./*/r.md` | `linkdir/r.md`, `real/r.md` | |
92
95
  | `./**/r.md` | `linkdir/r.md`, `real/r.md` | |
93
96
  | `./real/**` | `real/r.md` | |
97
+ | `./docs//api.md` | `docs//api.md` | |
98
+ | `./docs//*.md` | `docs//api.md`, `docs//guide.md` | |
99
+ | `./*//api.md` | `docs/api.md` | |
100
+ | `./docs/./api.md` | `docs/./api.md` | |
101
+ | `./*/./api.md` | `docs/./api.md` | |
102
+ | `./docs/../top.md` | `docs/../top.md` | |
103
+ | `./docs/nested/../../top.md` | `docs/nested/../../top.md` | |
104
+ | `./[dlr]*/../top.md` | `docs/../top.md`, `linkdir/../top.md`, `real/../top.md` | |
105
+ | `./**/nested/../api.md` | `docs/nested/../api.md` | |
106
+ | `./docs/*/../api.md` | `docs/nested/../api.md` | |
94
107
  | `./docs` | `docs/api.md`, `docs/guide.md` | directory-name |
95
108
  | `./docs/` | `docs/api.md`, `docs/guide.md` | directory-name |
96
109
  | `./*/` | `docs/api.md`, `docs/guide.md`, `linkdir/r.md`, `real/r.md` | directory-name |
@@ -198,7 +198,8 @@ fn steps(lo: i64, hi: i64, step: i64) -> Option<impl Iterator<Item = i128>> {
198
198
 
199
199
  /// Escape the braces bash left as literal text, so globset matches them
200
200
  /// rather than reading an alternation. A complete `[...]` class is copied as
201
- /// written; an unclosed `[` is a literal character.
201
+ /// written; an unclosed `[` is a literal character, and so is one whose
202
+ /// class would span a `/`, which ends a component first.
202
203
  fn escape_braces(word: &str) -> String {
203
204
  let chars: Vec<char> = word.chars().collect();
204
205
  let mut out = String::with_capacity(word.len());
@@ -217,7 +218,7 @@ fn escape_braces(word: &str) -> String {
217
218
  }
218
219
  resume = i + 2;
219
220
  }
220
- ('[', _) => match class_end(&chars, i) {
221
+ ('[', _) => match class_end(&chars, i).filter(|&end| !chars[i..end].contains(&'/')) {
221
222
  Some(end) => {
222
223
  out.extend(&chars[i..=end]);
223
224
  resume = end + 1;
@@ -415,6 +416,14 @@ mod tests {
415
416
  assert_eq!(escape_braces("a].md"), "a].md");
416
417
  }
417
418
 
419
+ #[test]
420
+ fn a_class_spanning_a_slash_is_literal() {
421
+ assert_eq!(escape_braces("[b/c]/*"), "[[]b/c]/*");
422
+ assert_eq!(escape_braces("a[/]b"), "a[[]/]b");
423
+ assert_eq!(escape_braces("[!/]x"), "[[]!/]x");
424
+ assert_eq!(escape_braces("[a]/[b]"), "[a]/[b]");
425
+ }
426
+
418
427
  #[test]
419
428
  fn expand_leaves_an_unpartnered_brace_literal() {
420
429
  assert_eq!(expand("{a.md"), vec!["[{]a.md"]);
@@ -193,22 +193,43 @@ fn trailing_separator_as_star<S: Syntax>(name: &str) -> String {
193
193
  /// Split a `./`-relative target into the directory to walk beneath the index
194
194
  /// root and the glob to match there. The walk starts at the literal prefix
195
195
  /// and `path` is reported under it, so the rows read as if the index root
196
- /// had been walked whole.
196
+ /// had been walked whole. The prefix is kept as written, `//` and `.` and
197
+ /// `..` included, as the shell keeps it; past the first wildcard, repeated
198
+ /// separators collapse.
197
199
  fn split_relative(index_root: &Path, rest: &str, is_dir: &dyn Fn(&Path) -> bool) -> PathTable {
198
- let target = Utf8Path::<Utf8UnixEncoding>::new(rest);
199
- let (literal, glob) = split_target(target, &|rel| is_dir(&index_root.join(rel)));
200
- let root = if literal.as_str().is_empty() {
200
+ let parts: Vec<&str> = rest.split('/').collect();
201
+ let (literal, glob) = match parts.iter().position(|p| has_glob_metacharacter(p)) {
202
+ Some(at) => (parts[..at].join("/"), glob_of(&parts[at..])),
203
+ None if is_dir(&index_root.join(rest)) => (rest.to_string(), DIRECTORY_GLOB.to_string()),
204
+ None => {
205
+ let (name, parent) = parts.split_last().expect("split yields a part");
206
+ (parent.join("/"), (*name).to_string())
207
+ }
208
+ };
209
+ let root = if literal.is_empty() {
201
210
  index_root.to_path_buf()
202
211
  } else {
203
- index_root.join(literal.as_str())
212
+ index_root.join(&literal)
213
+ };
214
+ // A prefix already ending in a separator is not given another when a path
215
+ // is reported under it, so a written `//` needs the second one here.
216
+ let path_prefix = if literal.ends_with('/') {
217
+ format!("{literal}/")
218
+ } else {
219
+ literal
204
220
  };
205
221
  PathTable {
206
222
  root,
207
223
  glob,
208
- path_prefix: literal.into_string(),
224
+ path_prefix,
209
225
  }
210
226
  }
211
227
 
228
+ fn glob_of(parts: &[&str]) -> String {
229
+ let kept: Vec<&str> = parts.iter().copied().filter(|p| !p.is_empty()).collect();
230
+ kept.join("/")
231
+ }
232
+
212
233
  fn typed<S: Syntax>(path: &Path) -> Utf8PathBuf<S> {
213
234
  Utf8PathBuf::from(path.to_string_lossy().into_owned())
214
235
  }
@@ -400,6 +421,33 @@ mod tests {
400
421
  assert_eq!(DEFAULT_IGNORES, ["**/.git/**"]);
401
422
  }
402
423
 
424
+ #[test]
425
+ fn a_double_separator_in_the_literal_prefix_is_kept_as_written() {
426
+ let t = table("./docs//a.md", &nothing_is_a_dir);
427
+ assert_eq!(t.root, Path::new("/index/docs/"));
428
+ assert_eq!(t.glob, "a.md");
429
+ assert_eq!(t.path_prefix, "docs//");
430
+ }
431
+
432
+ #[test]
433
+ fn a_current_directory_component_in_the_literal_prefix_is_kept_as_written() {
434
+ let t = table("./docs/./*.md", &nothing_is_a_dir);
435
+ assert_eq!(t.glob, "*.md");
436
+ assert_eq!(t.path_prefix, "docs/.");
437
+ }
438
+
439
+ #[test]
440
+ fn a_current_directory_component_after_a_wildcard_stays_in_the_glob() {
441
+ let t = table("./*/./a.md", &nothing_is_a_dir);
442
+ assert_eq!(t.glob, "*/./a.md");
443
+ }
444
+
445
+ #[test]
446
+ fn a_double_separator_after_a_wildcard_collapses() {
447
+ let t = table("./*//a.md", &nothing_is_a_dir);
448
+ assert_eq!(t.glob, "*/a.md");
449
+ }
450
+
403
451
  #[test]
404
452
  fn has_glob_metacharacter_spots_each_metacharacter() {
405
453
  assert!(has_glob_metacharacter("a*"));
@@ -208,6 +208,9 @@ pub struct PathGlob {
208
208
  components: Vec<Component>,
209
209
  /// Where each word's components begin.
210
210
  starts: Vec<usize>,
211
+ /// Whether any word spells a `.` or `..` component, which the walk has to
212
+ /// enter itself: a directory listing never names them.
213
+ spells_relative: bool,
211
214
  }
212
215
 
213
216
  #[derive(Debug, Clone)]
@@ -253,6 +256,19 @@ impl PathGlob {
253
256
  !self.components.is_empty()
254
257
  }
255
258
 
259
+ /// The `.` and `..` entries a directory reached with `states` has as far
260
+ /// as the pattern is concerned, each with the states it leads to.
261
+ fn relative_entries(&self, states: &[usize]) -> Vec<(&'static str, Vec<usize>)> {
262
+ if !self.spells_relative {
263
+ return Vec::new();
264
+ }
265
+ [".", ".."]
266
+ .into_iter()
267
+ .map(|name| (name, self.step(states, OsStr::new(name), Kind::Dir)))
268
+ .filter(|(_, next)| self.reaches(next, Kind::Dir))
269
+ .collect()
270
+ }
271
+
256
272
  fn start(&self) -> Vec<usize> {
257
273
  self.closure(self.starts.clone())
258
274
  }
@@ -319,7 +335,11 @@ pub fn compile_globs(patterns: &[&str]) -> Result<PathGlob, GlobError> {
319
335
  let words: Vec<String> = patterns
320
336
  .iter()
321
337
  .flat_map(|pattern| crate::brace::expand(pattern))
338
+ .map(|word| collapse_separators(&word))
322
339
  .collect();
340
+ let spells_relative = words
341
+ .iter()
342
+ .any(|word| word.split('/').any(|c| c == "." || c == ".."));
323
343
  let mut files = Vec::new();
324
344
  let mut spelled_dot_names = Vec::new();
325
345
  for word in &words {
@@ -330,10 +350,8 @@ pub fn compile_globs(patterns: &[&str]) -> Result<PathGlob, GlobError> {
330
350
  }
331
351
  let mut components = Vec::new();
332
352
  let mut starts = Vec::new();
333
- // All or nothing: the walk prunes a directory no component can enter, so
334
- // a word left without components would lose its matches.
335
- let compiled: Option<Vec<_>> = words.iter().map(|w| compile_components(w)).collect();
336
- for word_components in compiled.unwrap_or_default() {
353
+ for word in &words {
354
+ let word_components = compile_components(word)?;
337
355
  starts.push(components.len());
338
356
  components.extend(word_components);
339
357
  components.push(Component::End);
@@ -343,16 +361,27 @@ pub fn compile_globs(patterns: &[&str]) -> Result<PathGlob, GlobError> {
343
361
  spelled_dot_names,
344
362
  components,
345
363
  starts,
364
+ spells_relative,
346
365
  })
347
366
  }
348
367
 
368
+ /// `word` with each run of `/` made one, as the shell reads a pattern's
369
+ /// components.
370
+ fn collapse_separators(word: &str) -> String {
371
+ let mut out = String::with_capacity(word.len());
372
+ for c in word.chars() {
373
+ if c != '/' || !out.ends_with('/') {
374
+ out.push(c);
375
+ }
376
+ }
377
+ out
378
+ }
379
+
349
380
  fn is_dot_named(name: &OsStr) -> bool {
350
381
  name.as_encoded_bytes().first() == Some(&b'.')
351
382
  }
352
383
 
353
- /// A word whose components do not compile on their own (a class spanning a
354
- /// `/`) gets none.
355
- fn compile_components(word: &str) -> Option<Vec<Component>> {
384
+ fn compile_components(word: &str) -> Result<Vec<Component>, GlobError> {
356
385
  let mut components = word
357
386
  .split('/')
358
387
  .map(|c| match c {
@@ -360,10 +389,9 @@ fn compile_components(word: &str) -> Option<Vec<Component>> {
360
389
  _ if is_dot_named(OsStr::new(c)) => Pattern::new(c).map(Component::DotName),
361
390
  _ => Pattern::new(c).map(Component::Name),
362
391
  })
363
- .collect::<Result<Vec<_>, _>>()
364
- .ok()?;
392
+ .collect::<Result<Vec<_>, _>>()?;
365
393
  components.dedup_by(|a, b| matches!((a, b), (Component::AnyDepth, Component::AnyDepth)));
366
- Some(components)
394
+ Ok(components)
367
395
  }
368
396
 
369
397
  /// Module-argument spelling for a scan that respects `.gitignore`.
@@ -486,6 +514,21 @@ impl<'a> Place<'a> {
486
514
  } else {
487
515
  Vec::new()
488
516
  };
517
+ let relative = walk.glob.map_or_else(Vec::new, |glob| {
518
+ glob.relative_entries(&states)
519
+ .into_iter()
520
+ .map(|(name, next)| {
521
+ Step::Dir(Box::new(Place {
522
+ walk: walk.clone(),
523
+ dir: dir.join(name),
524
+ rel: rel.join(name),
525
+ states: next,
526
+ linked,
527
+ }))
528
+ })
529
+ .collect::<Vec<_>>()
530
+ });
531
+ steps.extend(relative);
489
532
  let entered =
490
533
  listing
491
534
  .entries()
@@ -1037,6 +1080,44 @@ mod tests {
1037
1080
  assert_eq!(nested, vec![Path::new("a").join(".dirsql")]);
1038
1081
  }
1039
1082
 
1083
+ #[test]
1084
+ fn explore_enters_a_current_directory_component_the_glob_spells() {
1085
+ let root = tempfile::tempdir().unwrap();
1086
+ let ignore = TableMatcher::new(&[], &[]).unwrap();
1087
+ let glob = compile_glob("./x").unwrap();
1088
+ let top = Place {
1089
+ walk: walk_with(&ignore, Some(&glob), Vec::new()),
1090
+ dir: root.path().to_path_buf(),
1091
+ rel: PathBuf::new(),
1092
+ states: glob.start(),
1093
+ linked: false,
1094
+ };
1095
+ let [dot] = <[Place<'_>; 1]>::try_from(explored_dirs(top)).ok().unwrap();
1096
+ assert_eq!(dot.rel, Path::new("."));
1097
+ assert_eq!(dot.dir, root.path().join("."));
1098
+ }
1099
+
1100
+ #[test]
1101
+ fn relative_entries_name_only_the_components_the_glob_spells() {
1102
+ let glob = compile_glob("*/../x").unwrap();
1103
+ let states = glob.step(&glob.start(), OsStr::new("docs"), Kind::Dir);
1104
+ let entries = glob.relative_entries(&states);
1105
+ assert_eq!(
1106
+ entries.iter().map(|(name, _)| *name).collect::<Vec<_>>(),
1107
+ vec![".."]
1108
+ );
1109
+ let plain = compile_glob("*/x").unwrap();
1110
+ let states = plain.step(&plain.start(), OsStr::new("docs"), Kind::Dir);
1111
+ assert!(plain.relative_entries(&states).is_empty());
1112
+ }
1113
+
1114
+ #[test]
1115
+ fn a_glob_spells_relative_components_only_when_a_word_has_one() {
1116
+ assert!(compile_glob("a/./b").unwrap().spells_relative);
1117
+ assert!(compile_glob("a/../b").unwrap().spells_relative);
1118
+ assert!(!compile_glob("a/b").unwrap().spells_relative);
1119
+ }
1120
+
1040
1121
  #[test]
1041
1122
  fn reaches_dir_enters_the_root_and_unignored_directories() {
1042
1123
  let ignore = TableMatcher::new(&[], &["**/node_modules/**"]).unwrap();
@@ -1465,19 +1546,12 @@ mod tests {
1465
1546
  }
1466
1547
 
1467
1548
  #[test]
1468
- fn a_pattern_whose_components_do_not_compile_alone_follows_no_link() {
1469
- let glob = compile_glob("[a/b]").unwrap();
1549
+ fn a_glob_without_words_follows_no_link() {
1550
+ let glob = compile_globs(&[]).unwrap();
1470
1551
  assert!(glob.components.is_empty());
1471
1552
  assert!(!glob.reaches(&glob.start(), Kind::LinkedDir));
1472
1553
  }
1473
1554
 
1474
- #[test]
1475
- fn one_brace_word_without_components_leaves_the_glob_without_any() {
1476
- let glob = compile_glob("{x,[a/b]}").unwrap();
1477
- assert!(glob.components.is_empty());
1478
- assert!(!glob.has_components());
1479
- }
1480
-
1481
1555
  #[test]
1482
1556
  fn each_brace_word_is_walked_from_its_own_start() {
1483
1557
  let glob = compile_glob("{a,b/c}").unwrap();
@@ -1575,7 +1649,7 @@ mod tests {
1575
1649
  #[test]
1576
1650
  fn enters_every_real_directory_when_the_glob_has_no_components() {
1577
1651
  let ignore = TableMatcher::new(&[], &[]).unwrap();
1578
- let glob = compile_glob("[a/b]").unwrap();
1652
+ let glob = compile_globs(&[]).unwrap();
1579
1653
  let walk = Walk {
1580
1654
  ignore: &ignore,
1581
1655
  glob: Some(&glob),
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