dirsql 0.4.43__tar.gz → 0.4.44__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.
- {dirsql-0.4.43 → dirsql-0.4.44}/Cargo.lock +2 -2
- {dirsql-0.4.43 → dirsql-0.4.44}/PKG-INFO +1 -1
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/Cargo.toml +1 -1
- dirsql-0.4.44/packages/python/e2e-attestations/claude-1119-ext-plan.json +7 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/Cargo.toml +1 -1
- dirsql-0.4.44/packages/rust/src/extension_resolution.rs +421 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/lib.rs +2 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/Cargo.toml +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/README.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/__init__.py +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/_async.py +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/_dirsql.pyi +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/cli/__init__.py +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/cli/discover_plugins/__init__.py +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/cli/discover_plugins/discovered_fragments.py +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/cli/discover_plugins/discovery_disabled.py +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/cli/discover_plugins/fragment_path.py +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/cli/discover_plugins/user_passed_config.py +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/cli/discover_plugins/with_discovered_plugins.py +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/cli/main.py +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/cli/resolve_config_extensions.py +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/has_bare_name.py +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/is_bare_name.py +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/load_extension_entries.py +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/platform_patterns.py +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/py.typed +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/resolve_config_extensions.py +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/resolve_configs_extension_specs.py +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/resolve_entries.py +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/resolve_extension.py +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/resolve_package.py +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/toml_module.py +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/.vitepress/config.ts +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/AGENTS.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/explanation.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/getting-started.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/howto/define-tables.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/howto/embed.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/howto/load-extension.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/howto/persist.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/howto/query-json.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/howto/query-without-config.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/howto/search-indexes.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/howto/skip-files.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/index.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/package.json +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/plugins.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/pnpm-lock.yaml +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/reference/cli.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/reference/columns.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/reference/config.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/reference/hooks.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/reference/http-api.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/reference/path-tables.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/docs/reference/sdk.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/CHANGELOG.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/MIGRATIONS.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/README.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-07-13-plugin-discovery.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-07-13-rename-extract-to-on-file.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-07-13-repeatable-config.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-07-20-drop-implicit-files-table.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-07-21-remove-glob-captures.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-07-24-hookless-table-config-error.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-07-24-remove-stat-fact-injection.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-07-29-restore-python-310.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-08-02-release-profile.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-08-02-scan-failures.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-08-03-discovery-ext-resolution.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-08-03-manylinux-dynamic-binary.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-08-03-python-no-ignore.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-08-04-cast-lints.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-08-04-cli-in-process.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-08-20-curtaincall-dev-dependency.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-08-20-declared-table-name.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-09-04-config-paths-from-argv-module.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-09-05-config-extension-loader-split.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-09-05-resolve-config-extensions-split.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-09-05-resolve-extension-split.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-09-09-launcher-config-path-scan.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/README.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/conftest.py +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/.vitepress/config.ts +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/AGENTS.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/explanation.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/getting-started.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/howto/define-tables.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/howto/embed.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/howto/load-extension.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/howto/persist.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/howto/query-json.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/howto/query-without-config.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/howto/search-indexes.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/howto/skip-files.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/index.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/package.json +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/plugins.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/pnpm-lock.yaml +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/reference/cli.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/reference/columns.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/reference/config.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/reference/hooks.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/reference/http-api.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/reference/path-tables.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/reference/sdk.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/cc-keen-knuth-f11gyq.json +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-1056-py-ofpf9.json +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-1066-p1-resolve-extension.json +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-1078-argv-config-paths-core.json +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-1079-p2-resolve-config-extensions.json +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-1080-share-vtab-scaffolding.json +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-1081-indicatif-progress.json +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-1096-watch-moved-dir.json +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-1109-watch-moved-out.json +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-819-oneshot-timeout.json +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-827-unquote-doubled-quotes.json +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-epic-953-slice2-reedline.json +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-epic-953-slice3-format.json +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-epic-953-stacked-prs-x59wm3.json +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-github-issue-825-e4mhhp.json +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-issue-951-0eease.json +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-issue-962-0jjrfv.json +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-issue-986-red-test-e7sjrb.json +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-tackle-1034-cachesplit.json +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-tackle-1042-py12.json +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-tackle-956-xzen74.json +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6-worker-calls.json +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6.json +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-tackle-975-n8mc2h.json +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/migrations.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/migrations.d/2026-07-13-rename-extract-to-on-file.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/migrations.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/migrations.d/2026-07-20-drop-implicit-files-table.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/migrations.d/2026-07-21-remove-glob-captures.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/migrations.d/2026-07-24-hookless-table-config-error.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/migrations.d/2026-07-24-remove-stat-fact-injection.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/migrations.d/2026-07-29-restore-python-310.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/migrations.d/2026-08-04-cli-in-process.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/migrations.d/2026-08-20-declared-table-name.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/migrations.d/README.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/src/lib.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/testing-conventions.toml +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/tests/__init__.py +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/tests/conftest.py +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/tests/e2e/__init__.py +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/__init__.py +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/dirsql.toml +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/tests/integration/__init__.py +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/tests/integration/binding/__init__.py +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/tests/integration/hermetic/__init__.py +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/CHANGELOG.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/MIGRATIONS.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/README.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/benches/db_bench.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/benches/differ_bench.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/benches/matcher_bench.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/benches/scanner_bench.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/explanation.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/getting-started.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/howto/define-tables.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/howto/embed.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/howto/load-extension.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/howto/persist.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/howto/query-json.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/howto/query-without-config.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/howto/search-indexes.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/howto/skip-files.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/index.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/plugins.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/reference/cli.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/reference/columns.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/reference/config.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/reference/hooks.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/reference/http-api.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/reference/path-tables.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/reference/sdk.md +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/bin/dirsql.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/cli/execute.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/cli/init.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/cli/mod.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/cli/repl.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/cli/router.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/cli/run.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/cli/serialize.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/cli/server.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/cli/table.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/command.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/config.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/db.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/default_config.toml +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/differ.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/functions.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/infer.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/launcher.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/matcher.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/parsed_cache.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/parsed_vtab.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/path_table.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/persist.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/progress.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/scanner.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/sql_literal.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/vtab.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/vtab_scaffold.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/watcher.rs +0 -0
- {dirsql-0.4.43 → dirsql-0.4.44}/pyproject.toml +0 -0
|
@@ -552,7 +552,7 @@ checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
|
|
|
552
552
|
|
|
553
553
|
[[package]]
|
|
554
554
|
name = "dirsql"
|
|
555
|
-
version = "0.4.
|
|
555
|
+
version = "0.4.44"
|
|
556
556
|
dependencies = [
|
|
557
557
|
"assert_cmd",
|
|
558
558
|
"axum",
|
|
@@ -597,7 +597,7 @@ dependencies = [
|
|
|
597
597
|
|
|
598
598
|
[[package]]
|
|
599
599
|
name = "dirsql-py-ext"
|
|
600
|
-
version = "0.4.
|
|
600
|
+
version = "0.4.44"
|
|
601
601
|
dependencies = [
|
|
602
602
|
"dirsql",
|
|
603
603
|
"pyo3",
|
|
@@ -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.
|
|
7
|
+
version = "0.4.44"
|
|
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
|
|
@@ -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.
|
|
9
|
+
version = "0.4.44"
|
|
10
10
|
edition.workspace = true
|
|
11
11
|
# Literal `license` (not `license.workspace = true`) because
|
|
12
12
|
# putitoutthere's preflight check reads `[package].license` directly
|
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
//! Planning the resolution of `[[dirsql.extension]]` entries.
|
|
2
|
+
//!
|
|
3
|
+
//! Each launcher used to carry its own port of this: read the configs, decide
|
|
4
|
+
//! whether any entry names a package rather than a file, resolve the rest
|
|
5
|
+
//! against the config's directory. Only "where is package `X` installed on
|
|
6
|
+
//! this host" is genuinely host-specific (`importlib.util.find_spec` /
|
|
7
|
+
//! `require.resolve`), so that stays with the launcher and comes back here as
|
|
8
|
+
//! a set of directories.
|
|
9
|
+
//!
|
|
10
|
+
//! The suffix list is a parameter because it differs per host: Python counts
|
|
11
|
+
//! `.pyd` as a loadable, Node counts `.node`.
|
|
12
|
+
|
|
13
|
+
use std::fmt;
|
|
14
|
+
use std::path::{Path, PathBuf};
|
|
15
|
+
|
|
16
|
+
use crate::config::{ExtensionSpec, load_config_str};
|
|
17
|
+
|
|
18
|
+
/// One config file's contents, or `None` when it is missing or unreadable.
|
|
19
|
+
///
|
|
20
|
+
/// `path` must be absolute: entry paths and the bare-name shadow probe resolve
|
|
21
|
+
/// against its parent directory.
|
|
22
|
+
#[derive(Debug, Clone, Copy)]
|
|
23
|
+
pub struct ConfigSource<'a> {
|
|
24
|
+
pub path: &'a Path,
|
|
25
|
+
pub contents: Option<&'a str>,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/// One planned extension entry.
|
|
29
|
+
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
30
|
+
pub enum PlanEntry {
|
|
31
|
+
/// A concrete path, already absolute against its config's directory.
|
|
32
|
+
Literal {
|
|
33
|
+
path: PathBuf,
|
|
34
|
+
entrypoint: Option<String>,
|
|
35
|
+
},
|
|
36
|
+
/// A bare package name. Use `shadow` when it is a file on disk; otherwise
|
|
37
|
+
/// locate the package on the host and hand its directories, plus every
|
|
38
|
+
/// file found under them, to [`select_loadable`].
|
|
39
|
+
Package {
|
|
40
|
+
name: String,
|
|
41
|
+
shadow: PathBuf,
|
|
42
|
+
entrypoint: Option<String>,
|
|
43
|
+
},
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/// Why a package's loadable file could not be picked.
|
|
47
|
+
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
48
|
+
pub enum SelectError {
|
|
49
|
+
NotFound {
|
|
50
|
+
name: String,
|
|
51
|
+
suffixes: Vec<String>,
|
|
52
|
+
dirs: Vec<PathBuf>,
|
|
53
|
+
},
|
|
54
|
+
Ambiguous {
|
|
55
|
+
name: String,
|
|
56
|
+
matches: Vec<PathBuf>,
|
|
57
|
+
},
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
fn join_display(paths: &[PathBuf], sep: &str) -> String {
|
|
61
|
+
paths
|
|
62
|
+
.iter()
|
|
63
|
+
.map(|p| p.display().to_string())
|
|
64
|
+
.collect::<Vec<_>>()
|
|
65
|
+
.join(sep)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
impl fmt::Display for SelectError {
|
|
69
|
+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
70
|
+
match self {
|
|
71
|
+
SelectError::NotFound {
|
|
72
|
+
name,
|
|
73
|
+
suffixes,
|
|
74
|
+
dirs,
|
|
75
|
+
} => {
|
|
76
|
+
let patterns = suffixes
|
|
77
|
+
.iter()
|
|
78
|
+
.map(|s| format!("*{s}"))
|
|
79
|
+
.collect::<Vec<_>>()
|
|
80
|
+
.join(" / ");
|
|
81
|
+
write!(
|
|
82
|
+
f,
|
|
83
|
+
"no loadable extension file ({patterns}) found in package '{name}' (searched {})",
|
|
84
|
+
join_display(dirs, ", ")
|
|
85
|
+
)
|
|
86
|
+
}
|
|
87
|
+
SelectError::Ambiguous { name, matches } => write!(
|
|
88
|
+
f,
|
|
89
|
+
"multiple loadable extension files found in package '{name}': {}; disambiguate with a literal path",
|
|
90
|
+
join_display(matches, ", ")
|
|
91
|
+
),
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
impl std::error::Error for SelectError {}
|
|
97
|
+
|
|
98
|
+
/// True when `path` names a package rather than a file.
|
|
99
|
+
///
|
|
100
|
+
/// Both separators count regardless of host, so a Windows-style path is a path
|
|
101
|
+
/// everywhere.
|
|
102
|
+
pub fn is_bare_name(path: &str, suffixes: &[&str]) -> bool {
|
|
103
|
+
if path.contains('/') || path.contains('\\') {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
!suffixes.iter().any(|s| path.ends_with(s))
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/// Plan the extension entries of several configs, in order.
|
|
110
|
+
///
|
|
111
|
+
/// `None` means "do not intervene": no config names an extension by bare
|
|
112
|
+
/// package name, so the core's own config loading (and its error reporting)
|
|
113
|
+
/// handles every entry. Otherwise **every** config's entries are planned, each
|
|
114
|
+
/// against its own directory, concatenated in `configs` order — once the
|
|
115
|
+
/// caller suppresses the core's config-extension loading it must supply the
|
|
116
|
+
/// literal entries too.
|
|
117
|
+
///
|
|
118
|
+
/// A config whose contents are absent or do not parse is skipped rather than
|
|
119
|
+
/// reported, leaving the error to the core.
|
|
120
|
+
pub fn plan_config_extensions(
|
|
121
|
+
configs: &[ConfigSource<'_>],
|
|
122
|
+
suffixes: &[&str],
|
|
123
|
+
) -> Option<Vec<PlanEntry>> {
|
|
124
|
+
let loaded: Vec<(PathBuf, Vec<ExtensionSpec>)> = configs
|
|
125
|
+
.iter()
|
|
126
|
+
.filter_map(|source| {
|
|
127
|
+
let config = load_config_str(source.contents?).ok()?;
|
|
128
|
+
Some((source.path.parent()?.to_path_buf(), config.extensions))
|
|
129
|
+
})
|
|
130
|
+
.collect();
|
|
131
|
+
|
|
132
|
+
if !loaded
|
|
133
|
+
.iter()
|
|
134
|
+
.flat_map(|(_, extensions)| extensions)
|
|
135
|
+
.any(|extension| spec_is_bare_name(extension, suffixes))
|
|
136
|
+
{
|
|
137
|
+
return None;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
Some(
|
|
141
|
+
loaded
|
|
142
|
+
.into_iter()
|
|
143
|
+
.flat_map(|(base, extensions)| {
|
|
144
|
+
extensions.into_iter().map(move |extension| {
|
|
145
|
+
let name = extension.path.to_string_lossy().into_owned();
|
|
146
|
+
if is_bare_name(&name, suffixes) {
|
|
147
|
+
PlanEntry::Package {
|
|
148
|
+
shadow: base.join(&name),
|
|
149
|
+
name,
|
|
150
|
+
entrypoint: extension.entrypoint,
|
|
151
|
+
}
|
|
152
|
+
} else {
|
|
153
|
+
// `join` already yields an absolute path verbatim.
|
|
154
|
+
PlanEntry::Literal {
|
|
155
|
+
path: base.join(&extension.path),
|
|
156
|
+
entrypoint: extension.entrypoint,
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
})
|
|
160
|
+
})
|
|
161
|
+
.collect(),
|
|
162
|
+
)
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
fn spec_is_bare_name(extension: &ExtensionSpec, suffixes: &[&str]) -> bool {
|
|
166
|
+
extension
|
|
167
|
+
.path
|
|
168
|
+
.to_str()
|
|
169
|
+
.is_some_and(|path| is_bare_name(path, suffixes))
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/// Pick the single loadable file for package `name` out of a host's listing.
|
|
173
|
+
///
|
|
174
|
+
/// `dirs` are the package's directories (used only for the not-found message);
|
|
175
|
+
/// `candidates` is every file found under them. Zero matches and more than one
|
|
176
|
+
/// are both errors — the user must disambiguate with a literal path.
|
|
177
|
+
pub fn select_loadable(
|
|
178
|
+
name: &str,
|
|
179
|
+
dirs: &[PathBuf],
|
|
180
|
+
candidates: &[PathBuf],
|
|
181
|
+
suffixes: &[&str],
|
|
182
|
+
) -> Result<PathBuf, SelectError> {
|
|
183
|
+
let mut matches: Vec<PathBuf> = candidates
|
|
184
|
+
.iter()
|
|
185
|
+
.filter(|candidate| {
|
|
186
|
+
candidate
|
|
187
|
+
.to_str()
|
|
188
|
+
.is_some_and(|path| suffixes.iter().any(|suffix| path.ends_with(suffix)))
|
|
189
|
+
})
|
|
190
|
+
.cloned()
|
|
191
|
+
.collect();
|
|
192
|
+
matches.sort();
|
|
193
|
+
matches.dedup();
|
|
194
|
+
|
|
195
|
+
match matches.len() {
|
|
196
|
+
0 => Err(SelectError::NotFound {
|
|
197
|
+
name: name.to_owned(),
|
|
198
|
+
suffixes: suffixes.iter().map(|s| (*s).to_owned()).collect(),
|
|
199
|
+
dirs: dirs.to_vec(),
|
|
200
|
+
}),
|
|
201
|
+
1 => Ok(matches.remove(0)),
|
|
202
|
+
_ => Err(SelectError::Ambiguous {
|
|
203
|
+
name: name.to_owned(),
|
|
204
|
+
matches,
|
|
205
|
+
}),
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
#[cfg(test)]
|
|
210
|
+
mod tests {
|
|
211
|
+
use super::{
|
|
212
|
+
ConfigSource, PlanEntry, SelectError, is_bare_name, plan_config_extensions, select_loadable,
|
|
213
|
+
};
|
|
214
|
+
use std::path::{Path, PathBuf};
|
|
215
|
+
|
|
216
|
+
const PY: &[&str] = &[".so", ".dylib", ".dll", ".pyd"];
|
|
217
|
+
const NODE: &[&str] = &[".so", ".dylib", ".dll", ".node"];
|
|
218
|
+
|
|
219
|
+
fn source<'a>(path: &'a Path, contents: &'a str) -> ConfigSource<'a> {
|
|
220
|
+
ConfigSource {
|
|
221
|
+
path,
|
|
222
|
+
contents: Some(contents),
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
#[test]
|
|
227
|
+
fn a_value_with_no_separator_and_no_loadable_suffix_is_a_bare_name() {
|
|
228
|
+
assert!(is_bare_name("sqlite_vec", PY));
|
|
229
|
+
assert!(is_bare_name("vec0", NODE));
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
#[test]
|
|
233
|
+
fn a_value_carrying_either_separator_is_a_path() {
|
|
234
|
+
assert!(!is_bare_name("ext/vec0", PY));
|
|
235
|
+
assert!(!is_bare_name("ext\\vec0", PY));
|
|
236
|
+
assert!(!is_bare_name("/abs/vec0", PY));
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
#[test]
|
|
240
|
+
fn a_value_ending_in_a_loadable_suffix_is_a_path() {
|
|
241
|
+
for suffix in [".so", ".dylib", ".dll"] {
|
|
242
|
+
assert!(!is_bare_name(&format!("vec0{suffix}"), PY));
|
|
243
|
+
assert!(!is_bare_name(&format!("vec0{suffix}"), NODE));
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
#[test]
|
|
248
|
+
fn the_suffix_list_is_the_hosts_own() {
|
|
249
|
+
assert!(!is_bare_name("vec0.pyd", PY));
|
|
250
|
+
assert!(is_bare_name("vec0.pyd", NODE));
|
|
251
|
+
assert!(!is_bare_name("vec0.node", NODE));
|
|
252
|
+
assert!(is_bare_name("vec0.node", PY));
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
#[test]
|
|
256
|
+
fn configs_using_only_literal_paths_are_left_to_the_core() {
|
|
257
|
+
let path = Path::new("/project/.dirsql.toml");
|
|
258
|
+
let config = "[[dirsql.extension]]\npath = \"ext/vec0.so\"\n";
|
|
259
|
+
assert_eq!(plan_config_extensions(&[source(path, config)], PY), None);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
#[test]
|
|
263
|
+
fn a_config_with_no_extension_array_is_left_to_the_core() {
|
|
264
|
+
let path = Path::new("/project/.dirsql.toml");
|
|
265
|
+
assert_eq!(
|
|
266
|
+
plan_config_extensions(&[source(path, "[dirsql]\nignore = [\"*.tmp\"]\n")], PY),
|
|
267
|
+
None
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
#[test]
|
|
272
|
+
fn an_absent_or_unparseable_config_is_skipped_rather_than_reported() {
|
|
273
|
+
let path = Path::new("/project/.dirsql.toml");
|
|
274
|
+
let missing = ConfigSource {
|
|
275
|
+
path,
|
|
276
|
+
contents: None,
|
|
277
|
+
};
|
|
278
|
+
assert_eq!(plan_config_extensions(&[missing], PY), None);
|
|
279
|
+
assert_eq!(
|
|
280
|
+
plan_config_extensions(&[source(path, "not valid = [")], PY),
|
|
281
|
+
None
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
#[test]
|
|
286
|
+
fn a_bare_name_plans_a_package_lookup_shadowed_by_the_configs_own_directory() {
|
|
287
|
+
let path = Path::new("/project/conf/.dirsql.toml");
|
|
288
|
+
let plan = plan_config_extensions(
|
|
289
|
+
&[source(
|
|
290
|
+
path,
|
|
291
|
+
"[[dirsql.extension]]\npath = \"sqlite_vec\"\n",
|
|
292
|
+
)],
|
|
293
|
+
PY,
|
|
294
|
+
)
|
|
295
|
+
.expect("a bare name makes the SDK intervene");
|
|
296
|
+
|
|
297
|
+
assert_eq!(
|
|
298
|
+
plan,
|
|
299
|
+
vec![PlanEntry::Package {
|
|
300
|
+
name: "sqlite_vec".into(),
|
|
301
|
+
shadow: PathBuf::from("/project/conf/sqlite_vec"),
|
|
302
|
+
entrypoint: None,
|
|
303
|
+
}]
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
#[test]
|
|
308
|
+
fn intervening_plans_the_literal_entries_too_and_keeps_config_order() {
|
|
309
|
+
let first = Path::new("/project/one/.dirsql.toml");
|
|
310
|
+
let second = Path::new("/project/two/.dirsql.toml");
|
|
311
|
+
let plan = plan_config_extensions(
|
|
312
|
+
&[
|
|
313
|
+
source(
|
|
314
|
+
first,
|
|
315
|
+
"[[dirsql.extension]]\npath = \"ext/vec0.so\"\nentrypoint = \"sqlite3_vec_init\"\n",
|
|
316
|
+
),
|
|
317
|
+
source(second, "[[dirsql.extension]]\npath = \"sqlite_vec\"\n"),
|
|
318
|
+
],
|
|
319
|
+
PY,
|
|
320
|
+
)
|
|
321
|
+
.expect("a bare name anywhere makes the SDK intervene for the whole set");
|
|
322
|
+
|
|
323
|
+
assert_eq!(
|
|
324
|
+
plan,
|
|
325
|
+
vec![
|
|
326
|
+
PlanEntry::Literal {
|
|
327
|
+
path: PathBuf::from("/project/one/ext/vec0.so"),
|
|
328
|
+
entrypoint: Some("sqlite3_vec_init".into()),
|
|
329
|
+
},
|
|
330
|
+
PlanEntry::Package {
|
|
331
|
+
name: "sqlite_vec".into(),
|
|
332
|
+
shadow: PathBuf::from("/project/two/sqlite_vec"),
|
|
333
|
+
entrypoint: None,
|
|
334
|
+
},
|
|
335
|
+
]
|
|
336
|
+
);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
#[test]
|
|
340
|
+
fn an_absolute_entry_path_is_left_alone() {
|
|
341
|
+
let path = Path::new("/project/.dirsql.toml");
|
|
342
|
+
let plan = plan_config_extensions(
|
|
343
|
+
&[source(
|
|
344
|
+
path,
|
|
345
|
+
"[[dirsql.extension]]\npath = \"/opt/vec0.so\"\n\n[[dirsql.extension]]\npath = \"sqlite_vec\"\n",
|
|
346
|
+
)],
|
|
347
|
+
PY,
|
|
348
|
+
)
|
|
349
|
+
.expect("intervening");
|
|
350
|
+
|
|
351
|
+
assert_eq!(
|
|
352
|
+
plan[0],
|
|
353
|
+
PlanEntry::Literal {
|
|
354
|
+
path: PathBuf::from("/opt/vec0.so"),
|
|
355
|
+
entrypoint: None,
|
|
356
|
+
}
|
|
357
|
+
);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
#[test]
|
|
361
|
+
fn select_loadable_returns_the_single_matching_file() {
|
|
362
|
+
let dir = PathBuf::from("/site-packages/sqlite_vec");
|
|
363
|
+
let found = select_loadable(
|
|
364
|
+
"sqlite_vec",
|
|
365
|
+
std::slice::from_ref(&dir),
|
|
366
|
+
&[
|
|
367
|
+
dir.join("__init__.py"),
|
|
368
|
+
dir.join("vec0.so"),
|
|
369
|
+
dir.join("README.md"),
|
|
370
|
+
],
|
|
371
|
+
PY,
|
|
372
|
+
);
|
|
373
|
+
assert_eq!(found, Ok(dir.join("vec0.so")));
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
#[test]
|
|
377
|
+
fn select_loadable_dedupes_and_sorts_before_counting() {
|
|
378
|
+
let dir = PathBuf::from("/pkg");
|
|
379
|
+
let found = select_loadable(
|
|
380
|
+
"vec",
|
|
381
|
+
std::slice::from_ref(&dir),
|
|
382
|
+
&[dir.join("vec0.so"), dir.join("vec0.so")],
|
|
383
|
+
PY,
|
|
384
|
+
);
|
|
385
|
+
assert_eq!(found, Ok(dir.join("vec0.so")));
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
#[test]
|
|
389
|
+
fn select_loadable_reports_every_searched_directory_when_nothing_matches() {
|
|
390
|
+
let dirs = vec![PathBuf::from("/a"), PathBuf::from("/b")];
|
|
391
|
+
let err = select_loadable("vec", &dirs, &[PathBuf::from("/a/vec.py")], PY)
|
|
392
|
+
.expect_err("no loadable file");
|
|
393
|
+
assert_eq!(
|
|
394
|
+
err.to_string(),
|
|
395
|
+
"no loadable extension file (*.so / *.dylib / *.dll / *.pyd) found in package 'vec' (searched /a, /b)"
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
#[test]
|
|
400
|
+
fn select_loadable_rejects_an_ambiguous_package_in_sorted_order() {
|
|
401
|
+
let dir = PathBuf::from("/pkg");
|
|
402
|
+
let err = select_loadable(
|
|
403
|
+
"vec",
|
|
404
|
+
std::slice::from_ref(&dir),
|
|
405
|
+
&[dir.join("z.so"), dir.join("a.so")],
|
|
406
|
+
PY,
|
|
407
|
+
)
|
|
408
|
+
.expect_err("two loadable files");
|
|
409
|
+
assert_eq!(
|
|
410
|
+
err,
|
|
411
|
+
SelectError::Ambiguous {
|
|
412
|
+
name: "vec".into(),
|
|
413
|
+
matches: vec![dir.join("a.so"), dir.join("z.so")],
|
|
414
|
+
}
|
|
415
|
+
);
|
|
416
|
+
assert_eq!(
|
|
417
|
+
err.to_string(),
|
|
418
|
+
"multiple loadable extension files found in package 'vec': /pkg/a.so, /pkg/z.so; disambiguate with a literal path"
|
|
419
|
+
);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
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
|
|
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
|
{dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-07-13-rename-extract-to-on-file.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-07-20-drop-implicit-files-table.md
RENAMED
|
File without changes
|
{dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-07-21-remove-glob-captures.md
RENAMED
|
File without changes
|