On 9 April 2014 at 10:31:29 am, Adam Murdoch
(adam.murd...@gradleware.com(mailto:adam.murd...@gradleware.com)) wrote:
>
> On 9 Apr 2014, at 9:12 am, Luke Daley wrote:
> > On 9 April 2014 at 5:23:35 am, Peter Niederwieser
> > (pnied...@gmail.com(mailto:pnied...@gmail.com)) wrote:
> > > All,
> > >
> > > as we are improving component metadata rules, we need a way for a rule to
> > >
> > > declare which metadata it is interested in. The current proposal is to do
> > >
> > > this via typed callback parameters. For example:
> > >
> > > dependencies {
> > > components {
> > > eachComponent { ComponentMetaDataDetails details,
> > > IvyModuleDescriptor descriptor -> ... }
> > > }
> > > }
> > >
> > > The rule above declares that it is interested in the generic metadata
> > > (`ComponentMetaDataDetails`) and Ivy specific metadata
> > > (`IvyModuleDescriptor`). Because it is interested in Ivy specific
> > > metadata,
> > > the rule will only fire for Ivy components.
> > >
> > > The set of potentially supported parameter types is open-ended. For
> > > example,
> > > future Gradle versions may support a `ArtifactoryProperties` parameter
> > > type.
> > >
> > > This raises some questions:
> > >
> > > * The above looks very much like a model rule. (`details` is the object
> > > to
> > > be mutated, `descriptor` is an input.) Should `eachComponent()` indeed
> > > accept a `ModelRule`, now or in the future?
> > > * If not, what should the Java API look like?
> > > * Do we want to generate the closure-based Groovy API from the Java API,
> > > now
> > > or in the future?
> > >
> > > For the time being, I've hand-coded the Groovy API, but obviously we also
> > >
> > > need a Java API.
> > >
> > > Thanks for any insights.
> >
> > Not sure it’s insightful, but here goes…
> >
> >
> > This is slightly different to the model rules we’ve implemented to date,
> > but not different to the types of rules we’ve discussed or conceptualised.
> >
> >
> > Disclaimer: I don’t have a good understand of the component model, so I
> > could be well off with what I’m about to say.
> >
> >
> > My understand is that conceptually we are transforming things (modules?)
> > into components, and this hook allows you to augment how that should be
> > done. So internally, there is a model rule that knows how to create
> > components from module descriptors (roughly). We want to supply extra
> > configuration to the created components, based on how they were created
> > (i.e. what type of module descriptor they were created from). So, this is a
> > model rule where the bindings are relative to the rule the created the
> > thing to mutate.
> >
> >
> > We currently don’t have any implementation for partially (potential other
> > names: speculatively, relatively) bound rules. Currently, the rule itself
> > dictates how it is bound to the model. In this case, The same rule can be
> > reused and be bound to different elements each time because the bindings
> > are not absolute. So, this is some context specific sugar that would
> > somehow create many absolutely bound rules (in some form) from the
> > partially bound rule.
> >
> >
> > In terms of API, the complication here is that there are constraints on the
> > rule. It can only mutate a ComponentMetaDataDetails. Arbitrary targets
> > don’t make sense. I can’t see an easy way to express “first argument must
> > be , but the rest are any ”. Java’s type system isn’t up for this. We are
> > going to have this problem generally for the model rules of course.
> >
> >
> >
>
> This is a pretty good summary, I reckon.
>
> I’d tweak it a little:
>
> 1. The rule takes as input the default meta-data for the component, and it
> can mutate this meta-data however it likes.
> 2. The rule may also take as input some stuff about the source of the
> component.
> 3. The rule may also take as input any arbitrary model object.
>
> For #2, we have some Ivy meta-data and later maybe some other things like
> artifactory properties and maybe some maven stuff.
>
> For #3, we might have a custom model, for example a set of black-listed
> versions from some service, or perhaps a set of versions that have passed
> some CI build stage.
>
> At this stage, we don’t really care about #3, but we do want to aim for the
> situation where rules can take arbitrary inputs, some of which might be
> expensive to calculate. I think we want to wait until we’ve made more
> progress with the rule execution infrastructure before we tackle that, so
> that we can pick up caching and parallel execution and so on.
>
> I guess there’s another group of inputs as well, which is custom meta-data
> about the component, some of which might be expensive to calculate. Again,
> I’d leave this for a later.
>
> >
> > One possibility for a general pattern would be something like…
> >
> >
> > interface Components {
> >
> >
> > void eachComponent(MutationRules rules) {}
> >
> >
> > }
> >
> > abstract class MutationRules {
> >
> > public final T getTarget() {
> >
> >
> > // retrieve the target from some thread scoped global that we manage
> >
> >
> > }
> >
> >
> >
>
> I don’t love this pattern, but it is an option. I think I’d rather treat the
> inputs and outputs more symmetrically, so if we inject via properties for the
> target, we should inject via properties for the inputs too.
My problem with this is that we can’t express the requirement that the output
is a ComponentMetaDataDetails in the type system if it’s part of the method
signature, which is a big loss for tooling.
Well, I guess we could in an unenforceable way. The rule object could be
paramterized and we could just not use the param, and fail at runtime if the
first rule param is not the type.
>
> Regardless, we do need to share pattern between the meta-data rules and the
> (currently) more general rules, so whatever we choose must also be
> implemented for both. Probably that was implicit in the “general pattern” bit
> above.
>
> I think we might end up with a small number of patterns that we support.
> We’ll have at least 2 - one for Java and one for Groovy.
> For now, I think I’d just keep it simple and use the pattern we already,
> where the first parameter is the target and the remaining parameters are the
> inputs.
Groovy 2.3 has a new mechanism for declaring closure parameter type signatures
(http://melix.github.io/blog/2014/01/closure_param_inference.html). We could
potentially use this in combination with GDSL to give IDEA understanding of the
pattern and give it some hope of intellisense.
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email