34

I am creating three applications which are very similar to each other but each will apply different logic. I am not sure how to best structure it to avoid repeating code.

All applications have the following in common: - read and parse config - setup SQL database connection - gather stats - read from STDIN

Each application will apply different logic to the data read from STDIN.

Would this be considered acceptable? Put all common code in main.go then build as "go build -o bin/app1 main.go app1.go" and so on - pulling in only the app specific logic for each binary to build?

main.go:

func main() {
    // db connection
    // stats worker
    // read from stdin

    proccessLine(line)
}

app1.go:

func processLine(line string) {
    // logic for app 1
}

app2.go:

func processLine(line string) {
    // logic for app 2
}

etc.

Harrison
  • 341
  • 1
  • 3
  • 3

2 Answers2

44

The following folder structure is used in many popular go projects such as helm,kubicorn etc.

goproject/
├── bin
├── cmd
├── pkg
└── Makefile

The cmd directory will contain the different binaries, separated in directories.

cmd/
├── bin1
│   └── main.go
├── bin2
│   └── main.go
└── bin3
    └── main.go

pkg directory will contain all your reusable packages. In your case the common code used by the different binaries. This directory can also be named internal , learn more about it here.

pkg
├── reusablepackage1
└── reusablepackage2

The bin directory is optional, It can be used to store the generated binaries. In case you are generating binaries to $GOBIN this can be omitted.

bin/
├── bin1
├── bin2
└── bin3

The Makefile can be used for writing helpful scripts, such as generating binaries running test suite etc. You can have commands such as make bin1,make bin2 etc.This is optional but I highly recommend this. because it saves me from writing long build commands over and over again.

scriptonist
  • 697
  • 4
  • 9
  • 3
    A project-local `bin` directory is a pretty unusual pattern, and calling the makefile "highly recommended" is purely your opinion. – Adrian Jun 18 '18 at 15:09
  • 2
    It's a pretty common convention esp. in larger projects. Best to instill good practices for any newbies that come along. – Kenny Worden Oct 11 '19 at 14:10
  • @scriptonist When using such a structure in Git or Svn and only release one of the binaries how do you handle tag names etc (do you delete the bin2 folder for the tag, if not doesn't this become confusing?) – refro Dec 06 '19 at 12:55
  • 5
    Where does the `go.mod` go? In the base directory, or does each `binX` have its own? – Jordan Mitchell Barrett May 13 '22 at 07:42
  • `go.mod` should be always in the base directory since it is related to `pkg` also not only `cmd`s – Tarek Mar 14 '23 at 15:44
24

Usual directory structure for such projects look like that:

cmd/
    a/
        main.go
    b/
        main.go

To build executables run

go build ./cmd/a
go build ./cmd/b

Examples

Grzegorz Żur
  • 47,257
  • 14
  • 109
  • 105