@splunk/rum-cli
Version:
Tools for handling symbol and mapping files for symbolication
125 lines (124 loc) • 5.31 kB
JavaScript
;
/*
* Copyright Splunk Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.readdirRecursive = readdirRecursive;
exports.readlines = readlines;
exports.makeReadStream = makeReadStream;
exports.overwriteFileContents = overwriteFileContents;
exports.cleanupTemporaryFiles = cleanupTemporaryFiles;
const node_fs_1 = require("node:fs");
const promises_1 = require("node:fs/promises");
const node_path_1 = __importDefault(require("node:path"));
const node_readline_1 = __importDefault(require("node:readline"));
const node_os_1 = __importDefault(require("node:os"));
const promises_2 = require("node:stream/promises");
const glob_1 = require("glob");
const TEMP_FILE_EXTENSION = '.splunk.tmp';
/**
* Returns a list of paths to all files within the given directory.
*
* If dir is "path/to/dist", then the returned file paths will look like:
* - path/to/dist/main.js
* - path/to/dist/main.js.map
* - path/to/dist/nested/folder/page1.js
*/
function readdirRecursive(dir_1) {
return __awaiter(this, arguments, void 0, function* (dir, include = '**/*', exclude = []) {
// Using 'glob' instead of native 'readdir' due to:
// https://github.com/nodejs/node/issues/48858
// https://github.com/nodejs/node/issues/51773
// glob does not report some readdir errors (ENOTDIR, EACCES)
// that our user should know about, so try reading the dir before running glob
yield (0, promises_1.readdir)(dir);
const partialPaths = yield (0, glob_1.glob)(include, {
cwd: dir,
nodir: true,
ignore: ['**/node_modules/**', ...exclude]
});
return partialPaths.map(partialPath => node_path_1.default.join(dir, partialPath));
});
}
function readlines(stream) {
return node_readline_1.default.createInterface({
input: stream,
crlfDelay: Infinity, // recognize all instances of CR LF ('\r\n') as a single line break
});
}
function makeReadStream(filePath) {
return (0, node_fs_1.createReadStream)(filePath, { encoding: 'utf-8' });
}
/**
* Safely overwrite the contents of filePath by writing to a temporary
* file and replacing filePath. This avoids destructive edits to filePath
* if the process exits before this function has completed.
*
* If this method is used by a command, the command must always invoke
* cleanupTemporaryFiles before exiting successfully.
*/
function overwriteFileContents(filePath, lines) {
return __awaiter(this, void 0, void 0, function* () {
const tempFilePath = getTempFilePath(filePath);
yield writeLinesToFile(tempFilePath, lines);
yield (0, promises_1.rename)(tempFilePath, filePath);
});
}
/**
* Recursively remove any temporary files that may still be present in the directory.
*/
function cleanupTemporaryFiles(dir) {
return __awaiter(this, void 0, void 0, function* () {
const paths = yield readdirRecursive(dir);
for (const path of paths) {
if (path.endsWith(TEMP_FILE_EXTENSION)) {
yield (0, promises_1.rm)(path);
}
}
});
}
/**
* Return a tempFilePath based on the input filePath:
*
* - `path/to/file.js` -> `path/to/.file.js${TEMP_FILE_EXTENSION}`
*/
function getTempFilePath(filePath) {
const fileName = node_path_1.default.basename(filePath);
const tempFileName = `.${fileName}${TEMP_FILE_EXTENSION}`;
return node_path_1.default.join(node_path_1.default.dirname(filePath), tempFileName);
}
function writeLinesToFile(path, lines) {
return __awaiter(this, void 0, void 0, function* () {
const outStream = (0, node_fs_1.createWriteStream)(path, { encoding: 'utf-8' });
for (const line of lines) {
outStream.write(line);
outStream.write(node_os_1.default.EOL);
}
outStream.end();
return (0, promises_2.finished)(outStream);
});
}