tauri/tooling/create-tauri-app/test/spawn.test.mjs

195 lines
5.6 KiB
JavaScript
Raw Normal View History

// Copyright 2019-2021 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
import { main, spawn, sleep } from 'effection'
import { exec } from '@effection/process'
import fs from 'fs/promises'
import path from 'path'
import crypto from 'crypto'
import tempDirectory from 'temp-dir'
let assert
const nodeVersion = process.versions.node.split('.')[0]
if (nodeVersion === '14') {
assert = await import('assert')
} else {
assert = await import('assert/strict')
}
const ctaBinary = path.resolve('./bin/create-tauri-app.js')
const clijs = path.resolve('../cli.js/')
const api = path.resolve('../api/')
const manager = process.env.TAURI_RUN_MANAGER || 'yarn'
const recipes = process.env.TAURI_RECIPE
? process.env.TAURI_RECIPE.split(',')
: ['vanillajs', 'cra', 'vite', 'ngcli', 'solid']
const parallelize = process.env.TAURI_RECIPE_PARALLELIZE || false
main(function* start() {
const tauriTemp = path.join(
tempDirectory,
`tauri_${crypto.randomBytes(16).toString('hex')}`
)
try {
const appName = 'tauri-app'
let output = {}
for (let i = 0; i < recipes.length; i++) {
const recipe = recipes[i]
console.log(`::group::recipe ${recipe}`)
console.log(`------------------ ${recipe} started -------------------`)
const recipeFolder = path.join(tauriTemp, recipe)
const appFolder = path.join(recipeFolder, appName)
yield fs.mkdir(recipeFolder, { recursive: true })
console.log(`${recipeFolder} created.`)
// runs CTA with all args set to avoid any prompts
const run = `node '${ctaBinary}' --manager ${manager} --recipe ${recipe} --ci --dev`
console.log(`[running] ${run}`)
let opts = []
if (manager === 'npm') {
opts =
recipe == 'vuecli'
? ['run', 'tauri:build']
: ['run', 'tauri', '--', 'build']
} else if (manager === 'yarn') {
opts = recipe == 'vuecli' ? ['tauri:build'] : ['tauri', 'build']
}
if (!parallelize) {
const cta = yield exec(run, { cwd: recipeFolder })
yield streamLogs(cta)
// now it is finished, assert on some things
yield assertCTAState({ appFolder, appName })
const tauriBuild = yield exec(manager, {
arguments: opts,
cwd: appFolder
})
yield streamLogs(tauriBuild)
// build is complete, assert on some things
yield assertTauriBuildState({ appFolder, appName })
} else {
console.log('running CTA recipe in parallel')
output[recipe] = yield spawn(function* () {
const childCTA = yield exec(run, { cwd: recipeFolder })
const cta = yield captureLogs(childCTA)
const childTauriBuild = yield exec(manager, {
arguments: opts,
cwd: appFolder
})
const tauriBuild = yield captureLogs(childTauriBuild)
return { cta, tauriBuild }
})
}
console.log(`------------------ ${recipe} complete -------------------`)
console.log('::endgroup::')
// sometimes it takes a moment to flush all of the logs
// to the console, let things catch up here
yield sleep(1000)
}
if (parallelize) {
for (let i = 0; i < recipes.length; i++) {
const recipe = recipes[i]
console.log(`::group::recipe ${recipe} logs`)
console.log(
`------------------ ${recipe} output start -------------------`
)
const out = yield output[recipe]
console.log(out.cta)
console.log(out.tauriBuild)
console.log(
`------------------ ${recipe} output end -------------------`
)
console.log('::endgroup::')
}
}
} catch (e) {
console.error(e)
throw Error(e)
} finally {
console.log('\nstopping process...')
// wait a tick for file locks to be release
yield sleep(5000)
yield fs.rm(tauriTemp, { recursive: true, force: true })
console.log(`${tauriTemp} deleted.`)
}
})
function* streamLogs(child) {
yield child.stdout.forEach((data) => {
process.stdout.write(data)
})
yield child.stderr.forEach((data) => {
process.stderr.write(data)
})
}
function* captureLogs(child) {
let log = ''
yield child.stdout.forEach((data) => {
log += data
})
yield child.stderr.forEach((data) => {
log += data
})
return log
}
function* assertCTAState({ appFolder, appName }) {
const packageFileInitial = JSON.parse(
yield fs.readFile(path.join(appFolder, 'package.json'), 'utf-8')
)
assert.strictEqual(
packageFileInitial.name,
appName,
`The package.json did not have the name "${appName}".`
)
assert.strictEqual(
packageFileInitial.scripts.tauri,
'tauri',
`The package.json did not have the tauri script.`
)
}
function* assertTauriBuildState({ appFolder, appName }) {
const packageFileOutput = JSON.parse(
yield fs.readFile(path.join(appFolder, 'package.json'), 'utf-8')
)
assert.strictEqual(
packageFileOutput.name,
appName,
`The package.json did not have the name "${appName}".`
)
assert.strictEqual(
packageFileOutput.scripts.tauri,
'tauri',
`The package.json did not have the tauri script.`
)
const cargoFileOutput = yield fs.readFile(
path.join(appFolder, 'src-tauri', 'Cargo.toml'),
'utf-8'
)
assert.strictEqual(
cargoFileOutput.startsWith(`[package]\nname = "app"`),
true,
`The Cargo.toml did not have the name "app".`
)
const tauriTarget = yield fs.readdir(
path.join(appFolder, 'src-tauri', 'target')
)
assert.strictEqual(
tauriTarget.includes('release'),
true,
`The Tauri build does not have a target/release directory.`
)
}