Reputation: 868
I may be going about this incorrectly (I've read How to Write Go Code), but here's what I'm trying to achieve: I want to write a golang package that also come with a CLI, so that a user can use the package in their own programs but also use the CLI that I've built with it.
So what I have so far is this structure:
mypackage/
-api/
-account.go // package api
-node.go // package api
-main.go // package main - this is where I want
// the executable code to be that is put in the `bin` folder.
This is a very crude file structure as I'm just starting out the project, but that's what I'm trying to achieve rather than build a package with the usable code in it and then build a separate repo with my CLI in it. But when I attempt to run main.go
, it says undefined: Account
(which is a struct in account.go
).
The contents of my code is unimportant right now, it's very basic as I'm just trying to get the code to work. Here's what I have.
account.go
package api
import (
"io/ioutil"
"net/http"
)
type Account struct {
email string
}
main.go
package main
import (
"github.com/username/mypackage/api"
"fmt"
)
func main() {
a := Account{}
fmt.Printf("%T", a)
}
If this is completely bad practice, I suppose I'll just make 2 repos, one with the CLI and another with my actual package code (again, usable in development by others by importing), but I'd really like it to be an all-in-one repo.
Upvotes: 0
Views: 416
Reputation: 24260
There's no "one way", but the common approach is to make your top-level repo your library - i.e. github.com/you/somelib
and then have a cmd
directory underneath that contains your CLI (package mains) - there may even be many.
e.g.
yourlib/
api.go
api_test.go
handler.go
handler_test.go
cmd/
command-name/
main.go // Builds a "command-name" binary
other-command/
main.go // Builds a "other-command" binary
Your CLI apps are just consumers of your library. Users can retrieve it via go get github.com/you/yourlib/...
which will install the lib and the binaries onto their GOPATH.
The Go source itself, Camlistore and BoltDB all use this approach (amongst many other libs).
Upvotes: 3