This commit is contained in:
Max Howell 2022-09-01 13:49:14 -04:00 committed by GitHub
parent e35091d0be
commit 915e9f1d82
10 changed files with 112 additions and 154 deletions

View file

@ -70,8 +70,9 @@ jobs:
id: sorted
run: ./scripts/sort.ts ${{ inputs.projects }}
- name: Build
run: |
- run: ./scripts/install.ts ${{ steps.sorted.outputs.pre-install }}
- run: |
./scripts/build.ts ${{ steps.sorted.outputs.pkgs }}
id: build
env:

View file

@ -0,0 +1,29 @@
distributable:
url: https://ftp.gnu.org/gnu/wget/wget-{{version}}.tar.gz
strip-components: 1
versions:
- 1.21.3
dependencies:
openssl.org: ^1.1
build:
dependencies:
tea.xyz/gx/cc: c99
tea.xyz/gx/make: '*'
freedesktop.org/pkg-config: ^0.29
script: |
./configure $ARGS
make --jobs {{hw.concurrency}} install
env:
ARGS:
- --prefix={{prefix}}
- --disable-pcre
- --disable-pcre2
- --without-libps1
- --without-included-regex
- --with-ssl=openssl
test:
wget tea.xyz

View file

@ -17,17 +17,21 @@ build:
tea.xyz/gx/cc: c99
tea.xyz/gx/make: '*'
perl.org: 5
curl.se: '*'
script: |
case "X{{ hw.target }}" in
"Xaarch64-apple-darwin") ARCH="darwin64-arm64-cc";;
"Xx86_64-apple-darwin") ARCH="darwin64-x86_64-cc";;
"Xx86_64-unknown-linux-gnu") ARCH="linux-x86_64";;
"Xaarch64-unknown-linux-gnu") ARCH="linux-aarch64";;
esac
./Configure --prefix={{ prefix }} $ARCH no-tests
make --jobs {{ hw.concurrency }}
make install
make install_sw # `_sw` avoids installing docs
#TODO needs to be a curl.se/pkg that gets updates
mkdir -p "$CERTDIR"
curl https://curl.se/ca/cacert-2022-07-19.pem -o "$CERTDIR"/cert.pem
env:
CERTDIR: ${{prefix}}/ssl
darwin/aarch64: {ARCH: 'darwin64-arm64-cc'}
darwin/x86-64: {ARCH: 'darwin64-x86_64-cc'}
linux/aarch64: {ARCH: 'linux-aarch64'}
linux/x86-64: {ARCH: 'linux-x86_64'}
test:
script: |

View file

@ -1,33 +0,0 @@
import usePantry from "hooks/usePantry.ts"
import { PackageRequirement } from "types"
/// this function is poorly named and does too many things
/// sorry. Refactor is desired.
export function get_build_deps(dry: Set<string>) {
const pantry = usePantry()
return async (pkg: PackageRequirement) => {
const deps = await pantry.getDeps(pkg)
if (dry.has(pkg.project)) {
// we hydrate the runtime deps of any build deps since if
// any of `dry` is a runtime dep of any build dep (obv. from another)
// pkg in the set we are building then it needs to be sorted first
const rv = [...deps.runtime, ...deps.build]
// if we are building a test-dep then we need it to be built before we
// build `pkg` or we will not be able to test it before building the whole
// graph
for (const test_dep of deps.test) {
if (dry.has(test_dep.project)) {
rv.push(test_dep)
}
}
return rv
} else {
return deps.runtime
}
}
}

View file

@ -1,14 +0,0 @@
#!/bin/bash
set -eo pipefail
d="$(cd "$(dirname "$0")" && pwd)"
all=$($d/ls.ts | xargs $d/sort.ts)
for x in $all
do
$d/build.ts $x
$d/test.ts $x --magic #FIXME be precise
done
# $d/bottle.ts $all

View file

@ -1,46 +0,0 @@
#!/usr/bin/env -S tea -E
/// deps to build the provided including building all its deps too
/*---
args:
- deno
- run
- --allow-net
- --allow-run
- --allow-read=/opt,/Library/Developer/CommandLineTools
- --allow-write=/opt
- --allow-env
- --import-map={{ srcroot }}/import-map.json
---*/
import { parsePackageRequirement } from "types"
import hydrate from "prefab/hydrate-topological.ts"
import useFlags from "hooks/useFlags.ts"
import { PackageRequirement } from "types"
import usePantry from "hooks/usePantry.ts"
const flags = useFlags()
const pantry = usePantry()
const dry = Deno.args.map(project => {
const match = project.match(/projects\/(.*)\/package.yml/)
return match ? match[1] : project
}).map(parsePackageRequirement)
const wet = await hydrate(dry, get)
const gas = wet.map(x => x.project)
if (Deno.env.get("GITHUB_ACTIONS")) {
console.log(`::set-output name=pkgs::${gas.join(" ")}`)
} else if (flags.json) {
console.log(gas)
} else {
console.log(gas.join("\n"))
}
async function get(pkg: PackageRequirement) {
const { build, runtime } = await pantry.getDeps(pkg)
return [...build, ...runtime]
}

View file

@ -17,13 +17,8 @@ import useCellar from "hooks/useCellar.ts"
import usePantry from "hooks/usePantry.ts"
import useCache from "hooks/useCache.ts"
import { lvl1 as link } from "prefab/link.ts"
import install from "prefab/install.ts"
import build from "prefab/build.ts"
import { semver, PackageRequirement, Package } from "types"
import { parsePackageRequirement } from "types"
import hydrate from "prefab/hydrate.ts"
import resolve from "prefab/resolve.ts"
import { get_build_deps } from "./_lib.ts"
import { Package, parsePackageRequirement, semver } from "types"
import useFlags from "hooks/useFlags.ts"
import usePlatform from "hooks/usePlatform.ts"
@ -37,51 +32,23 @@ const dry = Deno.args.map(project => {
return match ? match[1] : project
}).map(parsePackageRequirement)
const explicit_deps = new Set(dry.map(({ project }) => project))
const wet = await hydrate(dry, get_build_deps(explicit_deps))
const gas = async () => {
const rv: PackageRequirement[] = []
for (const pkg of wet) {
if (await cellar.isInstalled(pkg)) continue
if (explicit_deps.has(pkg.project)) continue
rv.push(pkg)
}
return rv
}
const plasma = await resolve(await gas())
for await (const pkg of plasma) {
console.log({ installing: pkg.project })
const installation = install(pkg)
await link(installation)
}
const rv: Package[] = []
for await (const pkg of dry) {
console.log({ building: pkg.project })
const versions = await pantry.getVersions(pkg)
const version = semver.maxSatisfying(versions, pkg.constraint)
for (const pkgrq of dry) {
const versions = await pantry.getVersions(pkgrq)
const version = semver.maxSatisfying(versions, pkgrq.constraint)
if (!version) throw "no-version-found"
await b({ project: pkg.project, version })
const pkg = { project: pkgrq.project, version }
rv.push({ project: pkg.project, version })
}
if (Deno.env.get("SKIP") && await cellar.isInstalled(pkg)) {
console.log({ skipping: pkg.project })
continue
}
const built_pkgs = rv.map(({ project, version }) => `${project}@${version}`).join(" ")
const txt = `::set-output name=pkgs::${built_pkgs}\n`
await Deno.stdout.write(new TextEncoder().encode(txt))
//end
async function b(pkg: Package) {
console.log({ building: pkgrq.project })
// Get the source
const prebuild = async () => {
const dstdir = useCellar().mkpath(pkg).join("src")
const dstdir = cellar.mkpath(pkg).join("src")
const { url, stripComponents } = await pantry.getDistributable(pkg)
const { download } = useCache()
const zip = await download({ pkg, url, type: 'src' })
@ -101,4 +68,10 @@ async function b(pkg: Package) {
// Build and link
const path = await build({ pkg, deps, prebuild, env })
await link({ path, pkg })
rv.push(pkg)
}
const built_pkgs = rv.map(({ project, version }) => `${project}@${version}`).join(" ")
const txt = `::set-output name=pkgs::${built_pkgs}\n`
await Deno.stdout.write(new TextEncoder().encode(txt))

35
scripts/install.ts Executable file
View file

@ -0,0 +1,35 @@
#!/usr/bin/env -S tea -E
// returns all pantry entries as `[{ name, path }]`
/*---
args:
- deno
- run
- --allow-env
- --allow-read
- --allow-write
- --import-map={{ srcroot }}/import-map.json
- --allow-net
- --allow-run
---*/
import { lvl1 as link } from "prefab/link.ts"
import install from "prefab/install.ts"
import { parsePackageRequirement } from "types"
import resolve from "prefab/resolve.ts"
import useFlags from "hooks/useFlags.ts"
useFlags()
const pkgs = Deno.args.map(project => {
const match = project.match(/projects\/(.*)\/package.yml/)
return match ? match[1] : project
}).map(parsePackageRequirement)
// resolve and install precise versions that are available in available inventories
for await (const pkg of await resolve(pkgs)) {
console.log({ installing: pkg.project })
const installation = install(pkg)
await link(installation)
}

View file

@ -12,25 +12,33 @@ args:
- --import-map={{ srcroot }}/import-map.json
---*/
// sorts input for building
// does a full hydration, but only returns ordered, dry packages
import { parsePackageRequirement } from "types"
import hydrate from "prefab/hydrate-topological.ts"
import { get_build_deps } from "./_lib.ts"
import hydrate from "prefab/hydrate.ts"
import useFlags from "hooks/useFlags.ts"
import usePantry from "../src/hooks/usePantry.ts"
const flags = useFlags()
const pantry = usePantry()
const dry = Deno.args.map(project => {
const match = project.match(/projects\/(.*)\/package.yml/)
return match ? match[1] : project
}).map(parsePackageRequirement)
const set = new Set(dry.map(x => x.project))
const wet = await hydrate(dry, get_build_deps(set))
const gas = wet.map(x => x.project)
.filter(x => set.has(x)) // we're only sorting `dry` so reject the rest
const wet = await hydrate(dry, async (pkg, dry) => {
const deps = await pantry.getDeps(pkg)
return dry ? [...deps.build, ...deps.runtime] : deps.runtime
})
const gas = wet.dry.map(x => x.project)
if (Deno.env.get("GITHUB_ACTIONS")) {
const pre = wet.wet.map(x=>x.project)
console.log(`::set-output name=pkgs::${gas.join(" ")}`)
console.log(`::set-output name=pre-install::${pre.join(" ")}`)
} else if (flags.json) {
console.log(gas)
} else {

View file

@ -94,7 +94,8 @@ async function get_deps() {
const rv: PackageRequirement[] = []
attempt(yml.dependencies)
attempt(yml.test.dependencies)
return await hydrate(rv)
const { pkgs } = await hydrate(rv, pkg => pantry.getDeps(pkg).then(x=>x.runtime))
return pkgs
function attempt(obj: PlainObject) {
if (isPlainObject(obj))