Почему Gradle Wrapper должен быть привержен VCS?

148

Из документации Gradle: https://docs.gradle.org/current/dsl/org.gradle.api.tasks.wrapper.Wrapper.html

Сценарии, сгенерированные этой задачей, предназначены для фиксации в вашей системе контроля версий. Эта задача также генерирует небольшой файл JAR загрузочного файла gradle-wrapper.jar и файл свойств, которые также должны быть переданы вашей VCS. Сценарии делегатов для этого JAR.

От: Что НЕ должно находиться под контролем источников?

Я думаю, что Generated filesне должно быть в VCS.

Когда gradlewи gradle/gradle-wrapper.jarнужны?

Почему бы не сохранить gradle versionв build.gradleфайле?

farmer1992
источник
1
Что может быть интересным, учитывая ответы ниже, это полезность этих файлов, если вы используете какой-либо инструмент непрерывной интеграции. Какие из них будут проверять упаковку и использовать ее, если она там есть?
lilbyrdie

Ответы:

124

Потому что весь смысл оболочки Gradle заключается в том, чтобы иметь возможность, даже не устанавливая gradle, и даже не зная, как он работает, откуда его загружать, с какой версии, чтобы клонировать проект из VCS, выполнить его сценарий gradlew содержит, и построить проект без каких-либо дополнительных шагов.

Если все, что у вас было, это номер версии Gradle в файле build.gradle, вам понадобится README, объясняющий всем, что версия X Gradle должна быть загружена с URL Y и установлена, и вам придется делать это при каждом увеличении версии.

Дж. Б. Низет
источник
94
Это глупо. gradle-wrapper.jar не требуется в VCS. Gradle должен иметь возможность загружать любую версию после установки первой, если это необходимо. Цепочка инструментов не имеет ничего общего с VCS ... Я понимаю, что ваш ответ правильный, и это дизайн Gradle. Но этот дизайн абсурден.
Марк Плано-Лесай
26
Суть в том, чтобы иметь возможность загружать Gradle без предварительной установки Gradle . В чем проблема с размером файла 50 КБ в VCS?
JB Низет
59
Проблема в том, что это не часть проекта. Это инструмент, который вы используете для создания проекта. Вы не будете хранить JDK в VCS, не так ли? Ни GCC для приложения C? Так зачем вам хранить деталь Gradle? Если разработчик не может сам прочитать и установить Gradle, это еще одна проблема.
Марк Плано-Лесай
26
Проблема также в том, что вы не можете вспомнить, через 2 года после выпуска, какая версия Gradle использовалась для создания версии вашего программного обеспечения v1.0, что вам нужно исправить для клиента, который все еще использует этот 1.0 версия и не может обновить. Оболочка gradle решает, что: вы клонируете тег 1.0 из VCS, создаете его с помощью gradlew, и он использует версию gradle, которая использовалась 2 года назад для сборки версии 1.0.
JB Низет
33
Я согласен с тем, что используемую версию Gradle нужно указать где-то в проекте. Но Gradle - это внешний инструмент, ничто не сравнимо с README или чем-то, что вы перечислили. Gradle должен иметь возможность извлекать соответствующую версию самостоятельно, без необходимости хранить jar на VCS.
Марк Плано-Лесай,
80

Потому что весь смысл грейферной обертки в том, чтобы иметь возможность, даже не устанавливая грейфер

То же самое относится и к JDK, вы тоже хотите это зафиксировать? Вы также фиксируете все свои зависимые библиотеки?

Зависимости должны постоянно обновляться по мере выпуска новых версий. Чтобы получить безопасность и другие исправления ошибок. И потому, что если вы далеко позади, это может быть очень трудоемкой задачей, чтобы обновиться.

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

и даже не зная, как это работает

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

откуда его скачать, какая версия

task wrapper(type: Wrapper) {
 gradleVersion = 'X.X' 
}

А потом

gradle wrapper

Чтобы скачать правильную версию.

клонировать проект из VCS, выполнить содержащийся в нем скрипт gradlew и построить проект без каких-либо дополнительных шагов.

Решено по шагам выше. Загрузка оболочки Gradle не отличается от загрузки любых других зависимостей. Сценарий может быть разумным, чтобы проверить наличие любой текущей оболочки Gradle и загружать ее только при наличии новой версии.

Если разработчик никогда не использовал Gradle и, возможно, не знает, что проект собирается с Gradle. Тогда более очевидно запускать «build.sh» по сравнению с «gradlew build».

Если все, что у вас было, это номер версии Gradle в файле build.gradle, вам понадобится README, объясняющий всем, что версия X Gradle должна быть загружена с URL Y установленным,

Нет, вам не нужно README. Вы могли бы иметь один, но мы разработчики, и мы должны максимально автоматизировать. Создание сценария лучше.

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

Если разработчики согласны с тем, что правильный процесс заключается в следующем:

  1. Клон репо
  2. Запустить скрипт сборки

Тогда обновление до последней версии Gradle не является проблемой. Если версия увеличивается с момента последнего запуска, скрипт может загрузить новую версию.

Томас Бьерре
источник
2
«Зависимости должны постоянно обновляться». Да, в перспективном направлении. Нет, в обратном направлении. Чтобы воспроизвести старую сборку, вам нужно иметь конкретные версии зависимостей. Gradle ускоряет и облегчает работу с некоторыми типами проектов. Это будет беспорядок в организации, которая нуждается в воспроизведении и аудите.
lilbyrdie
3
Не совсем уверен, что вы имеете в виду. Но если у вас есть build.gradleконтроль версий, и у вас есть: task wrapper(type: Wrapper) { gradleVersion = 'X.X' } Затем gradle wrapperзагрузите используемую оболочку, и вы сможете воспроизвести старую сборку.
Томас Бьерре
1
Ссылался на вашу строку о зависимостях, а не версию Gradle. Конечно, вы хотите, чтобы в ваших библиотеках были все последние исправления безопасности и ошибок, но НЕ когда вы пытаетесь воспроизвести старую сборку, возможно, для аудита или в юридических целях. Вы хотите, чтобы ваши библиотеки и процесс сборки могли производить двоичный идентичный вывод, если это вообще возможно. Как и в случае зависимости от библиотеки, нет никакой гарантии, что конкретная версия будет доступна во время сборки ... будь то через 2 недели или через 2 десятилетия. Так что да, это то же самое, что библиотеки и SDK для некоторых проектов.
lilbyrdie
3
Я думаю, что обертка там в первую очередь по историческим причинам. В начале все используют Maven, и никто не установил Gradle. Было бы трудно убедить коллегу установить неизвестные навязчивые зависимости, поэтому оболочка помогает им при загрузке. В настоящее время у всех уже есть Gradle, и обертка становится излишней.
Франклин Ю.
1
Вы предлагаете выполнять gradle wrapperпосле клонирования на каждой сборке? По сути, это делает обертку бесполезной, поскольку весь смысл в том, что вам не нужно устанавливать Gradle локально для сборки проекта !
Xerus
41

Я хотел бы рекомендовать простой подход.

В README вашего проекта, документ, который требуется шаг установки, а именно:

gradle wrapper --gradle-version 3.3

Это работает с Gradle 2.4 или выше. Это создает оболочку без необходимости добавления выделенной задачи в «build.gradle».

С помощью этой опции игнорируйте (не регистрируйте) эти файлы / папки для контроля версий:

  • ./gradle
  • gradlew
  • gradlew.bat

Основное преимущество заключается в том, что вам не нужно регистрировать загруженный файл в систему контроля версий. Это стоит один дополнительный шаг при установке. Я думаю, это того стоит.

Дэвид Дж.
источник
15
зачем вам тогда обертка? Идея обертки заключается в том, что вы можете собрать проект, не занимаясь в своей системе.
edio
4
Хорошее решение. Нет бинарных файлов в git и все еще возможность использовать gradlew. @edio вам понадобится, чтобы скачать и использовать конкретную версию Gradle.
Кирилл
3

Что такое "проект"?

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

Но если мы говорим «ваш проект», это все, что вы сделали . Тогда мы можем сказать, что вы должны включить его и только его в VCS.

Это очень теоретически и, возможно, не практично в случае наших разработок. Поэтому мы изменили его на « ваш проект - это каждый файл (или папка), который вам нужно редактировать напрямую ».

«напрямую» означает «не косвенно», а «косвенно» означает редактирование другого файла, после чего эффект будет отражен в этом файле .

Таким образом, мы достигаем того же, что сказал OP (и сказано здесь ):

Я думаю, что сгенерированные файлы не должны быть в VCS.

Да. Потому что вы их не создали. Таким образом, они не являются частью «вашего проекта» согласно второму определению.


Каков результат этих файлов:

  • build.gradle : да. Нам нужно отредактировать это. Наши работы должны быть версионными.

    Примечание: нет разницы, где вы редактируете это. В среде вашего текстового редактора или в среде с графическим интерфейсом структуры проекта . В любом случае вы делаете это напрямую !

  • gradle-wrapper.properties : Да. Нам нужно как минимум определить версию Gradle в этом файле.

  • gradle-wrapper.jar и gradlew [.bat] : Я не создавал и не редактировал их ни в одной из своих разработок, до этого момента! Так что ответ «Нет». Если вы сделали это, ответ «Да» о вас на этой работе (и о том же файле, который вы редактировали).


Важное замечание о последнем случае это пользователь , который клонирует ваш репозиторий, необходимо выполнить эту команду на репо<root-directory> для автоматического создания обертки файлов:

> gradle wrapper --gradle-version=$v --distribution-type=$distType

$vи $distTypeопределяются из gradle-wrapper.properties :

distributionUrl=https\://services.gradle.org/distributions/gradle-{$v}-{$distType}.zip

См. Https://gradle.org/install/ для получения дополнительной информации.

gradleисполняемый файл находится bin/gradle[.bat]в локальном распределении. Не требуется, чтобы локальное распространение было таким же, как определено в репо. После создания файлов-gradlew[.bat] оберток можно автоматически загрузить определенный дистрибутив Gradle (если он не существует локально). Затем он / она, вероятно, должен восстановить файлы-оболочки, используя новый gradleисполняемый файл (в загруженном дистрибутиве), используя приведенные выше инструкции.


Примечание. В приведенных выше инструкциях предполагается, что у пользователя есть хотя бы один дистрибутив Gradle локально (например ~/.gradle/wrapper/dists/gradle-4.10-bin/bg6py687nqv2mbe6e1hdtk57h/gradle-4.10). Он охватывает практически все реальные случаи. Но что произойдет, если у пользователя еще нет рассылки?

Он / она может загрузить его вручную, используя URL-адрес в .propertiesфайле. Но если он / она не найдет его по пути, ожидаемому упаковщиком , оболочка загрузит его снова! Ожидаемый путь полностью предсказуем, но находится вне темы ( самую сложную часть см. Здесь ).

Есть также несколько более простых (но грязных) способов. Например, он / она может копировать файлы-оболочки (кроме .propertiesфайла) из любого другого локального / удаленного репозитория в свой репозиторий и затем запускать gradlewв своем репозитории. Он автоматически загрузит подходящий дистрибутив.

Мир-исмаилиты
источник
1

Согласно документации Gradle , добавление gradle-wrapper.jarв VCS ожидается, поскольку обеспечение доступности Gradle Wrapper для разработчиков является частью подхода Gradle:

Чтобы сделать файлы Wrapper доступными для других разработчиков и сред выполнения, вам необходимо проверить их в системе контроля версий. Все файлы Wrapper, включая файл JAR, имеют очень маленький размер. Добавление файла JAR в систему управления версиями ожидается. Некоторые организации не разрешают проектам отправлять двоичные файлы в систему контроля версий. На данный момент нет альтернативных вариантов подхода.

Артур Хазбс
источник
1

Старый вопрос, свежий ответ. Если вы не обновляете gradle часто (большинство из нас этого не делают), лучше передать его в VCS. И главная причина для меня - увеличить скорость сборки на CI-сервере. В настоящее время большинство проектов создаются и устанавливаются CI-серверами, каждый раз с разными экземплярами сервера.

Если вы не подтвердите это, сервер CI будет загружать jar для каждой сборки, что значительно увеличивает время сборки. Есть и другие способы решения этой проблемы, но я считаю, что этот способ проще всего поддерживать.

smgn
источник