aenvs/.docs/02-opus-cli-docs/03-commands.md

483 lines
13 KiB
Markdown
Raw Permalink 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.

# Commands
## Обзор команд
| Команда | Описание |
|---------|----------|
| `aevs config` | Настройка глобального конфига (credentials) |
| `aevs init` | Инициализация проекта в текущей директории |
| `aevs push` | Загрузить .env файлы в storage |
| `aevs pull` | Скачать .env файлы из storage |
| `aevs list` | Показать список проектов в storage |
| `aevs status` | Показать статус текущего проекта |
---
## `aevs config`
Интерактивная настройка глобального конфига.
### Синтаксис
```bash
aevs config
```
### Поведение
1. Запрашивает параметры storage интерактивно
2. Проверяет подключение к storage (list bucket)
3. Сохраняет в `~/.config/aevs/config.yaml`
4. Устанавливает права `0600` на файл
### Пример сессии
```
$ aevs config
AEVS Configuration
==================
Storage type (s3): s3
S3 Endpoint (https://s3.amazonaws.com):
AWS Region (us-east-1): eu-central-1
Bucket name: my-envs-bucket
Access Key ID: AKIA...
Secret Access Key: ****
Testing connection...
✓ Successfully connected to s3://my-envs-bucket
Config saved to ~/.config/aevs/config.yaml
```
### Ошибки
| Ситуация | Сообщение |
|----------|-----------|
| Невалидные credentials | `Error: Access Denied. Check your credentials.` |
| Bucket не существует | `Error: Bucket "xxx" not found.` |
| Сетевая ошибка | `Error: Could not connect to endpoint.` |
---
## `aevs init`
Инициализация проекта в текущей директории.
### Синтаксис
```bash
aevs init [project-name]
```
### Аргументы
| Аргумент | Обязательный | Описание |
|----------|--------------|----------|
| `project-name` | нет | Имя проекта. По умолчанию: имя текущей директории |
### Флаги
| Флаг | Сокращение | Описание |
|------|------------|----------|
| `--force` | `-f` | Перезаписать существующий `aevs.yaml` |
### Поведение (новый проект)
1. Проверяет, что `aevs.yaml` не существует
2. Сканирует директорию на `.env*` файлы (см. [File Scanning](#file-scanning))
3. Если `project-name` не указан — запрашивает интерактивно (default: имя папки)
4. Создаёт `aevs.yaml` с найденными файлами
5. Выводит результат
### Поведение (проект существует)
1. Если `aevs.yaml` существует и нет `--force`:
- Сканирует на новые `.env*` файлы
- Предлагает добавить новые файлы в конфиг
2. Если `--force`:
- Перезаписывает конфиг полностью
### Пример сессии
```
$ aevs init my-project
Scanning for env files...
Found 3 env files:
✓ .env.prod
✓ .env.dev
✓ docker/.env
Created aevs.yaml for project "my-project"
Next steps:
1. Review aevs.yaml
2. Run 'aevs push' to upload files
```
### Пример (добавление новых файлов)
```
$ aevs init
Project "my-project" already initialized.
Scanning for new env files...
Found 1 new file:
+ services/.env.api
Add to aevs.yaml? [Y/n]: y
Updated aevs.yaml
```
### File Scanning
**Паттерны для включения:**
- `.env` — точное совпадение
- `.env.*` — например `.env.prod`, `.env.local`, `.env.development`
- `*.env` — например `docker.env`, `app.env`
**Игнорируемые директории:**
- `node_modules/`
- `.git/`
- `vendor/`
- `venv/`, `.venv/`
- `__pycache__/`
- `.idea/`, `.vscode/`
**Игнорируемые файлы:**
- `.env.example`
- `.env.sample`
- `.env.template`
### Ошибки
| Ситуация | Сообщение |
|----------|-----------|
| Config существует | `Error: aevs.yaml already exists. Use --force to overwrite.` |
| Невалидное имя проекта | `Error: Invalid project name. Use only a-z, 0-9, -, _` |
| Нет env файлов | `Warning: No env files found. Add files manually to aevs.yaml` |
---
## `aevs push`
Загружает локальные `.env` файлы в storage.
### Синтаксис
```bash
aevs push
```
### Флаги
| Флаг | Сокращение | Описание |
|------|------------|----------|
| `--config` | `-c` | Путь к конфигу (default: `./aevs.yaml`) |
| `--dry-run` | | Показать что будет загружено, без реальной загрузки |
### Поведение
1. Читает `aevs.yaml`
2. Проверяет существование всех файлов из `files`
3. Создаёт tar.gz архив в памяти
4. Загружает архив в `{bucket}/{project}/envs.tar.gz`
5. Загружает metadata в `{bucket}/{project}/metadata.json`
6. Выводит результат
### Структура архива
```
envs.tar.gz
├── .env.prod
├── .env.dev
└── docker/
└── .env
```
Пути в архиве сохраняются относительно корня проекта.
### Пример вывода
```
$ aevs push
Pushing "my-project" to storage...
✓ .env.prod (234 bytes)
✓ .env.dev (189 bytes)
✓ docker/.env (56 bytes)
Uploaded to s3://my-envs-bucket/my-project/envs.tar.gz
Total: 3 files, 479 bytes
```
### Пример (dry-run)
```
$ aevs push --dry-run
Dry run - no changes will be made
Would upload:
.env.prod (234 bytes)
.env.dev (189 bytes)
docker/.env (56 bytes)
Target: s3://my-envs-bucket/my-project/envs.tar.gz
```
### Ошибки
| Ситуация | Сообщение |
|----------|-----------|
| Нет aevs.yaml | `Error: No aevs.yaml found. Run 'aevs init' first.` |
| Нет глобального конфига | `Error: No storage configured. Run 'aevs config' first.` |
| Файл не найден | `Error: File not found: .env.prod` |
| Ошибка S3 | `Error: Storage error: {details}` |
---
## `aevs pull`
Скачивает `.env` файлы из storage.
### Синтаксис
```bash
aevs pull [project-name]
```
### Аргументы
| Аргумент | Обязательный | Описание |
|----------|--------------|----------|
| `project-name` | нет | Имя проекта для скачивания |
### Флаги
| Флаг | Сокращение | Описание |
|------|------------|----------|
| `--config` | `-c` | Путь к конфигу (default: `./aevs.yaml`) |
| `--force` | `-f` | Перезаписать существующие файлы без подтверждения |
| `--dry-run` | | Показать что будет скачано |
### Режимы работы
**Режим 1: С локальным конфигом**
```bash
aevs pull
```
- Читает `project` из `./aevs.yaml`
- Скачивает и распаковывает файлы
**Режим 2: По имени проекта**
```bash
aevs pull my-project
```
- Скачивает архив для указанного проекта
- Распаковывает в текущую директорию
- Не создаёт и не изменяет `aevs.yaml`
### Поведение
1. Определяет имя проекта (из аргумента или конфига)
2. Скачивает metadata.json для проверки
3. Скачивает envs.tar.gz
4. Для каждого файла в архиве:
- Если файл не существует — создаёт (и директории)
- Если файл существует и отличается — спрашивает что делать
- Если `--force` — перезаписывает без вопросов
5. Выводит результат
### Обработка конфликтов
```
$ aevs pull
Pulling "my-project"...
File .env.prod already exists and differs from remote.
Local: DATABASE_URL=postgres://localhost
Remote: DATABASE_URL=postgres://prod.db
[o]verwrite / [s]kip / [d]iff / [O]verwrite all / [S]kip all: _
```
| Опция | Действие |
|-------|----------|
| `o` | Перезаписать этот файл |
| `s` | Пропустить этот файл |
| `d` | Показать полный diff |
| `O` | Перезаписать все конфликтующие файлы |
| `S` | Пропустить все конфликтующие файлы |
### Пример вывода
```
$ aevs pull my-project
Pulling "my-project" from storage...
✓ .env.prod (created)
✓ .env.dev (created)
✓ docker/.env (created directory, created file)
Done. 3 files pulled.
```
### Пример (с конфликтами)
```
$ aevs pull --force
Pulling "my-project" from storage...
✓ .env.prod (overwritten)
- .env.dev (unchanged)
✓ docker/.env (overwritten)
Done. 2 files updated, 1 unchanged.
```
### Ошибки
| Ситуация | Сообщение |
|----------|-----------|
| Проект не указан и нет aevs.yaml | `Error: Project name required. Usage: aevs pull <project-name>` |
| Проект не найден в storage | `Error: Project "xxx" not found in storage.` |
| Нет глобального конфига | `Error: No storage configured. Run 'aevs config' first.` |
---
## `aevs list`
Показывает список проектов в storage.
### Синтаксис
```bash
aevs list
```
### Флаги
| Флаг | Сокращение | Описание |
|------|------------|----------|
| `--json` | | Вывод в формате JSON |
### Поведение
1. Читает глобальный конфиг
2. Запрашивает список "директорий" в bucket (S3 list с delimiter `/`)
3. Для каждого проекта читает metadata.json
4. Выводит отсортированный список
### Пример вывода
```
$ aevs list
Projects in s3://my-envs-bucket:
PROJECT FILES UPDATED SIZE
my-awesome-project 3 2 hours ago 479 B
another-project 5 3 days ago 1.2 KB
old-project 2 45 days ago 234 B
Total: 3 projects
```
### Пример (JSON)
```
$ aevs list --json
[
{
"project": "my-awesome-project",
"files": 3,
"updated_at": "2026-01-28T13:30:00Z",
"size_bytes": 479
},
...
]
```
### Ошибки
| Ситуация | Сообщение |
|----------|-----------|
| Нет глобального конфига | `Error: No storage configured. Run 'aevs config' first.` |
| Bucket пустой | `No projects found in storage.` |
---
## `aevs status`
Показывает статус текущего проекта.
### Синтаксис
```bash
aevs status
```
### Флаги
| Флаг | Сокращение | Описание |
|------|------------|----------|
| `--config` | `-c` | Путь к конфигу (default: `./aevs.yaml`) |
### Поведение
1. Читает локальный конфиг
2. Скачивает metadata.json из storage
3. Сравнивает локальные файлы с remote
4. Выводит статус
### Пример вывода
```
$ aevs status
Project: my-awesome-project
Storage: s3://my-envs-bucket/my-awesome-project
Remote last updated: 2 hours ago (from MacBook-Pro.local)
FILE LOCAL REMOTE STATUS
.env.prod 234 B 234 B ✓ up to date
.env.dev 195 B 189 B ⚡ local modified
docker/.env — 56 B ✗ missing locally
.env.staging 128 B — + local only
Summary: 1 up to date, 1 modified, 1 missing, 1 new
```
### Статусы файлов
| Статус | Описание |
|--------|----------|
| `✓ up to date` | Файлы идентичны |
| `⚡ local modified` | Локальный файл изменён |
| `⚡ remote modified` | Remote файл изменён (другая машина сделала push) |
| `✗ missing locally` | Файл есть в remote, но нет локально |
| `+ local only` | Файл есть локально, но нет в remote |
### Ошибки
| Ситуация | Сообщение |
|----------|-----------|
| Нет aevs.yaml | `Error: No aevs.yaml found. Run 'aevs init' first.` |
| Проект не найден в storage | `Project "xxx" not found in storage. Run 'aevs push' first.` |