Go binary distribution: run another binary/Go module from the code

Hello there!

The title is a bit ambigious, but let me try to explain my problem here:

Context:

I'm building a toy CLI tool (using Go and Cobra). My tool needs to be able to do the following:

- "start" command:

mytool start

The command starts the HTTP server and returns the terminal to the end user. The HTTP server should keep running.

- "fetch" command:

mytool fetch

The command makes a request to the running HTTP server and prints the result. The HTTP server runs a longlive goroutine on each request (another reason to keep the HTTP server up and running).

- "stop" command:

mytool stop

The command shuts down the HTTP server.

Problem:

Here lies the key problem: how to keep the HTTP server running between the commands and, at the same time, return the terminal to the end user (so they can use it for their own purposes).

It seems to me that any tricks with goroutines won't work, as they will be destroyed alongside the Go program.

What I did:

- created another module (let's call it "server") that has its own "main.go" and it keeps the HTTP-server logic. The structure looks like this:

server
------main.go
main.go

- started the HTTP server via OS-command when the user does "mytool start":

dir, err := os.Getwd()

if err != nil { return errors.New("unable to get the current filename") } command := exec.Command("go", "run", "main.go") command.Dir = dir + string(os.PathSeparator) + "server" if err := command.Start(); err != nil { return err } return nil

It makes sure that the HTTP server is up and running between the commands.

However, this approach suffers from the "it works on my machine" sickness + as soon as I build my tool as a binary (in order to distribute it), the piece of code provided above stops working, as the binary knows nothing about the codebase directories, but rather uses the directories of the machine it is running on.

My second idea was to embed the HTTP server binary somehow into the binary of my project, and then run it as `exec.Command("httpServerBinary")`, but that doesn't seem to be possible.

However, I found a possible workaround with the "go-bindata" tool:

- generate a Go file that keeps the binary- restore the binary when the end user runs `mytool start` command- start HTTP server from the restored binary

While this approach seems like a doable one, it has problems with the multi-OS support, as then I should ship binaries for all the supported OS and architectures there, which will make the size of the "mytool" binary quite significant.

Question:

Basically, the question is whether there is a simpler way to achieve the desired results. Maybe I'm overcomplicating things while missing something easier.

Thanks and have fun =)