Tại sao Gradle Wrapper phải được cam kết với VCS?


147

Từ tài liệu của Gradle: https://docs.gradle.org/civerse/dsl/org.gradle.api.t task.wrapper.Wrapper.html

Các tập lệnh được tạo bởi tác vụ này được dự định sẽ được cam kết với hệ thống kiểm soát phiên bản của bạn. Tác vụ này cũng tạo ra một tệp JAR và tệp thuộc tính bootstrap gradle-Wrapper.jar cũng nên được cam kết với VCS của bạn. Các kịch bản đại biểu cho JAR này.

Từ: Điều gì KHÔNG nên được kiểm soát nguồn?

Tôi nghĩ Generated fileskhông nên ở trong VCS.

Khi nào gradlewgradle/gradle-wrapper.jarcần thiết?

Tại sao không lưu trữ một gradle versiontrong các build.gradletập tin?


1
Điều có thể là một cuộc thảo luận bên lề thú vị, được đưa ra các câu trả lời dưới đây, là tính hữu ích của các tệp này nếu bạn đang sử dụng một số dạng công cụ tích hợp liên tục. Những cái nào sẽ kiểm tra lớp bọc và sử dụng nó nếu nó ở đó?
lilbyrdie

Câu trả lời:


124

Bởi vì toàn bộ điểm của trình bao bọc lớp là có thể, mà chưa bao giờ cài đặt lớp, và thậm chí không biết nó hoạt động như thế nào, tải xuống từ đâu, phiên bản nào, để sao chép dự án từ VCS, để thực thi tập lệnh gradlew chứa, và để xây dựng dự án mà không cần thêm bước nào.

Nếu tất cả những gì bạn có là số phiên bản cấp trong tệp build.gradle, bạn sẽ cần README giải thích cho mọi người rằng phiên bản cấp X phải được tải xuống từ URL Y và được cài đặt, và bạn sẽ phải làm điều đó mỗi khi phiên bản được tăng lên.


94
Thật là ngu xuẩn. gradle-Wrapper.jar không cần thiết trên VCS. Gradle sẽ có thể tải xuống bất kỳ phiên bản nào sau khi bạn cài đặt phiên bản đầu tiên, nếu cần. Chuỗi công cụ không có gì để làm trên một bản VCS Tôi hiểu câu trả lời của bạn là đúng và đó là thiết kế của Gradle. Nhưng thiết kế này là vô lý.
Marc Plano-Lesay 7/12/13

26
Vấn đề là có thể tải xuống lớp mà không cần cài đặt lớp trước. Có vấn đề gì khi có tệp lớn 50KB trong VCS?
JB Nizet

59
Vấn đề là nó không phải là một phần của dự án. Đó là một công cụ bạn sử dụng để xây dựng dự án. Bạn sẽ không lưu trữ JDK trong VCS chứ? Cũng không GCC cho một ứng dụng C? Vậy tại sao bạn lại lưu trữ một phần Gradle? Nếu một nhà phát triển không thể tự đọc và cài đặt Gradle, thì đó là một vấn đề khác.
Marc Plano-Lesay

26
Vấn đề cũng là bạn không thể nhớ, 2 năm sau khi nó được phát hành, phiên bản Gradle nào đã được sử dụng để xây dựng phiên bản v1.0 của phần mềm của bạn, mà bạn phải cập nhật cho một khách hàng vẫn đang sử dụng phiên bản 1.0 này phiên bản và không thể nâng cấp. Trình bao bọc lớp giải quyết rằng: bạn sao chép thẻ 1.0 từ VCS, xây dựng nó bằng gradlew và nó sử dụng phiên bản lớp được sử dụng 2 năm trước để xây dựng phiên bản 1.0.
JB Nizet

33
Tôi đồng ý rằng phiên bản Gradle được sử dụng cần được chỉ định ở đâu đó trong dự án. Nhưng Gradle là một công cụ bên ngoài , không có gì có thể so sánh với README hoặc bất cứ thứ gì bạn liệt kê. Gradle có thể tự tìm nạp phiên bản tương ứng mà không phải lưu trữ một jar trên VCS.
Marc Plano-Lesay

80

Bởi vì toàn bộ điểm của trình bao bọc lớp là có thể, mà không cần cài đặt lớp

Đối số tương tự cũng xảy ra với JDK, bạn có muốn cam kết điều đó không? Bạn cũng cam kết tất cả các thư viện phụ thuộc của bạn?

Các phụ thuộc phải được nâng cấp liên tục khi các phiên bản mới được phát hành. Để có được bảo mật và sửa lỗi khác. Và bởi vì nếu bạn đi xa phía sau, nó có thể là một nhiệm vụ rất tốn thời gian để cập nhật lại.

Nếu trình bao bọc lớp được tăng lên cho mỗi bản phát hành mới và được cam kết, repo sẽ phát triển rất lớn. Vấn đề là rõ ràng khi làm việc với VCS phân tán, nơi một bản sao sẽ tải xuống tất cả các phiên bản của mọi thứ.

và thậm chí không biết làm thế nào nó hoạt động

Tạo một tập lệnh xây dựng tải xuống trình bao bọc và sử dụng nó để xây dựng. Mọi người không cần biết kịch bản hoạt động như thế nào, họ cần phải đồng ý rằng dự án được xây dựng bằng cách thực hiện nó.

, tải về từ đâu, phiên bản nào

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

Và sau đó

gradle wrapper

Để tải phiên bản chính xác.

, để sao chép dự án từ VCS, để thực thi tập lệnh gradlew mà nó chứa và để xây dựng dự án mà không cần thêm bước nào.

Giải quyết bằng các bước trên. Tải xuống trình bao bọc lớp không khác với tải xuống bất kỳ phụ thuộc nào khác. Kịch bản có thể là enaugh thông minh để kiểm tra bất kỳ trình bao bọc lớp hiện tại nào và chỉ tải xuống nếu có phiên bản mới.

Nếu nhà phát triển chưa bao giờ sử dụng Gradle trước đây và có thể không biết dự án được xây dựng với Gradle. Sau đó, rõ ràng hơn để chạy một "build.sh" so với chạy "gradlew build".

Nếu tất cả những gì bạn có là số phiên bản lớp trong tệp build.gradle, bạn sẽ cần README giải thích cho mọi người rằng phiên bản lớp X phải được tải xuống từ URL Y được cài đặt,

Không, bạn sẽ không cần README. Bạn có thể có một, nhưng chúng tôi là nhà phát triển và chúng tôi nên tự động hóa càng nhiều càng tốt. Tạo một kịch bản là tốt hơn.

và bạn sẽ phải làm điều đó mỗi khi phiên bản được tăng lên.

Nếu các nhà phát triển đồng ý rằng quy trình chính xác là:

  1. Bản sao repo
  2. Chạy tập lệnh xây dựng

Sau đó, nâng cấp lên lớp bọc mới nhất là không có vấn đề. Nếu phiên bản được tăng lên kể từ lần chạy trước, tập lệnh có thể tải xuống phiên bản mới.


2
"Các phụ thuộc nên được nâng cấp liên tục." Vâng, trong một hướng nhìn về phía trước. Không, theo hướng nhìn lạc hậu. Để tái tạo một bản dựng cũ, bạn cần có các phiên bản cụ thể của các phụ thuộc. Gradle làm cho một số loại dự án nhanh hơn và dễ dàng hơn để giải quyết. Nó sẽ là một mớ hỗn độn trong một tổ chức cần tái sản xuất và kiểm toán.
lilbyrdie

3
Không thực sự chắc chắn những gì bạn có ý nghĩa. Nhưng nếu bạn có build.gradlequyền kiểm soát phiên bản và trong đó bạn có: task wrapper(type: Wrapper) { gradleVersion = 'X.X' } Sau đó gradle wrappersẽ tải xuống trình bao bọc đã được sử dụng và bạn có thể sao chép bản dựng cũ.
Tomas Bjerre

1
Đã đề cập đến dòng của bạn về các phụ thuộc, không phải phiên bản lớp. Chắc chắn, bạn muốn thư viện của mình có tất cả các bản sửa lỗi và bảo mật mới nhất nhưng KHÔNG khi bạn cố gắng tạo lại bản dựng cũ, có thể cho mục đích kiểm toán hoặc pháp lý. Bạn muốn các thư viện của mình và xây dựng quy trình để có thể tạo ra một đầu ra giống hệt nhị phân, nếu có thể. Như với một phụ thuộc thư viện, không có gì đảm bảo rằng một phiên bản cụ thể sẽ có sẵn tại thời điểm xây dựng ... có thể là 2 tuần kể từ bây giờ hoặc 2 thập kỷ kể từ bây giờ. Vì vậy, có, nó giống như các thư viện và SDK, đối với một số dự án.
lilbyrdie

3
Tôi nghĩ rằng bao bọc chủ yếu là vì lý do lịch sử. Ban đầu, mọi người đều sử dụng Maven và không ai cài đặt Gradle. Sẽ rất khó để thuyết phục đồng nghiệp cài đặt các phụ thuộc xâm nhập không xác định, vì vậy trình bao bọc giúp họ bootstrap. Ngày nay mọi người đều đã có Gradle rồi, và trình bao bọc trở nên dư thừa.
Franklin Yu

1
Bạn đang đề nghị thực hiện gradle wrappersau khi sao chép trên mỗi bản dựng? Điều này về cơ bản làm cho trình bao bọc trở nên vô dụng, bởi vì toàn bộ quan điểm của bạn là bạn không phải cài đặt Gradle cục bộ để xây dựng dự án !
Xerus

41

Tôi muốn giới thiệu một cách tiếp cận đơn giản.

Trong README của dự án của bạn, tài liệu yêu cầu một bước cài đặt, cụ thể là:

gradle wrapper --gradle-version 3.3

Điều này hoạt động với Gradle 2.4 trở lên. Điều này tạo ra một trình bao bọc mà không yêu cầu một tác vụ chuyên dụng được thêm vào "build.gradle".

Với tùy chọn này, bỏ qua (không đăng nhập) các tệp / thư mục này để kiểm soát phiên bản:

  • ./ Nâng cấp
  • lớp
  • gradlew.bat

Lợi ích chính là bạn không phải đăng ký tệp đã tải xuống để kiểm soát nguồn. Nó chi phí thêm một bước khi cài đặt. Tôi nghĩ điều đó chắc chắn.


15
Tại sao bạn lại cần bọc? Toàn bộ ý tưởng của trình bao bọc là bạn có thể xây dựng dự án mà không cần phân lớp trên hệ thống của mình.
edio

4
Giải pháp tốt đẹp. Không có nhị phân trong git và vẫn có khả năng sử dụng gradlew. @edio bạn sẽ cần nó để tải xuống và sử dụng một phiên bản cụ thể của lớp.
Kirill

3

"Dự án" là gì?

Có thể có một định nghĩa kỹ thuật của thành ngữ này không bao gồm các tập lệnh xây dựng. Nhưng nếu chúng tôi chấp nhận định nghĩa này, thì chúng tôi phải nói rằng "dự án" của bạn không phải là tất cả những thứ bạn cần để phiên bản!

Nhưng nếu chúng tôi nói "dự án của bạn" là mọi thứ bạn đã làm . Sau đó, chúng tôi có thể nói bạn phải đưa nó vào và chỉ đưa nó vào VCS.

Điều này rất lý thuyết và có thể không thực tế trong trường hợp các công trình phát triển của chúng tôi. Vì vậy, chúng tôi thay đổi nó thành " dự án của bạn là mỗi tệp (hoặc thư mục) bạn cần chỉnh sửa trực tiếp ".

"Trực tiếp" có nghĩa là "không gián tiếp" và "gián tiếp" có nghĩa là bằng cách chỉnh sửa một tệp khác và sau đó một hiệu ứng sẽ được phản ánh vào tệp này .

Vì vậy, chúng tôi đạt được điều tương tự mà OP đã nói (và được nói ở đây ):

Tôi nghĩ rằng các tệp đã tạo không nên có trong VCS.

Đúng. Bởi vì bạn đã không tạo ra chúng. Vì vậy, chúng không phải là một phần của "dự án của bạn" theo định nghĩa thứ hai.


Kết quả về những tập tin này là gì:

  • xây dựng.gradle : Có. Chúng ta cần chỉnh sửa nó. Các tác phẩm của chúng tôi nên được phiên bản.

    Lưu ý: Không có sự khác biệt nơi bạn chỉnh sửa nó. Cho dù trong môi trường soạn thảo văn bản của bạn hoặc trong môi trường GUI Cấu trúc dự án . Dù sao bạn làm nó trực tiếp !

  • gradle-wrapper.properies : Có. Chúng ta cần xác định ít nhất phiên bản Gradle trong tệp này.

  • gradle-Wrapper.jargradlew [.bat] : Tôi chưa tạo hoặc chỉnh sửa chúng trong bất kỳ tác phẩm phát triển nào của tôi, cho đến thời điểm này! Vì vậy, câu trả lời là không". Nếu bạn đã làm như vậy, câu trả lời là "Có" về bạn tại công việc đó (và về cùng một tệp bạn đã chỉnh sửa).


Các lưu ý quan trọng về trường hợp mới nhất là người dùng bắt chước repo của bạn, cần phải thực hiện lệnh này trên repo của<root-directory> để tự động tạo wrapper file:

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

$v$distTypeđược xác định từ gradle-wrapper.properies :

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

Xem https://gradle.org/install/ để biết thêm thông tin.

gradlethực thi là bin/gradle[.bat]trong phân phối địa phương. Không yêu cầu phân phối cục bộ giống như phân phối trong repo. Sau khi các tệp bao bọc được tạo thì gradlew[.bat]có thể tự động tải xuống phân phối Gradle xác định (nếu không tồn tại cục bộ). Sau đó, anh ấy / cô ấy có thể phải tạo lại các tệp bao bọc bằng cách sử dụng gradletệp thực thi mới (trong bản phân phối được tải xuống) bằng các hướng dẫn ở trên.


Lưu ý: Trong các hướng dẫn ở trên, giả sử người dùng có ít nhất một bản phân phối Gradle cục bộ (ví dụ ~/.gradle/wrapper/dists/gradle-4.10-bin/bg6py687nqv2mbe6e1hdtk57h/gradle-4.10). Nó bao gồm hầu hết các trường hợp thực tế. Nhưng điều gì xảy ra nếu người dùng chưa có bất kỳ phân phối nào?

Anh ấy / Cô ấy có thể tải xuống bằng tay bằng cách sử dụng URL trong .propertiestệp. Nhưng nếu anh ấy / cô ấy không tìm thấy nó trong đường dẫn mà trình bao bọc mong đợi, trình bao bọc sẽ tải xuống lại! Đường dẫn dự kiến ​​là hoàn toàn có thể dự đoán được nhưng nằm ngoài chủ đề (xem ở đây để biết phần phức tạp nhất).

Cũng có một số cách dễ dàng hơn (nhưng bẩn). Ví dụ, anh ấy / cô ấy có thể sao chép các tệp bao bọc (trừ .propertiestệp) từ bất kỳ kho lưu trữ cục bộ / từ xa nào khác vào kho lưu trữ của anh ấy / cô ấy và sau đó chạy gradlewtrên kho lưu trữ của anh ấy / cô ấy. Nó sẽ tự động tải về bản phân phối phù hợp.


0

Theo tài liệu của Gradle , việc thêm gradle-wrapper.jarvào VCS được kỳ vọng là làm cho Gradle Wrapper có sẵn cho các nhà phát triển là một phần của phương pháp Gradle:

Để cung cấp các tệp Wrapper cho các nhà phát triển và môi trường thực thi khác, bạn cần kiểm tra chúng trong kiểm soát phiên bản. Tất cả các tệp Wrapper bao gồm tệp JAR có kích thước rất nhỏ. Thêm tệp JAR vào kiểm soát phiên bản được mong đợi. Một số tổ chức không cho phép các dự án gửi tệp nhị phân để kiểm soát phiên bản. Hiện tại không có lựa chọn thay thế cho cách tiếp cận.


0

Câu hỏi cũ, câu trả lời mới. Nếu bạn không nâng cấp lớp thường xuyên (hầu hết chúng ta không), tốt hơn hết là bạn nên cam kết với VCS. Và lý do chính đối với tôi là để tăng tốc độ xây dựng trên máy chủ CI. Ngày nay, hầu hết các dự án đang được xây dựng và cài đặt bởi các máy chủ CI, ví dụ máy chủ khác nhau mỗi lần.

Nếu bạn không cam kết, máy chủ CI sẽ tải xuống một jar cho mỗi bản dựng và nó làm tăng đáng kể thời gian xây dựng. Có nhiều cách khác để xử lý vấn đề này, nhưng tôi thấy đây là cách dễ nhất để duy trì.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.