Skip to content

Commit

Permalink
PathUtils.ts: search and manage $PATH (pkgxdev#506)
Browse files Browse the repository at this point in the history
* add search path inspection
* stupid ubuntu
* ok. bin and usr/bin are symlinks, at least in ubuntu:latest.
* is nothing sacred?
* move PathUtils.ts to its own library
* markdownlint
  • Loading branch information
jhheider authored and mxcl committed Apr 13, 2023
1 parent 61da0e3 commit f5f9ff7
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 0 deletions.
1 change: 1 addition & 0 deletions import-map.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"imports": {
"path": "./src/vendor/Path.ts",
"path-utils": "./src/vendor/PathUtils.ts",
"types": "./src/types.ts",
"hooks": "./src/hooks/index.ts",
"hooks/": "./src/hooks/",
Expand Down
40 changes: 40 additions & 0 deletions src/vendor/PathUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import Path from "path"

export default {
envPath,
addPath,
rmPath,
findBinary,
}

function envPath(pathVar: string | undefined = undefined): Path[] {
const pathVar_ = pathVar || Deno.env.get("PATH")!
return pathVar_.split(":").map(x => new Path(x))
}

function addPath(path: Path | string, pathVar: string | undefined = undefined): Path[] {
const pathVar_ = envPath(pathVar)
const path_ = new Path(path)
if (!pathVar_.includes(path_)) {
pathVar_.push(path_)
Deno.env.set("PATH", pathVar_.join(":"))
}
return pathVar_
}

function rmPath(path: Path | string, pathVar: string | undefined = undefined): Path[] {
const path_ = new Path(path)
const pathVar_ = envPath(pathVar).filter(x => x.string != path_.string)
Deno.env.set("PATH", pathVar_.join(":"))
return pathVar_
}

function findBinary(name: string, pathVar: string | Path[] | undefined = undefined): Path | undefined {
let pathVar_: Path[]
if (pathVar instanceof Array) {
pathVar_ = pathVar
} else {
pathVar_ = envPath(pathVar)
}
return pathVar_.find(x => x.join(name).isExecutableFile())?.join(name)
}
6 changes: 6 additions & 0 deletions src/vendor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,9 @@ Goals:
6. Consistent

Based on [mxcl/Path.swift](https://github.com/mxcl/Path.swift)

<!-- markdownlint-disable-next-line MD025 -->
# PathUtils.ts

Companion library to `Path.ts`. Contains common path-oriented
operations that don't specifically belong on a `Path` object.
48 changes: 48 additions & 0 deletions tests/unit/path-utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import Path from "path"
import PathUtils from "path-utils"
import { assertArrayIncludes, assertEquals } from "deno/testing/asserts.ts"

Deno.test("test PathUtils", async test => {
await test.step("modify $PATH", () => {
const envPath = PathUtils.envPath()

assertArrayIncludes(envPath, [Path.root.join("usr/bin")])

const a = Path.home().join("tmp/bin")
const b = PathUtils.addPath(a)
assertArrayIncludes(b, [a])

const c = PathUtils.envPath()
assertArrayIncludes(c, [a])

const d = PathUtils.rmPath(a)
assertEquals(d, envPath)

const e = PathUtils.envPath()
assertEquals(e, envPath)
})

await test.step("search $PATH", () => {
const usrBin = Path.root.join("usr/bin")
const bin = Path.root.join("bin")
const sbin = Path.root.join("sbin")
const envPath = PathUtils.envPath()

assertArrayIncludes(envPath, [usrBin])

const a = PathUtils.findBinary("env", envPath)
assertEquals(a, usrBin.join("env"))

const b = PathUtils.findBinary("env")
assertEquals(b, usrBin.join("env"))

const c = PathUtils.findBinary("bloogargle", envPath)
assertEquals(c, undefined)

const d = PathUtils.findBinary("ls", [bin])
assertEquals(d, bin.join("ls"))

const e = PathUtils.findBinary("ls", [sbin])
assertEquals(e, undefined)
})
})

0 comments on commit f5f9ff7

Please sign in to comment.