dirsql 0.4.99 → 0.4.101

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.
@@ -67,5 +67,6 @@ why indexes belong to only one of them, are in
67
67
  - Paths outside the root resolve too — `'/var/log/*.log'`, `'../notes'`,
68
68
  `'~/notes/*.md'` — reporting absolute paths
69
69
  ([path-tables reference](../reference/path-tables.md#paths-outside-the-index-root)).
70
- - `node_modules/` and `.git/` are skipped by default so a bare `'./**'` does
71
- not drown in machinery ([skip rules](../reference/path-tables.md#skip-rules)).
70
+ - `.git/` is skipped by default, and a git repo's `.gitignore` hides what it
71
+ lists, so a bare `'./**'` does not drown in machinery
72
+ ([skip rules](../reference/path-tables.md#skip-rules)).
@@ -249,7 +249,7 @@ Config flags are subcommand-local: pass them after `server`
249
249
  | `--port <n>` | `7117` | TCP port to bind. |
250
250
  | `--cors-origin <origin>` | off | Let browser pages on `<origin>` (an exact origin such as `http://localhost:3202`, or `*` for any) call `/query` and open `/events`. See [Cross-origin requests](#cross-origin-requests). |
251
251
  | `--persist [<path>]` | off | Keep the SQLite index on disk between runs so a restart only re-parses files that actually changed. Bare `--persist` caches at `<root>/.dirsql/cache.db`; `--persist <path>` caches at `<path>`. Off by default (the index is ephemeral). Also available on [`dirsql query`](#dirsql-query). See [Keep the index across restarts](../howto/persist.md). |
252
- | `--no-ignore` | off | Scan files a `.gitignore` would hide. [Path-tables](./path-tables.md#skip-rules) respect `.gitignore` files by default; this flag restores the full walk. The built-in skips (`node_modules`/`.git`) and configured `ignore` patterns still apply. Also available on [`dirsql query`](#dirsql-query). |
252
+ | `--no-ignore` | off | Scan files a `.gitignore` would hide. [Path-tables](./path-tables.md#skip-rules) respect `.gitignore` files by default; this flag restores the full walk. The built-in `.git` skip and configured `ignore` patterns still apply. Also available on [`dirsql query`](#dirsql-query). |
253
253
  | `--extension <path>` | none | Load a SQLite extension by literal path, overriding the config's `[[dirsql.extension]]` entries. Repeatable. Format: `<path>` or `<path>::<entrypoint>`. Internal plumbing for the pip/npm launchers, which resolve package-name extensions and pass the resolved paths here — not intended for direct use. When any `--extension` is present, the config file's own extension entries are not loaded. |
254
254
  | `--version` | | Print the version and exit. |
255
255
  | `--help` | | Print usage and exit. |
@@ -47,13 +47,12 @@ ignore = ["node_modules/**", ".git/**"]
47
47
 
48
48
  ### Glob rule
49
49
 
50
- Every glob in dirsql — `ignore`, a `[[table]]`'s `glob`, and a
51
- [path-table](./path-tables.md#writing-the-path) — reads as the shell does:
52
- `*` and `?` match within one path segment and never cross `/`; `**` matches
53
- any depth. So `ignore = ["*"]` hides only the files directly inside the root,
54
- `ignore = ["build/*"]` hides `build/a.o` but not `build/sub/b.o`, and
55
- `glob = "*.json"` selects only the top-level `.json` files; write
56
- `**/*.json` to select them at every depth.
50
+ Every glob in dirsql, whether `ignore`, a `[[table]]`'s `glob` or a
51
+ [path-table](./path-tables.md#writing-the-path), reads as bash does with
52
+ `globstar` on. The [glob page](./glob.md) has the rules, examples and every
53
+ divergence. In short, `*` and `?` stay within one path segment, `**` crosses
54
+ directories, and `glob = "*.json"` selects only top-level `.json` files; write
55
+ `**/*.json` for every depth.
57
56
 
58
57
  Persistence is not a config key. Keep the SQLite index on disk between runs
59
58
  with the [`--persist [PATH]` CLI flag](./cli.md#dirsql-server) — a machine-local
@@ -232,7 +231,7 @@ what its required `on-file` command emits — dirsql injects nothing (see
232
231
  |---|---|---|
233
232
  | `name` | yes | The table's SQL name — the name you query it by. Declared, never derived from `ddl`: dirsql does not read the DDL text. The `ddl` must create a table by this name; if it doesn't, loading fails. |
234
233
  | `ddl` | yes | A SQL batch, run verbatim — any number of statements. It must create a table called `name`; that table holds the file rows, and only the columns it declares are kept (keys the `on-file` command emits that are not declared are dropped). The rest of the batch is yours: indexes, virtual tables, triggers. See [Batch `ddl`](#batch-ddl). |
235
- | `glob` | yes | Glob pattern, [anchored](#glob-anchor) at the config file's directory, under the [one glob rule](#glob-rule): `*` matches one level, `**` any depth. Every table whose glob matches a file receives that file's rows — a file can populate multiple tables. A `{name}` segment is rewritten to `*` (it matches one path segment but captures nothing). |
234
+ | `glob` | yes | Glob pattern, [anchored](#glob-anchor) at the config file's directory, under the [one glob rule](#glob-rule): `*` matches one level, `**` any depth. Every table whose glob matches a file receives that file's rows — a file can populate multiple tables. A `{name}` is a literal, as in bash and a path-table; the [glob page](./glob.md) has the syntax. |
236
235
  | `on-file` | **yes** | A command run once per table, with every matched file's absolute path appended as a trailing argument; its stdout (one JSON array of row objects) is the table's rows. Must be non-empty. A `[[table]]` with no `on-file` is a load error (see [parse errors](#parse-errors)). See [Command hooks](./hooks.md#on-file). |
237
236
  | `strict` | no (default `false`) | When `true`, rows whose keys do not exactly match the declared columns are rejected with an error: extra keys error, and every declared column must be supplied by the `on-file` output. When `false`, extra keys are dropped and missing columns become `NULL`. |
238
237
 
@@ -0,0 +1,139 @@
1
+ # Globs
2
+
3
+ A glob is the string you write where a table name goes (`FROM './docs/*.md'`)
4
+ or in a config `[[table]]`'s `glob`. dirsql reads it the way `bash` does with
5
+ `globstar` on and `dotglob` off, and every place it does not is listed under
6
+ [Divergences from bash](#divergences-from-bash).
7
+
8
+ ## Why bash
9
+
10
+ Bash with `globstar` is the most popular glob behavior. Bash, zsh, node-glob
11
+ and minimatch (npm, ESLint, VS Code, GitHub Actions) and Python's `glob` agree
12
+ on one core: `*`, `?` and `[...]`, recursive `**`, `{a,b}` braces, `*` hiding
13
+ dotfiles, and `**` not entering symlinked directories. Python has no braces
14
+ and follows symlinks; bash breaks that tie. POSIX has no `**` or braces. So
15
+ there is one standard nobody has to learn, the same string works in a
16
+ [path-table](./path-tables.md) and in a [config](./config.md) `glob`, and each
17
+ divergence is a written decision.
18
+
19
+ ## The fixture
20
+
21
+ Every example below runs against this tree. A name ending in `/` is an empty
22
+ directory, `a -> b` is a symlink, and `.gitignore` holds `*.log`.
23
+
24
+ <!-- conformance-tree -->
25
+ ```text
26
+ top.md
27
+ a.md
28
+ b.md
29
+ c.md
30
+ 1.md
31
+ 2.md
32
+ 3.md
33
+ 4.md
34
+ x.txt
35
+ ignored.log
36
+ {q}.md
37
+ [a].md
38
+ [z.md
39
+ my file.md
40
+ .env
41
+ .git/
42
+ .config/app.toml
43
+ .config/.secret
44
+ .config/sub/deep.md
45
+ docs/guide.md
46
+ docs/api.md
47
+ docs/.draft.md
48
+ docs/nested/deep.md
49
+ docs/nested/.cache/x.md
50
+ node_modules/pkg/index.js
51
+ real/r.md
52
+ linkdir -> real
53
+ link.md -> top.md
54
+ broken -> nowhere
55
+ ```
56
+
57
+ ## Examples
58
+
59
+ Each row lists the files the pattern returns, sorted. Every row without a
60
+ divergence was produced by `bash -O globstar -O nullglob` with `dotglob` off,
61
+ run from the fixture's root, keeping only files. The `Divergence` column names
62
+ the rule from [below](#divergences-from-bash) that makes a row differ from
63
+ bash's raw output. `$ROOT` is the fixture's directory and `$BASE` its parent.
64
+
65
+ A test runs every row against dirsql as a path-table and, with the leading
66
+ `./` dropped, as a config `glob`, so this table cannot drift from the code.
67
+
68
+ <!-- conformance-table -->
69
+ | Pattern | Rows | Divergence |
70
+ | --- | --- | --- |
71
+ | `./*.md` | `1.md`, `2.md`, `3.md`, `4.md`, `[a].md`, `[z.md`, `a.md`, `b.md`, `c.md`, `link.md`, `my file.md`, `top.md`, `{q}.md` | |
72
+ | `./**/*.md` | `1.md`, `2.md`, `3.md`, `4.md`, `[a].md`, `[z.md`, `a.md`, `b.md`, `c.md`, `docs/api.md`, `docs/guide.md`, `docs/nested/deep.md`, `link.md`, `linkdir/r.md`, `my file.md`, `real/r.md`, `top.md`, `{q}.md` | |
73
+ | `./**` | `1.md`, `2.md`, `3.md`, `4.md`, `[a].md`, `[z.md`, `a.md`, `b.md`, `c.md`, `docs/api.md`, `docs/guide.md`, `docs/nested/deep.md`, `link.md`, `my file.md`, `node_modules/pkg/index.js`, `real/r.md`, `top.md`, `x.txt`, `{q}.md` | |
74
+ | `./?.md` | `1.md`, `2.md`, `3.md`, `4.md`, `a.md`, `b.md`, `c.md` | |
75
+ | `./[ab].md` | `a.md`, `b.md` | |
76
+ | `./[!a].md` | `1.md`, `2.md`, `3.md`, `4.md`, `b.md`, `c.md` | |
77
+ | `./\[a\].md` | `[a].md` | |
78
+ | `./[z.md` | `[z.md` | |
79
+ | `./{a,b}.md` | `a.md`, `b.md` | |
80
+ | `./{q}.md` | `{q}.md` | |
81
+ | `./{a.md` | none | |
82
+ | `./{1..3}.md` | `1.md`, `2.md`, `3.md` | |
83
+ | `./my file.md` | `my file.md` | |
84
+ | `./.*` | `.env`, `.gitignore` | |
85
+ | `./**/.*` | `.env`, `.gitignore`, `docs/.draft.md` | |
86
+ | `./.env` | `.env` | |
87
+ | `./.config/**` | `.config/app.toml`, `.config/sub/deep.md` | |
88
+ | `./docs/.*` | `docs/.draft.md` | |
89
+ | `./link.md` | `link.md` | |
90
+ | `./linkdir/*` | `linkdir/r.md` | |
91
+ | `./*/r.md` | `linkdir/r.md`, `real/r.md` | |
92
+ | `./**/r.md` | `linkdir/r.md`, `real/r.md` | |
93
+ | `./real/**` | `real/r.md` | |
94
+ | `./docs` | `docs/api.md`, `docs/guide.md` | directory-name |
95
+ | `./docs/` | `docs/api.md`, `docs/guide.md` | directory-name |
96
+ | `./*/` | `docs/api.md`, `docs/guide.md`, `linkdir/r.md`, `real/r.md` | directory-name |
97
+ | `./d*` | none | files-only |
98
+ | `./*.log` | none | gitignore |
99
+ | `./**/*.js` | `node_modules/pkg/index.js` | |
100
+ | `./node_modules/*/index.js` | `node_modules/pkg/index.js` | |
101
+ | `./docs/**/*.md` | `docs/api.md`, `docs/guide.md`, `docs/nested/deep.md` | |
102
+ | `./docs/*.md` | `docs/api.md`, `docs/guide.md` | |
103
+ | `$ROOT/docs/*.md` | `$ROOT/docs/api.md`, `$ROOT/docs/guide.md` | absolute |
104
+ | `~/docs/*.md` | `$ROOT/docs/api.md`, `$ROOT/docs/guide.md` | absolute |
105
+ | `../proj/docs/*.md` | `$BASE/proj/docs/api.md`, `$BASE/proj/docs/guide.md` | absolute |
106
+
107
+ ## Divergences from bash
108
+
109
+ | Tag | Rule | Why |
110
+ | --- | --- | --- |
111
+ | `gitignore` | Inside a git repo, `.gitignore` files hide matching files and directories. `--no-ignore` turns it off. | A query over a repo should not drown in build output. |
112
+ | `directory-name` | A pattern's last component that names a directory lists the files directly inside it, like `ls docs`. A trailing `/` is `*` appended. | A table is rows of files, and `ls` is the shell habit. |
113
+ | `files-only` | A pattern that matches a directory but no file returns nothing. | Every row is a file. |
114
+ | `absolute` | `/`, `~/` and `../` patterns report absolute `path` values, with `..` folded out textually. | The scanned root is derived from the pattern, so there is no relative base. |
115
+
116
+ `.git` needs no rule of its own: the dotfile rule hides it.
117
+
118
+ ## Where the glob is anchored
119
+
120
+ A path-table pattern is relative to the index root and starts with `./`. A config `[[table]] glob`
121
+ is relative to the directory holding its config file, whatever directory you
122
+ run `dirsql` from, and is written without the `./`: `./docs/*.md` in a path-table
123
+ is `glob = "docs/*.md"` in a config. A config table whose glob matches no files prints
124
+ `dirsql: table 'name': glob 'pattern' matched no files under <anchor>` to
125
+ stderr; the exit code is unchanged. Path-tables never warn.
126
+
127
+ ## Edge cases
128
+
129
+ - A `{`, `}` or `[` with no partner is a literal character.
130
+ - A brace group with no comma and no `..` is literal (`{q}`); `{1..3}` and
131
+ `{a..c}` expand, as do zero-padded
132
+ `{01..10}` and stepped `{1..10..2}` ranges. Groups nest.
133
+ - `\[` is a literal bracket.
134
+ - A dot-named file or directory is listed only where a component spells the
135
+ dot at that depth: `./**/.*` finds `docs/.draft.md` but does not enter
136
+ `.config/`.
137
+ - A symlinked file is a file. A symlinked directory is entered by any component
138
+ except `**`.
139
+ - A broken link lists nothing.
@@ -52,16 +52,8 @@ depth, as in the shell. A trailing `/` is `*` appended, so `'./*/'` is
52
52
  | `'./notes/today.md'` | exactly that one file — one file is one row |
53
53
 
54
54
  A path containing `*`, `?`, `[` or `{` is a glob and is used exactly as
55
- written: `*` matches within a single directory, `**` crosses directories.
56
-
57
- Braces expand as bash expands them. A group holding a comma is an
58
- alternation: `'./docs/{a,b}.md'` is `docs/a.md` and `docs/b.md`, and groups
59
- nest. A group holding a `..` range counts: `'./log/{1..3}.txt'`,
60
- `'./{a..c}.md'`, `'./{01..10}.md'` (zero-padded) and `'./{1..10..2}.md'`
61
- (every second value). Any other brace is literal text, so `'./br/{q}.md'`
62
- names the file `br/{q}.md`, and `\{` is always a literal brace. A `{`, `}`
63
- or `[` with no partner is literal too, in a path-table and in a config
64
- `[[table]] glob`.
55
+ written. The [glob page](./glob.md) has the syntax, examples and every
56
+ divergence from bash, including braces and unbalanced brackets.
65
57
 
66
58
  The scan starts at the last directory named outright before the first glob
67
59
  component, and descends only as deep as the pattern can match --
@@ -206,8 +198,8 @@ over a very large table. Its output *is* the table:
206
198
  ```
207
199
  dirsql_parsed: parser produced no rows for `posts/*.md`; cannot infer a schema
208
200
  ```
209
- - **The skip rules still apply.** A parsed scan honors the same `node_modules`
210
- /`.git`/`ignore` rules a stat scan does (see below).
201
+ - **The skip rules still apply.** A parsed scan honors the same `.git`
202
+ /`ignore` rules a stat scan does (see below).
211
203
  - **The parser runs on every start.** A parsed path-table is not kept in the
212
204
  [persistent cache](/howto/persist); declared tables are.
213
205
 
@@ -259,14 +251,9 @@ choice is stated as one trade in
259
251
  A path-table scan applies the same [`ignore`](/reference/config) patterns your
260
252
  declared tables use — matched against root-relative paths under the same
261
253
  [glob rule](/reference/config#glob-rule) as the path itself, `*` one level and
262
- `**` any depth — plus two built-in defaults so a zero-config
263
- `SELECT * FROM './**'` does not drown in machinery:
264
-
265
- - `**/node_modules/**`
266
- - `**/.git/**`
267
-
268
- Both apply at any depth, so a `node_modules` nested inside a subdirectory is
269
- skipped just like one at the top.
254
+ `**` any depth — plus one built-in default, `**/.git/**`, which applies at any depth.
255
+ `node_modules` is an ordinary directory: a `.gitignore` that lists it hides it,
256
+ as it hides any other.
270
257
 
271
258
  ### `.gitignore`
272
259
 
@@ -274,9 +261,7 @@ Path-table scans also respect `.gitignore` files by default, inside a git
274
261
  repo, the way git, fd and ripgrep do: a `.gitignore` applies below its own
275
262
  directory, deeper files override shallower ones, `!pattern` re-includes, and
276
263
  an ignored directory is pruned rather than walked. In a typical repo this
277
- excludes build output, virtualenvs, and caches with zero ceremony. The
278
- built-in defaults above remain as a floor for directories with no
279
- `.gitignore` at all.
264
+ excludes build output, virtualenvs, and caches with zero ceremony.
280
265
 
281
266
  A `.gitignore` is in force only when a directory holding `.git` encloses it.
282
267
  Outside a repo none applies, at the scan's start, above it or below it: a
@@ -288,7 +273,7 @@ applies, including those above the directory a scan starts in, so
288
273
  Pass [`--no-ignore`](./cli.md#flags) to restore the full walk — the
289
274
  determinism switch for scripted use, since results otherwise depend on
290
275
  `.gitignore` state. It disables only the `.gitignore` respect; the built-in
291
- defaults and configured `ignore` patterns still apply.
276
+ default and configured `ignore` patterns still apply.
292
277
 
293
278
  ### Naming a skipped directory
294
279
 
@@ -296,23 +281,13 @@ Skip rules are judged from the directory the scan starts in, so pointing at a
296
281
  skipped directory — built-in or gitignored — still scans it:
297
282
 
298
283
  ```sql
299
- SELECT path FROM './**'; -- no node_modules rows
300
- SELECT path FROM './node_modules/*/package.json'; -- scans it anyway
284
+ SELECT path FROM './.git/*'; -- scans .git anyway
301
285
  SELECT path FROM './dist'; -- scans dist/ even when gitignored
302
286
  ```
303
287
 
304
288
  The `.gitignore` files in force there, including those above it, still
305
289
  filter what lies beneath it.
306
290
 
307
- A `node_modules` component after a glob names it too, at any depth:
308
-
309
- ```sql
310
- SELECT path FROM './**/node_modules/*/package.json'; -- every node_modules
311
- SELECT path FROM './*/node_modules/**'; -- one level down
312
- ```
313
-
314
- Only the literal name counts; `'./**/*.js'` still skips every `node_modules`.
315
-
316
291
  ### Hidden files
317
292
 
318
293
  A path component starting with `.` is skipped unless the path spells it, the
@@ -123,7 +123,7 @@ shortcut was removed in #603 — use
123
123
  matched files are skipped entirely (scan and watch).
124
124
  - `no_ignore` / `noIgnore` — Scan files a `.gitignore` would hide.
125
125
  [Path-tables](./path-tables.md#skip-rules) respect `.gitignore` files by
126
- default; the built-in `node_modules`/`.git` skips and any `ignore` patterns
126
+ default; the built-in `.git` skip and any `ignore` patterns
127
127
  still apply. The CLI's [`--no-ignore`](./cli.md#flags).
128
128
  - `config` — Path to a [`.dirsql.toml`](./config.md). Its `[[table]]`
129
129
  entries are appended after any programmatic `tables`; its `ignore`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dirsql",
3
- "version": "0.4.99",
3
+ "version": "0.4.101",
4
4
  "description": "Ephemeral SQL index over a local directory",
5
5
  "license": "MIT",
6
6
  "repository": "https://github.com/thekevinscott/dirsql",
@@ -221,10 +221,10 @@
221
221
  ]
222
222
  },
223
223
  "optionalDependencies": {
224
- "@dirsql/lib-linux-x64-gnu": "0.4.99",
225
- "@dirsql/lib-linux-arm64-gnu": "0.4.99",
226
- "@dirsql/lib-darwin-x64": "0.4.99",
227
- "@dirsql/lib-darwin-arm64": "0.4.99",
228
- "@dirsql/lib-win32-x64-msvc": "0.4.99"
224
+ "@dirsql/lib-linux-x64-gnu": "0.4.101",
225
+ "@dirsql/lib-linux-arm64-gnu": "0.4.101",
226
+ "@dirsql/lib-darwin-x64": "0.4.101",
227
+ "@dirsql/lib-darwin-arm64": "0.4.101",
228
+ "@dirsql/lib-win32-x64-msvc": "0.4.101"
229
229
  }
230
230
  }