Обновить projdump.sh
This commit is contained in:
205
projdump.sh
205
projdump.sh
@@ -3,24 +3,40 @@
|
|||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
# ── Настройки (можно менять) ─────────────────────────────────────────────────
|
||||||
|
MAX_FILE_SIZE_KB=100 # Пропускать файлы больше этого размера (КБ)
|
||||||
|
TRUNCATE_LINES=2000 # Обрезать файлы длиннее этого кол-ва строк
|
||||||
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
cat >&2 <<EOF
|
cat >&2 <<EOF
|
||||||
Использование: $0 <директория>
|
Использование: $0 [опции] <директория>
|
||||||
|
|
||||||
Создаёт один файл:
|
Создаёт один файл:
|
||||||
<basename>-dump.txt — дерево проекта + содержимое файлов (без MD-разметки)
|
<basename>-dump.txt — дерево проекта + содержимое файлов
|
||||||
|
|
||||||
Параметры:
|
Опции:
|
||||||
|
-s, --max-size КБ Макс. размер файла в КБ (по умолчанию: $MAX_FILE_SIZE_KB)
|
||||||
|
-l, --max-lines N Обрезать после N строк (по умолчанию: $TRUNCATE_LINES)
|
||||||
-h, --help Показать эту справку
|
-h, --help Показать эту справку
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
if [[ $# -eq 0 ]] || [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then
|
# ── Парсинг аргументов ───────────────────────────────────────────────────────
|
||||||
usage
|
while [[ $# -gt 0 ]]; do
|
||||||
exit 0
|
case "$1" in
|
||||||
fi
|
-s|--max-size) MAX_FILE_SIZE_KB="$2"; shift 2 ;;
|
||||||
|
-l|--max-lines) TRUNCATE_LINES="$2"; shift 2 ;;
|
||||||
|
-h|--help) usage; exit 0 ;;
|
||||||
|
-*) echo "Неизвестная опция: $1" >&2; usage; exit 1 ;;
|
||||||
|
*) TARGET_DIR="$1"; shift ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
TARGET_DIR="$1"
|
if [[ -z "${TARGET_DIR:-}" ]]; then
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ ! -d "$TARGET_DIR" ]]; then
|
if [[ ! -d "$TARGET_DIR" ]]; then
|
||||||
echo "Ошибка: директория '$TARGET_DIR' не существует." >&2
|
echo "Ошибка: директория '$TARGET_DIR' не существует." >&2
|
||||||
@@ -35,24 +51,67 @@ if ! command -v tree >/dev/null 2>&1; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Список игнорирования (оставлен без изменений)
|
# ── Игнорируемые директории и файлы ──────────────────────────────────────────
|
||||||
IGNORE_LIST=(
|
IGNORE_LIST=(
|
||||||
"third_party" "3rd_party" "3rdparty" ".git" ".svn" ".hg" "node_modules"
|
# VCS
|
||||||
"__pycache__" "*.pyc" ".venv" "venv" "env" ".env" ".idea" ".vscode" ".vs"
|
".git" ".svn" ".hg"
|
||||||
".DS_Store" "Thumbs.db" "dist" "build" "out" "target" ".pytest_cache"
|
# Зависимости
|
||||||
".mypy_cache" ".next" ".nuxt" ".output" ".svelte-kit" "coverage" ".cache"
|
"node_modules" "vendor" "third_party" "3rd_party" "3rdparty"
|
||||||
".parcel-cache" ".eslintcache" ".yarn" "yarn-error.log" "package-lock.json"
|
"bower_components" ".pnp" ".pnp.js"
|
||||||
"yarn.lock" "pnpm-lock.yaml" "Cargo.lock" "go.sum" ".gradle" "gradle"
|
# Python
|
||||||
".mvn" "mvnw" "mvnw.cmd" "*.swp" "*.swo" ".stack-work" "_build" "deps"
|
"__pycache__" "*.pyc" "*.pyo" ".venv" "venv" "env" ".env"
|
||||||
".cargo" ".rustup" ".clangd" ".ccls-cache" "CMakeFiles" "CMakeCache.txt"
|
".mypy_cache" ".pytest_cache" ".ruff_cache" ".tox" "*.egg-info"
|
||||||
"CTestTestfile.cmake" "cmake_install.cmake" "*.dSYM" "*.ilk" "*.pdb"
|
# IDE / редакторы
|
||||||
"*.obj" "*.o" "*.so" "*.dylib" "*.dll" "*.exe" "*.bin" "*.hex" "*.elf"
|
".idea" ".vscode" ".vs" "*.swp" "*.swo" "*~"
|
||||||
"tags" "TAGS" "GPATH" "GTAGS" "GRTAGS" "GSYMS" ".github" ".gitlab"
|
# OS
|
||||||
".circleci" ".travis.yml" "Jenkinsfile" "Dockerfile*" "docker-compose*.yml"
|
".DS_Store" "Thumbs.db" "desktop.ini"
|
||||||
"*.log" "logs" "tmp" "temp" ".terraform" ".tfstate" ".tfstate.backup" "*.tfvars"
|
# Сборка / выходные директории
|
||||||
|
"dist" "build" "out" "target" "_build" "release"
|
||||||
|
# JS / фронтенд
|
||||||
|
".next" ".nuxt" ".output" ".svelte-kit" ".parcel-cache"
|
||||||
|
".eslintcache" "coverage" ".cache" ".turbo"
|
||||||
|
# Lock-файлы
|
||||||
|
"package-lock.json" "yarn.lock" "pnpm-lock.yaml" "bun.lockb"
|
||||||
|
"Cargo.lock" "go.sum" "Gemfile.lock" "poetry.lock"
|
||||||
|
"composer.lock" "Pipfile.lock" "flake.lock"
|
||||||
|
# Yarn
|
||||||
|
".yarn" "yarn-error.log"
|
||||||
|
# Java / Kotlin / Gradle / Maven
|
||||||
|
".gradle" "gradle" ".mvn" "mvnw" "mvnw.cmd"
|
||||||
|
# Rust / Go / Haskell
|
||||||
|
".cargo" ".rustup" ".stack-work" "deps"
|
||||||
|
# C / C++
|
||||||
|
".clangd" ".ccls-cache" "CMakeFiles" "CMakeCache.txt"
|
||||||
|
"CTestTestfile.cmake" "cmake_install.cmake"
|
||||||
|
# Скомпилированные бинарники
|
||||||
|
"*.dSYM" "*.ilk" "*.pdb" "*.obj" "*.o" "*.so" "*.dylib"
|
||||||
|
"*.dll" "*.exe" "*.bin" "*.hex" "*.elf" "*.a" "*.lib" "*.class"
|
||||||
|
# Теги
|
||||||
|
"tags" "TAGS" "GPATH" "GTAGS" "GRTAGS" "GSYMS"
|
||||||
|
# CI / CD / Docker
|
||||||
|
".github" ".gitlab" ".circleci" ".travis.yml"
|
||||||
|
"Jenkinsfile" "Dockerfile*" "docker-compose*.yml"
|
||||||
|
# Логи / временные
|
||||||
|
"*.log" "logs" "tmp" "temp"
|
||||||
|
# Terraform
|
||||||
|
".terraform" ".tfstate" ".tfstate.backup" "*.tfvars"
|
||||||
|
# Минифицированные файлы
|
||||||
|
"*.min.js" "*.min.css" "*.min.map"
|
||||||
|
# Source maps
|
||||||
|
"*.map"
|
||||||
|
# Медиа / шрифты / бинарные ассеты
|
||||||
|
"*.png" "*.jpg" "*.jpeg" "*.gif" "*.bmp" "*.ico" "*.icns"
|
||||||
|
"*.webp" "*.avif" "*.svg" "*.mp3" "*.mp4" "*.avi" "*.mov"
|
||||||
|
"*.mkv" "*.wav" "*.flac" "*.ogg" "*.webm"
|
||||||
|
"*.woff" "*.woff2" "*.ttf" "*.otf" "*.eot"
|
||||||
|
"*.pdf" "*.doc" "*.docx" "*.xls" "*.xlsx" "*.ppt" "*.pptx"
|
||||||
|
"*.zip" "*.tar" "*.gz" "*.bz2" "*.xz" "*.7z" "*.rar"
|
||||||
|
"*.db" "*.sqlite" "*.sqlite3"
|
||||||
|
"*.jar" "*.war" "*.ear"
|
||||||
|
"*.iso" "*.dmg" "*.img"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Подготовка аргументов для find
|
# ── Подготовка аргументов для find ───────────────────────────────────────────
|
||||||
FIND_IGNORE_ARGS=()
|
FIND_IGNORE_ARGS=()
|
||||||
for pat in "${IGNORE_LIST[@]}"; do
|
for pat in "${IGNORE_LIST[@]}"; do
|
||||||
if [[ "$pat" == */* ]]; then
|
if [[ "$pat" == */* ]]; then
|
||||||
@@ -64,7 +123,7 @@ done
|
|||||||
|
|
||||||
FIND_CMD=(find "$TARGET_DIR" \( -false "${FIND_IGNORE_ARGS[@]}" \) -prune -o -type f -print0)
|
FIND_CMD=(find "$TARGET_DIR" \( -false "${FIND_IGNORE_ARGS[@]}" \) -prune -o -type f -print0)
|
||||||
|
|
||||||
# Подготовка шаблонов для tree
|
# ── Подготовка шаблонов для tree ─────────────────────────────────────────────
|
||||||
TREE_IGNORE_PATTERNS=""
|
TREE_IGNORE_PATTERNS=""
|
||||||
for pat in "${IGNORE_LIST[@]}"; do
|
for pat in "${IGNORE_LIST[@]}"; do
|
||||||
base_pat="${pat%%/*}"
|
base_pat="${pat%%/*}"
|
||||||
@@ -75,29 +134,113 @@ for pat in "${IGNORE_LIST[@]}"; do
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# ── Проверка: текстовый ли файл ─────────────────────────────────────────────
|
||||||
|
is_text_file() {
|
||||||
|
local f="$1"
|
||||||
|
local mime
|
||||||
|
mime=$(file --brief --mime-type "$f" 2>/dev/null || echo "unknown")
|
||||||
|
case "$mime" in
|
||||||
|
text/*|application/json|application/xml|application/javascript|\
|
||||||
|
application/x-shellscript|application/x-httpd-php|application/toml|\
|
||||||
|
application/x-yaml|application/x-ruby|application/x-perl|\
|
||||||
|
application/x-python|inode/x-empty)
|
||||||
|
return 0 ;;
|
||||||
|
*)
|
||||||
|
return 1 ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Форматирование размера ───────────────────────────────────────────────────
|
||||||
|
human_size() {
|
||||||
|
local bytes=$1
|
||||||
|
if (( bytes < 1024 )); then
|
||||||
|
echo "${bytes} B"
|
||||||
|
elif (( bytes < 1048576 )); then
|
||||||
|
echo "$(( bytes / 1024 )) KB"
|
||||||
|
else
|
||||||
|
echo "$(awk "BEGIN {printf \"%.1f MB\", $bytes/1048576}")"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Генерация дампа ──────────────────────────────────────────────────────────
|
||||||
OUTPUT_FILE="${BASENAME}-dump.txt"
|
OUTPUT_FILE="${BASENAME}-dump.txt"
|
||||||
|
MAX_FILE_SIZE_BYTES=$(( MAX_FILE_SIZE_KB * 1024 ))
|
||||||
|
|
||||||
|
FILE_COUNT=0
|
||||||
|
SKIPPED_BINARY=0
|
||||||
|
SKIPPED_SIZE=0
|
||||||
|
TRUNCATED=0
|
||||||
|
|
||||||
{
|
{
|
||||||
echo "==============================================================================="
|
echo "==============================================================================="
|
||||||
echo "PROJECT NAME: $BASENAME"
|
echo "PROJECT NAME: $BASENAME"
|
||||||
echo "GENERATED ON: $(date)"
|
echo "GENERATED ON: $(date)"
|
||||||
|
echo "MAX FILE SIZE: ${MAX_FILE_SIZE_KB} KB"
|
||||||
|
echo "TRUNCATE AFTER: ${TRUNCATE_LINES} lines"
|
||||||
echo "==============================================================================="
|
echo "==============================================================================="
|
||||||
echo -e "\n--- PROJECT STRUCTURE ---"
|
echo ""
|
||||||
|
echo "--- PROJECT STRUCTURE ---"
|
||||||
tree -n -I "$TREE_IGNORE_PATTERNS" "$TARGET_DIR"
|
tree -n -I "$TREE_IGNORE_PATTERNS" "$TARGET_DIR"
|
||||||
echo -e "\n==============================================================================="
|
echo ""
|
||||||
|
echo "==============================================================================="
|
||||||
echo "SOURCE CODE CONTENTS"
|
echo "SOURCE CODE CONTENTS"
|
||||||
echo "==============================================================================="
|
echo "==============================================================================="
|
||||||
|
|
||||||
while IFS= read -r -d '' file; do
|
while IFS= read -r -d '' file; do
|
||||||
# Относительный путь для красоты
|
|
||||||
rel_path="${file#$TARGET_DIR/}"
|
rel_path="${file#$TARGET_DIR/}"
|
||||||
|
file_size=$(stat -c%s "$file" 2>/dev/null || stat -f%z "$file" 2>/dev/null || echo 0)
|
||||||
|
|
||||||
echo -e "\nFILE: $rel_path"
|
# Проверка размера
|
||||||
|
if (( file_size > MAX_FILE_SIZE_BYTES )); then
|
||||||
|
echo ""
|
||||||
|
echo "FILE: $rel_path ($(human_size "$file_size"))"
|
||||||
echo "-------------------------------------------------------------------------------"
|
echo "-------------------------------------------------------------------------------"
|
||||||
|
echo "[SKIPPED — file exceeds ${MAX_FILE_SIZE_KB} KB limit]"
|
||||||
|
echo "-------------------------------------------------------------------------------"
|
||||||
|
(( SKIPPED_SIZE++ ))
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Проверка: текстовый ли
|
||||||
|
if ! is_text_file "$file"; then
|
||||||
|
(( SKIPPED_BINARY++ ))
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
line_count=$(wc -l < "$file" || echo 0)
|
||||||
|
FILE_COUNT=$(( FILE_COUNT + 1 ))
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "FILE: $rel_path (${line_count} lines, $(human_size "$file_size"))"
|
||||||
|
echo "-------------------------------------------------------------------------------"
|
||||||
|
|
||||||
|
if (( line_count > TRUNCATE_LINES )); then
|
||||||
|
head -n "$TRUNCATE_LINES" "$file"
|
||||||
|
echo ""
|
||||||
|
echo "[TRUNCATED — showing first ${TRUNCATE_LINES} of ${line_count} lines]"
|
||||||
|
(( TRUNCATED++ ))
|
||||||
|
else
|
||||||
cat "$file"
|
cat "$file"
|
||||||
echo -e "\n-------------------------------------------------------------------------------"
|
fi
|
||||||
echo "END OF FILE: $rel_path"
|
|
||||||
done < <("${FIND_CMD[@]}")
|
echo ""
|
||||||
|
echo "-------------------------------------------------------------------------------"
|
||||||
|
done < <("${FIND_CMD[@]}" | sort -z)
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "==============================================================================="
|
||||||
|
echo "SUMMARY"
|
||||||
|
echo "==============================================================================="
|
||||||
|
echo "Files included: $FILE_COUNT"
|
||||||
|
echo "Skipped (binary): $SKIPPED_BINARY"
|
||||||
|
echo "Skipped (too large): $SKIPPED_SIZE"
|
||||||
|
echo "Truncated: $TRUNCATED"
|
||||||
|
echo "==============================================================================="
|
||||||
} > "$OUTPUT_FILE"
|
} > "$OUTPUT_FILE"
|
||||||
|
|
||||||
echo "Готово: $OUTPUT_FILE"
|
echo "Готово: $OUTPUT_FILE"
|
||||||
|
echo " Файлов включено: $FILE_COUNT"
|
||||||
|
echo " Пропущено (бинарные): $SKIPPED_BINARY"
|
||||||
|
echo " Пропущено (большие): $SKIPPED_SIZE"
|
||||||
|
echo " Обрезано: $TRUNCATED"
|
||||||
|
echo " Размер дампа: $(human_size "$(stat -c%s "$OUTPUT_FILE" 2>/dev/null || stat -f%z "$OUTPUT_FILE")")"
|
||||||
|
|||||||
Reference in New Issue
Block a user