2022-08-01 22:43:40 +03:00
|
|
|
#!/usr/bin/env -S tea -E
|
|
|
|
|
|
|
|
/*---
|
|
|
|
args:
|
|
|
|
- deno
|
|
|
|
- run
|
|
|
|
- --allow-net
|
|
|
|
- --allow-run
|
|
|
|
- --allow-read
|
2022-09-01 00:44:34 +03:00
|
|
|
- --allow-write
|
2022-08-01 22:43:40 +03:00
|
|
|
- --allow-env
|
|
|
|
- --import-map={{ srcroot }}/import-map.json
|
|
|
|
---*/
|
|
|
|
|
2022-09-02 17:51:31 +03:00
|
|
|
import { parsePackage, semver, Path, PackageRequirement, parsePackageRequirement } from "types"
|
2022-08-01 22:43:40 +03:00
|
|
|
import usePantry from "hooks/usePantry.ts"
|
|
|
|
import useShellEnv, { expand } from "hooks/useShellEnv.ts"
|
2022-09-02 17:51:31 +03:00
|
|
|
import { run, undent } from "utils"
|
2022-08-17 15:22:22 +03:00
|
|
|
import useFlags from "hooks/useFlags.ts"
|
2022-08-27 21:11:25 +03:00
|
|
|
import useCellar from "hooks/useCellar.ts"
|
2022-09-01 00:44:34 +03:00
|
|
|
import resolve from "prefab/resolve.ts"
|
|
|
|
import install from "prefab/install.ts"
|
2022-08-31 22:39:16 +03:00
|
|
|
import hydrate from "prefab/hydrate.ts"
|
2022-09-01 00:44:34 +03:00
|
|
|
import { lvl1 as link } from "prefab/link.ts"
|
2022-08-17 15:22:22 +03:00
|
|
|
|
2022-09-02 17:51:31 +03:00
|
|
|
const { debug, magic } = useFlags()
|
2022-09-01 00:44:34 +03:00
|
|
|
const cellar = useCellar()
|
2022-08-01 22:43:40 +03:00
|
|
|
const pantry = usePantry()
|
2022-09-02 17:51:31 +03:00
|
|
|
|
2022-08-27 21:11:25 +03:00
|
|
|
const pkg = await (async () => {
|
2022-09-02 17:51:31 +03:00
|
|
|
if (magic) {
|
2022-09-01 00:44:34 +03:00
|
|
|
const i = await cellar.resolve(parsePackageRequirement(Deno.args[0]))
|
2022-08-27 21:11:25 +03:00
|
|
|
return i.pkg
|
|
|
|
} else {
|
|
|
|
return parsePackage(Deno.args[0])
|
|
|
|
}
|
|
|
|
})()
|
|
|
|
|
2022-08-01 22:43:40 +03:00
|
|
|
const self = {
|
|
|
|
project: pkg.project,
|
|
|
|
constraint: new semver.Range(pkg.version.toString())
|
|
|
|
}
|
|
|
|
const [yml] = await pantry.getYAML(pkg)
|
2022-09-02 17:51:31 +03:00
|
|
|
const deps = (await hydrate(self, async (pkg, dry) => {
|
|
|
|
const { runtime, test } = await pantry.getDeps(pkg)
|
|
|
|
return dry ? [...runtime, ...test] : runtime
|
|
|
|
})).pkgs
|
2022-08-01 22:43:40 +03:00
|
|
|
|
2022-09-01 00:44:34 +03:00
|
|
|
await install_if_needed(deps)
|
|
|
|
|
2022-09-02 17:51:31 +03:00
|
|
|
const env = await useShellEnv([self, ...deps])
|
2022-08-01 22:43:40 +03:00
|
|
|
|
|
|
|
let text = undent`
|
|
|
|
#!/bin/bash
|
|
|
|
|
|
|
|
set -e
|
|
|
|
set -o pipefail
|
|
|
|
set -x
|
|
|
|
|
|
|
|
${expand(env.vars)}
|
|
|
|
|
|
|
|
`
|
|
|
|
|
2022-08-27 21:11:25 +03:00
|
|
|
const tmp = Path.mktmp({ prefix: `${pkg.project}-${pkg.version}+` })
|
2022-08-01 22:43:40 +03:00
|
|
|
|
|
|
|
try {
|
|
|
|
if (yml.test.fixture) {
|
|
|
|
const fixture = tmp.join("fixture.tea").write({ text: yml.test.fixture.toString() })
|
|
|
|
text += `export FIXTURE="${fixture}"\n\n`
|
|
|
|
}
|
|
|
|
|
2022-08-27 21:11:25 +03:00
|
|
|
const cwd = tmp.join("wd").mkdir()
|
|
|
|
|
|
|
|
text += `cd "${cwd}"\n\n`
|
|
|
|
|
2022-08-01 22:43:40 +03:00
|
|
|
text += await pantry.getScript(pkg, 'test')
|
|
|
|
text += "\n"
|
|
|
|
|
2022-08-27 21:11:25 +03:00
|
|
|
for await (const [path, {name, isFile}] of pantry.prefix(pkg).ls()) {
|
|
|
|
if (isFile && name != 'package.yml') path.cp({ into: cwd })
|
|
|
|
}
|
|
|
|
|
2022-08-01 22:43:40 +03:00
|
|
|
const cmd = tmp
|
|
|
|
.join("test.sh")
|
|
|
|
.write({ text, force: true })
|
|
|
|
.chmod(0o500)
|
2022-08-27 21:11:25 +03:00
|
|
|
await run({ cmd, cwd })
|
2022-08-01 22:43:40 +03:00
|
|
|
} finally {
|
2022-08-27 21:11:25 +03:00
|
|
|
if (!debug) tmp.rm({ recursive: true })
|
2022-08-01 22:43:40 +03:00
|
|
|
}
|
|
|
|
|
2022-09-02 17:51:31 +03:00
|
|
|
//TODO install step should do this for test requirements also
|
2022-09-01 00:44:34 +03:00
|
|
|
async function install_if_needed(deps: PackageRequirement[]) {
|
|
|
|
const needed: PackageRequirement[] = []
|
|
|
|
for await (const rq of deps) {
|
|
|
|
if (await cellar.isInstalled(rq)) continue
|
|
|
|
needed.push(rq)
|
|
|
|
}
|
|
|
|
const wet = await resolve(needed)
|
|
|
|
for (const pkg of wet) {
|
|
|
|
const installation = install(pkg)
|
|
|
|
await link(installation)
|
|
|
|
}
|
|
|
|
}
|