Gruntfile.js 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. /* jshint node:true */
  2. 'use strict';
  3. module.exports = function (grunt) {
  4. var config = {
  5. pkg: grunt.file.readJSON('package.json'),
  6. srcDir: 'src',
  7. destDir: 'dist',
  8. tempDir: 'tmp',
  9. meta: {
  10. banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +
  11. '<%= grunt.template.today("yyyy-mm-dd") %>\n' +
  12. '<%= pkg.homepage ? " * " + pkg.homepage + "\\n" : "" %>' +
  13. ' * Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
  14. ' Licensed <%= pkg.license %> */\n\n'
  15. },
  16. clean: {
  17. on_start: ['<%= destDir %>', '<%= tempDir %>'],
  18. temp: ['<%= tempDir %>'],
  19. },
  20. less: {
  21. // this is the only task, other than copy, that runs on the src directory, since we don't really need
  22. // the less files in the dist. Everything else runs from on temp, and require copys everything
  23. // from temp -> dist
  24. dist:{
  25. expand: true,
  26. cwd:'<%= srcDir %>/vendor/bootstrap/less/',
  27. src: ['bootstrap.dark.less', 'bootstrap.light.less'],
  28. dest: '<%= tempDir %>/css/',
  29. },
  30. // Compile in place when not building
  31. src:{
  32. options: {
  33. paths: ["<%= srcDir %>/vendor/bootstrap/less"],
  34. yuicompress:true
  35. },
  36. files: {
  37. "<%= srcDir %>/css/bootstrap.dark.min.css": "<%= srcDir %>/vendor/bootstrap/less/bootstrap.dark.less",
  38. "<%= srcDir %>/css/bootstrap.light.min.css": "<%= srcDir %>/vendor/bootstrap/less/bootstrap.light.less"
  39. }
  40. }
  41. },
  42. copy: {
  43. // copy source to temp, we will minify in place for the dist build
  44. everything_but_less_to_temp: {
  45. cwd: '<%= srcDir %>',
  46. expand: true,
  47. src: ['**/*', '!**/*.less'],
  48. dest: '<%= tempDir %>'
  49. }
  50. },
  51. jshint: {
  52. // just lint the source dir
  53. source: {
  54. files: {
  55. src: ['Gruntfile.js', '<%= srcDir %>/app/**/*.js']
  56. }
  57. },
  58. options: {
  59. jshintrc: '.jshintrc'
  60. }
  61. },
  62. htmlmin:{
  63. build: {
  64. options:{
  65. removeComments: true,
  66. collapseWhitespace: true
  67. },
  68. expand: true,
  69. cwd: '<%= tempDir %>',
  70. src: [
  71. 'index.html',
  72. 'app/panels/**/*.html',
  73. 'app/partials/**/*.html'
  74. ],
  75. dest: '<%= tempDir %>'
  76. }
  77. },
  78. cssmin: {
  79. build: {
  80. expand: true,
  81. cwd: '<%= tempDir %>',
  82. src: '**/*.css',
  83. dest: '<%= tempDir %>'
  84. }
  85. },
  86. ngmin: {
  87. build: {
  88. expand:true,
  89. cwd:'<%= tempDir %>',
  90. src: [
  91. 'app/controllers/**/*.js',
  92. 'app/directives/**/*.js',
  93. 'app/services/**/*.js',
  94. 'app/filters/**/*.js',
  95. 'app/panels/**/*.js',
  96. 'app/app.js',
  97. 'vendor/angular/**/*.js',
  98. 'vendor/elasticjs/elastic-angular-client.js'
  99. ],
  100. dest: '<%= tempDir %>'
  101. }
  102. },
  103. requirejs: {
  104. build: {
  105. options: {
  106. appDir: '<%= tempDir %>',
  107. dir: '<%= destDir %>',
  108. mainConfigFile: '<%= tempDir %>/app/components/require.config.js',
  109. modules: [], // populated below
  110. optimize: 'none',
  111. optimizeCss: 'none',
  112. optimizeAllPluginResources: false,
  113. removeCombined: true,
  114. findNestedDependencies: true,
  115. normalizeDirDefines: 'all',
  116. inlineText: true,
  117. skipPragmas: true,
  118. done: function (done, output) {
  119. var duplicates = require('rjs-build-analysis').duplicates(output);
  120. if (duplicates.length > 0) {
  121. grunt.log.subhead('Duplicates found in requirejs build:');
  122. grunt.log.warn(duplicates);
  123. done(new Error('r.js built duplicate modules, please check the excludes option.'));
  124. }
  125. done();
  126. }
  127. }
  128. }
  129. },
  130. uglify: {
  131. dest: {
  132. expand: true,
  133. src: ['**/*.js', '!config.js', '!app/dashboards/*.js'],
  134. dest: '<%= destDir %>',
  135. cwd: '<%= destDir %>',
  136. options: {
  137. quite: true,
  138. compress: true,
  139. preserveComments: false,
  140. banner: '<%= meta.banner %>'
  141. }
  142. }
  143. },
  144. 'git-describe': {
  145. me: {
  146. // Target-specific file lists and/or options go here.
  147. },
  148. },
  149. compress: {
  150. zip: {
  151. options: {
  152. archive: '<%= tempDir %>/<%= pkg.name %>-latest.zip'
  153. },
  154. files : [
  155. {
  156. expand: true,
  157. cwd: '<%= destDir %>',
  158. src: ['**/*'],
  159. dest: '<%= pkg.name %>-latest'
  160. },
  161. {
  162. expand: true,
  163. src: ['LICENSE.md', 'README.md'],
  164. dest: '<%= pkg.name %>-latest'
  165. }
  166. ]
  167. },
  168. tgz: {
  169. options: {
  170. archive: '<%= tempDir %>/<%= pkg.name %>-latest.tar.gz'
  171. },
  172. files : [
  173. {
  174. expand: true,
  175. cwd: '<%= destDir %>',
  176. src: ['**/*'],
  177. dest: '<%= pkg.name %>-latest'
  178. },
  179. {
  180. expand: true,
  181. src: ['LICENSE.md', 'README.md'],
  182. dest: '<%= pkg.name %>-latest'
  183. }
  184. ]
  185. }
  186. },
  187. s3: {
  188. dist: {
  189. bucket: 'download.elasticsearch.org',
  190. access: 'private',
  191. // debug: true, // uncommment to prevent actual upload
  192. upload: [
  193. {
  194. src: '<%= tempDir %>/<%= pkg.name %>-latest.zip',
  195. dest: 'kibana/kibana/<%= pkg.name %>-latest.zip',
  196. },
  197. {
  198. src: '<%= tempDir %>/<%= pkg.name %>-latest.tar.gz',
  199. dest: 'kibana/kibana/<%= pkg.name %>-latest.tar.gz',
  200. }
  201. ]
  202. }
  203. }
  204. };
  205. // setup the modules require will build
  206. var requireModules = config.requirejs.build.options.modules = [
  207. {
  208. // main/common module
  209. name: 'app',
  210. include: [
  211. 'css',
  212. 'kbn',
  213. 'text',
  214. 'jquery',
  215. 'angular',
  216. 'settings',
  217. 'bootstrap',
  218. 'modernizr',
  219. 'elasticjs',
  220. 'timepicker',
  221. 'datepicker',
  222. 'underscore',
  223. 'filters/all',
  224. 'jquery.flot',
  225. 'services/all',
  226. 'angular-strap',
  227. 'directives/all',
  228. 'jquery.flot.pie',
  229. 'angular-sanitize',
  230. 'angular-dragdrop'
  231. ]
  232. }
  233. ];
  234. // create a module for each directory in src/app/panels/
  235. require('fs')
  236. .readdirSync(config.srcDir+'/app/panels')
  237. .forEach(function (panelName) {
  238. requireModules.push({
  239. name: 'panels/'+panelName+'/module',
  240. exclude: ['app']
  241. });
  242. });
  243. // exclude the literal config definition from all modules
  244. requireModules
  245. .forEach(function (module) {
  246. module.excludeShallow = module.excludeShallow || [];
  247. module.excludeShallow.push('config');
  248. });
  249. // Run jshint
  250. grunt.registerTask('default', ['jshint:source', 'less:src']);
  251. // Concat and Minify the src directory into dist
  252. grunt.registerTask('build', [
  253. 'jshint:source',
  254. 'clean:on_start',
  255. 'less:dist',
  256. 'copy:everything_but_less_to_temp',
  257. 'htmlmin:build',
  258. 'cssmin:build',
  259. 'ngmin:build',
  260. 'requirejs:build',
  261. 'clean:temp',
  262. 'build:write_revision',
  263. 'uglify:dest'
  264. ]);
  265. // run a string replacement on the require config, using the latest revision number as the cache buster
  266. grunt.registerTask('build:write_revision', function() {
  267. grunt.event.once('git-describe', function (desc) {
  268. grunt.config('string-replace.config', {
  269. src: '<%= destDir %>/app/components/require.config.js',
  270. dest: '<%= destDir %>/app/components/require.config.js',
  271. options: {
  272. replacements: [
  273. {
  274. pattern: /(?:^|\/\/)(.*)@REV@/,
  275. replacement: '$1'+desc.object
  276. }
  277. ]
  278. }
  279. });
  280. grunt.task.run('string-replace:config');
  281. });
  282. grunt.task.run('git-describe');
  283. });
  284. // build, then zip and upload to s3
  285. grunt.registerTask('distribute', [
  286. 'distribute:load_s3_config',
  287. 'build',
  288. 'compress:zip',
  289. 'compress:tgz',
  290. 's3:dist',
  291. 'clean:temp'
  292. ]);
  293. // collect the key and secret from the .aws-config.json file, finish configuring the s3 task
  294. grunt.registerTask('distribute:load_s3_config', function () {
  295. var config = grunt.file.readJSON('.aws-config.json');
  296. grunt.config('s3.options', {
  297. key: config.key,
  298. secret: config.secret
  299. });
  300. });
  301. // load plugins
  302. grunt.loadNpmTasks('grunt-s3');
  303. grunt.loadNpmTasks('grunt-ngmin');
  304. grunt.loadNpmTasks('grunt-contrib-copy');
  305. grunt.loadNpmTasks('grunt-contrib-less');
  306. grunt.loadNpmTasks('grunt-git-describe');
  307. grunt.loadNpmTasks('grunt-contrib-clean');
  308. grunt.loadNpmTasks('grunt-contrib-jshint');
  309. grunt.loadNpmTasks('grunt-contrib-cssmin');
  310. grunt.loadNpmTasks('grunt-contrib-uglify');
  311. grunt.loadNpmTasks('grunt-string-replace');
  312. grunt.loadNpmTasks('grunt-contrib-htmlmin');
  313. grunt.loadNpmTasks('grunt-contrib-requirejs');
  314. grunt.loadNpmTasks('grunt-contrib-compress');
  315. // pass the config to grunt
  316. grunt.initConfig(config);
  317. };