'use strict'; var fs = require('fs'), path = require('path'); /* jshint node:true */ /* jshint browser:false */ var StringReplacePlugin = require('string-replace-webpack-plugin'); module.exports = function(grunt) { require('time-grunt')(grunt); require('load-grunt-tasks')(grunt); grunt.loadTasks('grunt/tasks'); var webpack = require('webpack'); var pkg = require('./package.json'); var dt = new Date().toISOString().replace(/T.*/, ''); var minElectronVersionForUpdate = '1.0.1'; var zipCommentPlaceholder = 'zip_comment_placeholder_that_will_be_replaced_with_hash'; var electronVersion = pkg.devDependencies['electron-prebuilt'].replace(/^\D/, ''); while (zipCommentPlaceholder.length < 512) { zipCommentPlaceholder += '.'; } function replaceFont(css) { css.walkAtRules('font-face', function (rule) { var fontFamily = rule.nodes.filter(function(n) { return n.prop === 'font-family'; })[0]; if (!fontFamily) { throw 'Bad font rule: ' + rule.toString(); } var value = fontFamily.value.replace(/["']/g, ''); var fontFiles = { FontAwesome: 'fontawesome-webfont.woff' }; var fontFile = fontFiles[value]; if (!fontFile) { throw 'Unsupported font ' + value + ': ' + rule.toString(); } var data = fs.readFileSync('tmp/fonts/' + fontFile, 'base64'); var src = 'url(data:application/font-woff;charset=utf-8;base64,{data}) format(\'woff\')' .replace('{data}', data); //var src = 'url(\'../fonts/fontawesome-webfont.woff\') format(\'woff\')'; rule.nodes = rule.nodes.filter(function(n) { return n.prop !== 'src'; }); rule.append({ prop: 'src', value: src }); }); } grunt.initConfig({ gitinfo: { branch: { current: { SHA: 'Current HEAD SHA', shortSHA: 'Current HEAD short SHA', name: 'Current branch name', lastCommitTime: 'Last commit time' } } }, 'bower-install-simple': { install: { } }, clean: { dist: ['dist', 'tmp'], 'desktop_dist': ['dist/desktop'], 'desktop_tmp': ['tmp/desktop'] }, copy: { html: { src: 'app/index.html', dest: 'tmp/index.html', nonull: true }, favicon: { src: 'app/favicon.png', dest: 'tmp/favicon.png', nonull: true }, touchicon: { src: 'app/touchicon.png', dest: 'tmp/touchicon.png', nonull: true }, fonts: { src: 'bower_components/font-awesome/fonts/fontawesome-webfont.*', dest: 'tmp/fonts/', nonull: true, expand: true, flatten: true }, 'desktop_app_content': { cwd: 'electron/', src: '**', dest: 'tmp/desktop/app/', expand: true, nonull: true }, 'desktop_windows_helper': { src: 'helper/win32/KeeWebHelper.exe', dest: 'tmp/desktop/app/', nonull: true }, 'desktop_osx': { src: 'tmp/desktop/mac/KeeWeb-' + pkg.version + '.dmg', dest: 'dist/desktop/KeeWeb.mac.dmg', nonull: true }, 'desktop_win': { src: 'tmp/desktop/win-ia32/KeeWeb Setup ' + pkg.version + '-ia32.exe', dest: 'dist/desktop/KeeWeb.win32.exe', nonull: true }, 'desktop_linux_x64': { src: 'tmp/desktop/KeeWeb.linux.x64.zip', dest: 'dist/desktop/KeeWeb.linux.x64.zip', nonull: true }, 'desktop_linux_ia32': { src: 'tmp/desktop/KeeWeb.linux.ia32.zip', dest: 'dist/desktop/KeeWeb.linux.ia32.zip', nonull: true }, 'desktop_linux_deb_x64': { src: 'tmp/desktop/keeweb-desktop_*_amd64.deb', dest: 'dist/desktop/KeeWeb.linux.x64.deb', nonull: true } }, jshint: { options: { jshintrc: true }, all: ['app/scripts/**/*.js'] }, sass: { options: { sourceMap: false, includePaths: ['./bower_components'] }, dist: { files: { 'tmp/css/main.css': 'app/styles/main.scss' } } }, postcss: { options: { processors: [ replaceFont, require('cssnano')({discardComments: {removeAll: true}}) ] }, dist: { src: 'tmp/css/main.css', dest: 'tmp/css/main.css' } }, inline: { app: { src: 'tmp/index.html', dest: 'tmp/app.html' } }, htmlmin: { options: { removeComments: true, collapseWhitespace: true }, app: { files: { 'dist/index.html': 'tmp/app.html' } } }, 'string-replace': { manifest: { options: { replacements: [ { pattern: '# YYYY-MM-DD:v0.0.0', replacement: '# ' + dt + ':v' + pkg.version }, { pattern: '# updmin:v0.0.0', replacement: '# updmin:v' + minElectronVersionForUpdate } ] }, files: { 'dist/manifest.appcache': 'app/manifest.appcache' } }, 'manifest_html': { options: { replacements: [{ pattern: '' }, linux64: { options: { platform: 'linux', arch: 'x64', icon: 'graphics/app.ico' } }, linux32: { options: { platform: 'linux', arch: 'ia32', icon: 'graphics/app.ico' } } }, 'electron-builder': { options: { publish: 'never', dist: false, projectDir: __dirname, appDir: 'tmp/desktop/app', sign: false }, osx: { options: { platforms: ['osx'], arch: 'x64' } }, win: { options: { platform: ['win32'], arch: 'ia32' } } // linux64: { // options: { // platform: ['linux'], // arch: 'x64' // } // }, // linux32: { // options: { // platform: ['linux'], // arch: 'ia32' // } // } }, compress: { linux64: { options: { archive: 'tmp/desktop/KeeWeb.linux.x64.zip' }, files: [{ cwd: 'tmp/desktop/KeeWeb-linux-x64', src: '**', expand: true }] }, linux32: { options: { archive: 'tmp/desktop/KeeWeb.linux.ia32.zip' }, files: [{ cwd: 'tmp/desktop/KeeWeb-linux-ia32', src: '**', expand: true }] }, 'desktop_update': { options: { archive: 'dist/desktop/UpdateDesktop.zip', comment: zipCommentPlaceholder }, files: [{ cwd: 'tmp/desktop/app', src: '**', expand: true }] } }, deb: { linux64: { options: { tmpPath: 'tmp/desktop/', package: { name: 'keeweb-desktop', version: pkg.version, description: pkg.description, author: pkg.author, homepage: pkg.homepage, rev: function() { return grunt.config.get('gitinfo.local.branch.current.shortSHA'); } }, info: { arch: 'amd64', targetDir: 'tmp/desktop', appName: 'KeeWeb', scripts: { postinst: 'package/deb/scripts/postinst' } } }, files: [ { cwd: 'package/deb/usr', src: '**', dest: '/usr', expand: true, nonull: true }, { cwd: 'tmp/desktop/KeeWeb-linux-x64/', src: '**', dest: '/opt/keeweb-desktop', expand: true, nonull: true }, { src: 'graphics/128x128.png', dest: '/usr/share/icons/hicolor/128x128/apps/keeweb.png', nonull: true }] } }, 'sign-archive': { 'desktop_update': { options: { file: 'dist/desktop/UpdateDesktop.zip', signature: zipCommentPlaceholder, privateKey: 'keys/private-key.pem' } } }, 'validate-desktop-update': { desktop: { options: { file: 'dist/desktop/UpdateDesktop.zip', expected: ['main.js', 'app.js', 'index.html', 'package.json', 'node_modules/node-stream-zip/node_stream_zip.js'], publicKey: 'app/resources/public-key.pem' } } }, 'sign-html': { 'app': { options: { file: 'dist/index.html', privateKey: 'keys/private-key.pem' } } } }); grunt.registerTask('default', [ 'gitinfo', 'bower-install-simple', 'clean', 'jshint', 'copy:html', 'copy:favicon', 'copy:touchicon', 'copy:fonts', 'webpack', 'uglify', 'sass', 'postcss', 'inline', 'htmlmin', 'string-replace:manifest_html', 'string-replace:manifest', 'sign-html' ]); grunt.registerTask('desktop', [ 'default', 'gitinfo', 'clean:desktop_tmp', 'clean:desktop_dist', 'copy:desktop_app_content', 'string-replace:desktop_html', 'compress:desktop_update', 'sign-archive:desktop_update', 'validate-desktop-update', 'electron', 'electron-builder:osx', 'copy:desktop_windows_helper', 'electron-builder:win', 'compress:linux64', 'compress:linux32', 'deb:linux64', 'copy:desktop_osx', 'copy:desktop_win', 'copy:desktop_linux_x64', 'copy:desktop_linux_ia32', 'copy:desktop_linux_deb_x64', 'clean:desktop_tmp' ]); };