Go Tools

05.12.2018

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

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

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

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

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

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

Tools

The go tool

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 код, който може и да ви спести доста главоболия. Проверява за често срещани грешки във вашия код и се оплаква, ако ги намери.

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

go doc

$ go doc github.com/ironsmile/httpms/src/webserver.BasicAuthHandler
type BasicAuthHandler struct {
    // Has unexported fields.
}
    BasicAuthHandler is a handler wrapper used for basic authenticate. Its only
    job is to do the authentication and then pass the work to the Handler it
    wraps around


func (hl BasicAuthHandler) ServeHTTP(writer http.ResponseWriter, req *http.Request)

godoc

$ godoc github.com/ironsmile/httpms/src/webserver BasicAuthHandler
use 'godoc cmd/github.com/ironsmile/httpms/src/webserver' for documentation on the github.com/ironsmile/httpms/src/webserver command

type BasicAuthHandler struct {
    // contains filtered or unexported fields
}
    BasicAuthHandler is a handler wrapper used for basic authenticate. Its
    only job is to do the authentication and then pass the work to the
    Handler it wraps around

func (hl BasicAuthHandler) ServeHTTP(writer http.ResponseWriter, req *http.Request)
    ServeHTTP implements the http.Handler interface and does the actual
    basic authenticate check for every request

godoc

godoc -http=:6060

Demo

golint

"Официален" linter за Go от 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 процес.

Online tools

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

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

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

Guru

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

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

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

golang.org/s/using-guru

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

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

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

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 ./...

go generate мъдрост

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

import "flag"

var stringVar string

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

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

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

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

Въпроси?