2021-04-23 19:52:32 +00:00
|
|
|
import { existsSync, readFileSync, writeFileSync, rmSync, mkdirSync } from 'fs'
|
|
|
|
import { execSync } from 'child_process'
|
2021-07-15 09:38:06 +00:00
|
|
|
import { resolve, dirname } from 'path'
|
|
|
|
import { fileURLToPath } from 'url'
|
2021-04-23 19:52:32 +00:00
|
|
|
import defu from 'defu'
|
|
|
|
import hash from 'object-hash'
|
2021-07-15 09:38:06 +00:00
|
|
|
import execa from 'execa'
|
2021-04-23 19:52:32 +00:00
|
|
|
|
2021-07-15 09:38:06 +00:00
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
|
|
|
|
|
|
export function resolveWorkspace (name) {
|
|
|
|
return resolve(__dirname, '../', name)
|
|
|
|
}
|
|
|
|
|
|
|
|
export function fixtureDir (name) {
|
2021-04-23 19:52:32 +00:00
|
|
|
return resolve(__dirname, 'fixtures', name)
|
|
|
|
}
|
|
|
|
|
2021-07-15 09:38:06 +00:00
|
|
|
export async function execNuxtCLI (args, opts) {
|
2021-08-10 17:37:03 +00:00
|
|
|
const nuxtCLI = resolveWorkspace('packages/nuxi/bin/nuxi.js')
|
2021-07-15 09:38:06 +00:00
|
|
|
await execa('node', [nuxtCLI, ...args], opts)
|
|
|
|
}
|
|
|
|
|
|
|
|
export async function loadFixture (opts, unhashedConfig) {
|
2021-04-23 19:52:32 +00:00
|
|
|
const buildId = hash(opts)
|
|
|
|
const buildDir = resolve(opts.rootDir, '.nuxt', buildId)
|
|
|
|
const { loadNuxt } = await import('@nuxt/kit')
|
|
|
|
const nuxt = await loadNuxt(defu(opts, { config: { buildDir, ...unhashedConfig } }))
|
|
|
|
return nuxt
|
|
|
|
}
|
|
|
|
|
2021-07-15 09:38:06 +00:00
|
|
|
export async function buildFixture (opts) {
|
2021-04-23 19:52:32 +00:00
|
|
|
const buildId = hash(opts)
|
|
|
|
const buildDir = resolve(opts.rootDir, '.nuxt', buildId)
|
|
|
|
|
|
|
|
const lockFile = resolve(opts.rootDir, `.build-${buildId}.lock`)
|
|
|
|
mkdirpSync(dirname(lockFile))
|
|
|
|
await waitWhile(() => isAlive(readSync(lockFile)))
|
|
|
|
writeFileSync(lockFile, process.pid + '', 'utf8')
|
|
|
|
|
|
|
|
try {
|
|
|
|
const integrity = gitHead() // TODO: Calculate hash from project source
|
|
|
|
const integrityFile = resolve(buildDir, '.integrity')
|
|
|
|
const lastBuildIntegrity = readSync(integrityFile)
|
|
|
|
if (integrity !== lastBuildIntegrity) {
|
|
|
|
const nuxt = await loadFixture(opts)
|
|
|
|
const { buildNuxt } = await import('@nuxt/kit')
|
|
|
|
await buildNuxt(nuxt)
|
|
|
|
await nuxt.close()
|
|
|
|
await writeFileSync(integrityFile, integrity)
|
|
|
|
}
|
|
|
|
} finally {
|
|
|
|
existsSync(lockFile) && rmSync(lockFile)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function mkdirpSync (dir) {
|
|
|
|
if (!existsSync(dir)) {
|
|
|
|
mkdirpSync(dirname(dir))
|
|
|
|
mkdirSync(dir)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function readSync (file) {
|
|
|
|
return existsSync(file) ? readFileSync(file, 'utf8') : null
|
|
|
|
}
|
|
|
|
|
|
|
|
function isAlive (pid) {
|
|
|
|
try {
|
|
|
|
process.kill(pid, 0)
|
|
|
|
return true
|
|
|
|
} catch (e) {
|
|
|
|
return e.code === 'EPERM'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function waitWhile (check, interval = 100, timeout = 30000) {
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
const t = setTimeout(() => reject(new Error('Timeout')), timeout)
|
|
|
|
const i = setInterval(() => {
|
|
|
|
if (!check()) {
|
|
|
|
clearTimeout(t)
|
|
|
|
clearInterval(i)
|
|
|
|
resolve(true)
|
|
|
|
}
|
|
|
|
}, interval)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-07-15 09:38:06 +00:00
|
|
|
function gitHead () {
|
2021-04-23 19:52:32 +00:00
|
|
|
return execSync('git rev-parse HEAD').toString('utf8').trim()
|
|
|
|
}
|