Files
egutierrez c383e6464a feat: add bash pipeline functions for Go project initialization
2 pipelines Bash: init_go_module (inicializa un modulo Go con go mod init y
estructura de directorios estandar) e init_go_project (scaffolding completo
de proyecto Go con cmd/, internal/, configs y Makefile). Componen funciones
shell existentes del registry.
2026-04-12 13:54:30 +02:00

297 lines
5.8 KiB
Bash

#!/usr/bin/env bash
# init_go_project
# ---------------
# Pipeline que inicializa un repositorio Go completo con estructura profesional:
# cmd/app, internal/config, internal/service, pkg/version, scripts/, Makefile,
# .gitignore, README y git init.
#
# USO:
# bash init_go_project.sh [module_path]
#
# ARGUMENTOS:
# module_path Path del módulo Go (opcional; default: github.com/<whoami>/<dirname>)
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
init_go_project() {
local module_path="${1:-}"
local project_name
project_name="$(basename "$(pwd)")"
if [[ -z "$module_path" ]]; then
module_path="github.com/$(whoami)/${project_name}"
fi
echo "=== Inicializar Proyecto Go Completo ==="
echo " Proyecto: ${project_name}"
echo " Módulo: ${module_path}"
echo " Dir: $(pwd)"
echo ""
# Verificar dependencias
if ! command -v go &>/dev/null; then
echo "init_go_project: Go no está instalado" >&2
return 1
fi
if ! command -v git &>/dev/null; then
echo "init_go_project: git no está instalado" >&2
return 1
fi
echo "Go: $(go version)"
echo "git: $(git --version)"
echo ""
# Crear estructura de carpetas
echo "Creando estructura de carpetas..."
mkdir -p cmd/app internal/config internal/service pkg/version scripts bin
echo "Estructura base creada"
echo ""
# go mod init
echo "Inicializando módulo Go..."
if ! go mod init "$module_path"; then
echo "init_go_project: falló go mod init" >&2
return 1
fi
echo "go.mod creado"
echo ""
# Crear archivos fuente
echo "Creando archivos fuente..."
cat > cmd/app/main.go << GOEOF
package main
import (
"fmt"
"${module_path}/internal/config"
"${module_path}/internal/service"
"${module_path}/pkg/version"
)
func main() {
cfg := config.Load()
msg := service.BuildStartupMessage(cfg.AppName, version.Current())
fmt.Println(msg)
}
GOEOF
cat > internal/config/config.go << 'CFGEOF'
package config
import "os"
type AppConfig struct {
AppName string
}
func Load() AppConfig {
appName := os.Getenv("APP_NAME")
if appName == "" {
appName = "Go Project"
}
return AppConfig{AppName: appName}
}
CFGEOF
cat > internal/service/message.go << 'SVCEOF'
package service
import "fmt"
func BuildStartupMessage(appName, appVersion string) string {
return fmt.Sprintf("%s iniciado correctamente (version %s)", appName, appVersion)
}
SVCEOF
cat > internal/service/message_test.go << 'TESTEOF'
package service
import "testing"
func TestBuildStartupMessage(t *testing.T) {
result := BuildStartupMessage("MyApp", "0.1.0")
want := "MyApp iniciado correctamente (version 0.1.0)"
if result != want {
t.Fatalf("resultado inesperado:\nwant: %s\ngot: %s", want, result)
}
}
TESTEOF
cat > pkg/version/version.go << 'VEREOF'
package version
var value = "0.1.0"
func Current() string {
return value
}
VEREOF
echo "Archivos fuente creados"
echo ""
# Makefile
echo "Creando Makefile..."
cat > Makefile << 'MAKEEOF'
APP_NAME=app
CMD_PATH=./cmd/app
BIN_DIR=./bin
.PHONY: run build build-all test fmt tidy clean
run:
go run $(CMD_PATH)
build:
mkdir -p $(BIN_DIR)
go build -o $(BIN_DIR)/$(APP_NAME) $(CMD_PATH)
build-all:
bash ./scripts/build-all.sh
test:
go test ./...
fmt:
gofmt -w ./cmd ./internal ./pkg
tidy:
go mod tidy
clean:
rm -rf $(BIN_DIR)
MAKEEOF
echo "Makefile creado"
echo ""
# .gitignore
cat > .gitignore << 'IGNEOF'
bin/
*.exe
*.exe~
*.dll
*.so
*.dylib
*.test
*.out
coverage.out
.idea/
.vscode/
*.swp
*.swo
*~
.DS_Store
Thumbs.db
IGNEOF
# README
cat > README.md << READEOF
# ${project_name}
Repositorio Go inicializado con estructura completa.
## Uso rápido
\`\`\`bash
./scripts/run.sh
./scripts/test.sh
./scripts/build.sh
\`\`\`
## Make
\`\`\`bash
make run
make test
make build
make build-all
\`\`\`
READEOF
# Scripts
echo "Creando scripts..."
cat > scripts/run.sh << 'RUNEOF'
#!/bin/bash
set -euo pipefail
go run ./cmd/app
RUNEOF
cat > scripts/test.sh << 'TESTSHEOF'
#!/bin/bash
set -euo pipefail
go test ./...
TESTSHEOF
cat > scripts/build.sh << 'BUILDSHEOF'
#!/bin/bash
set -euo pipefail
mkdir -p ./bin
go build -o ./bin/app ./cmd/app
echo "Binario: ./bin/app"
BUILDSHEOF
cat > scripts/build-all.sh << 'BUILDALLEOF'
#!/bin/bash
set -euo pipefail
mkdir -p ./bin
GOOS=linux GOARCH=amd64 go build -o ./bin/app-linux-amd64 ./cmd/app
GOOS=darwin GOARCH=amd64 go build -o ./bin/app-darwin-amd64 ./cmd/app
GOOS=windows GOARCH=amd64 go build -o ./bin/app-windows-amd64.exe ./cmd/app
echo "Builds en ./bin"
BUILDALLEOF
cat > scripts/lint.sh << 'LINTEOF'
#!/bin/bash
set -euo pipefail
unformatted="$(gofmt -l ./cmd ./internal ./pkg)"
if [ -n "$unformatted" ]; then
echo "Archivos sin formato:" >&2
echo "$unformatted" >&2
echo "Ejecuta: make fmt" >&2
exit 1
fi
echo "Formato OK"
LINTEOF
chmod +x scripts/*.sh
echo "Scripts creados"
echo ""
# go mod tidy
echo "Ajustando dependencias (go mod tidy)..."
go mod tidy
echo "Dependencias ajustadas"
echo ""
# git init
echo "Inicializando repositorio git..."
git init >/dev/null 2>&1
git add .
echo "Repositorio git inicializado"
echo ""
echo "=== Proyecto Go creado exitosamente ==="
echo ""
echo "Estructura:"
echo " cmd/app/main.go"
echo " internal/config/config.go"
echo " internal/service/message.go + message_test.go"
echo " pkg/version/version.go"
echo " scripts/ (run, test, build, build-all, lint)"
echo " Makefile, go.mod, .gitignore, README.md"
echo ""
echo "Proximos pasos:"
echo " 1. ./scripts/run.sh"
echo " 2. ./scripts/test.sh"
echo " 3. ./scripts/build-all.sh"
}
init_go_project "$@"