Skip to content

Commit

Permalink
arbitrary digit & openssl scheme version support (pkgxdev#255)
Browse files Browse the repository at this point in the history
  • Loading branch information
mxcl authored Dec 14, 2022
1 parent 01ba8be commit 87ce3f5
Show file tree
Hide file tree
Showing 10 changed files with 254 additions and 168 deletions.
2 changes: 1 addition & 1 deletion src/app.exec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ export async function which(arg0: string) {
rx = new RegExp(`^${foo}$`)
match = arg0.match(rx)
if (match) {
const constraint = new semver.Range(match[1])
const constraint = new semver.Range(`~${match[1]}`)
found = {...entry, constraint}
}
}
Expand Down
13 changes: 9 additions & 4 deletions src/hooks/useCellar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import SemVer from "semver"
import Path from "path"
//ALERT!! do not usePantry() or you can softlock in usePantry.git.ts
import { usePrefix } from "hooks"
import useFlags from "./useFlags.ts"


export default function useCellar() {
Expand All @@ -28,22 +29,26 @@ const keg = (pkg: Package) => shelf(pkg.project).join(`v${pkg.version}`)
/// returns a project’s installations (sorted by version)
async function ls(project: string) {
const d = shelf(project)
const { verbose } = useFlags()

if (!d.isDirectory()) return []

const rv: Installation[] = []
for await (const [path, {name, isDirectory}] of d.ls()) {
try {
if (!isDirectory) continue
if (!name.startsWith("v")) continue
const version = new SemVer(name.slice(1))
if (!name.startsWith("v") || name == 'var') continue
const version = new SemVer(name)
if (await vacant(path)) continue
rv.push({path, pkg: {project, version}})
} catch {
// not console.warn as we allow other dirs as a design choice
console.verbose(`warn: invalid version: ${name}`)
if (verbose) {
console.warn(`warn: invalid version: ${name}`)
}
}
}

return rv.sort((a, b) => pkgutils.compare(a.pkg, b.pkg))
}

Expand All @@ -56,7 +61,7 @@ async function resolve(pkg: Package | PackageRequirement | Path | Installation)
const prefix = usePrefix()
if (pkg instanceof Path) {
const path = pkg
const version = new SemVer(path.basename().slice(1))
const version = new SemVer(path.basename())
const project = path.parent().relative({ to: prefix })
return {
path, pkg: { project, version }
Expand Down
14 changes: 10 additions & 4 deletions src/prefab/link.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Package, Installation } from "types"
import { useCellar } from "hooks"
import Path from "path"
import SemVer, * as semver from "semver"
import { panic } from "../utils/safe-utils.ts"

export default async function link(pkg: Package | Installation) {
const installation = await useCellar().resolve(pkg)
Expand All @@ -12,19 +13,24 @@ export default async function link(pkg: Package | Installation) {
.map(({pkg: {version}, path}) => [version, path] as [SemVer, Path])
.sort(([a],[b]) => a.compare(b))

if (versions.length <= 0) {
console.error(pkg, installation)
throw new Error(`no versions`)
}

const shelf = installation.path.parent()
const newest = versions.slice(-1)[0]
const vMm = `${pkg.version.major}.${pkg.version.minor}`
const minorRange = new semver.Range(vMm)
const mostMinor = versions.filter(v => minorRange.satisfies(v[0])).at(-1)!
const minorRange = new semver.Range(`^${vMm}`)
const mostMinor = versions.filter(v => minorRange.satisfies(v[0])).at(-1) ?? panic()

if (mostMinor[0].neq(pkg.version)) return
// ^^ if we’re not the most minor we definitely not the most major

await makeSymlink(`v${vMm}`)

const majorRange = new semver.Range(pkg.version.major.toString())
const mostMajor = versions.filter(v => majorRange.satisfies(v[0])).at(-1)!
const majorRange = new semver.Range(`^${pkg.version.major.toString()}`)
const mostMajor = versions.filter(v => majorRange.satisfies(v[0])).at(-1) ?? panic()

if (mostMajor[0].neq(pkg.version)) return
// ^^ if we’re not the most major we definitely aren’t the newest
Expand Down
4 changes: 1 addition & 3 deletions src/utils/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,7 @@ export default class TeaError extends Error {
export class UsageError extends Error
{}

export function panic(message?: string): never {
throw new Error(message)
}
export { panic } from "./safe-utils.ts"

export const wrap = <T extends Array<unknown>, U>(fn: (...args: T) => U, id: ID) => {
return (...args: T): U => {
Expand Down
2 changes: 1 addition & 1 deletion src/utils/hacks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export function validatePackageRequirement(input: PlainObject): PackageRequireme
if (constraint === undefined) {
constraint = '*'
} else if (isNumber(constraint)) {
constraint = `${constraint}`
constraint = `^${constraint}`
}
if (!isString(constraint)) {
throw new Error(`invalid constraint: ${constraint}`)
Expand Down
4 changes: 1 addition & 3 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,7 @@ String.prototype.chuzzle = function() {
return this.trim() || undefined
}

export function chuzzle(input: number) {
return Number.isNaN(input) ? undefined : input
}
export { chuzzle } from "./safe-utils.ts"

Set.prototype.insert = function<T>(t: T) {
if (this.has(t)) {
Expand Down
17 changes: 17 additions & 0 deletions src/utils/safe-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// utils safe enough “pure” stuff (eg. semver.ts, Path.ts)

export function chuzzle(input: number) {
return Number.isNaN(input) ? undefined : input
}

export function panic(message?: string): never {
throw new Error(message)
}

export function flatmap<S, T>(t: T | undefined | null, body: (t: T) => S | undefined, opts?: {rescue?: boolean}): NonNullable<S> | undefined {
try {
if (t) return body(t) ?? undefined
} catch (err) {
if (!opts?.rescue) throw err
}
}
Loading

0 comments on commit 87ce3f5

Please sign in to comment.