Skip to content

Commit

Permalink
Support pantry providers
Browse files Browse the repository at this point in the history
  • Loading branch information
mxcl committed Apr 22, 2023
1 parent 3de7d29 commit 219c9bd
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 9 deletions.
27 changes: 19 additions & 8 deletions src/hooks/useExec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ interface Parameters {
}

export default async function({ pkgs, inject, sync, ...opts }: Parameters) {
const cmd = [...opts.args]
let cmd = [...opts.args]
const arg0 = await fetch_it(cmd[0])
if (arg0) cmd[0] = arg0?.toString() // if we downloaded it then we need to replace args[0]
const clutch = pkgs.length > 0
Expand Down Expand Up @@ -80,7 +80,7 @@ export default async function({ pkgs, inject, sync, ...opts }: Parameters) {
const found = await which(arg0)
if (found) {
pkgs.push(found)
cmd[0] = found.shebang
cmd = [...found.shebang, ...cmd.slice(1)]
await add_companions(found)
}
}
Expand Down Expand Up @@ -227,7 +227,7 @@ export async function which(arg0: string | undefined) {

const { TEA_PKGS } = useEnv()
const pantry = usePantry()
let found: { project: string, constraint: semver.Range, shebang: string } | undefined
let found: { project: string, constraint: semver.Range, shebang: string[] } | undefined
const promises: Promise<void>[] = []

for await (const entry of pantry.ls()) {
Expand All @@ -244,19 +244,19 @@ export async function which(arg0: string | undefined) {
// we are being executed via the command not found handler inside a dev-env
// so let’s use the version that was already calculated for this dev-env
if ("version" in inenv) {
found = {...inenv, constraint: new semver.Range(`=${inenv.version}`), shebang: provider }
found = {...inenv, constraint: new semver.Range(`=${inenv.version}`), shebang: [provider] }
} else {
found = {...inenv, shebang: provider }
found = {...inenv, shebang: [provider] }
}
} else {
const constraint = new semver.Range("*")
found = {...entry, constraint, shebang: provider }
found = {...entry, constraint, shebang: [provider] }
}
} else if (arg0.startsWith(provider)) {
// eg. `node^16` symlink
try {
const constraint = new semver.Range(arg0.substring(provider.length))
found = {...entry, constraint, shebang: provider }
found = {...entry, constraint, shebang: [provider] }
} catch {
// not a valid semver range; fallthrough
}
Expand All @@ -274,12 +274,23 @@ export async function which(arg0: string | undefined) {
match = arg0.match(rx)
if (match) {
const constraint = new semver.Range(`~${match[1]}`)
found = {...entry, constraint, shebang: arg0 }
found = {...entry, constraint, shebang: [arg0] }
}
}
}
}).swallow(/^parser: pantry: package.yml/)
promises.push(p)

const pp = pantry.getProvider({ project: entry.project }).then(f => {
if (!f) return
const rv = f(arg0)
if (rv) found = {
...entry,
constraint: new semver.Range('*'),
shebang: [...rv, arg0]
}
})
promises.push(pp)
}

if (!found) {
Expand Down
38 changes: 37 additions & 1 deletion src/hooks/usePantry.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Package, PackageRequirement, Installation } from "types"
import { host, validate_plain_obj, pkg, TeaError } from "utils"
import { host, validate_plain_obj, pkg, TeaError, validate_arr } from "utils"
import { isNumber, isPlainObject, isString, isArray, isPrimitive, PlainObject, isBoolean } from "is_what"
import { validatePackageRequirement } from "utils/hacks.ts"
import { useCellar, usePrefix } from "hooks"
Expand All @@ -21,6 +21,7 @@ export default function usePantry() {
getDeps,
getCompanions,
getProvides,
getProvider,
getInterpreter,
getRuntimeEnvironment,
available,
Expand Down Expand Up @@ -68,6 +69,41 @@ const getProvides = async (pkg: { project: string }) => {
})
}

import { parse as parseYaml } from "deno/encoding/yaml.ts"

const getProvider = async ({ project }: { project: string }) => {
for (const prefix of pantry_paths()) {
if (!prefix.exists()) continue
const dir = prefix.join(project)
const filename = dir.join("provider.yml")
if (!filename.exists()) continue
const read = await Deno.readTextFile(filename.string)
const yaml = validate_plain_obj(await parseYaml(read))
const cmds = validate_arr<string>(yaml.cmds)
return (binname: string) => {
if (!cmds.includes(binname)) return
const args = yaml['args']
if (isPlainObject(args)) {
if (args[binname]) {
return get_args(args[binname])
} else {
return get_args(args['...'])
}
} else {
return get_args(args)
}
}
}

function get_args(input: unknown) {
if (isString(input)) {
return input.split(/\s+/)
} else {
return validate_arr<string>(input)
}
}
}

const getCompanions = async (pkg: {project: string}) => {
const yml = await entry(pkg).yml()
const node = yml["companions"]
Expand Down

0 comments on commit 219c9bd

Please sign in to comment.