Skip to content

Commit b28a097

Browse files
committed
Apply all moustaches; Fixes zsh; Fixes #22
Can’t think of a way to add a test
1 parent 9633e40 commit b28a097

File tree

1 file changed

+51
-18
lines changed

1 file changed

+51
-18
lines changed

pkgm.ts

Lines changed: 51 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/usr/bin/env -S pkgx --quiet deno^2.1 run --ext=ts --allow-sys=uid --allow-run --allow-env --allow-read --allow-write --allow-ffi
22
import {
33
hooks,
4+
Installation,
45
Path,
56
plumbing,
67
SemVer,
@@ -62,13 +63,13 @@ if (parsedArgs.help) {
6263
break;
6364
case "local-install":
6465
case "li":
65-
await install(args, `${Deno.env.get("HOME")!}/.local`);
66+
await install(args, Path.home().join(".local").string);
6667
break;
6768
case "stub":
6869
case "shim":
6970
// this uses the old behavior of pkgx v1, which is to install to ~/.local/bin
7071
// if we want to write to /usr/local, we need to use sudo
71-
await shim(args, `${Deno.env.get("HOME")!}/.local`);
72+
await shim(args, Path.home().join(".local").string);
7273
break;
7374
case "uninstall":
7475
case "rm":
@@ -117,8 +118,9 @@ async function install(args: string[], basePath: string) {
117118
const pkgx = get_pkgx();
118119

119120
const [json, env] = await query_pkgx(pkgx, args);
120-
// deno-lint-ignore no-explicit-any
121-
const pkg_prefixes = json.pkgs.map((x: any) => `${x.project}/v${x.version}`);
121+
const pkg_prefixes = json.pkgs.map((x) =>
122+
`${x.pkg.project}/v${x.pkg.version}`
123+
);
122124

123125
const self = fromFileUrl(import.meta.url);
124126
const pkgx_dir = Deno.env.get("PKGX_DIR") || `${Deno.env.get("HOME")}/.pkgx`;
@@ -217,13 +219,19 @@ async function shim(args: string[], basePath: string) {
217219

218220
for (const pkg of json.pkgs) {
219221
for (const bin of ["bin", "sbin"]) {
220-
const bin_prefix = join(pkg.path, bin);
221-
if (!existsSync(bin_prefix)) continue;
222-
for await (const entry of Deno.readDir(bin_prefix)) {
222+
const bin_prefix = pkg.path.join(bin);
223+
if (!bin_prefix.exists()) continue;
224+
for await (const entry of Deno.readDir(bin_prefix.string)) {
223225
if (!entry.isFile && !entry.isSymlink) continue;
224226
const name = entry.name;
227+
const quick_shim = Deno.build.os == "darwin" &&
228+
pkgx == "/usr/local/bin/pkgx";
229+
const interpreter = quick_shim
230+
? "/usr/local/bin/pkgx"
231+
: "/usr/bin/env -S pkgx";
232+
225233
const shim =
226-
`#!/usr/bin/env -S pkgx --shebang --quiet +${pkg.project}=${pkg.version} -- ${name}`;
234+
`#!${interpreter} --shebang --quiet +${pkg.pkg.project}=${pkg.pkg.version} -- ${name}`;
227235

228236
if (existsSync(join(basePath, "bin", name))) {
229237
await Deno.remove(join(basePath, "bin", name));
@@ -237,7 +245,17 @@ async function shim(args: string[], basePath: string) {
237245
}
238246
}
239247

240-
async function query_pkgx(pkgx: string, args: string[]) {
248+
interface JsonResponse {
249+
runtime_env: Record<string, Record<string, string>>;
250+
pkgs: Installation[];
251+
env: Record<string, Record<string, string>>;
252+
pkg: Installation;
253+
}
254+
255+
async function query_pkgx(
256+
pkgx: string,
257+
args: string[],
258+
): Promise<[JsonResponse, Record<string, string>]> {
241259
args = args.map((x) => `+${x}`);
242260

243261
const env: Record<string, string> = {
@@ -265,7 +283,23 @@ async function query_pkgx(pkgx: string, args: string[]) {
265283
}
266284

267285
const out = await proc.output();
268-
return [JSON.parse(new TextDecoder().decode(out.stdout)), env];
286+
const json = JSON.parse(new TextDecoder().decode(out.stdout));
287+
const pkgs =
288+
(json.pkgs as { path: string; project: string; version: string }[]).map(
289+
(x) => {
290+
return {
291+
path: new Path(x.path),
292+
pkg: { project: x.project, version: new SemVer(x.version) },
293+
};
294+
},
295+
);
296+
const pkg = pkgs.find((x) => `+${x.pkg.project}` == args[0])!;
297+
return [{
298+
pkg,
299+
pkgs,
300+
env: json.env,
301+
runtime_env: json.runtime_env,
302+
}, env];
269303
}
270304

271305
async function mirror_directory(dst: string, src: string, prefix: string) {
@@ -376,20 +410,20 @@ async function create_v_symlinks(prefix: string) {
376410
}
377411

378412
function expand_runtime_env(
379-
// deno-lint-ignore no-explicit-any
380-
json: Record<string, any>,
413+
json: JsonResponse,
381414
basePath: string,
382415
) {
383-
const runtime_env = json.runtime_env as Record<string, string>;
416+
const { runtime_env, pkgs } = json;
384417

385418
//FIXME this combines all runtime env which is strictly overkill
386419
// for transitive deps that may not need it
387420

388421
const expanded: Record<string, Set<string>> = {};
389422
for (const [_project, env] of Object.entries(runtime_env)) {
390423
for (const [key, value] of Object.entries(env)) {
391-
//TODO expand all moustaches
392-
const new_value = value.replaceAll(/\$?{{.*prefix}}/g, basePath);
424+
const pkg = pkgs.find((x) => x.pkg.project == _project)!.pkg;
425+
const mm = hooks.useMoustaches().tokenize.all(pkg, json.pkgs);
426+
const new_value = hooks.useMoustaches().apply(value, mm);
393427
expanded[key] ??= new Set<string>();
394428
expanded[key].add(new_value);
395429
}
@@ -407,9 +441,8 @@ function expand_runtime_env(
407441
}
408442

409443
// DUMB but easiest way to fix a bug
410-
// deno-lint-ignore no-explicit-any
411-
const rv2: Record<string, any> = {};
412-
for (const { project } of json.pkgs as Record<string, string>[]) {
444+
const rv2: Record<string, Record<string, string>> = {};
445+
for (const { pkg: { project } } of json.pkgs) {
413446
rv2[project] = rv;
414447
}
415448

0 commit comments

Comments
 (0)