Русский
Русский
English
Статистика
Реклама

Перевод Go Как подключить внешнюю библиотеку и исключить ненужные зависимости


TL;DR: Кодогенератор.


Представьте, что вы разрабатываете некоторую библиотеку, которая поддерживает различные драйвера для хранения данных: Postgresql, Scylla, JSON и какие-либо другие.


У каждого из этих драйверов есть внешние зависимости от других библиотек. Postgresql database/sql, github.com/lib/pq. Scylla github.com/scylladb/gocql или стандартный github.com/gocql/gocql. JSON github.com/mailru/easyjson или github.com/json-iterator/go, или encoding/json.


Обычный пользователь подключает вашу библиотеку и получает неявное включение всех этих внешних библиотек.


В большинстве случаев это нормально, но не идеально: иногда пользователю нужен только Postgres драйвер, но вместе с ним он неявно получает огромное количество кода из внешних библиотек, которые ему никогда не будут нужны.


Попробуем это исправить, используя замечательный механизм кодогенерации.


Кодогенерация


Разбейте файлы на части


Разбейте файлы вашей библиотеки на логические части, которые реализуют каждую отдельную конкретную зависимость. Пример: sql.go, cql.go, json.go.


Это позволит вам сгенерировать для пользователя только ту часть вашей библиотеки, которую он запросит.


Упакуйте файлы


Упакуйте файлы через pkger или любое другое решение для хранения их в бинарном файле.


Для включения файлов через pkger в исходном коде просто нужно их использовать


    files := make([]string, 0)    if *cql {        files = append(files, pkger.Include("/cql.go"))    }    if *json {        files = append(files, pkger.Include("/json.go"))    }    if *sql {        files = append(files, pkger.Include("/sql.go"))    }

Далее запустите


pkger -o <путь к исходнику кодогенератора>

И после этого вы получите статический исходник с упакованными файлами, который будут включены в бинарный файл.


Удобно добавить генерацию в go generate


//go:generate pkger -o <путь к исходнику кодогенератора>

Упаковка исходных кодов в бинарный файл нужна потому, что кодогенератор будет использоваться независимо от вашей библиотеки.


Напишите кодогенератор


Кодогенератор это обычная программа на Go, которая принимает аргументы для генерации и записывает исходные файлы для выбранных типов в проект пользователя.


    for i := range files {        _, filename := filepath.Split(files[i])        in, err := pkger.Open(files[i])        if err != nil {            panic(err)        }        src := []byte(fmt.Sprintf(genStr, strings.Join(os.Args[1:], " ")))        reader := bufio.NewReader(in)        for {            line, err := reader.ReadBytes('\n')            if strings.HasPrefix(string(line), "package ") {                line = []byte(fmt.Sprintf("package %s\n", *pkgName))            }            src = append(src, line...)            if err == io.EOF {                break            }            if err != nil {                panic(err)            }        }        if err := ioutil.WriteFile(filename, src, 0644); err != nil {            panic(err)        }        in.Close()    }

Разместите исходный код вашего кодогенератора в подпапке проекта вида cmd/<имя вашего проекта>. Это позволит пользователю получить бинарный файл кодогенератора с тем же названием, что и название вашей библиотеки.


Использование


Пользователь устанавливает кодогенератор


go get github.com/<ваш профиль>/<ваша библиотека>/<путь к кодогенератору>

И затем запускает кодогенератор в своём проекте


<имя бинарного файла вашего кодогенератора> -sql

Когда нужно обновить вашу библиотеку пользователь обновляет кодогенератор


go get -u github.com/<ваш профиль>/<ваша библиотека>/<путь к кодогенератору>

И затем запускает генерацию заново.


Пример данного подхода к использованию зависимостей я и creker реализовали в библиотеке nan: с библиотекой можно работать как в обычном режиме, через import, так и в варианте кодогенерации.

Источник: habr.com
К списку статей
Опубликовано: 04.10.2020 04:14:12
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Go

Codegen

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru