Pular para o conteúdo

Configuração em camadas

Padrão, arquivo, ambiente e flag — nessa ordem, e com quem venceu dito na tela.

Toda ferramenta séria lê configuração de quatro lugares, e a ordem é o contrato: o padrão do programa, o arquivo do projeto, a variável de ambiente e a flag da linha de comando. A da direita vence.

CamadaPara quêExemplo
padrãofuncionar sem configurar nada{"formato": "tabela"}
arquivoa decisão do projeto, versionadaforge.toml, .minharc
ambientea decisão da máquina ou do CIMINHA_FORMATO=json
flaga decisão desta execução--formato=json
dataforge
adopt Arcane.OS as OS

PADRAO := {"formato": "tabela", "limite": 10, "cor": yes}

action em_camadas(arquivo, prefixo, flags):
    valor := {...PADRAO}
    cycle chave in keys(arquivo):
        valor[chave] := arquivo[chave]
    cycle chave in keys(valor):
        do_ambiente := OS.get_env($"{prefixo}_{upper(chave)}")
        given do_ambiente is not void:
            valor[chave] := do_ambiente
    cycle chave in keys(flags):
        given flags[chave] is not void:
            valor[chave] := flags[chave]
    yield valor

final := em_camadas({"limite": 50}, "MINHA", {"formato": "json"})
assert final["formato"] is "json"      // a flag venceu
assert final["limite"] is 50           // o arquivo venceu o padrão
assert final["cor"] is yes             // ninguém mexeu: o padrão

Dizer de onde veio cada valor#

A pergunta que aparece em todo suporte é "por que ele está usando isso?". Guardar a camada ao lado do valor transforma meia hora de investigação numa linha:

dataforge
PADRAO := {"formato": "tabela", "limite": 10}

action com_origem(arquivo, ambiente, flags):
    saida := {}
    cycle chave in keys(PADRAO):
        saida[chave] := {"valor": PADRAO[chave], "de": "padrão"}
    cycle chave in keys(arquivo):
        saida[chave] := {"valor": arquivo[chave], "de": "arquivo"}
    cycle chave in keys(ambiente):
        saida[chave] := {"valor": ambiente[chave], "de": "ambiente"}
    cycle chave in keys(flags):
        saida[chave] := {"valor": flags[chave], "de": "flag"}
    yield saida

visto := com_origem({"limite": 50}, {}, {"formato": "json"})
cycle chave in sorted(keys(visto)):
    out $"  {chave} = {visto[chave]['valor']}   ({visto[chave]['de']})"
assert visto["limite"]["de"] is "arquivo"

O cofre, quando há muitas camadas#

packages/cofre é um pacote deste repositório que faz exatamente isto, e serve de referência — ele está publicado no registro e tem testes.

bash
$ dataforge add cofre
$ dataforge search config