Gert Driesen wrote:
Ian MacLean wrote:
This seems to be causing a lot of grief. I'm really leaning towards having a list of <param> elements at the project level and allowing those and only those values to be passed on the commandline. I'm not sure how feasible that would be with the way we pass properties to nested builds but I think it would simplfy things a lot and add extra benefits. For example:
<project name="foo" > <param name="param1" default="somevalue" description="my first commandline param" />
Ian, I like the idea in general, but I'm not sure if the default value for these properties is always known at design time, so users would have to resort to the overwrite attribute anyway ... In the future, I'm pretty sure we'll need to allow user input for specifying property values (like Ant) : when a certain property is not specified on the command line, the build author might want to have the user asked to input the value ...
But as I said, I'm not sure the default attribute is all that useful, as its too "static" : when you need to execute other tasks/targets to determine the default value, the default attribute won't be of much use .... I understand the "problem" you're trying to tackle with this, but I'm not sure it will help users all that much ...
I don't think it matters how useful the default attribute is in general, because there are a number of parameters for which a default value would be the simplest and most consistent way to deal with them... "build.target" for example would probably default to "Release", but could be overridden to 'Debug' on a developer's machine.
In cases where there is no useful default value, then don't specify a default. If the value is required, then specify required="true" (default false or true?). I think the param mechanism gracefully handles all of these situations.
Its great that we can use the description (and property name) in the project help, and we could even add a required attribute to specify whether a given property needs to be specified on the command line....
Add one more attribute, "interactive" (or "ask-user", or something else), which is a boolean attribute; if true, and the parameter isn't specified, then request the user to input the parameter interactively - this is certainly the most secure way to enter a password in cases where the script can afford to be interactive.
A command-line parameter should probably be added to allow the build to fail if any interactive parameters haven't been specified on the command-line, so automated builds don't hang waiting for input... I don't know if it makes more sense for this option to be on or off by default - I'd probably swing more towards fail-on by default, since the "standard" use of NAnt is in an automated build... and since parameters are a new (potential) feature, a fail-secure mechanism won't break any existing builds ;-)
The fact that all of this can be included in the -projecthelp output would go a long way towards NAnt build scripts becoming self-documenting.
If you want a writable value based on a param you would set a new property - the same as you would in c# code with pass by value method arguments. Similarly it probably makes sense to have params and properties in the same namespace so you coulndn't create a property with the same name as an existing param.
I was going to say I don't really like this, because it has the same issues as the current read-only properties do... but on examination I changed my mind.
Using parameters that are declared as part of the build file, there is a (mostly) static mechanism to ensure that no property is attempting to overwrite a parameter. That is, most cases of properties clashing with a parameter could be raised as errors when the build script is parsed. Cases like <property name="${property.name}" /> would sneak under the radar, of course, but these would normally (?) be the exception.
We would also need to think about how to deal with this for nested builds and included build files ...
My suggestion for this:
I think parameters are simplest and most intuitive when they are static: As Ian suggested, you can only specify parameters that are defined in the build file;
Nested build files called using the nant task then define their own parameters. These parameters are passed through the nant task using a nested <params> (or <with-params>) element which replaces (?) the current properties element. Paramaters are not automatically inherited, they must be explicitly specified in the nant task... this could be made simpler by allowing something along the lines of paramsets, similar to Ant propertysets:
<param name="working.dir" default="${nant.project.basedir}" /> <nant buildfile="worker.build" target="do-stuff"> <with-params> <with-param name="foo" value="bah" /> <!-- If no value is specified, then the value of this project's parameter is used. If this parameter isn't defined in this project, then fail. --> <with-param name="working.dir" /> <!-- Is it worth having a 'failonempty' parameter in a with-paramset element? Since parameters are static, a paramset is either going to be always empty or always non-empty, which turns the failure into more of a static validation check, but is performed at runtime! --> <with-paramset pattern="foo.*" /> </with-params> </nant>
Included build files are a little trickier. It would probably be most useful to be able to define parameters in 'child' build files, as this improves encapsulation... otherwise, to correctly include a child build file a parameter would have to be specified in the top-level build file, which would then break if the child build file were changed...
To really be useful, however, the child build file's parameters really should be displayed in the -projecthelp output for the top-level build file. It shouldn't be too hard to do this for unconditional include elements, since they are only legal at the project level, so -projecthelp can evaluate these includes without executing any targets (Although if properties are defined at the project level, these should probably be evaluated?)
If an include is conditional, however, things can become much more intractable... If the conditional is based on the value of a parameter, then the output of -projecthelp (theoretically) becomes dependent on the value of that parameter, and worse is probably incomplete in the absense of that parameter! Then again, this applies to non-conditional includes whose filename is based on a parameter... but this should probably be a discouraged practice (?).
Things could be made simple again if the include task doesn't evaluate properties, and the if/unless attributes are removed... that is, include becomes a 100% static mechanism... dynamic build file calling would then use the nant task with property inheritance enabled. Is this a valid supposition?
Conclusion: I like the idea, but ... :-)
I think the idea has the potential to be the cleanest solution, but it also has the potential to be badly done...
Two related items to project parameters are adding parameters to targets (for use with command-line arguments [if project parameters are implemented... yet more discussion required though, probably], the call task and the nant task), and adding a -verify option to the command line, which would make NAnt perform a static check on the build file to test for correctness, without executing any targets. (Or any project-level tasks with side-effects?)
Gert
Whew.
Thoughts?
-- Troy
------------------------------------------------------- SF.Net email is sponsored by Shop4tech.com-Lowest price on Blank Media 100pk Sonic DVD-R 4x for only $29 -100pk Sonic DVD+R for only $33 Save 50% off Retail on Ink & Toner - Free Shipping and Free Gift. http://www.shop4tech.com/z/Inkjet_Cartridges/9_108_r285 _______________________________________________ Nant-users mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/nant-users