Module: OKF::MCP::Filters
- Defined in:
- lib/okf/mcp/filters.rb
Overview
The dir vocabulary, in one place.
It lived in two — one copy in the server, one in the memory backend, each
commented "the CLI's one rule kept verbatim" — and they drifted: only one
of them mapped "" and "/" onto the root, so catalog(dir: "/")
reported an empty bundle root while search and dirs answered for it.
Two copies of a rule is two answers waiting to disagree, so there is one.
There are genuinely two rules here, and the distinction is not drift. Only one of them still lives in this file:
concepts are filtered by `Bundle::RowFilter`, the kernel's one
catalog-row predicate — a dir names itself and everything
beneath it, and `.` is a prefix of nothing, so the root
selects only what lives directly in it (the CLI's `--dir`).
This module's job there is #normalize_dir, the spelling
fold the kernel deliberately does not do.
#within? scopes a *tree* of directory rows, where the root is the
ancestor of every row (`dirs`/`index` walking down). The
kernel has no view of a directory tree, so this one stays.
Class Method Summary collapse
- .dir_depth(dir) ⇒ Object
- .fold(value) ⇒ Object
-
.known_dir?(dirs, wanted) ⇒ Boolean
Is
wanteda directory this set actually has? Folded, and blind to a trailing slash, so it accepts the spelling the views print back. -
.normalize_dir(value) ⇒ Object
A
dirargument as the tools compare it: case-folded, trailing slashes gone, and both spellings of the bundle root — "." and "/" — normalized to ".". -
.within?(entry_dir, base) ⇒ Boolean
Tree scoping: the root is the ancestor of every row, so
.selects the whole tree rather than only what sits directly in it.
Class Method Details
.dir_depth(dir) ⇒ Object
65 66 67 |
# File 'lib/okf/mcp/filters.rb', line 65 def dir_depth(dir) dir == "." ? 0 : dir.split("/").length end |
.fold(value) ⇒ Object
28 29 30 |
# File 'lib/okf/mcp/filters.rb', line 28 def fold(value) value.to_s.downcase end |
.known_dir?(dirs, wanted) ⇒ Boolean
Is wanted a directory this set actually has? Folded, and blind to a
trailing slash, so it accepts the spelling the views print back.
71 72 73 74 75 76 |
# File 'lib/okf/mcp/filters.rb', line 71 def known_dir?(dirs, wanted) base = normalize_dir(wanted) return true if base == "." dirs.any? { |dir| fold(dir) == base } end |
.normalize_dir(value) ⇒ Object
A dir argument as the tools compare it: case-folded, trailing slashes
gone, and both spellings of the bundle root — "." and "/" — normalized
to ".".
A blank argument never reaches here as a filter. Every concept filter
short-circuits on OKF.blank? first, because a client that fills each
declared optional property with "" is doing something routine and means
"no filter" by it — so "" and an omitted dir are the same ask, and
neither is a synonym for the root. In the tree scoping the two coincide
anyway: . is the ancestor of every row, so a blank normalizes to "."
and selects the whole tree.
Deliberately not the CLI's fold_dir, which also folds the literal
name "root". Its whole rationale there is that a shell needs no quoting
for it; a JSON argument has no such problem, and no dir description on
this surface ever advertised the spelling. Importing it cost a bundle
with a real root/ directory the ability to name it — dir: "root"
answered for the bundle root instead, and scoped_rows skips its
existence check for the root, so not even the refusal fired.
51 52 53 54 |
# File 'lib/okf/mcp/filters.rb', line 51 def normalize_dir(value) folded = fold(value).sub(%r{/+\z}, "") folded.empty? || folded == "." ? "." : folded end |
.within?(entry_dir, base) ⇒ Boolean
Tree scoping: the root is the ancestor of every row, so . selects
the whole tree rather than only what sits directly in it.
58 59 60 61 62 63 |
# File 'lib/okf/mcp/filters.rb', line 58 def within?(entry_dir, base) return true if base == "." entry = fold(entry_dir) entry == base || entry.start_with?("#{base}/") end |