Как объединить похожие мультипакетные проекты в го - PullRequest
0 голосов
/ 28 июня 2018

Несколько организаций распространяют варианты одного и того же проекта, и мы регулярно получаем изменения друг от друга. Было бы здорово, если бы мы могли в конечном итоге объединить репозитории кода и, возможно, иметь общее дерево исходных кодов, управляемое консорциумом. Тем не менее, каждый участник, вероятно, хотел бы иметь возможность распространять свой вариант без особых проблем для клиентов в случае возникновения проблем при продвижении изменений, необходимых для работы с более новыми продуктами.

Проект состоит из трех пакетов:

  1. Библиотека
  2. Исполняемый файл компилятора, который выводит код, необходимый для импорта библиотеки
  3. Исполняемый файл утилиты, использующий код, сгенерированный # 2, и ссылки с # 1

Большое раздражение при перемещении изменений вперед и назад - это безвозмездные различия в путях импорта. Мы в основном должны редактировать каждую версию от import "github.com/companyA/whatever" до import "companyB.com/whatever". Конечно, эти проблемы исчезли бы (удушье) относительных путей импорта. Если мы прибегнем к такой ереси, наш компилятор может просто жестко закодировать абсолютный путь импорта в сгенерированном коде, чтобы изолировать конечных пользователей от пути импорта библиотеки. Это также потребовало бы только одного бесполезного различия в исходных деревьях (строка в компиляторе, который выводит операторы импорта), а не связку.

Но в любом случае, я знаю, что относительные пути импорта плохие - это сложная ситуация. Я знаю, что это похоже на такие вопросы, как это или это , потому что ответ просто попросить конечных пользователей создать каталог с именем companyB.com и клонировать что-то из companyA там просто не собирается летать по практическим и политическим причинам.

Я уже знаю, что Го не очень хорош в приспособлении к этому сценарию, поэтому я также не прошу волшебную пулю, чтобы заставить Го справиться с тем, что он не может. Еще одна вещь, которая, к сожалению, не сработает, - это попросить клиентов curl whatever | sh, поскольку это считается слишком большой обязанностью (считается «обучение клиентов делать опасные вещи»). Может быть, мы могли бы отказаться от go get и заставить всех клонировать какое-либо нейтральное не-DNS-имя под $GOPATH/src, но нам нужно было бы сделать это без «дня флага», когда код неожиданно ломается, если он находится в неправильном месте.

Мой вопрос: успешно ли кто-нибудь объединял проекты типа SDK с существующими конечными пользователями, и если да, то как вы это делали, что работало, а что нет? Вы действительно избегали относительных путей импорта или грубых GOPATH хакерских атак, и если так, то стоило ли это? Какие механизмы вы использовали (переменные среды, файлы конфигурации, файлы .project-config в текущем рабочем каталоге, злоупотребление каталогом vendor, пакеты генерации кода, которые вычисляют их абсолютный путь импорта во время компиляции), чтобы сделать это гладко? Вы только что запутались с огромным количеством sed или, может быть, gofmt -r? Существуют ли уловки, предусматривающие умное использование .gitattributes или go generate для перезаписи путей импорта при извлечении / регистрации?

1 Ответ

0 голосов
/ 28 июня 2018

Объединить их довольно легко - объединить их так, чтобы все они соответствовали, выбрать один (или создать новый) в качестве канонического источника правды, затем перенести все ссылки на канонический импорт и сделать все будущие обновления там.

Вероятность возникает здесь:

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

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

Не зная больше о ситуации, трудно предложить варианты, но если есть какой-то способ, которым каждая компания может абстрагировать свою часть в отдельную библиотеку, которую они могли бы поддерживать и обновлять в своем темпе, используя меньшую общую библиотеку с общей ответственностью, это, вероятно, будет лучшим вариантом - что-то вроде модели, используемой Terraform для своих провайдеров? По сути, вы должны были бы совместно обслуживать общее «ядро» и затем независимое сопровождение «специфичных для поставщика» пакетов.

...