sourcesailor
Version:
A CLI tool for analyzing and documenting codebases
107 lines (106 loc) • 4.12 kB
JavaScript
import fs from 'fs';
import os from 'os';
import path from 'path';
export function readConfig() {
const homeDir = os.homedir();
const configFile = path.join(homeDir, '.SourceSailor', 'config.json');
if (fs.existsSync(configFile)) {
try {
const config = JSON.parse(fs.readFileSync(configFile, 'utf8'));
return config;
}
catch (error) {
console.error('Error parsing config file:', error);
}
return {};
}
return {};
}
export function writeConfig(config) {
const homeDir = os.homedir();
const configDir = path.join(homeDir, '.SourceSailor');
const configFile = path.join(configDir, 'config.json');
if (!fs.existsSync(configDir)) {
fs.mkdirSync(configDir, { recursive: true });
}
fs.writeFileSync(configFile, JSON.stringify(config, null, 2));
}
export function addAnalysisInGitIgnore(projectRoot) {
// First check if the project root has gitignore file, if the file is not found don't create one.
// If the file is found, append .SourceSailor/analysis to the file.
const gitignoreFile = path.join(projectRoot, '.gitignore');
if (fs.existsSync(gitignoreFile)) {
const gitignoreContent = fs.readFileSync(gitignoreFile, 'utf8');
if (!gitignoreContent.includes('.SourceSailor/analysis')) {
fs.appendFileSync(gitignoreFile, '\n.SourceSailor/analysis');
}
}
}
export function writeAnalysis(projectRoot, analysisName, analysisContent, isJson = false, isProjectRoot = false) {
const analysisDir = isProjectRoot ? path.join(projectRoot, '.SourceSailor', 'analysis') : path.join(projectRoot, 'analysis');
if (!fs.existsSync(analysisDir)) {
fs.mkdirSync(analysisDir, { recursive: true });
}
if (isJson) {
const analysisFile = path.join(analysisDir, `${analysisName}.json`);
fs.writeFileSync(analysisFile, JSON.stringify(analysisContent, null, 4));
}
else {
const analysisFile = path.join(analysisDir, `${analysisName}.md`);
fs.writeFileSync(analysisFile, analysisContent);
}
}
export function writeError(projectRoot, errorType, errorContent, errorMssage) {
const errorDir = path.join(projectRoot, 'errors');
if (!fs.existsSync(errorDir)) {
fs.mkdirSync(errorDir, { recursive: true });
}
const errorFile = path.join(errorDir, `${errorType}.txt`);
fs.writeFileSync(errorFile, `${errorContent}\n\n${errorMssage}`);
}
export function getAnalysis(projectRoot, isProjectRoot) {
const analysis = {};
const analysisDir = isProjectRoot ? path.join(projectRoot, '.SourceSailor', 'analysis') : path.join(projectRoot, 'analysis');
if (!fs.existsSync(analysisDir)) {
return analysis;
}
const entries = fs.readdirSync(analysisDir);
for (const entry of entries) {
const fullPath = path.join(analysisDir, entry);
const isDirectory = fs.statSync(fullPath).isDirectory();
// console.log({entry})
const fileName = path.basename(entry, path.extname(entry));
if (isDirectory) {
analysis[fileName] = getAnalysis(fullPath, false);
}
else {
analysis[fileName] = fs.readFileSync(fullPath, 'utf-8');
}
}
return analysis;
}
export async function processStream(iterator, processChunk) {
let fullResponse = '';
const { value, done } = await iterator.next();
while (done) {
const message = processChunk(value);
process.stdout.write(message);
fullResponse += message;
}
return fullResponse;
}
export function maskSensitiveInfo(input) {
// This is a simple implementation. You might want to enhance it based on your specific needs.
const sensitivePatterns = [
/api[-_]?key/i,
/password/i,
/secret/i,
/token/i,
/credential/i
];
let maskedInput = input;
for (const pattern of sensitivePatterns) {
maskedInput = maskedInput.replace(new RegExp(`(${pattern.source}\\s*[=:])\\s*["']?[^"'\\s]+["']?`, 'gi'), '$1 "********"');
}
return maskedInput;
}