Gruntfile.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  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. zip_release: {
  187. options: {
  188. archive: '<%= tempDir %>/<%= pkg.name %>-<%= pkg.version %>.zip'
  189. },
  190. files : [
  191. {
  192. expand: true,
  193. cwd: '<%= destDir %>',
  194. src: ['**/*'],
  195. dest: '<%= pkg.name %>-<%= pkg.version %>'
  196. },
  197. {
  198. expand: true,
  199. src: ['LICENSE.md', 'README.md'],
  200. dest: '<%= pkg.name %>-<%= pkg.version %>'
  201. }
  202. ]
  203. },
  204. tgz_release: {
  205. options: {
  206. archive: '<%= tempDir %>/<%= pkg.name %>-<%= pkg.version %>.tar.gz'
  207. },
  208. files : [
  209. {
  210. expand: true,
  211. cwd: '<%= destDir %>',
  212. src: ['**/*'],
  213. dest: '<%= pkg.name %>-<%= pkg.version %>'
  214. },
  215. {
  216. expand: true,
  217. src: ['LICENSE.md', 'README.md'],
  218. dest: '<%= pkg.name %>-<%= pkg.version %>'
  219. }
  220. ]
  221. }
  222. },
  223. s3: {
  224. dist: {
  225. bucket: 'download.elasticsearch.org',
  226. access: 'private',
  227. // debug: true, // uncommment to prevent actual upload
  228. upload: [
  229. {
  230. src: '<%= tempDir %>/<%= pkg.name %>-latest.zip',
  231. dest: 'kibana/kibana/<%= pkg.name %>-latest.zip',
  232. },
  233. {
  234. src: '<%= tempDir %>/<%= pkg.name %>-latest.tar.gz',
  235. dest: 'kibana/kibana/<%= pkg.name %>-latest.tar.gz',
  236. }
  237. ]
  238. },
  239. release: {
  240. bucket: 'download.elasticsearch.org',
  241. access: 'private',
  242. // debug: true, // uncommment to prevent actual upload
  243. upload: [
  244. {
  245. src: '<%= tempDir %>/<%= pkg.name %>-<%= pkg.version %>.zip',
  246. dest: 'kibana/kibana/<%= pkg.name %>-<%= pkg.version %>.zip',
  247. },
  248. {
  249. src: '<%= tempDir %>/<%= pkg.name %>-<%= pkg.version %>.tar.gz',
  250. dest: 'kibana/kibana/<%= pkg.name %>-<%= pkg.version %>.tar.gz',
  251. }
  252. ]
  253. }
  254. }
  255. };
  256. // setup the modules require will build
  257. var requireModules = config.requirejs.build.options.modules = [
  258. {
  259. // main/common module
  260. name: 'app',
  261. include: [
  262. 'css',
  263. 'kbn',
  264. 'text',
  265. 'jquery',
  266. 'angular',
  267. 'settings',
  268. 'bootstrap',
  269. 'modernizr',
  270. 'elasticjs',
  271. 'timepicker',
  272. 'datepicker',
  273. 'underscore',
  274. 'filters/all',
  275. 'jquery.flot',
  276. 'services/all',
  277. 'angular-strap',
  278. 'directives/all',
  279. 'jquery.flot.pie',
  280. 'angular-sanitize',
  281. 'angular-dragdrop'
  282. ]
  283. }
  284. ];
  285. // create a module for each directory in src/app/panels/
  286. require('fs')
  287. .readdirSync(config.srcDir+'/app/panels')
  288. .forEach(function (panelName) {
  289. requireModules.push({
  290. name: 'panels/'+panelName+'/module',
  291. exclude: ['app']
  292. });
  293. });
  294. // exclude the literal config definition from all modules
  295. requireModules
  296. .forEach(function (module) {
  297. module.excludeShallow = module.excludeShallow || [];
  298. module.excludeShallow.push('config');
  299. });
  300. // Run jshint
  301. grunt.registerTask('default', ['jshint:source', 'less:src']);
  302. // Concat and Minify the src directory into dist
  303. grunt.registerTask('build', [
  304. 'jshint:source',
  305. 'clean:on_start',
  306. 'less:dist',
  307. 'copy:everything_but_less_to_temp',
  308. 'htmlmin:build',
  309. 'cssmin:build',
  310. 'ngmin:build',
  311. 'requirejs:build',
  312. 'clean:temp',
  313. 'build:write_revision',
  314. 'uglify:dest'
  315. ]);
  316. // run a string replacement on the require config, using the latest revision number as the cache buster
  317. grunt.registerTask('build:write_revision', function() {
  318. grunt.event.once('git-describe', function (desc) {
  319. grunt.config('string-replace.config', {
  320. src: '<%= destDir %>/app/components/require.config.js',
  321. dest: '<%= destDir %>/app/components/require.config.js',
  322. options: {
  323. replacements: [
  324. {
  325. pattern: /(?:^|\/\/)(.*)@REV@/,
  326. replacement: '$1'+desc.object
  327. }
  328. ]
  329. }
  330. });
  331. grunt.task.run('string-replace:config');
  332. });
  333. grunt.task.run('git-describe');
  334. });
  335. // build, then zip and upload to s3
  336. grunt.registerTask('distribute', [
  337. 'distribute:load_s3_config',
  338. 'build',
  339. 'compress:zip',
  340. 'compress:tgz',
  341. 's3:dist',
  342. 'clean:temp'
  343. ]);
  344. // build, then zip and upload to s3
  345. grunt.registerTask('release', [
  346. 'distribute:load_s3_config',
  347. 'build',
  348. 'compress:zip_release',
  349. 'compress:tgz_release',
  350. 's3:release',
  351. 'clean:temp'
  352. ]);
  353. // collect the key and secret from the .aws-config.json file, finish configuring the s3 task
  354. grunt.registerTask('distribute:load_s3_config', function () {
  355. var config = grunt.file.readJSON('.aws-config.json');
  356. grunt.config('s3.options', {
  357. key: config.key,
  358. secret: config.secret
  359. });
  360. });
  361. // load plugins
  362. grunt.loadNpmTasks('grunt-s3');
  363. grunt.loadNpmTasks('grunt-ngmin');
  364. grunt.loadNpmTasks('grunt-contrib-copy');
  365. grunt.loadNpmTasks('grunt-contrib-less');
  366. grunt.loadNpmTasks('grunt-git-describe');
  367. grunt.loadNpmTasks('grunt-contrib-clean');
  368. grunt.loadNpmTasks('grunt-contrib-jshint');
  369. grunt.loadNpmTasks('grunt-contrib-cssmin');
  370. grunt.loadNpmTasks('grunt-contrib-uglify');
  371. grunt.loadNpmTasks('grunt-string-replace');
  372. grunt.loadNpmTasks('grunt-contrib-htmlmin');
  373. grunt.loadNpmTasks('grunt-contrib-requirejs');
  374. grunt.loadNpmTasks('grunt-contrib-compress');
  375. // pass the config to grunt
  376. grunt.initConfig(config);
  377. };