Хобрук: Ваш путь к мастерству в программировании

Управление переходными версиями зависимостей в Gradle

У меня есть 3 проекта Gradle: Project-1, Project-2, Project-3. Project-1 и Project-2 — это библиотеки Java, Project-3 — потребитель этих библиотек. И Project-1, и Project-2 зависят от модуля-A. Однако для каждого из них я хочу указать список точных версий, с которыми они совместимы. Например, Project-1 совместим и протестирован с Module-A версий 1 и 2, а Project-2 совместим с Module-A версий 2 и 3. Я хочу иметь возможность указать эти требования в конфигурации сборки каждый проект. Эти зависимости могут быть только имплементационными или даже только компилируемыми.

Когда Project-3 использует библиотеки, созданные Project-1 и Project-2, я хочу убедиться, что Module-A разрешен до последней версии, которая явно указана как в Project-1, так и в Project-2. В противном случае я хотел бы получить ошибку на этапе сборки, что не может быть найдено удовлетворительное разрешение зависимостей. В идеале я хотел бы иметь возможность явно указать версию Module-A в сборке Project-3 Gradle и получить сообщение об ошибке, если он несовместим ни с одним из Project-1 или Project-2.

Артефакты Project-1 и Project-2 используются и загружаются в локальный репозиторий Maven с помощью подключаемого модуля Maven.


  • какая разница между проектом и модулем здесь? 03.11.2018
  • @homerman термин модуль часто используется в документах Gradle для описания зависимости: docs .gradle.org/current/userguide/ 03.11.2018
  • @homerman в моем случае использует модуль как внешнее программное обеспечение, а не проект как то, что я могу контролировать. Но для Project-3 артефакты Project-1 и Project-2 являются зависимостями внешних модулей, как и любые другие. 04.11.2018
  • Спасибо. как пользователь IntelliJ и Gradle, я часто ловлю себя на том, что сомневаюсь в том, о чем говорят люди, когда ссылаются на проект и/или модуль. 04.11.2018

Ответы:


1

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

Top-level
├── Project-1
├── Project-2
└── Project-3

... и различные версии Guava берут на себя роль Module-A, как вы описали настройку.

Верхний уровень build.gradle:

ext {
  project1GuavaVersions = ['26.0-jre','27.0-jre']
  project2GuavaVersions = ['25.0-jre','26.0-jre']

  if(project1GuavaVersions.disjoint(project2GuavaVersions)) {
    throw new GradleException('No common version(s) of Guava defined')
  } else {
    project3GuavaVersion = new HashSet(project1GuavaVersions + project2GuavaVersions).max()
  }

subprojects {
  apply plugin: 'java'
}

дополнительные свойства, используемые для указания допустимых версий Guava для каждого модуля. Версия Project-3 рассчитывается как последняя версия, используемая между Project-1 и Project-2. (дополнительно для удобства к трем подпроектам применяется плагин Java).

Проект-1 build.gradle:

archivesBaseName = 'project1'

repositories {
  mavenCentral()
}

dependencies {
  implementation "com.google.guava:guava:[${project1GuavaVersions.join(',')}]"
}

дополнительное свойство для версий Project-1 Guava интерполируется и преобразуется из списка строк в строку с разделителями-запятыми. это использует способность Gradle использовать нотацию Ivy для указания диапазона версий, то есть [26.0-jre,27.0-jre].

Проект-2 build.gradle:

archivesBaseName = 'project2'

repositories {
  mavenCentral()
}

dependencies {
  implementation "com.google.guava:guava:[${project2GuavaVersions.join(',')}]"
}

(аналогичная реализация Project-1)

Проект-3 build.gradle:

archivesBaseName = 'project3'

repositories {
  mavenCentral()
}

dependencies {
  implementation project(':project1')
  implementation project(':project2')
  implementation "com.google.guava:guava:$project3GuavaVersion"
}

Project-1 и Project-2 определяются как зависимости на уровне проекта, и здесь используется явно рассчитанная версия для Guava, определенная как дополнительное свойство.

я надеюсь, что охватывает все. по крайней мере, я надеюсь, что это вдохновит на новые мысли!

ОБНОВЛЕНИЕ

как вы упомянули в комментариях, что ваши проекты не настроены иерархически, у вас также есть возможность настроить их в «плоском» расположении, в котором все проекты существуют в одной и той же папке, например так:

(root)
├── project1
│   └── build.gradle
├── project2
│   └── build.gradle
├── project3
│   └── build.gradle
└── master
    ├── build.gradle
    └── settings.gradle

«мастер» здесь — это специально названный проект, который находится рядом с другими проектами. settings.gradle следует переместить в master и использовать Settings.includeFlat(), чтобы указать, что вы хотите включить проекты, существующие на одном уровне:

includeFlat 'project1'
includeFlat 'project2'
includeFlat 'project3'

детали моего первоначально предложенного решения должны быть применимы к этой настройке.

04.11.2018
  • Спасибо за Ваш ответ! Однако эта установка не дает того, что мне нужно: если project1GuavaVersions = ['27.0-jre','28.0-jre'], я хочу, чтобы сборка project3 не удалась, так как нет общей версии, которая могла бы удовлетворить все зависимости. 06.11.2018
  • я обновил фрагмент в файле сборки верхнего уровня, чтобы решить эту проблему. 06.11.2018
  • В моей настройке нет сборки верхнего уровня. Все там проекты строятся самостоятельно. 06.11.2018
  • я обновил свой пост с подробностями о плоской структуре проекта 07.11.2018
  • Новые материалы

    Аргументы прогрессивного улучшения почти всегда упускают суть
    В наши дни в кругах веб-разработчиков много болтают о Progressive Enhancement — PE, но на самом деле почти все аргументы с обеих сторон упускают самую фундаментальную причину, по которой PE..

    Введение в Джанго Фреймворк
    Схема «работать умно, а не усердно» В этой и последующих статьях я познакомлю вас с тем, что такое фреймворк Django и как создать свое первое приложение с помощью простых и понятных шагов, а..

    Настольный ПК как «одно кольцо, чтобы править всеми» домашних компьютеров
    Вид после 9 месяцев использования С настольных компьютеров все началось, но в какой-то момент они стали «серверами», и мы все перешли на ноутбуки. В прошлом году я столкнулся с идеей настольных..

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

    стройный-i18следующий
    Представляем стройную оболочку для i18next. Эта библиотека, основанная на i18next, заключает экземпляр i18next в хранилище svelte и отслеживает события i18next, такие как languageChanged,..

    Обзор 20 основных и современных методов работы с массивами в JavaScript
    Вы знаете их всех? В этом коротком посте я покажу сводку методов, доступных в JavaScript для работы с массивами. Я надеюсь, что вы найдете это полезным! В конце поста вы найдете ссылку на..

    Да, но я чувствую необходимость указать, что это или не единственные два.
    Да, но я чувствую необходимость указать, что это или не единственные два. Обучение с подкреплением (в качестве примера) также является важным.