From 5c57df91a52d06f11b9c78454abc90c298329ea5 Mon Sep 17 00:00:00 2001 From: Sven Slootweg Date: Sat, 27 Jul 2019 19:15:31 +0200 Subject: [PATCH] Implement the run feature --- lib/generate-environment.js | 37 +++++++++++++++++++++++++++++++++++++ lib/nix-build.js | 22 ++++++++++++++++++++++ lib/run-program.js | 28 ++++++++++++++++++++++++++++ locate.js | 26 +++++++++++++++++++++++++- package.json | 2 ++ yarn.lock | 23 +++++++++++++++++++++++ 6 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 lib/generate-environment.js create mode 100644 lib/nix-build.js create mode 100644 lib/run-program.js diff --git a/lib/generate-environment.js b/lib/generate-environment.js new file mode 100644 index 0000000..83ef25a --- /dev/null +++ b/lib/generate-environment.js @@ -0,0 +1,37 @@ +"use strict"; + +// const nijs = require("nijs"); +const path = require("path"); + +function nixEscapeString(string) { + return string + .replace(/\\/g, "\\\\") + .replace(/"/g, "\\\""); +} + +module.exports = function generateEnvironment({ targetBinary, packages, binaryName }) { + // return nijs.jsToNix("foo", true); + + // return nijs.jsToNix(function (args) { + // return args.pkgs().buildFHSUserEnv({ + // name: path.basename(targetBinary) + // }); + // }, true); + + return ` + { pkgs ? import {} }: + pkgs.buildFHSUserEnv { + name = "${nixEscapeString(binaryName)}"; + + targetPkgs = pkgs: with pkgs; [ + ${packages.join(" ")} + ]; + + runScript = pkgs.writeScript "run-${nixEscapeString(binaryName)}" '' + cmd="$1" + shift + exec -- "${nixEscapeString(targetBinary)}" "$@" + ''; + } + `; +}; diff --git a/lib/nix-build.js b/lib/nix-build.js new file mode 100644 index 0000000..bf137d1 --- /dev/null +++ b/lib/nix-build.js @@ -0,0 +1,22 @@ +"use strict"; + +const Promise = require("bluebird"); +const nanoid = require("nanoid"); + +const runProgram = require("./run-program"); + +module.exports = function nixBuild(file) { + return Promise.try(() => { + let outLink = `/tmp/depfish-build-${nanoid()}`; + + return Promise.try(() => { + return runProgram("nix", [ + "build", + "--file", file, + "--out-link", outLink + ]); + }).then(() => { + return outLink; + }); + }); +}; diff --git a/lib/run-program.js b/lib/run-program.js new file mode 100644 index 0000000..fc3cfca --- /dev/null +++ b/lib/run-program.js @@ -0,0 +1,28 @@ +"use strict"; + +const Promise = require("bluebird"); +const childProcess = require("child_process"); + +module.exports = function runProgram(binary, args = [], options = {}) { + return new Promise((resolve, reject) => { + let proc = childProcess.spawn(binary, args, Object.assign({ + stdio: [ process.stdin, process.stdout, process.stderr ] + }, options)); + + proc.on("error", (error) => { + reject(error); + }); + + proc.on("exit", (exitCode, signal) => { + if (exitCode === 0) { + resolve(); + } else if (exitCode != null) { + reject(`Non-zero exit code: ${exitCode}`); + } else if (signal != null) { + reject(`Process terminated by signal: ${signal}`); + } else { + reject("Process exited abnormally"); + } + }); + }); +}; diff --git a/locate.js b/locate.js index d470264..d21cbbe 100644 --- a/locate.js +++ b/locate.js @@ -5,9 +5,14 @@ const path = require("path"); const chalk = require("chalk"); const pad = require("pad"); const yargs = require("yargs"); +const nanoid = require("nanoid"); +const fs = Promise.promisifyAll(require("fs")); const ldd = require("./lib/ldd"); const findPackages = require("./lib/find-packages"); +const generateEnvironment = require("./lib/generate-environment"); +const nixBuild = require("./lib/nix-build"); +const runProgram = require("./lib/run-program"); let argv = yargs .boolean("run") @@ -68,6 +73,25 @@ Promise.try(() => { if (argv.run) { console.log(chalk.cyan(`Preparing to run ${chalk.bold(binaryName)}...`)); - /* TODO */ + let buildExpression = generateEnvironment({ + binaryName: binaryName, + targetBinary: target, + packages: Object.keys(groupedPackages) + .concat([ "systemd" ]) /* Hack for libudev SIGTRAP issue; this may need to be detected interactively in the future */ + }); + + let expressionPath = `/tmp/depfish-expr-${nanoid()}`; + + return Promise.try(() => { + return fs.writeFileAsync(expressionPath, buildExpression); + }).then(() => { + console.log("Expression path:", expressionPath); + + return nixBuild(expressionPath); + }).then((outPath) => { + console.log("Build path:", outPath); + + return runProgram(`${outPath}/bin/${binaryName}`); + }); } }); diff --git a/package.json b/package.json index d39753f..cfa7053 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,8 @@ "escape-string-regexp": "^2.0.0", "js-lcs": "^1.0.1", "map-obj": "^4.1.0", + "nanoid": "^2.0.3", + "nijs": "^0.0.25", "pad": "^3.2.0", "yargs": "^13.2.4" } diff --git a/yarn.lock b/yarn.lock index 028c234..eb85563 100644 --- a/yarn.lock +++ b/yarn.lock @@ -207,11 +207,24 @@ mimic-fn@^2.0.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +nanoid@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.0.3.tgz#dde999e173bc9d7bd2ee2746b89909ade98e075e" + integrity sha512-NbaoqdhIYmY6FXDRB4eYtDVC9Z9eCbn8TyaiC16LNKtpPv/aqa0tOPD8y6gNE4yUNnaZ7LLhYtXOev/6+cBtfw== + nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== +nijs@^0.0.25: + version "0.0.25" + resolved "https://registry.yarnpkg.com/nijs/-/nijs-0.0.25.tgz#04b035cb530d46859d1018839a518c029133f676" + integrity sha1-BLA1y1MNRoWdEBiDmlGMApEz9nY= + dependencies: + optparse ">= 1.0.3" + slasp "0.0.4" + npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" @@ -226,6 +239,11 @@ once@^1.3.1, once@^1.4.0: dependencies: wrappy "1" +"optparse@>= 1.0.3": + version "1.0.5" + resolved "https://registry.yarnpkg.com/optparse/-/optparse-1.0.5.tgz#75e75a96506611eb1c65ba89018ff08a981e2c16" + integrity sha1-dedallBmEescZbqJAY/wipgeLBY= + os-locale@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" @@ -331,6 +349,11 @@ signal-exit@^3.0.0: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= +slasp@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/slasp/-/slasp-0.0.4.tgz#9adc26ee729a0f95095851a5489f87a5258d57a9" + integrity sha1-mtwm7nKaD5UJWFGlSJ+HpSWNV6k= + string-width@^3.0.0, string-width@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961"