Gruntfile.coffee 13 KB

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