Skip to content

Commit 7bab45e

Browse files
committed
The pursuit of ’app’yness
1 parent fd22271 commit 7bab45e

File tree

11 files changed

+901
-32
lines changed

11 files changed

+901
-32
lines changed

.github/workflows/ci.yml

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ on:
55
pull_request:
66

77
jobs:
8-
test:
8+
test-action:
99
runs-on: ubuntu-latest
1010
strategy:
1111
matrix:
@@ -15,8 +15,22 @@ jobs:
1515
container: ${{ matrix.container }}
1616
steps:
1717
- uses: actions/checkout@v4
18+
with:
19+
path: clone
1820
- run: echo '{}' > deno.json
19-
- uses: ./
21+
- run: "! deno"
22+
- uses: ./clone
2023
- run: echo $PATH
2124
- run: env
2225
- run: deno --version
26+
27+
lint:
28+
runs-on: ubuntu-latest
29+
steps:
30+
- uses: actions/checkout@v4
31+
- uses: denolib/setup-deno@v2
32+
with:
33+
deno-version: v2.x
34+
- run: deno fmt --check .
35+
- run: deno lint .
36+
- run: deno check ./app.ts

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"deno.enable": true
3+
}

README.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# `dev`
2+
3+
`dev` uses `pkgx` and shellcode to automatically, install and activate the
4+
packages you need for different projects as you navigate in your shell.
5+
6+
## Installation
7+
8+
```sh
9+
echo 'eval "$(pkgx dev --shellcode)"' >> ~/.zshrc
10+
```
11+
12+
> [!NOTE]
13+
> `pkgx` is a required dependency.
14+
>
15+
> ```sh
16+
> brew install pkgxdev/made/pkgx || sh <(curl https://pkgx.sh)
17+
> ```
18+
19+
> [!TIP]
20+
> If you like, preview the shellcode: `pkgx dev --shellcode`.
21+
22+
## Usage
23+
24+
```sh
25+
$ cd my-project
26+
my-project $ ls
27+
package.json
28+
my-project $ dev
29+
+nodejs.org
30+
my-project $ node --version
31+
v22.12.0
32+
$ which node
33+
~/.pkgx/nodejs.org/v22.12.0/bin/node
34+
$ cd ..
35+
-nodejs.org
36+
$ node
37+
command not found: node
38+
```
39+
40+
## How Packages are Determined
41+
42+
- We look at the files you have and figure out the packages you need.
43+
- Where possible we also determine the versions you need if such things can be
44+
determined by looking at configuration files.
45+
46+
## Specifying Versions
47+
48+
We allow you to add YAML front matter to all files to specify versions more
49+
precisely:
50+
51+
```toml
52+
# pkgx:
53+
# openssl.org: 1.1.1n
54+
55+
[package]
56+
name = "my cargo project"
57+
# snip…
58+
```
59+
60+
We allow more terse expressions including eg:
61+
62+
```toml
63+
# pkgx: [email protected] deno^2 npm
64+
```
65+
66+
The major exception being json since it doesn’t support comments, in this case
67+
we read a special `pkgx` node:
68+
69+
```json
70+
{
71+
"pkgx": {
72+
"openssl.org": "1.1.1n",
73+
"deno": "^2",
74+
"npm": null
75+
}
76+
}
77+
```
78+
79+
You can also make a `pkgx.yaml` file.
80+
81+
## Adding Custom Environment Variables
82+
83+
You can add your own environment variables if you like:
84+
85+
```toml
86+
# pkgx:
87+
# openssl.org: 1.1.1n
88+
# env:
89+
# MY_VAR: my-value
90+
```
91+
92+
## Contributing
93+
94+
Mostly you will likely want to edit [./src/sniff.ts] to add new dev types.

action.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,17 @@ runs:
1313

1414
- run: |
1515
TMP="$(mktemp)"
16-
pkgx --internal.activate "$PWD" > "$TMP"
16+
"$GITHUB_ACTION_PATH"/app.ts "$PWD" > "$TMP"
1717
echo "file=$TMP" >> $GITHUB_OUTPUT
1818
id: env
1919
working-directory: ${{ inputs.path }}
2020
shell: bash
2121
2222
- run: |
2323
if ! node --version >/dev/null 2>&1; then
24+
set -a
2425
eval "$(pkgx +node)"
26+
set +a
2527
fi
2628
node "$GITHUB_ACTION_PATH"/parse.js ${{ steps.env.outputs.file }}
2729
shell: bash

app.ts

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#!/usr/bin/env -S pkgx deno^2 run -A
2+
3+
//TODO if you step into dev-dir/subdir does it work?
4+
//TODO dev off uses PWD which may not be correct if in subdir (obv)
5+
6+
import { Path, utils } from "libpkgx";
7+
import shellcode from "./src/shellcode().ts";
8+
import sniff from "./src/sniff.ts";
9+
import shell_escape from "./src/shell-escape.ts";
10+
11+
switch (Deno.args[0]) {
12+
case "--help": {
13+
const status = await new Deno.Command("pkgx", {
14+
args: ["gh", "repo", "view", "pkgxdev/dev"],
15+
}).spawn().status;
16+
Deno.exit(status.code);
17+
break; // deno lint insists
18+
}
19+
case "--shellcode":
20+
console.log(shellcode());
21+
Deno.exit(0);
22+
break; // deno lint insists
23+
}
24+
25+
const snuff = await sniff(Path.cwd());
26+
27+
const pkgspecs = snuff.pkgs.map((pkg) => `+${utils.pkg.str(pkg)}`);
28+
29+
const cmd = new Deno.Command("pkgx", {
30+
args: [...pkgspecs],
31+
stdout: "piped",
32+
env: { CLICOLOR_FORCE: "1" }, // unfortunate
33+
}).spawn();
34+
35+
await cmd.status;
36+
37+
const stdout = (await cmd.output()).stdout;
38+
let env = new TextDecoder().decode(stdout);
39+
40+
// add any additional env that we sniffed
41+
for (const [key, value] of Object.entries(snuff.env)) {
42+
env += `${key}=${shell_escape(value)}\n`;
43+
}
44+
45+
env = env.trim();
46+
47+
let undo = "";
48+
for (const envln of env.trim().split("\n")) {
49+
const [key] = envln.split("=", 2);
50+
const value = Deno.env.get(key);
51+
if (value) {
52+
undo += ` export ${key}=${shell_escape(value)}\n`;
53+
} else {
54+
undo += ` unset ${key}\n`;
55+
}
56+
}
57+
58+
const dir = Deno.cwd();
59+
60+
const bye_bye_msg = pkgspecs.map((pkgspec) => `-${pkgspec.slice(1)}`).join(" ");
61+
62+
console.log(`
63+
set -a
64+
${env}
65+
set +a
66+
67+
_pkgx_dev_try_bye() {
68+
suffix="\${PWD#"${dir}"}"
69+
if test "$PWD" != "${dir}$suffix"; then
70+
${undo.trim()}
71+
unset -f _pkgx_dev_try_bye
72+
echo "\\033[31m${bye_bye_msg}\\033[0m" >&2
73+
return 0
74+
else
75+
return 1
76+
fi
77+
}
78+
`.trim());
79+
80+
console.error("%c%s", "color: green", pkgspecs.join(" "));

deno.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"compilerOptions": {
3+
"strict": true
4+
},
5+
"pkgx": "deno^2.1",
6+
"lint": {
7+
"include": ["src/", "./app.ts"],
8+
"exclude": ["**/*.test.ts", "./parse.js"]
9+
},
10+
"test": {
11+
"include": ["src/"]
12+
},
13+
"imports": {
14+
"libpkgx": "https://raw.githubusercontent.com/pkgxdev/libpkgx/refs/tags/v0.20.1/mod.ts",
15+
"libpkgx/": "https://raw.githubusercontent.com/pkgxdev/libpkgx/refs/tags/v0.20.1/src/",
16+
"is-what": "https://deno.land/x/[email protected]/src/index.ts",
17+
"outdent": "https://deno.land/x/[email protected]/mod.ts"
18+
}
19+
}

deno.lock

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

0 commit comments

Comments
 (0)