Mengapa Gradle Wrapper harus berkomitmen untuk VCS?

148

Dari dokumentasi Gradle: https://docs.gradle.org/current/dsl/org.gradle.api.tasks.wrapper.Wrapper.html

Skrip yang dihasilkan oleh tugas ini dimaksudkan untuk dikomit ke sistem kontrol versi Anda. Tugas ini juga menghasilkan file JAR bootstrap gradle-wrapper.jar kecil dan file properti yang juga harus berkomitmen untuk VCS Anda. Script mendelegasikan ke JAR ini.

Dari: Apa yang TIDAK boleh berada di bawah kendali sumber?

Saya pikir Generated filestidak boleh di VCS.

Kapan gradlewdan gradle/gradle-wrapper.jardibutuhkan?

Mengapa tidak menyimpan gradle versiondalam build.gradlefile?

petani1992
sumber
1
Apa yang mungkin menjadi diskusi sampingan yang menarik, mengingat jawaban di bawah ini, adalah kegunaan file-file ini jika Anda menggunakan beberapa bentuk alat integrasi berkelanjutan. Yang mana yang akan memeriksa grade-wrapper dan menggunakannya jika ada di sana?
lilbyrdie

Jawaban:

124

Karena seluruh inti dari pembungkus gradle adalah untuk dapat, tanpa pernah menginstal gradle, dan bahkan tanpa mengetahui cara kerjanya, di mana untuk mengunduhnya, dari versi mana, untuk mengkloning proyek dari VCS, untuk mengeksekusi skrip gradlew berisi, dan untuk membangun proyek tanpa langkah tambahan apa pun.

Jika semua yang Anda miliki adalah nomor versi gradle dalam file build.gradle, Anda memerlukan README yang menjelaskan kepada semua orang bahwa gradle versi X harus diunduh dari URL Y dan diinstal, dan Anda harus melakukannya setiap kali versinya bertambah.

JB Nizet
sumber
94
Itu bodoh. gradle-wrapper.jar seharusnya tidak diperlukan di VCS. Gradle seharusnya dapat mengunduh versi apa pun setelah Anda menginstal yang pertama, jika perlu. Toolchain tidak ada hubungannya dengan VCS ... Saya mengerti jawaban Anda benar, dan itu desain Gradle. Tapi desain ini tidak masuk akal.
Marc Plano-Lesay
26
Intinya adalah untuk dapat mengunduh gradle tanpa menginstal gradle sebelumnya. Apa masalahnya memiliki file berukuran besar 50KB di VCS?
JB Nizet
59
Masalahnya adalah itu bukan bagian dari proyek. Ini alat yang Anda gunakan untuk membangun proyek. Anda tidak akan menyimpan JDK di VCS, bukan? Atau GCC untuk aplikasi C? Jadi mengapa Anda menyimpan bagian Gradle? Jika seorang pengembang tidak dapat membaca dan menginstal Gradle sendiri, itu masalah lain.
Marc Plano-Lesay
26
Masalahnya adalah Anda tidak dapat mengingatnya, 2 tahun setelah dirilis, versi Gradle mana yang digunakan untuk membangun versi perangkat lunak v1.0 Anda, yang harus Anda hotfix untuk pelanggan yang masih menggunakan 1.0 ini versi dan tidak dapat ditingkatkan. Wrapper gradle memecahkan bahwa: Anda mengkloning tag 1.0 dari VCS, membuatnya menggunakan gradlew, dan itu menggunakan versi gradle yang digunakan 2 tahun lalu untuk membangun versi 1.0.
JB Nizet
33
Saya setuju bahwa versi Gradle yang akan digunakan perlu ditunjukkan di suatu tempat dalam proyek. Tetapi Gradle adalah alat eksternal , tidak ada yang sebanding dengan README atau apa pun yang Anda daftarkan. Gradle harus dapat mengambil versi yang sesuai itu sendiri, tanpa harus menyimpan toples di VCS.
Marc Plano-Lesay
80

Karena seluruh titik pembungkus gradle adalah untuk dapat, tanpa pernah menginstal gradle

Argumen yang sama berlaku untuk JDK, apakah Anda ingin melakukan itu juga? Apakah Anda juga melakukan semua perpustakaan dependencie Anda?

Ketergantungan harus ditingkatkan terus menerus saat versi baru dirilis. Untuk mendapatkan keamanan dan perbaikan bug lainnya. Dan karena jika Anda sampai jauh di belakang, itu bisa menjadi tugas yang sangat memakan waktu untuk mendapatkan yang terbaru.

Jika pembungkus gradle bertambah untuk setiap rilis baru, dan itu berkomitmen, repo akan tumbuh sangat besar. Masalahnya jelas ketika bekerja dengan VCS terdistribusi di mana klon akan mengunduh semua versi dari segalanya.

, dan bahkan tanpa mengetahui cara kerjanya

Buat skrip build yang mengunduh wrapper dan menggunakannya untuk membangun. Setiap orang tidak perlu tahu bagaimana skrip bekerja, mereka harus setuju bahwa proyek dibangun dengan menjalankannya.

, dari mana untuk mengunduhnya, dari versi mana

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

Lalu

gradle wrapper

Untuk mengunduh versi yang benar.

, untuk mengkloning proyek dari VCS, untuk mengeksekusi skrip gradlew yang dikandungnya, dan untuk membangun proyek tanpa langkah tambahan.

Dipecahkan oleh langkah-langkah di atas. Mengunduh pembungkus gradle tidak berbeda dengan mengunduh dependensi lainnya. Script bisa jadi pintar untuk memeriksa apakah ada pembungkus gradle saat ini dan hanya mengunduhnya jika ada versi baru.

Jika pengembang belum pernah menggunakan Gradle sebelumnya dan mungkin tidak mengetahui proyek ini dibangun dengan Gradle. Maka lebih jelas untuk menjalankan "build.sh" dibandingkan dengan menjalankan "gradlew build".

Jika yang Anda miliki hanyalah nomor versi gradle dalam file build.gradle, Anda memerlukan README yang menjelaskan kepada semua orang bahwa gradle versi X harus diunduh dari URL Y yang terpasang,

Tidak, Anda tidak perlu README. Anda dapat memilikinya, tetapi kami adalah pengembang dan kami harus mengotomatiskan sebanyak mungkin. Membuat skrip lebih baik.

dan Anda harus melakukannya setiap kali versi bertambah.

Jika pengembang setuju bahwa proses yang benar adalah:

  1. Klon repo
  2. Jalankan skrip pembuatan

Lalu ada peningkatan ke pembungkus gradle terbaru tidak masalah. Jika versi bertambah sejak dijalankan terakhir, skrip dapat mengunduh versi baru.

Tomas Bjerre
sumber
2
"Ketergantungan harus ditingkatkan terus menerus." Ya, dalam arah pandang ke depan. Tidak, dalam arah yang melihat ke belakang. Untuk mereproduksi bangunan lama, Anda harus memiliki versi dependensi tertentu. Gradle membuat beberapa jenis proyek lebih cepat dan lebih mudah untuk ditangani. Ini akan menjadi kekacauan dalam organisasi yang membutuhkan reproduksi dan audit.
lilbyrdie
3
Tidak begitu yakin apa yang Anda maksud. Tetapi jika Anda memiliki build.gradlekontrol versi dan di dalamnya Anda memiliki: task wrapper(type: Wrapper) { gradleVersion = 'X.X' } Kemudian gradle wrapperakan mengunduh bungkus yang digunakan, dan Anda dapat mereproduksi build lama.
Tomas Bjerre
1
Mengacu pada baris Anda tentang dependensi, bukan versi gradle. Tentu, Anda ingin perpustakaan Anda memiliki semua keamanan terbaru dan perbaikan bug tetapi TIDAK ketika Anda mencoba mereproduksi bangunan lama, mungkin untuk tujuan audit atau hukum. Anda ingin perpustakaan Anda dan proses pembangunan untuk dapat menghasilkan output identik biner, jika memungkinkan. Seperti halnya ketergantungan pada perpustakaan, tidak ada jaminan bahwa versi tertentu akan tersedia pada saat pembangunan ... baik itu 2 minggu dari sekarang atau 2 dekade dari sekarang. Jadi ya, itu sama dengan perpustakaan dan SDK, untuk beberapa proyek.
lilbyrdie
3
Saya pikir bungkusnya ada terutama karena alasan sejarah. Pada awalnya semua orang menggunakan Maven, dan tidak ada yang memasang Gradle. Akan sulit untuk membujuk rekan kerja untuk menginstal dependensi mengganggu yang tidak diketahui, sehingga bungkusnya membantu mereka melakukan bootstrap. Saat ini semua orang sudah memiliki Gradle, dan pembungkusnya menjadi mubazir.
Franklin Yu
1
Apakah Anda menyarankan untuk mengeksekusi gradle wrappersetelah mengkloning pada setiap build? Ini pada dasarnya membuat pembungkus tidak berguna, karena intinya adalah Anda tidak harus menginstal Gradle secara lokal untuk membangun proyek !
Xerus
41

Saya ingin merekomendasikan pendekatan sederhana.

Dalam README proyek Anda, dokumentasikan langkah pemasangan yang diperlukan, yaitu:

gradle wrapper --gradle-version 3.3

Ini berfungsi dengan Gradle 2.4 atau lebih tinggi. Ini menciptakan pembungkus tanpa memerlukan tugas khusus untuk ditambahkan ke "build.gradle".

Dengan opsi ini, abaikan (jangan laporkan) file / folder ini untuk kontrol versi:

  • ./gradle
  • gradlew
  • gradlew.bat

Manfaat utama adalah Anda tidak perlu check-in file yang diunduh ke kontrol sumber. Biayanya satu langkah ekstra pada instalasi. Saya pikir itu sepadan.

David J.
sumber
15
mengapa Anda membutuhkan pembungkus? Seluruh ide wrapper adalah bahwa Anda dapat membangun proyek tanpa memiliki gradle pada sistem Anda.
edio
4
Solusi bagus Tidak ada binari di git dan masih bisa digunakan gradlew. @edio Anda akan perlu untuk men-download dan menggunakan spesifik versi Gradle.
Kirill
3

Apa itu "proyek"?

Mungkin ada definisi teknis dari idiom ini yang mengecualikan skrip membangun. Tetapi jika kami menerima definisi ini, maka kami harus mengatakan "proyek" Anda tidak semua hal yang perlu Anda ubah versi!

Tetapi jika kami mengatakan "proyek Anda" adalah semua yang telah Anda lakukan . Maka kita dapat mengatakan Anda harus memasukkannya dan hanya itu ke dalam VCS.

Ini sangat teoretis dan mungkin tidak praktis jika pengembangan kami berjalan. Jadi kami mengubahnya menjadi " proyek Anda adalah setiap file (atau folder) yang Anda butuhkan untuk mengeditnya secara langsung ".

"secara langsung" berarti "tidak secara tidak langsung" dan "secara tidak langsung" berarti dengan mengedit file lain dan kemudian suatu efek akan tercermin ke dalam file ini .

Jadi kita mencapai hal yang sama seperti yang dikatakan OP (dan dikatakan di sini ):

Saya pikir file Generated tidak boleh dalam VCS.

Iya. Karena Anda belum membuatnya. Jadi mereka bukan bagian dari "proyek Anda" sesuai dengan definisi kedua.


Apa hasil dari file-file ini:

  • build.gradle : Ya. Kami perlu mengeditnya. Karya kami harus diversi.

    Catatan: Tidak ada perbedaan di mana Anda mengeditnya. Baik di lingkungan editor teks Anda atau di lingkungan Struktur Proyek GUI. Pokoknya Anda melakukannya secara langsung !

  • gradle-wrapper.properties : Ya. Setidaknya kita perlu menentukan versi Gradle dalam file ini.

  • gradle-wrapper.jar dan gradlew [.bat] : Saya belum membuat atau mengeditnya di salah satu karya pengembangan saya, sampai saat ini! Jadi jawabannya adalah "Tidak". Jika Anda telah melakukannya, jawabannya adalah "Ya" tentang Anda di kantor itu (dan tentang file yang sama yang Anda edit).


Catatan penting tentang kasing terakhir adalah pengguna yang mengkloning repo Anda, perlu menjalankan perintah ini di repo<root-directory> untuk menghasilkan berkas pembungkus otomatis :

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

$vdan $distTypeditentukan dari gradle-wrapper.properties :

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

Lihat https://gradle.org/install/ untuk informasi lebih lanjut.

gradleexecutable bin/gradle[.bat]dalam distribusi lokal. Tidak diperlukan bahwa distribusi lokal sama dengan yang ditentukan dalam repo. Setelah file wrapper dibuat maka gradlew[.bat]dapat mengunduh distribusi Gradle yang ditentukan secara otomatis (jika tidak ada secara lokal). Maka ia mungkin harus membuat ulang file wrapper menggunakan gradleexecutable baru (dalam distribusi yang diunduh) menggunakan instruksi di atas.


Catatan: Dalam instruksi di atas, seharusnya pengguna memiliki setidaknya satu distribusi Gradle secara lokal (mis ~/.gradle/wrapper/dists/gradle-4.10-bin/bg6py687nqv2mbe6e1hdtk57h/gradle-4.10.). Ini mencakup hampir semua kasus nyata. Tetapi apa yang terjadi jika pengguna belum memiliki distribusi?

Ia dapat mengunduhnya secara manual menggunakan URL dalam .propertiesfile. Tetapi jika dia tidak menemukannya di jalan yang diharapkan oleh pembungkus , pembungkus akan mengunduhnya lagi! Jalur yang diharapkan benar-benar dapat diprediksi tetapi berada di luar subjek (lihat di sini untuk bagian paling rumit).

Ada juga beberapa cara yang lebih mudah (tapi kotor). Sebagai contoh, ia dapat menyalin file pembungkus (kecuali .propertiesfile) dari repositori lokal / jauh ke repositori dan kemudian menjalankan gradlewrepositori. Secara otomatis akan mengunduh distribusi yang sesuai.

Mir-Ismaili
sumber
1

Menurut dokumen Gradle , menambah gradle-wrapper.jarVCS diharapkan karena membuat Gradle Wrapper tersedia bagi para pengembang adalah bagian dari pendekatan Gradle:

Untuk membuat file Wrapper tersedia untuk pengembang lain dan lingkungan eksekusi Anda harus memeriksanya ke dalam kontrol versi. Semua file Wrapper termasuk file JAR berukuran sangat kecil. Menambahkan file JAR ke kontrol versi diharapkan. Beberapa organisasi tidak mengizinkan proyek untuk mengirimkan file biner ke kontrol versi. Saat ini tidak ada pilihan alternatif untuk pendekatan tersebut.

Arthur Khazbs
sumber
1

Pertanyaan lama, jawaban segar. Jika Anda tidak sering memutakhirkan gradle (kebanyakan dari kita tidak), lebih baik komit ke VCS. Dan alasan utama bagi saya adalah untuk meningkatkan kecepatan build di server CI. Saat ini, sebagian besar proyek sedang dibangun dan diinstal oleh server CI, contoh server yang berbeda setiap waktu.

Jika Anda tidak melakukannya, server CI akan mengunduh toples untuk setiap build dan secara signifikan menambah waktu build. Ada cara lain untuk menangani masalah ini, tetapi saya menemukan ini yang paling mudah untuk dijaga.

smgn
sumber