193 lines
4.9 KiB
Bash
Executable File
193 lines
4.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# projdump.sh — dump project structure and source code into text files
|
||
|
||
set -euo pipefail
|
||
|
||
usage() {
|
||
cat >&2 <<EOF
|
||
Использование: $0 <директория>
|
||
|
||
Создаёт два файла:
|
||
<basename>-tree.txt — дерево проекта (через tree)
|
||
<basename>-code.txt — содержимое всех исходных файлов
|
||
|
||
Игнорирует типичные артефакты сборки, кэши, IDE-файлы и зависимости.
|
||
|
||
Параметры:
|
||
-h, --help Показать эту справку
|
||
EOF
|
||
}
|
||
|
||
if [[ $# -eq 0 ]] || [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then
|
||
usage
|
||
exit 0
|
||
fi
|
||
|
||
TARGET_DIR="$1"
|
||
|
||
if [[ ! -d "$TARGET_DIR" ]]; then
|
||
echo "Ошибка: директория '$TARGET_DIR' не существует." >&2
|
||
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"
|
||
)
|
||
|
||
# === Подготовка аргументов для find ===
|
||
FIND_IGNORE_ARGS=()
|
||
for pat in "${IGNORE_LIST[@]}"; do
|
||
# Для шаблонов с /* или * внутри — используем -name или -path соответственно
|
||
if [[ "$pat" == */* ]]; then
|
||
FIND_IGNORE_ARGS+=(-o -path "*/$pat")
|
||
else
|
||
FIND_IGNORE_ARGS+=(-o -name "$pat")
|
||
fi
|
||
done
|
||
|
||
# Строим команду find: пропускаем игнорируемые, печатаем остальные файлы
|
||
# \( -false ... \) гарантирует корректную логику без начального -o
|
||
FIND_CMD=(find "$TARGET_DIR" \( -false "${FIND_IGNORE_ARGS[@]}" \) -prune -o -type f -print0)
|
||
|
||
# === Паттерны для tree (только имена, без путей; tree использует glob-паттерны через |) ===
|
||
TREE_IGNORE_PATTERNS=""
|
||
for i in "${!IGNORE_LIST[@]}"; do
|
||
pat="${IGNORE_LIST[i]}"
|
||
# tree не поддерживает пути — только имена файлов/директорий
|
||
# поэтому берём только basename шаблона, если он содержит /
|
||
if [[ "$pat" == */* ]]; then
|
||
# Например, ".github/workflows" → игнорируем только ".github"
|
||
base_pat="${pat%%/*}"
|
||
else
|
||
base_pat="$pat"
|
||
fi
|
||
# Удаляем звёздочки для tree? Нет — tree поддерживает * в -I
|
||
if [[ -z "$TREE_IGNORE_PATTERNS" ]]; then
|
||
TREE_IGNORE_PATTERNS="$base_pat"
|
||
else
|
||
TREE_IGNORE_PATTERNS="$TREE_IGNORE_PATTERNS|$base_pat"
|
||
fi
|
||
done
|
||
|
||
# === Сбор кода ===
|
||
{
|
||
while IFS= read -r -d '' file; do
|
||
echo "========================================"
|
||
echo "// FILE: $file"
|
||
echo "========================================"
|
||
cat "$file"
|
||
echo -e "\n\n"
|
||
done < <("${FIND_CMD[@]}")
|
||
} > "${BASENAME}-code.txt"
|
||
|
||
# === Построение дерева ===
|
||
tree -I "$TREE_IGNORE_PATTERNS" "$TARGET_DIR" > "${BASENAME}-tree.txt"
|
||
|
||
echo "Готово:"
|
||
echo " Дерево: ${BASENAME}-tree.txt"
|
||
echo " Код: ${BASENAME}-code.txt"
|
||
|