deploy: v0.12 fix 存档key名

This commit is contained in:
2026-06-24 03:09:02 +00:00
parent 7a08d49fe3
commit e0a5281119
58743 changed files with 7297269 additions and 39505 deletions
+15
View File
@@ -0,0 +1,15 @@
Software License Agreement (ISC License)
Copyright (c) 2016, Matthew Voss
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+251
View File
@@ -0,0 +1,251 @@
// objects and functions for formatting diffs with partial context. see the 'makeHunks()' documentation, below
// for details.
'use strict'
function calcLen (linechanges, ab) {
let len = 0
for (let ci = 0; ci < linechanges.length; ci++) {
switch (linechanges[ci].type) {
case REMOVED:
len += ab[0]
break
case ADDED:
len += ab[1]
break
case UNMODIFIED:
len++
break
default:
throw Error('unknown change type: ' + linechanges[ci].type)
}
}
return len
}
function Hunk (aoff, boff, changes) {
this.changes = changes
this.aoff = aoff
this.boff = boff
this._alen = -1
this._blen = -1
}
Object.defineProperty (Hunk.prototype, 'alen', {
get: function () { return this._alen === -1 ? (this._alen = calcLen(this.changes, [1,0])) : this._alen }
})
Object.defineProperty (Hunk.prototype, 'blen', {
get: function () { return this._blen === -1 ? (this._blen = calcLen(this.changes, [0,1])) : this._blen }
})
Hunk.prototype.unified = function () {
let ret = [this.unifiedHeader()]
this.changes.forEach(function(c) {
ret.push(c.unified())
})
// console.log("expect:\n'" + ret.join("'\n'") + "'") // useful for creating test output
return ret.join('\n')
}
Hunk.prototype.unifiedHeader = function () {
let alen = this.alen === 1 ? '' : ',' + this.alen
let blen = this.blen === 1 ? '' : ',' + this.blen
// empty hunks show zeroith line (prior). hunks with lines show first line number
let afudg = this.alen === 0 ? 0 : 1
let bfudg = this.blen === 0 ? 0 : 1
return '@@ -' + (this.aoff+afudg) + alen + ' +' + (this.boff+bfudg) + blen + ' @@'
}
Hunk.prototype.shorthand = function () {
return this.changes.reduce(function(s,c){ return s + c.type }, '')
}
Hunk.prototype.toString = function () {
return "{" + this.shorthand() + "} " + this.unifiedHeader()
}
const ADDED = '+'
const REMOVED = '-'
const UNMODIFIED = 's'
function type2unified (type) { return type === 's' ? ' ' : type }
// LineChange objects represent a single line of change. Converting diff.diffLine() result array into LineChange
// object array:
//
// 1. simplifies logic that needs work with lines
// 2. separates this extension module from specific dependency on the diff library
function LineChange (type, text) {
this.type = type // ADDED, REMOVED, UNMODIFIED
this.text = text
}
LineChange.prototype.unified = function () {
return type2unified(this.type) + this.text
}
LineChange.prototype.toString = function () { return this.unified() }
// convert a single change from diff.diffLines() into a single line string
// (handy for debugging)
function change2string (c, maxwidth) {
maxwidth = maxwidth || 60
let ret = c.count + ': ' + type2unified(c.type)
let lim = Math.min(maxwidth - ret.length, c.value.length-1) // remove last newline
let txt = c.value.substring(0,lim).replace(/\n/g, ',') + (c.value.length > (lim+1) ? '...' : '')
return ret + txt
}
// Convert a change as returned from diff.diffLines() into an LineChange objects with offset information.
//
// change - object returned from diff.diffLines() containing one or more lines of change info
// select - (int)
// positive, return up to this many lines from the start of change.
// negative, return up to this many lines from the end of the change.
// zero, return empty array
// undefined, return all lines
//
function lineChanges (change, select) {
// debug:
// console.log(change2str(change) + (select === undefined ? '' : ' (select:' + select + ')'))
if (select === 0) {
return []
}
let lines = []
let v = change.value
if (select === undefined) {
lines = v.split('\n')
if (!lines[lines.length-1]) { lines.pop() } // remove terminating new line
} else if(select > 0) {
let i = nthIndexOf(v, '\n', 0, select, false)
lines = v.substring(0,i).split('\n')
} else {
let len = v[v.length-1] === '\n' ? v.length-1 : v.length
let i = nthIndexOf(v, '\n', len-1, -select, true)
lines = v.substring(i+1, len).split('\n')
}
return lines.map(function (line){ return new LineChange(change.type, line)})
}
// convert a list of changes into a shorthand notation like 'ss--+++ss-+ss'
function changes2shorthand (changes) {
return '{' + changes.reduce(function (s,c) { for(let i=0; i< c.count; i++) s += c.type; return s }, '') + '}'
}
// concat-in-place, a -> b and return b
function concatTo (a, b) {
Array.prototype.push.apply(b, a)
return b
}
// Make Hunk objects from changes as returned from a call to unidiff.lineChanges(). Hunks are collections
// of continuous line changes, therefore every hunk after the first marks a gap
// where unmodified context lines are skipped.
//
// let 's' represent an unmodifed line 'same'
// '-' represent a removed line
// '+' represent an added line
//
// then hunks with a context of 2 could might like this:
//
// hunk hunk hunk
// ___|____ ___|__ ___|___
// | | | | | |
// sssss----++ssssssssssssss-ss--sssssssss+++++ssssssssss
//
// or this:
//
// hunk hunk hunk
// ___|____ ______|_______ ____|___
// | | | | | |
// ++++++++sssssssss+++ssss---++sssssss--++++++
//
// notice that with a context of 2, series of 4 or fewer unmodified lines are included in the same hunk.
//
// basic algo with context of 3, for illustration:
//
// 0. loop (over each block change)
// modified block:
// add all modified lines, continue loop 0
//
// unmodified block:
// first hunk: collect tail portion, continue
// subsequent hunks: get head portion, and tail (iff there are more changes)
// head + tail <= 6 ?
// add all to current hunk, continue loop 0
// head + tail > 6 ?
// finish hunk with head portion
// start new hunk with tail portion (iff there are more changes), continue loop 0
//
function makeHunks (changes, precontext, postcontext) {
//console.log('--------\nmakeHunks(' + [changes2shorthand(changes), precontext, postcontext].join(', ') + ')')
let ret = [] // completed hunks to return
let lchanges = [] // accumulated line changes (continous/no-gap) to put into next hunk
let lskipped = 0 // skipped context to take into account in next hunk line numbers
function finishHunk () {
if (lchanges.length) {
let aoff = lskipped, boff = lskipped
if (ret.length) {
let prev = ret[ret.length-1]
aoff += prev.aoff + prev.alen
boff += prev.boff + prev.blen
}
// add hunk and reset state
ret.push(new Hunk(aoff, boff, lchanges))
lchanges = []
lskipped = 0
}
// else keep state (lskipped) and continue
}
for (let ci=0; ci < changes.length; ci++) {
let change = changes[ci]
if (change.type === UNMODIFIED) {
// add context
let ctx_after = ci > 0 ? postcontext : 0 // context lines following previous change
let ctx_before = ci < changes.length - 1 ? precontext : 0 // context lines preceding next change (iff there are more changes)
let skip = Math.max(change.count - (ctx_after + ctx_before), 0)
if (skip > 0) {
concatTo(lineChanges(change, ctx_after), lchanges) // finish up previous hunk
finishHunk()
concatTo(lineChanges(change, -ctx_before), lchanges)
lskipped = skip // remember skipped for next hunk
} else {
concatTo(lineChanges(change), lchanges) // add all context
}
} else {
concatTo(lineChanges(change), lchanges) // add all modifications
}
}
finishHunk()
//console.log(ret.map(function(h){ return h.toString() }).join('\n'))
return ret
}
// no safty checks. caller knows that there are at least n occurances of v in s to be found.
// reverse will search from high to low using lastIndexOf().
function nthIndexOf (s, v, from, n, reverse) {
let d = reverse ? -1 : 1
from -= d
for (let c=0; c<n; c++) {
from = reverse ? s.lastIndexOf(v, from + d) : s.indexOf(v, from + d)
}
return from
}
// for testing and debugging
exports.hunk = function (aoff, boff, lchanges) { return new Hunk(aoff, boff, lchanges) }
exports.linechange = function (type, text) { return new LineChange(type, text)}
exports.lineChanges = lineChanges
exports.change2string = change2string
exports.changes2shorthand = changes2shorthand
exports.nthIndexOf = nthIndexOf
// main API
exports.makeHunks = makeHunks
exports.ADDED = ADDED
exports.REMOVED = REMOVED
exports.UNMODIFIED = UNMODIFIED
+108
View File
@@ -0,0 +1,108 @@
'use strict'
let jdiff = require('diff')
let hunk = require('./hunk')
// return a change type code for the change (returned from diff.diffLines())
function changeType (change) {
if (change.added) {
return hunk.ADDED
} else if (change.removed) {
return hunk.REMOVED
} else {
return hunk.UNMODIFIED
}
}
// Given changes from a call to diff.diffLines(), assign each change a type code and
// check that no two of same type occur in a row
function checkAndAssignTypes (changes) {
if (changes.length === 0) { return [] }
changes[0].type = changeType(changes[0])
return changes.reduce(function (a, b, i) {
b.type = changeType(b)
if (a.type === b.type) {
throw Error('repeating change types are not handled: ' + a.type + ' (at ' + (i-1) + ' and ' + i + ')')
}
return b
})
}
// convert an array of results from diff.diffLines() into text in unified diff format.
// return empty string if there are no changes.
function formatLines (changes, opt) {
checkAndAssignTypes(changes)
opt = opt || {}
opt.aname = opt.aname || 'a'
opt.bname = opt.bname || 'b'
let context = (opt.context || opt.context === 0) ? opt.context : 0
opt.pre_context = (opt.pre_context || opt.pre_context === 0) ? opt.pre_context : context
opt.post_context = (opt.post_context || opt.post_context === 0) ? opt.post_context : context
let hunks = hunk.makeHunks(changes, opt.pre_context, opt.post_context)
if (hunks.length) {
let ret = []
ret.push('--- ' + opt.aname)
ret.push('+++ ' + opt.bname)
hunks.forEach(function (h) {
ret.push(h.unified())
})
return ret.join('\n')
} else {
return ''
}
}
// same as jsdiff.diffLines, but returns empty array when there are no changes (instead of an array with a single
// unmodified change object)
function diffLines (a, b, cb) {
a = Array.isArray(a) ? a.join('\n') + '\n' : a
b = Array.isArray(b) ? b.join('\n') + '\n' : b
let ret = jdiff.diffLines(a, b, cb)
if (ret.length === 1 && !ret[0].added && !ret[0].removed) {
return []
} else {
return ret
}
}
function diffAsText (a, b, opt) {
return formatLines(diffLines(a, b), opt)
}
// handy assertion function that asserts that two arrays or two multi-line strings are the same and reports
// differences to console.log in unified format if there are differences.
//
// actual - array or multi-line string to compare
// expected - array or multi-line string to compare
// label - label to clarify output if there are differences
// okFn - function like tape.ok that takes two arguments:
// expression - true if OK, false if failed test
// msg - a one-line message that prints upon failure
// logFn - function to call with diff output when there are differences (defaults to console.log)
//
function assertEqual (actual, expected, okFn, label, logFn) {
logFn = logFn || console.log
okFn = okFn.ok || okFn
let diff = diffAsText(actual, expected, {context: 3, aname: label + " (actual)", bname: label + ' (expected)'})
okFn(!diff, label)
if (diff) {
diff.split('\n').forEach(function (line) {
logFn(' ' + line)
})
}
}
exports.assertEqual = assertEqual
exports.diffAsText = diffAsText
exports.formatLines = formatLines
exports.diffLines = diffLines
Object.keys(jdiff).forEach(function (k) {
if (!exports[k]) {
exports[k] = jdiff[k]
}
})
+30
View File
@@ -0,0 +1,30 @@
{
"name": "unidiff",
"version": "1.0.4",
"description": "diff with unified diff format handling",
"main": "index.js",
"dependencies": {
"diff": "^5.1.0"
},
"devDependencies": {
"tape": "^5.6.3",
"test-kit": "^2.8.7"
},
"repository": {
"type": "git",
"url": "https://github.com/mvoss9000/unidiff.git"
},
"scripts": {
"test": "tape test.js",
"cov": "tap --coverage-report=html test.js"
},
"files": [
"index.js",
"hunk.js"
],
"keywords": [
"example"
],
"author": "Matthew Voss",
"license": "MIT"
}
+64
View File
@@ -0,0 +1,64 @@
# unidiff #
unidiff adds support for creating [unified diff format](https://en.wikipedia.org/wiki/Diff_utility#Unified_format)
to [jsdiff](https://github.com/kpdecker/jsdiff)
The following snippet:
var unidiff = require('unidiff')
var diff = unidiff.diffLines(
'a quick\nbrown\nfox\njumped\nover\nthe\nlazy\ndog\n',
'a quick\nbrown\ncat\njumped\nat\nthe\nnot-so-lazy\nfox\n'
)
console.log(unidiff.formatLines(diff), {context: 2})
Produces this [unified diff](https://en.wikipedia.org/wiki/Diff_utility#Unified_format) output:
--- a
+++ b
@@ -1,8 +1,8 @@
a quick
brown
-fox
+cat
jumped
-over
+at
the
-lazy
-dog
+not-so-lazy
+fox
This same output can be achieved more concisely using the diffAsText function:
console.log(require('unidiff').diffAsText(
'a quick\nbrown\nfox\njumped\nover\nthe\nlazy\ndog\n',
'a quick\nbrown\ncat\njumped\nat\nthe\nnot-so-lazy\nfox\n'
))
Both formatLines() and diffAsText() take a format options parameter with the
following options.
{
aname: file name for input a, defaults to 'a'
bname: file name for input b, defaults to 'b'
pre_context: write up to this many unmodified lines before each change
post_context: write up to this many unmodified lines after each change
context: default values for pre_context and post_context (specify both in one setting)
(context defaults to 3 when nothing is specified)
format: format of output text. currently only "unified" is supported
}
## Differences From JSDiff ##
All js-diff functions are also availalbe in unidiff, with a couple minor changes:
* unidiff.diffLines() and unidiff.diffAsText() accept arrays of strings as well as strings with new lines for input.
* unidiff.diffLines() returns an empty array when there are no differences instead of an array with a single unmodified change.
## Useful features to add to unidiff ##
* implement parsing of unified format to convert text output into patches.