mirror of
https://github.com/anomalyco/opencode.git
synced 2026-09-07 10:44:35 +00:00
fix(util): stage npm installs under the cache directory's real path (#46887)
This commit is contained in:
parent
44e0b35303
commit
db09cc842e
2 changed files with 32 additions and 1 deletions
|
|
@ -319,6 +319,31 @@ describe("Npm.add", () => {
|
|||
expect(result.pinned).toContain("root: true")
|
||||
expect(result.current).toBeFalse()
|
||||
}, 30_000)
|
||||
|
||||
// Symlink creation needs elevated privileges on Windows.
|
||||
test.skipIf(win)("records Git revisions when the cache directory is reached through a symlink", async () => {
|
||||
await using tmp = await tmpdir()
|
||||
const fixture = await createGitFixture(tmp.path)
|
||||
await fs.mkdir(path.join(tmp.path, "cache"))
|
||||
await fs.symlink(path.join(tmp.path, "cache"), path.join(tmp.path, "link"))
|
||||
const mutable = `git+${pathToFileURL(fixture.repository).href}#fixture-branch`
|
||||
|
||||
const result = await Effect.gen(function* () {
|
||||
const npm = yield* Npm.Service
|
||||
const added = yield* npm.add(mutable)
|
||||
const current = yield* npm.check(mutable)
|
||||
yield* Effect.promise(async () => {
|
||||
await Bun.write(path.join(fixture.repository, "index.js"), 'export default { root: "second" }\n')
|
||||
await Bun.$`git -C ${fixture.repository} add .`
|
||||
await Bun.$`git -C ${fixture.repository} -c user.name=fixture -c user.email=fixture@example.com commit -qm second`
|
||||
})
|
||||
return { added, current, outdated: yield* npm.check(mutable) }
|
||||
}).pipe(Effect.scoped, Effect.provide(npmLayer(path.join(tmp.path, "link"))), Effect.runPromise)
|
||||
|
||||
expect(result.added.version).toBe(fixture.commit)
|
||||
expect(result.current).toBeFalse()
|
||||
expect(result.outdated).toBeTrue()
|
||||
}, 30_000)
|
||||
})
|
||||
|
||||
describe("Npm.resolve", () => {
|
||||
|
|
|
|||
|
|
@ -286,7 +286,13 @@ const layer = Layer.effect(
|
|||
|
||||
yield* mkdir(dir)
|
||||
const startedAt = yield* Clock.currentTimeMillis
|
||||
const staging = path.join(dir, `.staging-${startedAt}-${randomUUID()}`)
|
||||
// Arborist keys lockfile entries relative to the root's real path. When the cache
|
||||
// directory is reached through a symlink (macOS `/var` → `/private/var`, a linked
|
||||
// XDG cache), the keys become `../../…` paths that installedRevision never finds,
|
||||
// so Git checks report "not installed" and updates go undetected. Stage under the
|
||||
// resolved directory so the root path and real path agree.
|
||||
const root = yield* fs.realPath(dir).pipe(Effect.mapError((cause) => new InstallFailedError({ dir, cause })))
|
||||
const staging = path.join(root, `.staging-${startedAt}-${randomUUID()}`)
|
||||
const staged = yield* Effect.gen(function* () {
|
||||
const tree = yield* reify({ dir: staging, config: dir, add: [pkg], update })
|
||||
const installed = tree.edgesOut.values().next().value?.to
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue