Re: About macrodef in the trenches
On Fri, 10 Dec 2004, Peter Reilly [EMAIL PROTECTED] wrote: 1) this attribute is good. however, it is only really usefull in combination with the iftrue attribute, or with ant-contrib if task Agreed. Or IOW, I don't think it is that useful without an if-task like structure. 2) a default value for the element is good. The default value should be in the declaration, but it is ok to have it the body of the macrodef. +1 for having it in the declaration. 3) this sounds good if a little stange initially. Agreed on both counts (sounds useful and strange). 4) I don't like since I don't want to see the @{...} constructs leak out of the macrodef body at all. Stefan - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: About macrodef in the trenches
All these features sould great. 1) this attribute is good. however, it is only really usefull in combination with the iftrue attribute, or with ant-contrib if task 2) a default value for the element is good. The default value should be in the declaration, but it is ok to have it the body of the macrodef. 3) this sounds good if a little stange initially. 4) this is good as well, if one is useing elements with macrodefs a lot. It may be a bit confusing. I would say go for it! Peter Dominique Devienne wrote: This past two weeks, I've worked on coming up with a generic build file for our multiple projects, which I'd say are 80% to 99% common from one project to the next. Of course, I'm using heavily import, target overriding, and macrodef, but even with these fine features, it's not always easy to accomodate the variations from one build to the next, especially if I want to avoid having to rewrite whole tasks/targets. To achieve this maximum reuse, and minimum overriding, i.e. to avoid being forced to rewrite whole tasks, I've defined complex macros with built-in conditionals, and lots of default attributes. Alas, there's no default 'value' for macro elements, so providing default tags for a macro element is currently not possible. I believe this lack of element default makes macrodef less powerful that it can be. So finally today I had a look at the macrodef code, and tried to understand how things worked under the hood. I was surprised to find out I understood the code ;-) (if I glossed over most of the UE/RC cuisine that is). BTW, I'm amazed this can all be implemented in a couple of tasks with no changes to the framework itself. The new fully dynamic nature of Ant 1.6 (everything's a UE) is powerful indeed! I then proceeded to copy MacroDef/MacroInstance to my own antlib, and amazingly after repackaging and adding a single import, everything worked fine. (I duplicate the code because we only use an official Ant release.) I then tweaked macrodef to add the following features: 1) Everytime a macro attribute or element is explicitly defined in a macro instance (where the macro is used), I define an additional macro attribute (local property in the code) which allows to find out in the macro body whether the attribute or element was explicitly used/specified. When an 'foo' attribute is used, I define '@foo?' with value of true. When an 'bar' element is used, I define 'bar?' with value of true My macro bodies/impls then do things or not (or differently) based on this info. For example: bm:macrodef name=my-copy ... attribute name=tos default=/dev/null / sequential ... bm:sequential ifTrue=@[EMAIL PROTECTED] copy file=@{tos} tofile=... / /bm:sequential /sequential /bm:macrodef bm:macrodef name=my-module-image ... element name=sources optional=true / sequential ... bm:sequential ifTrue=@[EMAIL PROTECTED] zip destfile=@{todir}/sdk/src.zip sources / /zip /bm:sequential /sequential /bm:macrodef 2) Allow defining an macro element 'default value'. Instead of the default being inside the macrodef element, its inside the macro sequential where the element is used. I did it this way because the implementation was easier, and it makes it easy to read the macro impl, although it could be confusing to some I guess?! If a macro element is not explicitly specified in the macro instance, and the element is optional, then the 'default value' from the macro definition is used. If specified, the macro instance value is used as usual otherwise. For example: bm:macrodef name=my-register ... element name=patterns optional=true / sequential ds:register ... ... fileset dir=@{dir} patterns include name=**/*.class / exclude name=**/test/*Test.class / /patterns /fileset /ds:register /sequential /bm:macrodef The macro above defaults the patterns element to 1 include + 1 exclude. 3) When coming up with elements a macro could contain, I often end up wanting to contain a classpath macro element that I want to pass in to java or another task taking a classpath. If I can't use the single implicit element for some reason, I then have to do something ugly: macrodef name=ugly ... element name=my-classpath optional=true / sequential ... java ... my-classpath / /java /sequential /macrodef and I'm forced to use: ugly my-classpath classpath refid=classpath / /my-classpath /ugly If I throw in element defaults from (2), the macro becomes: macrodef name=ugly ... element name=my-classpath optional=true / sequential ... java ... my-classpath classpath refid=classpath / /my-classpath /java /sequential /macrodef To work
RE: About macrodef in the trenches
Thanks for the feedback Peter. I'll be off line most of Dec, so for now I'll just attach my modified MacroDef/Instance files in bugzilla until I can properly try to integrate it to Ant (it's not very tested yet, and not unit tested at all either). I worked off the 1.6 branch anyway, and this would need to happen in the HEAD I guess, no? About (1), you're right. I used my bm:sequential which is more like xsl:if than ac:if, because it has no then or else block. 90% of the time, I don't need if/then/else, just if. I find having conditions on sequential very natural and the Ant way ;-) (2) I initialy thought about putting it in the declaration, but I didn't think I could pull it off. And after using it, I thought it was easier to read the macro code with the defaults inside the macro impl instead of in the element declaration. (3) I agree it requires to get used to, but for the client code actually looks more 'normal' and task-like. Like (4), one doesn't have to use it. (4) Again, it's a question of reuse. I don't deny using @{attr} in the macro instance looks strange, but I did naturally try to use it with the regular Ant macrodef to learn it didn't work. I wanted to avoid duplicate some info I had already entered in a macro attribute. I'd say it's a nice to have thing, and one doesn't have to use it. BTW, after droping this code in my Antlib, my checkstyle Javadocs error count jumped from 0 to 35 ;-) I'll try to fix this too. (I have a checkstyle config for Javadocs only). --DD From: Peter Reilly [mailto:[EMAIL PROTECTED] Sent: Fri 12/10/2004 9:15 AM To: Ant Developers List Subject: Re: About macrodef in the trenches All these features sould great. 1) this attribute is good. however, it is only really usefull in combination with the iftrue attribute, or with ant-contrib if task 2) a default value for the element is good. The default value should be in the declaration, but it is ok to have it the body of the macrodef. 3) this sounds good if a little stange initially. 4) this is good as well, if one is useing elements with macrodefs a lot. It may be a bit confusing. I would say go for it! Peter - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
RE: About macrodef in the trenches
I've never used macrodef in Ant, but would say that I'd find a template definition easiest to understand with the following structure: define id=t parameters parameter id=x ... (gives default value) /parameter /parameters body ... /body /define and usage of the form: apply refid=t binding id=x (maps to a parameter) ... (gives actual value) /binding /apply or something like that. You might even want to indicate that a given parameter is mandatory by not specifying a default for the parameter. How does that relate to macrodef? Can this approach be used? Is it worth it? Just my tuppence worth. ;n) Phil On Fri, 2004-12-10 at 15:58, Dominique Devienne wrote: Thanks for the feedback Peter. I'll be off line most of Dec, so for now I'll just attach my modified MacroDef/Instance files in bugzilla until I can properly try to integrate it to Ant (it's not very tested yet, and not unit tested at all either). I worked off the 1.6 branch anyway, and this would need to happen in the HEAD I guess, no? About (1), you're right. I used my bm:sequential which is more like xsl:if than ac:if, because it has no then or else block. 90% of the time, I don't need if/then/else, just if. I find having conditions on sequential very natural and the Ant way ;-) (2) I initialy thought about putting it in the declaration, but I didn't think I could pull it off. And after using it, I thought it was easier to read the macro code with the defaults inside the macro impl instead of in the element declaration. (3) I agree it requires to get used to, but for the client code actually looks more 'normal' and task-like. Like (4), one doesn't have to use it. (4) Again, it's a question of reuse. I don't deny using @{attr} in the macro instance looks strange, but I did naturally try to use it with the regular Ant macrodef to learn it didn't work. I wanted to avoid duplicate some info I had already entered in a macro attribute. I'd say it's a nice to have thing, and one doesn't have to use it. BTW, after droping this code in my Antlib, my checkstyle Javadocs error count jumped from 0 to 35 ;-) I'll try to fix this too. (I have a checkstyle config for Javadocs only). --DD From: Peter Reilly [mailto:[EMAIL PROTECTED] Sent: Fri 12/10/2004 9:15 AM To: Ant Developers List Subject: Re: About macrodef in the trenches All these features sould great. 1) this attribute is good. however, it is only really usefull in combination with the iftrue attribute, or with ant-contrib if task 2) a default value for the element is good. The default value should be in the declaration, but it is ok to have it the body of the macrodef. 3) this sounds good if a little stange initially. 4) this is good as well, if one is useing elements with macrodefs a lot. It may be a bit confusing. I would say go for it! Peter - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] -- Phil Weighill-Smith [EMAIL PROTECTED] Volantis Systems