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

Reply via email to