commit c77c655ef039e92b3d7cf11810a42067f7e12c47
parent 298115f0741752d341d35f9023dac7adbe58b1e7
Author: Sivaldo <gxixtx@xsxixvxaxlxdxoxdxaxvxix.xcxoxm>
Date: Sat, 27 Jun 2026 16:25:51 -0300
refactor(install): adiciona logging, confirmação e validações ao script de setup
Diffstat:
| M | .local/bin/install | | | 153 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------- |
1 file changed, 111 insertions(+), 42 deletions(-)
diff --git a/.local/bin/install b/.local/bin/install
@@ -12,13 +12,52 @@ export GOPATH="$SHARE_DIR/go"
export GOBIN="$GOPATH/bin"
export PATH="$PATH:$GOBIN"
+# ─── Log de execução ─────────────────────────────────────────────
+# Tudo que for impresso no terminal também é salvo em arquivo, para revisão posterior.
+# Usa um fifo em vez de process substitution (bash) para manter compatibilidade com /bin/sh (ash/dash).
+LOG_FILE="$HOME/install_$(date +%Y%m%d_%H%M%S).log"
+LOG_PIPE="$(mktemp -u)"
+mkfifo "$LOG_PIPE"
+tee -a "$LOG_FILE" < "$LOG_PIPE" &
+exec > "$LOG_PIPE" 2>&1
+rm -f "$LOG_PIPE"
+
+# ─── Cores no output ─────────────────────────────────────────────
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+NC='\033[0m'
+
+# Lista global de falhas, usada para o resumo final
+GLOBAL_FAILURES=""
+
+log_ok() {
+ printf "${GREEN}OK${NC} %s\n" "$1"
+}
+
+log_warn() {
+ printf "${YELLOW}AVISO${NC} %s\n" "$1"
+}
+
+log_fail() {
+ printf "${RED}FALHA${NC} %s\n" "$1"
+ GLOBAL_FAILURES="$GLOBAL_FAILURES\n - $1"
+}
+
# ─── Funções utilitárias ──────────────────────────────────────────────────────
die() {
- echo "ERRO: $1" >&2
+ printf "${RED}ERRO:${NC} %s\n" "$1" >&2
exit 1
}
+# Checagem de comandos essenciais
+check_dependencies() {
+ for cmd in doas git curl; do
+ command -v "$cmd" >/dev/null 2>&1 || die "'$cmd' não encontrado. Instale-o antes de continuar."
+ done
+}
+
mklink() {
target="$1"
link_name="$2"
@@ -62,11 +101,11 @@ install_all_fonts() {
name="$1"; url="$2"; dir="$FONT_DIR/$name"
mkdir -p "$dir"
echo "Baixando fonte '$name'..."
- curl -L -A "Mozilla/5.0" "$url" -o "/tmp/font.zip" || { echo "⚠️ Falha ao baixar '$name', pulando." ; return; }
- unzip -o "/tmp/font.zip" -d "$dir" || { echo "Falha ao extrair '$name', pulando." ; return; }
+ curl -L -A "Mozilla/5.0" "$url" -o "/tmp/font.zip" || { log_fail "Download da fonte '$name'"; return; }
+ unzip -o "/tmp/font.zip" -d "$dir" || { log_fail "Extração da fonte '$name'"; return; }
find "$dir" -type f ! -name "*.ttf" ! -name "*.otf" ! -name "*.ttc" -delete
rm "/tmp/font.zip"
- echo "Fonte '$name' instalada."
+ log_ok "Fonte '$name' instalada."
}
mkdir -p "$FONT_DIR"
@@ -85,7 +124,7 @@ setup_ssh() {
printf "Email para a chave SSH: "
read -r SSH_EMAIL
[ -z "$SSH_EMAIL" ] && die "Email não pode ser vazio."
-
+
mkdir -p "$SHARE_DIR/ssh"
chmod 700 "$SHARE_DIR/ssh"
@@ -96,7 +135,7 @@ setup_ssh() {
ssh-keygen -t ed25519 -C "$SSH_EMAIL" -f "$KEY_PATH" -N "" || die "Falha ao gerar chave SSH."
fi
- echo "\n Chave pública (cole no Codeberg/Github em Settings → SSH/GPG Keys):"
+ printf "\n Chave pública (cole no Codeberg/Github em Settings -> SSH/GPG Keys):\n"
echo "─────────────────────────────────────────"
cat "$KEY_PATH.pub"
echo "─────────────────────────────────────────"
@@ -109,17 +148,18 @@ setup_ssh() {
setup_android() {
echo "Instalando android-tools..."
doas apk add android-tools || die "Falha ao instalar android-tools."
- echo " android-tools instalado."
+ log_ok "android-tools instalado."
}
setup_email() {
echo "Instalando mbsync..."
doas apk add mbsync || die "Falha ao instalar mbsync."
- echo "mbsync instalado."
+ log_ok "mbsync instalado."
}
setup_alpine_answers() {
echo "Gerando arquivo de respostas para o instalador do Alpine..."
+ log_warn "Confirme antes de usar: disco (/dev/nvme0n1) e interface de rede (usb0) abaixo são valores fixos. Ajuste se necessário."
cat << ALPINE_EOF > ./answers.txt
# Configuração do teclado
KEYMAPOPTS="br br-thinkpad"
@@ -160,7 +200,7 @@ NTPOPTS=busybox
# Instalação no disco com criptografia em modo sistema (sys)
DISKOPTS="-e -m sys /dev/nvme0n1"
ALPINE_EOF
- echo "Arquivo 'answers.txt' gerado com sucesso para a instalação do Alpine!"
+ log_ok "Arquivo 'answers.txt' gerado com sucesso para a instalação do Alpine!"
}
# ─── Módulos principais da instalação ─────────────────────────────────────────
@@ -176,7 +216,7 @@ REPOS_EOF
doas apk update || die "Falha em 'apk update'."
doas apk upgrade --available || die "Falha em 'apk upgrade'."
- echo " Repositórios atualizados."
+ log_ok "Repositórios atualizados."
}
install_packages() {
@@ -193,24 +233,24 @@ install_packages() {
for pkg in $ALL_PACKAGES; do
if ! doas apk add "$pkg" 2>/dev/null; then
- echo "Pacote não encontrado ou falhou: $pkg"
+ log_warn "Pacote não encontrado ou falhou: $pkg"
FAILED_PKGS="$FAILED_PKGS $pkg"
fi
done
if [ -n "$FAILED_PKGS" ]; then
- echo "\n Os seguintes pacotes falharam e foram pulados:$FAILED_PKGS"
- echo " Verifique os nomes e instale manualmente se necessário.\n"
+ log_fail "Pacotes que falharam:$FAILED_PKGS"
+ echo " Verifique os nomes e instale manualmente se necessário."
fi
- doas setup-xorg-base || echo "'setup-xorg-base' falhou, continue manualmente se necessário."
- echo "Pacotes processados."
+ doas setup-xorg-base || log_warn "'setup-xorg-base' falhou, continue manualmente se necessário."
+ log_ok "Pacotes processados."
}
setup_permissions() {
echo "Configurando permissões e X11..."
for grp in lp wheel audio video input messagebus; do
- doas adduser "$USER_NAME" "$grp" || echo "Não foi possível adicionar '$USER_NAME' ao grupo '$grp'."
+ doas adduser "$USER_NAME" "$grp" || log_warn "Não foi possível adicionar '$USER_NAME' ao grupo '$grp'."
done
doas mkdir -p /etc/doas.d
@@ -229,20 +269,30 @@ Section "InputClass"
Option "Tapping" "on"
EndSection
X11_EOF
- echo "Permissões configuradas."
+ log_ok "Permissões configuradas."
}
setup_services() {
echo "Configurando serviços..."
- doas rc-service dbus start || echo "Falha ao iniciar dbus."
+ doas rc-service dbus start || log_warn "Falha ao iniciar dbus."
doas rc-update add dbus default
- echo "Serviços configurados."
+ log_ok "Serviços configurados."
+}
+
+# Verifica se o repositório local de dotfiles aponta para o remote esperado
+dotfiles_remote_is_valid() {
+ remote_url=$(cd "$HOME" && git remote get-url origin 2>/dev/null)
+ [ "$remote_url" = "$BASE_URL/dotfiles.git" ] || [ "$remote_url" = "$BASE_URL/dotfiles" ]
}
setup_dotfiles() {
echo "Configurando Dotfiles..."
if [ -d "$HOME/.git" ]; then
- (cd "$HOME" && git pull) || echo "Falha ao atualizar dotfiles."
+ if dotfiles_remote_is_valid; then
+ (cd "$HOME" && git pull) || log_warn "Falha ao atualizar dotfiles."
+ else
+ log_warn "$HOME/.git existe mas não aponta para $BASE_URL/dotfiles.git — pulando 'git pull' para evitar misturar repositórios."
+ fi
else
git clone "$BASE_URL/dotfiles.git" "$HOME/dotfiles_tmp" || die "Falha ao clonar dotfiles."
cp -af "$HOME/dotfiles_tmp/." "$HOME/"
@@ -251,10 +301,10 @@ setup_dotfiles() {
mklink "$CONF/X11/profile" "$HOME/.profile"
mklink "$CONF/X11/xinitrc" "$HOME/.xinitrc"
-
+
mkdir -p "$SHARE_DIR/gnupg"
chmod 700 "$SHARE_DIR/gnupg"
- echo "✅ Dotfiles configurados."
+ log_ok "Dotfiles configurados."
}
install_source_tools() {
@@ -264,18 +314,18 @@ install_source_tools() {
# 1. Ferramentas Suckless
for repo in $REPOS; do
REPO_DIR="$SRC_DIR/$repo"
-
+
if [ -d "$REPO_DIR" ]; then
echo "Git: repositório $repo já existe, atualizando..."
- (cd "$REPO_DIR" && git pull) || echo "Falha ao atualizar $repo."
+ (cd "$REPO_DIR" && git pull) || log_warn "Falha ao atualizar $repo."
else
echo "Clonando $repo..."
- git clone "$BASE_URL/$repo.git" "$REPO_DIR" || echo "Falha ao clonar $repo."
+ git clone "$BASE_URL/$repo.git" "$REPO_DIR" || log_warn "Falha ao clonar $repo."
fi
if [ -d "$REPO_DIR" ]; then
echo "Compilando $repo..."
- (cd "$REPO_DIR" && doas make clean install) || echo "Falha ao compilar '$repo'."
+ (cd "$REPO_DIR" && doas make clean install) || log_fail "Compilação de '$repo'."
fi
done
@@ -283,30 +333,30 @@ install_source_tools() {
NSXIV_DIR="$SRC_DIR/nsxiv"
if [ -d "$NSXIV_DIR" ]; then
echo "Git: repositório nsxiv já existe, atualizando..."
- (cd "$NSXIV_DIR" && git pull) || echo "Falha ao atualizar nsxiv."
+ (cd "$NSXIV_DIR" && git pull) || log_warn "Falha ao atualizar nsxiv."
else
echo "Clonando nsxiv..."
- git clone "https://codeberg.org/nsxiv/nsxiv.git" "$NSXIV_DIR" || echo "Falha ao clonar nsxiv."
+ git clone "https://codeberg.org/nsxiv/nsxiv.git" "$NSXIV_DIR" || log_warn "Falha ao clonar nsxiv."
fi
if [ -d "$NSXIV_DIR" ]; then
echo "Compilando nsxiv..."
- (cd "$NSXIV_DIR" && doas make clean install) || echo "Falha ao compilar 'nsxiv'."
+ (cd "$NSXIV_DIR" && doas make clean install) || log_fail "Compilação de 'nsxiv'."
fi
- echo "Ferramentas compiladas com sucesso."
+ log_ok "Ferramentas compiladas."
}
install_lf() {
- echo "📁 Instalando LF (file manager)..."
+ echo "Instalando LF (file manager)..."
mkdir -p "$GOPATH"
CGO_ENABLED=0 go install -ldflags="-s -w" github.com/gokcehan/lf@latest || die "Falha ao instalar lf via go."
-
+
if [ -f "$GOBIN/lf" ]; then
doas mv "$GOBIN/lf" /usr/local/bin/
- echo "lf instalado em /usr/local/bin/."
+ log_ok "lf instalado em /usr/local/bin/."
else
- echo "Binário lf não encontrado após go install."
+ log_warn "Binário lf não encontrado após go install."
fi
}
@@ -314,27 +364,35 @@ setup_vim() {
echo "Configurando plugins do Vim..."
if command -v vim >/dev/null; then
curl -fLo "$HOME/.config/vim/plugin/pm.vim" --create-dirs "https://git.sr.ht/~bpv/pm/blob/master/pm.vim"
- vim +DownloadPlugins +qall || echo "Falha ao instalar plugins do Vim."
- echo "Vim configurado."
+ vim +DownloadPlugins +qall || log_warn "Falha ao instalar plugins do Vim."
+ log_ok "Vim configurado."
else
- echo "Vim não encontrado, pulando setup."
+ log_warn "Vim não encontrado, pulando setup."
fi
}
setup_ffsetup() {
echo "Configurando Firefox (ffsetup)..."
- git clone "https://codeberg.org/sivaldodavi/ffsetup.git" "/tmp/ffsetup" || echo "Falha ao clonar ffsetup."
+ git clone "https://codeberg.org/sivaldodavi/ffsetup.git" "/tmp/ffsetup" || log_warn "Falha ao clonar ffsetup."
if [ -d "/tmp/ffsetup" ]; then
- (cd "/tmp/ffsetup" && chmod +x ffsetup.sh && ./ffsetup.sh) || echo "Falha ao executar ffsetup.sh."
+ (cd "/tmp/ffsetup" && chmod +x ffsetup.sh && ./ffsetup.sh) || log_warn "Falha ao executar ffsetup.sh."
rm -rf "/tmp/ffsetup"
- echo "ffsetup concluído."
+ log_ok "ffsetup concluído."
fi
}
# ─── Fluxo Completo (Config) ──────────────────────────────────────────────────
run_full_installation() {
+ # Confirmação antes de rodar tudo
+ printf "Isso vai executar a instalação completa (repos, pacotes, permissões, dotfiles, etc). Continuar? [s/N] "
+ read -r resp
+ case "$resp" in
+ s|S|sim|Sim) ;;
+ *) echo "Instalação cancelada."; exit 0 ;;
+ esac
+
setup_repos
install_packages
setup_permissions
@@ -349,6 +407,15 @@ run_full_installation() {
echo "──────────────────────"
echo " Instalação concluída "
echo "──────────────────────"
+
+ # Resumo final de falhas
+ if [ -n "$GLOBAL_FAILURES" ]; then
+ printf "${YELLOW}Resumo de etapas com falha durante a instalação:${NC}\n"
+ printf "%b\n" "$GLOBAL_FAILURES"
+ else
+ log_ok "Nenhuma falha registrada durante a instalação."
+ fi
+ echo "Log completo salvo em: $LOG_FILE"
}
# ─── Pacotes ──────────────────────────────────────────────────────
@@ -377,8 +444,10 @@ run_full_installation() {
# ─── Controle do Roteamento de Comandos ───────────────────────────────────────
+check_dependencies
+
case "$1" in
- # Módulos individuais
+ # Módulos individuais
repos) setup_repos ;;
pacotes) install_packages ;;
permissoes) setup_permissions ;;
@@ -388,7 +457,7 @@ case "$1" in
lf) install_lf ;;
vim) setup_vim ;;
ffsetup) setup_ffsetup ;;
-
+
# Fluxos e extras originais
config) run_full_installation ;;
alpine) setup_alpine_answers ;;