Skip to content

v3.25.0: positional path scope, runtime coverage joins callbacks and object members

Choose a tag to compare

@BartWaardenburg BartWaardenburg released this 11 Sep 08:48
· 639 commits to main since this release
Immutable release. Only release title and notes can be modified.
v3.25.0
30167b4

Scope any file command to a path

Bare fallow, check, dupes, health, audit, security, fix, list and
similar-code now take an optional positional path:

npx fallow src/components
npx fallow health src/api/client.ts
npx fallow fix src/legacy

fallow still builds the whole-project graph, and every cross-file fact stays
sound. Only the reported findings are limited to the path. fix plans and
applies only the fixes that touch scoped files.

Resolution is root-first for a bare relative path. fallow reads ./ and ../
as claims about the current directory. A missing path, or one outside the root,
gets an exit-2 error that says what to do. The run stops there instead of
analysing the whole project. The scope acts as one more
workspace root next to --workspace, and it intersects with --changed-since
and --diff-file. audit limits the set of changed files it considers, which
keeps its result and its base attribution consistent. Its base pass stays
unscoped, because that pass runs in another worktree.

Runtime coverage joins far more of your code

fallow coverage analyze --cloud matches cloud runtime rows against a static
index. That index came from the health and complexity pass, which lists
declarations and bindings and nothing else. The runtime instrumenter names more
shapes than that. An arrow passed to a call takes the name of its callee:
rows.map(...), sqliteTable("t", {}, (table) => [...]),
.references(() => ...). An object-literal method, a getter or setter, and a
function assigned to a member get their own names too. For all of those, the
index held nothing to match. Their rows went into
cloud_functions_unmatched and never appeared in findings or hot_paths. In a
typical service they are the highest-traffic functions, and the top of the
hot-path list was whatever declaration the pass happened to list.

The index now holds every function the instrumenter would name. It resolves them
through the same walker the static inventory upload uses, which makes the
identity match the stable_id the cloud stores. A function known only by the
callee it was passed to is marked as a callback. The text fallow prints for it
names the call site ("Callback passed to map; ...") instead of a declaration
that does not exist.

The static function inventory got the same fix. An object-literal method, a
function-valued property, and a getter or setter kept the (anonymous_N)
placeholder. So did a function assigned to a member expression, and an anonymous
export default. The instrumenter names those functions run, execute,
get closed, rollback and default. Both sides now agree, and an
uploaded inventory entry and the runtime row for one function share a single
identity.

The inventory blob reports its own size guard

fallow coverage upload-inventory --with-callers has always capped the
importer-edge map per callee. The cap keeps a pathological fan-in from bloating
the upload, and it shortened the list silently. Nobody reading the body could
tell a function that genuinely has as many importers as the cap from one that
lost some.

The version 3 body has a callerEdgeLimits header next to callerEdges. The
header holds maxSitesPerFunction, maxSymbolsPerSite and truncatedFunctions.
The command prints a warning that says how many functions lost importer sites.
The header appears only when callerEdges does, and a version 1 or version 2
body keeps exactly the shape it had.

Windows paths read correctly in check and health

Both human renderers printed the separator of the platform. A Windows user read
src\a.ts while dupes, list, fix and every JSON output said src/a.ts.
The split between the dimmed directory and the bold filename keys on /, so the
whole path lost that emphasis as well. Every path those two renderers put on
screen normalises the way the rest of the CLI already did. Path handling on disk
is untouched.

Install

npx fallow@3.25.0
npm install --save-dev fallow@3.25.0
cargo install fallow-cli@3.25.0

Full Changelog: v3.24.1...v3.25.0