Gruntfile.js 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. module.exports = function(grunt) {
  2. // Load all grunt modules
  3. require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
  4. // Tell our Express server that Grunt launched it
  5. process.env.GRUNTED = true;
  6. // Project configuration.
  7. grunt.initConfig({
  8. pkg: grunt.file.readJSON('package.json'),
  9. settings: grunt.file.readJSON('./server_config/settings.json'),
  10. font: {
  11. icons: {
  12. src: ['front/src/fonts/svg-icons/*.svg'],
  13. destCss: 'front/src/less/icons.less',
  14. destFonts: 'front/src/fonts/icons.woff',
  15. // Optional: Custom routing of font filepaths for CSS
  16. cssRouter: function (fontpath) {
  17. var pathArray = fontpath.split('/');
  18. var fileName = pathArray[pathArray.length - 1];
  19. return '/fonts/' + fileName;
  20. }
  21. }
  22. },
  23. less: {
  24. all: {
  25. files: [
  26. {
  27. expand: true,
  28. cwd: 'front/src/less/',
  29. src: ['**/*.less'],
  30. dest: 'front/src/css/',
  31. ext: '.css'
  32. }
  33. ]
  34. }
  35. },
  36. replace: {
  37. dist: {
  38. options: {
  39. patterns: [
  40. {
  41. match: 'googleAnalyticsId',
  42. replacement: '<%= settings.googleAnalyticsId %>'
  43. },
  44. {
  45. match: 'version',
  46. replacement: 'v<%= pkg.version %>'
  47. }
  48. ]
  49. },
  50. files: [
  51. {expand: true, flatten: true, src: ['front/src/main.html'], dest: 'front/build/'}
  52. ]
  53. }
  54. },
  55. jshint: {
  56. all: [
  57. '*.js',
  58. 'app/lib/*.js',
  59. 'bin/*.js',
  60. 'lib/**/*.js',
  61. 'app/nodeControllers/*.js',
  62. 'app/public/scripts/*.js',
  63. 'phantomas_custom/**/*.js',
  64. 'test/**/*.js',
  65. 'front/src/js/**/*.js'
  66. ]
  67. },
  68. clean: {
  69. tmp: {
  70. src: ['.tmp']
  71. },
  72. dev: {
  73. src: ['front/src/css']
  74. },
  75. coverage: {
  76. src: ['.tmp', 'coverage/']
  77. },
  78. build: {
  79. src: ['front/build']
  80. }
  81. },
  82. copy: {
  83. beforeCoverage: {
  84. files: [
  85. {src: ['bin/server.js'], dest: '.tmp/'}
  86. ]
  87. },
  88. coverage: {
  89. files: [
  90. {src: ['test/**'], dest: 'coverage/'},
  91. {src: ['lib/metadata/**'], dest: 'coverage/'}
  92. ]
  93. },
  94. build: {
  95. files: [
  96. {src: ['./front/src/fonts/icons.woff'], dest: './front/build/fonts/icons.woff'},
  97. {src: ['./front/src/img/favicon.png'], dest: './front/build/img/favicon.png'},
  98. ]
  99. }
  100. },
  101. lineremover: {
  102. beforeCoverage: {
  103. files: {
  104. '.tmp/bin/cli.js': 'bin/cli.js'
  105. },
  106. options: {
  107. exclusionPattern: /#!\/usr\/bin\/env node/
  108. }
  109. }
  110. },
  111. blanket: {
  112. coverageApp: {
  113. src: ['app/'],
  114. dest: 'coverage/app/'
  115. },
  116. coverageLib: {
  117. src: ['lib/'],
  118. dest: 'coverage/lib/'
  119. },
  120. coverageBin: {
  121. src: ['.tmp/bin/'],
  122. dest: 'coverage/bin/'
  123. }
  124. },
  125. mochaTest: {
  126. test: {
  127. options: {
  128. reporter: 'spec',
  129. },
  130. src: ['coverage/test/core/*.js', 'coverage/test/api/*.js']
  131. },
  132. 'test-current-work': {
  133. options: {
  134. reporter: 'spec',
  135. },
  136. src: ['coverage/test/api/apiTest.js']
  137. },
  138. coverage: {
  139. options: {
  140. reporter: 'html-cov',
  141. quiet: true,
  142. captureFile: 'coverage/coverage.html'
  143. },
  144. src: ['coverage/test/core/*.js', 'coverage/test/api/*.js']
  145. }
  146. },
  147. env: {
  148. dev: {
  149. NODE_ENV: 'development'
  150. },
  151. builded: {
  152. NODE_ENV: 'production'
  153. }
  154. },
  155. express: {
  156. dev: {
  157. options: {
  158. port: 8383,
  159. server: './bin/server.js',
  160. serverreload: true,
  161. showStack: true
  162. }
  163. },
  164. builded: {
  165. options: {
  166. port: 8383,
  167. server: './bin/server.js',
  168. serverreload: true,
  169. showStack: true
  170. }
  171. },
  172. test: {
  173. options: {
  174. port: 8387,
  175. server: './coverage/bin/server.js',
  176. showStack: true
  177. }
  178. },
  179. testSuite: {
  180. options: {
  181. port: 8388,
  182. bases: 'test/www'
  183. }
  184. }
  185. },
  186. useminPrepare: {
  187. html: './front/src/main.html',
  188. options: {
  189. dest: './front/build',
  190. root: ['./', './front/src']
  191. }
  192. },
  193. usemin: {
  194. html: './front/build/main.html',
  195. css: './front/build/css/*.css',
  196. options: {
  197. assetsDirs: ['front/build'],
  198. patterns: {
  199. css: [[/(\/fonts\/icons\.woff)/gm, 'Replacing reference to icons.woff']]
  200. }
  201. }
  202. },
  203. htmlmin: {
  204. options: {
  205. removeComments: true,
  206. collapseWhitespace: true
  207. },
  208. main: {
  209. files: [{
  210. expand: true,
  211. cwd: './front/build/',
  212. src: 'main.html',
  213. flatten: true,
  214. dest: './front/build'
  215. }]
  216. },
  217. views: {
  218. files: [{
  219. expand: true,
  220. cwd: './front/src/views',
  221. src: '*.html',
  222. flatten: true,
  223. dest: '.tmp/views/'
  224. }]
  225. }
  226. },
  227. inline_angular_templates: {
  228. build: {
  229. options: {
  230. base: '.tmp',
  231. method: 'append'
  232. },
  233. files: {
  234. './front/build/main.html': ['.tmp/views/*.html']
  235. }
  236. }
  237. },
  238. filerev: {
  239. options: {
  240. algorithm: 'md5',
  241. length: 8
  242. },
  243. assets: {
  244. src: './front/build/*/*.*'
  245. }
  246. }
  247. });
  248. // Custom task: copies the test settings.json file to the coverage folder, and checks if there's no missing fields
  249. grunt.registerTask('copy-test-server-settings', function() {
  250. var mainSettingsFile = './server_config/settings.json';
  251. var testSettingsFile = './test/fixtures/settings.json';
  252. var mainSettings = grunt.file.readJSON(mainSettingsFile);
  253. var testSettings = grunt.file.readJSON(testSettingsFile);
  254. // Recursively compare keys of two objects (not the values)
  255. function compareKeys(original, copy, context) {
  256. for (var key in original) {
  257. if (!copy[key] && copy[key] !== '' && copy[key] !== 0) {
  258. grunt.fail.warn('Settings file ' + testSettingsFile + ' doesn\'t contain key ' + context + '.' + key);
  259. }
  260. if (original[key] !== null && typeof original[key] === 'object') {
  261. compareKeys(original[key], copy[key], context + '.' + key);
  262. }
  263. }
  264. }
  265. compareKeys(mainSettings, testSettings, 'settings');
  266. var outputFile = './coverage/server_config/settings.json';
  267. grunt.file.write(outputFile, JSON.stringify(testSettings, null, 4));
  268. grunt.log.ok('File ' + outputFile + ' created');
  269. });
  270. grunt.registerTask('icons', [
  271. 'font:icons',
  272. 'less',
  273. 'clean:tmp'
  274. ]);
  275. grunt.registerTask('build', [
  276. 'clean:build',
  277. 'copy:build',
  278. 'less',
  279. 'useminPrepare',
  280. 'concat',
  281. 'uglify',
  282. 'cssmin',
  283. 'replace',
  284. 'htmlmin:views',
  285. 'inline_angular_templates',
  286. 'filerev',
  287. 'usemin',
  288. 'htmlmin:main',
  289. 'clean:tmp'
  290. ]);
  291. grunt.registerTask('hint', [
  292. 'jshint'
  293. ]);
  294. grunt.registerTask('dev', [
  295. 'env:dev',
  296. 'express:dev'
  297. ]);
  298. grunt.registerTask('builded', [
  299. 'env:builded',
  300. 'express:builded'
  301. ]);
  302. grunt.registerTask('test', [
  303. 'build',
  304. 'jshint',
  305. 'express:testSuite',
  306. 'clean:coverage',
  307. 'copy-test-server-settings',
  308. 'lineremover:beforeCoverage',
  309. 'copy:beforeCoverage',
  310. 'blanket',
  311. 'copy:coverage',
  312. 'express:test',
  313. 'mochaTest:test',
  314. 'mochaTest:coverage',
  315. 'clean:tmp'
  316. ]);
  317. grunt.registerTask('test-current-work', [
  318. 'build',
  319. 'jshint',
  320. 'express:testSuite',
  321. 'clean:coverage',
  322. 'copy-test-server-settings',
  323. 'lineremover:beforeCoverage',
  324. 'copy:beforeCoverage',
  325. 'blanket',
  326. 'copy:coverage',
  327. 'express:test',
  328. 'mochaTest:test-current-work',
  329. 'clean:tmp'
  330. ]);
  331. };