On Thu, Feb 10, 2011 at 6:38 PM, Adam Murdoch <[email protected]> wrote:

>
> On 10/02/2011, at 10:36 PM, Peter Niederwieser wrote:
>
>
> I fully agree that we need to solve this problem. However, I'd rather not
> want to be forced into creating a class around a dynamic property.
>
>
> Thinking about it, 'dynamic properties' is probably the wrong term for us
> to use. I think we're actually after a way to statically declare additional
> properties and methods for domain objects. I use 'static' in the sense that
> one can infer from the build language that these properties exist and are
> usable in the build script, without having to actually run the build script.
> For example, the declarative statement: apply plugin: 'java' infers that the
> project has a 'sourceCompatibility' property. Or that there is a 'runtime'
> configuration, and so on. You don't need to run the build script to know
> this.
>
> It would be nice if our solution to this problem lends itself to static
> analysis. This allows us to:
>
> * Generate documentation for the build.
>
> * Validate that appropriate values have been provided, before actually
> running the script. Project properties are often used to implement the
> configurable aspects of a build, where the user must provide a value as
> input for the build. For example, if the script declares a 'java5Home'
> property with no default value, Gradle can complain when no value has been
> provided before running the script. The means you don't need defensive
> if(hasProperty()) checks in your script.
>
> * Building on the above, Gradle can prompt for missing values, or give you
> a useful message in the help page, or display a build configuration wizard
> in the IDE or CI config UI, or offer other UIs for visualising and managing
> your build configuration.
>
> * Offer code completion when authoring build scripts.
>
> I wonder if we can simplify the problem by offering a dsl convenience only
> for project properties. You'd be able to use the convention object mechanism
> for all types (including project), but for the project (and only the
> project) we also offer a convenience mechanism.
>

I think almost every Gradle enterprise build done well will end up at one
point with custom properties for tasks or dependencies. We should make this
a first class concept also in terms of DSL. You could argue that you can
hide the non-convenience behind a plugin. But also a plugin should be as
readable as possible.


> We actually want to have some way to declare: domain object o has a
> property with the given name, type, default value, description, and
> constraints. Using a convention object provides natural places for all this
> stuff:
>
> class MyConfig {
>     /** description */
>    @Constraint1
>    Type name = defaultValue
> }
>
>
> One
> alternative would be to require the use of a "dyn" namespace for setting
> dynamic properties (somewhat similar to your properties block):
>
> dyn.foo = 3
> ...
> println foo // no qualification needed
>
>
> This feels like pretty much the same thing. A general pattern we have in
> the DSL is to allow either
>
> <namespace>.someProp = value
>
> or
>
> <namespace> {
>     someProp = value
> }
>
> (and sometimes <namespace> someProp: value, but that's a different issue)
>
> So, we would probably just handle both options.
>
>
>
> Another approach would be to reserve the "foo = bar" syntax for dynamic
> properties, and do all configuration with "foo bar":
>
> exec {
>  executable "my.exe"
>  args "one", "two"
>  foo = bar
> }
>
> This would make for a nice visual distinction between the declarative and
> imperative.
>
>
> I think there are a few issues with this approach:
>
> * Currently, for multi-valued properties, 'foo bar' will add 'bar' to the
> collection, and 'foo = bar' replaces the contents of foo with [bar]. We'd
> need to come up with a new syntax for handling multi-valued properties
> (which is fine - I don't 100% like the existing syntax anyway).
>
> * It feels like this might be more difficult to do static analysis for,
> given that assignment will still work the usual way in the imperative
> portions of the build script.
>
> * We might want the value provided on the rhs of the assignment to be a
> default value, so that it is only used if a value has not already been
> provided (eg using -P or gradle.properties). Overriding the semantics of
> assignment might be stretching too far.
>

I think we want to make it very visible if a custom property is declared. It
is about extending the Grade DSL which should be a prominent operation. It
is nothing you usually do 1000 times in a build in which case you wanted it
to make it a short as possible. Rather the opposite.

Hans

--
Hans Dockter
Founder, Gradle
http://www.gradle.org, http://twitter.com/gradleorg
CEO, Gradle Inc. - Gradle Training, Support, Consulting
http://www.gradle.biz


>
>
> Actually I have something bigger in mind here (more flexible
> mapping between DSL and domain model), but I don't want to distract from
> the
> current discussion.
>
>
> Go on. You can't not talk about it now you've mentioned it :)
>
>
> --
> Adam Murdoch
> Gradle Developer
> http://www.gradle.org
> CTO, Gradle Inc. - Gradle Training, Support, Consulting
> http://www.gradle.biz
>
>

Reply via email to