From 24466eb01d5461060c1e77332bfb60d954b06a5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1n=20D=C3=A9nes?= Date: Mon, 14 Nov 2022 00:40:05 +0100 Subject: [PATCH] Footprint sideloading progress --- package-lock.json | 165 +++++++++++++++++++++++++++++-- package.json | 1 + rollup.config.js | 5 +- src/cli.js | 88 ++++++++++++++--- src/ergogen.js | 16 ++- src/io.js | 21 ++++ test/cli/nonexistent_input/error | 2 +- test/helpers/mock_footprints.js | 10 +- 8 files changed, 279 insertions(+), 29 deletions(-) diff --git a/package-lock.json b/package-lock.json index c52b1dd..2e3177e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "dependencies": { "fs-extra": "^10.0.1", "js-yaml": "^3.14.1", + "jszip": "^3.10.1", "kle-serial": "github:ergogen/kle-serial#ergogen", "makerjs": "github:ergogen/maker.js#ergogen", "mathjs": "^10.1.1", @@ -983,6 +984,11 @@ "safe-buffer": "~5.1.1" } }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -1422,6 +1428,11 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==" + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -1453,8 +1464,7 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/is-binary-path": { "version": "2.1.0", @@ -1575,6 +1585,11 @@ "node": ">=0.10.0" } }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -1754,6 +1769,17 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, "node_modules/kdbush": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-2.0.1.tgz", @@ -1768,6 +1794,14 @@ "json5": "^2.1.0" } }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dependencies": { + "immediate": "~3.0.5" + } + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -2258,6 +2292,11 @@ "node": ">=8" } }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -2382,6 +2421,11 @@ "node": ">=8" } }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, "node_modules/process-on-spawn": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", @@ -2403,6 +2447,20 @@ "safe-buffer": "^5.1.0" } }, + "node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -2505,8 +2563,7 @@ "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "node_modules/seedrandom": { "version": "3.0.5", @@ -2537,6 +2594,11 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -2601,6 +2663,14 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -2756,6 +2826,11 @@ "node": ">= 10.0.0" } }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, "node_modules/uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", @@ -3645,6 +3720,11 @@ "safe-buffer": "~5.1.1" } }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -3953,6 +4033,11 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, + "immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==" + }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -3978,8 +4063,7 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "is-binary-path": { "version": "2.1.0", @@ -4064,6 +4148,11 @@ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -4203,6 +4292,17 @@ "universalify": "^2.0.0" } }, + "jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "requires": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, "kdbush": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-2.0.1.tgz", @@ -4215,6 +4315,14 @@ "json5": "^2.1.0" } }, + "lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "requires": { + "immediate": "~3.0.5" + } + }, "locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -4598,6 +4706,11 @@ "release-zalgo": "^1.0.0" } }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -4688,6 +4801,11 @@ } } }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, "process-on-spawn": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", @@ -4706,6 +4824,20 @@ "safe-buffer": "^5.1.0" } }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -4778,8 +4910,7 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "seedrandom": { "version": "3.0.5", @@ -4807,6 +4938,11 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -4859,6 +4995,14 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -4966,6 +5110,11 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, "uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", diff --git a/package.json b/package.json index 4e76399..dfcbca5 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "dependencies": { "fs-extra": "^10.0.1", "js-yaml": "^3.14.1", + "jszip": "^3.10.1", "kle-serial": "github:ergogen/kle-serial#ergogen", "makerjs": "github:ergogen/maker.js#ergogen", "mathjs": "^10.1.1", diff --git a/rollup.config.js b/rollup.config.js index 3e71d16..95bc171 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -4,7 +4,7 @@ import commonjs from '@rollup/plugin-commonjs' export default { input: 'src/ergogen.js', - external: ['makerjs', 'js-yaml', 'mathjs', 'kle-serial'], + external: ['makerjs', 'js-yaml', 'mathjs', 'kle-serial', 'jszip'], output: { name: 'ergogen', file: 'dist/ergogen.js', @@ -14,7 +14,8 @@ export default { 'makerjs': 'makerjs', 'js-yaml': 'jsyaml', 'mathjs': 'math', - 'kle-serial': 'kle' + 'kle-serial': 'kle', + 'jszip': 'jszip' } }, plugins: [ diff --git a/src/cli.js b/src/cli.js index cff5116..397a5e5 100755 --- a/src/cli.js +++ b/src/cli.js @@ -1,11 +1,17 @@ #!/usr/bin/env node const fs = require('fs-extra') +const fsp = require('fs/promises') const path = require('path') const yaml = require('js-yaml') const yargs = require('yargs') -const ergogen = require('./ergogen') +const jszip = require('jszip') + +const io = require('./io') const pkg = require('../package.json') +const ergogen = require('./ergogen') + +;(async () => { // command line args @@ -29,7 +35,52 @@ const args = yargs }) .argv -// config reading +// greetings + +const title_suffix = args.debug ? ' (Debug Mode)' : '' +console.log(`Ergogen v${pkg.version} CLI${title_suffix}`) +console.log() + +// input helpers + +// zip handling is baked in at the io level, so that both the cli and the webui can use it +// if, for local development, we want to use a folder as input, we temporarily zip it in +// memory so that it can be handled the exact same way +// functions shamelessly repurposed from https://github.com/Stuk/jszip/issues/386 + +// return a flat array of absolute paths of all files recursively contained in the dir +const list_files_in_dir = async (dir) => { + const list = await fsp.readdir(dir) + const statPromises = list.map(async (file) => { + const fullPath = path.resolve(dir, file) + const stat = await fsp.stat(fullPath) + if (stat && stat.isDirectory()) { + return list_files_in_dir(fullPath) + } + return fullPath + }) + + return (await Promise.all(statPromises)).flat(Infinity) +} + +// create an in-memory zip stream from a folder in the file system +const zip_from_dir = async (dir) => { + const absRoot = path.resolve(dir) + const filePaths = await list_files_in_dir(dir) + return filePaths.reduce((z, filePath) => { + const relative = filePath.replace(absRoot, '') + // create folder trees manually :( + const zipFolder = path + .dirname(relative) + .split(path.sep) + .reduce((zf, dirName) => zf.folder(dirName), z) + + zipFolder.file(path.basename(filePath), fs.createReadStream(filePath)) + return z + }, new jszip()) +} + +// input reading const config_file = args._[0] if (!config_file) { @@ -37,20 +88,33 @@ if (!config_file) { process.exit(1) } -let config_text +if (!fs.existsSync(config_file)) { + console.error(`Could not read config file "${config_file}": File does not exist!`) + process.exit(2) +} + +let config_text = '' +let injections = [] + try { - config_text = fs.readFileSync(config_file).toString() + if (config_file.endsWith('.zip') || config_file.endsWith('.ekb')) { + [config_text, injections] = await io.unpack( + (new jszip()).loadAsync(fs.readFileSync(config_file)) + ) + } else if (fs.statSync(config_file).isDirectory()) { + [config_text, injections] = await io.unpack(zip_from_dir(config_file)) + } else { + config_text = fs.readFileSync(config_file).toString() + // no injections... + } + for (const [type, value] of injections) { + ergogen.inject(type, value) + } } catch (err) { console.error(`Could not read config file "${config_file}": ${err}`) process.exit(2) } -const title_suffix = args.debug ? ' (Debug Mode)' : '' -console.log(`Ergogen v${pkg.version} CLI${title_suffix}`) -console.log() - -;(async () => { - // processing let results @@ -61,7 +125,7 @@ try { process.exit(3) } -// helpers +// output helpers const single = (data, rel) => { if (!data) return @@ -89,7 +153,7 @@ const composite = (data, rel) => { } } -// output +// output generation if (args.clean) { console.log('Cleaning output folder...') diff --git a/src/ergogen.js b/src/ergogen.js index bef7755..62afa0d 100644 --- a/src/ergogen.js +++ b/src/ergogen.js @@ -92,8 +92,22 @@ const process = async (raw, debug=false, logger=()=>{}) => { return results } +const inject = (type, name, value) => { + if (value === undefined) { + value = name + name = type + type = 'footprint' + } + switch (type) { + case 'footprint': + return pcbs_lib.inject_footprint(name, value) + default: + throw new Error(`Unknown injection type "${type}" with name "${name}" and value "${value}"!`) + } +} + module.exports = { version, process, - inject_footprint: pcbs_lib.inject_footprint + inject } \ No newline at end of file diff --git a/src/io.js b/src/io.js index 60e91fc..ce42cc4 100644 --- a/src/io.js +++ b/src/io.js @@ -1,10 +1,31 @@ const yaml = require('js-yaml') +const jszip = require('jszip') const makerjs = require('makerjs') const u = require('./utils') const a = require('./assert') const kle = require('./kle') +exports.unpack = async (zip) => { + + // main config text (has to be called "config.ext" where ext is one of yaml/json/js) + const config_text = await zip.file(/^config\.(yaml|json|js)$/).async('string') + const injections = [] + + // bundled footprints + const fps = zip.folder('footprints') + const module_prefix = 'const module = {};\n\n' + const module_suffix = '\n\nreturn module.exports;' + for (const fp in fps.file(/.*\.js$/)) { + const name = fp.name.split('.')[0] + const text = await fp.async('string') + const parsed = new Function(module_prefix + text + module_suffix)() + injections.push(['footprint', name, parsed]) + } + + return [config_text, injections] +} + exports.interpret = (raw, logger) => { let config = raw let format = 'OBJ' diff --git a/test/cli/nonexistent_input/error b/test/cli/nonexistent_input/error index 4207ee3..15be3d3 100644 --- a/test/cli/nonexistent_input/error +++ b/test/cli/nonexistent_input/error @@ -1 +1 @@ -Could not read config file "nonexistent.yaml": Error: ENOENT: no such file or directory, open 'nonexistent.yaml' \ No newline at end of file +Could not read config file "nonexistent.yaml": File does not exist! \ No newline at end of file diff --git a/test/helpers/mock_footprints.js b/test/helpers/mock_footprints.js index 80bea95..ddb0e82 100644 --- a/test/helpers/mock_footprints.js +++ b/test/helpers/mock_footprints.js @@ -1,5 +1,5 @@ exports.inject = (ergogen) => { - ergogen.inject_footprint('trace_test', { + ergogen.inject('footprint', 'trace_test', { nets: { P1: 'P1' }, @@ -28,7 +28,7 @@ exports.inject = (ergogen) => { } }) - ergogen.inject_footprint('zone_test', { + ergogen.inject('footprint', 'zone_test', { nets: { P1: 'P1' }, @@ -62,7 +62,7 @@ exports.inject = (ergogen) => { } }) - ergogen.inject_footprint('dynamic_net_test', { + ergogen.inject('footprint', 'dynamic_net_test', { nets: {}, params: { class: 'T', @@ -90,7 +90,7 @@ exports.inject = (ergogen) => { } }) - ergogen.inject_footprint('anchor_test', { + ergogen.inject('footprint', 'anchor_test', { nets: {}, params: { class: 'T', @@ -114,7 +114,7 @@ exports.inject = (ergogen) => { } }) - ergogen.inject_footprint('references_test', { + ergogen.inject('footprint', 'references_test', { nets: {}, params: {}, body: p => {