Ir para o conteúdo

🛠️ Configuração do CLI

Este guia explica como configurar e personalizar o comportamento global do CLI.

📖 Para configuração de comandos individuais (command.json de comandos), veja Como Adicionar Novos Comandos.


📁 Arquivos de Configuração

O CLI usa diversos níveis de configuração:

1. cli.json - Configuração Global

Arquivo principal localizado na raiz do Susa CLI que define metadados gerais.

Localização: /caminho/para/susa/core/cli.json

Conteúdo:

{
  "name": "Susa CLI",
  "description": "Gerenciador de Shell Scripts para automação",
  "version": "1.0.0",
  "commands_dir": "commands",
  "plugins_dir": "plugins"
}

Campos:

Campo Tipo Descrição Padrão
name string Nome amigável exibido no help e versão -
description string Descrição exibida no help principal -
version string Versão semântica (major.minor.patch) -
commands_dir string Diretório onde ficam os comandos commands
plugins_dir string Diretório onde ficam os plugins plugins

Quando Modificar:

  • Alterar nome ou versão do CLI
  • Mudar descrição principal
  • Reorganizar estrutura de diretórios

2. config/settings.conf - Configurações Opcionais

Arquivo de configuração adicional para settings customizados.

Localização: /caminho/para/cli/config/settings.conf

Uso: Variáveis globais compartilhadas entre todos os comandos. Carregado automaticamente pelo framework.

Carregamento Automático:

O arquivo é carregado na linha 46 do core/susa:

[ -f "$CLI_DIR/config/settings.conf" ] && source "$CLI_DIR/config/settings.conf"

Como Usar em Comandos:

#!/bin/bash

# Variáveis do settings.conf já estão disponíveis automaticamente
echo "API_ENDPOINT: ${API_ENDPOINT:-https://api.default.com}"
echo "DEBUG_MODE: ${DEBUG_MODE:-false}"

Exemplo de Conteúdo:

# config/settings.conf

# API Configuration
API_ENDPOINT="https://api.example.com"
API_TOKEN="your-token-here"

# Default Settings
DEFAULT_REGION="us-east-1"
DEBUG_MODE="false"

# Paths
BACKUP_DIR="/var/backups"
LOG_DIR="/var/log/susa"

⚡ Ordem de Carregamento

Quando você executa susa categoria comando, o framework carrega as configurações nesta ordem:

┌─────────────────────────────────────────────────────────────┐
│ 1. Variáveis de Ambiente do Sistema                         │
│    └─ Já existentes na sessão (export VAR=value)           │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 2. Definição de Caminhos                                    │
│    ├─ CORE_DIR, CLI_DIR, LIB_DIR                           │
│    ├─ PLUGINS_DIR, GLOBAL_CONFIG_FILE                      │
│    └─ Exportados para child processes                       │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 3. Bibliotecas do Core                                      │
│    ├─ color.sh, logger.sh, string.sh                       │
│    ├─ os.sh, sudo.sh                                        │
│    ├─ config.sh, cli.sh, shell.sh                            │
│    ├─ git.sh                                                   │
│    └─ dependencies.sh                                        │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 4. Configurações Globais (se existir)                       │
│    └─ config/settings.conf                                  │
│       • Variáveis compartilhadas entre comandos             │
│       • Sobrescreve defaults, mas não sobrescreve sistema   │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 5. Validação do CLI                                         │
│    └─ core/cli.json                                         │
│       • Verifica se arquivo existe                          │
│       • Obtém metadados (nome, versão, descrição)          │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 6. Cache/Lock File (se existir)                             │
│    └─ susa.lock                                             │
│       • Usado para descoberta rápida de comandos            │
│       • Inclui comandos de plugins                          │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 7. Configuração do Comando                                  │
│    └─ categoria/comando/command.json                         │
│       • Valida comando existe e é compatível com OS         │
│       • Lê metadados (nome, entrypoint, sudo, os)          │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 8. Variáveis de Ambiente do Comando                         │
│    └─ load_command_envs() lê command.json → envs:           │
│       • Exporta variáveis específicas do comando            │
│       • NÃO sobrescreve variáveis já definidas no sistema   │
│       • Expande $HOME, $USER, etc.                          │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 9. Script do Comando                                        │
│    └─ categoria/comando/main.sh                             │
│       • Executa com todas as configurações carregadas       │
│       • Tem acesso a todas as variáveis                     │
└─────────────────────────────────────────────────────────────┘

Referência no código (core/susa):

# Linhas 15-28: Definição de caminhos
CORE_DIR="$(cd -P "$(dirname "$CURRENT_SCRIPT")" && pwd)"
CLI_DIR="$(cd -P "$CORE_DIR/.." && pwd)"
# ... exports

# Linhas 33-44: Carrega bibliotecas
source "$LIB_DIR/color.sh"
source "$LIB_DIR/logger.sh"
# ... outras bibliotecas

# Linha 46: Carrega settings.conf (se existir)
[ -f "$CLI_DIR/config/settings.conf" ] && source "$CLI_DIR/config/settings.conf"

# Linhas 48-51: Valida cli.json
if [ ! -f "$GLOBAL_CONFIG_FILE" ]; then
    echo "Erro: Arquivo de configuração '$GLOBAL_CONFIG_FILE' não encontrado"
    exit 1
fi

# Linha 396: Carrega envs do comando (antes de executar)
load_command_envs "$config_file"

# Linha 398: Executa o script
source "$script_path" "$@"

Precedência de Variáveis

⚠️ IMPORTANTE: Esta é a ordem oficial de precedência de variáveis de ambiente no Susa CLI.

Quando uma mesma variável é definida em múltiplos lugares:

┌─────────────────────────────────────────────────────────────┐
│ 1. Variáveis de Sistema (MAIOR PRECEDÊNCIA)                 │
│    ├─ export VAR=value                                      │
│    └─ VAR=value susa comando                                │
│    • Sempre tem prioridade máxima                           │
│    • Sobrescreve qualquer outra fonte                       │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 2. Envs do Comando                                          │
│    └─ command.json → envs:                                   │
│    • Variáveis definidas no command.json do comando          │
│    • Funciona em comandos built-in e plugins                │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 3. Variáveis Globais                                        │
│    └─ config/settings.conf                                  │
│    • Compartilhadas entre todos os comandos                 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 4. Arquivos .env                                            │
│    └─ command.json → env_files:                              │
│    • Carregados na ordem especificada                       │
│    • Último arquivo tem prioridade sobre anteriores         │
│    • Funciona em comandos built-in e plugins                │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 5. Valores Padrão no Script (MENOR PRECEDÊNCIA)             │
│    └─ ${VAR:-default}                                       │
│    • Usado apenas se nenhuma fonte definiu a variável       │
└─────────────────────────────────────────────────────────────┘

Exemplo prático completo:

// commands/setup/docker/command.json
{
  "env_files": [".env", ".env.local"],
  "envs": {
    "TIMEOUT": "60"
  }
}
# commands/setup/docker/.env
TIMEOUT="40"
API_URL="https://api.example.com"
# commands/setup/docker/.env.local
DATABASE_URL="postgresql://localhost/mydb"
# config/settings.conf
TIMEOUT="30"
# commands/setup/docker/main.sh
timeout="${TIMEOUT:-10}"
api_url="${API_URL:-https://default.com}"
database="${DATABASE_URL:-sqlite:///local.db}"

Resultados:

# Sem override
./susa setup docker
# → TIMEOUT=60 (do command.json envs - prioridade 2)
# → API_URL=https://api.example.com (do .env - prioridade 4)
# → DATABASE_URL=postgresql://localhost/mydb (do .env.local - prioridade 4)

# Com override via sistema
TIMEOUT=90 ./susa setup docker
# → TIMEOUT=90 (do sistema - prioridade 1, maior)
# → API_URL e DATABASE_URL continuam vindo dos arquivos .env

Funcionamento para Plugins:

A mesma lógica de precedência se aplica a plugins:

// plugins/meu-plugin/deploy/staging/command.json
{
  "env_files": [".env", ".env.staging"],
  "envs": {
    "DEPLOY_URL": "https://staging.example.com"
  }
}
# plugins/meu-plugin/deploy/staging/.env
DATABASE_URL="postgresql://localhost/mydb"
# Uso
./susa deploy staging
# → Carrega .env e .env.staging do plugin
# → Mesma ordem de precedência

3. Configuração de Categorias e Comandos

📖 Documentação completa: Para detalhes sobre arquivos de configuração (command.json e category.json) de categorias, subcategorias e comandos, consulte:

Resumo:

Tipo Arquivo Campos Principais Referência
Categoria commands/<categoria>/category.json name, description Ver guia
Comando commands/<categoria>/<comando>/command.json name, description, script, sudo, os, group (opcional) Ver guia
Subcategoria commands/<categoria>/<sub>/command.json name, description (sem script) Ver guia

Indicadores Visuais:

  • Comandos instalados exibem em verde (apenas categoria setup)
  • Comandos com sudo: true exibem [sudo] na listagem
  • Comandos de plugins exibem [plugin] na listagem
  • Todos podem aparecer juntos: comando ✓ [plugin] [sudo]

Exemplo:

Comandos:
  asdf            Instala ASDF ✓
  docker          Instala Docker ✓ [sudo]
  postgres        Instala PostgreSQL [sudo]
  deploy-prod     Deploy produção [plugin] [sudo]

Veja mais sobre indicadores em Filtros de Sistema Operacional e Sudo e Plugins.


🎛️ Variáveis de Ambiente

O CLI respeita algumas variáveis de ambiente para customização.

DEBUG

Ativa modo debug com logs adicionais.

Valores aceitos: true, 1, on

Exemplo:

DEBUG=true susa setup docker

Saída:

[DEBUG] 2026-01-12 14:30:45 - Carregando config de: /opt/cli/cli.json
[DEBUG] 2026-01-12 14:30:45 - Categoria detectada: install
[DEBUG] 2026-01-12 14:30:45 - Comando detectado: docker
[INFO] 2026-01-12 14:30:45 - Instalando Docker Engine...

Uso em Scripts:

#!/bin/bash
source "$LIB_DIR/logger.sh"

log_debug "Valor da variável X: $X"  # Só aparece com DEBUG=true

CLI_DIR

Diretório raiz do CLI (normalmente detectado automaticamente).

Uso: Raramente precisa ser definido manualmente.

Exemplo:

CLI_DIR=/opt/mycli ./susa setup docker

GLOBAL_CONFIG_FILE

Caminho para o arquivo cli.json (normalmente detectado automaticamente).

Uso: Útil para testar com configurações alternativas.

Exemplo:

GLOBAL_CONFIG_FILE=/tmp/test-cli.json ./susa --version

🌍 Variáveis de Ambiente por Comando

O Susa CLI permite definir variáveis de ambiente específicas para cada comando através da seção envs no command.json.

Como Funciona

Cada comando pode ter suas próprias variáveis de ambiente que são automaticamente carregadas e exportadas apenas durante a execução daquele comando. Isso garante isolamento e evita conflitos entre comandos.

Definindo Variáveis no command.json

No arquivo command.json do seu comando, adicione a seção envs:

{
  "name": "ASDF",
  "description": "Instala ASDF (gerenciador de versões polyglot)",
  "entrypoint": "main.sh",
  "sudo": false,
  "os": ["linux", "mac"],
  "envs": {
    "ASDF_GITHUB_API_URL": "https://api.github.com/repos/asdf-vm/asdf/releases/latest",
    "ASDF_GITHUB_REPO_URL": "https://github.com/asdf-vm/asdf.git",
    "ASDF_RELEASES_BASE_URL": "https://github.com/asdf-vm/asdf/releases/download",
    "ASDF_API_MAX_TIME": "10",
    "ASDF_API_CONNECT_TIMEOUT": "5",
    "ASDF_GIT_TIMEOUT": "5",
    "ASDF_DOWNLOAD_CONNECT_TIMEOUT": "30",
    "ASDF_DOWNLOAD_MAX_TIME": "300",
    "ASDF_DOWNLOAD_RETRY": "3",
    "ASDF_DOWNLOAD_RETRY_DELAY": "2",
    "ASDF_INSTALL_DIR": "$HOME/.asdf",
    "ASDF_LOCAL_BIN_DIR": "$HOME/.local/bin"
  }
}

Usando no Script

No main.sh do comando, use as variáveis com valores padrão de fallback:

#!/bin/bash
set -euo pipefail


# Usar variáveis com fallback para compatibilidade
get_latest_version() {
    local api_url="${ASDF_GITHUB_API_URL:-https://api.github.com/repos/asdf-vm/asdf/releases/latest}"
    local max_time="${ASDF_API_MAX_TIME:-10}"
    local connect_timeout="${ASDF_API_CONNECT_TIMEOUT:-5}"

    curl -s --max-time "$max_time" --connect-timeout "$connect_timeout" "$api_url"
}

install_asdf() {
    local install_dir="${ASDF_INSTALL_DIR:-$HOME/.asdf}"
    local download_timeout="${ASDF_DOWNLOAD_MAX_TIME:-300}"

    echo "Instalando em: $install_dir"
    curl -L --max-time "$download_timeout" "$download_url" -o /tmp/asdf.tar.gz
}

Características das Envs por Comando

✅ Expansão de Variáveis

Variáveis como $HOME, $USER, etc., são automaticamente expandidas:

{
  "envs": {
    "MY_CONFIG_DIR": "$HOME/.config/myapp",
    "BACKUP_PATH": "$HOME/backups/$USER"
  }
}

🔒 Isolamento Total

As variáveis são isoladas por comando. Não há vazamento entre comandos:

# Comando 1
$ susa setup asdf
   ASDF_INSTALL_DIR disponível
   FIM (variável descartada)

# Comando 2
$ susa setup docker
   ASDF_INSTALL_DIR NÃO está disponível
   DOCKER_* envs estão disponíveis

🎯 Escopo de Execução

Usuario executa comando
[core/susa] execute_command()
Valida e localiza command.json
[config.sh] load_command_envs(command.json)
Carrega arquivos .env (se especificados)
Carrega seção envs do command.json
Exporta todas as envs (com expansão)
Executa main.sh
Script usa ${VAR:-default}
Fim da execução (envs descartadas)

Suporte a Arquivos .env

Além de definir variáveis diretamente no command.json, você pode carregá-las de arquivos .env.

Configuração

// commands/deploy/app/command.json
{
  "name": "Deploy App",
  "description": "Deploy da aplicação",
  "entrypoint": "main.sh",
  "sudo": false,
  "os": ["linux"],
  "env_files": [
    ".env",
    ".env.local",
    ".env.production"
  ],
  "envs": {
    "DEPLOY_TIMEOUT": "300",
    "DEPLOY_TARGET": "production"
  }
}

Formato dos Arquivos .env

# .env
# Comentários são suportados
DATABASE_URL="postgresql://localhost/mydb"
API_KEY="your-api-key-here"
DEBUG_MODE="false"

# Suporta expansão de variáveis
CONFIG_DIR="$HOME/.config/app"
LOG_FILE="$PWD/logs/app.log"

# Valores entre aspas (simples ou duplas)
APP_NAME="My Application"
VERSION='1.0.0'

# Linhas vazias são ignoradas

REDIS_URL="redis://localhost:6379"

Características

  • ✅ Caminhos relativos ao diretório do command.json
  • ✅ Caminhos absolutos também suportados
  • ✅ Múltiplos arquivos .env podem ser especificados
  • ✅ Carregados na ordem definida em env_files
  • ✅ Suporta comentários (#) e linhas vazias
  • ✅ Suporta aspas simples e duplas
  • ✅ Expansão de variáveis ($HOME, $USER, etc.)
  • ✅ Arquivos inexistentes são ignorados silenciosamente

Precedência com Arquivos .env

1. Variáveis de Sistema    → export VAR=value ou VAR=value comando
2. Envs do Comando         → command.json → envs:
3. Variáveis Globais       → config/settings.conf
4. Arquivos .env           → command.json → env_files: (ordem especificada)
5. Valores Padrão          → ${VAR:-default}

Exemplo:

// command.json
{
  "env_files": [
    ".env",
    ".env.local"
  ],
  "envs": {
    "TIMEOUT": "60"
  }
}
# .env
TIMEOUT="40"
API_URL="https://api.example.com"
# .env.local
DATABASE_URL="postgresql://localhost/mydb"

Resultado:

  • TIMEOUT = 60 (do command.json envs, maior prioridade que .env)
  • API_URL = https://api.example.com (do .env)
  • DATABASE_URL = postgresql://localhost/mydb (do .env.local)

Exemplo com Múltiplos Ambientes

{
  "name": "Deploy",
  "entrypoint": "main.sh",
  "env_files": [
    ".env",
    ".env.${DEPLOY_ENV:-development}"
  ]
}
# Uso
$ susa deploy app                    # Usa .env.development
$ DEPLOY_ENV=staging susa deploy app # Usa .env.staging
$ DEPLOY_ENV=production susa deploy app # Usa .env.production

Vantagens

Configurações Centralizadas: Todos os parâmetros em um único lugar ✅ Fácil Customização: Basta editar o JSON ou .env, sem tocar no código ✅ Separação de Secrets: Use .env.secrets no .gitignore ✅ Múltiplos Ambientes: Fácil gerenciar dev, staging, production ✅ Valores de Fallback: Scripts continuam funcionando sem as envs ✅ Expansão Automática: Variáveis como $HOME são expandidas ✅ Isolamento: Comandos não interferem uns nos outros ✅ Sem Código Extra: Framework cuida do carregamento automaticamente

Boas Práticas

1. Use Prefixos Únicos

{
  "envs": {
    "ASDF_INSTALL_DIR": "..."      // ✅ Prefixo único
  }
}
{
  "envs": {
    "INSTALL_DIR": "..."           // ❌ Muito genérico
  }
}

2. Sempre Forneça Fallbacks

# ✅ Bom: funciona com ou sem env
local dir="${ASDF_INSTALL_DIR:-$HOME/.asdf}"

# ❌ Ruim: quebra sem a env
local dir="$ASDF_INSTALL_DIR"

3. Documente as Variáveis

{
  "envs": {
    // Timeout máximo para API do GitHub (em segundos)
    // Padrão: 10
    "ASDF_API_MAX_TIME": "10",

    // Diretório de instalação do ASDF
    // Padrão: $HOME/.asdf
    "ASDF_INSTALL_DIR": "$HOME/.asdf"
  }
}

4. Use Tipos Apropriados

{
  "envs": {
    "TIMEOUT": "30",
    "RETRY_COUNT": "3",
    "ENABLE_CACHE": "true",
    "API_URL": "https://...",
    "INSTALL_DIR": "$HOME/..."
  }
}

Exemplo Completo

command.json:

{
  "name": "Docker",
  "description": "Instala Docker Engine",
  "entrypoint": "main.sh",
  "sudo": true,
  "os": ["linux", "mac"],
  "envs": {
    "DOCKER_REPO_URL": "https://download.docker.com",
    "DOCKER_GPG_KEY_URL": "https://download.docker.com/linux/ubuntu/gpg",
    "DOCKER_DATA_ROOT": "/var/lib/docker",
    "DOCKER_LOG_LEVEL": "info",
    "DOCKER_MAX_CONCURRENT_DOWNLOADS": "3",
    "DOCKER_DOWNLOAD_TIMEOUT": "300",
    "DOCKER_STARTUP_TIMEOUT": "60"
  }
}

main.sh:

#!/bin/bash
set -euo pipefail

source "$LIB_DIR/logger.sh"

download_docker() {
    local repo_url="${DOCKER_REPO_URL:-https://download.docker.com}"
    local timeout="${DOCKER_DOWNLOAD_TIMEOUT:-300}"

    log_info "Baixando Docker de: $repo_url"
    curl -L --max-time "$timeout" "$repo_url/install.sh" | sudo bash
}

configure_docker() {
    local data_root="${DOCKER_DATA_ROOT:-/var/lib/docker}"
    local log_level="${DOCKER_LOG_LEVEL:-info}"

    cat > /etc/docker/daemon.json <<EOF
{
  "data-root": "$data_root",
  "log-level": "$log_level"
}
EOF
}

main() {
    download_docker
    configure_docker
    log_success "Docker instalado com sucesso!"
}

main "$@"

🌐 Variáveis de Ambiente Globais

Para configurações que devem estar disponíveis em todos os comandos, use config/settings.conf.

Configuração Global

Localização: config/settings.conf

# config/settings.conf

# Configurações globais da API
API_ENDPOINT="https://api.example.com"
API_TOKEN="your-token-here"

# Configurações de rede
HTTP_TIMEOUT="30"
HTTP_RETRY="3"

# Diretórios globais
BACKUP_DIR="/var/backups"
LOG_DIR="/var/log/susa"

# Debug
DEBUG_MODE="false"

Carregamento Automático

O arquivo config/settings.conf é carregado automaticamente no início da execução do CLI (se existir):

# core/susa (linha 46)
[ -f "$CLI_DIR/config/settings.conf" ] && source "$CLI_DIR/config/settings.conf"

Usando em Comandos

As variáveis globais estão automaticamente disponíveis:

#!/bin/bash
set -euo pipefail


# Variáveis do settings.conf já estão disponíveis
echo "API Endpoint: ${API_ENDPOINT:-não configurado}"
echo "HTTP Timeout: ${HTTP_TIMEOUT:-30}"
echo "Backup Dir: ${BACKUP_DIR:-/var/backups}"

# Fazer requisição usando config global
curl --max-time "${HTTP_TIMEOUT:-30}" \
     --retry "${HTTP_RETRY:-3}" \
     -H "Authorization: Bearer ${API_TOKEN}" \
     "${API_ENDPOINT}/status"

Precedência de Variáveis

Quando a mesma variável existe em múltiplos lugares:

1. Variáveis de Ambiente do Sistema (maior precedência)
2. Variáveis do Comando (command.json envs:)
3. Variáveis Globais (config/settings.conf)
4. Valores Padrão no Script (fallback)

Exemplo:

# settings.conf
TIMEOUT="30"
// comando/command.json
{
  "envs": {
    "TIMEOUT": "60"
  }
}
# No script
timeout="${TIMEOUT:-10}"  # Usará 60 (do comando)

# Mas se executar com:
TIMEOUT=90 susa comando   # Usará 90 (do sistema)

Quando Usar Cada Tipo

Tipo Quando Usar Exemplo
Envs por Comando Configurações específicas do comando URLs específicas, diretórios de instalação, timeouts customizados
Envs Globais Configurações compartilhadas entre comandos Credenciais de API, configurações de rede, paths globais
Variáveis de Sistema Override temporário durante execução DEBUG=true susa comando, TIMEOUT=90 susa comando
Valores Padrão Fallback quando nada está configurado ${VAR:-valor_padrao}

Exemplo Prático Completo

config/settings.conf (global):

# Configurações de rede globais
HTTP_TIMEOUT="30"
HTTP_RETRY="3"
API_BASE_URL="https://api.example.com"

commands/deploy/app/command.json:

{
  "name": "Deploy App",
  "description": "Deploy da aplicação",
  "entrypoint": "main.sh",
  "sudo": false,
  "os": ["linux"],
  "envs": {
    "DEPLOY_TARGET_DIR": "/var/www/app",
    "DEPLOY_BACKUP_ENABLED": "true",
    "DEPLOY_ROLLBACK_ENABLED": "true"
  }
}

commands/deploy/app/main.sh:

#!/bin/bash
set -euo pipefail


deploy_app() {
    # Usa configuração global
    local api_url="${API_BASE_URL:-https://api.example.com}"
    local timeout="${HTTP_TIMEOUT:-30}"

    # Usa configuração do comando
    local target_dir="${DEPLOY_TARGET_DIR:-/var/www/app}"
    local backup="${DEPLOY_BACKUP_ENABLED:-true}"

    log_info "Fazendo deploy para: $target_dir"
    log_info "API URL: $api_url"

    if [ "$backup" = "true" ]; then
        log_info "Criando backup..."
        cp -r "$target_dir" "${target_dir}.backup.$(date +%s)"
    fi

    # Deploy via API
    curl --max-time "$timeout" \
         --retry "${HTTP_RETRY:-3}" \
         -X POST "$api_url/deploy" \
         -d '{"target": "'"$target_dir"'"}'
}

deploy_app "$@"

Execução:

# Usa todas as configs definidas
$ susa deploy app

# Override de config global
$ HTTP_TIMEOUT=60 susa deploy app

# Override de config do comando
$ DEPLOY_TARGET_DIR=/tmp/app susa deploy app

# Override de múltiplas
$ API_BASE_URL=https://staging.api.com DEPLOY_BACKUP_ENABLED=false susa deploy app

🔧 Personalizações Comuns

Alterar Nome do CLI

Edite cli.json:

{
  "name": "MeuApp CLI",
  "description": "Meu gerenciador customizado"
}

Renomeie o executável:

mv susa meuapp

Reinstale:

./install.sh

Agora use:

meuapp setup asdf
meuapp self version

Adicionar Diretório de Configuração Customizado

Se quiser um diretório separado para configs de produção:

mkdir -p config/production

Crie arquivos de ambiente:

# config/production/database.conf
DB_HOST="prod-db.example.com"
DB_PORT="5432"
DB_NAME="production"

# config/production/api.conf
API_URL="https://api.production.com"
API_TIMEOUT="30"

Use em comandos:

#!/bin/bash
CLI_DIR="$(cd "$SCRIPT_DIR/../../.." && pwd)"

# Carrega configuração de produção
if [ -f "$CLI_DIR/config/production/database.conf" ]; then
    source "$CLI_DIR/config/production/database.conf"
fi

echo "Conectando a: $DB_HOST:$DB_PORT/$DB_NAME"

Configurar Aliases

Adicione aliases ao shell para comandos frequentes:

# ~/.zshrc ou ~/.bashrc

# Aliases do CLI
alias clic='susa setup'
alias cliu='cli update'
alias clid='susa deploy'
alias clip='susa self plugin'

Uso:

clic asdf         # Equivale a: susa setup asdf
cliu              # Equivale a: susa self update
clip list         # Equivale a: susa self plugin list

Configurar PATH

Se o Susa CLI foi instalado em /opt/susa, adicione ao PATH:

# Adicione ao ~/.zshrc ou ~/.bashrc
export PATH="$PATH:/opt/susa"

Ou durante instalação, o install.sh já faz isso automaticamente:

./install.sh
# Adiciona symlink em /usr/local/bin/susa automaticamente

🗂️ Estrutura de Configuração Completa

susa/
├── core/
│   ├── cli.json                 # ✅ Config global (obrigatório)
│   ├── susa                    # Entrypoint principal
│   └── lib/                    # Bibliotecas
├── config/
│   └── settings.conf           # ⚠️ Opcional (não usado por padrão)
├── commands/
│   ├── setup/
│   │   ├── category.json        # ⚠️ Opcional (metadados da categoria)
│   │   └── asdf/
│   │       ├── command.json      # ✅ Obrigatório (config do comando)
│   │       └── main.sh         # ✅ Obrigatório (script)
│   └── self/
│       ├── category.json
│       └── plugin/
│           ├── command.json
│           └── add/
│               ├── command.json # ✅ Obrigatório
│               └── main.sh     # ✅ Obrigatório
└── plugins/
    ├── registry.json            # 🔧 Gerado automaticamente
    └── hello-world/             # Exemplo de plugin
        └── text/
            ├── category.json
            └── hello-world/
                ├── command.json  # ✅ Obrigatório (plugin)
                └── main.sh      # ✅ Obrigatório (plugin)

Legenda:

  • ✅ Obrigatório
  • ⚠️ Opcional
  • 🔧 Gerado automaticamente

📝 Boas Práticas de Configuração

1. Use Configurações Descentralizadas

Evite:

# Um JSON centralizado gigante
categories:
  install:
    commands:
      - name: "Docker"
        description: "Docker description"
        # ... 50 linhas ...
      - name: "NodeJS"
        # ... 50 linhas ...
      # ... 500 comandos ...

Prefira:

commands/
├── install/
│   ├── docker/
│   │   └── command.json    # Config do docker
│   └── nodejs/
│       └── command.json    # Config do nodejs

2. Separe Secrets de Configuração

Evite:

// command.json - NÃO FAÇA ISSO!
{
  "api_token": "sk-1234567890abcdef"
}

Prefira:

# config/settings.conf (não commitado)
API_TOKEN="sk-1234567890abcdef"

# .gitignore
config/settings.conf
config/production/*.conf
config/*.secret

3. Use Variáveis de Ambiente para Overrides

#!/bin/bash

# Valores padrão
DB_HOST="${DB_HOST:-localhost}"
DB_PORT="${DB_PORT:-5432}"
API_TIMEOUT="${API_TIMEOUT:-30}"

# Permite override via env vars:
# DB_HOST=prod-db.com susa deploy app

4. Documente Configurações Customizadas

Se adicionar configurações em config/settings.conf, documente:

# config/settings.conf

# ============================================================
# Configurações da API
# ============================================================
# API_ENDPOINT: URL base da API (padrão: https://api.example.com)
# API_TOKEN: Token de autenticação (obtenha em: https://dashboard.example.com)
# API_TIMEOUT: Timeout em segundos (padrão: 30)

API_ENDPOINT="https://api.example.com"
API_TOKEN=""  # CONFIGURE AQUI
API_TIMEOUT="30"

# ============================================================
# Configurações de Backup
# ============================================================
# BACKUP_DIR: Diretório para armazenar backups
# BACKUP_RETENTION_DAYS: Dias para manter backups antigos

BACKUP_DIR="/var/backups/mycli"
BACKUP_RETENTION_DAYS="30"

5. Valide Configurações Obrigatórias

Em comandos que dependem de config:

#!/bin/bash
CLI_DIR="$(cd "$SCRIPT_DIR/../../.." && pwd)"

# Carrega configuração
if [ -f "$CLI_DIR/config/settings.conf" ]; then
    source "$CLI_DIR/config/settings.conf"
fi

# Valida campos obrigatórios
if [ -z "$API_TOKEN" ]; then
    log_error "API_TOKEN não configurado em config/settings.conf"
    log_info "Configure em: $CLI_DIR/config/settings.conf"
    exit 1
fi

# Prossegue com execução
log_info "Conectando a API..."

🔍 Troubleshooting de Configuração

📖 Para troubleshooting de comandos específicos, veja a seção Troubleshooting no guia de subcategorias.

Problema: CLI não encontra cli.json

Verificar:

# Verificar se arquivo existe no local correto
ls -la ./cli.json
ls -la /opt/susa/cli.json

# Testar com caminho absoluto
GLOBAL_CONFIG_FILE=/caminho/completo/cli.json susa --version

Problema: Configuração não está sendo carregada (settings.conf)

Debug:

# Ativar modo debug
DEBUG=true susa setup docker

# Verificar se arquivo existe
ls -la /caminho/para/cli/cli.json

# Verificar permissões
stat /caminho/para/cli/cli.json

# Validar sintaxe JSON
jq . /caminho/para/cli/cli.json

Problema: Variável de ambiente não funciona

Verificar:

# Verificar se variável está definida
echo $DEBUG
echo $CLI_DIR

# Exportar variável
export DEBUG=true
susa setup docker

# Ou inline
DEBUG=true susa setup docker

📚 Recursos Adicionais


🎯 Resumo

Configurações principais:

  1. cli.json - Metadados globais (obrigatório)
  2. <comando>/command.json - Config de cada comando com envs (obrigatório)
  3. config/settings.conf - Variáveis globais compartilhadas (opcional)
  4. Variáveis de ambiente do sistema - Override temporário (opcional)

Tipos de Variáveis de Ambiente:

Tipo Arquivo Escopo Uso
Por Comando command.json (seção envs:) Apenas durante execução do comando URLs, timeouts, paths específicos
Globais config/settings.conf Todos os comandos Credenciais, configs de rede
Sistema Linha de comando Override temporário DEBUG=true susa comando

Hierarquia de precedência (maior → menor):

1. Variáveis de Ambiente do Sistema (export VAR=value ou VAR=value comando)
2. Envs do Comando (command.json → envs:)
3. Variáveis Globais (config/settings.conf)
4. Valores Padrão no Script (${VAR:-default})

Características das Envs por Comando:

✅ Carregamento automático antes da execução ✅ Expansão de variáveis ($HOME, $USER) ✅ Isolamento total entre comandos ✅ Suporte a fallback (${VAR:-default}) ✅ Sem código adicional necessário

Para começar:

  • Básico: Apenas cli.json e <comando>/command.json são necessários
  • Com envs por comando: Adicione seção envs: no command.json do comando
  • Com envs globais: Crie config/settings.conf com variáveis compartilhadas

Exemplo mínimo com envs:

// commands/setup/docker/command.json
{
  "name": "Docker",
  "description": "Instala Docker",
  "entrypoint": "main.sh",
  "sudo": true,
  "os": ["linux"],
  "envs": {
    "DOCKER_REPO_URL": "https://download.docker.com",
    "DOCKER_TIMEOUT": "300"
  }
}
# commands/setup/docker/main.sh
#!/bin/bash

repo="${DOCKER_REPO_URL:-https://download.docker.com}"
timeout="${DOCKER_TIMEOUT:-300}"

curl --max-time "$timeout" "$repo/install.sh" | sudo bash