commit 63ec420edde5a6cbc9c5065a09ade65f5f24b183 Author: svsp Date: Sat Jan 31 07:51:45 2026 +0500 Инициализация репозитория diff --git a/cpm b/cpm new file mode 100755 index 0000000..366dd86 --- /dev/null +++ b/cpm @@ -0,0 +1,142 @@ +#!/bin/sh + +# CPM - Calista Package Manager +# Версия: 1.2 + +# Проверяем, установлен ли pkg +if ! command -v pkg >/dev/null 2>&1; then + echo "Ошибка: pkg не установлен или не найден в PATH" >&2 + exit 1 +fi + +# Функция для фильтрации стандартных пакетов FreeBSD +filter_freebsd_packages() { + pkg info | grep -v '^FreeBSD-' +} + +# Функция для получения списка пользовательских пакетов (корневых) +get_custom_packages() { + filter_freebsd_packages | awk '{print $1}' +} + +# Функция для получения имен всех установленных пакетов +get_all_packages() { + pkg info | awk '{print $1}' +} + +# Обработка команд +case "$1" in + "info") + if [ "$2" = "-v" ]; then + # Подробная информация о каждом пользовательском пакете + get_custom_packages | while read -r package; do + echo "=== Информация о пакете: $package ===" + pkg info "$package" + echo "" + done + elif [ "$2" = "-dtree" ]; then + build_dependency_tree + else + # Простой список пользовательских пакетов + filter_freebsd_packages + fi + ;; + + "deptree") + deptree -s "$2" + ;; + + "install") + if [ -z "$2" ]; then + echo "Использование: cpm install <имя_пакета>" >&2 + exit 1 + fi + shift + pkg install "$@" + ;; + + "delete"|"remove") + if [ -z "$2" ]; then + echo "Использование: cpm $1 <имя_пакета>" >&2 + exit 1 + fi + shift + pkg delete "$@" + ;; + + "autoremove") + pkg autoremove + ;; + + "upgrade") + pkg upgrade + ;; + + "update") + pkg update + ;; + + "search") + if [ -z "$2" ]; then + echo "Использование: cpm search <запрос>" >&2 + exit 1 + fi + shift + pkg search "$@" + ;; + + "clean") + pkg clean + ;; + + "version"|"-v"|"--version") + echo "CPM - Calista Package Manager wrapper v1.2" + echo "Использует: $(pkg -v)" + ;; + + "help"|"-h"|"--help") + cat << EOF +CPM - Calista Package Manager + +Использование: cpm <команда> [опции] + +Команды: + info Список установленных пакетов (без стандартных FreeBSD) + info -v Подробная информация о всех пользовательских пакетах + info -dtree Дерево зависимостей пользовательских пакетов + deptree <пакет> Полное дерево зависимостей для конкретного пакета + install <пакет> Установить пакет + delete <пакет> Удалить пакет + autoremove Удалить неиспользуемые зависимости + upgrade Обновить все пакеты + update Обновить репозиторий пакетов + search <запрос> Поиск пакетов + clean Очистить кэш пакетов + version Показать версию + help Показать эту справку + +Примеры: + cpm info + cpm info -v + cpm info -dtree + cpm deptree nano + cpm install nano + cpm delete nano + cpm search python +EOF + ;; + + *) + if [ -z "$1" ]; then + echo "Использование: cpm <команда>" >&2 + echo "Для справки: cpm help" >&2 + exit 1 + else + echo "Неизвестная команда: $1" >&2 + echo "Для справки: cpm help" >&2 + exit 1 + fi + ;; +esac + +exit 0 diff --git a/deptree b/deptree new file mode 100755 index 0000000..4a9a1d8 --- /dev/null +++ b/deptree @@ -0,0 +1,190 @@ +#!/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" ""