Merge pull request #34521 from amcasey/LazyDirectoryCreation
Stop pre-emptively creating directories
This commit is contained in:
commit
8cf13249ea
|
@ -96,35 +96,51 @@ namespace ts {
|
|||
if (existingDirectories.has(directoryPath)) {
|
||||
return true;
|
||||
}
|
||||
if (system.directoryExists(directoryPath)) {
|
||||
if ((compilerHost.directoryExists || system.directoryExists)(directoryPath)) {
|
||||
existingDirectories.set(directoryPath, true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function ensureDirectoriesExist(directoryPath: string) {
|
||||
if (directoryPath.length > getRootLength(directoryPath) && !directoryExists(directoryPath)) {
|
||||
const parentDirectory = getDirectoryPath(directoryPath);
|
||||
ensureDirectoriesExist(parentDirectory);
|
||||
if (compilerHost.createDirectory) {
|
||||
compilerHost.createDirectory(directoryPath);
|
||||
}
|
||||
else {
|
||||
system.createDirectory(directoryPath);
|
||||
function writeFile(fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void) {
|
||||
try {
|
||||
performance.mark("beforeIOWrite");
|
||||
|
||||
// NOTE: If patchWriteFileEnsuringDirectory has been called,
|
||||
// the system.writeFile will do its own directory creation and
|
||||
// the ensureDirectoriesExist call will always be redundant.
|
||||
writeFileEnsuringDirectories(
|
||||
fileName,
|
||||
data,
|
||||
writeByteOrderMark,
|
||||
(path, data, writeByteOrderMark) => writeFileWorker(path, data, writeByteOrderMark),
|
||||
path => (compilerHost.createDirectory || system.createDirectory)(path),
|
||||
path => directoryExists(path));
|
||||
|
||||
performance.mark("afterIOWrite");
|
||||
performance.measure("I/O Write", "beforeIOWrite", "afterIOWrite");
|
||||
}
|
||||
catch (e) {
|
||||
if (onError) {
|
||||
onError(e.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let outputFingerprints: Map<OutputFingerprint>;
|
||||
function writeFileWorker(fileName: string, data: string, writeByteOrderMark: boolean) {
|
||||
if (!isWatchSet(options) || !system.createHash || !system.getModifiedTime) {
|
||||
system.writeFile(fileName, data, writeByteOrderMark);
|
||||
return;
|
||||
}
|
||||
|
||||
function writeFileIfUpdated(fileName: string, data: string, writeByteOrderMark: boolean): void {
|
||||
if (!outputFingerprints) {
|
||||
outputFingerprints = createMap<OutputFingerprint>();
|
||||
}
|
||||
|
||||
const hash = system.createHash!(data); // TODO: GH#18217
|
||||
const mtimeBefore = system.getModifiedTime!(fileName); // TODO: GH#18217
|
||||
const hash = system.createHash(data);
|
||||
const mtimeBefore = system.getModifiedTime(fileName);
|
||||
|
||||
if (mtimeBefore) {
|
||||
const fingerprint = outputFingerprints.get(fileName);
|
||||
|
@ -139,7 +155,7 @@ namespace ts {
|
|||
|
||||
system.writeFile(fileName, data, writeByteOrderMark);
|
||||
|
||||
const mtimeAfter = system.getModifiedTime!(fileName) || missingFileModifiedTime; // TODO: GH#18217
|
||||
const mtimeAfter = system.getModifiedTime(fileName) || missingFileModifiedTime;
|
||||
|
||||
outputFingerprints.set(fileName, {
|
||||
hash,
|
||||
|
@ -148,28 +164,6 @@ namespace ts {
|
|||
});
|
||||
}
|
||||
|
||||
function writeFile(fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void) {
|
||||
try {
|
||||
performance.mark("beforeIOWrite");
|
||||
ensureDirectoriesExist(getDirectoryPath(normalizePath(fileName)));
|
||||
|
||||
if (isWatchSet(options) && system.createHash && system.getModifiedTime) {
|
||||
writeFileIfUpdated(fileName, data, writeByteOrderMark);
|
||||
}
|
||||
else {
|
||||
system.writeFile(fileName, data, writeByteOrderMark);
|
||||
}
|
||||
|
||||
performance.mark("afterIOWrite");
|
||||
performance.measure("I/O Write", "beforeIOWrite", "afterIOWrite");
|
||||
}
|
||||
catch (e) {
|
||||
if (onError) {
|
||||
onError(e.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getDefaultLibLocation(): string {
|
||||
return getDirectoryPath(normalizePath(system.getExecutingFilePath()));
|
||||
}
|
||||
|
|
|
@ -522,17 +522,6 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function recursiveCreateDirectory(directoryPath: string, sys: System) {
|
||||
const basePath = getDirectoryPath(directoryPath);
|
||||
const shouldCreateParent = basePath !== "" && directoryPath !== basePath && !sys.directoryExists(basePath);
|
||||
if (shouldCreateParent) {
|
||||
recursiveCreateDirectory(basePath, sys);
|
||||
}
|
||||
if (shouldCreateParent || !sys.directoryExists(directoryPath)) {
|
||||
sys.createDirectory(directoryPath);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* patch writefile to create folder before writing the file
|
||||
*/
|
||||
|
@ -540,13 +529,14 @@ namespace ts {
|
|||
export function patchWriteFileEnsuringDirectory(sys: System) {
|
||||
// patch writefile to create folder before writing the file
|
||||
const originalWriteFile = sys.writeFile;
|
||||
sys.writeFile = (path, data, writeBom) => {
|
||||
const directoryPath = getDirectoryPath(normalizeSlashes(path));
|
||||
if (directoryPath && !sys.directoryExists(directoryPath)) {
|
||||
recursiveCreateDirectory(directoryPath, sys);
|
||||
}
|
||||
originalWriteFile.call(sys, path, data, writeBom);
|
||||
};
|
||||
sys.writeFile = (path, data, writeBom) =>
|
||||
writeFileEnsuringDirectories(
|
||||
path,
|
||||
data,
|
||||
!!writeBom,
|
||||
(path, data, writeByteOrderMark) => originalWriteFile.call(sys, path, data, writeByteOrderMark),
|
||||
path => sys.createDirectory(path),
|
||||
path => sys.directoryExists(path));
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
|
|
|
@ -3700,6 +3700,36 @@ namespace ts {
|
|||
}, sourceFiles);
|
||||
}
|
||||
|
||||
function ensureDirectoriesExist(
|
||||
directoryPath: string,
|
||||
createDirectory: (path: string) => void,
|
||||
directoryExists: (path: string) => boolean): void {
|
||||
if (directoryPath.length > getRootLength(directoryPath) && !directoryExists(directoryPath)) {
|
||||
const parentDirectory = getDirectoryPath(directoryPath);
|
||||
ensureDirectoriesExist(parentDirectory, createDirectory, directoryExists);
|
||||
createDirectory(directoryPath);
|
||||
}
|
||||
}
|
||||
|
||||
export function writeFileEnsuringDirectories(
|
||||
path: string,
|
||||
data: string,
|
||||
writeByteOrderMark: boolean,
|
||||
writeFile: (path: string, data: string, writeByteOrderMark: boolean) => void,
|
||||
createDirectory: (path: string) => void,
|
||||
directoryExists: (path: string) => boolean): void {
|
||||
|
||||
// PERF: Checking for directory existence is expensive. Instead, assume the directory exists
|
||||
// and fall back to creating it if the file write fails.
|
||||
try {
|
||||
writeFile(path, data, writeByteOrderMark);
|
||||
}
|
||||
catch {
|
||||
ensureDirectoriesExist(getDirectoryPath(normalizePath(path)), createDirectory, directoryExists);
|
||||
writeFile(path, data, writeByteOrderMark);
|
||||
}
|
||||
}
|
||||
|
||||
export function getLineOfLocalPosition(currentSourceFile: SourceFile, pos: number) {
|
||||
return getLineAndCharacterOfPosition(currentSourceFile, pos).line;
|
||||
}
|
||||
|
|
|
@ -303,20 +303,20 @@ namespace ts {
|
|||
readDirectory: maybeBind(host, host.readDirectory),
|
||||
};
|
||||
|
||||
function ensureDirectoriesExist(directoryPath: string) {
|
||||
if (directoryPath.length > getRootLength(directoryPath) && !host.directoryExists!(directoryPath)) {
|
||||
const parentDirectory = getDirectoryPath(directoryPath);
|
||||
ensureDirectoriesExist(parentDirectory);
|
||||
if (host.createDirectory) host.createDirectory(directoryPath);
|
||||
}
|
||||
}
|
||||
|
||||
function writeFile(fileName: string, text: string, writeByteOrderMark: boolean, onError: (message: string) => void) {
|
||||
try {
|
||||
performance.mark("beforeIOWrite");
|
||||
ensureDirectoriesExist(getDirectoryPath(normalizePath(fileName)));
|
||||
|
||||
host.writeFile!(fileName, text, writeByteOrderMark);
|
||||
// NOTE: If patchWriteFileEnsuringDirectory has been called,
|
||||
// the host.writeFile will do its own directory creation and
|
||||
// the ensureDirectoriesExist call will always be redundant.
|
||||
writeFileEnsuringDirectories(
|
||||
fileName,
|
||||
text,
|
||||
writeByteOrderMark,
|
||||
(path, data, writeByteOrderMark) => host.writeFile!(path, data, writeByteOrderMark),
|
||||
path => host.createDirectory!(path),
|
||||
path => host.directoryExists!(path));
|
||||
|
||||
performance.mark("afterIOWrite");
|
||||
performance.measure("I/O Write", "beforeIOWrite", "afterIOWrite");
|
||||
|
|
Loading…
Reference in a new issue