Maven vs Gradle? Це неправильна постановка питання

Написати, нарешті, цей пост мене змусила вже давня дискусія ось до цього посту на тему, яка час від часу спливає то там, то тут.

Я багато разів мав можливість переконатися, що далеко не всі однаково розуміють, у чому ж полягає декларативність vs процедурність тієї чи іншої системи складання. Основною перевагою інструменту складання часто вважається можливість писати алгоритми складання на зручному мовою. Потрібен DSL, нікуди без нього.

У gradle цей DSL базується на groovy. sbt використовує скелю, leiningen — Clojure, Ant використовує xml (абсолютно не по справі, до речі). Неважко пригадати системи складання на базі javascript. Кожен збирає тією мовою, яка йому ближча. І нові інструменти пишуть, наприклад, на котлине.

На жаль, але наявність DSL зовсім не означає декларативності. Швидше навпаки. У підсумку, gradle проект взагалі не може повноцінно жити без pom.xml. Це жарт, але з великою часткою правди. Подивіться ось сюди: репозиторий.

Що у нас тут лежить? Так-так, саме pom.xml він самий. А де ж у нас build.gradle? А немає його. Розумієте? Його тут немає.

Тобто всі метадані, які надані зібраному проекті, який зауважимо, збирається за допомогою gradle, складаються тільки і виключно з метаданих maven.

Вас це не дивує? Мене — анітрохи. На мій погляд, gradle, sbt, leiningen і багато інші інструменти майже (або зовсім) не надають метаданих в доступному іншим продуктам вигляді.

Вони реально видно тільки самим собі, і тільки зсередини процесу складання. Просто тому, що скрипт збірки — це груви код (Clojure, скеля, javascript). Саме тому ж їх так погано підтримують IDE (в порівнянні з maven або ant, де скрипт це xml). Щоб зрозуміти, що там відбувається, потрібно виконати. Потрібно мати gradle всередині, і потрібно щоб gradle віддавав в IDE необхідну інформацію.

Як я бачу собі декларативність, і навіщо вона буває потрібна? В якості ілюстрації наведу два своїх проекту, і один від apache:

  • Почнемо мабуть з Apache Karaf. У ssh-консолі вам доступна команда установки модуля (OSGI-bundle). Ця команда використовує не що інше, як координати модуля в maven repository: bundle:install mvn:groupId/artifactId/version. При цьому самого maven karaf не містить — під капотом ніщо інше, як Ефір, плюс обгортка над ним (Pax URL).
  • Аналогічну конструкцію я реалізував колись давно на Jython, і працювала вона всередині Weblogic. Використовувався той же Aether, плюс WLST API. І дозволяло все це автоматично оновлювати встановлені в контейнері JavaEE модулі, розшукуючи їх нові версії у сховищі.
    Знову ж таки — maven в конструкцію не входив. Використовувалися репозиторій, Ефір, і pom.xml, які maven упаковує в META-INF модуля.
  • І останній приклад. У моїй практиці був один maven plugin, який в якості вихідних даних для своєї роботи використовував SVN, скануючи папки і файли на предмет змін в проектах, порівнюючи їх з bug tracker, та приймаючи рішення, які саме зібрані артифакты потрібно включати в реліз, і деплоить.
Які висновки можна з цього зробити?

По-перше, ми бачимо, що з описом проекту (в моєму випадку це завжди був pom.xml) іноді буває потрібно і можна працювати з будь-якого достатньо розвиненої мови. Це не зобов'язаний бути інструмент збірки, на який розрахований проект.

По-друге, якщо репозиторій спроектований правильно, у відповідності з принципами REST, то нам не потрібен ніякий спеціальний софт для роботи з ним, крім http-сервера. Потрібні тільки дані метауровня трохи вище проекту (список доступних версій, наприклад).

По-третє, дуже зручно те, що важлива частина інфраструктури, в нашому випадку plugins, самі просто звичайні артефакти, лежать в тому ж репозиторії, і ніяк не пов'язані взагалі з конкретним проектом.

Ось це я називаю декларативним підходом. У нас є проекти, їх багато. Вони бувають у репозиторії, у вигляді зібраних артефактів, VCS, і ще де-небудь, і можуть оброблятися різними інструментами, а не тільки одним єдиним. Дескриптор проекту — це просто файл, будь-якого стандартного і зручного для обробки формату. Репозиторій артефактів — це теж стандартизований формат + простий REST API. А логіка складання, на будь-якому зручному вам DSL, лежить окремо. Хочете — в самому дескрипторі, хочете — в репозиторії.

Як би я взагалі це все зробив? По суті, якщо брати за основу maven, то зараз тут не вистачає гнучкості в частині plugins, їх налаштувань, і т. п., тому що існуючий xml — це сериализованное подання java-моделі даних plugins і ядра, і воно не гнучко. Якщо розробники вирішили, що якісь дані про проект вам не потрібні — у вас залишається тільки варіант key-value у вигляді properties.

А варто було б зробити щось довільною, але регулярної структури, ну скажімо типу RDF (не обов'язково саме його).
Опис проекту у вигляді RDF відразу дозволяє робити корисні речі на зразок пошуку в ньому, як в базі даних (тобто репозиторій, в частині метаданих, стає просто SPARQL endpoint, і вміє відповідати на пошукові запити). І такі ж запити можна будувати стосовно до проекту.

Ось це і був би справжній poliglot maven. Причому це, до речі, виглядає цілком реалізовується, навіть в рамках існуючої інфраструктури.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.