1path = require 'path' 2async = require 'async' 3fs = require 'fs' 4minimatch = require 'minimatch' 5less = require 'less' 6vm = require 'vm' 7shelljs = require 'shelljs' 8ejs = require 'ejs' 9uglify = require 'uglify-js' 10sass = require 'node-sass' 11 12compressCss = (source, callback) -> 13 parser = new less.Parser optimization: 2 14 parser.parse source, (err, tree) -> 15 callback err, tree.toCSS(compress: true) 16 17compressJs = (source, callback) -> 18 {code, map} = uglify.minify source, fromString: true 19 callback null, code 20 21compileSass = (file, callback) -> 22 data = readFile file 23 sass.render data, callback, include_paths: [sourceSassDir], output_style: null 24 25isDirectory = (dir) -> 26 fs.existsSync(dir) and fs.statSync(dir).isDirectory() 27 28readFile = (filename) -> 29 fs.readFileSync filename, 'utf8' 30 31writeFile = (filename, content) -> 32 fs.writeFileSync filename, content, 'utf8' 33 34findFilesIn = (dir, pattern) -> 35 shelljs.find(dir) 36 .filter (file) -> 37 minimatch file, pattern, matchBase: true 38 .filter (file) -> 39 not isDirectory file 40 41loadFilesIntoVariables = (dir) -> 42 result = {} 43 44 for file in findFilesIn dir, '*.*' 45 varName = path.basename(file, path.extname(file)) 46 result[varName] = readFile file 47 48 result 49 50baseDir = __dirname 51sourceDir = path.resolve baseDir, '..', 'src' 52outputDir = path.resolve baseDir, '..', 'pkg' 53componentsDir = path.resolve baseDir, '..', 'components' 54includesDir = path.resolve baseDir, 'includes' 55sourceJsDir = path.resolve sourceDir, 'js' 56sourceSassDir = path.resolve sourceDir, 'sass' 57outputJsDir = path.resolve outputDir, 'scripts' 58outputCssDir = path.resolve outputDir, 'styles' 59 60variables = loadFilesIntoVariables includesDir 61variables.version = JSON.parse(readFile path.resolve baseDir, '../package.json').version 62variables.date = new Date().toUTCString() 63variables.about = variables.about.replace(/\r|\n|\t/g, "").replace(/"/g, "\\\"") 64 65module.exports = (grunt) -> 66 grunt.registerTask 'build', 'clean compile_sass copy_misc_files build_core pack validate add_header'.split(/\s/g) 67 68 grunt.registerTask 'clean', 'Cleans the build folder', -> 69 shelljs.rm '-fr', outputDir 70 shelljs.mkdir '-p', outputJsDir, outputCssDir 71 72 grunt.registerTask 'compile_sass', -> 73 files = findFilesIn sourceSassDir, "**/*.scss" 74 75 jobs = files.map (sassFile) -> 76 (done) -> 77 cssFile = path.join(outputCssDir, path.basename sassFile).replace /\.scss$/, '.css' 78 79 # skip the theme template 80 return done() if /theme_template/.test sassFile 81 82 compileSass sassFile, (err, css) -> 83 writeFile cssFile, css 84 done() 85 86 async.parallel jobs, @async() 87 88 grunt.registerTask 'copy_misc_files', -> 89 shelljs.cp "#{baseDir}/index.html", outputDir 90 shelljs.cp "#{sourceJsDir}/sh*.js", outputJsDir 91 92 grunt.registerTask 'build_core', -> 93 variables.about = ejs.render variables.about, variables 94 corePath = path.join outputJsDir, 'shCore.js' 95 xregexpSource = readFile path.join(componentsDir, 'xregexp', 'src', 'xregexp.js') 96 coreSource = ejs.render readFile(corePath), variables 97 98 writeFile corePath, xregexpSource + coreSource 99 100 grunt.registerTask 'pack', -> 101 addMinExt = (filename) -> 102 ext = path.extname filename 103 filename = path.basename filename, ext 104 "#{filename}.min#{ext}" 105 106 # this could be changed to minify all JS files, not just core 107 findFilesIn(outputJsDir, '**/shCore.js').forEach (file) -> 108 compressJs readFile(file), (err, source) -> 109 writeFile path.join(outputJsDir, path.basename(addMinExt file)), source 110 111 findFilesIn(outputCssDir, '**/*.css').forEach (file) -> 112 compressCss readFile(file), (err, source) -> 113 writeFile file, source 114 115 grunt.registerTask 'add_header', -> 116 files = findFilesIn(outputDir, "**/*.js").concat(findFilesIn(outputDir, '**.css')) 117 header = ejs.render variables.header, variables 118 119 files.forEach (file) -> 120 writeFile file, header + readFile file 121 122 grunt.registerTask 'validate', -> 123 context = {} 124 coreFile = path.join(outputJsDir, 'shCore.js') 125 vm.runInNewContext readFile(coreFile), context, coreFile 126 127 findFilesIn(outputDir, "**.js").forEach (file) -> 128 return if /shCore/.test(file) 129 vm.runInNewContext readFile(file), context, file 130 131