Skip to content

Commit 30a6adc

Browse files
authored
Dev status (#40)
Fixes #37
1 parent 8511634 commit 30a6adc

File tree

8 files changed

+124
-29
lines changed

8 files changed

+124
-29
lines changed

README.md

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,66 @@ dev, across your team and in production.
1212
1313
## Getting Started
1414

15+
Since `dev` v1.7.0 we integrate with `pkgm` and this is the recommended way to
16+
use `dev`.
17+
18+
> [!IMPORTANT]
19+
>
20+
> `dev` must be installed to `/usr/local/bin/dev` for this route to work:
21+
>
22+
> ```sh
23+
> sudo pkgm install dev # use of `shim` is also fine
24+
> ```
25+
26+
```sh
27+
$ cd my-project
28+
$ ls
29+
package.json
30+
31+
$ node --version
32+
command not found: node
33+
34+
$ sudo pkgm install dev node
35+
$ node --version && which node
36+
v23.11.0
37+
/usr/local/bin/node
38+
39+
$ cat package.json | jq .engines
40+
{
41+
"node": "^20"
42+
}
43+
44+
$ dev
45+
activated `~/my-project` (+node^20)
46+
47+
$ node --version && which node
48+
v20.19.0
49+
/usr/local/bin/node
50+
51+
$ cd ..
52+
$ node --version && which node
53+
v23.11.0
54+
/usr/local/bin/node
55+
56+
$ cd -
57+
$ node --version && which node
58+
v20.19.0
59+
/usr/local/bin/node
60+
```
61+
62+
`pkgm` installs `dev`-aware packages to `/usr/local/bin`. Provided you have
63+
`/usr/local/bin/dev` installed and you have activated `dev` in your project
64+
directories the `node` that is invoked is swapped out _when invoked_.
65+
66+
This is the recommended way to use `dev` because it works everywhere and not
67+
just the terminal.
68+
69+
## `dev` via Shellcode
70+
71+
Shellcode works _as well_ and is your preference. It has notable caveats with
72+
regard to use in tools like editors. It also requires you to add shellcode to
73+
your `shell.rc` files and thus is more intrusive (depending on your outlook).
74+
1575
```sh
1676
pkgx dev integrate
1777
```
@@ -78,6 +138,7 @@ command not found: node
78138
> ```sh
79139
> $ cd my-project
80140
> $ eval "$(pkgx dev)"
141+
> +deno^2
81142
> ```
82143
>
83144
> The devenv will only exist for the duration of your shell session.
@@ -166,8 +227,8 @@ environment. We recommend Visual Studio Code, `dev && code .` works great.
166227
- uses: pkgxdev/dev@v1
167228
```
168229
169-
Installs needed packages and sets up the environment the same as `dev` does in
170-
your terminal.
230+
Installs needed packages (via `pkgx`) and sets up the environment the same as
231+
`dev` does in your terminal.
171232
172233
## Contributing
173234

action.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,16 @@ const replaceEnvVars = (str) => {
2121
return value;
2222
};
2323

24+
let found = false;
25+
2426
readInterface.on("line", (line) => {
27+
if (!found) found = line.trim() == "set -a";
28+
if (!found) return;
2529
const match = line.match(/^([^=]+)=(.*)$/);
2630
if (match) {
2731
const [_, key, value_] = match;
2832
const value = stripQuotes(value_);
29-
if (key === "PATH") {
33+
if (key.trim() === "PATH") {
3034
value
3135
.replaceAll("${PATH:+:$PATH}", "")
3236
.replaceAll("$PATH", "")

action.yml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ description:
44

55
inputs:
66
path:
7+
description: path that should be evaluated by `dev`
78
required: false
89

910
runs:
1011
using: composite
1112
steps:
12-
- uses: pkgxdev/setup@v3
13+
- uses: pkgxdev/setup@v4
1314

1415
- run: |
1516
TMP="$(mktemp)"
@@ -20,10 +21,10 @@ runs:
2021
shell: bash
2122
2223
- run: |
23-
if ! node --version >/dev/null 2>&1; then
24-
set -a
25-
eval "$(pkgx +node)"
26-
set +a
24+
if ! command -v node >/dev/null 2>&1; then
25+
node() {
26+
pkgx node^20 "$@"
27+
}
2728
fi
2829
node "$GITHUB_ACTION_PATH"/action.js ${{ steps.env.outputs.file }}
2930
shell: bash

app.ts

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,35 @@
1-
#!/usr/bin/env -S pkgx deno^2 run -A
1+
#!/usr/bin/env -S pkgx --quiet deno^2 run -A
22

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

66
import { Path } from "libpkgx";
7-
import shellcode from "./src/shellcode().ts";
7+
import shellcode, { datadir } from "./src/shellcode().ts";
88
import app_version from "./src/app-version.ts";
99
import integrate from "./src/integrate.ts";
10-
import { parse } from "jsr:@std/flags";
10+
import { parseArgs } from "jsr:@std/cli@^1/parse-args";
1111
import dump from "./src/dump.ts";
12+
import sniff from "./src/sniff.ts";
1213

13-
const parsedArgs = parse(Deno.args, {
14+
const parsedArgs = parseArgs(Deno.args, {
1415
alias: {
1516
n: "dry-run",
1617
"just-print": "dry-run",
1718
recon: "dry-run",
1819
v: "version",
1920
h: "help",
21+
q: "quiet",
2022
},
21-
boolean: ["help", "version", "shellcode"],
23+
collect: ["quiet"],
24+
boolean: ["help", "version", "shellcode", "quiet"],
2225
default: {
2326
"dry-run": false,
2427
},
2528
});
2629

2730
if (parsedArgs.help) {
2831
const status = await new Deno.Command("pkgx", {
29-
args: ["gh", "repo", "view", "pkgxdev/dev"],
32+
args: ["--quiet", "gh", "repo", "view", "pkgxdev/dev"],
3033
}).spawn().status;
3134
Deno.exit(status.code);
3235
} else if (parsedArgs.shellcode) {
@@ -36,16 +39,31 @@ if (parsedArgs.help) {
3639
} else {
3740
const subcommand = parsedArgs._[0];
3841
const dryrun = parsedArgs["dry-run"] as boolean;
42+
const quiet = parsedArgs["quiet"] != undefined;
3943
switch (subcommand) {
4044
case "integrate":
4145
await integrate("install", { dryrun });
4246
break;
4347
case "deintegrate":
4448
await integrate("uninstall", { dryrun });
4549
break;
50+
case "status":
51+
{
52+
const cwd = Path.cwd();
53+
if (
54+
datadir().join(cwd.string.slice(1), "dev.pkgx.activated").isFile()
55+
) {
56+
//FIXME probably slower than necessary
57+
const { pkgs } = await sniff(cwd);
58+
Deno.exit(pkgs.length == 0 ? 1 : 0);
59+
} else {
60+
Deno.exit(1);
61+
}
62+
}
63+
break;
4664
default: {
4765
const cwd = Path.cwd().join(subcommand as string);
48-
await dump(cwd, { dryrun });
66+
await dump(cwd, { dryrun, quiet });
4967
}
5068
}
5169
}

deno.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
},
1313
"imports": {
1414
"libpkgx": "https://raw.githubusercontent.com/pkgxdev/libpkgx/refs/tags/v0.21.0/mod.ts",
15-
"libpkgx/": "https://raw.githubusercontent.com/pkgxdev/libpkgx/refs/tags/v0.20.1/src/",
15+
"libpkgx/": "https://raw.githubusercontent.com/pkgxdev/libpkgx/refs/tags/v0.21.0/src/",
1616
"is-what": "https://deno.land/x/[email protected]/src/index.ts",
1717
"outdent": "https://deno.land/x/[email protected]/mod.ts"
1818
}

deno.lock

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/dump.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ import { Path, utils } from "libpkgx";
22
import sniff from "./sniff.ts";
33
import shell_escape from "./shell-escape.ts";
44

5-
export default async function (cwd: Path, opts: { dryrun: boolean }) {
5+
export default async function (
6+
cwd: Path,
7+
opts: { dryrun: boolean; quiet: boolean },
8+
) {
69
const snuff = await sniff(cwd);
710

811
if (snuff.pkgs.length === 0 && Object.keys(snuff.env).length === 0) {
@@ -20,7 +23,7 @@ export default async function (cwd: Path, opts: { dryrun: boolean }) {
2023

2124
if (snuff.pkgs.length > 0) {
2225
const cmd = new Deno.Command("pkgx", {
23-
args: [...pkgspecs],
26+
args: ["--quiet", ...pkgspecs],
2427
stdout: "piped",
2528
env: { CLICOLOR_FORCE: "1" }, // unfortunate
2629
}).spawn();
@@ -54,7 +57,9 @@ export default async function (cwd: Path, opts: { dryrun: boolean }) {
5457
" ",
5558
);
5659

57-
console.error("%c%s", "color: green", pkgspecs.join(" "));
60+
if (!opts.quiet) {
61+
console.error("%c%s", "color: green", pkgspecs.join(" "));
62+
}
5863

5964
console.log(`
6065
eval "_pkgx_dev_try_bye() {

src/shellcode().ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
import { Path } from "libpkgx";
22

33
export default function shellcode() {
4-
const datadir = new Path(
5-
Deno.env.get("XDG_DATA_HOME")?.trim() || platform_data_home_default(),
6-
).join("pkgx", "dev");
7-
84
// find self
95
const dev_cmd = Deno.env.get("PATH")?.split(":").map((path) =>
106
Path.abs(path)?.join("dev")
@@ -17,9 +13,9 @@ export default function shellcode() {
1713
_pkgx_chpwd_hook() {
1814
if ! type _pkgx_dev_try_bye >/dev/null 2>&1 || _pkgx_dev_try_bye; then
1915
dir="$PWD"
20-
while [ "$dir" != "/" ]; do
21-
if [ -f "${datadir}/$dir/dev.pkgx.activated" ]; then
22-
eval "$(${dev_cmd})"
16+
while [ "$dir" != / -a "$dir" != . ]; do
17+
if [ -f "${datadir()}/$dir/dev.pkgx.activated" ]; then
18+
eval "$(${dev_cmd})" "$dir"
2319
break
2420
fi
2521
dir="$(dirname "$dir")"
@@ -31,7 +27,7 @@ dev() {
3127
case "$1" in
3228
off)
3329
if type -f _pkgx_dev_try_bye >/dev/null 2>&1; then
34-
rm "${datadir}$PWD/dev.pkgx.activated"
30+
rm "${datadir()}$PWD/dev.pkgx.activated"
3531
PWD=/ _pkgx_dev_try_bye
3632
else
3733
echo "no devenv" >&2
@@ -40,8 +36,8 @@ dev() {
4036
if [ "$2" ]; then
4137
"${dev_cmd}" "$@"
4238
elif ! type -f _pkgx_dev_try_bye >/dev/null 2>&1; then
43-
mkdir -p "${datadir}$PWD"
44-
touch "${datadir}$PWD/dev.pkgx.activated"
39+
mkdir -p "${datadir()}$PWD"
40+
touch "${datadir()}$PWD/dev.pkgx.activated"
4541
eval "$(${dev_cmd})"
4642
else
4743
echo "devenv already active" >&2
@@ -74,6 +70,12 @@ fi
7470
`.trim();
7571
}
7672

73+
export function datadir() {
74+
return new Path(
75+
Deno.env.get("XDG_DATA_HOME")?.trim() || platform_data_home_default(),
76+
).join("pkgx", "dev");
77+
}
78+
7779
function platform_data_home_default() {
7880
const home = Path.home();
7981
switch (Deno.build.os) {

0 commit comments

Comments
 (0)