dirsql 0.4.98 → 0.4.100

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.
@@ -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,140 @@
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`, `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` | none | node-modules |
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
+ | `node-modules` | A `node_modules` directory is skipped unless the pattern spells its name. | A zero-config `./**` should not walk dependencies. |
115
+ | `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. |
116
+
117
+ `.git` needs no rule of its own: the dotfile rule hides it.
118
+
119
+ ## Where the glob is anchored
120
+
121
+ A path-table pattern is relative to the index root and starts with `./`. A config `[[table]] glob`
122
+ is relative to the directory holding its config file, whatever directory you
123
+ run `dirsql` from, and is written without the `./`: `./docs/*.md` in a path-table
124
+ is `glob = "docs/*.md"` in a config. A config table whose glob matches no files prints
125
+ `dirsql: table 'name': glob 'pattern' matched no files under <anchor>` to
126
+ stderr; the exit code is unchanged. Path-tables never warn.
127
+
128
+ ## Edge cases
129
+
130
+ - A `{`, `}` or `[` with no partner is a literal character.
131
+ - A brace group with no comma and no `..` is literal (`{q}`); `{1..3}` and
132
+ `{a..c}` expand, as do zero-padded
133
+ `{01..10}` and stepped `{1..10..2}` ranges. Groups nest.
134
+ - `\[` is a literal bracket.
135
+ - A dot-named file or directory is listed only where a component spells the
136
+ dot at that depth: `./**/.*` finds `docs/.draft.md` but does not enter
137
+ `.config/`.
138
+ - A symlinked file is a file. A symlinked directory is entered by any component
139
+ except `**`.
140
+ - 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 --
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dirsql",
3
- "version": "0.4.98",
3
+ "version": "0.4.100",
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.98",
225
- "@dirsql/lib-linux-arm64-gnu": "0.4.98",
226
- "@dirsql/lib-darwin-x64": "0.4.98",
227
- "@dirsql/lib-darwin-arm64": "0.4.98",
228
- "@dirsql/lib-win32-x64-msvc": "0.4.98"
224
+ "@dirsql/lib-linux-x64-gnu": "0.4.100",
225
+ "@dirsql/lib-linux-arm64-gnu": "0.4.100",
226
+ "@dirsql/lib-darwin-x64": "0.4.100",
227
+ "@dirsql/lib-darwin-arm64": "0.4.100",
228
+ "@dirsql/lib-win32-x64-msvc": "0.4.100"
229
229
  }
230
230
  }