Skip to content

Commit 08b77ce

Browse files
authored
Merge pull request #26 from pkgxdev/add-local-install
add `local-install`/`li` option
2 parents b010f90 + fccf199 commit 08b77ce

2 files changed

Lines changed: 25 additions & 15 deletions

File tree

.github/workflows/ci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ jobs:
3333
- run: ./pkgm.ts i pkgx.sh/brewkit
3434
- run: /usr/local/bin/bk --help
3535

36+
- run: ./pkgm.ts li pkgx.sh/brewkit
37+
- run: ~/.local/bin/bk --help
38+
3639
- run: |
3740
if [[ "$(/usr/local/bin/pkgx --version)" != "pkgx 2"* ]]; then
3841
exit 1

pkgm.ts

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env -S pkgx --quiet deno^2.1 run --ext=ts --allow-sys=uid --allow-run --allow-env=PKGX_DIR,HOMEBREW_PREFIX,HOME --allow-read=/usr/local/pkgs
1+
#!/usr/bin/env -S pkgx --quiet deno^2.1 run --ext=ts --allow-sys=uid --allow-run --allow-env=PKGX_DIR,HOMEBREW_PREFIX,HOME --allow-read=/usr/local/pkgs,${HOME}/.local/pkgs
22
import { dirname, fromFileUrl, join } from "jsr:@std/path@^1";
33
import { ensureDir, existsSync } from "jsr:@std/fs@^1";
44
import { parseArgs } from "jsr:@std/cli@^1";
@@ -46,7 +46,11 @@ if (parsedArgs.help) {
4646
switch (parsedArgs._[0]) {
4747
case "install":
4848
case "i":
49-
await install(args);
49+
await install(args, "/usr/local");
50+
break;
51+
case "local-install":
52+
case "li":
53+
await install(args, `${Deno.env.get("HOME")!}/.local`);
5054
break;
5155
case "uninstall":
5256
case "rm":
@@ -61,12 +65,12 @@ if (parsedArgs.help) {
6165
Deno.exit(1);
6266
break;
6367
case "sudo-install": {
64-
const [pkgx_dir, runtime_env, ...paths] = args;
68+
const [pkgx_dir, runtime_env, basePath, ...paths] = args;
6569
const parsed_runtime_env = JSON.parse(runtime_env) as Record<
6670
string,
6771
Record<string, string>
6872
>;
69-
await sudo_install(pkgx_dir, paths, parsed_runtime_env);
73+
await sudo_install(pkgx_dir, paths, parsed_runtime_env, basePath);
7074
break;
7175
}
7276
default:
@@ -79,7 +83,7 @@ if (parsedArgs.help) {
7983
}
8084
}
8185

82-
async function install(args: string[]) {
86+
async function install(args: string[], basePath: string) {
8387
if (args.length === 0) {
8488
console.error("no packages specified");
8589
Deno.exit(1);
@@ -118,7 +122,7 @@ async function install(args: string[]) {
118122

119123
const to_install = [];
120124
for (const prefix of pkg_prefixes) {
121-
if (!existsSync(join("/usr/local/pkgs", prefix))) {
125+
if (!existsSync(join(`${basePath}/pkgs`, prefix))) {
122126
to_install.push(prefix);
123127
}
124128
}
@@ -129,10 +133,10 @@ async function install(args: string[]) {
129133
}
130134

131135
const self = fromFileUrl(import.meta.url);
132-
const pkgx_dir = Deno.env.get("PKGX_DIR") ?? `${Deno.env.get("HOME")}/.pkgx`;
133-
const needs_sudo = Deno.uid() != 0;
136+
const pkgx_dir = Deno.env.get("PKGX_DIR") || `${Deno.env.get("HOME")}/.pkgx`;
137+
const needs_sudo = Deno.uid() != 0 && basePath === "/usr/local";
134138

135-
const runtime_env = expand_runtime_env(json.runtime_env);
139+
const runtime_env = expand_runtime_env(json.runtime_env, basePath);
136140

137141
args = [
138142
"pkgx",
@@ -145,6 +149,7 @@ async function install(args: string[]) {
145149
"sudo-install",
146150
pkgx_dir,
147151
runtime_env,
152+
basePath,
148153
...to_install,
149154
];
150155
let cmd = "";
@@ -167,12 +172,13 @@ async function sudo_install(
167172
pkgx_dir: string,
168173
pkg_prefixes: string[],
169174
runtime_env: Record<string, Record<string, string>>,
175+
basePath: string,
170176
) {
171-
const dst = "/usr/local";
177+
const dst = basePath;
172178
for (const pkg_prefix of pkg_prefixes) {
173-
// create /usr/local/pkgs/${prefix}
179+
// create ${dst}/pkgs/${prefix}
174180
await mirror_directory(join(dst, "pkgs"), pkgx_dir, pkg_prefix);
175-
// symlink /usr/local/pkgs/${prefix} to /usr/local
181+
// symlink ${dst}/pkgs/${prefix} to ${dst}
176182
if (!pkg_prefix.startsWith("pkgx.sh/v")) {
177183
// ^^ don’t overwrite ourselves
178184
// ^^ * https://github.com/pkgxdev/pkgm/issues/14
@@ -191,14 +197,14 @@ async function sudo_install(
191197
if (!pkg_prefix) continue; //FIXME wtf?
192198

193199
for (const bin of ["bin", "sbin"]) {
194-
const bin_prefix = join("/usr/local/pkgs", pkg_prefix, bin);
200+
const bin_prefix = join(`${dst}/pkgs`, pkg_prefix, bin);
195201

196202
if (!existsSync(bin_prefix)) continue;
197203

198204
for await (const entry of Deno.readDir(bin_prefix)) {
199205
if (!entry.isFile) continue;
200206

201-
const to_stub = join("/usr/local", bin, entry.name);
207+
const to_stub = join(dst, bin, entry.name);
202208

203209
let sh = `#!/bin/sh\n`;
204210
for (const [key, value] of Object.entries(env)) {
@@ -310,12 +316,13 @@ async function create_v_symlinks(prefix: string) {
310316

311317
function expand_runtime_env(
312318
runtime_env: Record<string, Record<string, string>>,
319+
basePath: string,
313320
) {
314321
const expanded: Record<string, Record<string, string>> = {};
315322
for (const [project, env] of Object.entries(runtime_env)) {
316323
const expanded_env: Record<string, string> = {};
317324
for (const [key, value] of Object.entries(env)) {
318-
const new_value = value.replaceAll(/\$?{{.*prefix}}/g, "/usr/local");
325+
const new_value = value.replaceAll(/\$?{{.*prefix}}/g, basePath);
319326
expanded_env[key] = new_value;
320327
}
321328
expanded[project] = expanded_env;

0 commit comments

Comments
 (0)