Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,25 @@ following [semver] syntax:
[semver]: https://devhints.io/semver


## Where does `pkgx` store files

* pkgs are cached to `~/.pkgx` (`$PKGX_DIR` overrides)

* pkg tarballs are cached to
* `~/Library/Caches/pkgx` on Mac
* `~/.cache/pkgx` on *nix
* `%LOCALAPPDATA%/cache/pkgx` on Windows
* ⚠️⚠️`$XDG_CACHE_HOME` overrides on all platforms
* runtime data like the [pantry] is stored in:
* `~/Library/Application Support/pkgx` on Mac
* `~/.local/share/pkgx` on *nix
* `%LOCALAPPDATA%/pkgx` on Windows
* ⚠️⚠️ `$XDG_DATA_HOME` overrides on all platforms

> If `$XDG_STATE_HOME` is set then `$XDG_STATE_HOME/pkgx` is used for some
> temporary shellcode state.


## I have another question

[Support](support.md)
6 changes: 5 additions & 1 deletion src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ type Args = BaseArgs & { flags: { verbosity: number } }

export default async function({ flags, ...opts }: Args, logger_prefix?: string) {
if (flags.sync) {
await useSync() //TODO Logger
try {
await useSync() //TODO Logger
} catch (err) {
if (!flags.keepGoing) throw err
}
}

const logger = make_logger(flags.verbosity, logger_prefix)
Expand Down
8 changes: 5 additions & 3 deletions src/err-handler.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { DownloadError, InstallationNotFoundError, PantryError, PantryParseError, ResolveError, PkgxError, utils } from "pkgx"
import { AmbiguityError, ProgrammerError, ProvidesError } from "./utils/error.ts"
import announce from "./utils/announce.ts";
import announce from "./utils/announce.ts"
import { red } from "./utils/color.ts"

export default function(err: Error) {
if (err instanceof InstallationNotFoundError) {
Expand All @@ -11,10 +12,11 @@ export default function(err: Error) {
['there was an issue fetching %s', err.src.toString()]
], 'http-failure')
} else if (err instanceof ResolveError) {
const { platform, arch } = utils.host()
render('version unavailable', utils.pkg.str(err.pkg), [
['please check the following url for available versions'],
['if it’s not there, we’ll build it! open a ticket on the pantry.']
], `https://dist.pkgx.dev/?prefix=${err.pkg.project}`)
], `https://dist.pkgx.dev/?prefix=${err.pkg.project}/${platform}/${arch}`)
} else if (err instanceof PantryParseError) {
//TODO well not if it's a custom edit tho
render('parse error', err.project, [
Expand Down Expand Up @@ -55,5 +57,5 @@ export default function(err: Error) {
}

export function render(title: string, subtitle: string | undefined, body: (string[])[], help: string | undefined) {
announce({ title, subtitle, body, help, color: 'red' })
announce({ title, subtitle, body, help, color: red })
}
25 changes: 20 additions & 5 deletions src/modes/shellcode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default function() {
const blurple = (x: string) => `\\033[38;5;63m${x}\\033[0m`
const dim = (x: string) => `\\e[2m${x}\\e[0m`
const datadir = useConfig().data.join("dev")
const tmp = (flatmap(Deno.env.get("XDG_STATE_HOME"), Path.abs) ?? Path.home().join(".local", "state")).join("pkgx")
const tmp = (flatmap(Deno.env.get("XDG_STATE_HOME"), Path.abs) ?? platform_state_default()).join("pkgx")
const sh = '${SHELL:-/bin/sh}'

return undent`
Expand Down Expand Up @@ -48,8 +48,10 @@ export default function() {
case $1 in
"")
if [ -f "${tmp}/shellcode/x.$$" ]; then
eval "$(${sh} "${tmp}/shellcode/u.$$" --hush)"
${sh} "${tmp}/shellcode/x.$$"
if foo="$("${tmp}/shellcode/u.$$")"; then
eval "$foo"
${sh} "${tmp}/shellcode/x.$$"
fi
rm "${tmp}/shellcode/"?.$$
else
echo "pkgx: nothing to run" >&2
Expand Down Expand Up @@ -100,13 +102,15 @@ export default function() {
if [ "$1" = pkgx ]; then
echo 'fatal: \`pkgx\` not in PATH' >&2
return 1
elif command pkgx --silent --provider "$1"; then
elif command pkgx --sync --keep-going --silent --provider "$1"; then
echo -e '${dim('^^ type `')}x${dim('` to run that')}' >&2

d="${tmp}/shellcode"
mkdir -p "$d"
echo "echo -e \\"${blurple('env')} +$1 ${dim('&&')} $@ \\" >&2" > "$d/u.$$"
echo "#!${sh}" > "$d/u.$$"
echo "echo -e \\"${blurple('env')} +$1 ${dim('&&')} $@ \\" >&2" >> "$d/u.$$"
echo "exec pkgx --internal.use +\\"$1\\"" >> "$d/u.$$"
chmod u+x "$d/u.$$"
echo -n "exec " > "$d/x.$$"
for arg in "$@"; do
printf "%q " "$arg" >> "$d/x.$$"
Expand Down Expand Up @@ -181,3 +185,14 @@ export default function() {
fi
`
}

function platform_state_default() {
switch (Deno.build.os) {
case 'darwin':
return Path.home().join("Library/Application Support")
case "windows":
return new Path(Deno.env.get("LOCALAPPDATA")!)
default:
return Path.home().join(".local", "state")
}
}
3 changes: 2 additions & 1 deletion src/modes/x.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ async function find_it(args: string[], dry: PackageRequirement[]) {
}

// be just works: do a sync in case this has been recently added to the pantry
_internals.useSync()
await _internals.useSync()

wut = await find_arg0(args, dry)
if (wut) {
return wut
Expand Down
7 changes: 6 additions & 1 deletion src/parse-args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ interface Flags {
sync: boolean
update: boolean
verbosity?: number
keepGoing: boolean
}

export default function(input: string[]): Args {
Expand All @@ -54,7 +55,8 @@ export default function(input: string[]): Args {
const unknown: string[] = []
const flags: Flags = {
sync: false,
update: false
update: false,
keepGoing: false
}
let mode: string | undefined
let dryrun: boolean | undefined
Expand Down Expand Up @@ -111,6 +113,9 @@ export default function(input: string[]): Args {
case 'dry-run':
dryrun = true
break
case 'keep-going':
flags.keepGoing = true
break
case '':
// empty the main loop iterator
for (const arg of it) unknown.push(arg)
Expand Down
33 changes: 19 additions & 14 deletions src/prefab/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,36 @@ export type Logger = {
upgrade(dry: PackageSpecification[], pending: Package[]): BaseLogger | undefined
}

export default async function(dry: PackageSpecification[], { logger, ...opts }: {
interface Options {
update: boolean | Set<string>,
logger: Logger
}) {
}

export default async function(dry: PackageSpecification[], { logger, ...opts }: Options) {
logger.replace("resolving graph…")

const { resolve, install, link, getproj, hydrate } = _internals
try {
const { resolve, install, link, getproj, hydrate } = _internals

const companions = (await Promise.all(dry.map(pkg => getproj(pkg).companions()))).flatMap(x => x)
const companions = (await Promise.all(dry.map(pkg => getproj(pkg).companions()))).flatMap(x => x)

const { pkgs: wet, dry: pkgenv_ } = await failsafe(() => hydrate(dry.concat(companions)))
const { pending, installed: installations } = await resolve(wet, opts)
const { pkgs: wet, dry: pkgenv_ } = await failsafe(() => hydrate(dry.concat(companions)))
const { pending, installed: installations } = await resolve(wet, opts)

const superlogger = logger.upgrade(dry, pending)
const superlogger = logger.upgrade(dry, pending)

const installers = pending.map(pkg => install(pkg, superlogger).then(i => link(i).then(() => i)))
installations.push(...await Promise.all(installers))
const installers = pending.map(pkg => install(pkg, superlogger).then(i => link(i).then(() => i)))
installations.push(...await Promise.all(installers))

logger.clear()
const pkgenv = pkgenv_.filter(({project}) => companions.some(x => x.project == project) == false)

const pkgenv = pkgenv_.filter(({project}) => companions.some(x => x.project == project) == false)
return {
installations,
pkgenv
}

return {
installations,
pkgenv
} finally {
logger.clear()
}
}

Expand Down
14 changes: 7 additions & 7 deletions src/utils/announce.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { dim } from './color.ts'
import { dim, blurple } from './color.ts'

export default function({ title, subtitle, body, help, color }: {title: string, subtitle?: string | undefined, body: (string[])[], help?: string | undefined, color?: string}) {
color = `color: ${color ?? '#5f5fff'}`
export default function({ title, subtitle, body, help, color }: {title: string, subtitle?: string | undefined, body: (string[])[], help?: string | undefined, color?: (x: string) => string}) {
color ??= blurple
help ??= 'unknown-error'

if (subtitle) {
console.error('%c× %s %c%s', color, title, 'color: initial', subtitle)
console.error(`${color(`× %s`)} %s`, title, subtitle)
} else {
console.error('%c× %s', color, title)
console.error(color('× %s'), title)
}
for (const [s1, ...ss] of body) {
console.error(`%c│%c ${s1 ?? ''}`, color, 'color: initial', ...ss)
console.error(`${color('│')} ${s1 ?? ''}`, ...ss)
}

const url = help.startsWith('http') ? help : `https://docs.pkgx.sh/help/${help}`
console.error('%c╰─➤%c %s', color, 'color: initial', dim(url))
console.error(`${color('╰─➤')} %s`, dim(url))
}
4 changes: 2 additions & 2 deletions src/utils/color.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { dim, rgb8, bgRgb8 } from "deno/fmt/colors.ts"
import { dim, rgb8, bgRgb8, red } from "deno/fmt/colors.ts"

export const blurple = (x: string) => rgb8(x, 63)
export { dim }
export { dim, red }
export const inverse_blurple = (x: string) => bgRgb8(x, 63)