Skip to content

Commit 9239b9e

Browse files
committed
test(entrypoint): use @effect/platform FileSystem to satisfy Effect-TS lint
1 parent b38ae32 commit 9239b9e

1 file changed

Lines changed: 52 additions & 43 deletions

File tree

packages/lib/tests/shell/entrypoint-clone-target.test.ts

Lines changed: 52 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5,56 +5,65 @@
55
// REF: issue-408
66
// SOURCE: n/a
77
// FORMAT THEOREM: defaultTargetDir(entrypoint) = appDir(Dockerfile) ∧ appDir ⊂ chown(dev, /home/dev)
8-
// PURITY: SHELL (reads repository source files)
8+
// PURITY: SHELL (reads repository source files via @effect/platform FileSystem)
99
// INVARIANT: clone target is owned by the unprivileged clone user
1010
// COMPLEXITY: O(|file|)
11+
import * as FileSystem from "@effect/platform/FileSystem"
12+
import * as Path from "@effect/platform/Path"
13+
import { NodeContext } from "@effect/platform-node"
1114
import { describe, expect, it } from "@effect/vitest"
12-
import { readFileSync } from "node:fs"
13-
import path from "node:path"
14-
import { fileURLToPath } from "node:url"
15+
import { Effect } from "effect"
1516

16-
const __filename = fileURLToPath(import.meta.url)
17-
const __dirname = path.dirname(__filename)
18-
// packages/lib/tests/shell -> repository root
19-
const repoRoot = path.resolve(__dirname, "..", "..", "..", "..")
17+
// CHANGE: derive the dev home that the Dockerfile recursively chowns to the clone user
18+
// WHY: `git clone` runs as `su - dev`, so the target must live under a dev-owned path
19+
// PURITY: CORE
20+
// INVARIANT: returns the `chown -R dev:dev <home>` argument, or "" when absent
21+
const matchChownedHome = (dockerfile: string): string =>
22+
dockerfile.match(/chown -R dev:dev (\/home\/dev)\b/)?.[1] ?? ""
2023

21-
const readRepoFile = (relativePath: string): string =>
22-
readFileSync(path.join(repoRoot, relativePath), "utf8")
24+
// CHANGE: derive the default TARGET_DIR the entrypoint clones into
25+
// WHY: the bug is a wrong default that points outside the dev-owned home
26+
// PURITY: CORE
27+
// INVARIANT: returns the `TARGET_DIR="${TARGET_DIR:-<default>}"` value, or "" when absent
28+
const matchDefaultTargetDir = (entrypoint: string): string =>
29+
entrypoint.match(/TARGET_DIR="\$\{TARGET_DIR:-([^}]+)\}"/)?.[1] ?? ""
2330

24-
describe("standalone base-image clone target", () => {
25-
const entrypoint = readRepoFile("entrypoint.sh")
26-
const dockerfile = readRepoFile("Dockerfile")
27-
28-
// CHANGE: derive the dev home that the Dockerfile recursively chowns to the clone user
29-
// WHY: `git clone` runs as `su - dev`, so the target must live under a dev-owned path
30-
// PURITY: CORE
31-
// INVARIANT: chownedHome captures the `chown -R dev:dev <home>` argument
32-
const chownedHome = (() => {
33-
const match = dockerfile.match(/chown -R dev:dev (\/home\/dev)\b/)
34-
return match?.[1]
35-
})()
36-
37-
// CHANGE: derive the default TARGET_DIR the entrypoint clones into
38-
// WHY: the bug is a wrong default that points outside the dev-owned home
39-
// PURITY: CORE
40-
// INVARIANT: defaultTargetDir captures `TARGET_DIR="${TARGET_DIR:-<default>}"`
41-
const defaultTargetDir = (() => {
42-
const match = entrypoint.match(/TARGET_DIR="\$\{TARGET_DIR:-([^}]+)\}"/)
43-
return match?.[1]
44-
})()
31+
// CHANGE: read the repo-root entrypoint + Dockerfile through the Effect FileSystem service
32+
// WHY: lint forbids node:* imports; @effect/platform is the sanctioned IO boundary
33+
// PURITY: SHELL
34+
// EFFECT: Effect<{ entrypoint, dockerfile }, PlatformError | BadArgument, FileSystem | Path>
35+
const readRepoSources = Effect.gen(function*(_) {
36+
const fs = yield* _(FileSystem.FileSystem)
37+
const path = yield* _(Path.Path)
38+
const here = yield* _(path.fromFileUrl(new URL(import.meta.url)))
39+
// packages/lib/tests/shell -> repository root
40+
const repoRoot = path.resolve(path.dirname(here), "..", "..", "..", "..")
41+
const entrypoint = yield* _(fs.readFileString(path.join(repoRoot, "entrypoint.sh")))
42+
const dockerfile = yield* _(fs.readFileString(path.join(repoRoot, "Dockerfile")))
43+
return { dockerfile, entrypoint }
44+
})
4545

46-
it("prepares an app folder under the dev home in the Dockerfile", () => {
47-
expect(dockerfile).toContain("mkdir -p /home/dev/app")
48-
expect(chownedHome).toBe("/home/dev")
49-
})
46+
describe("standalone base-image clone target", () => {
47+
it.effect("prepares an app folder under the dev home in the Dockerfile", () =>
48+
Effect.gen(function*(_) {
49+
const { dockerfile } = yield* _(readRepoSources)
50+
expect(dockerfile).toContain("mkdir -p /home/dev/app")
51+
expect(matchChownedHome(dockerfile)).toBe("/home/dev")
52+
}).pipe(Effect.provide(NodeContext.layer)))
5053

51-
it("defaults the clone target to the prepared app folder", () => {
52-
expect(defaultTargetDir).toBe("/home/dev/app")
53-
})
54+
it.effect("defaults the clone target to the prepared app folder", () =>
55+
Effect.gen(function*(_) {
56+
const { entrypoint } = yield* _(readRepoSources)
57+
expect(matchDefaultTargetDir(entrypoint)).toBe("/home/dev/app")
58+
}).pipe(Effect.provide(NodeContext.layer)))
5459

55-
it("keeps the clone target under the dev-owned home so `su - dev` can write into it", () => {
56-
expect(defaultTargetDir).toBeDefined()
57-
expect(chownedHome).toBeDefined()
58-
expect(`${defaultTargetDir}/`.startsWith(`${chownedHome}/`)).toBe(true)
59-
})
60+
it.effect("keeps the clone target under the dev-owned home so `su - dev` can write into it", () =>
61+
Effect.gen(function*(_) {
62+
const { dockerfile, entrypoint } = yield* _(readRepoSources)
63+
const chownedHome = matchChownedHome(dockerfile)
64+
const defaultTargetDir = matchDefaultTargetDir(entrypoint)
65+
expect(chownedHome).not.toBe("")
66+
expect(defaultTargetDir).not.toBe("")
67+
expect(`${defaultTargetDir}/`.startsWith(`${chownedHome}/`)).toBe(true)
68+
}).pipe(Effect.provide(NodeContext.layer)))
6069
})

0 commit comments

Comments
 (0)