Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix when pkgx is installed by Homebrew on Linux #23

Merged
merged 4 commits into from
Feb 24, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 30 additions & 11 deletions pkgm.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,31 @@
#!/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
import { dirname, fromFileUrl, join } from "jsr:@std/path@^1";
import { ensureDir, existsSync } from "jsr:@std/fs@^1";
import { parse as parse_args } from "jsr:@std/[email protected]";
import { parseArgs } from "jsr:@std/cli@^1";
import * as semver from "jsr:@std/semver@^1";

function standardPath() {
const basePath = "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin";
// for pkgm installed via homebrew
const homebrew = `${Deno.env.get("HOMEBREW_PREFIX") || "/opt/homebrew"}/bin`;
if (Deno.build.os === "darwin") {
return `${homebrew}:${basePath}`;
} else {
return basePath;
let path = "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin";

// for pkgx installed via homebrew
let homebrewPrefix = "";
switch (Deno.build.os) {
case "darwin":
homebrewPrefix = "/opt/homebrew"; // /usr/local is already in the path
break;
case "linux":
homebrewPrefix = `/home/linuxbrew/.linuxbrew:${Deno.env.get("HOME")}/.linuxbrew`;
break;
}
if (homebrewPrefix) {
homebrewPrefix = Deno.env.get("HOMEBREW_PREFIX") ?? homebrewPrefix;
path = `${homebrewPrefix}/bin:${path}`;
}

return path;
Comment on lines +8 to +25
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would be slower to use fs.exists(), but we could just loop an array of paths and add them if they're there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but I think it still makes sense to only search on some directories conditionally. For example, it doesn't make sense to search for /home/linuxbrew/.linuxbrew on a macOS.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's reasonably correct. if it's present, who knows what it's doing?

}

const parsedArgs = parse_args(Deno.args, {
const parsedArgs = parseArgs(Deno.args, {
alias: {
v: "version",
h: "help",
Expand Down Expand Up @@ -117,7 +127,7 @@ async function install(args: string[]) {
}

const self = fromFileUrl(import.meta.url);
const pkgx_dir = Deno.env.get("PKGX_DIR") || `${Deno.env.get("HOME")}/.pkgx`;
const pkgx_dir = Deno.env.get("PKGX_DIR") ?? `${Deno.env.get("HOME")}/.pkgx`;
const needs_sudo = Deno.uid() != 0;

const runtime_env = expand_runtime_env(json.runtime_env);
Expand All @@ -135,7 +145,16 @@ async function install(args: string[]) {
runtime_env,
...to_install,
];
const cmd = needs_sudo ? "/usr/bin/sudo" : args.shift()!;
let cmd = ""
if (needs_sudo) {
cmd = "/usr/bin/sudo";
args.unshift(
"-E", // we already cleared the env, it's safe
"env", `PATH=${env.PATH}`,
);
} else {
cmd = args.shift()!;
}
status = await new Deno.Command(cmd, { args, env, clearEnv: true })
.spawn().status;
Deno.exit(status.code);
Expand Down
Loading