🚀 Add xdelta3 support
This commit is contained in:
parent
b5037c2a71
commit
6bb8ccea22
2 changed files with 52 additions and 3 deletions
|
@ -11,6 +11,7 @@ import readSsnFile from './reader/readSsnFile';
|
|||
import getFileFromDisks from './streams/getFileFromDisks';
|
||||
import verifyPatch from './verify/verifyPatch';
|
||||
import verifyProductName from './verify/verifyProductName';
|
||||
import performDiffing from './xdelta3/performDiffing';
|
||||
|
||||
interface IGetPatchArgs {
|
||||
/** The product that should be patched. */
|
||||
|
@ -103,9 +104,31 @@ export default async function getPatch({ product, from, to, sourceDirectory, tar
|
|||
const fileStream = await getFileFromDisks(diskFilenames, { diskStart: file.diskNumberStart, offset: file.offset, length: file.compressedSize });
|
||||
const fileContents = await extractFileAsStream(file, fileStream);
|
||||
|
||||
//TODO: need to apply xdelta3 diffing, then write to disk
|
||||
//if source === target, need to create .temp file, and when it's done, delete source file and rename .temp to actual name
|
||||
console.warn(`Could not extract "${file.name}"; xdelta3 diffing is not yet implemented.`);
|
||||
//need to apply xdelta3 diffing, then write to disk
|
||||
const sourceFile = path.join(sourceDir, file.name);
|
||||
const outputName = path.join(targetDir, file.name);
|
||||
const outputNameTemp = `${outputName}.tmp`;
|
||||
await performDiffing(sourceFile, fileContents, outputNameTemp);
|
||||
|
||||
//clean up: delete source file if necessary, and remove .tmp file extension
|
||||
if (sourceDir === targetDir) {
|
||||
fs.unlink(sourceFile, (deleteError) => {
|
||||
if (deleteError) {
|
||||
throw new Error(`Could not delete old source file "${sourceFile}": ${deleteError.name}`);
|
||||
}
|
||||
fs.rename(outputNameTemp, outputName, (renameError) => {
|
||||
if (renameError) {
|
||||
throw new Error(`Could not rename output file "${outputNameTemp}": ${renameError.name}`);
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
fs.rename(outputNameTemp, outputName, (renameError) => {
|
||||
if (renameError) {
|
||||
throw new Error(`Could not rename output file "${outputNameTemp}": ${renameError.name}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Could not extract file "${file.name}"`, error);
|
||||
}
|
||||
|
|
26
src/ssn/xdelta3/performDiffing.ts
Normal file
26
src/ssn/xdelta3/performDiffing.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
import * as childProcess from 'child_process';
|
||||
import * as fs from 'fs';
|
||||
import * as stream from 'stream';
|
||||
|
||||
export default function performDiffing(sourceFile: string, diffStream: stream.Readable, targetFile: string): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
//const sourceStream = fs.createReadStream(sourceFile);
|
||||
const targetStream = fs.createWriteStream(targetFile);
|
||||
|
||||
//spawn xdelta3 process, set up listeners
|
||||
const process = childProcess.spawn('xdelta3', ['-d', '-s', sourceFile]);
|
||||
diffStream.pipe(process.stdin);
|
||||
process.stdout.pipe(targetStream);
|
||||
process.stderr.on('data', (chunk) => {
|
||||
reject(`Error during xdelta3: ${chunk}`);
|
||||
});
|
||||
|
||||
process.on('exit', (code, signal) => {
|
||||
if (code === 0) {
|
||||
resolve();
|
||||
} else {
|
||||
reject(`xdelta3 exited with code "${code}" due to signal "${signal}".`);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
Loading…
Reference in a new issue