Skip to content

feat: install from lockfile#48

Open
fbosch wants to merge 2 commits into
masterfrom
feature/install-from-lock
Open

feat: install from lockfile#48
fbosch wants to merge 2 commits into
masterfrom
feature/install-from-lock

Conversation

@fbosch
Copy link
Copy Markdown
Owner

@fbosch fbosch commented May 22, 2026

Summary

  • Add docs-cache install [id...] to restore cache/targets from docs-lock.json without rewriting the lock file.
  • Use locked repo/ref/commit data during install and fail when lock entries are missing or materialization rules drift from config.
  • Update README postinstall guidance and add install/CLI parser tests.

Validation

  • pnpm test
  • pnpm typecheck
  • rtk proxy pnpm lint

Summary by CodeRabbit

  • New Features

    • Added an install command to restore cached docs from a lock file, supporting offline restoration and optional source filtering.
  • Bug Fixes

    • Install now validates lock consistency and rejects installs when the lock is missing, out-of-date, or used with incompatible flags.
  • Documentation

    • Updated workflow and postinstall guidance to recommend the install step before a frozen sync and clarified pinning behavior.
  • Tests

    • Added integration and parsing tests covering install behavior and lock validation.

Review Change Stack

Copilot AI review requested due to automatic review settings May 22, 2026 08:24
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 22, 2026

📝 Walkthrough

Walkthrough

Adds an install CLI command that restores docs from an existing lock without resolving remote refs or rewriting the lock; includes CLI parsing, wiring into the sync command with lock validation, tests, and README updates.

Changes

Install Command Feature

Layer / File(s) Summary
CLI command contract and parsing
src/cli/types.ts, src/types/sync.ts, src/cli/parse-args.ts
New install command variant added to CliCommand union and SyncOptions type; argument parser recognizes install [id...] and maps it to parsed command structure.
Install command handler and dispatcher
src/cli/index.ts
runInstallCommand handler wires install mode to sync with lock-based restoration; help text and command dispatcher case added; argument validation in main() exempts install from positionals error.
Install mode execution in sync command
src/commands/sync.ts
Plan generation branches to new buildInstallResult for install mode, deriving commit from lock entry; assertInstallLock validator ensures lock exists and rule hashes and repo/ref match; finalizeSync skips lock rewriting when installing; job runner selects repo/ref from lock during fetch; early guard rejects install && lockOnly combination.
Integration tests and documentation
tests/cli-parse.test.js, tests/install.test.js, README.md
CLI parsing test for install command; integration tests verify lock-based restoration and that stale/drifted locks are rejected; README updated to show install in usage and npm postinstall example.

Sequence Diagram

sequenceDiagram
  participant CLI as runInstallCommand
  participant Sync as runSync
  participant Plan as getSyncPlan
  participant Build as buildInstallResult
  participant Validate as assertInstallLock
  participant Fetch as createJobRunner
  participant Finalize as finalizeSync
  CLI->>Sync: invoke with install: true, lockOnly: false
  Sync->>Sync: reject install && lockOnly
  Sync->>Plan: request plan (install branch)
  Plan->>Build: buildInstallResult (derive resolvedCommit from lock)
  Build->>Plan: set status (missing/changed/up-to-date)
  Sync->>Validate: assertInstallLock(plan)
  Validate->>Sync: throw if lock missing/stale or repo/ref drift
  Sync->>Fetch: createJobRunner using lock repo/ref
  Fetch->>Fetch: fetch and materialize from lock values
  Sync->>Finalize: finalize without rewriting docs-lock.json
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly Related PRs

  • fbosch/docs-cache#36: Overlaps in createJobRunner/job execution area and related fetch/job guards that this PR also modifies.
  • fbosch/docs-cache#16: Changes to lock filename handling referenced by install-mode lock usage.
  • fbosch/docs-cache#26: Related extension of SyncOptions and lock-handling behavior in runSync.

Poem

🐇 I hop to the lock, quiet and still,
I fetch from its truth, no network will—
Materialize pages, leave the lock as found,
Docs snug at home, not a ref unwound.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat: install from lockfile' accurately and concisely describes the main change: adding a new install command that restores cache from a lockfile without rewriting it.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/install-from-lock

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 22, 2026

Open in StackBlitz

npx https://pkg.pr.new/docs-cache@48

commit: d021045

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new docs-cache install [id...] workflow to restore cache/targets directly from docs-lock.json without rewriting the lock file, enabling more deterministic installs (e.g., in CI or postinstall) while still failing when the lock is missing or out-of-date.

Changes:

  • Introduces install mode in the sync planner/executor to use lock data and skip lockfile writes.
  • Extends CLI parsing/dispatch to support docs-cache install [id...].
  • Adds tests for install behavior and CLI parsing, and updates README guidance.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/install.test.js Adds install-mode integration tests (materialize from lock; fail on rules drift).
tests/cli-parse.test.js Adds CLI parser test for install positional source filters.
src/types/sync.ts Extends SyncOptions with install?: boolean.
src/commands/sync.ts Implements install-mode planning, lock assertions, and skips lock rewrites during install.
src/cli/types.ts Adds install to the CLI command union.
src/cli/parse-args.ts Adds install command parsing and help registration.
src/cli/index.ts Adds install command execution path and wiring into runSync.
README.md Documents install usage and updates postinstall guidance.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/commands/sync.ts
Comment thread tests/install.test.js
Comment thread README.md Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/commands/sync.ts`:
- Around line 793-796: The drift detection in driftedSources uses source.ref
directly which misses the fallback to plan.defaults.ref used elsewhere; update
the filter in driftedSources to compute the effective ref (e.g., effectiveRef =
source.ref ?? plan.defaults?.ref or source.ref || plan.defaults?.ref) and
compare lockEntry.ref against that effectiveRef (keep the existing repo
comparison with source.repo), so inherited default refs are treated as matching
the lock.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 31970230-570c-4edb-9c3b-a1199d62b805

📥 Commits

Reviewing files that changed from the base of the PR and between 13c2b5d and d021045.

📒 Files selected for processing (3)
  • README.md
  • src/commands/sync.ts
  • tests/install.test.js
✅ Files skipped from review due to trivial changes (1)
  • README.md

Comment thread src/commands/sync.ts
Comment on lines +793 to +796
const driftedSources = plan.sources.filter((source) => {
const lockEntry = plan.lockData?.sources[source.id];
return lockEntry?.repo !== source.repo || lockEntry.ref !== source.ref;
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Compare drift against the effective ref, not the raw source field.

Line 795 uses source.ref directly, but this file falls back to plan.defaults.ref elsewhere. If a source inherits the default ref, this will report a matching lock as drifted and make docs-cache install fail on a valid lock.

Suggested fix
 const driftedSources = plan.sources.filter((source) => {
 	const lockEntry = plan.lockData?.sources[source.id];
-	return lockEntry?.repo !== source.repo || lockEntry.ref !== source.ref;
+	if (!lockEntry) {
+		return false;
+	}
+	const expectedRef = source.ref ?? plan.defaults.ref;
+	return lockEntry.repo !== source.repo || lockEntry.ref !== expectedRef;
 });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/commands/sync.ts` around lines 793 - 796, The drift detection in
driftedSources uses source.ref directly which misses the fallback to
plan.defaults.ref used elsewhere; update the filter in driftedSources to compute
the effective ref (e.g., effectiveRef = source.ref ?? plan.defaults?.ref or
source.ref || plan.defaults?.ref) and compare lockEntry.ref against that
effectiveRef (keep the existing repo comparison with source.repo), so inherited
default refs are treated as matching the lock.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants