grunt-incrediff
Advanced tools
Comparing version 3.3.0 to 3.3.1
{ | ||
"name": "grunt-incrediff", | ||
"version": "3.3.0", | ||
"version": "3.3.1", | ||
"dependencies": { | ||
@@ -5,0 +5,0 @@ "async": "^0.6.2", |
@@ -10,6 +10,9 @@ /* | ||
'use strict'; | ||
/* http请求,下载历史版本文件 */ | ||
var request = require('request'), | ||
async = require('async'), | ||
/* 显示差异文件大小 */ | ||
maxmin = require('maxmin'), | ||
chalk = require('chalk'), | ||
/* 差异算法库 */ | ||
diff = require('./lib/newChunk'); | ||
@@ -19,37 +22,60 @@ | ||
function responseHandler(dest, done, container, _name, url, cnt, all) { | ||
return function (error, response, body) { | ||
response = response || { statusCode: 0 }; | ||
/** | ||
* @description http响应的回调,为了获取dest, done, container, _name, url, cnt, all,而产生的闭包,如果直接写在里面太繁琐了 | ||
* @param {object} done async异步回调对象 | ||
* @param {object} container 统一存储下载下来的字符串 | ||
* @param {string} _name 存储的名称 | ||
* @param {string} url 下载路径,显示用 | ||
* @param {string} cnt 下载顺序,显示用 | ||
* @param {string} all 下载总数,显示用 | ||
* @return {Function} 返回闭包函数 | ||
*/ | ||
function responseHandler(dest, done, container, _name, url, cnt, all) { | ||
return function (error, response, body) { | ||
response = response || { statusCode: 0 }; | ||
if (error) { | ||
return done(error); | ||
} else if ( (response.statusCode < 200 || response.statusCode > 399)) { | ||
grunt.log.warn( 'Download ' + chalk.grey(url) + chalk.red(' Failed ' + response.statusCode)); | ||
return done(response.statusCode); | ||
} | ||
if (error) { | ||
return done(error); | ||
} else if ( (response.statusCode < 200 || response.statusCode > 399)) { | ||
grunt.log.warn( 'Download ' + chalk.grey(url) + chalk.red(' Failed ' + response.statusCode)); | ||
return done(response.statusCode); | ||
} | ||
container[ _name ] = body; | ||
grunt.log.warn( 'Download ' + chalk.grey(url) + chalk.green(' success ') + (++cnt.cnt + '/' + all) ); | ||
done(); | ||
}; | ||
} | ||
container[ _name ] = body; | ||
grunt.log.warn( 'Download ' + chalk.grey(url) + chalk.green(' success ') + (++cnt.cnt + '/' + all) ); | ||
done(); | ||
}; | ||
} | ||
function strFormat( source, kvd ) { | ||
if ( typeof source !== 'string' ) { return ''; } | ||
for ( var key in kvd ) { | ||
if ( kvd.hasOwnProperty( key ) ) { | ||
source = source.replace( new RegExp('%{'+ key +'}','g') , kvd[ key ] ); | ||
/** | ||
* @description 字符串处理格式化,按照指定的 %{XXX} 进行替换 | ||
* @param {string} source 源格式串 | ||
* @param {object} kvd 替换数据 | ||
* @return {string} 结果字串 | ||
*/ | ||
function strFormat( source, kvd ) { | ||
if ( typeof source !== 'string' ) { return ''; } | ||
for ( var key in kvd ) { | ||
if ( kvd.hasOwnProperty( key ) ) { | ||
source = source.replace( new RegExp('%{'+ key +'}','g') , kvd[ key ] ); | ||
} | ||
} | ||
return source; | ||
} | ||
return source; | ||
} | ||
grunt.registerMultiTask('incrediff', 'auto-generate tool of incremental difference of static files', function() { | ||
var options = this.options({ | ||
/* v[0] 为最新版本,v[1]为次新版本,之后类推 */ | ||
version: [], | ||
/* 默认差异分块大小,如果diff中指定则使用diff中的 */ | ||
chunkSize: 20, | ||
/* TRUE时只生成v[1]->v[0]的差异, FALSE生成v[>=1]->v[0]的差异 */ | ||
isSingleDiff: true, | ||
/* 是否对公共str采取hash存储,建议FALSE */ | ||
isHashStr: false, | ||
/* 算法,可选'chunk','chunklcs' */ | ||
algorithm: 'chunk', | ||
sourceFormat: '%{CDNURL}/%{NEWVERSION}/%{FILEPATH}', | ||
/* 从CDN上获取的旧版本文件的url格式 */ | ||
sourceFormat: '%{CDNURL}/%{OLDVERSION}/%{FILEPATH}', | ||
/* 产生新的差异的路径格式,前面默认会有CDN// */ | ||
format: '%{FILEPATH}_%{OLDVERSION}_%{NEWVERSION}.js' //支持FILEPATH,OLDVERSION,NEWVERSION三个替换 | ||
@@ -79,2 +105,3 @@ }); | ||
/* 各种路径后缀修正 */ | ||
options.dest = options.dest.replace(/\/$/,'') + '/'; | ||
@@ -89,8 +116,11 @@ options.newsrc = options.newsrc.replace(/\/$/,'') + '/'; | ||
/* 设置需要差生差异的各版本 */ | ||
_versions = options.isSingleDiff ? [ options.version[ 0 ], options.version[ 1 ] || undefined ] : options.version; | ||
if ( typeof _versions[ _versions.length -1 ] === 'undefined' ) { | ||
_versions.pop(); | ||
} | ||
_versions = _versions.concat( [''] ); | ||
//需要生成差异的版本数组,最后有一个 ''元素 | ||
/* 如果options.versions中只写了1个元素(最新),会进入这里,自动填充一个空元素 */ | ||
if ( typeof _versions[ _versions.length -1 ] === 'undefined' ) { | ||
_versions.pop(); | ||
} | ||
_versions = _versions.concat( [''] ); | ||
/* 需要产生差异的src源文件数组,去掉开头的斜杠 */ | ||
src = this.files[0].orig.src; | ||
@@ -114,5 +144,7 @@ src = src.map(function (data) { | ||
var reqQueue = []; | ||
/* 对每个列出的非最新版本 for-i */ | ||
for ( i = 1, len = _versions.length; i < len ; i ++) { | ||
var curVersion = _versions[ i ]; | ||
if ( curVersion !== '' ) { | ||
/* 对每个src源数据 */ | ||
for ( j = 0, lenJ = src.length; j < lenJ ; j++ ) { | ||
@@ -122,4 +154,4 @@ var oldUrl = strFormat( options.sourceFormat, { | ||
FILEPATH: src[ j ], | ||
OLDVERSION: '', | ||
NEWVERSION: curVersion | ||
OLDVERSION: curVersion, | ||
NEWVERSION: _versions[0] | ||
} ); | ||
@@ -135,3 +167,3 @@ //options.cdnUrl + curVersion + '/' + src[ j ]; | ||
var _count = {cnt:0}; | ||
async.each(reqQueue, | ||
async.each(reqQueue, | ||
function (file, next) { | ||
@@ -162,6 +194,7 @@ var r, callback; | ||
if ( curVersion === '' ) { | ||
/* 全量数据 */ | ||
generateFullData( newContent[ j ], src[ j ] ); | ||
} | ||
else { | ||
//Http下载 | ||
/* 差异数据 */ | ||
var oldContent = reqContent[ src[ j ] + '?' + curVersion ]; | ||
@@ -185,3 +218,3 @@ generateDiffData( newContent[ j ], oldContent, curVersion, src[ j ] ); | ||
if ( diff.merge(olddata, options.chunkSize, content) !== newdata ) { | ||
grunt.log.error('Diff Building ERROR: ' + path + ' ' + oldver +'->' + _versions[0]); | ||
grunt.log.error('差异数据计算出错,可能是算法有问题,请修改algorithm配置项: ' + path + ' ' + oldver +'->' + _versions[0]); | ||
} | ||
@@ -188,0 +221,0 @@ var writeContent = JSON.stringify( content ) + '/*"""*/'; |
@@ -10,3 +10,6 @@ var chunkFunc = require('./newChunk'); | ||
var ret = ChunkLCS( 100, 0, o, n ); | ||
return {diff: ret, chunkSize: 1} | ||
var diffSequence = {'hash':[],'diff':[], chunkSize: 1}; | ||
ret = miniLcsBlock(ret, o); | ||
concatDiffBlock(ret, diffSequence, true); | ||
return diffSequence; | ||
} | ||
@@ -191,3 +194,43 @@ | ||
//把lcs之后长度小于4的块都处理成字符 | ||
function miniLcsBlock(diff, o) { | ||
var newDiff = []; | ||
var i, len, d; | ||
for( i=0, len=diff.length; i<len; i++ ) { | ||
d = diff[i]; | ||
if ( typeof d === 'string' ) { | ||
newDiff.push( d ); | ||
} | ||
else if ( d.length === 2 && d[1] <= 8 ) { | ||
newDiff.push( o.substr(d[0], d[1]) ); | ||
} | ||
else { | ||
newDiff.push( d ); | ||
} | ||
} | ||
return newDiff; | ||
} | ||
//把diffHash的相邻块合并 | ||
function concatDiffBlock(diff, seq, noIndex) { | ||
var len = diff.length, | ||
d, | ||
preStr = '', | ||
i; | ||
for ( i = 0 ; i < len ; i ++) { | ||
d = diff[i]; | ||
if ( typeof d === 'string') { | ||
preStr += d; | ||
} | ||
else { | ||
if ( preStr.length ) { | ||
seq.diff.push( preStr ); | ||
preStr = ''; | ||
} | ||
seq.diff.push( d ); | ||
} | ||
} | ||
} | ||
function mergeDiff(o, chunkSize, diff) { | ||
@@ -226,3 +269,3 @@ var len = diff.diff.length, | ||
// console.log(et-bt, JSON.stringify(result).length) | ||
// console.log( newstr=== mergeDiff(origin,result) ) | ||
// console.log( newstr=== mergeDiff(origin,1,result) ) | ||
36755
835