Чтобы решить задачу, описанную в вашем сообщении, мы можем следовать этому плану:
### Шаги для решения задачи:
1. **Импорт необходимых библиотек**:
- Мы будем использовать `os` для работы с файловой системой, `re` для регулярных выражений и `subprocess` для выполнения команд shell.
2. **Обход директории**:
- Используем `os.walk` для обхода всех файлов и подкаталогов в заданной директории.
3. **Извлечение переменной CMDS**:
- Для каждого `.py` файла будем открывать его и искать определение переменной `CMDS`. Это можно сделать с помощью регулярных выражений.
4. **Сортировка путей**:
- Соберем все найденные команды и их пути, затем отсортируем их в алфавитном порядке.
5. **Выполнение команд**:
- Создадим множество для хранения уже выполненных команд и будем выполнять команды по очереди, проверяя, не была ли команда выполнена ранее.
6. **Обработка ошибок**:
- Обработаем ситуации, когда команды не могут быть выполнены.
7. **Создание requirements.txt** (если требуется):
- Убедимся, что все используемые библиотеки указаны.
### Пример кода:
```python
import os
import re
import subprocess
def extract_cmds_from_file(file_path):
""" Извлекает переменную CMDS из файла, если она есть. """
try:
with open(file_path, 'r') as file:
content = file.read()
match = re.search(r'CMDS\s*=\s*\[(.*?)\]', content, re.DOTALL)
if match:
# Извлекаем команды и убираем лишние пробелы и кавычки
cmds = [cmd.strip().strip('\'"') for cmd in match.group(1).split(',')]
return cmds
except Exception as e:
print(f"Ошибка при обработке файла {file_path}: {e}")
return []
def main(start_directory):
executed_cmds = set()
commands_to_execute = []
# Обход директории и сбор команд
for dirpath, _, filenames in os.walk(start_directory):
for filename in filenames:
if filename.endswith('.py'):
file_path = os.path.join(dirpath, filename)
cmds = extract_cmds_from_file(file_path)
for cmd in cmds:
if cmd not in executed_cmds:
commands_to_execute.append((file_path, cmd))
else:
print(f"Команда уже выполнена: {cmd}")
# Сортировка по имени файла/пути
commands_to_execute.sort(key=lambda x: x[0])
# Выполнение команд
for file_path, cmd in commands_to_execute:
try:
print(f"Выполнение команды из {file_path}: {cmd}")
subprocess.run(cmd, shell=True, check=True)
executed_cmds.add(cmd)
except subprocess.CalledProcessError as e:
print(f"Ошибка выполнения команды {cmd}: {e}")
if __name__ == "__main__":
main('/path/to/start/directory') # Укажите путь к директории, с которой нужно начать
```
### Создание requirements.txt
Для данного скрипта не требуется установки дополнительных сторонних библиотек, так как используется стандартная библиотека Python. Таким образом, файл `requirements.txt` может быть пустым или не нужен вовсе.
### Заключение
Этот код выполняет описанные шаги и решает задачу извлечения и выполнения команд из файлов Python. Обратите внимание, что выполнение команд может быть рискованным, поэтому убедитесь, что команды безопасны!