diff --git a/projdump.sh b/projdump.sh index 6467f38..9d99765 100755 --- a/projdump.sh +++ b/projdump.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# projdump.sh - dump project structure and source code into a single text file +# projdump.sh - dump project structure and source code into a single Markdown file set -euo pipefail @@ -8,7 +8,7 @@ usage() { Использование: $0 <директория> Создаёт один файл: - -dump.txt — дерево проекта + содержимое исходных файлов + -dump.md — дерево проекта + содержимое файлов в Markdown Игнорирует типичные артефакты сборки, кэши, IDE-файлы и зависимости. @@ -29,109 +29,28 @@ if [[ ! -d "$TARGET_DIR" ]]; then exit 1 fi -# Привести к абсолютному пути TARGET_DIR="$(cd "$TARGET_DIR" && pwd)" BASENAME=$(basename "$TARGET_DIR") -# Проверка зависимости if ! command -v tree >/dev/null 2>&1; then echo "Ошибка: требуется утилита 'tree'. Установите её (например, apt install tree)." >&2 exit 1 fi -# Расширенный список игнорируемых паттернов -# Охватывает: Python, Node.js, Rust, Go, C/C++ (CMake, build dirs), Java, .NET, CI, OS, etc. IGNORE_LIST=( - "third_party" - "3rd_party" - "3rdparty" - ".git" - ".svn" - ".hg" - "node_modules" - "__pycache__" - "*.pyc" - ".venv" - "venv" - "env" - ".env" - ".idea" - ".vscode" - ".vs" - ".DS_Store" - "Thumbs.db" - "dist" - "build" - "out" - "target" - ".pytest_cache" - ".mypy_cache" - ".next" - ".nuxt" - ".output" - ".svelte-kit" - "coverage" - ".cache" - ".parcel-cache" - ".eslintcache" - ".yarn" - "yarn-error.log" - "package-lock.json" - "yarn.lock" - "pnpm-lock.yaml" - "Cargo.lock" - "go.sum" - ".gradle" - "gradle" - ".mvn" - "mvnw" - "mvnw.cmd" - "*.swp" - "*.swo" - ".stack-work" - "_build" - "deps" - ".cargo" - ".rustup" - ".clangd" - ".ccls-cache" - "CMakeFiles" - "CMakeCache.txt" - "CTestTestfile.cmake" - "cmake_install.cmake" - "*.dSYM" - "*.ilk" - "*.pdb" - "*.obj" - "*.o" - "*.so" - "*.dylib" - "*.dll" - "*.exe" - "*.bin" - "*.hex" - "*.elf" - "tags" - "TAGS" - "GPATH" - "GTAGS" - "GRTAGS" - "GSYMS" - ".github" - ".gitlab" - ".circleci" - ".travis.yml" - "Jenkinsfile" - "Dockerfile*" - "docker-compose*.yml" - "*.log" - "logs" - "tmp" - "temp" - ".terraform" - ".tfstate" - ".tfstate.backup" - "*.tfvars" + "third_party" "3rd_party" "3rdparty" ".git" ".svn" ".hg" "node_modules" + "__pycache__" "*.pyc" ".venv" "venv" "env" ".env" ".idea" ".vscode" ".vs" + ".DS_Store" "Thumbs.db" "dist" "build" "out" "target" ".pytest_cache" + ".mypy_cache" ".next" ".nuxt" ".output" ".svelte-kit" "coverage" ".cache" + ".parcel-cache" ".eslintcache" ".yarn" "yarn-error.log" "package-lock.json" + "yarn.lock" "pnpm-lock.yaml" "Cargo.lock" "go.sum" ".gradle" "gradle" + ".mvn" "mvnw" "mvnw.cmd" "*.swp" "*.swo" ".stack-work" "_build" "deps" + ".cargo" ".rustup" ".clangd" ".ccls-cache" "CMakeFiles" "CMakeCache.txt" + "CTestTestfile.cmake" "cmake_install.cmake" "*.dSYM" "*.ilk" "*.pdb" + "*.obj" "*.o" "*.so" "*.dylib" "*.dll" "*.exe" "*.bin" "*.hex" "*.elf" + "tags" "TAGS" "GPATH" "GTAGS" "GRTAGS" "GSYMS" ".github" ".gitlab" + ".circleci" ".travis.yml" "Jenkinsfile" "Dockerfile*" "docker-compose*.yml" + "*.log" "logs" "tmp" "temp" ".terraform" ".tfstate" ".tfstate.backup" "*.tfvars" ) # === Подготовка find-аргументов === @@ -149,10 +68,7 @@ FIND_CMD=(find "$TARGET_DIR" \( -false "${FIND_IGNORE_ARGS[@]}" \) -prune -o -ty # === Подготовка шаблонов для tree === TREE_IGNORE_PATTERNS="" for pat in "${IGNORE_LIST[@]}"; do - # tree работает только с именами, не путями → берём базовое имя base_pat="${pat%%/*}" - # Убираем звёздочки? Нет — tree поддерживает glob, но * может мешать. - # Однако мы оставляем как есть, т.к. tree -I '*.pyc|node_modules' — нормально. if [[ -z "$TREE_IGNORE_PATTERNS" ]]; then TREE_IGNORE_PATTERNS="$base_pat" else @@ -160,24 +76,40 @@ for pat in "${IGNORE_LIST[@]}"; do fi done -OUTPUT_FILE="${BASENAME}-dump.txt" +OUTPUT_FILE="${BASENAME}-dump.md" { - echo "========================================" - echo "PROJECT STRUCTURE (via tree)" - echo "========================================" - tree -I "$TREE_IGNORE_PATTERNS" "$TARGET_DIR" - echo -e "\n\n" + echo "# PROJECT: $BASENAME" + echo "Generated on: $(date)" + echo -e "\n## PROJECT STRUCTURE" + echo '```text' + tree -n -I "$TREE_IGNORE_PATTERNS" "$TARGET_DIR" + echo '```' + echo -e "\n---\n" - echo "========================================" - echo "SOURCE CODE CONTENTS" - echo "========================================" + echo "## SOURCE CODE CONTENTS" while IFS= read -r -d '' file; do - echo "----------------------------------------" - echo "// FILE: $file" - echo "----------------------------------------" + # Пропускаем явно бинарные файлы по расширению, если нужно + # Но пока просто оформляем контент + + ext="${file##*.}" + # Маппинг для расширений без которых ИИ грустит + case "$ext" in + h|hpp|c|cpp) lang="cpp" ;; + sh) lang="bash" ;; + py) lang="python" ;; + md) lang="markdown" ;; + *) lang="$ext" ;; + esac + + # Если расширения нет + if [[ "$ext" == "$file" ]]; then lang="text"; fi + + echo "### File: $file" + echo " \`\`\`$lang" cat "$file" - echo -e "\n" + echo -e "\n \`\`\`" + echo -e "\n---\n" done < <("${FIND_CMD[@]}") } > "$OUTPUT_FILE"