Updates
This commit is contained in:
+46
-16
@@ -87,30 +87,54 @@ function bareOsEmitRaw(ctx, chunk) {
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} raw
|
||||
* @param {number} curLen
|
||||
* @returns {number | null}
|
||||
*/
|
||||
function resolveTruncateSize(raw, curLen) {
|
||||
const s = String(raw).trim()
|
||||
if (!s) return null
|
||||
if (/%$/.test(s)) {
|
||||
const inner = s.startsWith('+') || s.startsWith('-') ? s.slice(1) : s
|
||||
const pct = Number.parseFloat(inner.replace(/%$/, ''))
|
||||
if (!Number.isFinite(pct)) return null
|
||||
const delta = Math.floor((curLen * pct) / 100)
|
||||
if (s.startsWith('+')) return Math.max(0, curLen + delta)
|
||||
if (s.startsWith('-')) return Math.max(0, curLen - delta)
|
||||
return Math.max(0, Math.floor((curLen * pct) / 100))
|
||||
}
|
||||
if (s.startsWith('+')) {
|
||||
const n = Number.parseInt(s.slice(1), 10)
|
||||
if (!Number.isFinite(n)) return null
|
||||
return Math.max(0, curLen + n)
|
||||
}
|
||||
if (s.startsWith('-')) {
|
||||
const n = Number.parseInt(s.slice(1), 10)
|
||||
if (!Number.isFinite(n)) return null
|
||||
return Math.max(0, curLen - n)
|
||||
}
|
||||
const abs = Number.parseInt(s, 10)
|
||||
if (!Number.isFinite(abs) || abs < 0) return null
|
||||
return abs
|
||||
}
|
||||
|
||||
async function run(ctx, argv) {
|
||||
let size = null
|
||||
/** @type {string | null} */
|
||||
let sizeSpec = null
|
||||
const paths = []
|
||||
for (let i = 1; i < argv.length; i++) {
|
||||
const a = argv[i]
|
||||
if (a === '-h' || a === '--help') {
|
||||
ctx.console.log(
|
||||
'usage: truncate -s SIZE FILE\nSet file length to SIZE bytes (padded with zeros if growing).'
|
||||
'usage: truncate -s SIZE FILE\n' +
|
||||
'SIZE: bytes, +N, -N, +N%, -N%, or N% (of current length).\n' +
|
||||
'Sets file length (padded with zeros if growing).'
|
||||
)
|
||||
return
|
||||
}
|
||||
if ((a === '-s' || a === '--size') && argv[i + 1]) {
|
||||
const raw = argv[++i]
|
||||
if (raw.startsWith('+') || raw.startsWith('-')) {
|
||||
ctx.console.error('truncate: relative sizes not supported')
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
size = parseInt(raw, 10)
|
||||
if (!Number.isFinite(size) || size < 0) {
|
||||
ctx.console.error('truncate: invalid size')
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
sizeSpec = argv[++i]
|
||||
continue
|
||||
}
|
||||
if (a.startsWith('-')) {
|
||||
@@ -120,7 +144,7 @@ async function run(ctx, argv) {
|
||||
}
|
||||
paths.push(a)
|
||||
}
|
||||
if (size == null || paths.length !== 1) {
|
||||
if (!sizeSpec || paths.length !== 1) {
|
||||
ctx.console.error('usage: truncate -s SIZE FILE')
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
@@ -131,7 +155,13 @@ async function run(ctx, argv) {
|
||||
const b = await ctx.vfs.readFile(file)
|
||||
if (b) cur = b instanceof Uint8Array ? b : new Uint8Array(b)
|
||||
} catch {
|
||||
/* new file */
|
||||
/* new file — relative sizes use curLen 0 */
|
||||
}
|
||||
const size = resolveTruncateSize(sizeSpec, cur.length)
|
||||
if (size == null) {
|
||||
ctx.console.error('truncate: invalid size: ' + sizeSpec)
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
const out = new Uint8Array(size)
|
||||
out.set(cur.subarray(0, Math.min(cur.length, size)))
|
||||
|
||||
Reference in New Issue
Block a user