Pular para o conteúdo principal
Versão: 0.3.0

Precedência de Ambiente

Quando a mesma variável é definida em múltiplos lugares, o Invowk™ segue uma ordem de precedência específica. Fontes com maior precedência sobrescrevem as de menor.

Ordem de Precedência

Da maior para a menor prioridade:

PrioridadeFonteExemplo
1Vars da CLI--ivk-env-var KEY=value
2Arquivos env da CLI--ivk-env-file .env.local
3Vars do InvowkINVOWK_FLAG_*, INVOWK_ARG_*
4Vars de implementaçãoimplementations[].env.vars
5Vars de comandocommand.env.vars
6Vars raizroot.env.vars
7Arquivos de implementaçãoimplementations[].env.files
8Arquivos de comandocommand.env.files
9Arquivos raizroot.env.files
10Ambiente do sistemaAmbiente do host (se env_inherit_mode permitir)

Hierarquia Visual

CLI (highest priority)
├── --ivk-env-var KEY=value
└── --ivk-env-file .env.local

Invowk Vars
├── INVOWK_FLAG_*
└── INVOWK_ARG_*

Vars (by scope, highest to lowest)
├── Implementation env.vars
├── Command env.vars
└── Root env.vars

Files (by scope, highest to lowest)
├── Implementation env.files
├── Command env.files
└── Root env.files

System Environment (lowest priority)

Passo a Passo de Exemplo

Dado este invowkfile:

// Root level
env: {
files: [".env"]
vars: {
API_URL: "http://root.example.com"
LOG_LEVEL: "info"
}
}

cmds: [
{
name: "build"
// Command level
env: {
files: [".env.build"]
vars: {
API_URL: "http://command.example.com"
BUILD_MODE: "development"
}
}
implementations: [{
script: "echo $API_URL $LOG_LEVEL $BUILD_MODE $NODE_ENV"
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}]
// Implementation level
env: {
vars: {
BUILD_MODE: "production"
NODE_ENV: "production"
}
}
}]
}
]

E estes arquivos:

# .env
API_URL=http://envfile.example.com
DATABASE_URL=postgres://localhost/db

# .env.build
BUILD_MODE=release
CACHE_DIR=./cache

Ordem de Resolução

  1. Começar com ambiente do sistema (ex.: PATH, HOME) se env_inherit_mode não for none

  2. Carregar arquivos raiz (.env):

    • API_URL=http://envfile.example.com
    • DATABASE_URL=postgres://localhost/db
  3. Carregar arquivos de comando (.env.build):

    • BUILD_MODE=release
    • CACHE_DIR=./cache
  4. Carregar arquivos de implementação (implementations[].env.files):

    • (nenhum neste exemplo)
  5. Aplicar vars raiz (sobrescrever arquivos):

    • API_URL=http://root.example.com ← sobrescreve .env
    • LOG_LEVEL=info
  6. Aplicar vars de comando (sobrescrever arquivos):

    • API_URL=http://command.example.com ← sobrescreve raiz
    • BUILD_MODE=development ← sobrescreve .env.build
  7. Aplicar vars de implementação:

    • BUILD_MODE=production ← sobrescreve comando
    • NODE_ENV=production
  8. Aplicar vars do Invowk (flags/args):

    • INVOWK_FLAG_*, INVOWK_ARG_* (se presentes)
  9. Aplicar sobrescritas da CLI (se fornecidas):

    • --ivk-env-file e depois --ivk-env-var (maior prioridade)

Resultado Final

API_URL=http://command.example.com    # From command vars
LOG_LEVEL=info # From root vars
BUILD_MODE=production # From implementation vars
NODE_ENV=production # From implementation vars
DATABASE_URL=postgres://localhost/db # From .env file
CACHE_DIR=./cache # From .env.build file

Com Sobrescrita da CLI

invowk cmd build --ivk-env-var API_URL=http://cli.example.com

Agora API_URL=http://cli.example.com porque CLI tem a maior prioridade.

Vars Sempre Sobrescrevem Arquivos

Todos os env.files são carregados primeiro (raiz → comando → implementação), e depois todos os env.vars são aplicados por cima (raiz → comando → implementação). Isso significa que até vars do nível raiz sobrescrevem files do nível de implementação:

env: {
files: [".env"] // API_URL=from-file
vars: {
API_URL: "from-vars" // This wins
}
}

Múltiplos Arquivos no Mesmo Nível

Arquivos são carregados em ordem; arquivos posteriores sobrescrevem anteriores:

env: {
files: [
".env", // API_URL=base
".env.local", // API_URL=local (wins)
]
}

Variáveis Específicas de Plataforma

Para variáveis de ambiente específicas por plataforma, use implementações separadas por plataforma:

// Platform-specific env requires separate implementations
implementations: [
{
script: "echo $CONFIG_PATH"
runtimes: [{name: "native"}]
platforms: [{name: "linux"}]
env: {
vars: {
CONFIG_PATH: "/etc/app"
OTHER_VAR: "value"
}
}
},
{
script: "echo $CONFIG_PATH"
runtimes: [{name: "native"}]
platforms: [{name: "macos"}]
env: {
vars: {
CONFIG_PATH: "/usr/local/etc/app"
OTHER_VAR: "value"
}
}
}
]

Cada implementação tem seu próprio env que é aplicado quando aquela plataforma é selecionada.

Melhores Práticas

Use Níveis Apropriados

// Root: shared across all commands
env: {
vars: {
PROJECT_NAME: "myapp"
VERSION: "1.0.0"
}
}

// Command: specific to this command
{
name: "build"
env: {
vars: {
BUILD_TARGET: "production"
}
}
}

// Implementation: specific to this runtime
implementations: [{
runtimes: [{name: "container", image: "node:20"}]
platforms: [{name: "linux"}]
env: {
vars: {
NODE_OPTIONS: "--max-old-space-size=4096"
}
}
}]

Padrão de Sobrescrita

Config base em arquivos, sobrescritas em vars:

env: {
files: [".env"] // Defaults
vars: {
OVERRIDE_THIS: "value" // Specific override
}
}

Desenvolvimento Local

Use arquivos locais opcionais para sobrescritas de desenvolvedor:

env: {
files: [
".env", // Committed defaults
".env.local?", // Not committed, personal overrides
]
}

CLI para Sobrescritas Temporárias

# Quick test with different config
invowk cmd build --ivk-env-var DEBUG=true --ivk-env-var LOG_LEVEL=debug

Debugando Precedência

Para ver valores finais, adicione saída de debug:

{
name: "debug-env"
implementations: [{
script: """
echo "API_URL=$API_URL"
echo "LOG_LEVEL=$LOG_LEVEL"
echo "BUILD_MODE=$BUILD_MODE"
env | sort
"""
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}]
}]
}

Próximos Passos