Gruntfile.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*eslint-env node*/
  2. 'use strict';
  3. const fs = require('fs');
  4. const path = require('path');
  5. const semver = require('semver');
  6. module.exports = function(grunt) {
  7. require('load-grunt-tasks')(grunt);
  8. const s_ignoreRE = /\.(md|py|sh|enc)$/i;
  9. function noMds(filename) {
  10. return !s_ignoreRE.test(filename);
  11. }
  12. const s_isMdRE = /\.md$/i;
  13. function mdsOnly(filename) {
  14. return s_isMdRE.test(filename);
  15. }
  16. function notFolder(filename) {
  17. return !fs.statSync(filename).isDirectory();
  18. }
  19. function noMdsNoFolders(filename) {
  20. return noMds(filename) && notFolder(filename);
  21. }
  22. grunt.initConfig({
  23. eslint: {
  24. lib: {
  25. src: [
  26. 'threejs/resources/*.js',
  27. ],
  28. },
  29. support: {
  30. src: [
  31. 'Gruntfile.js',
  32. 'build/js/build.js',
  33. ],
  34. },
  35. examples: {
  36. src: [
  37. 'threejs/*.html',
  38. 'threejs/lessons/resources/*.js',
  39. '!threejs/lessons/resources/prettify.js',
  40. 'threejs/lessons/resources/*.html',
  41. ],
  42. },
  43. },
  44. copy: {
  45. main: {
  46. files: [
  47. { expand: false, src: '*', dest: 'out/', filter: noMdsNoFolders, },
  48. { expand: true, src: 'threejs/**', dest: 'out/', filter: noMds, },
  49. { expand: true, src: 'monaco-editor/**', dest: 'out/', },
  50. { expand: true, src: '3rdparty/**', dest: 'out/', },
  51. ],
  52. },
  53. },
  54. clean: [
  55. 'out/**/*',
  56. ],
  57. buildlesson: {
  58. main: {
  59. files: [],
  60. },
  61. },
  62. watch: {
  63. main: {
  64. files: [
  65. 'threejs/**',
  66. '3rdparty/**',
  67. ],
  68. tasks: ['copy'],
  69. options: {
  70. spawn: false,
  71. },
  72. },
  73. lessons: {
  74. files: [
  75. 'threejs/lessons/**/threejs*.md',
  76. ],
  77. tasks: ['buildlesson'],
  78. options: {
  79. spawn: false,
  80. },
  81. },
  82. },
  83. });
  84. let changedFiles = {};
  85. const onChange = grunt.util._.debounce(function() {
  86. grunt.config('copy.main.files', Object.keys(changedFiles).filter(noMds).map((file) => {
  87. return {
  88. src: file,
  89. dest: 'out/',
  90. };
  91. }));
  92. grunt.config('buildlesson.main.files', Object.keys(changedFiles).filter(mdsOnly).map((file) => {
  93. return {
  94. src: file,
  95. };
  96. }));
  97. changedFiles = {};
  98. }, 200);
  99. grunt.event.on('watch', function(action, filepath) {
  100. changedFiles[filepath] = action;
  101. onChange();
  102. });
  103. const buildSettings = {
  104. outDir: 'out',
  105. baseUrl: 'http://threejsfundamentals.org',
  106. rootFolder: 'threejs',
  107. lessonGrep: 'threejs*.md',
  108. siteName: 'ThreeJSFundamentals',
  109. siteThumbnail: 'threejsfundamentals.jpg', // in rootFolder/lessons/resources
  110. templatePath: 'build/templates',
  111. };
  112. // just the hackiest way to get this working.
  113. grunt.registerMultiTask('buildlesson', 'build a lesson', function() {
  114. const filenames = new Set();
  115. this.files.forEach((files) => {
  116. files.src.forEach((filename) => {
  117. filenames.add(filename);
  118. });
  119. });
  120. const buildStuff = require('./build/js/build');
  121. const settings = Object.assign({}, buildSettings, {
  122. filenames,
  123. });
  124. const finish = this.async();
  125. buildStuff(settings).then(function() {
  126. finish();
  127. }).done();
  128. });
  129. grunt.registerTask('buildlessons', function() {
  130. const buildStuff = require('./build/js/build');
  131. const finish = this.async();
  132. buildStuff(buildSettings).then(function() {
  133. finish();
  134. }).done();
  135. });
  136. grunt.task.registerMultiTask('fixthreepaths', 'fix three paths', function() {
  137. const options = this.options({});
  138. const oldVersionRE = new RegExp(`/${options.oldVersionStr}/`, 'g');
  139. const newVersionReplacement = `/${options.newVersionStr}/`;
  140. this.files.forEach((files) => {
  141. files.src.forEach((filename) => {
  142. const oldContent = fs.readFileSync(filename, {encoding: 'utf8'});
  143. const newContent = oldContent.replace(oldVersionRE, newVersionReplacement);
  144. if (oldContent !== newContent) {
  145. grunt.log.writeln(`updating ${filename} to ${options.newVersionStr}`);
  146. fs.writeFileSync(filename, newContent);
  147. }
  148. });
  149. });
  150. });
  151. grunt.registerTask('bumpthree', function() {
  152. const lessonInfo = JSON.parse(fs.readFileSync('package.json', {encoding: 'utf8'}));
  153. const oldVersion = lessonInfo.threejsfundamentals.threeVersion;
  154. const oldVersionStr = `r${oldVersion}`;
  155. const threePath = path.join(__dirname, '..', 'three.js');
  156. const threeInfo = JSON.parse(fs.readFileSync(path.join(threePath, 'package.json'), {encoding: 'utf8'}));
  157. const newVersion = semver.minor(threeInfo.version);
  158. const newVersionStr = `r${newVersion}`;
  159. const basePath = path.join('threejs', 'resources', 'threejs', newVersionStr);
  160. grunt.config.merge({
  161. copy: {
  162. threejs: {
  163. files: [
  164. { expand: true, cwd: `${threePath}/build/`, src: 'three.js', dest: `${basePath}/`, },
  165. { expand: true, cwd: `${threePath}/build/`, src: 'three.min.js', dest: `${basePath}/`, },
  166. { expand: true, cwd: `${threePath}/examples/js/`, src: '**', dest: `${basePath}/js/`, },
  167. ],
  168. },
  169. },
  170. fixthreepaths: {
  171. options: {
  172. oldVersionStr,
  173. newVersionStr,
  174. },
  175. src: [
  176. 'threejs/**/*.html',
  177. 'threejs/**/*.md',
  178. 'threejs/**/*.js',
  179. '!threejs/resources/threejs/**',
  180. ],
  181. },
  182. });
  183. lessonInfo.threejsfundamentals.threeVersion = newVersion;
  184. fs.writeFileSync('package.json', JSON.stringify(lessonInfo, null, 2));
  185. grunt.task.run(['copy:threejs', 'fixthreepaths']);
  186. });
  187. grunt.registerTask('build', ['clean', 'copy:main', 'buildlessons']);
  188. grunt.registerTask('buildwatch', ['build', 'watch']);
  189. grunt.registerTask('default', ['eslint', 'build']);
  190. };