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
22import { dirname , fromFileUrl , join } from "jsr:@std/path@^1" ;
33import { ensureDir , existsSync } from "jsr:@std/fs@^1" ;
44import { parse as parse_args } from "jsr:@std/flags@0.224.0" ;
@@ -34,7 +34,11 @@ if (parsedArgs.help) {
3434 switch ( parsedArgs . _ [ 0 ] ) {
3535 case "install" :
3636 case "i" :
37- await install ( args ) ;
37+ await install ( args , '/usr/local' ) ;
38+ break ;
39+ case "local-install" :
40+ case "li" :
41+ await install ( args , `${ Deno . env . get ( "HOME" ) ! } /.local` ) ;
3842 break ;
3943 case "uninstall" :
4044 case "rm" :
@@ -49,12 +53,12 @@ if (parsedArgs.help) {
4953 Deno . exit ( 1 ) ;
5054 break ;
5155 case "sudo-install" : {
52- const [ pkgx_dir , runtime_env , ...paths ] = args ;
56+ const [ pkgx_dir , runtime_env , basePath , ...paths ] = args ;
5357 const parsed_runtime_env = JSON . parse ( runtime_env ) as Record <
5458 string ,
5559 Record < string , string >
5660 > ;
57- await sudo_install ( pkgx_dir , paths , parsed_runtime_env ) ;
61+ await sudo_install ( pkgx_dir , paths , parsed_runtime_env , basePath ) ;
5862 break ;
5963 }
6064 default :
@@ -67,7 +71,7 @@ if (parsedArgs.help) {
6771 }
6872}
6973
70- async function install ( args : string [ ] ) {
74+ async function install ( args : string [ ] , basePath : string ) {
7175 if ( args . length === 0 ) {
7276 console . error ( "no packages specified" ) ;
7377 Deno . exit ( 1 ) ;
@@ -106,7 +110,7 @@ async function install(args: string[]) {
106110
107111 const to_install = [ ] ;
108112 for ( const prefix of pkg_prefixes ) {
109- if ( ! existsSync ( join ( "/usr/local/ pkgs" , prefix ) ) ) {
113+ if ( ! existsSync ( join ( ` ${ basePath } / pkgs` , prefix ) ) ) {
110114 to_install . push ( prefix ) ;
111115 }
112116 }
@@ -118,9 +122,9 @@ async function install(args: string[]) {
118122
119123 const self = fromFileUrl ( import . meta. url ) ;
120124 const pkgx_dir = Deno . env . get ( "PKGX_DIR" ) || `${ Deno . env . get ( "HOME" ) } /.pkgx` ;
121- const needs_sudo = Deno . uid ( ) != 0 ;
125+ const needs_sudo = Deno . uid ( ) != 0 && basePath === "/usr/local" ;
122126
123- const runtime_env = expand_runtime_env ( json . runtime_env ) ;
127+ const runtime_env = expand_runtime_env ( json . runtime_env , basePath ) ;
124128
125129 args = [
126130 "pkgx" ,
@@ -133,6 +137,7 @@ async function install(args: string[]) {
133137 "sudo-install" ,
134138 pkgx_dir ,
135139 runtime_env ,
140+ basePath ,
136141 ...to_install ,
137142 ] ;
138143 const cmd = needs_sudo ? "/usr/bin/sudo" : args . shift ( ) ! ;
@@ -145,12 +150,13 @@ async function sudo_install(
145150 pkgx_dir : string ,
146151 pkg_prefixes : string [ ] ,
147152 runtime_env : Record < string , Record < string , string > > ,
153+ basePath : string ,
148154) {
149- const dst = "/usr/local" ;
155+ const dst = basePath ;
150156 for ( const pkg_prefix of pkg_prefixes ) {
151- // create /usr/local /pkgs/${prefix}
157+ // create ${dst} /pkgs/${prefix}
152158 await mirror_directory ( join ( dst , "pkgs" ) , pkgx_dir , pkg_prefix ) ;
153- // symlink /usr/local/ pkgs/${prefix} to /usr/local
159+ // symlink ${dst}/ pkgs/${prefix} to ${dst}
154160 if ( ! pkg_prefix . startsWith ( "pkgx.sh/v" ) ) {
155161 // ^^ don’t overwrite ourselves
156162 // ^^ * https://github.com/pkgxdev/pkgm/issues/14
@@ -169,14 +175,14 @@ async function sudo_install(
169175 if ( ! pkg_prefix ) continue ; //FIXME wtf?
170176
171177 for ( const bin of [ "bin" , "sbin" ] ) {
172- const bin_prefix = join ( "/usr/local/ pkgs" , pkg_prefix , bin ) ;
178+ const bin_prefix = join ( ` ${ dst } / pkgs` , pkg_prefix , bin ) ;
173179
174180 if ( ! existsSync ( bin_prefix ) ) continue ;
175181
176182 for await ( const entry of Deno . readDir ( bin_prefix ) ) {
177183 if ( ! entry . isFile ) continue ;
178184
179- const to_stub = join ( "/usr/local" , bin , entry . name ) ;
185+ const to_stub = join ( dst , bin , entry . name ) ;
180186
181187 let sh = `#!/bin/sh\n` ;
182188 for ( const [ key , value ] of Object . entries ( env ) ) {
@@ -288,12 +294,13 @@ async function create_v_symlinks(prefix: string) {
288294
289295function expand_runtime_env (
290296 runtime_env : Record < string , Record < string , string > > ,
297+ basePath : string ,
291298) {
292299 const expanded : Record < string , Record < string , string > > = { } ;
293300 for ( const [ project , env ] of Object . entries ( runtime_env ) ) {
294301 const expanded_env : Record < string , string > = { } ;
295302 for ( const [ key , value ] of Object . entries ( env ) ) {
296- const new_value = value . replaceAll ( / \$ ? { { .* p r e f i x } } / g, "/usr/local" ) ;
303+ const new_value = value . replaceAll ( / \$ ? { { .* p r e f i x } } / g, basePath ) ;
297304 expanded_env [ key ] = new_value ;
298305 }
299306 expanded [ project ] = expanded_env ;
0 commit comments