feat(cli): add core go install command

- Add `core go install` for installing Go binaries
- Auto-detects cmd/ subdirectories
- Optional --no-cgo flag for pure Go builds
- Shows install location on success
- Update SKILL.md documentation

Dogfood the CLI daily for better DX.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Snider 2026-01-29 13:00:55 +00:00
parent f887c4b049
commit 5b0a0eac7c
2 changed files with 89 additions and 0 deletions

View file

@ -19,6 +19,7 @@ The `core` command provides a unified interface for Go/Wails development, multi-
| Lint Go code | `core go lint` | Uses golangci-lint | | Lint Go code | `core go lint` | Uses golangci-lint |
| Tidy Go modules | `core go mod tidy` | go mod tidy wrapper | | Tidy Go modules | `core go mod tidy` | go mod tidy wrapper |
| Sync Go workspace | `core go work sync` | go work sync wrapper | | Sync Go workspace | `core go work sync` | go work sync wrapper |
| Install Go binary | `core go install` | Auto-detects cmd/ |
| Run PHP tests | `core php test` | Auto-detects Pest/PHPUnit | | Run PHP tests | `core php test` | Auto-detects Pest/PHPUnit |
| Start PHP dev server | `core php dev` | FrankenPHP + Vite + Horizon + Reverb | | Start PHP dev server | `core php dev` | FrankenPHP + Vite + Horizon + Reverb |
| Format PHP code | `core php fmt --fix` | Laravel Pint | | Format PHP code | `core php fmt --fix` | Laravel Pint |
@ -236,9 +237,26 @@ core pkg outdated
| Run tests with coverage | `core go test --coverage` | Per-package breakdown | | Run tests with coverage | `core go test --coverage` | Per-package breakdown |
| Format code | `core go fmt --fix` | Uses goimports if available | | Format code | `core go fmt --fix` | Uses goimports if available |
| Lint code | `core go lint` | Uses golangci-lint | | Lint code | `core go lint` | Uses golangci-lint |
| Install binary | `core go install` | Auto-detects cmd/, --no-cgo option |
| Tidy modules | `core go mod tidy` | go mod tidy | | Tidy modules | `core go mod tidy` | go mod tidy |
| Sync workspace | `core go work sync` | go work sync | | Sync workspace | `core go work sync` | go work sync |
### Installing
```bash
# Install current module (auto-detects cmd/ subdirs)
core go install
# Install specific path
core go install ./cmd/core
# Pure Go, no C dependencies
core go install --no-cgo
# Verbose output
core go install -v
```
### Testing ### Testing
```bash ```bash

View file

@ -20,12 +20,14 @@ func AddGoCommands(parent *clir.Cli) {
" test Run tests with coverage\n" + " test Run tests with coverage\n" +
" fmt Format Go code\n" + " fmt Format Go code\n" +
" lint Run golangci-lint\n" + " lint Run golangci-lint\n" +
" install Install Go binary (CGO_ENABLED=0)\n" +
" mod Module management (tidy, download, verify)\n" + " mod Module management (tidy, download, verify)\n" +
" work Workspace management") " work Workspace management")
addGoTestCommand(goCmd) addGoTestCommand(goCmd)
addGoFmtCommand(goCmd) addGoFmtCommand(goCmd)
addGoLintCommand(goCmd) addGoLintCommand(goCmd)
addGoInstallCommand(goCmd)
addGoModCommand(goCmd) addGoModCommand(goCmd)
addGoWorkCommand(goCmd) addGoWorkCommand(goCmd)
} }
@ -253,6 +255,75 @@ func addGoLintCommand(parent *clir.Command) {
}) })
} }
func addGoInstallCommand(parent *clir.Command) {
var verbose bool
var noCgo bool
installCmd := parent.NewSubCommand("install", "Install Go binary")
installCmd.LongDescription("Install Go binary to $GOPATH/bin.\n\n" +
"Examples:\n" +
" core go install # Install current module\n" +
" core go install ./cmd/core # Install specific path\n" +
" core go install --no-cgo # Pure Go (no C dependencies)\n" +
" core go install -v # Verbose output")
installCmd.BoolFlag("v", "Verbose output", &verbose)
installCmd.BoolFlag("no-cgo", "Disable CGO (CGO_ENABLED=0)", &noCgo)
installCmd.Action(func() error {
// Get install path from args or default to current dir
args := installCmd.OtherArgs()
installPath := "./..."
if len(args) > 0 {
installPath = args[0]
}
// Detect if we're in a module with cmd/ subdirectories
if installPath == "./..." {
if entries, err := os.ReadDir("cmd"); err == nil && len(entries) > 0 {
installPath = "./cmd/..."
} else if _, err := os.Stat("main.go"); err == nil {
installPath = "."
}
}
fmt.Printf("%s Installing\n", dimStyle.Render("Install:"))
fmt.Printf(" %s %s\n", dimStyle.Render("Path:"), installPath)
if noCgo {
fmt.Printf(" %s %s\n", dimStyle.Render("CGO:"), "disabled")
}
cmdArgs := []string{"install"}
if verbose {
cmdArgs = append(cmdArgs, "-v")
}
cmdArgs = append(cmdArgs, installPath)
cmd := exec.Command("go", cmdArgs...)
if noCgo {
cmd.Env = append(os.Environ(), "CGO_ENABLED=0")
}
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
fmt.Printf("\n%s\n", errorStyle.Render("FAIL Install failed"))
return err
}
// Show where it was installed
gopath := os.Getenv("GOPATH")
if gopath == "" {
home, _ := os.UserHomeDir()
gopath = filepath.Join(home, "go")
}
binDir := filepath.Join(gopath, "bin")
fmt.Printf("\n%s Installed to %s\n", successStyle.Render("OK"), binDir)
return nil
})
}
func addGoModCommand(parent *clir.Command) { func addGoModCommand(parent *clir.Command) {
modCmd := parent.NewSubCommand("mod", "Module management") modCmd := parent.NewSubCommand("mod", "Module management")
modCmd.LongDescription("Go module management commands.\n\n" + modCmd.LongDescription("Go module management commands.\n\n" +