build.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*!
  2. * node-sass: scripts/build.js
  3. */
  4. var fs = require('fs'),
  5. mkdir = require('mkdirp'),
  6. path = require('path'),
  7. spawn = require('cross-spawn'),
  8. sass = require('../lib/extensions');
  9. /**
  10. * After build
  11. *
  12. * @param {Object} options
  13. * @api private
  14. */
  15. function afterBuild(options) {
  16. var install = sass.getBinaryPath();
  17. var target = path.join(__dirname, '..', 'build',
  18. options.debug ? 'Debug' :
  19. process.config.target_defaults
  20. ? process.config.target_defaults.default_configuration
  21. : 'Release',
  22. 'binding.node');
  23. mkdir(path.dirname(install), function(err) {
  24. if (err && err.code !== 'EEXIST') {
  25. console.error(err.message);
  26. return;
  27. }
  28. fs.stat(target, function(err) {
  29. if (err) {
  30. console.error('Build succeeded but target not found');
  31. return;
  32. }
  33. fs.rename(target, install, function(err) {
  34. if (err) {
  35. console.error(err.message);
  36. return;
  37. }
  38. console.log('Installed to', install);
  39. });
  40. });
  41. });
  42. }
  43. /**
  44. * Build
  45. *
  46. * @param {Object} options
  47. * @api private
  48. */
  49. function build(options) {
  50. var args = [require.resolve(path.join('node-gyp', 'bin', 'node-gyp.js')), 'rebuild', '--verbose'].concat(
  51. ['libsass_ext', 'libsass_cflags', 'libsass_ldflags', 'libsass_library'].map(function(subject) {
  52. return ['--', subject, '=', process.env[subject.toUpperCase()] || ''].join('');
  53. })).concat(options.args);
  54. console.log('Building:', [process.execPath].concat(args).join(' '));
  55. var proc = spawn(process.execPath, args, {
  56. stdio: [0, 1, 2]
  57. });
  58. proc.on('exit', function(errorCode) {
  59. if (!errorCode) {
  60. afterBuild(options);
  61. return;
  62. }
  63. if (errorCode === 127 ) {
  64. console.error('node-gyp not found!');
  65. } else {
  66. console.error('Build failed with error code:', errorCode);
  67. }
  68. process.exit(1);
  69. });
  70. }
  71. /**
  72. * Parse arguments
  73. *
  74. * @param {Array} args
  75. * @api private
  76. */
  77. function parseArgs(args) {
  78. var options = {
  79. arch: process.arch,
  80. platform: process.platform,
  81. force: process.env.npm_config_force === 'true',
  82. };
  83. options.args = args.filter(function(arg) {
  84. if (arg === '-f' || arg === '--force') {
  85. options.force = true;
  86. return false;
  87. } else if (arg.substring(0, 13) === '--target_arch') {
  88. options.arch = arg.substring(14);
  89. } else if (arg === '-d' || arg === '--debug') {
  90. options.debug = true;
  91. } else if (arg.substring(0, 13) === '--libsass_ext' && arg.substring(14) !== 'no') {
  92. options.libsassExt = true;
  93. }
  94. return true;
  95. });
  96. return options;
  97. }
  98. /**
  99. * Test for pre-built library
  100. *
  101. * @param {Object} options
  102. * @api private
  103. */
  104. function testBinary(options) {
  105. if (options.force || process.env.SASS_FORCE_BUILD) {
  106. return build(options);
  107. }
  108. if (!sass.hasBinary(sass.getBinaryPath())) {
  109. return build(options);
  110. }
  111. console.log('Binary found at', sass.getBinaryPath());
  112. console.log('Testing binary');
  113. try {
  114. require('../').renderSync({
  115. data: 's { a: ss }'
  116. });
  117. console.log('Binary is fine');
  118. } catch (e) {
  119. console.log('Binary has a problem:', e);
  120. console.log('Building the binary locally');
  121. return build(options);
  122. }
  123. }
  124. /**
  125. * Apply arguments and run
  126. */
  127. testBinary(parseArgs(process.argv.slice(2)));