print-project
Advanced tools
Comparing version 1.0.4 to 1.0.5
@@ -30,18 +30,18 @@ #!/usr/bin/env node | ||
const commander_1 = require("commander"); | ||
let projectPrint = ''; | ||
const constants_1 = require("./constants"); | ||
let projectPrint = ""; | ||
let treeStructure = {}; | ||
let treeStructureString = ''; | ||
let treeStructureString = ""; | ||
const program = new commander_1.Command(); | ||
program | ||
.argument('<startPath>', 'Starting directory path') | ||
.argument('[ignorePatterns]', 'Comma-separated list of patterns to ignore') | ||
.parse(process.argv); | ||
program.argument("<startPath>", "Starting directory path").argument("[ignorePatterns]", "Comma-separated list of patterns to ignore").option("--ignore-default", "Use default ignore patterns").parse(process.argv); | ||
const startPath = program.args[0] && path.resolve(program.args[0]); | ||
const patterns = program.args[1] ? program.args[1].split(',').filter(Boolean).map(pattern => pattern.trim()) : []; | ||
console.log('Start Path:', startPath); | ||
console.log('Patterns:', patterns); | ||
const userPatterns = program.args[1] ? program.args[1].split(",").filter(Boolean).map(pattern => pattern.trim()) : []; | ||
const useDefaultIgnore = program.opts().ignoreDefault; | ||
const patterns = useDefaultIgnore ? [...constants_1.defaultIgnorePatterns, ...userPatterns] : userPatterns; | ||
console.log("Start Path:", startPath); | ||
console.log("Patterns:", patterns); | ||
function isIgnored(filePath, patterns) { | ||
try { | ||
return patterns.some(pattern => { | ||
const parsedPattern = pattern.replace(/\./g, '\\.').replace(/\*/g, '.*'); | ||
const parsedPattern = pattern.replace(/\./g, "\\.").replace(/\*/g, ".*"); | ||
const regex = new RegExp(parsedPattern); | ||
@@ -56,11 +56,11 @@ return regex.test(filePath); | ||
} | ||
function readDirectory(dirPath, patterns = [], treeStructure = {}, currentPath = '') { | ||
function readDirectory(dirPath, patterns = [], treeStructure = {}, currentPath = "") { | ||
try { | ||
const dirents = fs.readdirSync(dirPath, { withFileTypes: true }); | ||
dirents.forEach((dirent) => { | ||
const fullPath = path.relative(process.cwd(), path.join(dirPath, dirent.name)).replace(/\\/g, '/'); | ||
const fullPath = path.relative(process.cwd(), path.join(dirPath, dirent.name)).replace(/\\/g, "/"); | ||
if (isIgnored(fullPath, patterns)) { | ||
return; | ||
} | ||
const relativePath = path.join(currentPath, dirent.name).replace(/\\/g, '/'); | ||
const relativePath = path.join(currentPath, dirent.name).replace(/\\/g, "/"); | ||
if (dirent.isDirectory()) { | ||
@@ -72,3 +72,3 @@ treeStructure[relativePath] = {}; | ||
treeStructure[relativePath] = {}; | ||
const content = fs.readFileSync(path.join(dirPath, dirent.name), 'utf8'); | ||
const content = fs.readFileSync(path.join(dirPath, dirent.name), "utf8"); | ||
if (content.length > 0) { | ||
@@ -84,7 +84,7 @@ projectPrint += `${fullPath}:\n${content}\n\n`; | ||
} | ||
function buildTreeStructure(tree, indent = '') { | ||
function buildTreeStructure(tree, indent = "") { | ||
for (const key in tree) { | ||
treeStructureString += indent + key + '\n'; | ||
if (typeof tree[key] === 'object' && Object.keys(tree[key]).length > 0) { | ||
buildTreeStructure(tree[key], indent + ' '); | ||
treeStructureString += indent + key + "\n"; | ||
if (typeof tree[key] === "object" && Object.keys(tree[key]).length > 0) { | ||
buildTreeStructure(tree[key], indent + " "); | ||
} | ||
@@ -95,15 +95,16 @@ } | ||
if (!startPath) { | ||
console.error('Starting directory path is required.'); | ||
console.error("Starting directory path is required."); | ||
process.exit(1); | ||
} | ||
console.log(`Starting directory read from ${startPath} (ignoring: ${patterns.join(', ')})`); | ||
console.log(`Starting directory read from ${startPath}`); | ||
console.log(`Ignoring: ${patterns.join(", ")}`); | ||
console.log(`Using default ignore: ${useDefaultIgnore}`); | ||
readDirectory(startPath, patterns, treeStructure); | ||
console.log('\nNon-ignored file structure:\n'); | ||
console.log("\nNon-ignored file structure:\n"); | ||
buildTreeStructure(treeStructure); | ||
console.log(treeStructureString); | ||
const finalContents = `File structure:\n${treeStructureString}\n\nProject print:\n${projectPrint}`; | ||
fs.writeFileSync('project-print.txt', ''); | ||
fs.writeFileSync('project-print.txt', finalContents); | ||
fs.writeFileSync("project-print.txt", finalContents); | ||
console.log(`\nProject print size: ${(projectPrint.length / 1024).toFixed(2)}KB`); | ||
} | ||
main(); |
{ | ||
"name": "print-project", | ||
"version": "1.0.4", | ||
"version": "1.0.5", | ||
"description": "A simple CLI tool to print the project tree structure and file contents", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -26,7 +26,28 @@ # Print-Project | ||
- `<startPath>`: Required. The path to the directory you want to scan. | ||
e.g., `/path/to/project` | ||
- | ||
e.g., `/path/to/project` | ||
- `[ignorePatterns]`: Optional. A comma-separated list of glob patterns to ignore files and directories. | ||
e.g., `"node_modules,*.log,dist,coverage,documentation,.prettierrc,.gitignore,dist,scripts,.serverless,.idea,.git,.DS_Store,.husky,package-lock.json"` | ||
e.g., `"node_modules,*.log,dist,coverage"` | ||
### Using Default Ignore Patterns | ||
To use the default ignore patterns, add the `--ignore-default` flag: | ||
```bash | ||
print-project <startPath> --ignore-default | ||
``` | ||
You can also combine default patterns with your own: | ||
```bash | ||
print-project <startPath> "your,custom,patterns" --ignore-default | ||
``` | ||
### Default Ignore Patterns | ||
The following patterns are ignored by default when using the `--ignore-default` flag: | ||
``` | ||
node_modules,*.log,dist,coverage,documentation,.prettierrc,.gitignore,dist,scripts,.serverless,.idea,.git,.DS_Store,.husky,package-lock.json | ||
``` | ||
### Examples | ||
@@ -43,7 +64,17 @@ | ||
```bash | ||
print-project ./src "node_modules,*.log,dist,coverage,documentation,.prettierrc,.gitignore,dist,scripts,.serverless,.idea,.git,.DS_Store,.husky,package-lock.json" | ||
print-project ./src "node_modules,*.log,dist,coverage" | ||
``` | ||
This will ignore all directories and files matching the `node_modules` folder and any files ending with `.log`. | ||
- **Use default ignore patterns**: | ||
```bash | ||
print-project ./src --ignore-default | ||
``` | ||
- **Use default ignore patterns and add custom ones**: | ||
```bash | ||
print-project ./src "*.tmp,*.bak" --ignore-default | ||
``` | ||
## Features | ||
@@ -53,2 +84,3 @@ | ||
- **Ignore Patterns**: Supports glob patterns to exclude specific files or directories from the output. | ||
- **Default Ignore Patterns**: Provides a set of commonly ignored patterns for convenience. | ||
- **Output Generation**: Creates a text file `project-print.txt` in the current working directory containing: | ||
@@ -55,0 +87,0 @@ - The structured list of non-ignored files and directories. |
#!/usr/bin/env node | ||
import * as fs from "fs"; | ||
import * as path from "path"; | ||
import { Command } from "commander"; | ||
import { defaultIgnorePatterns } from "./constants"; | ||
import * as fs from 'fs'; | ||
import * as path from 'path'; | ||
import { Command } from 'commander'; | ||
let projectPrint: string = ''; | ||
let projectPrint: string = ""; | ||
let treeStructure: Record<string, any> = {}; | ||
let treeStructureString: string = ''; | ||
let treeStructureString: string = ""; | ||
const program = new Command(); | ||
program.argument("<startPath>", "Starting directory path").argument("[ignorePatterns]", "Comma-separated list of patterns to ignore").option("--ignore-default", "Use default ignore patterns").parse(process.argv); | ||
program | ||
.argument('<startPath>', 'Starting directory path') | ||
.argument('[ignorePatterns]', 'Comma-separated list of patterns to ignore') | ||
.parse(process.argv); | ||
const startPath: string | undefined = program.args[0] && path.resolve(program.args[0]); | ||
const patterns: string[] = program.args[1] ? program.args[1].split(',').filter(Boolean).map(pattern => pattern.trim()) : []; | ||
const userPatterns: string[] = program.args[1] ? program.args[1].split(",").filter(Boolean).map(pattern => pattern.trim()) : []; | ||
const useDefaultIgnore: boolean = program.opts().ignoreDefault; | ||
console.log('Start Path:', startPath); | ||
console.log('Patterns:', patterns); | ||
const patterns: string[] = useDefaultIgnore ? [...defaultIgnorePatterns, ...userPatterns] : userPatterns; | ||
console.log("Start Path:", startPath); | ||
console.log("Patterns:", patterns); | ||
function isIgnored(filePath: string, patterns: string[]): boolean { | ||
try { | ||
return patterns.some(pattern => { | ||
const parsedPattern = pattern.replace(/\./g, '\\.').replace(/\*/g, '.*'); | ||
const parsedPattern = pattern.replace(/\./g, "\\.").replace(/\*/g, ".*"); | ||
const regex = new RegExp(parsedPattern); | ||
@@ -38,11 +37,11 @@ return regex.test(filePath); | ||
function readDirectory(dirPath: string, patterns: string[] = [], treeStructure: Record<string, any> = {}, currentPath: string = ''): void { | ||
function readDirectory(dirPath: string, patterns: string[] = [], treeStructure: Record<string, any> = {}, currentPath: string = ""): void { | ||
try { | ||
const dirents = fs.readdirSync(dirPath, { withFileTypes: true }); | ||
dirents.forEach((dirent) => { | ||
const fullPath = path.relative(process.cwd(), path.join(dirPath, dirent.name)).replace(/\\/g, '/'); | ||
const fullPath = path.relative(process.cwd(), path.join(dirPath, dirent.name)).replace(/\\/g, "/"); | ||
if (isIgnored(fullPath, patterns)) { | ||
return; | ||
} | ||
const relativePath = path.join(currentPath, dirent.name).replace(/\\/g, '/'); | ||
const relativePath = path.join(currentPath, dirent.name).replace(/\\/g, "/"); | ||
if (dirent.isDirectory()) { | ||
@@ -53,3 +52,3 @@ treeStructure[relativePath] = {}; | ||
treeStructure[relativePath] = {}; | ||
const content = fs.readFileSync(path.join(dirPath, dirent.name), 'utf8'); | ||
const content = fs.readFileSync(path.join(dirPath, dirent.name), "utf8"); | ||
if (content.length > 0) { | ||
@@ -65,7 +64,7 @@ projectPrint += `${fullPath}:\n${content}\n\n`; | ||
function buildTreeStructure(tree: Record<string, any>, indent: string = ''): void { | ||
function buildTreeStructure(tree: Record<string, any>, indent: string = ""): void { | ||
for (const key in tree) { | ||
treeStructureString += indent + key + '\n'; | ||
if (typeof tree[key] === 'object' && Object.keys(tree[key]).length > 0) { | ||
buildTreeStructure(tree[key], indent + ' '); | ||
treeStructureString += indent + key + "\n"; | ||
if (typeof tree[key] === "object" && Object.keys(tree[key]).length > 0) { | ||
buildTreeStructure(tree[key], indent + " "); | ||
} | ||
@@ -77,11 +76,12 @@ } | ||
if (!startPath) { | ||
console.error('Starting directory path is required.'); | ||
console.error("Starting directory path is required."); | ||
process.exit(1); | ||
} | ||
console.log(`Starting directory read from ${startPath} (ignoring: ${patterns.join(', ')})`); | ||
console.log(`Starting directory read from ${startPath}`); | ||
console.log(`Ignoring: ${patterns.join(", ")}`); | ||
console.log(`Using default ignore: ${useDefaultIgnore}`); | ||
readDirectory(startPath, patterns, treeStructure); | ||
console.log('\nNon-ignored file structure:\n'); | ||
console.log("\nNon-ignored file structure:\n"); | ||
buildTreeStructure(treeStructure); | ||
@@ -91,4 +91,3 @@ console.log(treeStructureString); | ||
const finalContents = `File structure:\n${treeStructureString}\n\nProject print:\n${projectPrint}`; | ||
fs.writeFileSync('project-print.txt', ''); | ||
fs.writeFileSync('project-print.txt', finalContents); | ||
fs.writeFileSync("project-print.txt", finalContents); | ||
console.log(`\nProject print size: ${(projectPrint.length / 1024).toFixed(2)}KB`); | ||
@@ -95,0 +94,0 @@ } |
38623
26
696
107