Как добавить вложенную коллекцию в расширение - PullRequest
0 голосов
/ 29 мая 2020

впервые в Gradle. У меня есть этот простой плагин с расширением, которое позволяет мне писать собственный DSL:

import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction

apply plugin: NeighborhoodPlugin

class Street {
    String name
    String type

    public Street(name) {
        this.name = name
    }
}

class Neighborhood {
    final NamedDomainObjectContainer<Street> streets
    def name

    public Neighborhood(streets) {
        this.streets = streets
    }

    def streets(Closure closure) {
        streets.configure(closure)
    }
}

// Plugin
class NeighborhoodPlugin implements Plugin<Project> {
    void apply(Project project) {
        // Create the NamedDomainObjectContainers
        def streets = project.container(Street);

        //https://docs.gradle.org/current/dsl/org.gradle.api.plugins.ExtensionAware.html
        def neighborhoodExt = project.extensions.create( 'neighborhood', Neighborhood, streets )
    }
}


neighborhood {
    name = 'My neighborhood'
    streets {
        street1 {
            type = 'T'
        }
        street2 {
            type = 'round'
        }
    }
}

task show {
    doLast {
        println "${neighborhood.name} has ${neighborhood.streets.toArray().length} streets"
    }
}

Кажется, что вышесказанное работает. Но я хотел бы расширить DSL, добавив Houses к Streets. Примерно так:

import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction

apply plugin: NeighborhoodPlugin

class House {
    String name
    String address

    public House(name) {
        this.name = name
    }
}

class Street {
    final NamedDomainObjectContainer<House> houses
    String name
    String type

    public Street(name) {
        this.name = name
    }
}

class Neighborhood {
    final NamedDomainObjectContainer<Street> streets
    def name

    public Neighborhood(streets) {
        this.streets = streets
    }

    def streets(Closure closure) {
        streets.configure(closure)
    }
}

// Plugin
class NeighborhoodPlugin implements Plugin<Project> {
    void apply(Project project) {
        // Create the NamedDomainObjectContainers
        def streets = project.container(Street);

        //https://docs.gradle.org/current/dsl/org.gradle.api.plugins.ExtensionAware.html
        def neighborhoodExt = project.extensions.create( 'neighborhood', Neighborhood, streets )
    }
}

neighborhood {
    name = 'My neighborhood'
    streets {
        street1 {
            type = 'T'
            houses {
                blueHouse {
                    address = '100 main'
                }
            }
        }
        street2 {
            type = 'round'
        }
    }
}

task show {
    doLast {
        println "${neighborhood.name} has ${neighborhood.streets.toArray().length} streets"
    }
}

Я пробовал разные комбинации вещей, но так и не смог заставить это работать. Ошибка всегда: No signature of method: build_ch0yxyi3isqke8j97jxnsaw72.neighborhood() is applicable for argument types.

Любая помощь очень ценится.

1 Ответ

0 голосов
/ 29 мая 2020

Это работает, и я получил его от: https://mrhaki.blogspot.com/2016/02/gradle-goodness-using-nested-domain.html:

import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction

apply plugin: NeighborhoodPlugin

class House {
    String name
    String address

    public House(name) {
        this.name = name
    }
}

class Street {
    NamedDomainObjectContainer<House> houses
    String name
    String type

    public Street(name) {
        this.name = name
    }

    def houses(Closure closure) {
        houses.configure(closure)
    }
}

class Neighborhood {
    final NamedDomainObjectContainer<Street> streets
    def name

    public Neighborhood(streets) {
        this.streets = streets
    }

    def streets(Closure closure) {
        streets.configure(closure)
    }
}

// Plugin
class NeighborhoodPlugin implements Plugin<Project> {
    void apply(Project project) {

        // Create the NamedDomainObjectContainers
        def streets = project.container(Street);

        streets.all {
            houses = project.container(House)
        }

        //https://docs.gradle.org/current/dsl/org.gradle.api.plugins.ExtensionAware.html
        def neighborhoodExt = project.extensions.create( 'neighborhood', Neighborhood, streets )
    }
}


neighborhood {
    name = 'My neighborhood'
    streets {
        main {
            type = 'Cul de-sac'
            houses {
                blueHouse {
                    address = '100 main'
                }
                pinkHouse {
                    address = '101 main'
                }
                greenHouse {
                    address = '103 main'
                }
            }
        }
        round {
            type = 'Round'
            houses {
                yellowHouse {
                    address = '100 round'
                }
                greenHouse {
                    address = '101 round'
                }
            }
        }
    }
}

task show {
    doLast {
        println "${neighborhood.name} has ${neighborhood.streets.toArray().length} streets"
        neighborhood.streets.all {
            println "--> name: ${name}"
            houses.all {
                println "--> --> name: ${name} address: ${address}"
            }
        }
    }
}
...