Как я могу добавить зависимости проекта gradle без изменения settings.gradle - PullRequest
0 голосов
/ 05 мая 2018

Фон

(Пожалуйста, имейте в виду, что я упростил задачу для обсуждения здесь)

  • У меня есть набор приложений и зависимых библиотек, что-то вроде этого (у каждого есть каталог src/ и build.gradle):

    appa/
    appb/
    libx/
    liby/
    libz/
    
  • В build.gradle зависимости в настоящее время объявлены следующим образом:

    appa/build.gradle:
       compile "com.asdf:libx:1.0"
       compile "com.asdf:liby:1.0"
    appb/build.gradle:
       compile "com.asdf:liby:1.0"
    liby/build.gradle:
       compile "com.asdf:libz:1.0"
    

Какую проблему я пытаюсь решить

  • Скажем, я работаю над appa, и мне нужно внести изменения в libx. Мне нужно сделать несколько шагов:
    1. Извлечь libx из системы контроля версий и вносить изменения локально
    2. Перестройте и отправьте изменения в некоторый репозиторий (не в продукт!)
    3. Перестройка appa (извлечение недавно обновленного libx из репозитория)
  • Если мое тестирование выявит ошибку в libx, я должен повторить это снова.
  • Это очень раздражает при работе в IDE, таких как Eclipse, где, хотя мои проекты логически используют другие проекты, я все равно должен использовать артефакты в качестве зависимостей.
  • Не было бы замечательно, если бы я мог просто вытянуть проект локально, и проекты, которые логически зависят от него, будут автоматически использовать исходный проект вместо артефакта для сборки?

Что я сделал до сих пор

  • Я написал небольшой плагин gradle (на который есть ссылка в build.gradle каждого проекта), который идентифицирует com.asdf зависимостей и использует подстановку зависимостей для замены зависимости артефакта зависимостью проекта, если этот проект существует локально.

    configurations.all {
        resolutionStrategy.dependencySubstitution {
            all { DependencySubstitution dependency ->
                if (dependency.requested instanceof ModuleComponentSelector && dependency.requested.group == 'com.asdf') {
                    def targetProject = findProject(":${dependency.requested.module}")
                    if (targetProject != null) {
                        dependency.useTarget targetProject
                    }
                }
            }
        }
    }
    
  • Ура! С некоторыми изменениями settings.gradle (см. Ниже) я достиг своей цели ... Кроме ...

Где я застрял

  • Мне нужно изменить settings.gradle, чтобы включить такие строки для каждой зависимости (в противном случае findProject не разрешает зависимый проект во время сборки):

    include ':libx'
    project(':libx').projectDir = new File(settingsDir, '../libx')
    
  • Хотя возможно , чтобы просмотреть все файлы settings.gradle и сделать это (я сделал это, как доказательство своей концепции), это уродливо, многократно, и логически это та же информация, которая передается compile аргументам для build.gradle зависимостей.

    • Это также подвержено ошибкам, когда кто-то добавляет новую зависимость, но не обновляет settings.gradle, или вводит опечатку между ними.
  • Я также пытался сделать settings.gradle просто определить проекты для всех каталогов, которые он находит на этом уровне, но затем создание любого проекта превращается в мега-сборку всех проектов.
  • (я пробовал несколько других вещей, но мой вопрос уже затянулся)

Мой вопрос

Какой лучший способ сделать это, не дублируя информацию между settings.gradle и build.gradle? Я хочу сделать так, чтобы добавить новые зависимости так же просто, как добавить ссылку compile в build.gradle, не касаясь settings.gradle ...

Я все еще довольно плохо знаком с groovy / gradle, так что, может быть, мне не хватает чего-то очевидного для более опытного мастера gradle?

1 Ответ

0 голосов
/ 05 мая 2018

Я считаю, что ваш сценарий использования является мотивом для Composite Builds .

У меня есть демо здесь , которое записывает в папку jars как фиктивную публикацию артефактов. Обязательно ознакомьтесь с README.md, так как демонстрационная версия - это мини-лаборатория для тестирования варианта использования до и после составной сборки.

В демоверсии mainBuild - это appa; utils - это libx. Синтаксис ключа в mainBuild/settings.gradle ( здесь ):

includeBuild '../utils'

Это говорит Gradle использовать локальную кодовую базу вместо опубликованного артефакта. Конечно, никто не передал бы эту строку в source-control.

...