forked from pkgxdev/pkgx
-
Notifications
You must be signed in to change notification settings - Fork 0
/
internal.activate.ts
126 lines (97 loc) · 3.71 KB
/
internal.activate.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import { PackageRequirement, Path, PkgxError, hooks, utils } from "pkgx"
import escape_if_necessary from "../utils/sh-escape.ts"
import construct_env from "../prefab/construct-env.ts"
import install, { Logger } from "../prefab/install.ts"
import { blurple } from "../utils/color.ts"
import devenv from "../utils/devenv.ts"
import undent from "outdent"
export default async function(dir: Path, { powder, ...opts }: { powder: PackageRequirement[], logger: Logger }) {
const { install, construct_env, datadir, getenv } = _internals
if (!dir.isDirectory()) {
throw new PkgxError(`not a directory: ${dir}`)
}
if (dir.eq(Path.home()) || dir.eq(Path.root)) {
throw new PkgxError(`refusing to activate: ${dir}`)
}
const { pkgs, env: userenv } = await devenv(dir)
const devenv_pkgs = [...pkgs]
pkgs.push(...powder)
if (pkgs.length <= 0 && Object.keys(userenv).length <= 0) {
throw new PkgxError("no env")
}
/// indicate to our shell scripts that this devenv is activated
const persistence = datadir().join("dev", dir.string.slice(1)).mkdir('p').join("dev.pkgx.activated").touch()
const installations = await install(pkgs, { update: false, ...opts })
const env = await construct_env(installations)
/// we only want to tell the user about NEW packages added to the env
const rv_pkgenv = (installed => {
const set = new Set(devenv_pkgs.map(({project}) => project))
return installed.filter(x => set.has(x.project))
})(installations.pkgenv)
let rv = ''
/// env specified in devenv files takes precedence
Object.assign(env, userenv)
for (const [key, value] of Object.entries(env)) {
const existing_value = getenv(key)
if (value == existing_value) {
delete env[key]
continue
}
//NOTE strictly env which we model ourselves on does not do value escaping which results in output
// that cannot be sourced if the value contains spaces
rv += `export ${key}=${escape_if_necessary(value)}\n`
}
// if (/\(pkgx\)/.test(getenv("PS1") ?? '') == false) {
// //FIXME doesn't work with warp.dev for fuck knows why reasons
// // https://github.com/warpdotdev/Warp/issues/3492
// rv += `export PS1="(pkgx) $PS1"\n`
// }
rv += `export PKGX_POWDER="${installations.pkgenv.map(utils.pkg.str).join(' ')}"\n`
rv += `export PKGX_PKGENV="${installations.installations.map(({pkg}) => utils.pkg.str(pkg)).join(' ')}"\n\n`
rv += "_pkgx_reset() {\n"
for (const key in env) {
const old = getenv(key)
if (old !== undefined) {
//TODO don’t export if not currently exported!
rv += ` export ${key}=${escape_if_necessary(old)}\n`
} else {
rv += ` unset ${key}\n`
}
}
// const ps1 = getenv('PS1')
// rv += ps1 ? ` export PS1="${ps1}"\n` : " unset PS1\n"
// rv += " unset -f _pkgx_reset\n"
rv += "}\n"
rv += "\n"
const raw_off_string = rv_pkgenv.map(x => `-${utils.pkg.str(x)}`).join(' ')
const off_string = rv_pkgenv.map(x => `-${escape_if_necessary(utils.pkg.str(x))}`).join(' ')
rv += undent`
_pkgx_should_deactivate_devenv() {
suffix="\${PWD#"${dir}"}"
test "$PWD" != "${dir}$suffix"
}
_pkgx_dev_off() {
echo '${blurple('env')} ${raw_off_string}' >&2
env ${off_string}
if [ "$1" != --shy ]; then
rm "${persistence}"
fi
unset -f _pkgx_dev_off _pkgx_should_deactivate_devenv
`
for (const key in userenv) {
const value = getenv(key)
if (value) {
rv += ` export ${key}=${escape_if_necessary(value)}\n`
} else {
rv += ` unset ${key}\n`
}
}
rv += "}"
return [rv, rv_pkgenv] as [string, PackageRequirement[]]
}
export const _internals = {
install,
construct_env,
datadir: () => hooks.useConfig().data,
getenv: Deno.env.get
}