generate file hash
parent
fdd2ac86e4
commit
8d246e2c1b
@ -0,0 +1,111 @@
|
||||
import readdir from "readdir-enhanced";
|
||||
import fs from "fs";
|
||||
import crypto from "crypto";
|
||||
import multimatch from "multimatch";
|
||||
|
||||
function applyExcludeFilter(stat, excludeFilters) {
|
||||
// match exclude, return immediatley
|
||||
if (excludeFilters.length > 0) {
|
||||
// todo this could be a performance problem...
|
||||
const pathWithFolderSlash = stat.path + (stat.isDirectory() ? "/" : "");
|
||||
const excludeMatch = multimatch(pathWithFolderSlash, excludeFilters, { matchBase: true, dot: true });
|
||||
|
||||
if (excludeMatch.length > 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param algorithm : "md5" | "sha1" | "sha256" | "sha512"
|
||||
*/
|
||||
async function fileHash(filename, algorithm) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Algorithm depends on availability of OpenSSL on platform
|
||||
// Another algorithms: "sha1", "md5", "sha256", "sha512" ...
|
||||
let shasum = crypto.createHash(algorithm);
|
||||
try {
|
||||
let s = fs.createReadStream(filename);
|
||||
s.on("data", function (data) {
|
||||
shasum.update(data)
|
||||
});
|
||||
|
||||
s.on("error", function (error) {
|
||||
reject(error);
|
||||
});
|
||||
|
||||
// making digest
|
||||
s.on("end", function () {
|
||||
const hash = shasum.digest("hex")
|
||||
return resolve(hash);
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
return reject("calc fail");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function createLocalState(localFiles, args) {
|
||||
console.log(`Creating local state at ${args["local-dir"]}${args["state-name"]}`);
|
||||
fs.writeFileSync(`${args["local-dir"]}${args["state-name"]}`, JSON.stringify(localFiles, undefined, 4), { encoding: "utf8" });
|
||||
console.log("Local state created");
|
||||
}
|
||||
async function getLocalFiles(args) {
|
||||
const files = await readdir.async(args["local-dir"], { deep: true, stats: true, sep: "/", filter: (stat) => applyExcludeFilter(stat, args.exclude) });
|
||||
let records = [];
|
||||
|
||||
for (let stat of files) {
|
||||
if (stat.isDirectory()) {
|
||||
records.push({
|
||||
type: "folder",
|
||||
name: stat.path,
|
||||
size: undefined
|
||||
});
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (stat.isFile()) {
|
||||
records.push({
|
||||
type: "file",
|
||||
name: stat.path,
|
||||
size: stat.size,
|
||||
hash: await fileHash(args["local-dir"] + stat.path, "sha256")
|
||||
});
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (stat.isSymbolicLink()) {
|
||||
console.warn("This script is currently unable to handle symbolic links - please add a feature request if you need this");
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
description: 'Don\'t delete',
|
||||
version: '1.0.0',
|
||||
generatedTime: new Date().getTime(),
|
||||
data: records
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const filename = ".generate-file-hash.json";
|
||||
const _args = {
|
||||
'local-dir': './',
|
||||
'state-name': filename,
|
||||
'exclude': [
|
||||
'**/node_modules/**',
|
||||
'**/.git*/**',
|
||||
'**/.git*/**',
|
||||
filename,
|
||||
]
|
||||
};
|
||||
const localFiles = await getLocalFiles(_args);
|
||||
createLocalState(localFiles, _args);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
Loading…
Reference in New Issue