Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ fmt:
lint:
bash -O globstar -c 'shellcheck -x bin/mona modules/**/*.sh'
shfmt -d bin modules recipes tests
ec

test:
bats -r tests

ci: lint test

40 changes: 37 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# MonaRepo TUI
# MonaRepo TUI (v0.4.0)

[![CI](https://github.com/Monynha-Softwares/MonaRepoTui/actions/workflows/lint_test.yml/badge.svg)](https://github.com/Monynha-Softwares/MonaRepoTui/actions/workflows/lint_test.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
Expand All @@ -14,10 +14,14 @@ sudo ./bin/mona
```

## Features
- Installer Wizard for GitHub/Docker
- interactive `.env` helper
- `docker compose` pull/up/ps/logs
- README viewer (`less` fallback, `MONA_USE_TUI_READER=1`)
- Bash modules & recipes
- Interactive TUI
- Interactive TUI (bashsimplecurses)
- Dry-run mode
- CI ready (shfmt, shellcheck, bats)
- CI ready (shfmt, shellcheck, bats, editorconfig)

## Install

Expand All @@ -29,6 +33,17 @@ cd MonaRepoTui
make install-dev
```

### TUI dependency

The interactive menus use [bashsimplecurses](https://github.com/metal3d/bashsimplecurses).
If `ui/bashsimplecurses/simple_curses.sh` is missing, `bin/mona` will try to download it at
runtime (`curl` required). To vendor it instead:

```bash
git submodule add https://github.com/metal3d/bashsimplecurses ui/bashsimplecurses
git submodule update --init --recursive
```

## Quickstart

Run the TUI (root recommended):
Expand All @@ -43,6 +58,25 @@ sudo ./bin/mona
./bin/mona --help
```

## Installer Wizard

`./bin/mona` ships an installer that can bootstrap projects from GitHub or Docker images.
It detects common actions and runs them one by one, logging everything to
`~/.mona/logs` (override with `$MONA_LOG_DIR`).

Examples:

```bash
# GitHub clone with PAT and README TUI viewer
GITHUB_TOKEN=ghp_xxxx MONA_USE_TUI_READER=1 ./bin/mona

# Preview commands without executing
MONA_DRY_RUN=true ./bin/mona
```

Detected actions include copying `.env.example` to `.env` with an interactive editor,
`docker compose pull/up/ps/logs`, `npm|yarn|pnpm install/build/dev/start`, and more.

## Development

Format and lint:
Expand Down
6 changes: 4 additions & 2 deletions bin/mona
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ flow_config_hosts() {
apply "hostnamectl set-hostname '$new_host'"
# /etc/hosts minimal
if [[ -f /etc/hosts ]]; then
apply "cp /etc/hosts /etc/hosts.bak.mona.$(date +%s)"
backup_file /etc/hosts
if ! $MONA_DRY_RUN; then
awk -v h="$new_host" '!( ($2==h) || ($2 ~ h"\\.") )' /etc/hosts >/etc/hosts.mona || true
mv /etc/hosts.mona /etc/hosts || true
Expand Down Expand Up @@ -280,7 +280,9 @@ YAML
echo "-----------------------------------------"
read -r -p "Aplicar? [y/N]: " ok || true
if [[ "${ok^^}" == Y* ]]; then
apply "cp /etc/netplan/99-mona.yaml /etc/netplan/99-mona.yaml.bak 2>/dev/null || true"
if [[ -f /etc/netplan/99-mona.yaml ]]; then
backup_file /etc/netplan/99-mona.yaml
fi
if ! $MONA_DRY_RUN; then printf "%s\n" "$netplan_yaml" >/etc/netplan/99-mona.yaml; fi
apply "netplan apply"
log "Netplan aplicado."
Expand Down
51 changes: 39 additions & 12 deletions lib/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,33 @@ IFS=$'\n\t'
. "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/log.sh"

needs_root() {
[[ $EUID -eq 0 ]] || { log_error "Execute como root (sudo)."; exit 1; }
[[ $EUID -eq 0 ]] || {
log_error "Execute como root (sudo)."
exit 1
}
}

pm_detect() {
if command -v apt-get >/dev/null 2>&1; then echo apt; return; fi
if command -v dnf >/dev/null 2>&1; then echo dnf; return; fi
if command -v yum >/dev/null 2>&1; then echo yum; return; fi
if command -v pacman >/dev/null 2>&1; then echo pacman; return; fi
if command -v zypper >/dev/null 2>&1; then echo zypper; return; fi
if command -v apt-get >/dev/null 2>&1; then
echo apt
return
fi
if command -v dnf >/dev/null 2>&1; then
echo dnf
return
fi
if command -v yum >/dev/null 2>&1; then
echo yum
return
fi
if command -v pacman >/dev/null 2>&1; then
echo pacman
return
fi
if command -v zypper >/dev/null 2>&1; then
echo zypper
return
fi
echo unknown
}

Expand All @@ -25,12 +43,15 @@ pkg_install() {
log_info "Instalando pacotes via $pm: ${pkgs[*]}"
[[ "${MONA_DRY_RUN:-false}" == "true" ]] && return 0
case "$pm" in
apt) apt-get update -y && DEBIAN_FRONTEND=noninteractive apt-get install -y "${pkgs[@]}" ;;
dnf) dnf install -y "${pkgs[@]}" ;;
yum) yum install -y "${pkgs[@]}" ;;
pacman) pacman -Sy --noconfirm "${pkgs[@]}" ;;
zypper) zypper --non-interactive install --no-recommends "${pkgs[@]}" ;;
*) log_error "Gerenciador de pacotes não suportado"; return 1 ;;
apt) apt-get update -y && DEBIAN_FRONTEND=noninteractive apt-get install -y "${pkgs[@]}" ;;
dnf) dnf install -y "${pkgs[@]}" ;;
yum) yum install -y "${pkgs[@]}" ;;
pacman) pacman -Sy --noconfirm "${pkgs[@]}" ;;
zypper) zypper --non-interactive install --no-recommends "${pkgs[@]}" ;;
*)
log_error "Gerenciador de pacotes não suportado"
return 1
;;
esac
}

Expand All @@ -42,4 +63,10 @@ apply() {
fi
}

backup_file() {
local src="$1" dst="${1}.bak.mona.$(date +%s)"
log "[mona] backup: $src -> $dst"
apply "cp '$src' '$dst'"
}

pause_any() { read -r -p $'Pressione Enter para voltar ao menu…\n' _ || true; }
15 changes: 15 additions & 0 deletions tests/backup.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env bats

setup() {
cd "$BATS_TEST_DIRNAME/.."
}

@test "backup_file creates timestamped backup" {
tmp=$(mktemp)
echo foo >"$tmp"
run bash -lc "MONA_DIR=$(pwd); . lib/common.sh; backup_file '$tmp'"
[ "$status" -eq 0 ]
[[ "$output" == *"[mona] backup:"* ]]
backup=$(ls "$tmp.bak.mona."*)
[ -f "$backup" ]
}
5 changes: 5 additions & 0 deletions tests/cli.bats
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,8 @@ setup() {
[ "$status" -eq 0 ]
[[ "$output" == *"Usage:"* ]]
}

@test "bin/mona --dry-run exits 0" {
run env MONA_NONINTERACTIVE=1 ./bin/mona --dry-run <<<""
[ "$status" -eq 0 ]
}