Skip to content

Commit e42943a

Browse files
committed
Allow dev [PATH] to activate devenvs
1 parent 30a6adc commit e42943a

File tree

3 files changed

+116
-23
lines changed

3 files changed

+116
-23
lines changed

README.md

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ $ cat package.json | jq .engines
4141
"node": "^20"
4242
}
4343
44-
$ dev
44+
$ dev .
4545
activated `~/my-project` (+node^20)
4646
4747
$ node --version && which node
@@ -72,6 +72,9 @@ Shellcode works _as well_ and is your preference. It has notable caveats with
7272
regard to use in tools like editors. It also requires you to add shellcode to
7373
your `shell.rc` files and thus is more intrusive (depending on your outlook).
7474

75+
A great advantage of the shellcode is not needing to install tools you may never
76+
need again when exploring new open source projects.
77+
7578
```sh
7679
pkgx dev integrate
7780
```
@@ -103,7 +106,7 @@ more shells.
103106
> If you like, preview the shellcode: `pkgx dev --shellcode`. This command only
104107
> outputs shellcode, it doesn’t modify any files or do anything else either.
105108
106-
## Usage
109+
### Usage
107110
108111
```sh
109112
$ cd my-project
@@ -130,15 +133,20 @@ command not found: node
130133
131134
> [!TIP]
132135
>
133-
> ### Try Before You `vi`
136+
> #### Try Before You `vi`
134137
>
135138
> Modifying your `shell.rc` can be… _intimidating_. If you just want to
136139
> temporarily try `dev` out before you `:wq`—we got you:
137140
>
138141
> ```sh
139142
> $ cd my-project
140-
> $ eval "$(pkgx dev)"
143+
> $ eval "$(pkgx dev .)"
141144
> +deno^2
145+
> $ deno --version
146+
> deno 2.1.1
147+
>
148+
> $ dev off
149+
> # ^^ or close your terminal
142150
> ```
143151
>
144152
> The devenv will only exist for the duration of your shell session.
@@ -208,27 +216,25 @@ You can add your own environment variables if you like:
208216
209217
> [!NOTE]
210218
>
211-
> The environment variable's value is sanitized, so expressions like
212-
> `MY_VAR: $(sudo rm -rf --no-preserve-root /)` will throw an error.
219+
> - Adding environment variables only works via the `shellcode` route.
220+
> - The environment variable's value is sanitized, so expressions like
221+
> `MY_VAR: $(sudo rm -rf --no-preserve-root /)` will throw an error.
222+
> - We recommend `direnv` instead of this route.
213223
214224
## `dev` & Editors
215225
216-
Most editors if opened via the Terminal will inherit that Terminal’s
217-
environment. We recommend Visual Studio Code, `dev && code .` works great.
218-
219-
> [!WARNING]
220-
>
221-
> Unfortunately, this usually means you _must_ open your editor via your
222-
> terminal.
226+
The sure fire way for things to work in editors is to use the `dev`/`pkgm`
227+
combo. Having said this most editors if opened via the Terminal will inherit
228+
that Terminal’s environment.
223229
224230
## GitHub Actions
225231
226232
```yaml
227233
- uses: pkgxdev/dev@v1
228234
```
229235
230-
Installs needed packages (via `pkgx`) and sets up the environment the same as
231-
`dev` does in your terminal.
236+
Our action installs needed packages (via `pkgx`) and sets up the environment the
237+
same as `dev` does in your terminal.
232238
233239
## Contributing
234240

app.ts

Lines changed: 87 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
//TODO if you step into dev-dir/subdir and type `dev` does it find the root properly?
44
//TODO dev off uses PWD which may not be correct if in subdir (obv)
55

6-
import { Path } from "libpkgx";
6+
import { Path, utils } from "libpkgx";
77
import shellcode, { datadir } from "./src/shellcode().ts";
88
import app_version from "./src/app-version.ts";
99
import integrate from "./src/integrate.ts";
1010
import { parseArgs } from "jsr:@std/cli@^1/parse-args";
1111
import dump from "./src/dump.ts";
1212
import sniff from "./src/sniff.ts";
13+
import { walk } from "jsr:@std/fs@1/walk";
1314

1415
const parsedArgs = parseArgs(Deno.args, {
1516
alias: {
@@ -28,10 +29,13 @@ const parsedArgs = parseArgs(Deno.args, {
2829
});
2930

3031
if (parsedArgs.help) {
31-
const status = await new Deno.Command("pkgx", {
32-
args: ["--quiet", "gh", "repo", "view", "pkgxdev/dev"],
32+
const { code } = await new Deno.Command("pkgx", {
33+
args: [
34+
"glow",
35+
"https://raw.githubusercontent.com/pkgxdev/dev/refs/heads/main/README.md",
36+
],
3337
}).spawn().status;
34-
Deno.exit(status.code);
38+
Deno.exit(code);
3539
} else if (parsedArgs.shellcode) {
3640
console.log(shellcode());
3741
} else if (parsedArgs.version) {
@@ -40,30 +44,106 @@ if (parsedArgs.help) {
4044
const subcommand = parsedArgs._[0];
4145
const dryrun = parsedArgs["dry-run"] as boolean;
4246
const quiet = parsedArgs["quiet"] != undefined;
47+
4348
switch (subcommand) {
4449
case "integrate":
4550
await integrate("install", { dryrun });
4651
break;
52+
4753
case "deintegrate":
4854
await integrate("uninstall", { dryrun });
4955
break;
56+
5057
case "status":
5158
{
5259
const cwd = Path.cwd();
5360
if (
5461
datadir().join(cwd.string.slice(1), "dev.pkgx.activated").isFile()
5562
) {
56-
//FIXME probably slower than necessary
63+
//FIXME probably slower than ideal
5764
const { pkgs } = await sniff(cwd);
5865
Deno.exit(pkgs.length == 0 ? 1 : 0);
5966
} else {
6067
Deno.exit(1);
6168
}
6269
}
6370
break;
71+
72+
case "ls":
73+
for await (
74+
const entry of walk(datadir().string, { includeDirs: false })
75+
) {
76+
if (entry.name === "dev.pkgx.activated") {
77+
const partial_path = new Path(entry.path).parent().relative({
78+
to: datadir(),
79+
});
80+
console.log(`/${partial_path}`);
81+
}
82+
}
83+
break;
84+
85+
case undefined:
86+
{
87+
const cwd = Path.cwd();
88+
const { pkgs } = await sniff(cwd);
89+
if (
90+
datadir().join(cwd.string.slice(1), "dev.pkgx.activated").isFile()
91+
) {
92+
console.log(
93+
"%cactive",
94+
"color: green",
95+
pkgs.map(utils.pkg.str).join(" "),
96+
);
97+
} else if (pkgs.length > 0) {
98+
console.log(
99+
"%cinactive",
100+
"color: red",
101+
pkgs.map(utils.pkg.str).join(" "),
102+
);
103+
} else {
104+
console.log("%cno keyfiles found", "color: red");
105+
}
106+
}
107+
break;
108+
109+
case "off": {
110+
let dir = Path.cwd();
111+
while (dir.string != "/") {
112+
const f = datadir().join(dir.string.slice(1), "dev.pkgx.activated")
113+
.isFile();
114+
if (f) {
115+
f.rm();
116+
console.log("%cdeactivated", "color: green", dir.string);
117+
Deno.exit(0);
118+
}
119+
dir = dir.parent();
120+
}
121+
console.error("%cno devenv found", "color: red");
122+
Deno.exit(1);
123+
break;
124+
}
125+
64126
default: {
65-
const cwd = Path.cwd().join(subcommand as string);
66-
await dump(cwd, { dryrun, quiet });
127+
if (Deno.stdout.isTerminal()) {
128+
const cwd = Path.cwd().join(subcommand as string);
129+
const { pkgs } = await sniff(cwd);
130+
if (pkgs.length > 0) {
131+
datadir().join(cwd.string.slice(1)).mkdir("p").join(
132+
"dev.pkgx.activated",
133+
).touch();
134+
console.log(
135+
"%cactived",
136+
"color: green",
137+
pkgs.map(utils.pkg.str).join(" "),
138+
);
139+
} else {
140+
console.error("%cno keyfiles found", "color: red");
141+
Deno.exit(1);
142+
}
143+
} else {
144+
const cwd = Path.cwd().join(subcommand as string);
145+
await dump(cwd, { dryrun, quiet });
146+
}
67147
}
68148
}
69149
}

src/shellcode().ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,14 @@ dev() {
2727
case "$1" in
2828
off)
2929
if type -f _pkgx_dev_try_bye >/dev/null 2>&1; then
30-
rm "${datadir()}$PWD/dev.pkgx.activated"
30+
dir="$PWD"
31+
while [ "$dir" != / -a "$dir" != . ]; do
32+
if [ -f "${datadir()}/$dir/dev.pkgx.activated" ]; then
33+
rm "${datadir()}/$dir/dev.pkgx.activated"
34+
break
35+
fi
36+
dir="$(dirname "$dir")"
37+
done
3138
PWD=/ _pkgx_dev_try_bye
3239
else
3340
echo "no devenv" >&2

0 commit comments

Comments
 (0)