Bug 24231

Summary: command-line option to signify no more options
Product: Ant Reporter: Matt Benson <mbenson>
Component: CoreAssignee: Ant Notifications List <notifications>
Status: NEW ---    
Severity: enhancement CC: jglick
Priority: P3 Keywords: PatchAvailable
Version: 1.6.0   
Target Milestone: ---   
Hardware: All   
OS: other   
Attachments: Patch to implement empty option as -.
patch to implement -- as the end of options

Description Matt Benson 2003-10-29 22:17:04 UTC
An option such as -- or -. would make the command-line more versatile and 
friendly.  In implementation it could be little more than a dummy.  I have 
marked this as an enhancement although it seems like a lot of payoff for a 
little work.
Comment 1 J.M. (Martijn) Kruithof 2003-10-30 06:18:19 UTC
What would be the benefits? (That the target names can start with a -?)
Comment 2 Matt Benson 2003-10-30 16:15:20 UTC
Actually I wasn't thinking along those lines at all.  Again, really I was 
meaning just that a dummy, do-nothing option could exist.  The primary benefit 
that drove me to this idea was the -find/-s option; currently it appears that 
a) it must be the last argument given, and b) if it is specified without a 
filename, it must use the default target of whatever build.xml it finds.  I 
have seen these types of options in other command-line utilities.
Comment 3 Matt Benson 2003-10-30 16:23:15 UTC
Created attachment 8829 [details]
Patch to implement empty option as -.
Comment 4 J.M. (Martijn) Kruithof 2003-10-30 18:00:39 UTC
Still what would be the benefits.
-find need not be the last argument given if a filename is specified
and if you specify -find -. it will probably start looking for the file name -.
and just carry on. 
Usually on other tools this kind of options is present to be able to specify a
file name / parameter value starting with - or to pass on the options to the
program run inside the program.
Comment 5 Matt Benson 2003-10-30 18:14:11 UTC
Indeed, -find would look for -. if it were not told specifically that the -. 
switch is not a filename.  I do realize that -find does not have to be last if 
you specify a filename, in spite of my having omitted that qualification from 
my previous statement.  I just have a problem with command-line options that 
take optional parameters, but whether a parameter is optional depends on the 
option's position on the command-line.  An alternate solution for this more 
specific situation might be to disallow build filenames beginning with "-" and 
therefore be able to go on to the next option when it was encountered.

Do any of the committers have an opinion on this subject?

-Matt
Comment 6 Steve Loughran 2003-10-30 18:29:48 UTC
I dont see the value in this patch, if find is the sole reason. I do
occasionally use find but I just say -find build.xml target

One version of Ant (1.2?) had auto-find; if a build.xml wasnt found locally, it
searched upstream. This was turned off in the followon version, as it caused too
many surprises. But you could patch your version of ant if you want...
Comment 7 Gus Heck 2003-11-10 23:19:17 UTC
Actually, this sounds like a request for the command line to conform to user
expectations... Even if the functionality can be achieved with the current
option processing, not suprising users and implementing -- or -. is I think a
positive if extremely minor thing. That said, it cannot be implemented because
it would break a widely used kludge that is noted in the discussion of bug 22020
(See Steve's comment there on how to use targets that start with '-' to prevent
user invocation of 'private' or 'internal' targets).
Comment 8 Matt Benson 2003-11-10 23:23:53 UTC
I don't see how adding any option would break the kludge (which I use 
tirelessly myself).  The whole point of that kludge is that the target cannot 
be invoked directly from the command line.  Adding option --, -. -/ -! -@, etc. 
has no bearing on that that I can see.
Comment 9 Gus Heck 2003-11-11 17:44:29 UTC
The usual point of -- is that it means "there are no further options past this
point in the command line". An example from the man page of the unix rm command:

To remove a file whose name starts with a ‘-’, for example ‘-foo’,  use
       one of these commands:

              rm -- -foo

              rm ./-foo

 
Correct me if this is not the meaning you intend, as I have misunderstood your
intent. I assume you do from this line in your patch:
+        msg.append("  -.                     signify end of options" + lSep);


So, to answer your question assuming I understand your intent and your patch
does what I think you intend (I havn't directly verified it)...

Currently targets begining with - are currently misidentified as (usually
unrecognized) options by the commandline parser. If -- was included in the
commandline before the target was specified the command line would now
understand that -targetname is a target and not an option and properly execute
it. Misidentification is the only reason targets starting with - don't execute
from the command line. They are otherwise perfectly legal targets with equal status.

Try this sometime:

<target name="-projecthelp">
  <echo message="You can't see me!"/>
</target>

With your patch I assume it would be possible to say 

ant -. -projecthelp 

and get the output:

-projecthelp:
     [echo] You can't see me!

The problem is that the -targetname "feature" is not (so far as I know) an
intentionally designed in feature with respect to "hiding internal targets", but
a coincidental side effect of command line parsing when it tries to warn the
user of typos in their options. Sadly, I just discovered that this technique of
access control was added to the documentation for the 1.5 release. IMHO Adding
'-' to the target name to prevent invoction should not have been made a
supported feature, although it now is (as of version 1.18 of using.html, and
it's subsequent release in 1.5). This practice overloads the meaning of the name
atribute, and creates a syntax within the realm of target names, which was
(until the "feature" was documented) unconstrained.

This "feature" had previously remained undocumented despite the fact that it
existed since version 1.1 of Main.java. (I avoid using it myself, since I came
up with an alternate, if somewhat lenghthier, method of controling access to
targets back when 1.4.1 was the current release). Another flaw of this "feature"
is that it yeilds an error message about options rather than one indicating that
the build file writer chose not to let the user run this target directly. The
later would imply that the user should look for another target, whereas the
former looks like a mistake by the writer of the build file and seems to imply
the build should be "fixed" by changing the target name (to the newish user who
doesn't know or remember about - targets at least).

The ability to protect/hide targets from the command line user is clearly
desired by many build file authors and the "feature" is widely used. Although
the "feature" is based on an "until recently undocumented feature" it is now is
a back compatability issue. I expect that back compatability is likely to be
honored here, but even if it isn't it would be very poor form (imho) to break it
without providing an alternative. 

My patch to bug 22020 attempts to add an explicit means of specifying command
line visibility, but is being held for consideration in 1.7 because the
mechanism I propose may also be expanded or altered to allow build file writers
to specify accessibility of targets from other contexts (such as import).
Several commiters feel (I am not a commiter) that access can't be implemented
until we are comfortable with import and have a feel for how people will use it.
I have to admit that this does sound reasonable.

Resolving bug 22020 (with or without my patch) would supply an alternative
access control mechanism and thus make it possible to begin considering a minor
break in back compatability by implementing the feature you are requesting.

However, given that it is now a back compatability issue, I suspect you will
need a use case that can't be resolved with a simple work around before any
patch will be commited. I will leave it to commiters to declare this WONTFIX or
not however.
Comment 10 Matt Benson 2003-11-13 21:57:32 UTC
Because you haven't tested the patch or apparently reviewed it in any great 
detail, you haven't seen that I have not broken backward compatibility.  If Bug 
22020 eliminates the utility of -.* target names, so be it.  But my patch does 
not impact it; in truth it doesn't even force the end of command-line 
processing.  Ultimately this option only allows the explicit specification that 
an optional parameter to a command-line option has been omitted; it just so 
happens that the only such example is -find/-s.  Because there is, AGAIN, no 
impact to -.* named targets, I have AGAIN removed the dependency on Bug 22020.
Comment 11 peter reilly 2003-11-14 17:33:44 UTC
-- is normally the indication of the end of options.
The patch should do this and also handle all the options that
have paramters (-nice, -logfile etc)
Comment 12 peter reilly 2003-11-14 17:34:31 UTC
Created attachment 9111 [details]
patch to implement -- as the end of options
Comment 13 Matt Benson 2003-11-14 17:48:16 UTC
Sounds fine except that this patch appears to truly implement "no more args".  
This is perhaps better (more intuitive) but appears to have the side effect of 
allowing targets with names beginning with - to be specified from the command 
line, as discussed already.  If this is the patch to use, the dependency on bug 
22020 will exist.
Comment 14 Gus Heck 2003-11-19 04:29:30 UTC
Ok, well when I read your patch I found the comment I referenced, so I didn't
know if it was buggy patch or not. It is now clear that it does what you
intended it to, and Your patch does not actually introduce the dependency on bug
22020. I had trouble understanding this in the first place due to the well know
but slightly different command line functionality.

I agree that Peter's patch would introduce the dependancy on bug 22020

I worry about people misunderstanding this in the way that I did, so perhaps
there is some place a detailed documentation could be placed. I don't offhand
remember if there is a section of the manual that deals with explaining the
command line options (id'd look, but the site seems to be down (11:30pm EST
11/18) and I don't have the manual locally on this computer.)
Comment 15 Matt Benson 2010-02-26 15:15:40 UTC
*** Bug 48823 has been marked as a duplicate of this bug. ***
Comment 16 Jesse Glick 2010-02-26 17:16:56 UTC
(In reply to comment #13)
> the side effect of 
> allowing targets with names beginning with - to be specified from the command 
> line

As I described in Bug 48823, I think this is a good thing. The use of '-' as an initial character to mark "internal" targets is a more or less established convention: it indicates the script author's intent that calling the target directly is unlikely to be useful.

But there is no sense in which it was ever impossible to run internal targets, i.e. there was no hard encapsulation; <antcall> or any program embedding Ant could invoke them. (For example, the NetBeans IDE does not offer Run in the context menu of an internal target node, but Run > Advanced... under the build script node lets you type in target names to run, which are never parsed as Ant options.) The situation was perhaps comparable to a Java private method: it is clearly not intended to be run directly, but (SecurityManager permitting) you can still do so via reflection if you know what you are doing.

Being able to run 'ant -- -internal-target' can be helpful for testing by the person who wrote the target, and it provides a sure way for a script to invoke Ant with a dynamically determined target without risk of misinterpretation as an option - which is why well-written scripts calling e.g. /usr/bin/rm use -- before the file list.