Like others said, failonerror="false" (someone mistyped this and said "true" but meant false) is a bad idea for the same reason that was already mentioned: you only want it to not fail if the target doesn't exist in a file, but want it to still fail for everything else.
One very easy solution I see is in every "individual" build file include a line like: <import file="${this.property.might.not.resolve}" optional="true"/> This fulfills your requirement that if you run the build independently, it won't know about the "skeleton" targets and also the build doesn't need to know anything about a "master" build, because the property which decides which file is imported isn't resolved unless it is passed in from another build. Just use subant to pass the desired property to all the build files it is executing on. Mat -----Original Message----- From: Jacob Kjome [mailto:[EMAIL PROTECTED] Sent: Tuesday, October 24, 2006 10:58 PM To: Ant Users List Subject: Re: AW: dynamic targets At 08:05 AM 10/24/2006, you wrote: >same - write a common buildfile (maybe with empty implementation) and all the >projects have all needed targets. Web project could overwrite the >target implementation. > >Jan > Yep, <import> is powerful and extremely useful and I use it all the time. I tried to keep my example specific and concrete so as not to complicate the question. But it seems to have caused the original point of this exercise to be entirely missed. Think of this in an OOP way. You let other classes know what you are capable of by implementing interfaces. There are a million things that you might be capable of doing, all represented by methods you might implement. Do you implement all possible methods and, for 99% of the ones you aren't really capable of doing, you just report that you aren't capable of the method (by returning null, logging a message, or throwing an exception, etc...)? Or do you implement only the interfaces having the methods representing the capabilities you do have? If you said "the former", please stop here. No need to keep reading. If you said "the latter", then you're still with me. Read on.... In other words, please don't focus on the "war" target. That's an implementation detail. Although I have a master build file, each individual build is entirely independent and need not have any knowledge that the master or any other builds exists. It might be a very unique build that implements a "blahblah" target. What those of you who have commented are telling me is that I should have every build implement a "blahblah" target simply because one unique build does. Yes, I could have all builds import a common build with the "blahblah" target and the build that cares about it could override it, but that's conceptually ugly. Let me put it this way. When I run the individual build with "ant -projecthelp", I want to see *ONLY* the targets that are actually implemented in the build. Not 10,000 other dummy targets imported from some common dummy build file. If the only capabilities I have in a build are "clean" and "compile", then all I want is... C:\dev>ant -projecthelp Buildfile: build.xml Main targets: clean compile Other targets: Default target: compile I do *NOT* want... C:\dev>ant -projecthelp Buildfile: build.xml Main targets: clean compile Other targets: blahblah war sometargetyoudontcareabout yetanothertargetyoudontcareabout isthisgettingoldyet amidrivingthepointhome maybeacouplemore icouldkeepgoing youthinkicant doyoudoubledogdareme okyougotitmister imstillgoing youaskedforitandyougotit onemorejustforoldtimesake wowthisisstartingtogetannoyingnow yepreallyannoying butforsomereasonijustcantstop okillstop justforyou hehgotchastillgoing okimsickofwriting illstop Default target: compile Does that make it a bit more clear? The dynamic targets would be generated only if the target is called on the build and it doesn't exist. And the use-case for this would be mass target calling using <subant> to tell all build files to run a particular target. Rather than having individual build files have to implement a target only to tell the caller that they don't really perform the task, I want a target to by generated on the fly just to satisfy Ant in order to continue on without build failure. And, again, this would allow my master build file to be really stupid and generic because it wouldn't have to know which builds implement a "war" target or a "blahblah" target. It would just mass call the target on the individual projects. And the individual projects wouldn't have to worry about being the one that bombed out the mass build by not implementing dummy targets, nor would they be forced to report that they perform tasks that they don't really perform. Dynamic target functionality could also make it so that I could have a really short master build file that takes whatever target is called on it and pass it on to all the other build files without the master target having to implement each mass build target, but have a common infrastructure for doing so. For instance... <project name="Build_master"> Dynamic target gets generated based on what the user entered. The dynamic target calls <m-iter/> with the target provided to Ant on the command line <macrodef name="m-iter"> <attribute name="target"/> <attribute name="patternsetref"/> <sequential> <subant target="@{target}" inheritAll="false"> <fileset dir="."> <patternset refid="@{patternsetref}"/> </fileset> </subant> </sequential> </macrodef> The alternative to the description above using the dynamic targets is, for instance.... <target name="jar"> <m-iter target="jar" patternsetref="subant.build.patternset"/> </target> <target name="test"> <m-iter target="test" patternsetref="subant.build.patternset"/> </target> <target name="war"> <m-iter target="war" patternsetref="subant.war.patternset"/> </target> etc.... for every possible top-level target implemented by all builds in question, as well as taking pains to define the patternsets for the different types of build types which perform certain tasks that others might not implement. </project> I can't explain it any better than that. I hope my point was made more clear. Jake >>-----Ursprüngliche Nachricht----- >>Von: Markus M. May [mailto:[EMAIL PROTECTED] >>Gesendet: Dienstag, 24. Oktober 2006 09:13 >>An: Ant Users List >>Betreff: Re: dynamic targets >> >>Hello Jacob, >> >>why don't you just import a common build file and define the >>common target there. Only when the target is not defined in >>the build file, the common target gets executed. >> >>R, >> >>Markus M. May >>-------- Original-Nachricht -------- >>Datum: Mon, 23 Oct 2006 22:28:35 -0500 >>Von: Jacob Kjome <[EMAIL PROTECTED]> >>An: user@ant.apache.org >>Betreff: dynamic targets >> >>> >>> Along the lines of.... >>> http://marc.theaimsgroup.com/?l=ant-user&m=107429941032345&w=2 >>> >>> Is it possible to create targets dynamically, deferring >>creation until >>> such time as it is found that the project doesn't have the target >>> already defined? My use-case is using <subant> to iterate over >>> sub-builds calling a target on each one. My current strategy is to >>> define <patternset>s for each type of project. For instance, I add >>> all web projects to a particular patternset and then reference that >>> patternset when calling <subant>.... >>> >>> <subant target="war" inheritAll="false"> >>> <fileset dir="."> >>> <patternset refid="war.patternset"/> >>> </fileset> >>> </subant> >>> >>> >>> As further fallback, individual builds may implement empty targets >>> just so that they don't fail, just in case... >>> >>> <target name="war"> >>> <echo message="Unimplemented target"/> </target> >>> >>> >>> However, ideally, I'd like to be able to create the above target >>> dynamically in the case that it isn't implemented already by the >>> build. This would have 2 benefits: >>> >>> 1. I wouldn't have to bother creating the patternsets. I'd >>just call >>> all the build files and let them either build the war file >>or echo the >>> "Unimplemented target" message. >>> >>> 2. Individual builds that aren't web projects wouldn't have to have >>> to know what a web project is. If the only artifact generated is a >>> simple jar library, it seems odd to have to implement a dummy "war" >>> target simply because some external master build file might >>call "war" >>> on it. >>> >>> >>> Instead of Ant failing with the following message... >>> >>> BUILD FAILED >>> Target `war' does not exist in this project. >>> >>> >>> ...I'd like Ant to just run the above dynamically created >>target (not >>> just the "war" target, but any target that might not exist), report >>> the "Unimplemented target" message, and continue on. >>> >>> So, is this possible? Where/how do I hook into Ant to know >>the target >>> isn't implemented and create it myself via a scriptdef before Ant >>> gives me the build failure? >>> >>> >>> Jake >>> >>> >>> --------------------------------------------------------------------- >>> To unsubscribe, e-mail: [EMAIL PROTECTED] For >>additional >>> commands, e-mail: [EMAIL PROTECTED] >> >>--------------------------------------------------------------------- >>To unsubscribe, e-mail: [EMAIL PROTECTED] For >>additional commands, e-mail: [EMAIL PROTECTED] >> >> > >--------------------------------------------------------------------- >To unsubscribe, e-mail: [EMAIL PROTECTED] >For additional commands, e-mail: [EMAIL PROTECTED] --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]