Skip to content

Instantly share code, notes, and snippets.

@enijar
Last active September 5, 2016 17:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save enijar/889ce2dbcaefb54da8c52b6d9b63f1ed to your computer and use it in GitHub Desktop.
Save enijar/889ce2dbcaefb54da8c52b6d9b63f1ed to your computer and use it in GitHub Desktop.
A work in progress, incremental backup script in Node.js
'use strict';
const fs = require('fs');
const crypto = require('crypto');
const currentDirectory = `${__dirname}/backup-tests/current`;
const backupDirectory = `${__dirname}/backup-tests/backup`;
const getFileHash = (filePath) => {
const contents = fs.readFileSync(filePath);
const hash = crypto.createHash('sha1');
hash.update(contents);
return hash.digest('hex')
};
const addFileToBackupsQueue = (directory, file, type, hashes) => {
hashes = hashes || null;
backupFilesQueue.push({
path: directory,
file: file,
hashes: hashes,
filePath: `${directory}/${file}`,
backupType: type
});
};
const getFilesNeedingBackup = (currentDirectory, backupDirectory) => {
let files = fs.readdirSync(currentDirectory);
files.forEach((file) => {
let stats = fs.lstatSync(`${currentDirectory}/${file}`);
if (stats.isDirectory()) {
getFilesNeedingBackup(`${currentDirectory}/${file}`, `${backupDirectory}/${file}`);
return;
}
if (!fs.existsSync(`${backupDirectory}/${file}`)) {
// File is not backed up, therefor file has to be copied
// to the backups directory.
addFileToBackupsQueue(currentDirectory, file, 'full');
return;
}
const currentHash = getFileHash(`${currentDirectory}/${file}`);
const backupHash = getFileHash(`${backupDirectory}/${file}`);
if (currentHash !== backupHash) {
// Hashes are different, therefor file has been
// modified and needs backing up.
addFileToBackupsQueue(currentDirectory, file, 'partial', {current: currentHash, backup: backupHash});
}
});
};
const backupFilesFromQueue = (backupFilesQueue) => {
backupFilesQueue.forEach((file) => {
console.log(JSON.stringify(file, null, 4));
});
let total = backupFilesQueue.length;
let fullTotal = backupFilesQueue.filter(file => file.backupType === 'partial').length;
let partialTotal = backupFilesQueue.filter(file => file.backupType === 'full').length;
console.log(`Files needing backup (${total} total):`);
console.log(`Full: ${partialTotal}/${total}`);
console.log(`Partial: ${fullTotal}/${total}`);
};
let backupFilesQueue = [];
// This method is recursive and synchronous
getFilesNeedingBackup(currentDirectory, backupDirectory);
// Perform backups from queue
backupFilesFromQueue(backupFilesQueue);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment