# Окружение и свойства

Elide загружает файлы `.env` как значения окружения приложения по умолчанию, а файлы `.properties` — как значения
системных свойств Java по умолчанию. Библиотека dotenv в приложении не нужна. Оба формата поддерживают зашифрованные
значения, совместимые с dotenvx.

> [!NOTE] Доступно в Elide 1.6.2
> В этом руководстве описана поддержка контекста запуска в Elide 1.6.2.

## Загрузка конфигурации

Создайте `.env` в каталоге, из которого вызываете Elide:

```dotenv
APP_NAME=greeter
APP_PORT=8080
APP_MESSAGE="Hello from ${APP_NAME}"
```

Создайте `app.ts`:

```typescript
console.log(process.env.APP_MESSAGE);
console.log(process.env.APP_PORT);
```

```sh
elide run app.ts
```

```text
Hello from greeter
8080
```

Унаследованная переменная окружения имеет приоритет, даже если её значение пустое:

```sh
APP_PORT=9090 elide run app.ts
APP_PORT= elide run app.ts
```

Второй вызов получает пустой `APP_PORT` вместо `8080`. Читайте переменные окружения через
[`process.env`](/docs/env-variables), `os.environ` в Python или интерфейс окружения вашего языка.
Дочерние процессы тоже получают действующее окружение. Если политика окружения фильтрует унаследованные переменные,
запускаемые процессы Java, задачи проекта и дочерние процессы Node наследуют только разрешённый снимок. Явные записи
окружения задачи или JVM применяются после этого; явная карта `env` дочернего процесса Node заменяет наследование.
Загрузка файлов не даёт дополнительных возможностей песочницы
и не расширяет доступ манифеста к окружению; действующие ограничения `--allow-env` по-прежнему применяются.

## Автоматический поиск файлов

В каждом выбранном каталоге Elide читает эти файлы по порядку:

| Конфигурация | Первым | Вторым, переопределяет первый |
| --- | --- | --- |
| Окружение | `.env` | `.env.local` |
| Свойства Java | `.properties` | `.properties.local` |

Отсутствующие автоматические файлы игнорируются. Существующие файлы, которые не удаётся прочитать или разобрать,
вызывают ошибку. Форматы независимы: переменная окружения с именем `app.mode` не задаёт свойство Java `app.mode`.

По умолчанию лаунчер проверяет только каталог вызова. Расположение скрипта этот каталог не меняет.
`elide run services/api/app.ts` не выбирает `services/api/.env` автоматически.

С `--project PATH` Elide выбирает этот каталог проекта или родительский каталог, если `PATH` указывает на манифест.
Сначала загружаются объемлющие каталоги, содержащие `elide.pkl`, от внешнего к внутреннему, затем выбранный каталог.
В каждом каталоге локальный файл идёт после базового. Более поздние каталоги переопределяют более ранние.
Произвольные предки, домашний каталог и несвязанные участники рабочего пространства не влияют на конфигурацию
лаунчера.

```sh
elide --project services/api run app.ts
```

Задачи проекта также используют свои объемлющие уровни окружения, уровень рабочего пространства и уровень участника.
Выберите проект явно, если его объемлющая конфигурация должна быть доступна при запуске. См.
[Настройка проекта](/docs/projects).

Elide не выбирает автоматически `.env.production`, `.env.test`, `.properties.production` и подобные имена.
`NODE_ENV`, именованный профиль выполнения и файлы профилей dotenvx не выбирают файлы конфигурации. Указывайте такие
файлы явно.

## Явный выбор файлов

`--env-file` заменяет автоматический поиск файлов dotenv. `--properties-file` независимо заменяет автоматический поиск
файлов свойств. Повторяйте любой из флагов, чтобы наслаивать файлы; при совпадении имён побеждают более поздние
аргументы. Пути указываются относительно каталога вызова, даже если задан `--project`.

```sh
elide --env-file .env --env-file .env.production run app.ts
elide --properties-file config/base.properties --properties-file config/production.properties run Main.java
elide --env-file config/service.env --properties-file config/service.properties run Main.java
```

Явно указанные файлы обязательны: отсутствующий файл — это ошибка. Выбор только `.env.production` не загружает
дополнительно `.env` или `.env.local`. Укажите каждый нужный файл.

| Флаг | Действие |
| --- | --- |
| `--no-env` | Отключает загрузку dotenv. Унаследованные переменные окружения остаются доступными. |
| `--no-properties` | Отключает загрузку файлов свойств. |
| `--no-env --no-properties` | Отключает оба вида загрузки файлов. |

```sh
elide --no-env --no-properties run app.ts
```

Сочетание `--no-env` с `--env-file` или `--no-properties` с `--properties-file` — ошибка использования.
Можно отключить один формат и явно выбрать файлы для другого.

Запуск отдельных исходных файлов Java тоже учитывает явный выбор файлов, `--no-env` и `--no-properties`, не выполняя
повторный автоматический поиск.

## Приоритет

Приоритет окружения, от низшего к высшему:

1. Выбранные файлы dotenv в порядке поиска или аргументов.
2. Унаследованное окружение процесса, включая пустые значения.
3. Явные присваивания окружения для конкретной задачи или дочернего процесса в пределах этой области выполнения.

Приоритет свойств Java, от низшего к высшему:

1. Выбранные файлы свойств в порядке поиска или аргументов.
2. Присваивания JVM `-D`, заданные оператором, когда Elide работает на уже существующей JVM.
3. Явные присваивания свойств в CLI Elide, например `--vm app.mode=production`.

Значения свойств по умолчанию, которые задаёт VM, не считаются присваиваниями оператора. Приложения получают свойства
до своей инициализации. Дочерние запуски Java получают значения свойств приложения по умолчанию до собственных явных
аргументов JVM. Задача с отличающимися свойствами VM выполняется в отдельной VM; её свойства не меняют глобальное
состояние драйвера сборки.

## Синтаксис dotenv

Файлы dotenv поддерживают комментарии, значения в кавычках, многострочные значения, пустые значения и интерполяцию
`${NAME}`. Одинарные кавычки сохраняют содержимое буквально. Двойные кавычки допускают интерполяцию.

```dotenv
# Application defaults
APP_NAME=greeter
APP_MESSAGE="Hello from ${APP_NAME}"
APP_LITERAL='${APP_NAME}'
APP_EMPTY=
APP_MULTILINE="first line
second line"
APP_COMMAND='$(echo hello)'
```

`APP_LITERAL` — это буквальная строка `${APP_NAME}`. `APP_COMMAND` — буквальная строка `$(echo hello)`;
Elide не выполняет подстановку команд оболочки в файлах конфигурации.

Интерполяция выполняется при разборе каждого файла. Она может использовать унаследованные переменные и более ранние
присваивания в том же файле. Она не выполняется повторно, когда более поздние файлы переопределяют значения. Если
`.env` задаёт `APP_NAME=greeter` и `APP_MESSAGE="Hello from ${APP_NAME}"`, а затем `.env.local` меняет `APP_NAME` на
`api`, сообщение по-прежнему будет `Hello from greeter`. Не полагайтесь на интерполяцию между разными файлами.

## Свойства Java

Для приложений на Java или Kotlin создайте `.properties`:

```properties
app.name=greeter
app.message=Hello world
app.empty=
app.multiline=first\
  second
app.unicode=\u263A
app.literal=${APP_NAME}
```

Читайте их через `System.getProperty("app.name")` в Java или Kotlin. Например, сохраните `Main.java`:

```java
class Main {
  public static void main(String[] args) {
    System.out.println(System.getProperty("app.message"));
  }
}
```

```sh
elide run Main.java
elide --vm app.message="Hello from the CLI" run Main.java
```

Первый вызов выводит `Hello world`, второй — `Hello from the CLI`.
`app.multiline` равно `firstsecond`; `app.unicode` равно `☺`; `app.literal` остаётся `${APP_NAME}`.

Свойства используют синтаксис Java: комментарии `#` и `!`, экранированные разделители, строки продолжения и
экранирование `\uXXXX`. Кавычки входят в значение и не работают как кавычки dotenv. Свойства не интерполируют
выражения dotenv и не выполняют команды. Для переносимого содержимого вне ASCII используйте экранирование Unicode:
читатель свойств декодирует байты как Windows-1252.

Имена свойств не могут быть пустыми и не могут содержать NUL или `=`. Значения могут содержать `=`, но не NUL.
Пространства имён свойств `java.*`, `elide*` и `org.graalvm*` ограничены, кроме `elide.diag.*`.
Шифрование не обходит эти ограничения. Настройки `polyglot.*` обрабатываются как параметры движка.
Для таких настроек, как размер кучи, используйте параметры VM в CLI; файл свойств не является файлом аргументов JVM.

Когда Elide работает на уже запущенной JVM, загрузка файлов передаёт слои окружения приложениям и дочерним процессам.
Она не переписывает `System.getenv()` этой JVM и не меняет задним числом её настройки запуска.

## Зашифрованные значения

Elide расшифровывает совместимые с dotenvx значения `encrypted:` в файлах dotenv и свойствах Java. Открытые и
зашифрованные значения могут находиться в одном файле и подчиняются одним правилам приоритета. Зашифрованному
значению, которое заменено более поздним открытым значением или унаследованным значением окружения, ключ расшифровки
не нужен.

Создавайте шифротекст совместимым инструментом шифрования. Elide расшифровывает значения при загрузке конфигурации,
но не предоставляет команды шифрования. Например, с установленным dotenvx:

```sh
dotenvx encrypt -f .env.production
elide --env-file .env.production run app.ts
```

Когда появится запрос, выберите локальное хранилище `.env.keys` в dotenvx. Его
[процесс шифрования](https://dotenvx.com/docs/custody/env-keys/) оставляет шифротекст в выбранном файле dotenv и
записывает закрытый ключ в `.env.keys`. Для `.env.production` ключ называется `DOTENV_PRIVATE_KEY_PRODUCTION`.
Elide по-прежнему требует `--env-file .env.production`; суффикс ключа файл не выбирает.

### Передача закрытых ключей

Elide принимает унаследованные переменные `DOTENV_PRIVATE_KEY` и `DOTENV_PRIVATE_KEY_*` с суффиксом либо ключи в
`.env.keys` рядом с выбранными источниками конфигурации. Окружение и свойства используют общий поиск ключей.

1. Elide проверяет `.env.keys` рядом с выбранными источниками dotenv, затем рядом с выбранными источниками свойств,
   в порядке источников. Каждый каталог проверяется один раз; более поздние присваивания из файлов ключей заменяют
   более ранние с тем же именем.
2. Унаследованные присваивания `DOTENV_PRIVATE_KEY*` переопределяют совпадающие имена из файлов ключей.
3. Доступные ключи пробуются на действующих зашифрованных значениях. Суффикс ключа не ограничивает расшифровку
   конкретным именем файла конфигурации.

Файлы ключей читаются, только когда действующее зашифрованное значение нужно расшифровать. Запуску только с открытыми
значениями `.env.keys` не нужен. Поиск ключей не затрагивает произвольных предков и ваш домашний каталог.

В CI передайте подходящую переменную с закрытым ключом через хранилище секретов CI и запускайте Elide как обычно:

```sh
# DOTENV_PRIVATE_KEY_PRODUCTION is supplied by the CI environment.
elide --env-file .env.production run app.ts
```

Не добавляйте `.env.keys` в систему контроля версий, храните его резервную копию отдельно и ограничьте доступ к файлу.
Проверяйте конфигурацию перед коммитом: если часть значений зашифрована, это не значит, что зашифрованы все.
Не выводите секреты приложения и не передавайте закрытые ключи открытым текстом в командах оболочки и журналах.

Записи из `.env.keys` используются только для расшифровки; в конфигурацию приложения они не добавляются.
Записи `DOTENV_PUBLIC_KEY*` в файлах конфигурации — это метаданные, и в загруженные значения приложения они не
попадают. Присваивания `DOTENV_PRIVATE_KEY*` в файле dotenv или файле свойств приложения — ошибка.
На унаследованные переменные с закрытыми ключами распространяются обычные правила видимости унаследованного окружения.

### Зашифрованные свойства Java

Свойство Java может содержать совместимый шифротекст без кавычек:

```properties
app.secret=encrypted:...
```

Многоточие обозначает настоящий шифротекст и не является допустимым зашифрованным значением. Elide сначала разбирает
свойства Java, а затем расшифровывает декодированное значение теми же ключами, что и для dotenv. Не рассчитывайте, что
CLI dotenvx умеет разбирать или переписывать файлы свойств Java. Расшифрованный текст используется как значение: он не
разбирается повторно как конфигурация, не интерполируется и не выполняется.

## Команды, тесты и ошибки

Автоматическая загрузка применяется к `run`, `serve`, `dev`, `install`, `build`, `test`, `project`, `classpath`,
`publish`, `java`, `python`, `repl` и к прямому запуску файлов. Справка, версия, автодополнение и несвязанные
административные команды пропускают автоматический поиск конфигурации. Команды инструментов, такие как `javac` и
`kotlinc`, не загружают эти файлы автоматически. Явные флаги файлов запрашивают загрузку конфигурации для команд,
которые доходят до лаунчера приложения.

Для воспроизводимых тестов выбирайте файлы явно или отключайте оба формата:

```sh
elide --env-file .env.test --no-properties test
elide --no-env --no-properties test
```

Эти флаги не очищают унаследованные переменные окружения. Задавайте или удаляйте их отдельно в средстве запуска
тестов. Разрешённый вызов сохраняет свой снимок конфигурации; чтобы учесть изменённые файлы или ключи, начните новый
вызов.

Нечитаемые выбранные файлы, некорректный синтаксис, запрещённые записи, недопустимые ключи и действующие значения,
которые не удаётся расшифровать, приводят к ошибке до запуска соответствующего приложения или задачи. Диагностика
сообщает категорию ошибки и путь к источнику, не выводя строки источника, значения, шифротекст или закрытые ключи.
Исправьте указанный источник или явно отключите его формат.
Частично разрешённая конфигурация из формата с ошибкой не публикуется.

О переменных, которые настраивают сам Elide, см.
[Переменные окружения среды выполнения](/docs/runtime-env-variables). Подробности о флагах:
[Справочник CLI](/docs/cli-references).
