Loading...
Loading...
Go package organization, imports, and dependency management from Google and Uber style guides. Use when creating packages, organizing imports, managing dependencies, using init(), or deciding how to structure Go code into packages.
npx skill4agent add cxuu/golang-skills go-packagesAdvisory: This is a best practice recommendation.
utilhelpercommon// Good: Meaningful package names
db := spannertest.NewDatabaseFromFile(...)
_, err := f.Seek(0, io.SeekStart)
// Bad: Vague package names obscure meaning
db := test.NewDatabaseFromFile(...)
_, err := f.Seek(0, common.SeekStart)utilstringutilAdvisory: This is best practice guidance.
bytes.Bufferring.NewNormative: This is required per Go Wiki CodeReviewComments.
package main
import (
"fmt"
"hash/adler32"
"os"
"github.com/foo/bar"
"rsc.io/goversion/version"
)Combined: Google + Uber guidance
// Good: Standard library separate from external packages
import (
"fmt"
"os"
"go.uber.org/atomic"
"golang.org/x/sync/errgroup"
)// Good: Full grouping with protos and side-effects
import (
"fmt"
"os"
"github.com/dsnet/compress/flate"
"golang.org/x/text/encoding"
foopb "myproj/foo/proto/proto"
_ "myproj/rpc/protocols/dial"
)Normative: This is required per Go Wiki CodeReviewComments and Google's Go style guide.
pbv1// Good: Proto packages renamed with pb suffix
import (
foosvcpb "path/to/package/foo_service_go_proto"
)
// Good: urlpkg when url variable is needed
import (
urlpkg "net/url"
)
func parseEndpoint(url string) (*urlpkg.URL, error) {
return urlpkg.Parse(url)
}import _Normative: This is required per Go Wiki CodeReviewComments and Google's Go style guide.
import _ "pkg"// Good: Blank import in main package
package main
import (
_ "time/tzdata"
_ "image/jpeg"
)import .Normative: This is required per Go Wiki CodeReviewComments and Google's Go style guide.
Quuximport .package foo_test
import (
"bar/testutil" // also imports "foo"
. "foo"
)foobar/testutilfooimport .fooimport .// Bad: Dot import hides origin
import . "foo"
var myThing = Bar() // Where does Bar come from?
// Good: Explicit qualification
import "foo"
var myThing = foo.Bar()Source: Uber Go Style Guide
init()init()init()// Bad: init() with I/O and environment dependencies
var _config Config
func init() {
cwd, _ := os.Getwd()
raw, _ := os.ReadFile(path.Join(cwd, "config.yaml"))
yaml.Unmarshal(raw, &_config)
}// Good: Explicit function for loading config
func loadConfig() (Config, error) {
cwd, err := os.Getwd()
if err != nil {
return Config{}, err
}
raw, err := os.ReadFile(path.Join(cwd, "config.yaml"))
if err != nil {
return Config{}, err
}
var config Config
if err := yaml.Unmarshal(raw, &config); err != nil {
return Config{}, err
}
return config, nil
}database/sqlSource: Uber Go Style Guide
os.Exitlog.Fatal*main()defer// Bad: log.Fatal in helper function
func readFile(path string) string {
f, err := os.Open(path)
if err != nil {
log.Fatal(err) // Exits program, skips defers
}
b, err := io.ReadAll(f)
if err != nil {
log.Fatal(err)
}
return string(b)
}// Good: Return errors, let main() decide to exit
func main() {
body, err := readFile(path)
if err != nil {
log.Fatal(err)
}
fmt.Println(body)
}
func readFile(path string) (string, error) {
f, err := os.Open(path)
if err != nil {
return "", err
}
b, err := io.ReadAll(f)
if err != nil {
return "", err
}
return string(b), nil
}os.Exitlog.Fatalmain()// Good: Single exit point with run() pattern
func main() {
if err := run(); err != nil {
log.Fatal(err)
}
}
func run() error {
args := os.Args[1:]
if len(args) != 1 {
return errors.New("missing file")
}
f, err := os.Open(args[0])
if err != nil {
return err
}
defer f.Close() // Will always run
b, err := io.ReadAll(f)
if err != nil {
return err
}
// Process b...
return nil
}run()main()defer| Topic | Rule | Type |
|---|---|---|
| Import organization | std first, groups separated by blank lines | Normative |
| Import grouping | std → other (→ proto → side-effect) | Combined |
| Import renaming | Only when necessary; prefer renaming local/project import | Normative |
| Blank imports | Only in main packages or tests | Normative |
| Dot imports | Only for circular test dependencies | Normative |
| Util packages | Avoid; use descriptive names | Advisory |
| Package size | Balance cohesion vs. distinct concepts | Advisory |
| init() | Avoid; must be deterministic if used | Advisory |
| Exit in main | Only exit from main(); return errors | Advisory |
go-style-corego-naminggo-error-handlinggo-defensivego-linting