Summary: mass rename files Reviewed By: passy Differential Revision: D33890034 fbshipit-source-id: 1c654a4f7f5b83eaa56a8c11df863003e8d7bed7
88 lines
2.8 KiB
TypeScript
88 lines
2.8 KiB
TypeScript
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @format
|
|
*/
|
|
|
|
import packlist from 'npm-packlist';
|
|
import path from 'path';
|
|
import crypto from 'crypto';
|
|
import fs from 'fs-extra';
|
|
|
|
export default async function computePackageChecksum(
|
|
dir: string,
|
|
checksumFilePath?: string,
|
|
): Promise<string> {
|
|
const fullChecksumFilePath = checksumFilePath
|
|
? path.resolve(dir, checksumFilePath)
|
|
: undefined;
|
|
if (fullChecksumFilePath) {
|
|
// This block is an optimisation to not recompute checksum if nothing changed.
|
|
// tsbuildinfo file is changed every time when typescript compiler re-compiles anything,
|
|
// so we could compare its modification date with checksum modification date to
|
|
// decide whether we need to re-compute checksum or we can just use already computed one.
|
|
const tsBuildInfoPath = path.join(dir, 'tsconfig.tsbuildinfo');
|
|
try {
|
|
const [tsBuildInfoStat, checksumStat] = await Promise.all([
|
|
fs.stat(tsBuildInfoPath),
|
|
fs.stat(fullChecksumFilePath),
|
|
]);
|
|
if (checksumStat.mtime > tsBuildInfoStat.mtime) {
|
|
return (await fs.readFile(fullChecksumFilePath)).toString();
|
|
}
|
|
} catch {}
|
|
}
|
|
const hash = crypto.createHash('sha1');
|
|
hash.setEncoding('hex');
|
|
const files = (await packlist({path: dir})).sort();
|
|
for (const file of files) {
|
|
const segments = file.split(path.sep);
|
|
if (segments.length > 0 && segments[0] === 'docs') {
|
|
continue;
|
|
}
|
|
|
|
const filePath = path.resolve(dir, file);
|
|
|
|
if (filePath === fullChecksumFilePath) {
|
|
// If there is already existing checksum file, we need to ignore it as it is not a part of package content.
|
|
continue;
|
|
}
|
|
|
|
// add hash of relative normalized file path
|
|
hash.write(process.platform === 'win32' ? file.replace(/\\/g, '/') : file);
|
|
|
|
if (file === 'package.json') {
|
|
// add hash of package.json with version set to "0.0.0" to avoid changing hash when only version changed
|
|
const packageJson = await fs.readJson(filePath);
|
|
if (packageJson.version) {
|
|
packageJson.version = '0.0.0';
|
|
}
|
|
if (packageJson.engines && packageJson.engines.flipper) {
|
|
packageJson.engines.flipper = '0.0.0';
|
|
}
|
|
hash.write(JSON.stringify(packageJson));
|
|
} else {
|
|
// add hash of file content
|
|
const stream = fs.createReadStream(filePath);
|
|
try {
|
|
stream.pipe(hash, {end: false});
|
|
await new Promise((resolve, reject) => {
|
|
stream.once('end', resolve);
|
|
stream.once('error', reject);
|
|
});
|
|
} finally {
|
|
stream.close();
|
|
}
|
|
}
|
|
}
|
|
hash.end();
|
|
const checksum = hash.read();
|
|
if (fullChecksumFilePath) {
|
|
await fs.writeFile(fullChecksumFilePath, checksum);
|
|
}
|
|
return checksum;
|
|
}
|