dirsql 0.3.87__tar.gz → 0.3.89__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.3.87 → dirsql-0.3.89}/Cargo.lock +1 -1
- {dirsql-0.3.87 → dirsql-0.3.89}/PKG-INFO +1 -1
- {dirsql-0.3.87/packages/python → dirsql-0.3.89}/docs/howto/extract-from-contents.md +1 -1
- {dirsql-0.3.87/packages/rust → dirsql-0.3.89}/docs/reference/hooks.md +2 -2
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/Cargo.toml +1 -1
- {dirsql-0.3.87/packages/rust → dirsql-0.3.89/packages/python}/docs/howto/extract-from-contents.md +1 -1
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/reference/hooks.md +2 -2
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/e2e-attestation.json +2 -2
- {dirsql-0.3.87 → dirsql-0.3.89/packages/rust}/docs/howto/extract-from-contents.md +1 -1
- {dirsql-0.3.87 → dirsql-0.3.89/packages/rust}/docs/reference/hooks.md +2 -2
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/src/command.rs +9 -59
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/src/lib.rs +34 -15
- {dirsql-0.3.87 → dirsql-0.3.89}/Cargo.toml +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/README.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/dirsql/__init__.py +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/dirsql/_async.py +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/dirsql/_dirsql.pyi +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/dirsql/cli/__init__.py +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/dirsql/cli/binary_path.py +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/dirsql/cli/is_windows.py +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/dirsql/cli/main.py +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/dirsql/cli/resolve_config_extensions.py +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/dirsql/py.typed +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/dirsql/resolve_config_extensions.py +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/dirsql/resolve_extension.py +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/.vitepress/config.ts +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/AGENTS.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/explanation.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/getting-started.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/howto/define-tables.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/howto/embed.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/howto/load-extension.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/howto/persist.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/howto/skip-files.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/index.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/migrations.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/package.json +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/playwright.config.ts +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/pnpm-lock.yaml +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/reference/cli.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/reference/columns.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/reference/config.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/reference/http-api.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/reference/sdk.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/tests/integration/home.spec.ts +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/tests/integration/language-flag.spec.ts +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/tests/integration/sidebar.spec.ts +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/tests/unit/config.test.ts +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/tests/unit/lang.test.ts +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/docs/vitest.config.ts +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/README.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/conftest.py +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/.vitepress/config.ts +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/AGENTS.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/explanation.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/getting-started.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/howto/define-tables.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/howto/embed.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/howto/load-extension.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/howto/persist.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/howto/skip-files.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/index.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/migrations.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/package.json +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/playwright.config.ts +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/pnpm-lock.yaml +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/reference/cli.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/reference/columns.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/reference/config.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/reference/http-api.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/reference/sdk.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/tests/integration/home.spec.ts +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/tests/integration/language-flag.spec.ts +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/tests/integration/sidebar.spec.ts +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/tests/unit/config.test.ts +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/tests/unit/lang.test.ts +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/docs/vitest.config.ts +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/src/lib.rs +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/tests/__init__.py +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/tests/conftest.py +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/tests/e2e/__init__.py +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/tests/integration/__init__.py +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/tests/integration/binding/__init__.py +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/python/tests/integration/hermetic/__init__.py +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/Cargo.toml +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/README.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/benches/db_bench.rs +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/benches/differ_bench.rs +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/benches/matcher_bench.rs +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/benches/scanner_bench.rs +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/docs/explanation.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/docs/getting-started.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/docs/howto/define-tables.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/docs/howto/embed.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/docs/howto/load-extension.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/docs/howto/persist.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/docs/howto/skip-files.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/docs/index.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/docs/migrations.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/docs/reference/cli.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/docs/reference/columns.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/docs/reference/config.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/docs/reference/http-api.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/docs/reference/sdk.md +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/src/bin/dirsql.rs +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/src/cli/execute.rs +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/src/cli/init.rs +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/src/cli/mod.rs +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/src/cli/router.rs +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/src/cli/serialize.rs +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/src/cli/server.rs +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/src/config.rs +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/src/db.rs +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/src/default_config.toml +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/src/differ.rs +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/src/matcher.rs +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/src/persist.rs +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/src/scanner.rs +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/packages/rust/src/watcher.rs +0 -0
- {dirsql-0.3.87 → dirsql-0.3.89}/pyproject.toml +0 -0
|
@@ -23,7 +23,7 @@ glob = "books/*.json"
|
|
|
23
23
|
on-file = "jq -c '[{title, author, year}]' {path}"
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
`{path}` is the matched file
|
|
26
|
+
`{path}` is the matched file's absolute path — one of the
|
|
27
27
|
placeholders defined by the
|
|
28
28
|
[command hook contract](../reference/hooks.md#on-file), which also covers
|
|
29
29
|
the argv splitting, working directory, stdout protocol, and timeout shared
|
|
@@ -101,8 +101,8 @@ row-mapping rules.
|
|
|
101
101
|
|
|
102
102
|
| Placeholder | Value |
|
|
103
103
|
|---|---|
|
|
104
|
-
| `{path}` | The matched file's path
|
|
105
|
-
| `{root}` | The index root directory. |
|
|
104
|
+
| `{path}` | The matched file's **absolute** path. `on-file = "extract.py {path}"` — self-sufficient from any working directory, so the command resolves it even when the config lives outside the index. |
|
|
105
|
+
| `{root}` | The index root directory. Derive a root-relative path with `relpath({path}, {root})`. |
|
|
106
106
|
|
|
107
107
|
### `pre-query`
|
|
108
108
|
|
|
@@ -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.3.
|
|
7
|
+
version = "0.3.89"
|
|
8
8
|
# abi3 note: the `abi3-py311` pyo3 feature (below) builds ONE stable-ABI
|
|
9
9
|
# `cp311-abi3` wheel per platform that loads on every CPython >= 3.11
|
|
10
10
|
# (matching `pyproject.toml`'s `requires-python = ">=3.11"`), instead of
|
{dirsql-0.3.87/packages/rust → dirsql-0.3.89/packages/python}/docs/howto/extract-from-contents.md
RENAMED
|
@@ -23,7 +23,7 @@ glob = "books/*.json"
|
|
|
23
23
|
on-file = "jq -c '[{title, author, year}]' {path}"
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
`{path}` is the matched file
|
|
26
|
+
`{path}` is the matched file's absolute path — one of the
|
|
27
27
|
placeholders defined by the
|
|
28
28
|
[command hook contract](../reference/hooks.md#on-file), which also covers
|
|
29
29
|
the argv splitting, working directory, stdout protocol, and timeout shared
|
|
@@ -101,8 +101,8 @@ row-mapping rules.
|
|
|
101
101
|
|
|
102
102
|
| Placeholder | Value |
|
|
103
103
|
|---|---|
|
|
104
|
-
| `{path}` | The matched file's path
|
|
105
|
-
| `{root}` | The index root directory. |
|
|
104
|
+
| `{path}` | The matched file's **absolute** path. `on-file = "extract.py {path}"` — self-sufficient from any working directory, so the command resolves it even when the config lives outside the index. |
|
|
105
|
+
| `{root}` | The index root directory. Derive a root-relative path with `relpath({path}, {root})`. |
|
|
106
106
|
|
|
107
107
|
### `pre-query`
|
|
108
108
|
|
|
@@ -23,7 +23,7 @@ glob = "books/*.json"
|
|
|
23
23
|
on-file = "jq -c '[{title, author, year}]' {path}"
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
`{path}` is the matched file
|
|
26
|
+
`{path}` is the matched file's absolute path — one of the
|
|
27
27
|
placeholders defined by the
|
|
28
28
|
[command hook contract](../reference/hooks.md#on-file), which also covers
|
|
29
29
|
the argv splitting, working directory, stdout protocol, and timeout shared
|
|
@@ -101,8 +101,8 @@ row-mapping rules.
|
|
|
101
101
|
|
|
102
102
|
| Placeholder | Value |
|
|
103
103
|
|---|---|
|
|
104
|
-
| `{path}` | The matched file's path
|
|
105
|
-
| `{root}` | The index root directory. |
|
|
104
|
+
| `{path}` | The matched file's **absolute** path. `on-file = "extract.py {path}"` — self-sufficient from any working directory, so the command resolves it even when the config lives outside the index. |
|
|
105
|
+
| `{root}` | The index root directory. Derive a root-relative path with `relpath({path}, {root})`. |
|
|
106
106
|
|
|
107
107
|
### `pre-query`
|
|
108
108
|
|
|
@@ -15,9 +15,6 @@
|
|
|
15
15
|
//! value that itself contains `{…}` is never re-scanned — a substituted value
|
|
16
16
|
//! is always exactly one argv element, keeping values with spaces (and
|
|
17
17
|
//! untrusted input) injection-safe. An unknown `{…}` is left literal.
|
|
18
|
-
//! - **append-if-absent.** A [`Placeholder`] marked [`Placeholder::append`] is
|
|
19
|
-
//! appended as a final argv element when its `{name}` does not appear in the
|
|
20
|
-
//! template (the `on-file` ergonomic: `cmd {path}` and `cmd` behave the same).
|
|
21
18
|
//! - **cwd / env / timeout.** The child runs in `cwd` (the config file's
|
|
22
19
|
//! directory), inherits dirsql's environment (so `uvx --with …` / `npx …`
|
|
23
20
|
//! dependency resolution works), and is killed if it exceeds `timeout`.
|
|
@@ -44,34 +41,21 @@ pub const DEFAULT_COMMAND_TIMEOUT: Duration = Duration::from_secs(30);
|
|
|
44
41
|
/// A named placeholder substituted into a command's argv.
|
|
45
42
|
///
|
|
46
43
|
/// `name` is the bare identifier (no braces): a `name` of `path` matches the
|
|
47
|
-
/// template token `{path}`.
|
|
44
|
+
/// template token `{path}`. Substitution only — a placeholder whose `{name}`
|
|
45
|
+
/// never appears in the template is a no-op.
|
|
48
46
|
#[derive(Debug, Clone)]
|
|
49
47
|
pub struct Placeholder {
|
|
50
48
|
pub name: String,
|
|
51
49
|
pub value: String,
|
|
52
|
-
/// When `true` and the template contains no `{name}`, `value` is appended
|
|
53
|
-
/// as a final argv element instead of being dropped.
|
|
54
|
-
pub append_if_absent: bool,
|
|
55
50
|
}
|
|
56
51
|
|
|
57
52
|
impl Placeholder {
|
|
58
|
-
///
|
|
59
|
-
///
|
|
53
|
+
/// Replaces `{name}` where it appears, and is a no-op when the template
|
|
54
|
+
/// omits it.
|
|
60
55
|
pub fn new(name: impl Into<String>, value: impl Into<String>) -> Self {
|
|
61
56
|
Self {
|
|
62
57
|
name: name.into(),
|
|
63
58
|
value: value.into(),
|
|
64
|
-
append_if_absent: false,
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/// A placeholder that is *appended* to argv when the template omits its
|
|
69
|
-
/// `{name}` (the `on-file` `{path}` ergonomic).
|
|
70
|
-
pub fn append(name: impl Into<String>, value: impl Into<String>) -> Self {
|
|
71
|
-
Self {
|
|
72
|
-
name: name.into(),
|
|
73
|
-
value: value.into(),
|
|
74
|
-
append_if_absent: true,
|
|
75
59
|
}
|
|
76
60
|
}
|
|
77
61
|
}
|
|
@@ -246,32 +230,23 @@ fn build_argv(command: &str, placeholders: &[Placeholder]) -> Result<Vec<String>
|
|
|
246
230
|
return Err(CommandError::InvalidCommand(command.to_string()));
|
|
247
231
|
}
|
|
248
232
|
|
|
249
|
-
let
|
|
250
|
-
let mut argv: Vec<String> = tokens
|
|
233
|
+
let argv: Vec<String> = tokens
|
|
251
234
|
.iter()
|
|
252
|
-
.map(|token| substitute(token, placeholders
|
|
235
|
+
.map(|token| substitute(token, placeholders))
|
|
253
236
|
.collect();
|
|
254
237
|
|
|
255
|
-
for (i, ph) in placeholders.iter().enumerate() {
|
|
256
|
-
if ph.append_if_absent && !used[i] {
|
|
257
|
-
argv.push(ph.value.clone());
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
|
|
261
238
|
Ok(argv)
|
|
262
239
|
}
|
|
263
240
|
|
|
264
241
|
/// Replace every `{name}` in `token` with its placeholder value in a single
|
|
265
242
|
/// left-to-right pass. Injected values are never re-scanned, so an untrusted
|
|
266
243
|
/// value containing `{…}` is inert. Unknown `{…}` sequences are left literal.
|
|
267
|
-
|
|
268
|
-
fn substitute(token: &str, placeholders: &[Placeholder], used: &mut [bool]) -> String {
|
|
244
|
+
fn substitute(token: &str, placeholders: &[Placeholder]) -> String {
|
|
269
245
|
let mut out = String::with_capacity(token.len());
|
|
270
246
|
let mut i = 0;
|
|
271
247
|
while i < token.len() {
|
|
272
248
|
if let Some((idx, consumed)) = match_placeholder(token, i, placeholders) {
|
|
273
249
|
out.push_str(&placeholders[idx].value);
|
|
274
|
-
used[idx] = true;
|
|
275
250
|
i += consumed;
|
|
276
251
|
continue;
|
|
277
252
|
}
|
|
@@ -417,27 +392,8 @@ mod tests {
|
|
|
417
392
|
}
|
|
418
393
|
|
|
419
394
|
#[test]
|
|
420
|
-
fn
|
|
421
|
-
assert_eq!(
|
|
422
|
-
argv("extract.py", &[Placeholder::append("path", "docs/a.md")]),
|
|
423
|
-
["extract.py", "docs/a.md"]
|
|
424
|
-
);
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
#[test]
|
|
428
|
-
fn append_if_absent_does_not_append_when_the_token_is_present() {
|
|
429
|
-
assert_eq!(
|
|
430
|
-
argv(
|
|
431
|
-
"extract.py --file {path}",
|
|
432
|
-
&[Placeholder::append("path", "docs/a.md")]
|
|
433
|
-
),
|
|
434
|
-
["extract.py", "--file", "docs/a.md"]
|
|
435
|
-
);
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
#[test]
|
|
439
|
-
fn substitute_only_placeholder_is_dropped_when_absent() {
|
|
440
|
-
assert_eq!(argv("run", &[Placeholder::new("extra", "/tmp/x")]), ["run"]);
|
|
395
|
+
fn a_placeholder_the_template_omits_is_dropped() {
|
|
396
|
+
assert_eq!(argv("run", &[Placeholder::new("path", "/tmp/x")]), ["run"]);
|
|
441
397
|
}
|
|
442
398
|
|
|
443
399
|
#[test]
|
|
@@ -476,12 +432,6 @@ mod tests {
|
|
|
476
432
|
assert!(tail.ends_with('x'));
|
|
477
433
|
}
|
|
478
434
|
|
|
479
|
-
#[test]
|
|
480
|
-
fn placeholder_constructors_set_append_flag() {
|
|
481
|
-
assert!(!Placeholder::new("a", "b").append_if_absent);
|
|
482
|
-
assert!(Placeholder::append("a", "b").append_if_absent);
|
|
483
|
-
}
|
|
484
|
-
|
|
485
435
|
// The run_command tests spawn real `sh`/`echo`/`cat`. Their test code must
|
|
486
436
|
// statically reference only `super::` items (plus pure std) to satisfy the
|
|
487
437
|
// unit-lint isolation rule.
|
|
@@ -992,8 +992,9 @@ impl DirSQLBuilder {
|
|
|
992
992
|
};
|
|
993
993
|
config_root = Some(resolved_root.clone());
|
|
994
994
|
|
|
995
|
-
// `on-file` commands run in the config file's directory
|
|
996
|
-
// `{
|
|
995
|
+
// `on-file` commands run in the config file's directory; `{path}`
|
|
996
|
+
// is the matched file's absolute path and `{root}` the resolved
|
|
997
|
+
// index root.
|
|
997
998
|
let cfg_tables = build_tables_from_config(&cfg, &cfg_parent, &resolved_root)?;
|
|
998
999
|
tables.extend(cfg_tables);
|
|
999
1000
|
ignore.extend(cfg.ignore);
|
|
@@ -1379,7 +1380,7 @@ fn relative_path(root: &Path, path: &Path) -> String {
|
|
|
1379
1380
|
/// array of row objects on stdout, which becomes the file's rows (filesystem
|
|
1380
1381
|
/// facts are still merged on top, user values winning). `config_dir` is the
|
|
1381
1382
|
/// command's working directory (the config file's parent) and `root` is the
|
|
1382
|
-
/// resolved index root
|
|
1383
|
+
/// resolved index root exposed as the `{root}` placeholder. Each run is
|
|
1383
1384
|
/// bounded by the global `[dirsql].hook-timeout` key when present, falling
|
|
1384
1385
|
/// back to [`command::DEFAULT_COMMAND_TIMEOUT`].
|
|
1385
1386
|
fn build_tables_from_config(
|
|
@@ -1427,9 +1428,10 @@ fn build_tables_from_config(
|
|
|
1427
1428
|
/// Run a table's `on-file` command for one matched file and parse its output
|
|
1428
1429
|
/// into rows.
|
|
1429
1430
|
///
|
|
1430
|
-
/// Placeholders: `{path}` (the file
|
|
1431
|
-
///
|
|
1432
|
-
///
|
|
1431
|
+
/// Placeholders: `{path}` (the file's absolute path) and `{root}` (the index
|
|
1432
|
+
/// root). An absolute `{path}` is self-sufficient from any cwd, so a hook whose
|
|
1433
|
+
/// config lives outside the index still resolves it. A template that omits a
|
|
1434
|
+
/// placeholder simply never receives its value — nothing is appended.
|
|
1433
1435
|
///
|
|
1434
1436
|
/// Per-file isolation: any failure — a spawn/exit/timeout error from
|
|
1435
1437
|
/// [`command::run_command`], or output that is not a JSON array of objects —
|
|
@@ -1443,13 +1445,8 @@ fn run_on_file(
|
|
|
1443
1445
|
root: &Path,
|
|
1444
1446
|
timeout: Duration,
|
|
1445
1447
|
) -> Vec<Row> {
|
|
1446
|
-
let abs = Path::new(abs_path);
|
|
1447
|
-
let rel = abs
|
|
1448
|
-
.strip_prefix(root)
|
|
1449
|
-
.map(|p| p.to_string_lossy().into_owned())
|
|
1450
|
-
.unwrap_or_else(|_| abs_path.to_string());
|
|
1451
1448
|
let placeholders = [
|
|
1452
|
-
Placeholder::
|
|
1449
|
+
Placeholder::new("path", abs_path),
|
|
1453
1450
|
Placeholder::new("root", root.to_string_lossy().into_owned()),
|
|
1454
1451
|
];
|
|
1455
1452
|
|
|
@@ -2874,9 +2871,8 @@ mod internal_tests {
|
|
|
2874
2871
|
fn run_on_file_parses_command_json_output() {
|
|
2875
2872
|
let dir = TempDir::new().unwrap();
|
|
2876
2873
|
let abs = dir.path().join("f.txt");
|
|
2877
|
-
//
|
|
2878
|
-
//
|
|
2879
|
-
// keeping the JSON payload clean.
|
|
2874
|
+
// The template omits every placeholder, so nothing is appended; the
|
|
2875
|
+
// `printf` payload is the whole output.
|
|
2880
2876
|
let rows = run_on_file(
|
|
2881
2877
|
"printf '[{\"n\":1}]'",
|
|
2882
2878
|
&abs.to_string_lossy(),
|
|
@@ -2907,6 +2903,29 @@ mod internal_tests {
|
|
|
2907
2903
|
assert_eq!(rows[0]["q"], Value::Text("{abspath}".into()));
|
|
2908
2904
|
}
|
|
2909
2905
|
|
|
2906
|
+
/// `{path}` interpolates the matched file's **absolute** path (not a
|
|
2907
|
+
/// root-relative one). The command echoes its `{path}` argument back as a
|
|
2908
|
+
/// row value, and we assert it is byte-for-byte the absolute path even when
|
|
2909
|
+
/// the file sits directly under `root` (the case the old `strip_prefix`
|
|
2910
|
+
/// would have shortened to a bare relative path).
|
|
2911
|
+
#[test]
|
|
2912
|
+
fn run_on_file_passes_absolute_path_for_path_placeholder() {
|
|
2913
|
+
let dir = TempDir::new().unwrap();
|
|
2914
|
+
let abs = dir.path().join("f.txt");
|
|
2915
|
+
let rows = run_on_file(
|
|
2916
|
+
r#"sh -c "printf '[{\"p\":\"%s\"}]' \"$1\"" sh {path}"#,
|
|
2917
|
+
&abs.to_string_lossy(),
|
|
2918
|
+
dir.path(),
|
|
2919
|
+
dir.path(),
|
|
2920
|
+
command::DEFAULT_COMMAND_TIMEOUT,
|
|
2921
|
+
);
|
|
2922
|
+
assert_eq!(rows.len(), 1);
|
|
2923
|
+
assert_eq!(
|
|
2924
|
+
rows[0]["p"],
|
|
2925
|
+
Value::Text(abs.to_string_lossy().into_owned())
|
|
2926
|
+
);
|
|
2927
|
+
}
|
|
2928
|
+
|
|
2910
2929
|
/// A command that cannot be spawned yields no rows (per-file isolation).
|
|
2911
2930
|
#[test]
|
|
2912
2931
|
fn run_on_file_returns_no_rows_on_spawn_failure() {
|
|
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
|
|
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.3.87 → dirsql-0.3.89}/packages/python/docs/tests/integration/language-flag.spec.ts
RENAMED
|
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
|