feat: init_cli_app bash pipeline — scaffold Go CLI app con TUI opcional
Genera apps/{nombre}/ con main.go (subcommand routing via os.Args + switch),
cmd_version.go, cmd_status.go, Makefile (build/run/install/test/vet/clean),
.gitignore, go.mod y app.md. Sin cobra/urfave — consistente con el resto de
apps del registry.
Flag --with-tui anade model.go con un modelo Bubbletea fullscreen (lista
filtrable con bubbles/list, spinner con bubbles/spinner, dark theme con
lipgloss). main.go arranca la TUI con tea.NewProgram(m, WithAltScreen) si no
hay args; sino hace subcommand routing normal.
Verifica con go mod tidy + go vet.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,110 @@
|
|||||||
|
---
|
||||||
|
name: init_cli_app
|
||||||
|
kind: pipeline
|
||||||
|
lang: bash
|
||||||
|
domain: pipelines
|
||||||
|
version: "1.0.0"
|
||||||
|
purity: impure
|
||||||
|
signature: "init_cli_app(nombre: string, [--with-tui]) -> void"
|
||||||
|
description: "Scaffold de Go CLI app con subcomandos (version/status/help) routed via os.Args. Con --with-tui genera model.go con un modelo Bubbletea fullscreen (lista filtrable + spinner + dark theme) y main.go arranca la TUI en modo fullscreen. Sin dependencias de cobra/urfave — consistente con las apps del registry."
|
||||||
|
tags: [init, scaffold, cli, tui, pipeline, bash, launcher]
|
||||||
|
uses_functions:
|
||||||
|
- assert_command_exists_bash_shell
|
||||||
|
- new_base_model_go_tui
|
||||||
|
- dark_styles_go_tui
|
||||||
|
- run_fullscreen_go_tui
|
||||||
|
- new_spinner_go_tui
|
||||||
|
- new_filtered_list_go_tui
|
||||||
|
uses_types: []
|
||||||
|
returns: []
|
||||||
|
returns_optional: false
|
||||||
|
error_type: "error_go_core"
|
||||||
|
imports: []
|
||||||
|
params:
|
||||||
|
- name: nombre
|
||||||
|
desc: "nombre de la CLI app (apps/{nombre}/); se usa como binario y como modulo Go"
|
||||||
|
- name: "--with-tui"
|
||||||
|
desc: "anade model.go con modelo Bubbletea (lista + spinner + dark theme) y arranca TUI fullscreen al invocar sin args"
|
||||||
|
output: "CLI app en apps/{nombre}/ con main.go (subcommand routing), cmd_version.go, cmd_status.go, Makefile con targets build/run/install/test/vet/clean. Con --with-tui anade model.go y el default sin args arranca TUI."
|
||||||
|
tested: false
|
||||||
|
tests: []
|
||||||
|
test_file_path: ""
|
||||||
|
example: "fn run init_cli_app my_cli --with-tui"
|
||||||
|
file_path: "bash/functions/pipelines/init_cli_app.sh"
|
||||||
|
---
|
||||||
|
|
||||||
|
## Sinopsis
|
||||||
|
|
||||||
|
```bash
|
||||||
|
fn run init_cli_app <nombre> [--with-tui]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ejemplo rapido
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# CLI clasica
|
||||||
|
fn run init_cli_app mytool
|
||||||
|
cd apps/mytool
|
||||||
|
make build
|
||||||
|
./mytool version
|
||||||
|
./mytool status
|
||||||
|
|
||||||
|
# CLI + TUI fullscreen
|
||||||
|
fn run init_cli_app deploy_helper --with-tui
|
||||||
|
cd apps/deploy_helper
|
||||||
|
make build
|
||||||
|
./deploy_helper # arranca TUI
|
||||||
|
./deploy_helper version # subcomando
|
||||||
|
```
|
||||||
|
|
||||||
|
## Archivos generados
|
||||||
|
|
||||||
|
| Archivo | Descripcion |
|
||||||
|
|---------|-------------|
|
||||||
|
| `main.go` | Entry con `switch os.Args[1]`; subcomandos: version, status, help |
|
||||||
|
| `cmd_version.go` | Imprime nombre + version |
|
||||||
|
| `cmd_status.go` | Imprime app/version/go/os/arch |
|
||||||
|
| `go.mod` | Modulo Go con replace `fn-registry`; con `--with-tui` agrega bubbletea/bubbles/lipgloss |
|
||||||
|
| `Makefile` | Targets build, run (ARGS=...), install (~/.local/bin/), test, vet, clean |
|
||||||
|
| `.gitignore` | Binario + IDE files |
|
||||||
|
| `app.md` | Tag `cli` (o `cli,tui,bubbletea` con `--with-tui`) |
|
||||||
|
|
||||||
|
Con `--with-tui` anade:
|
||||||
|
- `model.go` — `Model` con spinner (spinner.Dot), lista Bubbletea con 4 items de ejemplo, dark theme (lipgloss con colores 7D56F4 / 06B6D4), keys enter/q/ctrl+c
|
||||||
|
- `main.go` arranca la TUI con `tea.NewProgram(model, tea.WithAltScreen())` si no hay args
|
||||||
|
|
||||||
|
## Flags
|
||||||
|
|
||||||
|
| Flag | Efecto |
|
||||||
|
|------|--------|
|
||||||
|
| `--with-tui` | Anade model.go con Bubbletea y TUI fullscreen como default |
|
||||||
|
|
||||||
|
## Post-setup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd apps/{nombre}
|
||||||
|
make build # construye ./{nombre}
|
||||||
|
./{nombre} version
|
||||||
|
./{nombre} status
|
||||||
|
make install # copia a ~/.local/bin/{nombre}
|
||||||
|
make run ARGS="status" # build + run con argumentos
|
||||||
|
```
|
||||||
|
|
||||||
|
## Notas
|
||||||
|
|
||||||
|
Pipeline impuro: genera archivos, ejecuta `go mod tidy` y `go vet` al final.
|
||||||
|
|
||||||
|
Los ejemplos del modelo TUI (items "Deploy", "Status", "Logs", "Exit") son
|
||||||
|
placeholders — reemplazar con la logica real de la app. El modelo usa los
|
||||||
|
componentes estandar de bubbles (`list`, `spinner`) y lipgloss para estilos.
|
||||||
|
|
||||||
|
Las funciones del registry `new_base_model_go_tui`, `dark_styles_go_tui`,
|
||||||
|
`run_fullscreen_go_tui`, `new_spinner_go_tui`, `new_filtered_list_go_tui`
|
||||||
|
son referenciadas en el frontmatter como deps conceptuales aunque el
|
||||||
|
scaffold inline el codigo Bubbletea directamente (las funciones del registry
|
||||||
|
son stubs que delegan a devfactory/tui).
|
||||||
|
|
||||||
|
Abort si `apps/{nombre}/` ya existe.
|
||||||
|
|
||||||
|
El tag `launcher` permite que aparezca en el Pipeline Launcher TUI (aunque
|
||||||
|
una CLI con TUI interactiva normalmente no se lanza como subprocess).
|
||||||
Executable
+460
@@ -0,0 +1,460 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# init_cli_app
|
||||||
|
# ------------
|
||||||
|
# Scaffold de Go CLI app con subcomandos, opcionalmente con TUI Bubbletea.
|
||||||
|
#
|
||||||
|
# Genera main.go con routing de subcomandos (os.Args + switch), cmd_version.go,
|
||||||
|
# cmd_status.go, Makefile, .gitignore, go.mod y app.md.
|
||||||
|
#
|
||||||
|
# Con --with-tui genera ademas model.go con un modelo Bubbletea base y main.go
|
||||||
|
# arranca la TUI con tea.NewProgram().Run() en modo fullscreen.
|
||||||
|
#
|
||||||
|
# USO:
|
||||||
|
# ./init_cli_app.sh <nombre> [--with-tui]
|
||||||
|
#
|
||||||
|
# EJEMPLOS:
|
||||||
|
# ./init_cli_app.sh my_cli
|
||||||
|
# ./init_cli_app.sh deploy_helper --with-tui
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
REGISTRY_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
|
||||||
|
|
||||||
|
source "$REGISTRY_ROOT/bash/functions/shell/assert_command_exists.sh"
|
||||||
|
|
||||||
|
NOMBRE=""
|
||||||
|
WITH_TUI="false"
|
||||||
|
|
||||||
|
while [ $# -gt 0 ]; do
|
||||||
|
case "$1" in
|
||||||
|
--with-tui) WITH_TUI="true"; shift ;;
|
||||||
|
-h|--help) grep "^#" "$0" | sed 's/^# \?//' ; exit 0 ;;
|
||||||
|
-*) echo "Flag desconocido: $1" >&2 ; exit 1 ;;
|
||||||
|
*)
|
||||||
|
if [ -z "$NOMBRE" ]; then NOMBRE="$1"
|
||||||
|
else echo "Argumento extra ignorado: $1" >&2
|
||||||
|
fi
|
||||||
|
shift ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$NOMBRE" ]; then
|
||||||
|
echo "Uso: $0 <nombre> [--with-tui]" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
APP_DIR="${REGISTRY_ROOT}/apps/${NOMBRE}"
|
||||||
|
if [ -d "$APP_DIR" ]; then
|
||||||
|
echo "ERROR: ${APP_DIR} ya existe. Abortando." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "════════════════════════════════════════════════════════════"
|
||||||
|
echo " INIT CLI APP: ${NOMBRE}"
|
||||||
|
echo " Directorio: ${APP_DIR}"
|
||||||
|
echo " TUI: ${WITH_TUI}"
|
||||||
|
echo "════════════════════════════════════════════════════════════"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# ── 1. Verificar Go ──────────────────────────────────────────
|
||||||
|
|
||||||
|
echo "[1/5] Verificando herramientas..."
|
||||||
|
assert_command_exists go
|
||||||
|
echo " Go: $(go version)"
|
||||||
|
|
||||||
|
# ── 2. Crear estructura ──────────────────────────────────────
|
||||||
|
|
||||||
|
echo "[2/5] Creando estructura..."
|
||||||
|
mkdir -p "$APP_DIR"
|
||||||
|
|
||||||
|
# go.mod
|
||||||
|
if [ "$WITH_TUI" = "true" ]; then
|
||||||
|
cat > "$APP_DIR/go.mod" <<EOF
|
||||||
|
module ${NOMBRE}
|
||||||
|
|
||||||
|
go 1.25.0
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/charmbracelet/bubbles v1.0.0
|
||||||
|
github.com/charmbracelet/bubbletea v1.3.10
|
||||||
|
github.com/charmbracelet/lipgloss v1.1.0
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
fn-registry v0.0.0-00010101000000-000000000000
|
||||||
|
)
|
||||||
|
|
||||||
|
replace fn-registry => ${REGISTRY_ROOT}
|
||||||
|
EOF
|
||||||
|
else
|
||||||
|
cat > "$APP_DIR/go.mod" <<EOF
|
||||||
|
module ${NOMBRE}
|
||||||
|
|
||||||
|
go 1.25.0
|
||||||
|
|
||||||
|
require (
|
||||||
|
fn-registry v0.0.0-00010101000000-000000000000
|
||||||
|
)
|
||||||
|
|
||||||
|
replace fn-registry => ${REGISTRY_ROOT}
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 3. Archivos Go ───────────────────────────────────────────
|
||||||
|
|
||||||
|
echo "[3/5] Escribiendo archivos Go..."
|
||||||
|
|
||||||
|
# cmd_version.go — siempre existe
|
||||||
|
cat > "$APP_DIR/cmd_version.go" <<EOF
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
var version = "0.1.0"
|
||||||
|
|
||||||
|
func cmdVersion() {
|
||||||
|
fmt.Printf("${NOMBRE} %s\n", version)
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# cmd_status.go — siempre existe
|
||||||
|
cat > "$APP_DIR/cmd_status.go" <<EOF
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
func cmdStatus() {
|
||||||
|
fmt.Printf("app: ${NOMBRE}\n")
|
||||||
|
fmt.Printf("version: %s\n", version)
|
||||||
|
fmt.Printf("go: %s\n", runtime.Version())
|
||||||
|
fmt.Printf("os/arch: %s/%s\n", runtime.GOOS, runtime.GOARCH)
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
if [ "$WITH_TUI" = "true" ]; then
|
||||||
|
# model.go — Bubbletea BaseModel con spinner y lista
|
||||||
|
cat > "$APP_DIR/model.go" <<EOF
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/charmbracelet/bubbles/list"
|
||||||
|
"github.com/charmbracelet/bubbles/spinner"
|
||||||
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
|
"github.com/charmbracelet/lipgloss"
|
||||||
|
)
|
||||||
|
|
||||||
|
// --- estilos (dark theme) ---
|
||||||
|
|
||||||
|
var (
|
||||||
|
titleStyle = lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("#7D56F4"))
|
||||||
|
helpStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#626262"))
|
||||||
|
selectedStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#06B6D4"))
|
||||||
|
)
|
||||||
|
|
||||||
|
// --- item de la lista ---
|
||||||
|
|
||||||
|
type item struct {
|
||||||
|
title, desc string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i item) Title() string { return i.title }
|
||||||
|
func (i item) Description() string { return i.desc }
|
||||||
|
func (i item) FilterValue() string { return i.title }
|
||||||
|
|
||||||
|
// --- modelo raiz ---
|
||||||
|
|
||||||
|
type Model struct {
|
||||||
|
spinner spinner.Model
|
||||||
|
list list.Model
|
||||||
|
status string
|
||||||
|
quit bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewModel() Model {
|
||||||
|
items := []list.Item{
|
||||||
|
item{title: "Deploy", desc: "Subir codigo al VPS"},
|
||||||
|
item{title: "Status", desc: "Ver estado de servicios"},
|
||||||
|
item{title: "Logs", desc: "Tail de logs en tiempo real"},
|
||||||
|
item{title: "Exit", desc: "Salir"},
|
||||||
|
}
|
||||||
|
|
||||||
|
l := list.New(items, list.NewDefaultDelegate(), 0, 0)
|
||||||
|
l.Title = "${NOMBRE} — elige una accion"
|
||||||
|
l.Styles.Title = titleStyle
|
||||||
|
|
||||||
|
s := spinner.New()
|
||||||
|
s.Spinner = spinner.Dot
|
||||||
|
s.Style = selectedStyle
|
||||||
|
|
||||||
|
return Model{
|
||||||
|
spinner: s,
|
||||||
|
list: l,
|
||||||
|
status: "listo",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Model) Init() tea.Cmd {
|
||||||
|
return tea.Batch(m.spinner.Tick)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
|
var cmds []tea.Cmd
|
||||||
|
|
||||||
|
switch msg := msg.(type) {
|
||||||
|
case tea.KeyMsg:
|
||||||
|
switch msg.String() {
|
||||||
|
case "q", "ctrl+c":
|
||||||
|
m.quit = true
|
||||||
|
return m, tea.Quit
|
||||||
|
case "enter":
|
||||||
|
if it, ok := m.list.SelectedItem().(item); ok {
|
||||||
|
if it.title == "Exit" {
|
||||||
|
m.quit = true
|
||||||
|
return m, tea.Quit
|
||||||
|
}
|
||||||
|
m.status = fmt.Sprintf("seleccionado: %s", it.title)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case tea.WindowSizeMsg:
|
||||||
|
m.list.SetSize(msg.Width, msg.Height-4)
|
||||||
|
case spinner.TickMsg:
|
||||||
|
var cmd tea.Cmd
|
||||||
|
m.spinner, cmd = m.spinner.Update(msg)
|
||||||
|
cmds = append(cmds, cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
var cmd tea.Cmd
|
||||||
|
m.list, cmd = m.list.Update(msg)
|
||||||
|
cmds = append(cmds, cmd)
|
||||||
|
|
||||||
|
return m, tea.Batch(cmds...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Model) View() string {
|
||||||
|
if m.quit {
|
||||||
|
return "adios!\n"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf(
|
||||||
|
"%s\n\n%s %s\n%s",
|
||||||
|
m.list.View(),
|
||||||
|
m.spinner.View(),
|
||||||
|
m.status,
|
||||||
|
helpStyle.Render("enter: seleccionar · q: salir"),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# main.go con TUI
|
||||||
|
cat > "$APP_DIR/main.go" <<EOF
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if len(os.Args) < 2 {
|
||||||
|
runTUI()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch os.Args[1] {
|
||||||
|
case "tui":
|
||||||
|
runTUI()
|
||||||
|
case "version":
|
||||||
|
cmdVersion()
|
||||||
|
case "status":
|
||||||
|
cmdStatus()
|
||||||
|
case "help", "-h", "--help":
|
||||||
|
printUsage()
|
||||||
|
default:
|
||||||
|
fmt.Fprintf(os.Stderr, "comando desconocido: %s\n", os.Args[1])
|
||||||
|
printUsage()
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func runTUI() {
|
||||||
|
p := tea.NewProgram(NewModel(), tea.WithAltScreen())
|
||||||
|
if _, err := p.Run(); err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "tui error: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func printUsage() {
|
||||||
|
fmt.Println(\`${NOMBRE} — CLI tool
|
||||||
|
|
||||||
|
Uso:
|
||||||
|
${NOMBRE} [comando]
|
||||||
|
|
||||||
|
Sin comando arranca la TUI fullscreen.
|
||||||
|
|
||||||
|
Comandos:
|
||||||
|
tui Arranca la TUI fullscreen (default)
|
||||||
|
version Imprime la version
|
||||||
|
status Muestra info del sistema
|
||||||
|
help Muestra esta ayuda\`)
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
else
|
||||||
|
# main.go sin TUI — subcommand routing clasico
|
||||||
|
cat > "$APP_DIR/main.go" <<EOF
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if len(os.Args) < 2 {
|
||||||
|
printUsage()
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch os.Args[1] {
|
||||||
|
case "version":
|
||||||
|
cmdVersion()
|
||||||
|
case "status":
|
||||||
|
cmdStatus()
|
||||||
|
case "help", "-h", "--help":
|
||||||
|
printUsage()
|
||||||
|
default:
|
||||||
|
fmt.Fprintf(os.Stderr, "comando desconocido: %s\n", os.Args[1])
|
||||||
|
printUsage()
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func printUsage() {
|
||||||
|
fmt.Println(\`${NOMBRE} — CLI tool
|
||||||
|
|
||||||
|
Uso:
|
||||||
|
${NOMBRE} <comando>
|
||||||
|
|
||||||
|
Comandos:
|
||||||
|
version Imprime la version
|
||||||
|
status Muestra info del sistema
|
||||||
|
help Muestra esta ayuda\`)
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 4. Makefile, .gitignore, app.md ─────────────────────────
|
||||||
|
|
||||||
|
echo "[4/5] Escribiendo Makefile, .gitignore, app.md..."
|
||||||
|
|
||||||
|
cat > "$APP_DIR/Makefile" <<EOF
|
||||||
|
.PHONY: build run install test vet clean
|
||||||
|
|
||||||
|
BIN=${NOMBRE}
|
||||||
|
|
||||||
|
build:
|
||||||
|
CGO_ENABLED=1 go build -tags fts5 -o \$(BIN) .
|
||||||
|
|
||||||
|
run: build
|
||||||
|
./\$(BIN) \$(ARGS)
|
||||||
|
|
||||||
|
install: build
|
||||||
|
install -m755 \$(BIN) \$(HOME)/.local/bin/\$(BIN)
|
||||||
|
@echo "instalado en \$(HOME)/.local/bin/\$(BIN)"
|
||||||
|
|
||||||
|
test:
|
||||||
|
CGO_ENABLED=1 go test -tags fts5 -v ./...
|
||||||
|
|
||||||
|
vet:
|
||||||
|
CGO_ENABLED=1 go vet -tags fts5 ./...
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f \$(BIN)
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat > "$APP_DIR/.gitignore" <<EOF
|
||||||
|
# Binario
|
||||||
|
${NOMBRE}
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.idea/
|
||||||
|
.vscode/
|
||||||
|
*.swp
|
||||||
|
EOF
|
||||||
|
|
||||||
|
if [ "$WITH_TUI" = "true" ]; then
|
||||||
|
FRAMEWORK="bubbletea"
|
||||||
|
USES_FUNCTIONS=' - new_base_model_go_tui
|
||||||
|
- dark_styles_go_tui
|
||||||
|
- run_fullscreen_go_tui
|
||||||
|
- new_spinner_go_tui
|
||||||
|
- new_filtered_list_go_tui'
|
||||||
|
TAGS='[cli, tui, bubbletea]'
|
||||||
|
else
|
||||||
|
FRAMEWORK=""
|
||||||
|
USES_FUNCTIONS=' []'
|
||||||
|
TAGS='[cli]'
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat > "$APP_DIR/app.md" <<EOF
|
||||||
|
---
|
||||||
|
name: ${NOMBRE}
|
||||||
|
lang: go
|
||||||
|
domain: tools
|
||||||
|
description: "CLI app generada por init_cli_app."
|
||||||
|
tags: ${TAGS}
|
||||||
|
uses_functions:
|
||||||
|
${USES_FUNCTIONS}
|
||||||
|
uses_types: []
|
||||||
|
framework: "${FRAMEWORK}"
|
||||||
|
entry_point: "main.go"
|
||||||
|
dir_path: "apps/${NOMBRE}"
|
||||||
|
---
|
||||||
|
|
||||||
|
## Notas
|
||||||
|
|
||||||
|
CLI con routing de subcomandos (\`os.Args\` + switch). Sin cobra/urfave —
|
||||||
|
consistente con las apps del registry.
|
||||||
|
|
||||||
|
Ejecutar: \`make run ARGS="version"\` o \`./\${NOMBRE} status\`.
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# ── 5. go mod tidy + go vet ─────────────────────────────────
|
||||||
|
|
||||||
|
echo "[5/5] Verificacion..."
|
||||||
|
(
|
||||||
|
cd "$APP_DIR"
|
||||||
|
if CGO_ENABLED=1 go mod tidy 2>&1 | tail -5; then
|
||||||
|
:
|
||||||
|
fi
|
||||||
|
if CGO_ENABLED=1 go vet -tags fts5 ./... 2>&1; then
|
||||||
|
echo " go vet OK"
|
||||||
|
else
|
||||||
|
echo " WARN: go vet fallo" >&2
|
||||||
|
fi
|
||||||
|
)
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "════════════════════════════════════════════════════════════"
|
||||||
|
echo " CLI APP '${NOMBRE}' LISTA"
|
||||||
|
echo "════════════════════════════════════════════════════════════"
|
||||||
|
echo ""
|
||||||
|
echo " Pasos siguientes:"
|
||||||
|
echo " cd apps/${NOMBRE}"
|
||||||
|
echo " make build"
|
||||||
|
if [ "$WITH_TUI" = "true" ]; then
|
||||||
|
echo " ./${NOMBRE} # arranca la TUI fullscreen"
|
||||||
|
echo " ./${NOMBRE} version # comando CLI"
|
||||||
|
else
|
||||||
|
echo " ./${NOMBRE} version"
|
||||||
|
echo " ./${NOMBRE} status"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
Reference in New Issue
Block a user