- Выполненный вариант: Medium
- Цель: Освоить работу с файловой системой средствами Python, реализовать основные команды управления файлами, научиться вести журнал действий пользователя и освоить расширение функциональности за счёт механизма отмены действий.
- Используемые библиотеки:
pathlib,shutil,os,argparse,shlex,re,zipfile,tarfile,logging.
Проект представляет собой интерактивную командную оболочку (shell), написанную на Python без использования системных вызовов (subprocess). Все операции выполняются средствами стандартной библиотеки Python.
Все аргументы, принимающие пути поддерживают .. (родительский каталог), ~ (домашний каталог) и абсолютные/относительные пути.
ls [-l] [path]: Отображение списка файлов и каталогов. Поддерживает флаг-lдля вывода детальной информации (права, размер, дата изменения, имя).cd [path]: Переход в указанный каталог. По умолчанию переходит в домашний каталог (~).cat <file_path> ...: Вывод содержимого одного или нескольких файлов в консоль.cp [-r] <source> <destination>: Копирование файлов. С флагом-rрекурсивно копирует каталоги.mv <source> <destination>: Перемещение или переименование файлов и каталогов.rm [-r] [-f] <path>: Удление (перемещение) файла или каталога в корзину (.trash).- Не удаляет файлы необратимо, а перемещает их для возможности восстановления.
- Требует флаг
-rдля рекурсивной обработки каталогов. - При обработке каталога запрашивает подтверждение (
Y/n) (можно пропустить с флагом-f). - Содержит защиту от удаления родительских каталогов, оттносительно текущей рабочей директории, в том числе корневых каталогов (
/илиC:\).
history [N]: Вывод последнихN(по умолчанию 100) введенных команд.undo: Отмена последней обратимой операции (cp,mv,rm).grep [-i] [-r] <pattern> <path>: Поиск текста по шаблону (регулярному выражению) в файлах.-i: Поиск без учета регистра.-r: Рекурсивный поиск в каталоге.
zip <folder> <archive_name>: Создание ZIP-архива из указанного каталога.unzip <archive_name> [-d <path>]: Распаковка ZIP-архива в указанный (по умолчанию текущий) каталог.tar <folder> <archive_name>: Создание TAR.GZ-архива из указанного каталога.untar <archive_name> [-d <path>]: Распаковка TAR.GZ-архива в указанный (по умолчанию текущий) каталог.
- Логирование: Все выполненные команды, их статус (успех/ошибка) и сообщения об ошибках записываются в файл
shell.log. - История команд: Вся история вводимых команд сохраняется в файле
.history, сохраняясь между сессиями. - Механизм отмены: Информация для отмены операций
cp,mv,rmсохраняется в файле.undo. - Безопасное удаление: Файлы не удаляются навсегда, а перемещаются в папку
.trashс уникальным именем (добавляется timestamp). - Стилизованное приглашение: Приглашение для ввода команды имеет двухстрочный вид и использует цвета для лучшей читаемости.
- Работа с путями: Команды поддерживают абсолютные и относительные пути, а также
~для обозначения домашней директории. Вся работа с путями ведется через библиотекуpathlib. cpиmv: Эти команды не создают промежуточные родительские каталоги для объекта. Если родительская папка для пути назначения не существует, команда вернет ошибку.rm: Команда не удаляет файлы безвозвратно, а перемещает их в папку.trash, расположенную в корневой директории проекта. Это сделано для реализации механизмаundo- возможности восстановить файл.undo: Отменяет только последнюю успешную операцию из числа обратимых (cp,mv,rm). В файл.undoв корне проекта сохраняет всю необходимую информацию для отмены этих команд (и только они).- Обработка ошибок: При возникновении ошибок (файл не найден, отказано в доступе и т.д.) оболочка выводит информативное сообщение и продолжает свою работу, не закрываясь.
- Формат вывода: Вывод команд, например таких как
lsиcat, производится посредством специального объектаCommandOutputв обход стандартногоprint. Это позволяет ядру оболочки получить результат выполнения в виде строки, вывести его в консоль, а также делает возможным автоматическое тестирование вывода, возвращая результат команды из функцииexecute_command.
- ООП: Каждая команда (
ls,cd,cpи т.д.) реализована как отдельный класс, наследуемый от абстрактного базового классаCommand. - Расширяемость Наличие классов позволяет легко добавлять новые команды, не изменяя ядро оболочки благодаря методу
register_command, я вдохновлялся идеей того, как происходит регистрация эндпойнтов (хендлеров/обработчиков) вFastAPI, и попытался сделать похожее. - Модульная архитектура: Проект разделен на логические модули, расположенные в директории
src/:commands/: Реализация каждой отдельной команды.archive/,search/: Модули для продвинутых командzip,tarиgrepсоответственно.utils/: Вспомогательные утилиты (логгер, обработчик истории, генератор строки приглашения ввода, обработчик путей т.д.).shell.py: Ядро оболочки, отвечающее за основной цикл, регистрацию и вызов команд.config.py: Централизованное хранение путей к служебным файлам (.history,.undo,.trash).
- Обработка аргументов: Для парсинга аргументов командной строки используется стандартная библиотека
argparse. Был создан собственный класс-наследникArgParser, который не завершает работу приложения при ошибках или вызове--help(как это делает стандартный), а вместо этого выбрасывает исключения. Это позволяет ядру оболочки перехватывать их и корректно обрабатывать. - Централизованное управление состоянием: Служебные файлы (
.history,.undo,.trash) создаются и управляются централизованно изshell.pyиconfig.py, что гарантирует их предсказуемое расположение в корне проекта. - Тестируемость: Благодаря тому, что метод
execute_commandвозвращает весь текстовый вывод команды, проект легко поддается автоматическому тестированию с помощьюpytest. Для тестов создается изолированная подготовленная файловая структура (как песочница) с помощьюpytest.fixture. При этом командная оболочка единая дла всех тестов, но для каждого теста создается заново вся файловая "песочница", чтобы тесты были изолированны. - Разделение тестов: Модульные тесты разделены на логические файлы, на команды меняющие файловую структуру (типа
rm,mv), на команды которые выводят информацию (типаls,cat), на продвинутые команды (типаgrep,zip,tar), на команды работы с историей и отменой дейтсвия (cat,mv,cp) и отдельно проверкаcd.
python3 -m venv .venv
# Активировать его в Linux/mac OS
source .venv/bin/activate
# Активировать его в Windows
.venv\Scripts\activateВ этой лабе не используются зависимости для работы приложения, а только для тестов pytest.
pip install -r requirements.txtpython -m src.main
# Если есть еще Python 2.x
python3 -m src.mainpytest