Skip to content

Commit 99ec068

Browse files
committed
chore: wip
1 parent ac3b481 commit 99ec068

File tree

6 files changed

+105
-45
lines changed

6 files changed

+105
-45
lines changed

packages/launchpad/src/dev/dump.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1968,19 +1968,30 @@ async function createPhpShimsAfterInstall(envDir: string): Promise<void> {
19681968
*/
19691969
async function maybeRunProjectPostSetup(projectDir: string, envDir: string, _isShellIntegration: boolean): Promise<void> {
19701970
try {
1971+
if (process.env.LAUNCHPAD_VERBOSE === 'true') {
1972+
console.warn(`maybeRunProjectPostSetup called: projectDir=${projectDir}, envDir=${envDir}`)
1973+
}
1974+
19711975
// Use a marker file inside env to avoid re-running on every prompt
19721976
const markerDir = path.join(envDir, 'pkgs')
19731977
const markerFile = path.join(markerDir, '.post_setup_done')
19741978

19751979
if (fs.existsSync(markerFile)) {
1980+
if (process.env.LAUNCHPAD_VERBOSE === 'true') {
1981+
console.warn(`Post-setup marker file already exists, skipping: ${markerFile}`)
1982+
}
19761983
return
19771984
}
19781985

19791986
// Ensure envDir/pkgs exists (env may be fast-activated without pkgs when empty)
19801987
try {
19811988
fs.mkdirSync(markerDir, { recursive: true })
19821989
}
1983-
catch {}
1990+
catch (error) {
1991+
if (process.env.LAUNCHPAD_VERBOSE === 'true') {
1992+
console.warn(`Failed to create marker directory ${markerDir}: ${error instanceof Error ? error.message : String(error)}`)
1993+
}
1994+
}
19841995

19851996
// Aggregate post-setup commands from both runtime config and project-local config
19861997
const commands: PostSetupCommand[] = []
@@ -1995,14 +2006,19 @@ async function maybeRunProjectPostSetup(projectDir: string, envDir: string, _isS
19952006
try {
19962007
const configPathTs = path.join(projectDir, 'launchpad.config.ts')
19972008
if (fs.existsSync(configPathTs)) {
1998-
const mod = await import(configPathTs)
2009+
const configUrl = new URL(`file://${configPathTs}`)
2010+
const mod = await import(configUrl.href)
19992011
const local = mod.default || mod
20002012
if (local?.postSetup?.enabled && Array.isArray(local.postSetup.commands)) {
20012013
commands.push(...local.postSetup.commands)
20022014
}
20032015
}
20042016
}
2005-
catch {
2017+
catch (error) {
2018+
// Log import errors in verbose mode for debugging
2019+
if (process.env.LAUNCHPAD_VERBOSE === 'true') {
2020+
console.warn(`Failed to import launchpad.config.ts: ${error instanceof Error ? error.message : String(error)}`)
2021+
}
20062022
// Ignore import errors; absence or parse errors should not fail setup
20072023
}
20082024

packages/launchpad/test/dev-hooks.test.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ postActivation:
3939
writeFileSync(path.join(tmpDir, 'hooks.log'), '', 'utf8')
4040
})
4141

42-
it.skip('runs hooks in correct phases and creates readiness marker', async () => {
42+
it('runs hooks in correct phases and creates readiness marker', async () => {
4343
// Import dump programmatically
4444
const { dump } = await import('../src/dev/dump')
4545

@@ -64,19 +64,33 @@ postActivation:
6464
const resolved = fsmod.existsSync(tmpDir) ? fsmod.realpathSync(tmpDir) : tmpDir
6565
const md5 = crypto.createHash('md5').update(resolved).digest('hex')
6666
const hash = `${path.basename(resolved)}_${md5.slice(0, 8)}`
67-
const ready = path.join(envsDir, hash, '.launchpad_ready')
67+
68+
// Compute dependency fingerprint to match dump.ts logic
69+
let depSuffix = ''
70+
try {
71+
const depsFilePath = path.join(tmpDir, 'deps.yaml')
72+
if (fsmod.existsSync(depsFilePath)) {
73+
const depContent = fsmod.readFileSync(depsFilePath)
74+
const depHash = crypto.createHash('md5').update(depContent).digest('hex').slice(0, 8)
75+
depSuffix = `-d${depHash}`
76+
}
77+
}
78+
catch {}
79+
80+
const ready = path.join(envsDir, `${hash}${depSuffix}`, '.launchpad_ready')
6881

6982
console.log('tmpDir:', tmpDir)
7083
console.log('resolved:', resolved)
7184
console.log('hash:', hash)
85+
console.log('depSuffix:', depSuffix)
7286
console.log('envsDir:', envsDir)
7387
console.log('expected ready path:', ready)
7488
console.log('ready file exists:', existsSync(ready))
75-
console.log('envs directory exists:', existsSync(path.join(envsDir, hash)))
89+
console.log('envs directory exists:', existsSync(path.join(envsDir, `${hash}${depSuffix}`)))
7690

7791
// List files in env directory if it exists
78-
if (existsSync(path.join(envsDir, hash))) {
79-
const files = fsmod.readdirSync(path.join(envsDir, hash))
92+
if (existsSync(path.join(envsDir, `${hash}${depSuffix}`))) {
93+
const files = fsmod.readdirSync(path.join(envsDir, `${hash}${depSuffix}`))
8094
console.log('files in env dir:', files)
8195
}
8296

packages/launchpad/test/end-to-end-integration.test.ts

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -264,30 +264,6 @@ dependencies:
264264
console.log = originalLog
265265
}
266266
}, 90000)
267-
268-
it.skip('should create project database automatically', async () => {
269-
// Import database creation function
270-
const { createProjectDatabase } = await import('../src/services/database')
271-
272-
const dbConfig = {
273-
type: 'postgres' as const,
274-
host: '127.0.0.1',
275-
port: 5432,
276-
username: 'postgres',
277-
password: '',
278-
}
279-
280-
// In test mode, this should not fail even if PostgreSQL isn't running
281-
try {
282-
await createProjectDatabase('test_laravel_app', dbConfig)
283-
// If we get here without throwing, the function structure is correct
284-
expect(true).toBe(true)
285-
}
286-
catch (error) {
287-
// In test environment, connection failures are expected
288-
expect(error instanceof Error).toBe(true)
289-
}
290-
})
291267
})
292268

293269
describe('Shell Integration and PATH Management', () => {

packages/launchpad/test/pin-downgrade-fastpath.test.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ function runDevShell(projectDir: string, extraEnv?: Record<string, string>): { s
2424
return { stderr: res.stderr || '', stdout: res.stdout || '' }
2525
}
2626

27-
describe.skip('pin downgrade fast-path behavior', () => {
27+
describe('pin downgrade fast-path behavior', () => {
2828
const projectDir = mkdtemp()
2929
const home = os.homedir()
3030
const envsRoot = path.join(home, '.local', 'share', 'launchpad', 'envs')
@@ -36,12 +36,26 @@ describe.skip('pin downgrade fast-path behavior', () => {
3636
const r1 = runDevShell(projectDir)
3737
expect(r1.stdout).toContain('# Launchpad environment setup')
3838

39-
// Compute hash as in implementation
39+
// Compute hash as in implementation (including dependency suffix)
4040
const real = fs.realpathSync(projectDir)
4141
const base = path.basename(real)
4242

4343
const md5 = crypto.createHash('md5').update(real).digest('hex')
44-
projectHash = `${base}_${md5.slice(0, 8)}`
44+
const baseHash = `${base}_${md5.slice(0, 8)}`
45+
46+
// Compute dependency fingerprint to match dump.ts logic
47+
let depSuffix = ''
48+
try {
49+
const depsFilePath = path.join(projectDir, 'deps.yaml')
50+
if (fs.existsSync(depsFilePath)) {
51+
const depContent = fs.readFileSync(depsFilePath)
52+
const depHash = crypto.createHash('md5').update(depContent).digest('hex').slice(0, 8)
53+
depSuffix = `-d${depHash}`
54+
}
55+
}
56+
catch {}
57+
58+
projectHash = `${baseHash}${depSuffix}`
4559
expect(fs.existsSync(path.join(envsRoot, projectHash))).toBe(true)
4660
})
4761

packages/launchpad/test/postsetup-pg-readiness.test.ts

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,35 @@ pkgs:
6666

6767
// Mock artisan that writes a marker file
6868
const artisan = path.join(binDir, 'artisan')
69-
fs.writeFileSync(artisan, `#!/bin/sh\necho \"artisan called with args: $@\" > \"${path.join(projectDir, 'artisan-debug.log')}\"\nif [ \"$1\" = \"migrate:fresh\" ]; then echo migrated > \"${path.join(projectDir, 'migrated.marker')}\"; fi; exit 0\n`)
69+
fs.writeFileSync(artisan, `#!/bin/sh
70+
echo "artisan called with args: $@" > "${path.join(projectDir, 'artisan-debug.log')}"
71+
echo "First arg: '$1'" >> "${path.join(projectDir, 'artisan-debug.log')}"
72+
echo "Checking condition: [ '$1' = 'migrate:fresh' ]" >> "${path.join(projectDir, 'artisan-debug.log')}"
73+
if [ "$1" = "migrate:fresh" ]; then
74+
echo "Condition matched! Creating marker file..." >> "${path.join(projectDir, 'artisan-debug.log')}"
75+
echo migrated > "${path.join(projectDir, 'migrated.marker')}"
76+
echo "Marker file created: $?" >> "${path.join(projectDir, 'artisan-debug.log')}"
77+
else
78+
echo "Condition NOT matched" >> "${path.join(projectDir, 'artisan-debug.log')}"
79+
fi
80+
exit 0
81+
`)
7082
fs.chmodSync(artisan, 0o755)
7183

72-
// Compute envDir exactly like dump.ts
73-
const envHash = generateProjectHashForTest(projectDir)
74-
envDir = path.join(os.homedir(), '.local', 'share', 'launchpad', 'envs', envHash)
84+
// Compute envDir exactly like dump.ts (including dependency suffix)
85+
const envHash = generateProjectHashForTest(projectDir)
86+
// Compute dependency fingerprint to match dump.ts logic
87+
let depSuffix = ''
88+
try {
89+
const depsFilePath = path.join(projectDir, 'deps.yaml')
90+
if (fs.existsSync(depsFilePath)) {
91+
const depContent = fs.readFileSync(depsFilePath)
92+
const depHash = crypto.createHash('md5').update(depContent).digest('hex').slice(0, 8)
93+
depSuffix = `-d${depHash}`
94+
}
95+
}
96+
catch {}
97+
envDir = path.join(os.homedir(), '.local', 'share', 'launchpad', 'envs', `${envHash}${depSuffix}`)
7598
fs.mkdirSync(envDir, { recursive: true })
7699
fs.writeFileSync(path.join(envDir, '.launchpad_ready'), '1')
77100
// Create expected bin/sbin to satisfy composed PATH
@@ -95,8 +118,8 @@ pkgs:
95118
catch {}
96119
})
97120

98-
it.skip('runs post-setup after services and completes without connection errors', async () => {
99-
await dump(projectDir, { shellOutput: true, quiet: true })
121+
it('runs post-setup after services and completes without connection errors', async () => {
122+
await dump(projectDir, { shellOutput: false, quiet: true })
100123

101124
// Check if artisan was called at all
102125
const debugLogPath = path.join(projectDir, 'artisan-debug.log')
@@ -107,9 +130,25 @@ pkgs:
107130

108131
// Expect our mock artisan to have executed
109132
const markerPath = path.join(projectDir, 'migrated.marker')
133+
console.log('Expected marker path:', markerPath)
134+
console.log('Marker exists:', fs.existsSync(markerPath))
135+
console.log('Project dir contents:', fs.readdirSync(projectDir))
136+
if (fs.existsSync(markerPath)) {
137+
console.log('Marker content:', fs.readFileSync(markerPath, 'utf8'))
138+
}
110139
expect(fs.existsSync(markerPath)).toBe(true)
111140
// And the idempotent marker to be created
112141
const postMarker = path.join(envDir, 'pkgs', '.post_setup_done')
142+
console.log('Expected post marker path:', postMarker)
143+
console.log('EnvDir exists:', fs.existsSync(envDir))
144+
console.log('EnvDir/pkgs exists:', fs.existsSync(path.join(envDir, 'pkgs')))
145+
if (fs.existsSync(envDir)) {
146+
console.log('EnvDir contents:', fs.readdirSync(envDir))
147+
if (fs.existsSync(path.join(envDir, 'pkgs'))) {
148+
console.log('EnvDir/pkgs contents:', fs.readdirSync(path.join(envDir, 'pkgs')))
149+
}
150+
}
151+
console.log('Post marker exists:', fs.existsSync(postMarker))
113152
expect(fs.existsSync(postMarker)).toBe(true)
114153
})
115154
})
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
1+
12
pkgs:
23
- bun.sh
34

45
preSetup:
56
enabled: true
67
commands:
7-
- {command: "bash -lc 'echo preSetup >> hooks.log'"}
8+
- { command: "bash -lc 'echo preSetup >> hooks.log'" }
89
postSetup:
910
enabled: true
1011
commands:
11-
- {command: "bash -lc 'echo postSetup >> hooks.log'"}
12+
- { command: "bash -lc 'echo postSetup >> hooks.log'" }
1213
preActivation:
1314
enabled: true
1415
commands:
15-
- {command: "bash -lc 'echo preActivation >> hooks.log'"}
16+
- { command: "bash -lc 'echo preActivation >> hooks.log'" }
1617
postActivation:
1718
enabled: true
1819
commands:
19-
- {command: "bash -lc 'echo postActivation >> hooks.log'"}
20+
- { command: "bash -lc 'echo postActivation >> hooks.log'" }

0 commit comments

Comments
 (0)