191 lines
7.2 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/sh
# Скрипт для отображения дерева зависимостей пакета в FreeBSD
show_usage() {
echo "Использование: $0 [-s] <имя пакета>"
echo "Опции:"
echo " -s Показывать системные зависимости как 'системная зависимость'"
echo "Примеры:"
echo " $0 nano # Полное дерево зависимостей"
echo " $0 -s nano # Скрыть системные пакеты"
exit 1
}
# Переменные по умолчанию
SHOW_SYSTEM_DETAILS=true
PKG_NAME=""
# Разбор аргументов командной строки
while getopts "s" opt; do
case $opt in
s)
SHOW_SYSTEM_DETAILS=false
;;
\?)
show_usage
;;
esac
done
# Сдвигаем аргументы, чтобы получить имя пакета
shift $((OPTIND - 1))
# Проверка наличия имени пакета
if [ $# -eq 0 ]; then
show_usage
fi
PKG_NAME="$1"
# Проверка установлен ли пакет
if ! pkg info "$PKG_NAME" > /dev/null 2>&1; then
echo "Пакет '$PKG_NAME' не найден или не установлен"
exit 1
fi
# Функция для проверки, является ли пакет системным
# Системные пакеты начинаются с FreeBSD- и содержат версию
is_system_package() {
local pkg="$1"
# Проверяем, начинается ли имя с FreeBSD-
if echo "$pkg" | grep -q "^FreeBSD-"; then
# Проверяем, содержит ли версию (цифры после последнего дефиса)
#if echo "$pkg" | grep -q -- '-[0-9][0-9.]*$'; then
# return 0 # Это системный пакет
#fi
return 0
fi
return 1 # Не системный пакет
}
# Функция для очистки имени пакета (удаляем версию и скобки с библиотеками)
clean_pkg_name() {
local pkg="$1"
# Удаляем все после первого пробела (включая скобки с библиотеками)
echo "$pkg" | awk '{print $1}'
}
# Функция для получения зависимостей пакета
get_deps() {
local pkg="$1"
pkg info -d $(clean_pkg_name "$pkg") 2>/dev/null | tail -n +2 | sed 's/^[[:space:]]*//' | \
while read -r dep_line; do
# Пропускаем пустые строки
[ -z "$dep_line" ] && continue
# Очищаем имя пакета
local clean_dep=$(clean_pkg_name "$dep_line")
# Проверяем, существует ли пакет
if pkg info "$clean_dep" > /dev/null 2>&1; then
echo "$dep_line"
else
# Если пакет не найден, пытаемся получить базовое имя
# (для FreeBSD-clibs-15.0 -> FreeBSD-clibs)
local base_name=$(echo "$clean_dep" | sed 's/-[0-9].*//')
if [ -n "$base_name" ] && pkg info "$base_name" > /dev/null 2>&1; then
echo "$dep_line"
else
# Если не удалось найти, выводим оригинальное имя
echo "$dep_line"
fi
fi
done
}
# Рекурсивная функция для отображения дерева
show_tree() {
local pkg="$1"
local indent="$2"
local is_last="$3"
local processed_pkgs="$4" # Список уже обработанных пакетов
# Проверяем, не обрабатывали ли мы уже этот пакет в данной ветке
if echo "$processed_pkgs" | grep -q "^$pkg$"; then
# Пакет уже был обработан - выводим информацию о циклической зависимости
if [ "$is_last" = "true" ]; then
echo "${indent} └── [циклическая зависимость: $pkg]"
else
echo "${indent}│ └── [циклическая зависимость: $pkg]"
fi
return
fi
# Добавляем текущий пакет в список обработанных
if [ -z "$processed_pkgs" ]; then
processed_pkgs="$pkg"
else
processed_pkgs="$processed_pkgs
$pkg"
fi
# Определяем префиксы для отображения
if [ "$is_last" = "true" ]; then
local prefix="└── "
local next_indent="$indent "
else
local prefix="├── "
local next_indent="$indent"
fi
# Выводим имя пакета или "системная зависимость"
if [ "$SHOW_SYSTEM_DETAILS" = "true" ] || ! is_system_package "$pkg"; then
echo "${indent}${prefix}${pkg}"
else
echo "${indent}${prefix}системная зависимость"
# Для системных зависимостей не показываем дальнейшее дерево, если не включен детальный режим
if [ "$SHOW_SYSTEM_DETAILS" = "false" ]; then
return
fi
fi
# Получаем зависимости текущего пакета
local deps
deps=$(get_deps "$pkg")
if [ -z "$deps" ]; then
# Если зависимостей нет
if [ "$is_last" = "true" ]; then
echo "${indent} └── (нет зависимостей)"
else
echo "${indent}│ └── (нет зависимостей)"
fi
else
# Обрабатываем зависимости
local count=0
local total=$(echo "$deps" | wc -l)
echo "$deps" | while read -r dep; do
count=$((count + 1))
# Пропускаем системные зависимости, если они не в детальном режиме
if [ "$SHOW_SYSTEM_DETAILS" = "false" ] && is_system_package "$dep"; then
# Если это последняя зависимость и она системная
if [ $count -eq $total ]; then
echo "${next_indent}└── системная зависимость"
else
# echo "${next_indent}├── системная зависимость"
fi
continue
fi
if [ $count -eq $total ]; then
# Последняя зависимость
show_tree "$dep" "$next_indent" "true" "$processed_pkgs"
else
# Не последняя зависимость
show_tree "$dep" "$next_indent" "false" "$processed_pkgs"
fi
done
fi
}
# Основная часть скрипта
echo "======= Дерево зависимостей пакета $PKG_NAME ======="
#if [ "$SHOW_SYSTEM_DETAILS" = "false" ]; then
# echo "Режим: системные зависимости скрыты"
#fi
show_tree "$PKG_NAME" "" "true" ""