Выбирать TargetFramework для восточных библиотек по выбранной конфигурации цемента#27
Conversation
| build: | ||
| - tool: dotnet | ||
| parameters: build | ||
| target: library-common-props/Resolve-Main-TargetFramework.csproj -p:PropsFile=Main-TargetFramework-netstandard2.0.props |
There was a problem hiding this comment.
а зачем тут вообще что-то билдить?
нельзя ли только в остальных конфигах это делать?
тогда текущее поведение останется без изменений
There was a problem hiding this comment.
я подумал, что будет неявно, а тут сразу понятно какая конфигурация что делает.
И условный импорт я добавил не как основной способ задания, а больше как fallback для обратной совместимости, и на деле сейчас не знаю сценария, когда сработает fallback.
There was a problem hiding this comment.
можно сделать дефолтной конфигурацию base, которая без сборки
это немного упростит тогда фикс для явных веток
There was a problem hiding this comment.
просто как-то не понятно, в csproj есть if под случай когда файла нету, а ситуации такой быть не должно
хочется как-то однообразно, либо файл всегда генерится и есть, либо же наоборот
There was a problem hiding this comment.
мне больше нравиться убрать fallback и везде собирать, это однообразно.
но я знаю только сценарии использования модуля вместе с цементом, вдруг есть еще какие, которые я не знаю, а вы в курсе.
либо убрать, а если сценарий найдется, то только тогда добавить.
There was a problem hiding this comment.
давай уберем, будет сразу падать если что
There was a problem hiding this comment.
убрал, изменения в Main-Project.props
Проблема
Сейчас через модуль vostok.devtools для всех восточных библиотек устанавливается свойство TargetFramework для сборки.
Это упрощает команде базовой инфраструктуры предоставлять разные TargetFramework для пользователей.
Сейчас пользователи могут выбрать под какие TargetFramework собирать, выбрав определенную ветку этого репозитория:
Но у этого есть недостатки:
Сейчас это незаметно из-за того, что в основном все пользуются неявной веткой master и явной with-net6.0, и такое цемент может разрулить.
Но если появятся использования only-net6.0 или появятся новые ветки (например с net7.0), то проблема выстрелит во всей красе, особенно сейчас многие начинают завязываться на with-net6.0 ради некоторых фич, которые там доступны.
Это уже сейчас больно как локально у пользователя, так и на агентах CI.
Концепт
Похожая проблема была уже решена в цементе - у каждой цементного модуля могут быть разные конфигурации сборки и другие модули могут хотеть разные их варианты.
И тут спасает наследование конфигураций - если несколько модулей хотят разные конфигурации этого модуля, то можно найти и собрать общую конфигурациию, которая содержит обе эти конфигурации.
Собственно я хочу сделать выбор TargetFramework на основе выбранной конфигурации цементного модуля.
Будут следующие конфигурации:
И теперь:
Но есть минус:
Если при сборке одного конечного модуля, которому нужна небольная конфигурацию (например netstandard2.0), другой модуль уже собирал в этой цементной папке часть восточных зависимостей с большей конфигурацией (with-net6.0), то все остальные еще не собранные восточные зависимости будут собраны под большую конфигурацию, хотя хватило бы меньшей, что влияет на время сборки.
Но мне кажется это лучше, чем пересобирать цементную папку каждый раз.
Тем более есть вероятность собирать какой-то третий модуль, которому нужны были бы зависимости второго модуля в большей конфигурации, и тут он их уже получит бесплатно.
Также в решение будет учтено:
Обсуждение
https://kontur.slack.com/archives/C08DRHZTP/p1665407872789439
Решение
Вытащим из Main-Project.props установку TargetFramework, вместо этого в Main-Project.props будет импортить Main-TargetFramework.props, в котором будет задаваться это свойство.
Изначально файла Main-TargetFramework.props нет, он будет появляется в результате цементной сборки.
Цементная сборка будет состоять просто из копирования одного из заготовленных файлов в Main-TargetFramework.props:
Чтобы было кросплатформенно, решил копировать через утилиту dotnet, а не скриптом, для этого пришлось завести Resolve-Main-TargetFramework.csproj, в котором указана логика копирования.
Чтобы, на всякий случай для обратной совместимости, работало без сборки, указал импорт Main-TargetFramework-netstandard2.0.props, если Main-TargetFramework.props не существует.
Проблема:
При влитии в другие актуальные ветки (only-net6.0, with-net6.0) будет конфликт, который надо порешать и указать другой дефолтный файл.
Если не торопиться со влитием в эти ветку, будет проблема того, что при переключении с мастера на эти ветку будет ругаться на незакоммиченный файл Main-TargetFramework.props (так как игнор его также лежит в .gitignore мастера).
Но МР-ки с решением этих конфликтов можно подготовить заранее.