Toolchain в Go
- пятница, 22 декабря 2023 г. в 00:00:23
 

Привет, коллеги! В Го toolchain это не просто buzzword, а реальная рабочая фича. Если вы провели немало времени, погружаясь в дебри кода и модулей, вы знаете, что каждая строчка и каждый пакет как и в любом япе имеют свое место и значение.
Набор инструментов или toolchain (тулчейн звучит покруче) используются для создания, тестирования, отладки и управления вашими Go-проектами:
go build — это команда, которая стоит в центре вашего Go-проекта. Она берет ваш исходный код и превращает его в исполняемый файл, готовый к запуску на вашем сервере, в вашем контейнере, или даже на вашем Raspberry Pi, если вы в тот типаж разработчиков....кхм
go build использует мощные оптимизации компилятора, чтобы ваш код выполнялся быстро и эффективно.
Нет нужды в сложных сценариях сборки или конфигурациях. Выполните go build, и всё готово.
Простая компиляция к примеру может выглядеть так:
У вас есть простой файл main.go:
package main
import "fmt"
func main() {
    fmt.Println("Hello, Habr!")
}Выполните go build, и Go создаст исполняемый файл в текущем каталоге. На Linux или macOS это будет файл без расширения, на Windows — .exe файл. Просто, быстро, а самое главно - эффективно.
Хотите назвать ваш исполняемый файл по-особенному? Нет проблем! Используйте -o флаг.
go build -o myotusappТеперь ваш исполняемый файл будет называться myotusapp (или myotusapp.exe на Windows).
Одна из крутейших фич Go — это возможность кросс-компиляции. Вы можете собрать программу на Linux для Windows, на macOS для ARM, и так далее:
GOOS=windows GOARCH=amd64 go build -o myapp.exeЭта команда создаст исполняемый файл для Windows, даже если вы находитесь на Linux или macOS.
Перед тем как go mod появился в Го, go get был основным способом управления зависимостями. Он позволяет вам скачивать и устанавливать пакеты из различных репозиториев.
Допустим, вы хотите использовать пакет для HTTP запросов - gorilla/mux. Вот как мы это сделаем:
go get -u github.com/gorilla/muxКоманда скачает пакет mux и сделает его доступным для вашего проекта. Просто и эффективно, но без явного контроля версий.
С появлением Go Modules в версии 1.11 у нас есть гибкий инструмент для управления зависимостями, который обеспечивает точный контроль версий и упрощает работу с большими проектами.
Перед тем как начать работать с зависимостями, вам нужно инициализировать модуль:
go mod init myawesomeprojectЭто создаст файл go.mod, который будет содержать информацию о вашем проекте и его зависимостях.
Когда вы используете внешний пакет в вашем коде, Go автоматически добавит его в ваш go.mod. Например:
package main
import (
    "fmt"
    "github.com/gorilla/mux"
)
func main() {
    r := mux.NewRouter()
    // ...
    fmt.Println("Router created:", r)
}После запуска вашего кода или выполнения команды go build, Go автоматически обновит go.mod и создаст go.sum, содержащий список зависимостей с их хешами для обеспечения целостности.
Хотите обновить все зависимости до последних версий? Просто выполните:
go get -uИли обновите конкретный пакет:
go get -u github.com/gorilla/muxgo test — это команда, которая запускает тесты в вашем Go-проекте. Тесты — это маленькие, но мощные программы, которые проверяют, что ваш код делает именно то, что от него ожидается. Они помогают обнаружить ошибки, упрощают рефакторинг и поддерживают высокий уровень качества кода.
Тесты позволяют вам рефакторить и обновлять код, не боясь случайно что-то сломать.
К примеру есть простая функция, которая складывает два числа:
package math
func Add(x, y int) int {
    return x + y
}Напишем тест для неё:
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)
    }
}Выполняем go test, и Go автоматически найдет и запустит этот тест. Если всё в порядке, вы увидите что-то вроде:
PASS
ok      yourpackage/math 0.002sИногда важно убедиться, что ваш код корректно обрабатывает нештатные ситуации. Допустим, у вас есть функция, которая должна вызывать панику при определенных условиях:
package panic
func DoPanic(flag bool) {
    if flag {
        panic("something went wrong")
    }
}Тест на панику может выглядеть так:
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)
}Тест проверяет, что DoPanic(true) действительно вызывает панику.
go fmt — личный стилист в Go. Он автоматически форматирует ваш код, следуя стандартам и конвенциям языка Go. Это обеспечивает единообразие и читаемость кода.
Допустим, у вас есть код, который выглядит немного хаотично:
package main
import "fmt"
func main() {fmt.Println("Hello, Habr!")}Выполните go fmt на файле, и он превратится в:
package main
import "fmt"
func main() {
    fmt.Println("Hello, Habr!")
}go fmt автоматически добавил отступы и переносы строк, сделав код более читаемым и красивым.
go vet — это инструмент для обнаружения подозрительных конструкций в коде. Он не заменяет тесты, но помогает найти проблемы, которые могут быть неочевидны на первый взгляд, такие как неправильное использование форматов строк, неправильные типы аргументов и многое другое.
Предположим, у вас есть следующий код:
package main
import "fmt"
func main() {
    var name = "Habr"
    fmt.Printf("Hello, %d!", name)
}Здесь вы случайно использовали %d (формат для целых чисел) вместо %s (формат для строк). Выполнение go vet на этом коде выдаст предупреждение:
# command-line-arguments
./main.go:6: Printf format %d has arg name of wrong type string
go vet помогает обнаружить такие ошибки до того, как они приведут к проблемам в работающем приложении.
godoc — это инструмент для автоматической генерации документации из исходного кода на Go. Он извлекает комментарии прямо из вашего кода и превращает их в красиво оформленную документацию, доступную в виде веб-страницы или в консоли.
К примеру у вас есть функция, которая складывает два числа:
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
}Комментарий над функцией Add — это то, что godoc будет использовать для создания документации. Если вы запустите godoc -http=:6060 и перейдете к http://localhost:6060/pkg/, вы увидите документацию для вашего пакета и функции.
Для документирования всего пакета просто добавьте комментарий в начале файла:
// 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
}
Этот комментарий будет использоваться godoc для создания обзора пакета.
Gin — это фреймворк для создания веб-приложений и API. Он дает маршрутизацию, промежуточное ПО (middleware), шаблонизацию и многое другое:
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 — это ORM библиотека для Go, которая упрощает работу с базами данных, предоставляя удобный интерфейс для запросов, вставок, обновлений и удалений.
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 — это отладчик, специально разработанный для Go. Он позволяет  запускать программы пошагово, просматривать и изменять переменные, и даже использовать условные точки остановки. 
dlv debug myapp.goПомните, что каждый инструмент — это лишь часть большой картины. Истинное мастерство заключается не только в знании инструментов, но и в понимании того, как и когда их применять.
И помните, как бы сложно ни было, всегда есть сообщество которое поможет.
А про актуальные инструменты и особенности их применения на практике, вы всегда можете узнать на онлайн-курсах OTUS под руководством экспертов отрасли.
Keep coding, keep improving, и до новых встреч на Хабре.
и... с наступающим Новым Годом! 🎄