Зависимости относительно подпроектов Gradle, которые также могут быть построены независимо - PullRequest
0 голосов
/ 27 апреля 2018

Фон

Я унаследовал старый, чрезвычайно сложный Java-проект на основе Gradle со многими подпроектами. Многие из них имеют *.jar библиотеки с закрытым исходным кодом, которые не должны попадать в другие (под) проекты, чтобы избежать конфликтов пространства имен, когда несколько проектов используют разные версии "одной и той же" библиотеки.

Я пытаюсь обновить проект для использования некоторых новых версий некоторых из этих библиотек и в целом очистить зависимости, так как разработка стала чрезвычайно сложной. Что еще хуже, один проект вложен как подмодуль Git , который, как предполагается, может быть построен независимо или как подпроект основного проекта Gradle, над которым я работаю с.

Подмодуль Git

Вот упрощенная структура, аналогичная подмодулю Git / проекту Gradle / подпроекту Gradle:

robotcontroller
+--.git
+--gradle
+--libs
+--planning
|  +--src
|  +--build.gradle
+--plugins
|  +--nao
|  |  +--libs
|  |  |  +--robocommons.jar
|  |  +--src
|  |  +--build.gradle
|  +--pepper
|  |  +--libs
|  |  |  +--graphadapter.jar
|  |  +--src
|  |  +--build.gradle
+--build.gradle
+--gradlew
+--gradlew.bat
+--settings.gradle

plugins/nao/build.gradle:

dependencies {
    compile project(':planning')
    // This is inside the subproject's "libs/" dir
    compile name: 'robocommons'
    compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.3'
}

[rootProject, this].each {
    it.repositories {
        flatDir {
            dirs "${rootDir}/plugins/nao/libs/"
        }
    }
}

plugins/pepper/build.gradle:

dependencies {
    compile project(':planning')
    // This is inside the subproject's "libs/" dir
    compile name: 'graphadapter'
    compile group: 'com.google.guava', name: 'guava', version: '19.0'
}

[rootProject, this].each {
    it.repositories {
        maven {
            // Some proprietary, closed-source repo
        }
        flatDir {
            dirs "${rootDir}/plugins/pepper/libs/"
        }
    }
}   

plugins/build.gradle:

dependencies {
    compile project(':plugins:nao')
    compile project(':plugins:pepper')
}

build.gradle:

// Stuff like plugins here
...

allprojects {
  repositories {
    flatDir {
      dirs "${rootDir}/libs"
    }
    jcenter()

    maven {
        // Some other proprietary repo here
    }
  }

  dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
  }
}

dependencies {
    compile subprojects
}

// Stuff like javadoc and sourceJar tasks
...

settings.gradle:

include 'planning'
include 'plugins'
include 'plugins:nao'
include 'plugins:pepper'

Корневой репозиторий Git

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

complicatedrobotproject
+--.git
+--gradle
+--robotcontroller@SOMEREVISION // This is managed by the ".gitmodules" file
+--robocommons // A different, partially-compatible version of the source code used to make "robocommons.jar" is here
|  +--src
|  +--build.gradle
+--.gitmodules
+--build.gradle
+--gradlew
+--gradlew.bat
+--settings.gradle

build.gradle:

allprojects {
    repositories {
        flatDir {
            dirs "${rootDir}/robotcontroller/libs"
        }
    }
}

dependencies {
    // some external dependencies
    ...
    compile project(":robotcontroller")
    compile project(":robocommons")

    // TEST
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

settings.gradle:

include 'robocommons'
include 'robotcontroller:planning'
include 'robotcontroller:plugins'
include 'robotcontroller:plugins:nao'
include 'robotcontroller:plugins:pepper'

Проблема

В приведенном выше примере моей непосредственной целью является замена исходного кода, найденного в complicatedrobotproject/robocommons, на robocommons.jar. Тем не менее, единственный способ построить проект - использовать модифицированную версию подмодуля Git robotcontroller, которая на самом деле зависит от этого:

robotcontroller/plugins/nao/build.gradle от редакции SOMEREVISION:

dependencies {
    compile name ':robocommons' // When building "complicatedrobotproject", this in fact links "robocommons" the directory, not "robocommons.jar"!
    compile project(':robotcontroller:planning')
    compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.3'
}

Путем добавления :robotcontroller к зависимостям можно построить проект complicatedrobotproject, но robotcontroller нельзя построить как отдельный проект Gradle. Принятие этого квалификатора делает последним строимым за счет первого. Классы, присутствующие в robocommons.jar, также присутствующие в каталоге robocommons, в значительной степени, но не полностью эквивалентны. В конечном счете, я хочу заменить обоих на соответствующую внешнюю зависимость, например, compile group: 'com.complicatedrobots', name: 'robocommons', version: '2.0.3', но это потребует много повторной реализации, и сначала мне нужно разобраться с этим кошмаром зависимости.

Моя задача - не придавать проекту смысл; Как бы это ни причиняло мне боль, мне нужно, чтобы оба репозитория Git были доступны для сборки, а также использовать одну версию robocommons для всех проектов Gradle, независимо от того, какой репозиторий Git создается. Я даже не могу думать о проблеме прямо, потому что каждая возможность, о которой я думаю, блокирует какую-то другую вещь, которая должна работать.

1 Ответ

0 голосов
/ 27 апреля 2018

Не могу сказать, что понимаю, что происходит в этой сборке, и я чувствую вашу боль. Первое, что я хотел бы сказать, это то, что составные сборки могут предложить путь к "нормальной" поддерживаемой сборке, позволяющей сохранить robotcontroller в качестве отдельного проекта. Если вы пойдете по этому пути, вам придется удалить `include": robotcontroller "из родительского файла settings.gradle и заменить его эквивалентной составной конфигурацией сборки.

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

  1. Переместите все эти JAR-файлы в plugins / * / libs в robotcontroller / libs , добавив версию к их именам файлов

  2. Обновите все зависимости этих JAR-файлов, чтобы они включали соответствующую версию

  3. Удалите каталог / robocommons

Видите ли, robotcontroller / libs , похоже, уже настроен как хранилище плоских каталогов как в robotcontroller , так и в родительском проекте. Мне кажется, что единственная причина, по которой проблемные библиотеки находятся в директориях для конкретных проектов, заключается в том, что в их именах нет номеров версий, чтобы различать их. Добавляя номер версии, вы можете хранить их рядом в одном каталоге.

Это имеет смысл? Надеюсь, это поможет в любом случае!

...