0

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.

4
  • 4
    Account is in the api package, so you reference it as api.Account Commented Jun 29, 2015 at 20:55
  • Wow... definitely overthought everything and missed that... That was it. Thanks! Commented Jun 29, 2015 at 20:56
  • api is a bad name for a package, especially since you explicitly mention other users using your package. Commented Jun 30, 2015 at 15:33
  • Yeah, it needs to change. This isn't really fleshed out, just wanted to make sure I had my structure right. Commented Jun 30, 2015 at 16:36

1 Answer 1

3

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).

Sign up to request clarification or add additional context in comments.

2 Comments

So just to clarify, anything in the 'main' package and a 'main' func will be added as an executable in the bin dir?
Correct - it will get added to $GOPATH/bin when you use go get to fetch the package.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.