build.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #!/usr/bin/env node
  2. var fs = require("fs");
  3. var path = require('path');
  4. var child_process = require('child_process');
  5. var Promise = require("bluebird");
  6. var _ = require('lodash');
  7. var exec = function (cmd, args) {
  8. return new Promise(function(resolve, reject) {
  9. // Execute command
  10. var child = child_process.exec(cmd, {cwd: process.cwd(), env: process.env});
  11. // Pass stdout and stderr
  12. child.stdout.on('data', function(data) { process.stdout.write(data.toString()); });
  13. child.stderr.on('data', function(data) { process.stderr.write(data.toString()); });
  14. // Handle result
  15. child.on('exit', function (code) {
  16. if (code) reject(code);
  17. else resolve();
  18. });
  19. child.on('error', reject);
  20. });
  21. }
  22. var CWD = process.cwd();
  23. var POSTINSTALL_BUILD_CWD = process.env.POSTINSTALL_BUILD_CWD;
  24. // If we didn't have this check, then we'd be stuck in an infinite `postinstall`
  25. // loop, since we run `npm install --only=dev` below, triggering another
  26. // `postinstall`. We can't use `--ignore-scripts` because that ignores scripts
  27. // on all the modules that get installed, too, which would break stuff. So
  28. // instead, we set an environment variable, `POSTINSTALL_BUILD_CWD`, that keeps
  29. // track of what we're installing. It's more than just a yes/no flag because
  30. // the dev dependencies we're installing might use `postinstall-build` too, and
  31. // we don't want the flag to prevent them from running.
  32. if (POSTINSTALL_BUILD_CWD !== CWD) {
  33. var BUILD_ARTIFACT = process.argv[2];
  34. var BUILD_COMMAND = process.argv[3];
  35. fs.stat(BUILD_ARTIFACT, function(err, stats) {
  36. if (err || !(stats.isFile() || stats.isDirectory())) {
  37. // This script will run again after we run `npm install` below. Set an
  38. // environment variable to tell it to skip the check. Really we just want
  39. // the execSync's `env` to be modified, but it's easier just modify and
  40. // pass along the entire `process.env`.
  41. process.env.POSTINSTALL_BUILD_CWD = CWD;
  42. // We already have prod dependencies, that's what triggered `postinstall`
  43. // in the first place. So only install dev.
  44. // Fetch package.json
  45. var pkgJson = require(path.join(CWD, "package.json"));
  46. var devDeps = pkgJson.devDependencies;
  47. // Values listed under `buildDependencies` contain the dependency names
  48. // that are required for `lib` building.
  49. var buildDependencies = _.pick(devDeps, pkgJson.buildDependencies);
  50. // Proceed only if there is something to install
  51. if (!_.isEmpty(buildDependencies)) {
  52. var opts = { env: process.env, stdio: 'inherit' };
  53. console.log('Building Knex.js')
  54. // Map all key (dependency) value (semver) pairs to
  55. // "dependency@semver dependency@semver ..." string that can be used
  56. // for `npm install` command
  57. var installArgs = _(buildDependencies).pickBy(function (semver, dep) {
  58. // Check if the dependency is already installed
  59. try { require(dep); return false; }
  60. catch (err) { return true; }
  61. }).map(function (semver, dep) {
  62. // Format installable dependencies
  63. return dep + '@' + semver;
  64. }).value().join(' ');
  65. Promise.try(function() {
  66. if (!_.isEmpty(installArgs)) {
  67. console.log('Installing dependencies');
  68. return exec("npm install " + installArgs, opts);
  69. }
  70. }).then(function(stdout, stderr) {
  71. console.log('✓')
  72. // Don't need the flag anymore as `postinstall` was already run.
  73. // Change it back so the environment is minimally changed for the
  74. // remaining commands.
  75. process.env.POSTINSTALL_BUILD_CWD = POSTINSTALL_BUILD_CWD;
  76. console.log('Building compiled files (' + BUILD_COMMAND + ')');
  77. return exec(BUILD_COMMAND, opts);
  78. })
  79. .catch(function(err) {
  80. console.error(err);
  81. process.exit(1);
  82. })
  83. .then(function(stdout, stderr) {
  84. if (process.env.NODE_ENV === 'production') {
  85. console.log('✓');
  86. console.log('Pruning dev dependencies for production build');
  87. return exec("npm prune --production", opts);
  88. } else {
  89. console.log('Skipping npm prune');
  90. }
  91. })
  92. .then(function() {
  93. console.log('✓')
  94. })
  95. .catch(function(err) {
  96. console.error(err)
  97. process.exit(1);
  98. })
  99. }
  100. }
  101. });
  102. }