Tôi đang viết một plugin gradle tùy chỉnh để xử lý một số công việc phức tạp mơ hồ và tôi đã gặp sự cố bực bội trong khi sử dụng các thuộc tính để định cấu hình một số tác vụ mà plugin áp dụng.Tiện ích mở rộng gradle có thể xử lý đánh giá lười biếng của một thuộc tính không?
apply plugin: myPlugin
//Provide properties for the applied plugin
myPluginProps {
message = "Hello"
}
//Define a task that uses my custom task directly
task thisTaskWorksFine(type: MyTask) {
input = myPluginProps.message
}
//Define a plugin that will apply a task of my custom type
class MyPlugin implements Plugin<Project> {
void apply(Project project) {
project.extensions.create('myPluginProps', MyPluginExtension)
project.task(type: MyTask, 'thisTaskWorksIncorrectly') {
input = project.myPluginProps.message
}
}
}
//The extension used by my custom plugin to get input
class MyPluginExtension {
def String message
}
//The task used by both the standard build section and the plugin
class MyTask extends DefaultTask {
def String input
@TaskAction
def action() {
println "You gave me this: ${input}"
}
}
Kết quả từ việc sử dụng tập tin này như sau:
$ gradle thisTaskWorksFine thisTaskWorksIncorrectly
:thisTaskWorksFine
You gave me this: Hello
:thisTaskWorksIncorrectly
You gave me this: null
BUILD SUCCESSFUL
Tôi coi đây là rất bất ngờ. Để tâm trí của tôi, việc áp dụng một nhiệm vụ từ các plugin và viết một trực tiếp nên kết quả trong cùng một đầu ra khi đưa ra cùng một đầu vào. Trong trường hợp này, cả hai nhiệm vụ đều được cung cấp myPluginProps.message
làm đầu vào, nhưng tác vụ được áp dụng bởi plugin là tham lam và đánh giá thành null sớm. (Trong quá trình áp dụng giai đoạn?)
Giải pháp duy nhất tôi đã tìm thấy là sử dụng đóng cửa trong khối cấu hình các nhiệm vụ plugin như vậy:
//Define a plugin that will apply a task of my custom type
class MyPlugin implements Plugin<Project> {
void apply(Project project) {
project.extensions.create('myPluginProps', MyPluginExtension)
project.task(type: MyTask, 'thisTaskWorksIncorrectly') {
input = { project.myPluginProps.message }
}
}
}
Đó giải quyết vấn đề thẩm định tham lam khá độc đáo trừ mà bây giờ nhiệm vụ tùy chỉnh phải được sửa đổi để mong đợi và xử lý việc đóng cửa. Nó không phải là khó khăn để làm, nhưng tôi không nghĩ rằng nó phải là trách nhiệm của nhiệm vụ để đối phó với việc đóng cửa, kể từ khi plugin là "đổ lỗi".
Tôi có đang sử dụng tiện ích không chính xác tại đây không? Hoặc là họ chỉ không đủ? Quan điểm chính thức có vẻ như là we should use extensions nhưng tôi chưa tìm thấy bất kỳ ví dụ nào mà tiện ích mở rộng có thể làm những gì tôi cần. Tôi có thể di chuyển về phía trước với việc sử dụng các bao đóng và viết một loạt các getters boilerplate mà đóng cửa eval và setters có thể xử lý các bao đóng và các loại bình thường, nhưng nó có vẻ rất chống lại triết lý của groovy và do đó gradle. Tôi sẽ rất hạnh phúc nếu có một cách mà tôi có thể sử dụng phần mở rộng và nhận được đánh giá lười biếng tự động.
Có sự khác biệt nào giữa bản đồ quy ước và quy ước không? Câu trả lời của bạn trông khá trơn, vì vậy tôi gần như chắc chắn sẽ sử dụng nó, nhưng một trong những devs lõi đã nói "Trong ngắn hạn, chỉ sử dụng phần mở rộng, không sử dụng công ước." Có lẽ tôi đã làm điều đó quá nghĩa đen. –
[quy ước] (http://www.gradle.org/docs/current/dsl/org.gradle.api.Project.html#org.gradle.api.Project:convention) mà Peter đang đề cập là cơ chế cũ cho tiện ích. Sự khác biệt là bạn nhận được dsl ('myPluginProps {message =" Hello "}') miễn phí với các phần mở rộng và bạn không nhận được chúng với các quy ước.Các quy ước và ánh xạ quy ước là hai thứ khác nhau và ánh xạ quy ước được sử dụng trong nội bộ trong [mã gradle] (https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/groovy/org/gradle/ api/plugins/JavaPlugin.java # L131) rất nhiều. – erdi
Tuyệt vời. Trong nghiên cứu của tôi, tôi đã né tránh mọi thứ đã đề cập đến quy ước từ, nhưng điều đó thật vội vàng. Cảm ơn vì lời khuyên! –