Skip to content

Commit 7ea8bb4

Browse files
committed
Unfortunately, we must stub for runtime-env
1 parent 76641c8 commit 7ea8bb4

File tree

2 files changed

+57
-5
lines changed

2 files changed

+57
-5
lines changed

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,15 @@
22

33
Install `pkgx` packages to `/usr/local`.
44

5+
> [!CAUTION]
6+
>
7+
> `pkgm` is new software. Please report any issues you encounter and try it
8+
> out in parallel with your current package manager.
9+
510
> [!WARNING]
611
>
7-
> `pkgm` is new software. Please report any issues you encounter and try it out
8-
> in parallel with your current package manager.
12+
> `pkgm` is new software. Some features listed here are not yet implemented.
13+
> You can help! Or we’ll get to it soon.
914
1015
## Usage
1116

pkgm.ts

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,9 @@ if (parsedArgs.help) {
4646
Deno.exit(1);
4747
break;
4848
case "sudo-install": {
49-
const [pkgx_dir, ...paths] = args;
50-
await sudo_install(pkgx_dir, paths);
49+
const [pkgx_dir, runtime_env, ...paths] = args;
50+
const parsed_runtime_env = JSON.parse(runtime_env) as Record<string, Record<string, string>>;
51+
await sudo_install(pkgx_dir, paths, parsed_runtime_env);
5152
break;
5253
}
5354
default:
@@ -109,6 +110,8 @@ async function install(args: string[]) {
109110
const pkgx_dir = Deno.env.get("PKGX_DIR") || `${Deno.env.get("HOME")}/.pkgx`;
110111
const needs_sudo = Deno.uid() != 0;
111112

113+
const runtime_env = expand_runtime_env(json.runtime_env, json.pkgs)
114+
112115
args = [
113116
"pkgx",
114117
"deno^2.1",
@@ -119,6 +122,7 @@ async function install(args: string[]) {
119122
self,
120123
"sudo-install",
121124
pkgx_dir,
125+
runtime_env,
122126
...to_install,
123127
];
124128
const cmd = needs_sudo ? "/usr/bin/sudo" : args.shift()!;
@@ -127,7 +131,7 @@ async function install(args: string[]) {
127131
Deno.exit(status.code);
128132
}
129133

130-
async function sudo_install(pkgx_dir: string, pkg_prefixes: string[]) {
134+
async function sudo_install(pkgx_dir: string, pkg_prefixes: string[], runtime_env: Record<string, Record<string, string>>) {
131135
const dst = "/usr/local";
132136
for (const pkg_prefix of pkg_prefixes) {
133137
// create /usr/local/pkgs/${prefix}
@@ -137,6 +141,31 @@ async function sudo_install(pkgx_dir: string, pkg_prefixes: string[]) {
137141
// create v1, etc. symlinks
138142
await create_v_symlinks(join("/usr/local/pkgs", pkg_prefix));
139143
}
144+
145+
for (const [project, env] of Object.entries(runtime_env)) {
146+
const pkg_prefix = pkg_prefixes.find((x) => x.startsWith(project))!;
147+
for (const bin of ["bin", "sbin"]) {
148+
const bin_prefix = join("/usr/local/pkgs", pkg_prefix, bin);
149+
150+
if (!existsSync(bin_prefix)) continue;
151+
152+
for await (const entry of Deno.readDir(bin_prefix)) {
153+
if (!entry.isFile) continue;
154+
155+
const to_stub = join("/usr/local", bin, entry.name);
156+
157+
let sh = `#!/bin/sh\n`
158+
for (const [key, value] of Object.entries(env)) {
159+
sh += `export ${key}="${value}"\n`;
160+
}
161+
sh += `exec "${bin_prefix}/${entry.name}" "$@"\n`;
162+
163+
await Deno.remove(to_stub); //FIXME inefficient to symlink for no reason
164+
await Deno.writeTextFile(to_stub, sh);
165+
await Deno.chmod(to_stub, 0o755);
166+
}
167+
}
168+
}
140169
}
141170

142171
async function mirror_directory(dst: string, src: string, prefix: string) {
@@ -185,6 +214,10 @@ async function symlink(src: string, dst: string) {
185214
await processEntry(entrySourcePath, entryTargetPath);
186215
}
187216
} else {
217+
// resinstall
218+
if (existsSync(targetPath)) {
219+
await Deno.remove(targetPath);
220+
}
188221
await Deno.symlink(sourcePath, targetPath);
189222
}
190223
}
@@ -223,3 +256,17 @@ async function create_v_symlinks(prefix: string) {
223256
await Deno.symlink(`v${semver.format(value)}`, join(shelf, `v${key}`));
224257
}
225258
}
259+
260+
function expand_runtime_env(runtime_env: Record<string, Record<string, string>>, pkgs: [Record<string, string>]) {
261+
const expanded: Record<string, Record<string, string>> = {};
262+
for (const [project, env] of Object.entries(runtime_env)) {
263+
const expanded_env: Record<string, string> = {};
264+
const pkg = pkgs.find((x) => x.project === project)!;
265+
for (const [key, value] of Object.entries(env)) {
266+
let new_value = value.replaceAll(/\$?{{.*prefix}}/g, '/usr/local')
267+
expanded_env[key] = new_value;
268+
}
269+
expanded[project] = expanded_env;
270+
}
271+
return JSON.stringify(expanded);
272+
}

0 commit comments

Comments
 (0)