Go toolchain / Habr

Go toolchain / Habr

Hello colleagues! In Go toolchain is not just a buzzword, but a real working feature. If you’ve spent a lot of time delving into the code and modules, you know that every line and every package, like in any app, has a place and a meaning.

Tool chain

A toolchain or toolchain (toolchain sounds cooler) is used to build, test, debug, and manage your Go projects:

1. Compilation and assembly (Build)

go build – This is the team that stands at the center of your Go project. It takes your source code and turns it into an executable ready to run on your server, your container, or even your Raspberry Pi if you’re the developer type.

go build uses powerful compiler optimizations to make your code run fast and efficiently.

No need for complex build scripts or configurations. Execute go buildAnd everything is ready.

A simple compilation might look like this:

You have a simple file main.go:

package main

import "fmt"

func main() {
    fmt.Println("Hello, Habr!")
}

Execute go build, and Go will create an executable in the current directory. On Linux or macOS it will be a file without an extension, on Windows .exe file Simple, fast, and most importantly, effective.

Want to give your executable a special name? No problem! Use it -o flag.

go build -o myotusapp

Your file will now be called myotusapp (or myotusapp.exe on Windows).

One of the coolest features of Go is cross-compilation. You can build a program on Linux for Windows, on macOS for ARM, and so on:

GOOS=windows GOARCH=amd64 go build -o myapp.exe

This command will create a Windows executable even if you are on Linux or macOS.

2. Addiction management

Before go mod appeared in Go, go get was the main way of managing addictions. It allows you to download and install packages from various repositories.

Let’s say you want to use a package for HTTP requests – gorilla/mux. Here’s how we do it:

go get -u github.com/gorilla/mux

The team downloads the package mux and make it available to your project. Simple and effective, but without explicit version control.

With the introduction of Go Modules in version 1.11, we have a flexible dependency management tool that provides precise version control and simplifies work with large projects.

Before you can start working with dependencies, you need to initialize the module:

go mod init myawesomeproject

This will create a file go.modwhich will contain information about your project and its dependencies.

When you use an external package in your code, Go will automatically add it to yours go.mod. Example:

package main

import (
    "fmt"
    "github.com/gorilla/mux"
)

func main() {
    r := mux.NewRouter()
    // ...
    fmt.Println("Router created:", r)
}

After running your code or executing a command go buildGo will automatically update go.mod and will create go.sumcontains a list of dependencies with their hashes to ensure integrity.

Do you want to update all dependencies to the latest versions? Just do:

go get -u

Or upgrade your package.

go get -u github.com/gorilla/mux

3. Testing

go test – This is the command that runs the tests in your Go project. Tests are small but powerful programs that verify that your code is doing exactly what is expected of it. They help detect errors, simplify refactoring, and maintain a high level of code quality.

Tests allow you to refactor and update code without the fear of accidentally breaking something.

For example, there is a simple function that is two numbers:

package math

func Add(x, y int) int {
    return x + y
}

Let’s write a test for it:

package math

import "testing"

func TestAdd(t *testing.T) {
    result := Add(1, 2)
    if result != 3 {
        t.Errorf("Add(1, 2) = %d; want 3", result)
    }
}

We execute go test, and Go will automatically find and run this test. If everything is OK, you will see something like:

PASS
ok      yourpackage/math 0.002s

Sometimes it’s important to make sure your code handles exceptions correctly. Let’s say you have a function that should trigger a panic under certain conditions:

package panic

func DoPanic(flag bool) {
    if flag {
        panic("something went wrong")
    }
}

A panic test might look like this:

package panic

import "testing"

func TestDoPanic(t *testing.T) {
    defer func() {
        if r := recover(); r == nil {
            t.Errorf("The code did not panic")
        }
    }()
    DoPanic(true)
}

The test checks that DoPanic(true) really panicking.

4. Formatting and style

go fmt – Personal stylist in Go. It automatically formats your code following the standards and conventions of the Go language. This ensures code uniformity and readability.

Let’s say you have some code that looks a little messy:

package main
import "fmt"
func main() {fmt.Println("Hello, Habr!")}

Execute go fmt on the file and it will become:

package main

import "fmt"

func main() {
    fmt.Println("Hello, Habr!")
}

go fmt automatically added indents and line breaks, making the code more readable and beautiful.

go vet – This is a tool for detecting suspicious structures in code. It doesn’t replace tests, but it helps you find problems that might not be obvious at first glance, such as incorrect use of string formats, wrong argument types, and more.

Suppose you have the following code:

package main

import "fmt"

func main() {
    var name = "Habr"
    fmt.Printf("Hello, %d!", name)
}

Here you accidentally used %d (integer format) instead %s (Format for strings). Implementation go vet on this code will issue a warning:

# command-line-arguments
./main.go:6: Printf format %d has arg name of wrong type string

go vet helps detect such errors before they cause problems in the running application.

5. Documentation

godoc is a tool for automatically generating documentation from Go source code. It takes comments directly from your code and turns them into beautifully designed documentation, available as a web page or in the console.

For example, you have a function that sums two numbers:

package math

// Add returns the sum of x and y.
// It's a simple example to demonstrate how godoc works.
func Add(x, y int) int {
    return x + y
}

Comment on the function Add – that’s what godoc will use to create documentation. If you run godoc -http=:6060 and go to http://localhost:6060/pkg/you will see the documentation for your package and feature.

To document the entire package, simply add a comment at the beginning of the file:

// Package math provides basic mathematical functions.
package math

// Add returns the sum of x and y.
func Add(x, y int) int {
    return x + y
}

This comment will be used godoc to create a batch review.

Let’s expand the functionality with the help of other tools

Gin is a framework for building web applications and APIs. It provides routing, middleware, templating, and more:

package main

import "github.com/gin-gonic/gin"

func main() {
    r := gin.Default()
    r.GET("/", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "hello world",
        })
    })
    r.Run() // listen and serve on 0.0.0.0:8080
}

GORM is an ORM library for Go that simplifies working with databases by providing a convenient interface for queries, inserts, updates, and deletes.

package main

import (
  "github.com/jinzhu/gorm"
  _ "github.com/jinzhu/gorm/dialects/sqlite"
)

type Product struct {
  gorm.Model
  Code  string
  Price uint
}

func main() {
  db, err := gorm.Open("sqlite3", "test.db")
  if err != nil {
    panic("failed to connect database")
  }
  defer db.Close()

  // Migrate the schema
  db.AutoMigrate(&Product{})

  // Create
  db.Create(&Product{Code: "L1212", Price: 1000})

  // Read
  var product Product
  db.First(&product, 1) // find product with id 1
  db.First(&product, "code = ?", "L1212") // find product with code L1212

  // Update - update product's price to 2000
  db.Model(&product).Update("Price", 2000)

  // Delete - delete product
  db.Delete(&product)
}

Delve – This is a debugger specially designed for Go. It allows you to run programs step by step, view and change variables, and even use conditional breakpoints.

dlv debug myapp.go

Remember that each tool is only part of the big picture. True skill lies not only in knowing the tools, but also in understanding how and when to use them.

And remember, no matter how difficult it is, there is always a community that will help.

And you can always learn about current tools and features of their application in practice at OTUS online courses under the guidance of industry experts.

Keep coding, keep improvingand to new meetings in Habra.

and… Happy New Year! 🎄

Related posts