Gruntfile.coffee 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. fs = require "fs"
  2. PackageVersions = require "./app/coffee/infrastructure/PackageVersions"
  3. require('es6-promise').polyfill()
  4. module.exports = (grunt) ->
  5. grunt.loadNpmTasks 'grunt-contrib-coffee'
  6. grunt.loadNpmTasks 'grunt-contrib-less'
  7. grunt.loadNpmTasks 'grunt-contrib-clean'
  8. grunt.loadNpmTasks 'grunt-mocha-test'
  9. grunt.loadNpmTasks 'grunt-available-tasks'
  10. grunt.loadNpmTasks 'grunt-contrib-requirejs'
  11. grunt.loadNpmTasks 'grunt-bunyan'
  12. grunt.loadNpmTasks 'grunt-sed'
  13. grunt.loadNpmTasks 'grunt-git-rev-parse'
  14. grunt.loadNpmTasks 'grunt-file-append'
  15. grunt.loadNpmTasks 'grunt-file-append'
  16. grunt.loadNpmTasks 'grunt-env'
  17. grunt.loadNpmTasks 'grunt-newer'
  18. grunt.loadNpmTasks 'grunt-contrib-watch'
  19. grunt.loadNpmTasks 'grunt-parallel'
  20. grunt.loadNpmTasks 'grunt-exec'
  21. grunt.loadNpmTasks 'grunt-postcss'
  22. # grunt.loadNpmTasks 'grunt-contrib-imagemin'
  23. # grunt.loadNpmTasks 'grunt-sprity'
  24. config =
  25. exec:
  26. run:
  27. command:"node app.js | ./node_modules/logger-sharelatex/node_modules/bunyan/bin/bunyan --color"
  28. cssmin:
  29. command:"node_modules/clean-css/bin/cleancss --s0 -o public/stylesheets/style.css public/stylesheets/style.css"
  30. watch:
  31. coffee:
  32. files: 'public/**/*.coffee'
  33. tasks: ['quickcompile:coffee']
  34. options: {}
  35. less:
  36. files: '**/*.less'
  37. tasks: ['compile:css']
  38. options: {}
  39. parallel:
  40. run:
  41. tasks:['exec', 'watch']
  42. options:
  43. grunt:true
  44. stream:true
  45. # imagemin:
  46. # dynamic:
  47. # files: [{
  48. # expand: true
  49. # cwd: 'public/img/'
  50. # src: ['**/*.{png,jpg,gif}']
  51. # dest: 'public/img/'
  52. # }]
  53. # options:
  54. # interlaced:false
  55. # optimizationLevel: 7
  56. # sprity:
  57. # sprite:
  58. # options:
  59. # cssPath:"/img/"
  60. # 'style': '../../public/stylesheets/app/sprites.less'
  61. # margin: 0
  62. # src: ['./public/img/flags/24/*.png']
  63. # dest: './public/img/sprite'
  64. coffee:
  65. app_dir:
  66. expand: true,
  67. flatten: false,
  68. cwd: 'app/coffee',
  69. src: ['**/*.coffee'],
  70. dest: 'app/js/',
  71. ext: '.js'
  72. app:
  73. src: 'app.coffee'
  74. dest: 'app.js'
  75. sharejs:
  76. options:
  77. join: true
  78. files:
  79. "public/js/libs/sharejs.js": [
  80. "public/coffee/ide/editor/sharejs/header.coffee"
  81. "public/coffee/ide/editor/sharejs/vendor/types/helpers.coffee"
  82. "public/coffee/ide/editor/sharejs/vendor/types/text.coffee"
  83. "public/coffee/ide/editor/sharejs/vendor/types/text-api.coffee"
  84. "public/coffee/ide/editor/sharejs/vendor/client/microevent.coffee"
  85. "public/coffee/ide/editor/sharejs/vendor/client/doc.coffee"
  86. "public/coffee/ide/editor/sharejs/vendor/client/ace.coffee"
  87. ]
  88. client:
  89. expand: true,
  90. flatten: false,
  91. cwd: 'public/coffee',
  92. src: ['**/*.coffee'],
  93. dest: 'public/js/',
  94. ext: '.js',
  95. options:
  96. sourceMap: true
  97. smoke_tests:
  98. expand: true,
  99. flatten: false,
  100. cwd: 'test/smoke/coffee',
  101. src: ['**/*.coffee'],
  102. dest: 'test/smoke/js/',
  103. ext: '.js'
  104. unit_tests:
  105. expand: true,
  106. flatten: false,
  107. cwd: 'test/UnitTests/coffee',
  108. src: ['**/*.coffee'],
  109. dest: 'test/UnitTests/js/',
  110. ext: '.js'
  111. acceptance_tests:
  112. expand: true,
  113. flatten: false,
  114. cwd: 'test/acceptance/coffee',
  115. src: ['**/*.coffee'],
  116. dest: 'test/acceptance/js/',
  117. ext: '.js'
  118. less:
  119. app:
  120. files:
  121. "public/stylesheets/style.css": "public/stylesheets/style.less"
  122. ol:
  123. files:
  124. "public/stylesheets/ol-style.css": "public/stylesheets/ol-style.less"
  125. postcss:
  126. options:
  127. map: true,
  128. processors: [
  129. require('autoprefixer')({browsers: [ 'last 2 versions', 'ie >= 10' ]})
  130. ]
  131. dist:
  132. src: 'public/stylesheets/style.css'
  133. env:
  134. run:
  135. add:
  136. NODE_TLS_REJECT_UNAUTHORIZED:0
  137. requirejs:
  138. compile:
  139. options:
  140. optimize:"uglify2"
  141. uglify2:
  142. mangle: false
  143. appDir: "public/js"
  144. baseUrl: "./"
  145. dir: "public/minjs"
  146. inlineText: false
  147. generateSourceMaps: true
  148. preserveLicenseComments: false
  149. paths:
  150. "moment": "libs/#{PackageVersions.lib('moment')}"
  151. "mathjax": "/js/libs/mathjax/MathJax.js?config=TeX-AMS_HTML"
  152. "pdfjs-dist/build/pdf": "libs/#{PackageVersions.lib('pdfjs')}/pdf"
  153. "ace": "#{PackageVersions.lib('ace')}"
  154. shim:
  155. "pdfjs-dist/build/pdf":
  156. deps: ["libs/#{PackageVersions.lib('pdfjs')}/compatibility"]
  157. skipDirOptimize: true
  158. modules: [
  159. {
  160. name: "main",
  161. exclude: ["libs"]
  162. }, {
  163. name: "ide",
  164. exclude: ["libs", "pdfjs-dist/build/pdf"]
  165. }, {
  166. name: "libs"
  167. },{
  168. name: "ace/mode-latex"
  169. },{
  170. name: "ace/worker-latex"
  171. }
  172. ]
  173. clean:
  174. app: ["app/js"]
  175. unit_tests: ["test/UnitTests/js"]
  176. acceptance_tests: ["test/acceptance/js"]
  177. mochaTest:
  178. unit:
  179. src: ["test/UnitTests/js/#{grunt.option('feature') or '**'}/*.js"]
  180. options:
  181. reporter: grunt.option('reporter') or 'spec'
  182. grep: grunt.option("grep")
  183. smoke:
  184. src: ['test/smoke/js/**/*.js']
  185. options:
  186. reporter: grunt.option('reporter') or 'spec'
  187. grep: grunt.option("grep")
  188. acceptance:
  189. src: ["test/acceptance/js/#{grunt.option('feature') or '**'}/*.js"]
  190. options:
  191. timeout: 40000
  192. reporter: grunt.option('reporter') or 'spec'
  193. grep: grunt.option("grep")
  194. "git-rev-parse":
  195. version:
  196. options:
  197. prop: 'commit'
  198. file_append:
  199. default_options: files: [ {
  200. append: '\n//ide.js is complete - used for automated testing'
  201. input: 'public/minjs/ide.js'
  202. output: 'public/minjs/ide.js'
  203. }]
  204. sed:
  205. version:
  206. path: "app/views/sentry.pug"
  207. pattern: '@@COMMIT@@',
  208. replacement: '<%= commit %>',
  209. release:
  210. path: "app/views/sentry.pug"
  211. pattern: "@@RELEASE@@"
  212. replacement: process.env.BUILD_NUMBER || "(unknown build)"
  213. availabletasks:
  214. tasks:
  215. options:
  216. filter: 'exclude',
  217. tasks: [
  218. 'coffee'
  219. 'less'
  220. 'clean'
  221. 'mochaTest'
  222. 'availabletasks'
  223. 'wrap_sharejs'
  224. 'requirejs'
  225. 'execute'
  226. 'bunyan'
  227. ]
  228. groups:
  229. "Compile tasks": [
  230. "compile:server"
  231. "compile:client"
  232. "compile:tests"
  233. "compile"
  234. "compile:unit_tests"
  235. "compile:smoke_tests"
  236. "compile:css"
  237. "compile:minify"
  238. "install"
  239. ]
  240. "Test tasks": [
  241. "test:unit"
  242. "test:acceptance"
  243. ]
  244. "Run tasks": [
  245. "run"
  246. "default"
  247. ]
  248. "Misc": [
  249. "help"
  250. ]
  251. moduleCompileServerTasks = []
  252. moduleCompileUnitTestTasks = []
  253. moduleUnitTestTasks = []
  254. moduleCompileClientTasks = []
  255. moduleIdeClientSideIncludes = []
  256. moduleMainClientSideIncludes = []
  257. if fs.existsSync "./modules"
  258. for module in fs.readdirSync "./modules"
  259. if fs.existsSync "./modules/#{module}/index.coffee"
  260. config.coffee["module_#{module}_server"] = {
  261. expand: true,
  262. flatten: false,
  263. cwd: "modules/#{module}/app/coffee",
  264. src: ['**/*.coffee'],
  265. dest: "modules/#{module}/app/js",
  266. ext: '.js'
  267. }
  268. config.coffee["module_#{module}_index"] = {
  269. src: "modules/#{module}/index.coffee",
  270. dest: "modules/#{module}/index.js"
  271. }
  272. moduleCompileServerTasks.push "coffee:module_#{module}_server"
  273. moduleCompileServerTasks.push "coffee:module_#{module}_index"
  274. config.coffee["module_#{module}_unit_tests"] = {
  275. expand: true,
  276. flatten: false,
  277. cwd: "modules/#{module}/test/unit/coffee",
  278. src: ['**/*.coffee'],
  279. dest: "modules/#{module}/test/unit/js",
  280. ext: '.js'
  281. }
  282. config.mochaTest["module_#{module}_unit"] = {
  283. src: ["modules/#{module}/test/unit/js/**/*.js"]
  284. options:
  285. reporter: grunt.option('reporter') or 'spec'
  286. grep: grunt.option("grep")
  287. }
  288. moduleCompileUnitTestTasks.push "coffee:module_#{module}_unit_tests"
  289. moduleUnitTestTasks.push "mochaTest:module_#{module}_unit"
  290. if fs.existsSync "./modules/#{module}/public/coffee/ide/index.coffee"
  291. config.coffee["module_#{module}_client_ide"] = {
  292. expand: true,
  293. flatten: false,
  294. cwd: "modules/#{module}/public/coffee/ide",
  295. src: ['**/*.coffee'],
  296. dest: "public/js/ide/#{module}",
  297. ext: '.js'
  298. }
  299. moduleCompileClientTasks.push "coffee:module_#{module}_client_ide"
  300. moduleIdeClientSideIncludes.push "ide/#{module}/index"
  301. if fs.existsSync "./modules/#{module}/public/coffee/main/index.coffee"
  302. config.coffee["module_#{module}_client_main"] = {
  303. expand: true,
  304. flatten: false,
  305. cwd: "modules/#{module}/public/coffee/main",
  306. src: ['**/*.coffee'],
  307. dest: "public/js/main/#{module}",
  308. ext: '.js'
  309. }
  310. moduleCompileClientTasks.push "coffee:module_#{module}_client_main"
  311. moduleMainClientSideIncludes.push "main/#{module}/index"
  312. grunt.initConfig config
  313. grunt.registerTask 'wrap_sharejs', 'Wrap the compiled ShareJS code for AMD module loading', () ->
  314. content = fs.readFileSync "public/js/libs/sharejs.js"
  315. fs.writeFileSync "public/js/libs/sharejs.js", """
  316. define(["ace/ace"], function() {
  317. #{content}
  318. return window.sharejs;
  319. });
  320. """
  321. grunt.registerTask 'help', 'Display this help list', 'availabletasks'
  322. grunt.registerTask 'compile:modules:server', 'Compile all the modules', moduleCompileServerTasks
  323. grunt.registerTask 'compile:modules:unit_tests', 'Compile all the modules unit tests', moduleCompileUnitTestTasks
  324. grunt.registerTask 'compile:modules:client', 'Compile all the module client side code', moduleCompileClientTasks
  325. grunt.registerTask 'compile:modules:inject_clientside_includes', () ->
  326. content = fs.readFileSync("public/js/ide.js").toString()
  327. content = content.replace(/, "__IDE_CLIENTSIDE_INCLUDES__"/g, moduleIdeClientSideIncludes.map((i) -> ", \"#{i}\"").join(""))
  328. fs.writeFileSync "public/js/ide.js", content
  329. content = fs.readFileSync("public/js/main.js").toString()
  330. content = content.replace(/, "__MAIN_CLIENTSIDE_INCLUDES__"/g, moduleMainClientSideIncludes.map((i) -> ", \"#{i}\"").join(""))
  331. fs.writeFileSync "public/js/main.js", content
  332. grunt.registerTask 'compile:server', 'Compile the server side coffee script', ['clean:app', 'coffee:app', 'coffee:app_dir', 'compile:modules:server']
  333. grunt.registerTask 'compile:client', 'Compile the client side coffee script', ['coffee:client', 'coffee:sharejs', 'wrap_sharejs', "compile:modules:client", 'compile:modules:inject_clientside_includes']
  334. grunt.registerTask 'compile:css', 'Compile the less files to css', ['less', 'postcss:dist']
  335. grunt.registerTask 'compile:minify', 'Concat and minify the client side js', ['requirejs', "file_append", "exec:cssmin",]
  336. grunt.registerTask 'compile:unit_tests', 'Compile the unit tests', ['clean:unit_tests', 'coffee:unit_tests']
  337. grunt.registerTask 'compile:acceptance_tests', 'Compile the acceptance tests', ['clean:acceptance_tests', 'coffee:acceptance_tests']
  338. grunt.registerTask 'compile:smoke_tests', 'Compile the smoke tests', ['coffee:smoke_tests']
  339. grunt.registerTask 'compile:tests', 'Compile all the tests', ['compile:smoke_tests', 'compile:unit_tests']
  340. grunt.registerTask 'compile', 'Compiles everything need to run web-sharelatex', ['compile:server', 'compile:client', 'compile:css']
  341. grunt.registerTask 'quickcompile:coffee', 'Compiles only changed coffee files',['newer:coffee']
  342. grunt.registerTask 'install', "Compile everything when installing as an npm module", ['compile']
  343. grunt.registerTask 'test:unit', 'Run the unit tests (use --grep=<regex> or --feature=<feature> for individual tests)', ['compile:server', 'compile:modules:server', 'compile:unit_tests', 'compile:modules:unit_tests', 'mochaTest:unit'].concat(moduleUnitTestTasks)
  344. grunt.registerTask 'test:acceptance', 'Run the acceptance tests (use --grep=<regex> or --feature=<feature> for individual tests)', ['compile:acceptance_tests', 'mochaTest:acceptance']
  345. grunt.registerTask 'test:smoke', 'Run the smoke tests', ['compile:smoke_tests', 'mochaTest:smoke']
  346. grunt.registerTask 'test:modules:unit', 'Run the unit tests for the modules', ['compile:modules:server', 'compile:modules:unit_tests'].concat(moduleUnitTestTasks)
  347. grunt.registerTask 'run:watch', "Compile and run the web-sharelatex server", ['compile', 'env:run', 'parallel']
  348. grunt.registerTask 'run', "Compile and run the web-sharelatex server", ['compile', 'env:run', 'exec']
  349. grunt.registerTask 'default', 'run'
  350. grunt.registerTask 'version', "Write the version number into sentry.pug", ['git-rev-parse', 'sed']