Gruntfile.coffee 14 KB

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