I had the idea, that it would be cool to be able to make a small Golang build tool, where all you had to do was create functions in a Golang file and you can call them from a cli. No extra work.

Here’s the proof of concept.

package main
import ( "fmt" "os" "reflect")
 
type Commands struct{}
var commands Commands
 
func main() {
    if len(os.Args) < 2 {
        commands.Help()
        return
    }
 
    commandName := os.Args[1]
    cmd := reflect.ValueOf(&commands).MethodByName(commandName)
 
    if cmd.IsValid() {
        cmd.Call([]reflect.Value{})
        return
    }
 
    fmt.Println("Invalid command.")
}
 
func (t *Commands) Help() {
    fmt.Println("Available options: Greet!")
}
 
func (t *Commands) Greet() {
    args := os.Args[2:]
    fmt.Println("Hello,", args)
}

Its a bit crude, especially since you have to capitalize commands. However, just like the idea, all you have to do is add functions.

It would would be nice to add things like case insensitivity, and wrap all that up in a package so the boilerplate was minimal. Maybe bring in Cobra to make the CLI experience better. Usage like this would be cool.

package main
import "github.com/metruzanca/gofile"
 
type Commands struct{}
var commands Commands
 
func main() {
  gofile.Start(&commands)
}
 
// your command implementations below e.g.
 
func (t *Commands) Greet() {
   fmt.Println("Hello, World!")
}

This way you can keep all your scripting in Golang, instead of in bash in a Makefile. Theoretically, you could have this file (say dev.go) in the root and you could run go run dev.go init and that would create an alias/or something so you could run dev greet soon after. Maybe you could define your custom PostInit that will also run go install github.com/air-verse/air@latest.