package main import ( "flag" "fmt" "os" "os/exec" "path/filepath" "strings" ) const ( binaryName = "techircd" version = "1.0.0" ) func main() { var ( buildFlag = flag.Bool("build", false, "Build the binary") runFlag = flag.Bool("run", false, "Build and run the server") testFlag = flag.Bool("test", false, "Run all tests") cleanFlag = flag.Bool("clean", false, "Clean build artifacts") fmtFlag = flag.Bool("fmt", false, "Format Go code") lintFlag = flag.Bool("lint", false, "Run linters") buildAllFlag = flag.Bool("build-all", false, "Build for multiple platforms") releaseFlag = flag.Bool("release", false, "Create optimized release build") helpFlag = flag.Bool("help", false, "Show help message") ) flag.Parse() if *helpFlag || flag.NFlag() == 0 { showHelp() return } switch { case *buildFlag: build() case *runFlag: build() run() case *testFlag: test() case *cleanFlag: clean() case *fmtFlag: format() case *lintFlag: lint() case *buildAllFlag: buildAll() case *releaseFlag: release() } } func showHelp() { fmt.Println("TechIRCd Build Tool") fmt.Println("") fmt.Println("Usage:") fmt.Println(" go run build.go [options]") fmt.Println("") fmt.Println("Options:") fmt.Println(" -build Build the binary") fmt.Println(" -run Build and run the server") fmt.Println(" -test Run all tests") fmt.Println(" -clean Clean build artifacts") fmt.Println(" -fmt Format Go code") fmt.Println(" -lint Run linters") fmt.Println(" -build-all Build for multiple platforms") fmt.Println(" -release Create optimized release build") fmt.Println(" -help Show this help message") } func build() { fmt.Println("Building TechIRCd...") gitVersion, err := exec.Command("git", "describe", "--tags", "--always", "--dirty").Output() var versionStr string if err != nil { versionStr = version } else { versionStr = strings.TrimSpace(string(gitVersion)) } ldflags := fmt.Sprintf("-ldflags=-X main.version=%s", versionStr) cmd := exec.Command("go", "build", ldflags, "-o", binaryName, ".") cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { fmt.Printf("Build failed: %v\n", err) os.Exit(1) } fmt.Println("Build completed successfully!") } func run() { fmt.Println("Starting TechIRCd...") cmd := exec.Command("./" + binaryName) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr cmd.Stdin = os.Stdin if err := cmd.Run(); err != nil { fmt.Printf("Run failed: %v\n", err) os.Exit(1) } } func test() { fmt.Println("Running tests...") cmd := exec.Command("go", "test", "-v", "-race", "./...") cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { fmt.Printf("Tests failed: %v\n", err) os.Exit(1) } fmt.Println("All tests passed!") } func clean() { fmt.Println("Cleaning build artifacts...") // Remove binary files patterns := []string{ binaryName + "*", "coverage.out", "coverage.html", } for _, pattern := range patterns { matches, err := filepath.Glob(pattern) if err != nil { continue } for _, match := range matches { if err := os.Remove(match); err != nil { fmt.Printf("Failed to remove %s: %v\n", match, err) } else { fmt.Printf("Removed %s\n", match) } } } fmt.Println("Clean completed!") } func format() { fmt.Println("Formatting Go code...") cmd := exec.Command("go", "fmt", "./...") cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { fmt.Printf("Format failed: %v\n", err) os.Exit(1) } // Try to run goimports if available if _, err := exec.LookPath("goimports"); err == nil { fmt.Println("Running goimports...") cmd := exec.Command("goimports", "-w", "-local", "github.com/ComputerTech312/TechIRCd", ".") cmd.Run() // Don't fail if this doesn't work } fmt.Println("Format completed!") } func lint() { fmt.Println("Running linters...") if _, err := exec.LookPath("golangci-lint"); err != nil { fmt.Println("golangci-lint not found, skipping...") return } cmd := exec.Command("golangci-lint", "run") cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { fmt.Printf("Linting found issues: %v\n", err) // Don't exit on lint errors, just report them } else { fmt.Println("No linting issues found!") } } func buildAll() { fmt.Println("Building for multiple platforms...") platforms := []struct { goos string goarch string ext string }{ {"linux", "amd64", ""}, {"windows", "amd64", ".exe"}, {"darwin", "amd64", ""}, {"darwin", "arm64", ""}, } gitVersion, err := exec.Command("git", "describe", "--tags", "--always", "--dirty").Output() var versionStr string if err != nil { versionStr = version } else { versionStr = strings.TrimSpace(string(gitVersion)) } for _, platform := range platforms { outputName := fmt.Sprintf("%s-%s-%s%s", binaryName, platform.goos, platform.goarch, platform.ext) fmt.Printf("Building %s...\n", outputName) ldflags := fmt.Sprintf("-ldflags=-X main.version=%s", versionStr) cmd := exec.Command("go", "build", ldflags, "-o", outputName, ".") cmd.Env = append(os.Environ(), "GOOS="+platform.goos, "GOARCH="+platform.goarch, ) if err := cmd.Run(); err != nil { fmt.Printf("Failed to build %s: %v\n", outputName, err) } else { fmt.Printf("Built %s successfully!\n", outputName) } } fmt.Println("Cross-platform build completed!") } func release() { fmt.Println("Creating optimized release build...") gitVersion, err := exec.Command("git", "describe", "--tags", "--always", "--dirty").Output() var versionStr string if err != nil { versionStr = version } else { versionStr = strings.TrimSpace(string(gitVersion)) } ldflags := fmt.Sprintf("-ldflags=-X main.version=%s", versionStr) cmd := exec.Command("go", "build", ldflags, "-a", "-installsuffix", "cgo", "-o", binaryName, ".") cmd.Env = append(os.Environ(), "CGO_ENABLED=0") cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { fmt.Printf("Release build failed: %v\n", err) os.Exit(1) } // Get file info to show size if info, err := os.Stat(binaryName); err == nil { fmt.Printf("Release build completed! Binary size: %.2f MB\n", float64(info.Size())/1024/1024) } else { fmt.Println("Release build completed!") } }