aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis Pilfold <louis@lpil.uk>2021-09-12 12:44:15 +0100
committerLouis Pilfold <louis@lpil.uk>2021-09-12 12:44:15 +0100
commit7669f75f4ee16d692b1171c3329bf5e3485c1a7c (patch)
tree3a3686993ee3e6da5b968851fc7009104abb2430
parent6529e7ebcd8681f2d1687d2aa8e44838c25ed279 (diff)
downloadjavascript-7669f75f4ee16d692b1171c3329bf5e3485c1a7c.tar.gz
javascript-7669f75f4ee16d692b1171c3329bf5e3485c1a7c.zip
Build script
-rw-r--r--bin/build.js156
-rw-r--r--bin/run-tests.js48
-rw-r--r--bin/test.sh62
-rw-r--r--package.json13
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"
+ }
+ ]
}