Tools, Tips and Good Practices

22.12.2015

Но преди това

Въпроси за "мъфини"

Как се извиква C код в Go програми?

Как се прави адресна аритметика в Go?

Как може да се debug-ва и променя работата на RUNTIME-а

И по същество...

The Go Toolkit

Вече сме говорили за някои от вградените инструменти:

Test coverage

go test -cover
go test -coverprofile <filename>
go tool cover -html <coverage_file> -o <html_result>

Примерен HTML output

Race condition detection

$ go test -race mypkg    // test the package
$ go run -race mysrc.go  // compile and run the program
$ go build -race mycmd   // build the command
$ go install -race mypkg // install the package

goimports

go get -u golang.org/x/tools/cmd/goimports
goimports -w .

go fix

Спомняте ли си как ви казахме че след версия 1.0 авторите са обещали, че каквото работи на 1.x ще работи на 1.y, където x < y ?

Е да ама ... понякога се налага да се променят основни API-та.

Ако след ъпдейт на go не ви се компилира проекта, можете просто да рънете:

go fix .

Все пак понякога се правят по специални промени, за които това няма да помогне.

go vet

Статичен анализатор на go код, който може и да ви спести доста главоболия. Проверява за често срещани грешки във вашия код и се оплаква, ако ги намери.

Някои поддържани проверки:

golint

"Официален" linter за Go от Google. Показва стилистични грешки.

go get -u github.com/golang/lint/golint

И го викаме с : (drum rolls)

golint .

или

golint ./...

Други linter-и

gometalinter обединява и унифицира много различни вградени и външни инструменти за анализ на кода

go get -u github.com/alecthomas/gometalinter
gometalinter --install --update

Включва:

...

Прекалено тежко е да се се пуска на всеки filesave, за разлика от gofmt, goimports или golint.

Безценен е обаче като метрика и част от CI процес.

gorename

Позволява прецизно type-safe преименуване на неща в кода

go get -u golang.org/x/tools/cmd/gorename

С даден файл

gorename -from filename.go::NameOfSomething -to NewNameOfSomething

само разпознава какво е Something и го преименува в правилните файлове.

Или

gorename -from '"site.com/package/path".structName[.MethodName]' -to NewNameOfSomething

Преименува дадения идентификатор по даден пакет и идентификатор.

Навярно няма да го ползвате ръчно.

Oracle

go get -u golang.org/x/tools/cmd/oracle

Вие питате, а той ви отговаря на въпроси относно кода ви.

Не се ползва ръчно - или поне не лесно.

golang.org/s/oracle-user-manual

pprof

В Go има вграден profiler, който се използва така:

import _ "net/http/pprof"

И ако нямате HTTP сървър в програмата, трябва да дoбавите поне:

go func() {
    http.ListenAndServe("localhost:6060", nil)
}()

След това може да отидете на адреса и да разглеждате информация за heap-а, CPU usage, execution traces, горутини и др.

Може да се използва и вградения command-line tool:

go tool pprof http://localhost:6060/debug/pprof/heap

Повече информация има тук и тук

build tags (restrictions)

В go има едно нещо наречено build tag-ове или build restrictions

Представлят подобен коментар някъде в началото на файла (още преди package):

// +build tagname

Сигнализират на компилатора при какви обстоятелства да компилира или да не компилира даден файл

// +build linux
// +build !386

казва само под linux, но не под 386

Може да подаваме наши тагове с:

go build -tag tagname

go generate

Mожете да укажeте, че искате дадена друга команда да бъде изпълнена върху кода. Use cases:

Казвате какво и как искате да се пусне, като в началото на някой .go файл слагате:

//go:generate command args...

И след това извиквате

go generate ./...

Интеграция с редактори

Повечето tool-ве описане до тук са писани с идеята, че ще бъдат интегрирани или поне с възможността да бъдат интегрирани в един или друг текстов редактор и цялостно IDE.

Общото между двата и причината да не ви показваме как се ползват ръчно е, че и двата работят с byte offset, а не с номера на редове.

Command-line аргументи

import "flag"

var stringVar string

func init() {
    flag.StringVar(&stringVar,  "paramName", "help message")
}

func main() {
    flag.Parse()
    // do something with stringVar
}

Външни услуги

Има много външни услуги (често безплатни), които позволяват лесно и автоматизирано build-ване, тестване, показване на code coverage и др.

Примери:

Въпроси?