print-project
Advanced tools
Comparing version 1.0.35 to 1.0.36
@@ -8,2 +8,3 @@ "use strict"; | ||
"dist", | ||
"build", | ||
"coverage", | ||
@@ -13,3 +14,2 @@ "documentation", | ||
".gitignore", | ||
"scripts", | ||
".serverless", | ||
@@ -16,0 +16,0 @@ ".idea", |
{ | ||
"name": "print-project", | ||
"version": "1.0.35", | ||
"version": "1.0.36", | ||
"description": "A simple CLI tool to print the project tree structure and file contents", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -182,3 +182,3 @@ File structure: | ||
"name": "print-project", | ||
"version": "1.0.28", | ||
"version": "1.0.35", | ||
"description": "A simple CLI tool to print the project tree structure and file contents", | ||
@@ -227,3 +227,3 @@ "main": "dist/index.js", | ||
".idea", | ||
".git", | ||
".git/", | ||
".DS_Store", | ||
@@ -270,22 +270,30 @@ ".husky", | ||
console.log("\n🔍 Starting program execution"); | ||
// Initialize command line interface | ||
const program = new Command(); | ||
program.argument("<startPath>", "Starting directory path").option("--ignore <patterns>", "Comma-separated list of patterns to ignore").option("--include <patterns>", "Comma-separated list of patterns to include").option("--remove-default", "Remove default ignore patterns").parse(process.argv); | ||
const startPath: string | undefined = program.args[0] && path.resolve(program.args[0]); | ||
const options = program.opts(); | ||
const userIgnorePatterns: string[] = options.ignore ? options.ignore.split(",").filter(Boolean).map((pattern: string) => pattern.trim()) : []; | ||
const includePatterns: string[] = options.include ? options.include.split(",").filter(Boolean).map((pattern: string) => pattern.trim()) : []; | ||
const userIgnorePatterns: string[] = options.ignore | ||
? options.ignore.split(",").filter(Boolean).map((pattern: string) => { | ||
return pattern.trim(); | ||
}) | ||
: []; | ||
const includePatterns: string[] = options.include | ||
? options.include.split(",").filter(Boolean).map((pattern: string) => { | ||
return pattern.trim(); | ||
}) | ||
: []; | ||
const shouldAddDefaultIgnorePatterns: boolean = !options.removeDefault; | ||
console.log("🎯 Default patterns:", shouldAddDefaultIgnorePatterns ? "enabled" : "disabled"); | ||
// Build the final ignore patterns list | ||
let ignorePatterns: string[] = ["project-print.txt"]; // Always ignore the output file | ||
// If NOT using --remove-default, add default patterns FIRST | ||
// Build ignore patterns list | ||
let ignorePatterns: string[] = ["project-print.txt"]; | ||
if (shouldAddDefaultIgnorePatterns) { | ||
ignorePatterns = [...defaultIgnorePatterns, ...ignorePatterns]; | ||
} | ||
// Add user's ignore patterns LAST to give them precedence | ||
ignorePatterns = [...ignorePatterns, ...userIgnorePatterns]; | ||
function matchesAnyPattern(filePath: string, patterns: string[]): boolean { | ||
@@ -295,3 +303,2 @@ if (patterns.length === 0) { | ||
} | ||
return patterns.some(pattern => { | ||
@@ -301,16 +308,16 @@ if (!pattern) { | ||
} | ||
const normalizedPath = filePath.replace(/\\/g, "/").toLowerCase(); | ||
const normalizedPattern = pattern.toLowerCase(); | ||
if (normalizedPattern.includes("/")) { | ||
// For patterns with path separators, use them as-is | ||
const regexPattern = pattern.split("*").map(s => s.replace(/[|\\{}()[\]^$+?.]/g, "\\$&")).join(".*"); | ||
return new RegExp(regexPattern, "i").test(normalizedPath); | ||
const result = new RegExp(regexPattern, "i").test(normalizedPath); | ||
return result; | ||
} else { | ||
// For simple patterns, match against the basename and the full path | ||
const basename = path.basename(normalizedPath); | ||
const simpleRegex = new RegExp(pattern.split("*").map(s => s.replace(/[|\\{}()[\]^$+?.]/g, "\\$&")).join(".*"), "i"); | ||
return simpleRegex.test(basename) || normalizedPath.includes(normalizedPattern); | ||
const simpleRegex = new RegExp( | ||
pattern.split("*").map(s => s.replace(/[|\\{}()[\]^$+?.]/g, "\\$&")).join(".*"), | ||
"i", | ||
); | ||
const result = simpleRegex.test(basename) || normalizedPath.includes(normalizedPattern); | ||
return result; | ||
} | ||
@@ -321,39 +328,39 @@ }); | ||
function shouldProcess(filePath: string): boolean { | ||
// If we have include patterns, file must match one of them | ||
if (includePatterns.length > 0) { | ||
return matchesAnyPattern(filePath, includePatterns); | ||
const shouldInclude = matchesAnyPattern(filePath, includePatterns); | ||
return shouldInclude; | ||
} | ||
// If no include patterns, exclude if matches ignore patterns | ||
return !matchesAnyPattern(filePath, ignorePatterns); | ||
const shouldIgnore = matchesAnyPattern(filePath, ignorePatterns); | ||
return !shouldIgnore; | ||
} | ||
function readDirectory(dirPath: string, treeStructure: Record<string, any> = {}): void { | ||
function readDirectory(dirPath: string, tree: Record<string, any> = {}): void { | ||
let hasIncludedFiles = false; | ||
try { | ||
const entries = fs.readdirSync(dirPath, { withFileTypes: true }); | ||
for (const entry of entries) { | ||
const fullPath = path.join(dirPath, entry.name); | ||
const relativePath = path.relative(startPath || ".", fullPath).replace(/\\/g, "/"); | ||
const isIgnored = matchesAnyPattern(relativePath, ignorePatterns); | ||
if (entry.isDirectory()) { | ||
if (shouldProcess(relativePath)) { | ||
const subTree = {}; | ||
treeStructure[relativePath] = subTree; | ||
if (!isIgnored) { | ||
const subTree: Record<string, any> = {}; | ||
readDirectory(fullPath, subTree); | ||
// Remove empty directories | ||
if (Object.keys(subTree).length === 0) { | ||
delete treeStructure[relativePath]; | ||
if (Object.keys(subTree).length > 0) { | ||
tree[relativePath] = subTree; | ||
hasIncludedFiles = true; | ||
} | ||
} | ||
} else if (entry.isFile() && shouldProcess(relativePath)) { | ||
try { | ||
const content = fs.readFileSync(fullPath, "utf8"); | ||
if (content.length > 0) { | ||
treeStructure[relativePath] = {}; | ||
} else if (entry.isFile()) { | ||
if (!isIgnored && shouldProcess(relativePath)) { | ||
try { | ||
const content = fs.readFileSync(fullPath, "utf8"); | ||
tree[relativePath] = {}; | ||
projectPrint += `${relativePath}:\n${content}\n\n`; | ||
hasIncludedFiles = true; | ||
} catch (error: any) { | ||
console.error(` ❌ Error reading file ${relativePath}:`, error.message); | ||
console.error(` 📑 Error stack:`, error.stack); | ||
} | ||
} catch (error: any) { | ||
console.error(`Error reading file ${relativePath}:`, error.message); | ||
} | ||
@@ -363,3 +370,4 @@ } | ||
} catch (error: any) { | ||
console.error(`Error reading directory ${dirPath}:`, error.message); | ||
console.error(`❌ Error reading directory ${dirPath}:`, error.message); | ||
console.error(`📑 Error stack:`, error.stack); | ||
} | ||
@@ -378,19 +386,20 @@ } | ||
function main(): void { | ||
console.log("\n🎬 Starting main execution..."); | ||
if (!startPath) { | ||
console.error("Starting directory path is required."); | ||
console.error("❌ Starting directory path is required."); | ||
process.exit(1); | ||
} | ||
console.log("\nStarting directory read from:", startPath); | ||
console.log("Include patterns:", includePatterns.length ? includePatterns.join(", ") : "none"); | ||
console.log("Ignore patterns:", ignorePatterns.join(", ")); | ||
console.log("Remove default:", !shouldAddDefaultIgnorePatterns); | ||
console.log(); | ||
console.log("\n📌 Configuration:"); | ||
console.log(`📂 Start path: ${startPath}`); | ||
console.log(`📥 Include patterns: ${includePatterns.length ? includePatterns.join(", ") : "none"}`); | ||
console.log(`🚫 Ignore patterns: ${ignorePatterns.join(", ")}`); | ||
console.log(`🔄 Remove default: ${!shouldAddDefaultIgnorePatterns}`); | ||
console.log("\n🏁 Starting directory traversal..."); | ||
readDirectory(startPath, treeStructure); | ||
console.log("\n🏗️ Building final output..."); | ||
buildTreeStructure(treeStructure); | ||
const finalContents = `File structure:\n${treeStructureString}\n\nProject print:\n${projectPrint}`; | ||
console.log("\n💾 Writing output file..."); | ||
fs.writeFileSync("project-print.txt", finalContents); | ||
console.log(`Project print size: ${(projectPrint.length / 1024).toFixed(2)}KB`); | ||
console.log("\n✨ Process completed!"); | ||
} | ||
@@ -397,0 +406,0 @@ |
@@ -5,2 +5,3 @@ export const defaultIgnorePatterns: string[] = [ | ||
"dist", | ||
"build", | ||
"coverage", | ||
@@ -10,3 +11,2 @@ "documentation", | ||
".gitignore", | ||
"scripts", | ||
".serverless", | ||
@@ -13,0 +13,0 @@ ".idea", |
36112