summary refs log tree commit diff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--scripts/benchmark.js28
-rw-r--r--scripts/benchmark/connections.js (renamed from bundle/scripts/benchmark/connections.js)2
-rw-r--r--scripts/benchmark/index.js (renamed from bundle/scripts/benchmark/index.js)0
-rw-r--r--scripts/benchmark/users.js (renamed from bundle/scripts/benchmark/users.js)0
-rw-r--r--scripts/build.js72
-rwxr-xr-xscripts/db_migrations.sh41
-rw-r--r--scripts/depcheck.js56
-rw-r--r--scripts/depclean.js62
-rw-r--r--scripts/droptables.sql (renamed from api/scripts/droptables.sql)0
-rw-r--r--scripts/gen_index.js34
-rw-r--r--scripts/generate_openapi.js (renamed from api/scripts/generate_openapi.js)2
-rw-r--r--scripts/generate_schema.js (renamed from api/scripts/generate_schema.js)15
-rw-r--r--scripts/migrate_db_engine.js (renamed from util/scripts/migrate_db_engine.js)0
-rw-r--r--scripts/rights.js34
-rw-r--r--scripts/stresstest/.gitignore (renamed from api/scripts/stresstest/.gitignore)0
-rw-r--r--scripts/stresstest/accounts.json.example (renamed from api/scripts/stresstest/accounts.json.example)0
-rw-r--r--scripts/stresstest/config.json.example (renamed from api/scripts/stresstest/config.json.example)0
-rw-r--r--scripts/stresstest/index.js (renamed from api/scripts/stresstest/index.js)10
-rw-r--r--scripts/stresstest/package-lock.json (renamed from api/scripts/stresstest/package-lock.json)0
-rw-r--r--scripts/stresstest/package.json (renamed from api/scripts/stresstest/package.json)0
-rw-r--r--scripts/stresstest/src/login/index.js (renamed from api/scripts/stresstest/src/login/index.js)6
-rw-r--r--scripts/stresstest/src/message/send.js (renamed from api/scripts/stresstest/src/message/send.js)6
-rw-r--r--scripts/stresstest/src/register/index.js (renamed from api/scripts/stresstest/src/register/index.js)10
-rw-r--r--scripts/update_schemas.js9
-rw-r--r--scripts/utils.js51
25 files changed, 412 insertions, 26 deletions
diff --git a/scripts/benchmark.js b/scripts/benchmark.js
new file mode 100644

index 00000000..e7435191 --- /dev/null +++ b/scripts/benchmark.js
@@ -0,0 +1,28 @@ +const typeorm = require("typeorm"); +const Models = require("../dist/entities"); +const { PrimaryColumn } = require("typeorm"); + +function shouldIncludeEntity(name) { + return ![Models.BaseClassWithoutId, PrimaryColumn, Models.BaseClass, Models.PrimaryGeneratedColumn] + .map((x) => x?.name) + .includes(name); +} + +async function main() { + console.log("starting"); + const db = new typeorm.DataSource({ + type: "sqlite", + database: ":memory:", + entities: Object.values(Models).filter((x) => x.constructor.name == "Function" && shouldIncludeEntity(x.name)), + synchronize: true, + }); + await db.initialize(); + console.log("Initialized database"); + + for (var i = 0; i < 100; i++) { + await Models.User.register({ username: "User" + i }); + console.log("registered user " + i); + } +} + +main(); diff --git a/bundle/scripts/benchmark/connections.js b/scripts/benchmark/connections.js
index ffca2628..661548c3 100644 --- a/bundle/scripts/benchmark/connections.js +++ b/scripts/benchmark/connections.js
@@ -4,7 +4,7 @@ const WebSocket = require("ws"); const endpoint = process.env.GATEWAY || "ws://localhost:3001"; const connections = Number(process.env.CONNECTIONS) || 50; const token = process.env.TOKEN; -var cores = 1; +let cores = 1; try { cores = Number(process.env.THREADS) || os.cpus().length; } catch { diff --git a/bundle/scripts/benchmark/index.js b/scripts/benchmark/index.js
index 37ac5633..37ac5633 100644 --- a/bundle/scripts/benchmark/index.js +++ b/scripts/benchmark/index.js
diff --git a/bundle/scripts/benchmark/users.js b/scripts/benchmark/users.js
index bce67bf4..bce67bf4 100644 --- a/bundle/scripts/benchmark/users.js +++ b/scripts/benchmark/users.js
diff --git a/scripts/build.js b/scripts/build.js new file mode 100644
index 00000000..2c0d7328 --- /dev/null +++ b/scripts/build.js
@@ -0,0 +1,72 @@ +const { execSync } = require("child_process"); +const path = require("path"); +const fs = require("fs"); +const { argv, stdout, exit } = require("process"); +const { execIn, parts } = require('./utils'); + +if(argv.includes("help")) { + console.log(`Fosscord build script help: +Arguments: + clean Cleans up previous builds + verbose Enable verbose logging + logerrors Log build errors to console + pretty-errors Pretty-print build errors + silent No output to console or files.`); + exit(0); +} + +let steps = 1, i = 0; +if (argv.includes("clean")) steps++; + +const verbose = argv.includes("verbose") || argv.includes("v"); +const logerr = argv.includes("logerrors"); +const pretty = argv.includes("pretty-errors"); +const silent = argv.includes("silent"); + +if(silent) console.error = console.log = function(){} + +if (argv.includes("clean")) { + console.log(`[${++i}/${steps}] Cleaning...`); + let d = "dist"; + if (fs.existsSync(d)) { + fs.rmSync(d, { recursive: true }); + if (verbose) console.log(`Deleted ${d}!`); + } +} + +console.log(`[${++i}/${steps}] Compiling src files ...`); + +let buildFlags = '' +if(pretty) buildFlags += '--pretty ' + +try { + execSync( + 'node "' + + path.join(__dirname, "..", "node_modules", "typescript", "lib", "tsc.js") + + '" -p "' + + path.join(__dirname, "..") + + '" ' + buildFlags, + { + cwd: path.join(__dirname, ".."), + shell: true, + env: process.env, + encoding: "utf8" + } + ) +} catch (error) { + if(verbose || logerr) { + error.stdout.split(/\r?\n/).forEach((line) => { + let _line = line.replace('dist/','',1); + if(!pretty && _line.includes('.ts(')) { + //reformat file path for easy jumping + _line = _line.replace('(',':',1).replace(',',':',1).replace(')','',1) + } + console.error(_line); + }) + } + console.error(`Build failed! Please check build.log for info!`); + if(!silent){ + if(pretty) fs.writeFileSync("build.log.ansi", error.stdout); + fs.writeFileSync("build.log", error.stdout.replaceAll(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, '')); + } +} \ No newline at end of file diff --git a/scripts/db_migrations.sh b/scripts/db_migrations.sh new file mode 100755
index 00000000..9ec8230a --- /dev/null +++ b/scripts/db_migrations.sh
@@ -0,0 +1,41 @@ +#!/bin/sh + +if [ ! -z "$1" ] +then + FILENAME="$1" + echo "Using filename: $FILENAME" +else + read -p "Enter migration filename: " FILENAME +fi + +[ -f ".env" ] && ( + mv .env .env.tmp 2>/dev/null + source .env.tmp 2>/dev/null +) +npm run build clean logerrors pretty-errors + +make_migration() { + echo "Creating migrations for $2" + mkdir "src/util/migrations/$2" 2>/dev/null +# npm run build clean logerrors pretty-errors + THREADS=1 DATABASE="$1" DB_MIGRATE=a npm run start:bundle + THREADS=1 DATABASE="$1" DB_MIGRATE=a npx typeorm-ts-node-commonjs migration:generate "src/util/migrations/$2/$FILENAME" -d src/util/util/Database.ts -p + #npm run build clean logerrors pretty-errors + #THREADS=1 DATABASE="$1" DB_MIGRATE=a npm run start:bundle +} + +npm i sqlite3 +make_migration "database.db" "sqlite" + +[ -z "$FC_DB_POSTGRES" ] || ( + npm i pg + make_migration "$FC_DB_POSTGRES" "postgres" +) + +[ -z "$FC_DB_MARIADB" ] || ( + npm i mysql2 + make_migration "$FC_DB_MARIADB" "mariadb" +) + +[ -f ".env.tmp" ] && mv .env.tmp .env 2>/dev/null + diff --git a/scripts/depcheck.js b/scripts/depcheck.js new file mode 100644
index 00000000..08df156c --- /dev/null +++ b/scripts/depcheck.js
@@ -0,0 +1,56 @@ +const path = require("path"); +const fs = require("fs"); +const { env } = require("process"); +const { execSync } = require("child_process"); +const { argv, stdout, exit } = require("process"); + +const { execIn, getLines } = require("./utils"); + +let npmi_extra_flags = ""; + +const resolveminor = argv.includes("resolveminor"); +if(argv.includes("nobuild")) npmi_extra_flags += "--ignore-scripts "; + +parts.forEach((part) => { + let partDir = path.join(__dirname, "..", "..", part); + let distDir = path.join(partDir, "dist"); + console.log(`Checking updates for ${part} (${partDir})`); + if(part == "bundle") { + execIn(`npm run syncdeps`, partDir) + } + if(resolveminor) { + fs.rmSync(path.join(partDir, "node_modules"), { + recursive: true, + force: true, + }); + execIn(`npm i --save --no-fund --no-audit --no-package-lock ${npmi_extra_flags}`, partDir) + } + let x = [ + [ + "pkg", + { + current: "1.0", + wanted: "2.0", + latest: "2.0", + dependent: "cdn", + location: "/usr/src/fosscord/bundle/node_packages/pkg", + }, + ], + ]; + x = Object.entries( + JSON.parse(execIn("npm outdated --json", partDir)) + ); + x.forEach((a) => { + let pkgname = a[0]; + let pkginfo = a[1]; + if(!pkginfo.current) + console.log(`MISSING ${pkgname}: ${pkginfo.current} -> ${pkginfo.wanted} (latest: ${pkginfo.latest})`); + else if(pkginfo.latest != pkginfo.wanted){ + if(pkginfo.current != pkginfo.wanted) + console.log(`MINOR ${pkgname}: ${pkginfo.current} -> ${pkginfo.wanted}`); + console.log(`MAJOR ${pkgname}: ${pkginfo.current} -> ${pkginfo.latest}`); + } + else + console.log(`MINOR ${pkgname}: ${pkginfo.current} -> ${pkginfo.wanted}`); + }); +}); diff --git a/scripts/depclean.js b/scripts/depclean.js new file mode 100644
index 00000000..333f5aa0 --- /dev/null +++ b/scripts/depclean.js
@@ -0,0 +1,62 @@ +const path = require("path"); +const fs = require("fs"); +const { env } = require("process"); +const { execSync } = require("child_process"); +const { argv, stdout, exit } = require("process"); + +const { execIn, getLines } = require('./utils'); + +const bundleRequired = ["@ovos-media/ts-transform-paths"]; +const removeModules = argv.includes("cleanup"); + +console.log(`Installing all packages...`); +execIn("npm i", path.join(__dirname, "..")); + +let partDir = path.join(__dirname, ".."); +let distDir = path.join(partDir, "dist"); +let start = 0; +start = getLines( + execIn("npm ls --parseable --package-lock-only -a", partDir) +); +if (fs.existsSync(distDir)) + fs.rmSync(distDir, { + recursive: true, + force: true, + }); +let x = { + dependencies: [], + devDependencies: [], + invalidDirs: [], + invalidFiles: [], + missing: [], + using: [], +}; +let dcproc = execIn("npx depcheck --json", partDir); +if(dcproc.stdout) x = JSON.parse(dcproc.stdout); +else x = JSON.parse(dcproc); + +fs.writeFileSync( + path.join(__dirname, "..", `depclean.out.json`), + JSON.stringify(x, null, "\t"), + { encoding: "utf8" } +); + +let depsToRemove = x.dependencies.join(" "); +if (depsToRemove) execIn(`npm r --save ${depsToRemove}`, partDir); + +depsToRemove = x.devDependencies.join(" "); +if (depsToRemove) execIn(`npm r --save --dev ${depsToRemove}`, partDir); + +if (removeModules && fs.existsSync(path.join(partDir, "node_modules"))) + fs.rmSync(path.join(partDir, "node_modules"), { + recursive: true, + force: true, + }); +let end = getLines( + execIn("npm ls --parseable --package-lock-only -a", partDir) +); +console.log(`${part}: ${start} -> ${end} (diff: ${start - end})`); + +console.log("Installing required packages for bundle..."); + +execIn(`npm i --save ${bundleRequired.join(" ")}`, path.join(__dirname, "..")); diff --git a/api/scripts/droptables.sql b/scripts/droptables.sql
index 8a852048..8a852048 100644 --- a/api/scripts/droptables.sql +++ b/scripts/droptables.sql
diff --git a/scripts/gen_index.js b/scripts/gen_index.js new file mode 100644
index 00000000..71c64a9f --- /dev/null +++ b/scripts/gen_index.js
@@ -0,0 +1,34 @@ +const path = require("path"); +const fs = require("fs"); +const { execIn, getLines, parts } = require('./utils'); + +if (!process.argv[2] || !fs.existsSync(process.argv[2])) { + console.log("Please pass a directory that exists!"); + process.exit(1); +} +console.log(`// ${process.argv[2]}/index.ts`) +const recurse = process.argv.includes("--recursive") + +const files = fs.readdirSync(process.argv[2]).filter(x => x.endsWith('.ts') && x != 'index.ts'); + +let output = ''; + +files.forEach(x => output += `export * from "./${x.replaceAll('.ts','')}";\n`) + +const dirs = fs.readdirSync(process.argv[2]).filter(x => { + try { + fs.readdirSync(path.join(process.argv[2], x)); + return true; + } catch (e) { + return false; + } +}); +dirs.forEach(x => { + output += `export * from "./${x}/index";\n` +}) +console.log(output); +fs.writeFileSync(path.join(process.argv[2], "index.ts"), output) + +dirs.forEach(x => { + if(recurse) console.log(execIn([process.argv[0], process.argv[1], `"${path.join(process.argv[2], x)}"`, "--recursive"].join(' '), process.cwd())) +}) \ No newline at end of file diff --git a/api/scripts/generate_openapi.js b/scripts/generate_openapi.js
index c9de9fa6..9624a5b9 100644 --- a/api/scripts/generate_openapi.js +++ b/scripts/generate_openapi.js
@@ -11,7 +11,7 @@ const schemas = JSON.parse(fs.readFileSync(SchemaPath, { encoding: "utf8" })); const specification = JSON.parse(fs.readFileSync(openapiPath, { encoding: "utf8" })); function combineSchemas(schemas) { - var definitions = {}; + let definitions = {}; for (const name in schemas) { definitions = { diff --git a/api/scripts/generate_schema.js b/scripts/generate_schema.js
index b56c3fbc..6925df5d 100644 --- a/api/scripts/generate_schema.js +++ b/scripts/generate_schema.js
@@ -40,7 +40,7 @@ const Excluded = [ ]; function modify(obj) { - for (var k in obj) { + for (let k in obj) { if (typeof obj[k] === "object" && obj[k] !== null) { modify(obj[k]); } @@ -48,9 +48,8 @@ function modify(obj) { } function main() { - const files = [ - ...walk(path.join(__dirname, "..", "src", "routes")), - ...walk(path.join(__dirname, "..", "..", "util", "src")), + const files = [ + ...walk(path.join(__dirname, "..", "src", "util", "schemas")), ]; const program = TJS.getProgramFromFiles( files, @@ -62,7 +61,7 @@ function main() { let schemas = generator.getUserSymbols().filter((x) => (x.endsWith("Schema") || x.endsWith("Response")) && !Excluded.includes(x)); console.log(schemas); - var definitions = {}; + let definitions = {}; for (const name of schemas) { const part = TJS.generateSchema(program, name, settings, [], generator); @@ -79,11 +78,11 @@ function main() { main(); function walk(dir) { - var results = []; - var list = fs.readdirSync(dir); + let results = []; + let list = fs.readdirSync(dir); list.forEach(function (file) { file = dir + "/" + file; - var stat = fs.statSync(file); + let stat = fs.statSync(file); if (stat && stat.isDirectory()) { /* Recurse into a subdirectory */ results = results.concat(walk(file)); diff --git a/util/scripts/migrate_db_engine.js b/scripts/migrate_db_engine.js
index 79e9d86f..79e9d86f 100644 --- a/util/scripts/migrate_db_engine.js +++ b/scripts/migrate_db_engine.js
diff --git a/scripts/rights.js b/scripts/rights.js new file mode 100644
index 00000000..20fd139c --- /dev/null +++ b/scripts/rights.js
@@ -0,0 +1,34 @@ +const path = require("path"); +const fs = require("fs"); +const { env } = require("process"); +const { execSync } = require("child_process"); +const { argv, stdout, exit } = require("process"); + +const { execIn, getLines, parts } = require("./utils"); + +let lines = fs.readFileSync(path.join(__dirname, "..", "src", "util", "util","Rights.ts")).toString() +let lines2 = lines.split("\n"); +let lines3 = lines2.filter(y=>y.includes(": BitFlag(")); +let lines4 = lines3.map(x=>x.split("//")[0].trim()) + +function BitFlag(int) { + return 1n << eval(`${int}n`); +} + +let rights = [] +let maxRights = 0n; +lines4.forEach(x=>{ + maxRights += eval(`rights.${x.replace(':'," = ").replace(",",";")}`) +}) +//max rights... +console.log(`Maximum rights: ${maxRights}`); +//discord rights... +discordRights = maxRights; +discordRights -= rights.SEND_BACKDATED_EVENTS; +discordRights -= rights.MANAGE_GUILD_DIRECTORY; +discordRights -= rights.CREDITABLE; +discordRights -= rights.BYPASS_RATE_LIMITS; +discordRights -= rights.ADD_MEMBERS; +discordRights -= rights.MANAGE_RATE_LIMITS; +discordRights -= rights.OPERATOR; +console.log(`Discord-like rights: ${discordRights}`); \ No newline at end of file diff --git a/api/scripts/stresstest/.gitignore b/scripts/stresstest/.gitignore
index bde26fd4..bde26fd4 100644 --- a/api/scripts/stresstest/.gitignore +++ b/scripts/stresstest/.gitignore
diff --git a/api/scripts/stresstest/accounts.json.example b/scripts/stresstest/accounts.json.example
index 61904c5e..61904c5e 100644 --- a/api/scripts/stresstest/accounts.json.example +++ b/scripts/stresstest/accounts.json.example
diff --git a/api/scripts/stresstest/config.json.example b/scripts/stresstest/config.json.example
index 73f52f05..73f52f05 100644 --- a/api/scripts/stresstest/config.json.example +++ b/scripts/stresstest/config.json.example
diff --git a/api/scripts/stresstest/index.js b/scripts/stresstest/index.js
index a9a65097..740a9011 100644 --- a/api/scripts/stresstest/index.js +++ b/scripts/stresstest/index.js
@@ -19,19 +19,19 @@ setInterval(() => { getUsers(); }, 60 * 1000); async function generate() { - var accounts = await JSON.parse(fs.readFileSync("accounts.json")); + let accounts = await JSON.parse(fs.readFileSync("accounts.json")); console.log(accounts); - var account = await register(); + let account = await register(); accounts.push(account); fs.writeFileSync("accounts.json", JSON.stringify(accounts)); console.log(accounts.length); - var y = await login(account); + let y = await login(account); sendMessage(y); } async function getUsers() { - var accounts = await JSON.parse(fs.readFileSync("accounts.json")); + let accounts = await JSON.parse(fs.readFileSync("accounts.json")); accounts.forEach(async (x) => { - var y = await login(x); + let y = await login(x); console.log(y); sendMessage(y); }); diff --git a/api/scripts/stresstest/package-lock.json b/scripts/stresstest/package-lock.json
index 81c9b817..81c9b817 100644 --- a/api/scripts/stresstest/package-lock.json +++ b/scripts/stresstest/package-lock.json
diff --git a/api/scripts/stresstest/package.json b/scripts/stresstest/package.json
index 8d94d05b..8d94d05b 100644 --- a/api/scripts/stresstest/package.json +++ b/scripts/stresstest/package.json
diff --git a/api/scripts/stresstest/src/login/index.js b/scripts/stresstest/src/login/index.js
index bd9fea87..b153550e 100644 --- a/api/scripts/stresstest/src/login/index.js +++ b/scripts/stresstest/src/login/index.js
@@ -1,14 +1,14 @@ const fetch = require("node-fetch"); const fs = require("fs"); -var config = require("./../../config.json"); +let config = require("../../config.json"); module.exports = login; async function login(account) { - var body = { + let body = { fingerprint: "805826570869932034.wR8vi8lGlFBJerErO9LG5NViJFw", login: account.email, password: account.password }; - var x = await fetch(config.url + "/auth/login", { + let x = await fetch(config.url + "/auth/login", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body) diff --git a/api/scripts/stresstest/src/message/send.js b/scripts/stresstest/src/message/send.js
index 1f8af8aa..d1b86914 100644 --- a/api/scripts/stresstest/src/message/send.js +++ b/scripts/stresstest/src/message/send.js
@@ -1,14 +1,14 @@ const fetch = require("node-fetch"); const fs = require("fs"); -var config = require("./../../config.json"); +let config = require("./../../config.json"); module.exports = sendMessage; async function sendMessage(account) { - var body = { + let body = { fingerprint: "805826570869932034.wR8vi8lGlFBJerErO9LG5NViJFw", content: "Test", tts: false }; - var x = await fetch(config.url + "/channels/" + config["text-channel"] + "/messages", { + let x = await fetch(config.url + "/channels/" + config["text-channel"] + "/messages", { method: "POST", headers: { "Content-Type": "application/json", diff --git a/api/scripts/stresstest/src/register/index.js b/scripts/stresstest/src/register/index.js
index bb6f839f..578b9022 100644 --- a/api/scripts/stresstest/src/register/index.js +++ b/scripts/stresstest/src/register/index.js
@@ -1,17 +1,17 @@ const fetch = require("node-fetch"); const fs = require("fs"); -var config = require("./../../config.json"); +let config = require("./../../config.json"); module.exports = generate; async function generate() { - var mail = (Math.random() + 10).toString(36).substring(2); + let mail = (Math.random() + 10).toString(36).substring(2); mail = mail + "." + (Math.random() + 10).toString(36).substring(2) + "@stresstest.com"; - var password = + let password = (Math.random() * 69).toString(36).substring(-7) + (Math.random() * 69).toString(36).substring(-7) + (Math.random() * 69).toString(36).substring(-8); console.log(mail); console.log(password); - var body = { + let body = { fingerprint: "805826570869932034.wR8vi8lGlFBJerErO9LG5NViJFw", email: mail, username: "Fosscord Stress Test", @@ -22,7 +22,7 @@ async function generate() { gift_code_sku_id: null, captcha_key: null }; - var x = await fetch(config.url + "/auth/register", { + let x = await fetch(config.url + "/auth/register", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body) diff --git a/scripts/update_schemas.js b/scripts/update_schemas.js new file mode 100644
index 00000000..361bedc1 --- /dev/null +++ b/scripts/update_schemas.js
@@ -0,0 +1,9 @@ +const path = require("path"); +const fs = require("fs"); +const { env } = require("process"); +const { execSync } = require("child_process"); +const { argv, stdout, exit } = require("process"); + +const { execIn, getLines, parts } = require("./utils"); + +execIn("node scripts/generate_schema.js", path.join('.')); \ No newline at end of file diff --git a/scripts/utils.js b/scripts/utils.js new file mode 100644
index 00000000..84aaeed6 --- /dev/null +++ b/scripts/utils.js
@@ -0,0 +1,51 @@ +const path = require("path"); +const fs = require("fs"); +const { env } = require("process"); +const { execSync } = require("child_process"); +const { argv, stdout, exit } = require("process"); + +function copyRecursiveSync(src, dest) { + //if (verbose) console.log(`cpsync: ${src} -> ${dest}`); + let exists = fs.existsSync(src); + if (!exists) { + console.log(src + " doesn't exist, not copying!"); + return; + } + let stats = exists && fs.statSync(src); + let isDirectory = exists && stats.isDirectory(); + if (isDirectory) { + fs.mkdirSync(dest, { recursive: true }); + fs.readdirSync(src).forEach(function (childItemName) { + copyRecursiveSync( + path.join(src, childItemName), + path.join(dest, childItemName) + ); + }); + } else { + fs.copyFileSync(src, dest); + } +} + +function execIn(cmd, workdir, opts) { + try { + return execSync(cmd, { + cwd: workdir, + shell: true, + env: process.env, + encoding: "utf-8", + ...opts + }); + } catch (error) { + return error.stdout; + } +} + +function getLines(output) { + return output.split("\n").length; +} + +module.exports = { + //consts + //functions + copyRecursiveSync, execIn, getLines +};