Problem
Even though Go is beautifully straightforward and blatantly obvious as to what is going on, there is still room for coding style differences.And what happens when you're working in a multi-developer project not every developer uses the same coding styles?
Examples
- Use TAB character rather than spaces
- Use 2 spaces per TAB (v. 3 or 4 spaces)
- Open brace on new line (v. at end of line)
- etc...
Enough of that nonsense... Just use the following pre-commit script to force each developer to run the standard gofmt against each source file before they git committed to git.
misc/git/pre-commit script
Simply create a file named pre-commit in your project'spre-commit
#!/bin/sh
# Copyright 2012 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
# git gofmt pre-commit hook
#
# To use, store as .git/hooks/pre-commit inside your repository and make sure
# it has execute permissions.
#
# This script does not handle file names that contain spaces.
gofiles=$(git diff --cached --name-only --diff-filter=ACM | grep '.go$')
[ -z "$gofiles" ] && exit 0
unformatted=$(gofmt -l $gofiles)
[ -z "$unformatted" ] && exit 0
# Some files are not gofmt'd. Print message and fail.
echo >&2 "Go files must be formatted with gofmt. Please run:"
for fn in $unformatted; do
echo >&2 " gofmt -w $PWD/$fn"
done
exit 1
Make it executable
$ chmod +x .git/hooks/pre-commit
See the pre-commit hook work
Add and extra TAB.
$ git diff
diff --git a/errors.go b/errors.go
index fc62d4c..dc3addf 100644
--- a/errors.go
+++ b/errors.go
@@ -15,8 +15,8 @@
defaultErrMsg := "Oops! We had an issue with your request."
- for _, errMsg := range optionalDefaultErrMsg {
- defaultErrMsg = errMsg
+ if len(optionalDefaultErrMsg) > 0 {
+ defaultErrMsg = errMsg
}
$ git add-commit 'Add extra TAB to break formatting'
Go files must be formatted with gofmt. Please run:
gofmt -w /<PROJECT_DIRECTORY_HERE>/errors.go
See the pre-commit hook work
Run gofmt -w /<PROJECT_DIRECTORY_HERE>/errors.go and try again.This time, your commit should work and your properly formatted file will be saved to your local git repo.
Notes
Since the file pre-commit file is in your .git/hooks directory, by default it will not get checked into your repo.So, it's safe to use. No worries about an extra commit because you created the new pre-commit file.
Others on your team could rely only on their IDE to provide gofmt functionality (and choose not use this pre-commit hook).
But you can rest assured that all of your code will always be properly formatted before any push into the team git repo.
Configure gofmt Globally
Since git 2.9+ (2016-06-13), we can place our pre-commit file in a global git/hooks directory to configure all of our git repos to execute it.
$ git config --global core.hooksPath /path/to/global/git/hooks
Example
If you put your pre-commit script in $HOME/dev/global/.git/hooks/pre-commit then you can run the following command to configure git to run gofmt on the Go files that you want to commit to git:
$ git config --global core.hooksPath ~/dev/global/.git/hooks
Log for Configure gofmt Globally
Notes:
- main.go has some formatting issues on the func main() line
- We can build our Go app locally (with the formatting issues)
- We are unable to commit our poorly formatted Go code to our local repository due to our core.hooksPath git configuration
- After running gofmt -w
we are able to commit our file and push it to the remote repo - The pre-commit script looks for Go files in your index, i.e., your local git staging area, and will only run if you are attempting to commit one or more .go files
- See https://github.com/l3x/gofmt-demo.git
$ cat main.go
package main
import "fmt"
func main() {
fmt.Println("formatting errors above")
}
$ gs
On branch master
Your branch is up-to-date with 'origin/master'.
Untracked files:
(use "git add ..." to include in what will be committed)
main.go
nothing added to commit but untracked files present (use "git add" to track)
$ git add .
$ go build
$ ll
total 4128
drwxr-xr-x 6 lex staff 192 Mar 21 11:36 ./
drwxr-xr-x 3 lex staff 96 Mar 21 11:34 ../
drwxr-xr-x 13 lex staff 416 Mar 21 11:36 .git/
-rw-r--r-- 1 lex staff 0 Mar 21 11:34 README.md
-rwxr-xr-x 1 lex staff 2106512 Mar 21 11:36 gofmt-demo*
-rw-r--r-- 1 lex staff 86 Mar 21 11:36 main.go
$ ./gofmt-demo
formatting errors above
$ cat main.go
package main
import "fmt"
func main() {
fmt.Println("formatting errors above")
}
$ git commit -m 'demo use of global git precommit hook'
Go files must be formatted with gofmt. Please run:
gofmt -w /Users/lex/tmp/20180321-113307/gofmt-demo/main.go
$ gofmt -w /Users/lex/tmp/20180321-113307/gofmt-demo/main.go
$ gs
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD ..." to unstage)
new file: main.go
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git checkout -- ..." to discard changes in working directory)
modified: main.go
Untracked files:
(use "git add ..." to include in what will be committed)
gofmt-demo
$ git add .
$ go build
$ ./gofmt-demo
formatting errors above
$ git commit -m 'demo use of global git precommit hook'
[master f024a20] demo use of global git precommit hook
2 files changed, 7 insertions(+)
create mode 100755 gofmt-demo
create mode 100644 main.go
$ git push
Counting objects: 4, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 737.15 KiB | 6.41 MiB/s, done.
Total 4 (delta 0), reused 0 (delta 0)
To github.com:l3x/gofmt-demo.git
6cff8f6..f024a20 master -> master
$ cat main.go
package main
import "fmt"
func main() {
fmt.Println("formatting errors above")
}
References
http://blog.golang.org/go-fmt-your-codehttps://golang.org/doc/effective_go.html
This work is licensed under the Creative Commons Attribution 3.0 Unported License.
It is really a great idea for developers team. I used similar way when I worked on my project because my teammate did not work in Git. I also read about information about mobile app development company which uses a variety of schemes of work in development styles - http://www.intellectsoft.co.uk/
ReplyDeleteI am looking for some commercial refrigeration repairs sydney. I had to need repaired my refrigerator. Then I had found dave refrigerator. They had give me a good response.
ReplyDeleteI was looking for the NYC app design. I was looking for some company to create my Application. I had a meetup with APP DEVELOPMENT PROS. They provide me a better response from others which I had contacted. At the given time they delivered my project to me And I must prefer them to everyone who wants IT Service.
ReplyDeleteI had worked with a Software House in UK. I want an E-commerce website for my business. I had contacted them to create my website and now I can say I'm fully satisfied with their work.
ReplyDelete