diff --git a/src/hooks/usePantry.ts b/src/hooks/usePantry.ts index 64a1cf23..69ab8bb2 100644 --- a/src/hooks/usePantry.ts +++ b/src/hooks/usePantry.ts @@ -11,9 +11,14 @@ interface Response { /// returns sorted versions getVersions(rq: PackageRequirement | Package): Promise getDeps(pkg: Package | PackageRequirement): Promise<{ runtime: PackageRequirement[], build: PackageRequirement[] }> - getBuildScript(pkg: Package): Promise + getScript(pkg: Package, key: 'build' | 'test'): Promise update(): Promise getProvides(rq: PackageRequirement | Package): Promise + + //TODO take `T` and then type check it + getYAML(rq: PackageRequirement | Package): Promise<[PlainObject, Path]> + + prefix(rq: PackageRequirement | Package): Path } interface Entry { @@ -79,6 +84,12 @@ export default function usePantry(): Response { } } + const getYAML = async (pkg: Package | PackageRequirement): Promise<[PlainObject, Path]> => { + const foo = entry(pkg) + const yml = await foo.yml() + return [yml, foo.dir.join("package.yml")] + } + const getDeps = async (pkg: Package | PackageRequirement) => { const yml = await entry(pkg).yml() return { @@ -114,12 +125,15 @@ export default function usePantry(): Response { return { url, stripComponents } } - const getBuildScript = async (pkg: Package) => { + const getScript = async (pkg: Package, key: 'build' | 'test') => { const yml = await entry(pkg).yml() - let raw = validateString(validatePlainObject(yml.build).script) + const obj = validatePlainObject(yml[key]) - const wd = yml.build["working-directory"] + let raw = validateString(obj.script) + + let wd = obj["working-directory"] if (wd) { + wd = remapTokens(wd, pkg) raw = undent` mkdir -p ${wd} cd ${wd} @@ -128,7 +142,7 @@ export default function usePantry(): Response { ` } - const env = yml.build.env + const env = obj.env if (isPlainObject(env)) { const expanded_env = Object.entries(env).map(([key,value]) => { if (isArray(value)) { @@ -179,7 +193,8 @@ export default function usePantry(): Response { { from: "hw.target", to: platform.target }, { from: "hw.platform", to: platform.platform }, { from: "prefix", to: prefix.string }, - { from: "hw.concurrency", to: navigator.hardwareConcurrency.toString() } + { from: "hw.concurrency", to: navigator.hardwareConcurrency.toString() }, + { from: "pkg.pantry-prefix", to: getPrefix(pkg).string } ].reduce((acc, map) => acc.replace(new RegExp(`\\$?{{\\s*${map.from}\\s*}}`, "g"), map.to), input) } @@ -204,7 +219,12 @@ export default function usePantry(): Response { }) } - return { getVersions, getDeps, getDistributable, getBuildScript, update, getProvides } + const getPrefix = (pkg: Package | PackageRequirement) => prefix.join(pkg.project) + + return { getVersions, getDeps, getDistributable, getScript, update, getProvides, + getYAML, + prefix: getPrefix + } } diff --git a/src/hooks/useShellEnv.ts b/src/hooks/useShellEnv.ts index ffe4b64f..401f9aae 100644 --- a/src/hooks/useShellEnv.ts +++ b/src/hooks/useShellEnv.ts @@ -90,3 +90,12 @@ function suffixes(key: string) { throw new Error("unhandled") } } + +export function expand(env: Record) { + let rv = '' + for (let [key, value] of Object.entries(env)) { + if (key == 'PATH') value = value.concat("/usr/bin:/bin:/usr/sbin:/sbin") //FIXME + rv += `export ${key}='${value.join(":")}'\n` + } + return rv +} \ No newline at end of file diff --git a/src/prefab/build.ts b/src/prefab/build.ts index 0bc4e59d..52dd3952 100644 --- a/src/prefab/build.ts +++ b/src/prefab/build.ts @@ -1,7 +1,7 @@ import { Path, Package, PackageRequirement, semver } from "types" import usePantry from "hooks/usePantry.ts" import useCellar from "hooks/useCellar.ts" -import useShellEnv from "hooks/useShellEnv.ts" +import useShellEnv, { expand } from "hooks/useShellEnv.ts" import { run, undent } from "utils" import usePlatform from "hooks/usePlatform.ts" import hydrate from "prefab/hydrate.ts" @@ -22,7 +22,7 @@ export default async function build({ pkg, deps, prebuild }: Options): Promise

) { - let rv = '' - for (let [key, value] of Object.entries(env)) { - if (key == 'PATH') value = value.concat("/usr/bin:/bin:/usr/sbin:/sbin") //FIXME - rv += `export ${key}='${value.join(":")}'\n` - } - return rv -} - async function* exefiles(prefix: Path) { for (const basename of ["bin", "lib"]) { //TODO the rest const d = prefix.join(basename).isDirectory() diff --git a/src/types.ts b/src/types.ts index 9c5b95fe..7605500c 100644 --- a/src/types.ts +++ b/src/types.ts @@ -54,6 +54,18 @@ export function parsePackageRequirement(input: string): PackageRequirement { } } +export function parsePackage(input: string): Package { + const splat = input.split('@') //FIXME we do specs with eg. foo^1 + if (splat.length == 2) { + return { + project: splat[0], + version: new SemVer(splat[1]) + } + } else { + throw "invalid-pkgspec" + } +} + /////////////////////////////////////////////////////////////////////// semver import SemVer, * as semver from "semver"