UNPKG

generator-clam

Version:
472 lines (423 loc) 11.5 kB
var path = require('path'), fs = require('fs'), os = require('os'), exec = require('child_process').exec; module.exports = function (grunt) { var file = grunt.file; var task = grunt.task; var pathname = path.basename(__dirname); var files = doWalk('./src/'); // files.js 存储项目中的所有js文件 // file.css 存储项目中的所有css文件 // file.less 存储项目中所有less文件 // ======================= 配置每个任务 ========================== grunt.initConfig({ pkg: grunt.file.readJSON('abc.json'), // 配置默认分支 currentBranch: 'master', /** * 对页面进行清理 */ clean: { build: { src: 'build/*' } }, /** * 将src目录中的KISSY文件做编译打包,仅做合并,源文件不需要指定名称 * KISSY.add(function(S){}); * * @link https://github.com/daxingplay/grunt-kmc * * 如果需要只生成依赖关系表,不做合并,源文件必须指定名称,比如 * KISSY.add('group/project/file',function(S){}); * 并在kmc.options中增加两个参数: * depFilePath: 'build/mods.js', * comboOnly: true, */ kmc: { options: { packages: [ { name: '<%= pkg.name %>', path: '../', charset:'utf-8' } ], map: [['<%= pkg.name %>/src/', '<%= pkg.name %>/']] }, main: { files: [ { // 这里指定项目根目录下所有文件为入口文件,自定义入口请自行添加 expand: true, cwd: 'src/', src: [ '**/*.js', '!Gruntfile.js'], dest: 'build/' } ] } // 若有新任务,请自行添加 /* simple-example: { files: [ { src: "a.js", dest: "build/index.js" } ] } */ }, /** * 将css文件中引用的本地图片上传CDN并替换url */ mytps: { options: { argv: "--inplace" }, all: [ 'src/**/*.css'] }, /** * CSS-Combo * combo项目中所有css,通过@import "other.css"; 来处理依赖关系 */ css_combo: { options: { paths: './' }, main: { files: [ { expand: true, cwd:'src', src: ['**/*.css'], dest: 'build/', ext: '.css' } ] } }, /** * YUIDoc * 对build目录中的js文件生成文档,放入doc/中 */ /* yuidoc: { compile: { name: 'generator-clam', description: 'A Clam generator for Yeoman', options: { paths: 'build/', outdir: 'doc/' } } }, */ /** * 将LESS编译为CSS * @link https://github.com/gruntjs/grunt-contrib-less */ less: { options: { paths: './' }, main: { files: [ { expand: true, cwd:'src/', src: ['**/*.less'], dest: 'build/', ext: '.css' } ] } }, /** * 对JS文件进行压缩 * @link https://github.com/gruntjs/grunt-contrib-uglify */ uglify: { options: { banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd HH:MM:ss") %> */\n', beautify: { ascii_only: true } }, main: { files: [ { expand: true, cwd: 'build/', src: ['**/*.js', '!*-min.js'], dest: 'build/', ext: '-min.js' } ] } }, /** * 对CSS 文件进行压缩 * @link https://github.com/gruntjs/grunt-contrib-cssmin */ cssmin: { main: { files: [ { expand: true, cwd: 'build/', src: ['**/*.css', '!*-min.css'], dest: 'build/', ext: '-min.css' } ] } }, watch: { 'js': { files: [ 'src/**/*.js' ], tasks: [ 'kmc', 'uglify' ] }, 'css':{ files: [ 'src/**/*.css' ], tasks: [ 'copy','cssmin' ] }, 'less': { files: [ 'src/**/*.less'], tasks: ['less', 'cssmin'] } }, /** * 发布命令。 */ exec: { tag: { command: 'git tag publish/<%= currentBranch %>' }, publish: { command: 'git push origin publish/<%= currentBranch %>:publish/<%= currentBranch %>' }, commit:{ command: function(msg){ var command = 'git commit -m "' + grunt.config.get('currentBranch') + ' - ' + grunt.template.today("yyyy-mm-dd HH:MM:ss") + ' ' + msg + '"'; return command; } }, add: { command: 'git add .' }, prepub: { command: 'git push origin daily/<%= currentBranch %>:daily/<%= currentBranch %>' }, grunt_publish: { command: 'grunt default:publish' }, grunt_prepub:{ command: function(msg){ return 'grunt default:prepub:' + msg; } }, new_branch: { command: 'git checkout -b daily/<%= currentBranch %>' } }, // 拷贝文件 copy : { main: { files:[ { // src: files.js, expand:true, src: ['**/*.js','**/*.css'], dest: 'build/', cwd:'src/', filter: 'isFile' } ] } } // 合并文件 /* concat: { dist: { src: ['from.css'], dest: 'build/to.css' } } */ }); // ======================= 载入使用到的通过NPM安装的模块 ========================== grunt.loadNpmTasks('grunt-contrib-clean'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-css-combo'); grunt.loadNpmTasks('grunt-contrib-less'); grunt.loadNpmTasks('grunt-contrib-cssmin'); grunt.loadNpmTasks('grunt-contrib-watch'); //grunt.loadNpmTasks('grunt-kissy-template'); grunt.loadNpmTasks('grunt-kmc'); //grunt.loadNpmTasks('grunt-contrib-connect'); grunt.loadNpmTasks('grunt-exec'); grunt.loadNpmTasks('grunt-contrib-copy'); //grunt.loadNpmTasks('grunt-contrib-concat'); //grunt.loadNpmTasks('grunt-contrib-yuidoc'); grunt.loadNpmTasks('grunt-mytps'); // ======================= 注册Grunt 各个操作 ========================== /** * 正式发布 */ grunt.registerTask('publish', 'clam publish...', function() { task.run('exec:grunt_publish'); }); grunt.registerTask('pub', 'clam publish...', function() { task.run('exec:grunt_publish'); }); /** * 预发布 */ grunt.registerTask('prepub', 'clam pre publish...', function(msg) { task.run('exec:grunt_prepub:' + (msg || '')); }); /** * 监听修改 */ grunt.registerTask('listen', 'clam watch ...', function() { task.run('watch'); }); /* * 获取当前库的信息 **/ grunt.registerTask('info', 'clam info...', function() { var abcJSON = {}; try { abcJSON = require(path.resolve(process.cwd(), 'abc.json')); console.log('\n'+abcJSON.repository.url); } catch (e){ console.log('未找到abc.json'); } }); /* * 获取当前最大版本号,并创建新分支 **/ grunt.registerTask('newbranch', 'clam newBranch...', function(type, msg) { var done = this.async(); exec('git branch -a;git tag', function(err, stdout, stderr, cb) { var r = getBiggestVersion(stdout.match(/\d+\.\d+\.\d+/ig)); if(!r){ r = '0.0.1'; } else { r[2]++; r = r.join('.'); } grunt.log.write(('新分支:daily/' + r).green); grunt.config.set('currentBranch', r); task.run(['exec:new_branch']); done(); }); }); // ======================= 注册Grunt主流程 ========================== return grunt.registerTask('default', 'clam running ...', function(type, msg) { var done = this.async(); // 获取当前分支 exec('git branch', function(err, stdout, stderr, cb) { var reg = /\*\s+daily\/(\S+)/, match = stdout.match(reg); if (!match) { grunt.log.error('当前分支为 master 或者名字不合法(daily/x.y.z),请切换到daily分支'.red); grunt.log.error('创建新daily分支:grunt newbranch'.yellow); return; } grunt.log.write(('当前分支:' + match[1]).green); grunt.config.set('currentBranch', match[1]); done(); }); // 构建和发布任务 if (!type) { task.run(['clean:build', 'mytps','copy', 'kmc', 'uglify', 'css_combo' ,'less',, 'cssmin'/*'concat','yuidoc', 'copy', 'clean:mobile'*/]); } else if ('publish' === type || 'pub' === type) { task.run(['exec:tag', 'exec:publish']); } else if ('prepub' === type) { task.run(['exec:add','exec:commit:' + msg]); task.run(['exec:prepub']); } }); // ======================= 辅助函数 ========================== // 遍历当前目录的文件 function walk(uri, files) { var stat = fs.lstatSync(uri); if (stat.isFile() && !/(build|node_modules|demo|doc|\.git|\.+)[\\|\/]/i.test(uri) && !/grunt.+/i.test(uri)) { switch (path.extname(uri)) { case '.css': files.css.push(uri); break; case '.js': files.js.push(uri); break; case '.less': files.less.push(uri); break; case '.scss': files.scss.push(uri); break; default: files.other.push(uri); } } if (stat.isDirectory()) { fs.readdirSync(uri).forEach(function(part) { walk(path.join(uri, part), files); }); } } // 得到文件结构的数据结构 function doWalk(rootDir) { var files = { css: [], less: [], scss: [], js: [], other: [] // 暂时没用 }; walk(rootDir, files); return files; } function getBiggestVersion(A){ var a = []; var b = []; var t = []; var r = []; if(!A){ return [0,0,0]; } for(var i= 0;i< A.length;i++){ if(A[i].match(/^\d+\.\d+\.\d+$/)){ var sp = A[i].split('.'); a.push([ Number(sp[0]),Number(sp[1]),Number(sp[2]) ]); } } var r = findMax(findMax(findMax(a,0),1),2); return r[0]; } // a:二维数组,index,比较第几个 // return:返回保留比较后的结果组成的二维数组 function findMax(a,index){ var t = []; var b = []; var r = []; for(var i = 0;i<a.length;i++){ t.push(Number(a[i][index])); } var max = Math.max.apply(this,t); for(var i = 0;i<a.length;i++){ if(a[i][index] === max){ b.push(i); } } for(var i = 0;i<b.length;i++){ r.push(a[b[i]]); } return r; } };