inject-dependencies.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. 'use strict';
  2. var $ = {
  3. fs: require('fs'),
  4. path: require('path')
  5. };
  6. var config;
  7. var fileTypes;
  8. var filesCaught = [];
  9. var globalDependenciesSorted;
  10. var ignorePath;
  11. /**
  12. * Inject dependencies into the specified source file.
  13. *
  14. * @param {object} globalConfig the global configuration object.
  15. * @return {object} config
  16. */
  17. function injectDependencies(globalConfig) {
  18. config = globalConfig;
  19. var stream = config.get('stream');
  20. filesCaught = [];
  21. globalDependenciesSorted = config.get('global-dependencies-sorted');
  22. ignorePath = config.get('ignore-path');
  23. fileTypes = config.get('file-types');
  24. if (stream.src) {
  25. config.set('stream', {
  26. src: injectScriptsStream(stream.path, stream.src, stream.fileType),
  27. fileType: stream.fileType
  28. });
  29. } else {
  30. config.get('src').forEach(injectScripts);
  31. }
  32. return config;
  33. }
  34. function replaceIncludes(file, fileType, returnType) {
  35. /**
  36. * Callback function after matching our regex from the source file.
  37. *
  38. * @param {array} match strings that were matched
  39. * @param {string} startBlock the opening <!-- bower:xxx --> comment
  40. * @param {string} spacing the type and size of indentation
  41. * @param {string} blockType the type of block (js/css)
  42. * @param {string} oldScripts the old block of scripts we'll remove
  43. * @param {string} endBlock the closing <!-- endbower --> comment
  44. * @return {string} the new file contents
  45. */
  46. return function (match, startBlock, spacing, blockType, oldScripts, endBlock, offset, string) {
  47. blockType = blockType || 'js';
  48. var newFileContents = startBlock;
  49. var dependencies = globalDependenciesSorted[blockType] || [];
  50. var quoteMark = '';
  51. (string.substr(0, offset) + string.substr(offset + match.length)).
  52. replace(oldScripts, '').
  53. replace(fileType.block, '').
  54. replace(fileType.detect[blockType], function (match, reference) {
  55. quoteMark = match.match(/['"]/) && match.match(/['"]/)[0];
  56. filesCaught.push(reference.replace(/['"\s]/g, ''));
  57. });
  58. if (!quoteMark) {
  59. // What the heck. Check if there's anything in the oldScripts block.
  60. match.replace(fileType.detect[blockType], function (match) {
  61. quoteMark = match.match(/['"]/) && match.match(/['"]/)[0];
  62. });
  63. }
  64. spacing = returnType + spacing.replace(/\r|\n/g, '');
  65. dependencies.
  66. map(function (filePath) {
  67. return $.path.join(
  68. $.path.relative($.path.dirname(file), $.path.dirname(filePath)),
  69. $.path.basename(filePath)
  70. ).replace(/\\/g, '/').replace(ignorePath, '');
  71. }).
  72. filter(function (filePath) {
  73. return filesCaught.indexOf(filePath) === -1;
  74. }).
  75. forEach(function (filePath) {
  76. if (typeof fileType.replace[blockType] === 'function') {
  77. newFileContents += spacing + fileType.replace[blockType](filePath);
  78. } else if (typeof fileType.replace[blockType] === 'string') {
  79. newFileContents += spacing + fileType.replace[blockType].replace('{{filePath}}', filePath);
  80. }
  81. if (quoteMark) {
  82. newFileContents = newFileContents.replace(/"/g, quoteMark);
  83. }
  84. config.get('on-path-injected')({
  85. block: blockType,
  86. file: file,
  87. path: filePath
  88. });
  89. });
  90. return newFileContents + spacing + endBlock;
  91. };
  92. }
  93. /**
  94. * Take a file path, read its contents, inject the Bower packages, then write
  95. * the new file to disk.
  96. *
  97. * @param {string} filePath path to the source file
  98. */
  99. function injectScripts(filePath) {
  100. var contents = String($.fs.readFileSync(filePath));
  101. var fileExt = $.path.extname(filePath).substr(1);
  102. var fileType = fileTypes[fileExt] || fileTypes['default'];
  103. var returnType = /\r\n/.test(contents) ? '\r\n' : '\n';
  104. var newContents = contents.replace(
  105. fileType.block,
  106. replaceIncludes(filePath, fileType, returnType)
  107. );
  108. if (contents !== newContents) {
  109. $.fs.writeFileSync(filePath, newContents);
  110. config.get('on-file-updated')(filePath);
  111. }
  112. }
  113. function injectScriptsStream(filePath, contents, fileExt) {
  114. var returnType = /\r\n/.test(contents) ? '\r\n' : '\n';
  115. var fileType = fileTypes[fileExt] || fileTypes['default'];
  116. var newContents = contents.replace(
  117. fileType.block,
  118. replaceIncludes(filePath, fileType, returnType)
  119. );
  120. config.get('on-file-updated')(filePath);
  121. return newContents;
  122. }
  123. module.exports = injectDependencies;