alex-phillips
alex-phillips

Reputation: 868

Building CLI app/package in Go

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

Answers (1)

elithrar
elithrar

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

Related Questions