483 lines
13 KiB
Markdown
483 lines
13 KiB
Markdown
# 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.` |
|