Skip to content

perf(lock): single-pass lockfile membership; stop per-file awk in clean/doctor #25

Description

@Chemaclass

Context

bashdep::_is_orphan calls bashdep::_lock_get (which forks awk over the whole lockfile) for every file in a directory (bashdep:432), and _should_skip_download does the same per dep (bashdep:400). clean/doctor are therefore O(files) awk spawns.

Scope

  • Load the lockfile’s recorded names once per clean/doctor/install run and test membership in-shell (e.g. a newline-delimited string + case/grep -qxF), or do a single awk that joins the dir listing against the lockfile and emits orphans directly.
  • Keep behavior identical (orphan = regular file, not the lockfile, not the bashdep script, no lock entry).

Acceptance criteria

  • clean and doctor read each lockfile at most once, not once per file
  • Identical output/return codes to today (existing tests stay green)
  • Bench note in the PR: process/awk count before vs after for a dir with N files

Out of scope

Changing lockfile format; parallelism.


Constraints (apply to all bashdep work)

  • Bash 3.2+ compatible — no declare -A, ${var,,}/${var^^}, mapfile, negative array index, &>>.
  • Zero runtime deps beyond curl/wget/awk/mktemp/mkdir/rm/cp/mv/printf/cat/grep/sort/tr/dirname/basename + shell builtins.
  • TDD: write the failing test first (tests/unit/*_test.sh), then implement; keep make test green for the right reason. Mock curl/wget — no network in tests.
  • Quality gate: make test && make sa && make lint must all pass.
  • Update docs/api.md / docs/behavior.md when public API or semantics change; add a CHANGELOG.md ## [Unreleased] entry for any user-visible change.
  • Conventional commits (ref: for refactors); never mention AI/automation. One PR per issue, assigned to Chemaclass.

Metadata

Metadata

Assignees

Labels

performanceRuntime or CI performance

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions