golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
121.02k stars 17.36k forks source link

doc: filename conventions #36060

Open carnott-snap opened 4 years ago

carnott-snap commented 4 years ago

If I have simply missed where this is documented, please let me know where I should have looked, and close this out.

Many places describe how custom filename suffixes interact with the toolchain: _test, _linux, _arm. However I cannot find anywhere that says you should use snake case for multi-word file names, as is suggested by the standard library: e.g. time/zoneinfo_read.go/os/removeall_at.go not time/zoneinfoRead.go/os/removeallAt.go or time/zoneinfo-read.go/os/removeall-at.go.

This may seem self evident to experienced users, but I have seen many people get confused by the fact that variables use CamelCase := "", while files use snake_case.go.

toothrot commented 4 years ago

I am not certain where this convention is documented, but I feel like @ianlancetaylor or @bradfitz might have some guidance.

dmitshur commented 4 years ago

To my knowledge, there isn't a documented convention for .go file names (other than meaningful things like test.go, leading . or , trailing _goos_goarch, etc.) anywhere. I've checked https://golang.org/doc/effective_go.html and https://golang.org/s/style.

The Go project itself tends to prefer short names like io.go, pipe.go, etc. In the rare cases two words are needed, they are joined without an underscore, like cputicks.go or debugcall.go. For more complicated packages with many files, underscores are sometimes used when additional separation is needed.

carnott-snap commented 4 years ago

That is useful to note. It led me down a bit of a rabbit hole, and it looks like even the standard library is not consistent (though lowercasealloneword seems to be in the plurality). Should we make a standard?

file.extension.go

out:
- cmd/internal/obj/arm/a.out.go
- cmd/internal/obj/arm64/a.out.go
- cmd/internal/obj/mips/a.out.go
- cmd/internal/obj/ppc64/a.out.go
- cmd/internal/obj/s390x/a.out.go
- cmd/internal/obj/wasm/a.out.go
- cmd/internal/obj/x86/a.out.go

snake_case.go

marshaling:
- encoding/json/example_marshaling_test.go
- encoding/json/example_text_marshaling_test.go
- encoding/xml/example_marshaling_test.go
- encoding/xml/example_text_marshaling_test.go
mmap:
- cmd/compile/internal/gc/mapfile_mmap.go
- cmd/internal/bio/buf_mmap.go
- cmd/link/internal/ld/outbuf_mmap.go
- runtime/cgo_mmap.go
- runtime/export_mmap_test.go
- runtime/runtime_mmap_test.go
string:
- cmd/compile/internal/gc/class_string.go
- cmd/compile/internal/gc/op_string.go
- cmd/compile/internal/syntax/operator_string.go
- cmd/compile/internal/syntax/token_string.go
- cmd/compile/internal/types/etype_string.go
- cmd/internal/obj/abi_string.go
- cmd/internal/obj/addrtype_string.go
- cmd/internal/objabi/reloctype_string.go
- cmd/internal/objabi/symkind_string.go
- cmd/link/internal/sym/symkind_string.go
- debug/dwarf/attr_string.go
- debug/dwarf/class_string.go
- debug/dwarf/tag_string.go
- debug/macho/reloctype_string.go
- html/template/attr_string.go
- html/template/delim_string.go
- html/template/element_string.go
- html/template/jsctx_string.go
- html/template/state_string.go
- html/template/urlpart_string.go
- math/big/accuracy_string.go
- math/big/roundingmode_string.go
- regexp/syntax/op_string.go
sysnum:
- internal/syscall/unix/at_sysnum_darwin.go
- internal/syscall/unix/at_sysnum_dragonfly.go
- internal/syscall/unix/at_sysnum_fstatat64_linux.go
- internal/syscall/unix/at_sysnum_fstatat_linux.go
- internal/syscall/unix/at_sysnum_linux.go
- internal/syscall/unix/at_sysnum_netbsd.go
- internal/syscall/unix/at_sysnum_newfstatat_linux.go
- internal/syscall/unix/at_sysnum_openbsd.go

lowercase.go

gccgoinstallation:
- go/internal/gccgoimporter/gccgoinstallation_test.go
loopreschedchecks:
- cmd/compile/internal/ssa/loopreschedchecks.go
mkfastlog2table:
- runtime/mkfastlog2table.go
mksizeclasses:
- runtime/mksizeclasses.go
obscuretestdata:
- internal/obscuretestdata/obscuretestdata.go
reproduciblebuilds:
- cmd/compile/internal/gc/reproduciblebuilds_test.go

CamelCase.go

386Ops:
- cmd/compile/internal/ssa/gen/386Ops.go
"387":
- cmd/compile/internal/x86/387.go
AMD64Ops:
- cmd/compile/internal/ssa/gen/AMD64Ops.go
ARM64Ops:
- cmd/compile/internal/ssa/gen/ARM64Ops.go
ARMOps:
- cmd/compile/internal/ssa/gen/ARMOps.go
MIPS64Ops:
- cmd/compile/internal/ssa/gen/MIPS64Ops.go
MIPSOps:
- cmd/compile/internal/ssa/gen/MIPSOps.go
PPC64Ops:
- cmd/compile/internal/ssa/gen/PPC64Ops.go
S390XOps:
- cmd/compile/internal/ssa/gen/S390XOps.go
WasmOps:
- cmd/compile/internal/ssa/gen/WasmOps.go
arithBoundary:
- cmd/compile/internal/gc/testdata/arithBoundary_test.go
arithBoundaryGen:
- cmd/compile/internal/gc/testdata/gen/arithBoundaryGen.go
arithConst:
- cmd/compile/internal/gc/testdata/arithConst_test.go
arithConstGen:
- cmd/compile/internal/gc/testdata/gen/arithConstGen.go
deferNoReturn:
- cmd/compile/internal/gc/testdata/deferNoReturn_test.go
ianlancetaylor commented 4 years ago

Although the compiler made a different choice, for the standard library we've historically preferred all lowercase just to avoid confusion on case-insensitive systems. I don't know that this is written down anywhere. I don't know that we have any particular guidance for file names in packages outside the standard library.

dmitshur commented 4 years ago

I don't know that we have any particular guidance for file names in packages outside the standard library.

To make progress on this issue, we need to decide if we should change that and attempt to offer guidance by adding an entry to https://golang.org/doc/effective_go.html or https://golang.org/s/style, or if we should not.

At this time, I'm inclined to believe we should not.

People who care about this can look at the .go file naming strategies used by the Go standard library and mimic it. Those who don't care can choose a naming strategy that they prefer.

There are additional resources where people write down their opinions on Go style, such as those listed at https://medium.com/@dgryski/idiomatic-go-resources-966535376dba. Perhaps an entry in one of those lists would be more viable.

carnott-snap commented 4 years ago

I opened this issue because I have colleagues that asked, what filename conventions should I use with go?

I can understand that trying to stabilise this now may be problematic, noisy, or too late. But the lack of consensus will cause some amount of confusion and cognitive overhead. Because the community (seems to) understand the benefits of standardisation, see gofmt, even a soft recommendation in a blog post would go a long way.

peterbourgon commented 4 years ago

There is a de facto standard for Go source file names: all lowercase with underscore separation when necessary, i.e. snake case. (The exceptions are exceptions.) I'd appreciate having it as a documented standard, too, to answer questions like @carnott-snap notes, especially among junior Gophers. In my opinion it needn't be so formal as entering Effective Go, a short new section on CodeReviewComments is more than sufficient.

File names

Go source file names should be lowercase_with_underscores.go and not camelCase.go or TitleCase.go. This makes them consistent with other language conventions, like _test.go for test files, or _windows.go for build constraints. It also prevents ambiguities on case-insensitive file systems.

tv42 commented 2 years ago

Related, documenting what's allowed as opposed to recommended might be useful too.

https://github.com/golang/go/blob/d09e09bc615a50e9f2f1144991ebeba08a7c6f05/src/cmd/go/internal/load/pkg.go#L1883-L1895

https://github.com/golang/go/blob/d09e09bc615a50e9f2f1144991ebeba08a7c6f05/src/cmd/go/internal/load/pkg.go#L2196-L2211

matteoolivi commented 2 years ago

Any progress/plan to document this somewhere?

urandom2 commented 2 years ago

@peterbourgon, can we just add your text to the wiki? I did not see strong consensus, but this is an easy one and we should probably just fix it.

dfang commented 2 years ago

I agree with all lowercase with underscore separation when necessary, apparently greet_controller.go or greet_handler.go is more readable than greetcontroller.go and greet_handler.go.

you can gh repo clone golang/go or gh repo clone kubernetes/kubernetes source code to your local and run find . -iname "*_*.go" | egrep -v 'test|arm|darwin|openbsd|unix|windows|plan9', most file names are lowercase with underscore separation style.

this is the convention, just undocumented yet.

tv42 commented 2 years ago

The downside of blah_thing.go is that thing might get added as a new recognized architecture or operating system. It's just an unpleasant namespacing clash.

Imagine writing a game with npc_human.go, npc_monster.go, npc_android.go, and then Android gets released.

Imagine having embed_svg.go, embed_html.go, and embed_js.go, and then the platform js/wasm gets added.

Neither blahthing.go nor blahThing.go are vulnerable to that. Generally all lowercase is less likely to get damaged by OS X users. I'm almost tempted to use - where needed just to avoid that build tag collision.

bahag-salarzehis commented 1 year ago

no standards defined yet?

SpicyLemon commented 10 months ago

In addition to a recommended naming convention, I'd also like to see a list of all specially handled filenames and directories. E.g. *_test.go only compiled with go test, and nothing in internal directories exported outside the module. I'm not sure what else there might be. Is testutil special? I'm sure there's others that are special too.

takanuva15 commented 6 months ago

@peterbourgon, can we just add your text to the wiki? I did not see strong consensus, but this is an easy one and we should probably just fix it.

Peter's comment has more likes than the original issue lol. I was looking for the same thing on Golang file naming conventions and was surprised to see that effective go doesn't discuss it even though it touches on naming for pretty much everything else.

@tv42 makes a valid point, so we could add it as a disclaimer under Peter's text so we at least have something listed in Effective Go for this (as opposed to telling people to read other sites for a convention 🙃 ).

@urandom2 Since you've already merged a PR here before, how easy is it to just raise a PR in the effective go docs and add this section? Do you already know which file to update to add a new subsection to the docs?

gophun commented 6 months ago

how easy is it to just raise a PR in the effective go docs and add this section?

A better place would be https://go.dev/doc/modules/layout, since Effective Go is frozen, as mentioned at the end of its 'Introduction' section.

style95 commented 3 months ago

So is snake case the standard according to @peterbourgon's comments?

tempcke commented 1 week ago

I rather like @tv42 's comment contemplating the use of -

This way there is no potential conflict with the special handling of some _suffix 's

The only downside is that it isn't ever used in the standard library filenames near as I can tell. So it feels like breaking convention. Is there any good reason aside from that though to not use - 's?