diff --git a/README.md b/README.md index e6392ba..fc00c23 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ $ cat package.json | jq .engines "node": "^20" } -$ dev +$ dev . activated `~/my-project` (+node^20) $ node --version && which node @@ -72,6 +72,9 @@ Shellcode works _as well_ and is your preference. It has notable caveats with regard to use in tools like editors. It also requires you to add shellcode to your `shell.rc` files and thus is more intrusive (depending on your outlook). +A great advantage of the shellcode is not needing to install tools you may never +need again when exploring new open source projects. + ```sh pkgx dev integrate ``` @@ -103,7 +106,7 @@ more shells. > If you like, preview the shellcode: `pkgx dev --shellcode`. This command only > outputs shellcode, it doesn’t modify any files or do anything else either. -## Usage +### Usage ```sh $ cd my-project @@ -130,15 +133,20 @@ command not found: node > [!TIP] > -> ### Try Before You `vi` +> #### Try Before You `vi` > > Modifying your `shell.rc` can be… _intimidating_. If you just want to > temporarily try `dev` out before you `:wq`—we got you: > > ```sh > $ cd my-project -> $ eval "$(pkgx dev)" +> $ eval "$(pkgx dev .)" > +deno^2 +> $ deno --version +> deno 2.1.1 +> +> $ dev off +> # ^^ or close your terminal > ``` > > The devenv will only exist for the duration of your shell session. @@ -208,18 +216,16 @@ You can add your own environment variables if you like: > [!NOTE] > -> The environment variable's value is sanitized, so expressions like -> `MY_VAR: $(sudo rm -rf --no-preserve-root /)` will throw an error. +> - Adding environment variables only works via the `shellcode` route. +> - The environment variable's value is sanitized, so expressions like +> `MY_VAR: $(sudo rm -rf --no-preserve-root /)` will throw an error. +> - We recommend `direnv` instead of this route. ## `dev` & Editors -Most editors if opened via the Terminal will inherit that Terminal’s -environment. We recommend Visual Studio Code, `dev && code .` works great. - -> [!WARNING] -> -> Unfortunately, this usually means you _must_ open your editor via your -> terminal. +The sure fire way for things to work in editors is to use the `dev`/`pkgm` +combo. Having said this most editors if opened via the Terminal will inherit +that Terminal’s environment. ## GitHub Actions @@ -227,8 +233,8 @@ environment. We recommend Visual Studio Code, `dev && code .` works great. - uses: pkgxdev/dev@v1 ``` -Installs needed packages (via `pkgx`) and sets up the environment the same as -`dev` does in your terminal. +Our action installs needed packages (via `pkgx`) and sets up the environment the +same as `dev` does in your terminal. ## Contributing diff --git a/app.ts b/app.ts index 4ff1e7c..d09a546 100755 --- a/app.ts +++ b/app.ts @@ -3,13 +3,14 @@ //TODO if you step into dev-dir/subdir and type `dev` does it find the root properly? //TODO dev off uses PWD which may not be correct if in subdir (obv) -import { Path } from "libpkgx"; +import { Path, utils } from "libpkgx"; import shellcode, { datadir } from "./src/shellcode().ts"; import app_version from "./src/app-version.ts"; import integrate from "./src/integrate.ts"; import { parseArgs } from "jsr:@std/cli@^1/parse-args"; import dump from "./src/dump.ts"; import sniff from "./src/sniff.ts"; +import { walk } from "jsr:@std/fs@1/walk"; const parsedArgs = parseArgs(Deno.args, { alias: { @@ -28,10 +29,13 @@ const parsedArgs = parseArgs(Deno.args, { }); if (parsedArgs.help) { - const status = await new Deno.Command("pkgx", { - args: ["--quiet", "gh", "repo", "view", "pkgxdev/dev"], + const { code } = await new Deno.Command("pkgx", { + args: [ + "glow", + "https://raw.githubusercontent.com/pkgxdev/dev/refs/heads/main/README.md", + ], }).spawn().status; - Deno.exit(status.code); + Deno.exit(code); } else if (parsedArgs.shellcode) { console.log(shellcode()); } else if (parsedArgs.version) { @@ -40,20 +44,23 @@ if (parsedArgs.help) { const subcommand = parsedArgs._[0]; const dryrun = parsedArgs["dry-run"] as boolean; const quiet = parsedArgs["quiet"] != undefined; + switch (subcommand) { case "integrate": await integrate("install", { dryrun }); break; + case "deintegrate": await integrate("uninstall", { dryrun }); break; + case "status": { const cwd = Path.cwd(); if ( datadir().join(cwd.string.slice(1), "dev.pkgx.activated").isFile() ) { - //FIXME probably slower than necessary + //FIXME probably slower than ideal const { pkgs } = await sniff(cwd); Deno.exit(pkgs.length == 0 ? 1 : 0); } else { @@ -61,9 +68,82 @@ if (parsedArgs.help) { } } break; + + case "ls": + for await ( + const entry of walk(datadir().string, { includeDirs: false }) + ) { + if (entry.name === "dev.pkgx.activated") { + const partial_path = new Path(entry.path).parent().relative({ + to: datadir(), + }); + console.log(`/${partial_path}`); + } + } + break; + + case undefined: + { + const cwd = Path.cwd(); + const { pkgs } = await sniff(cwd); + if ( + datadir().join(cwd.string.slice(1), "dev.pkgx.activated").isFile() + ) { + console.log( + "%cactive", + "color: green", + pkgs.map(utils.pkg.str).join(" "), + ); + } else if (pkgs.length > 0) { + console.log( + "%cinactive", + "color: red", + pkgs.map(utils.pkg.str).join(" "), + ); + } else { + console.log("%cno keyfiles found", "color: red"); + } + } + break; + + case "off": { + let dir = Path.cwd(); + while (dir.string != "/") { + const f = datadir().join(dir.string.slice(1), "dev.pkgx.activated") + .isFile(); + if (f) { + f.rm(); + console.log("%cdeactivated", "color: green", dir.string); + Deno.exit(0); + } + dir = dir.parent(); + } + console.error("%cno devenv found", "color: red"); + Deno.exit(1); + break; + } + default: { - const cwd = Path.cwd().join(subcommand as string); - await dump(cwd, { dryrun, quiet }); + if (Deno.stdout.isTerminal()) { + const cwd = Path.cwd().join(subcommand as string); + const { pkgs } = await sniff(cwd); + if (pkgs.length > 0) { + datadir().join(cwd.string.slice(1)).mkdir("p").join( + "dev.pkgx.activated", + ).touch(); + console.log( + "%cactived", + "color: green", + pkgs.map(utils.pkg.str).join(" "), + ); + } else { + console.error("%cno keyfiles found", "color: red"); + Deno.exit(1); + } + } else { + const cwd = Path.cwd().join(subcommand as string); + await dump(cwd, { dryrun, quiet }); + } } } } diff --git a/src/shellcode().ts b/src/shellcode().ts index 3293bd9..0fb82e0 100644 --- a/src/shellcode().ts +++ b/src/shellcode().ts @@ -27,7 +27,14 @@ dev() { case "$1" in off) if type -f _pkgx_dev_try_bye >/dev/null 2>&1; then - rm "${datadir()}$PWD/dev.pkgx.activated" + dir="$PWD" + while [ "$dir" != / -a "$dir" != . ]; do + if [ -f "${datadir()}/$dir/dev.pkgx.activated" ]; then + rm "${datadir()}/$dir/dev.pkgx.activated" + break + fi + dir="$(dirname "$dir")" + done PWD=/ _pkgx_dev_try_bye else echo "no devenv" >&2