Hi,

Just revisiting the old 'how do we deal with names for domain objects' question.

Currently, our polymorphic container is-a NamedDomainObjectContainer. As such 
it forces every domain object to have a unique name. The problem with this 
approach is that I need to encode the type into the name.

For example, we are planning to use a `binaries` container to own all the 
binaries produced by the project. If I have a `main` Java library, then we need 
to add (by convention) a `mainClasses` ClassesDirectory binary and a `mainJar` 
Jar binary for this library. If I have a `main` Groovy library built for Groovy 
1.8 and Groovy 2.0, then I need to add `mainGroovy18Classes` and 
`mainGroovy20Classes` and `mainGroovy18Jar` and `mainGroovy20Jar`. If I have a 
`main` C library built for windows and linux with 32-bit and 64-bit and static 
and shared and debug and release variants, well… then we need lots of names.

I'd like to change things so we can get rid of the type from the name. This, of 
course, still leaves the other dimensions packed into the name. We don't have a 
good solution for this yet, but I suspect one will emerge.

The approach I'd like to take (which isn't a new idea - can't remember who 
suggested it) is to make (name, type) the unique identifier for a thing.

The DSL for defining an object would change from this:

binaries {
    mainStaticLibrary(StaticLibraryBinary) { … }
    mainSharedLibrary(SharedLibraryBinary) { … }
}

To:

binaries {
    staticLibraries {
        main { … }
    }
    sharedLibraries {
        main { … }
    }
}

Also:

publications {
    maven { 
        main { … }
    }
    ivy { 
        main { … }
    }
}


To find something:

// look something up by name
def main = binaries.main  // fails if there are multiple binaries with name 
`main`

// look something up by type and name
def main = binaries.staticLibraries.main

// look something up by super type and name
def main = binaries.nativeLibraries.main // fails if there are multiple native 
libraries with name `main`

// look up all things by type
def libs = binaries.staticLibraries

And to deal with the other dimensions, you'd use the existing collection stuff:

// All windows static libs
def libs = binaries.staticLibraries.matching { it.platform.operatingSystem == 
operatingSystems.windows }

We can come up with conveniences for the other dimensions. Perhaps a map-based 
selector:

def libs = binaries.staticLibraries(platform.operatingSystem: 
operatingSystems.windows)

Thoughts? I don't think this plan quite gets it right, but it feels better than 
the current DSL.


--
Adam Murdoch
Gradle Co-founder
http://www.gradle.org
VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
http://www.gradleware.com

Join us at the Gradle Summit 2013, June 13th and 14th in Santa Clara, CA: 
http://www.gradlesummit.com

Reply via email to