From c383e6464a4ef02d3fc8bc2eaac71d34daf91315 Mon Sep 17 00:00:00 2001 From: Egutierrez Date: Sun, 12 Apr 2026 13:54:30 +0200 Subject: [PATCH] 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. --- bash/functions/pipelines/init_go_module.md | 49 ++++ bash/functions/pipelines/init_go_module.sh | 160 +++++++++++ bash/functions/pipelines/init_go_project.md | 49 ++++ bash/functions/pipelines/init_go_project.sh | 296 ++++++++++++++++++++ 4 files changed, 554 insertions(+) create mode 100644 bash/functions/pipelines/init_go_module.md create mode 100644 bash/functions/pipelines/init_go_module.sh create mode 100644 bash/functions/pipelines/init_go_project.md create mode 100644 bash/functions/pipelines/init_go_project.sh diff --git a/bash/functions/pipelines/init_go_module.md b/bash/functions/pipelines/init_go_module.md new file mode 100644 index 00000000..fdb11920 --- /dev/null +++ b/bash/functions/pipelines/init_go_module.md @@ -0,0 +1,49 @@ +--- +name: init_go_module +kind: pipeline +lang: bash +domain: pipelines +version: "1.0.0" +purity: impure +signature: "init_go_module([module_path: string]) -> void" +description: "Pipeline que inicializa un módulo Go simple en el directorio actual. Crea go.mod (go mod init), main.go con hello world, .gitignore, build.sh (cross-compilation linux/windows/all) y dev.sh para ejecución rápida." +tags: [bash, go, module, init, scaffold, launcher] +uses_functions: [install_go_bash_infra, assert_command_exists_bash_shell] +uses_types: [] +returns: [] +returns_optional: false +error_type: "error_go_core" +imports: [] +params: + - name: module_path + desc: "path del módulo Go, ej: github.com/user/mymodule (default: github.com/user/)" +output: "crea archivos en el directorio actual y muestra progreso; exit code 1 si Go no está instalado o go mod init falla" +tested: false +tests: [] +test_file_path: "" +file_path: "bash/functions/pipelines/init_go_module.sh" +source_repo: "https://gitea-dgg044oo04woo4ggcsws4gk0.organic-machine.com/egutierrez/DevLauncher.git" +source_license: "MIT" +source_file: "scripts/linux/inicializar_repos/go/init_go_module.sh" +--- + +## Ejemplo + +```bash +mkdir mi-modulo && cd mi-modulo + +# Con module_path automático (github.com/user/mi-modulo) +bash bash/functions/pipelines/init_go_module.sh + +# Con module_path explícito +bash bash/functions/pipelines/init_go_module.sh github.com/miorg/mi-modulo + +# Ejecutar tras crear +./dev.sh +./build.sh +./build.sh all +``` + +## Notas + +Crea un módulo minimalista (main.go simple + build tools). Para proyectos con estructura profesional (cmd/, internal/, pkg/) usar `init_go_project`. No inicializa git — añadido manualmente o via gitea_init_app. diff --git a/bash/functions/pipelines/init_go_module.sh b/bash/functions/pipelines/init_go_module.sh new file mode 100644 index 00000000..afe3860a --- /dev/null +++ b/bash/functions/pipelines/init_go_module.sh @@ -0,0 +1,160 @@ +#!/usr/bin/env bash +# init_go_module +# -------------- +# Pipeline que inicializa un módulo Go simple en el directorio actual. +# Crea: go.mod, main.go, .gitignore, build.sh y dev.sh. +# +# USO: +# bash init_go_module.sh [module_path] +# +# ARGUMENTOS: +# module_path Path del módulo Go (opcional; default: github.com/user/) + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +init_go_module() { + local module_path="${1:-}" + + local dir_name + dir_name="$(basename "$(pwd)")" + + if [[ -z "$module_path" ]]; then + module_path="github.com/user/${dir_name}" + fi + + echo "=== Inicializar Módulo Go ===" + echo " Módulo: ${module_path}" + echo " Directorio: $(pwd)" + echo "" + + # Verificar Go + if ! command -v go &>/dev/null; then + echo "init_go_module: Go no está instalado" >&2 + return 1 + fi + echo "Go detectado: $(go version)" + echo "" + + # Inicializar módulo + echo "Inicializando go module..." + if ! go mod init "$module_path"; then + echo "init_go_module: falló go mod init" >&2 + return 1 + fi + echo "go.mod creado" + echo "" + + # Crear main.go + echo "Creando main.go..." + cat > main.go << 'GOEOF' +package main + +import ( + "fmt" +) + +func main() { + fmt.Println("Hola desde Go!") + fmt.Println("Modulo inicializado correctamente") +} +GOEOF + echo "main.go creado" + echo "" + + # Crear .gitignore + echo "Creando .gitignore..." + cat > .gitignore << 'IGNEOF' +# Binarios +*.exe +*.exe~ +*.dll +*.so +*.dylib +bin/ +build/ + +# Archivos de test +*.test +*.out +coverage.txt +*.prof + +# IDEs +.idea/ +.vscode/ +*.swp +*.swo +*~ + +# OS +.DS_Store +Thumbs.db +IGNEOF + echo ".gitignore creado" + echo "" + + # Crear build.sh + echo "Creando build.sh..." + cat > build.sh << 'BUILDEOF' +#!/bin/bash +set -euo pipefail + +TARGET="${1:-linux}" +mkdir -p bin + +case "$TARGET" in + linux) + GOOS=linux GOARCH=amd64 go build -o bin/app-linux main.go + chmod +x bin/app-linux + echo "Compilado: bin/app-linux" + ;; + windows) + GOOS=windows GOARCH=amd64 go build -o bin/app-windows.exe main.go + echo "Compilado: bin/app-windows.exe" + ;; + all) + GOOS=linux GOARCH=amd64 go build -o bin/app-linux main.go && echo "Linux OK" + GOOS=windows GOARCH=amd64 go build -o bin/app-windows.exe main.go && echo "Windows OK" + GOOS=darwin GOARCH=amd64 go build -o bin/app-macos main.go && echo "macOS OK" + ;; + *) + echo "Uso: ./build.sh [linux|windows|all]" >&2 + exit 1 + ;; +esac +BUILDEOF + chmod +x build.sh + echo "build.sh creado" + echo "" + + # Crear dev.sh + echo "Creando dev.sh..." + cat > dev.sh << 'DEVEOF' +#!/bin/bash +set -euo pipefail + +go run main.go "$@" +DEVEOF + chmod +x dev.sh + echo "dev.sh creado" + echo "" + + echo "=== Modulo Go creado exitosamente ===" + echo "" + echo "Archivos generados:" + echo " main.go - Codigo del modulo" + echo " go.mod - Modulo Go (${module_path})" + echo " .gitignore - Exclusiones git" + echo " build.sh - Compilar binario" + echo " dev.sh - Ejecutar directamente" + echo "" + echo "Proximos pasos:" + echo " ./dev.sh - Ejecutar el modulo" + echo " ./build.sh - Compilar para Linux" + echo " ./build.sh windows - Compilar para Windows" + echo " ./build.sh all - Compilar para todo" +} + +init_go_module "$@" diff --git a/bash/functions/pipelines/init_go_project.md b/bash/functions/pipelines/init_go_project.md new file mode 100644 index 00000000..2e7ab74d --- /dev/null +++ b/bash/functions/pipelines/init_go_project.md @@ -0,0 +1,49 @@ +--- +name: init_go_project +kind: pipeline +lang: bash +domain: pipelines +version: "1.0.0" +purity: impure +signature: "init_go_project([module_path: string]) -> void" +description: "Pipeline que inicializa un repositorio Go completo con estructura profesional: cmd/app, internal/config, internal/service (con tests), pkg/version, scripts (run/test/build/build-all/lint), Makefile, .gitignore, README y git init con git add." +tags: [bash, go, project, init, scaffold, professional, launcher] +uses_functions: [install_go_bash_infra, assert_command_exists_bash_shell, create_project_structure_bash_shell] +uses_types: [] +returns: [] +returns_optional: false +error_type: "error_go_core" +imports: [] +params: + - name: module_path + desc: "path del módulo Go, ej: github.com/org/myproject (default: github.com//)" +output: "crea estructura completa en el directorio actual y muestra progreso; exit code 1 si Go o git no están disponibles" +tested: false +tests: [] +test_file_path: "" +file_path: "bash/functions/pipelines/init_go_project.sh" +source_repo: "https://gitea-dgg044oo04woo4ggcsws4gk0.organic-machine.com/egutierrez/DevLauncher.git" +source_license: "MIT" +source_file: "scripts/linux/inicializar_repos/go/init_go_proyect.sh" +--- + +## Ejemplo + +```bash +mkdir mi-proyecto && cd mi-proyecto + +# Con module_path automático +bash bash/functions/pipelines/init_go_project.sh + +# Con module_path explícito +bash bash/functions/pipelines/init_go_project.sh github.com/miorg/mi-proyecto + +# Ejecutar y testear tras crear +./scripts/run.sh +./scripts/test.sh +make build-all +``` + +## Notas + +Genera una arquitectura funcional con separación clara: cmd/ (entrypoint), internal/ (lógica privada), pkg/ (librería pública). Incluye un test de ejemplo en internal/service/. Ejecuta go mod tidy y git init + git add al final. Para módulos simples sin estructura, usar `init_go_module`. diff --git a/bash/functions/pipelines/init_go_project.sh b/bash/functions/pipelines/init_go_project.sh new file mode 100644 index 00000000..10e98060 --- /dev/null +++ b/bash/functions/pipelines/init_go_project.sh @@ -0,0 +1,296 @@ +#!/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//) + +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 "$@"