diff options
author | Louis Pilfold <louis@lpil.uk> | 2021-09-12 12:44:15 +0100 |
---|---|---|
committer | Louis Pilfold <louis@lpil.uk> | 2021-09-12 12:44:15 +0100 |
commit | 7669f75f4ee16d692b1171c3329bf5e3485c1a7c (patch) | |
tree | 3a3686993ee3e6da5b968851fc7009104abb2430 | |
parent | 6529e7ebcd8681f2d1687d2aa8e44838c25ed279 (diff) | |
download | javascript-7669f75f4ee16d692b1171c3329bf5e3485c1a7c.tar.gz javascript-7669f75f4ee16d692b1171c3329bf5e3485c1a7c.zip |
Build script
-rw-r--r-- | bin/build.js | 156 | ||||
-rw-r--r-- | bin/run-tests.js | 48 | ||||
-rw-r--r-- | bin/test.sh | 62 | ||||
-rw-r--r-- | package.json | 13 |
4 files changed, 167 insertions, 112 deletions
diff --git a/bin/build.js b/bin/build.js new file mode 100644 index 0000000..3937705 --- /dev/null +++ b/bin/build.js @@ -0,0 +1,156 @@ +import { stat, copyFile, readFile, mkdir, access, readdir } from "fs/promises"; +import { resolve, relative, join } from "path"; +import { promisify } from "util"; +import { exec as callbackExec } from "child_process"; + +let exec = promisify(callbackExec); + +export async function build() { + let { name, gleamDependencies } = JSON.parse( + await readFile("./package.json") + ); + + await Promise.all(gleamDependencies.map(clone)); + for (let dep of gleamDependencies) await cachedBuildProject(dep); + + await buildProject({ + name, + root: ".", + includeTests: true, + dependencies: gleamDependencies.map((d) => d.name), + }); + + return { + name, + }; +} + +async function copyJs(name, dir) { + let inDir = join(dir, "src"); + let out = outDir(name); + let files = await readdir(inDir); + files.map(async (file) => { + if (file.endsWith(".js")) { + await copyFile(join(inDir, file), join(out, file)); + } + }); +} + +async function cachedBuildProject(info) { + if (await fileExists(outDir(info.name))) return; + await buildProject(info); +} + +async function buildProject({ name, root, dependencies, includeTests }) { + console.log(`Building ${name}`); + let dir = root || libraryDir(name); + let src = join(dir, "src"); + let test = join(dir, "test"); + let out = outDir(name); + try { + await exec( + [ + "gleam compile-package", + `--name ${name}`, + "--target javascript", + `--src ${src}`, + includeTests ? `--test ${test}` : "", + `--out ${out}`, + (dependencies || []).map((dep) => `--lib=${outDir(dep)}`).join(" "), + ].join(" ") + ); + } catch (error) { + console.error(error.stderr); + process.exit(1); + } + await copyJs(name, dir); +} + +async function clone({ name, ref, url }) { + let dir = libraryDir(name); + if (await fileExists(dir)) return; + await mkdir(dir, { recursive: true }); + await exec(`git clone --depth=1 --branch="${ref}" "${url}" "${dir}"`); +} + +function libraryDir(name) { + return join("target", "deps", name); +} + +function outDir(name) { + return join("target", "lib", name); +} + +async function fileExists(path) { + try { + await access(path); + return true; + } catch { + return false; + } +} + +async function test() { + let gleamPackage = await build(); + + console.log("Running tests..."); + + let dir = `target/lib/${gleamPackage.name}`; + let passes = 0; + let failures = 0; + + for await (let path of await getFiles(dir)) { + if (!path.endsWith("_test.js")) continue; + let module = await import(path); + + for await (let fnName of Object.keys(module)) { + if (!fnName.endsWith("_test")) continue; + try { + await module[fnName](); + process.stdout.write(`\u001b[32m.\u001b[0m`); + passes++; + } catch (error) { + let moduleName = "\n" + relative(dir, path).slice(0, -3); + process.stdout.write(`\n❌ ${moduleName}.${fnName}: ${error}\n`); + failures++; + } + } + } + + console.log(` + +${passes + failures} tests +${failures} failures`); + process.exit(failures ? 1 : 0); +} + +async function getFiles(dir) { + const subdirs = await readdir(dir); + const files = await Promise.all( + subdirs.map(async (subdir) => { + const res = resolve(dir, subdir); + return (await stat(res)).isDirectory() ? getFiles(res) : res; + }) + ); + return files.reduce((a, f) => a.concat(f), []); +} + +async function main() { + switch (process.argv[process.argv.length - 1]) { + case "build": + return await build(); + + case "test": + return await test(); + + default: + console.error(` +Usage: + node bin/build.js test + node bin/build.js build +`); + process.exit(1); + } +} + +main(); diff --git a/bin/run-tests.js b/bin/run-tests.js deleted file mode 100644 index 0497367..0000000 --- a/bin/run-tests.js +++ /dev/null @@ -1,48 +0,0 @@ -import { readdir, stat } from "fs/promises"; -import { resolve, relative } from "path"; - -const dir = "target/lib/gleam_javascript"; - -async function main() { - console.log("Running tests..."); - - let passes = 0; - let failures = 0; - - for await (let path of await getFiles(dir)) { - if (!path.endsWith("_test.js")) continue; - let module = await import(path); - - for await (let fnName of Object.keys(module)) { - if (!fnName.endsWith("_test")) continue; - try { - await module[fnName](); - process.stdout.write(`\u001b[32m.\u001b[0m`); - passes++; - } catch (error) { - let moduleName = "\n" + relative(dir, path).slice(0, -3); - process.stdout.write(`\n❌ ${moduleName}.${fnName}: ${error}\n`); - failures++; - } - } - } - - console.log(` - -${passes + failures} tests -${failures} failures`); - process.exit(failures ? 1 : 0); -} - -async function getFiles(dir) { - const subdirs = await readdir(dir); - const files = await Promise.all( - subdirs.map(async (subdir) => { - const res = resolve(dir, subdir); - return (await stat(res)).isDirectory() ? getFiles(res) : res; - }) - ); - return files.reduce((a, f) => a.concat(f), []); -} - -main(); diff --git a/bin/test.sh b/bin/test.sh deleted file mode 100644 index d8efb03..0000000 --- a/bin/test.sh +++ /dev/null @@ -1,62 +0,0 @@ -#/bin/bash -set -eu - -library_dir() { - echo "target/deps/$1" -} - -project_dir() { - echo "target/lib/$1" -} - -clone_dep() { - local dir=$(library_dir "$1") - local tag="$2" - local url="$3" - - if [ ! -d "$dir" ] ; then - mkdir -p "$dir" - git clone --depth=1 --branch="$tag" "$url" "$dir" - fi -} - -compile_library() { - local name="$1" - echo "Compiling $name" - - shift - local lib_flags=() - for dep in "$@"; do - lib_flags+=("--lib=$(project_dir $dep)") - done - - local dir=$(library_dir "$name") - local src="$dir/src" - local out=$(project_dir "$name") - - - if [ ! -d "$out" ] ; then - gleam compile-package \ - --name "$name" \ - --target javascript \ - --src "$src" \ - --out $(project_dir "$name") \ - "${lib_flags[@]: }" - cp "$src/"*.js "$out/" - fi -} - -clone_dep gleam_stdlib main https://github.com/gleam-lang/stdlib.git -compile_library gleam_stdlib - -rm -rf $(project_dir gleam_javascript) -gleam compile-package \ - --name gleam_javascript \ - --target javascript \ - --src src \ - --test test \ - --out $(project_dir gleam_javascript) \ - --lib $(project_dir gleam_stdlib) -cp "src/"*.js $(project_dir gleam_javascript)/ - -node bin/run-tests.js diff --git a/package.json b/package.json index 05119aa..eeac2a1 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,18 @@ { + "name": "gleam_javascript", "type": "module", "scripts": { - "test": "bash bin/test.sh" + "build": "node bin/build.js build", + "test": "node bin/build.js test" }, "devDependencies": { "gleam-packages": "file:./target/lib" - } + }, + "gleamDependencies": [ + { + "name": "gleam_stdlib", + "ref": "main", + "url": "https://github.com/gleam-lang/stdlib.git" + } + ] } |