jesicabaxter / ndmitchell

Automatically exported from code.google.com/p/ndmitchell
0 stars 0 forks source link

Cannot use annotations argPos and args together. #625

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
It's not uncommon for me to have a mode that has a few positional arguments I 
would like to capture and document using the argPos annotation followed by a 
trail of arguments for which the args pattern would be logical if only it was 
restricted to arguments not already captured by argPos.

The work-around I currently use is to use args to capture the fixed arguments 
as well which makes them optional and causes the generated documentation to be 
very awkward because those arguments are fundamentally different than the 
others.

I could make them options rather than arguments, but that solution would 
require me to redesign other parts of the UI for consistency.

Therefore, I request that the args annotation be changed to capture trailing 
arguments not captured by argPos, or, if it's more feasible or convenient, to 
create a new annotation argsPos that will let you specify a starting position 
for the arguments it refers to.

$ cabal list --installed cmdargs
* cmdargs
    Synopsis: Command line argument processing
    Default available version: 0.10.5
    Installed versions: 0.9.5, 0.10.5
    Homepage: http://community.haskell.org/~ndm/cmdargs/
    License:  BSD3

$ uname -s
Linux

Original issue reported on code.google.com by oh.hello...@gmail.com on 26 Nov 2013 at 8:09

GoogleCodeExporter commented 8 years ago
They are certainly meant to work together. Looking through my test suite I see:

data Test3 = Test3 {pos1_1 :: [Int], pos1_2 :: [String], pos1_rest :: [String]}
             deriving (Show, Eq, Data, Typeable)

mode3 = cmdArgsMode $ Test3 (def &= argPos 1) (def &= argPos 2 &= opt "foo") 
(def &= args)

test3 = do
    let Tester{..} = testers "Test3" [mode3,mode3_]
    fails []
    fails ["a"]
    ["a","1"] === Test3 [1] ["foo"] ["a"]
    ["a","1","c"] === Test3 [1] ["c"] ["a"]
    ["a","1","c","d"] === Test3 [1] ["c"] ["a","d"]
    invalid $ \_ -> Test3 def def (def &= help "help" &= args)

Which strongly suggests things captured by argPos get removed from args, and 
this test also shows that argPos doesn't have to always start at 0 even. Do you 
have a particular example in mind that doesn't work?

(Apologies for taking a few days to reply, I've been ill, but am now getting 
better.)

Original comment by ndmitch...@gmail.com on 30 Nov 2013 at 4:04

GoogleCodeExporter commented 8 years ago
In trying to re-create the example, I ultimately failed to reproduce the
issue.  I did initially use argPos 1 when I apparently intended argPos 0.
That causes the first argument to be captured by the args list and perhaps
caused me to conclude that args was capturing all arguments rather than
trailing ones.  The bug is invalid, but if you think the error will be a
common one, you might consider explicitly documenting that args excludes
arguments captured by argPos.

Original comment by oh.hello...@gmail.com on 30 Nov 2013 at 9:39

GoogleCodeExporter commented 8 years ago
Curiously, I notice that I've consistently used argPos 1 for the first argument 
and it did not cause any commands to fail to work as I intended.  The attached 
program demonstrates the apparent inconsistency of index policy.

$ ./issue625 catpub0 a b c d
spec  = "a"
files = ["b","c","d"]
$ ./issue625 catpub1 a b c d
spec  = "b"
files = ["a","c","d"]
./issue625 justone0 a
arg = "a"
./issue625 justone1 a
arg = "a"

Original comment by oh.hello...@gmail.com on 30 Nov 2013 at 10:04

Attachments:

GoogleCodeExporter commented 8 years ago
Documentation of anything anyone ever got confused on even once is usually 
worthwhile, so I'll certainly document the 0 based index and the exclusion of 
argPos things.

For justone0/justone1 at fist glance there does seem to be something funny 
going on there. I'll take a closer look.

Original comment by ndmitch...@gmail.com on 30 Nov 2013 at 10:11

GoogleCodeExporter commented 8 years ago
In fact, I think the justone thing might be CmdArgs trying to do "the most 
sensible thing". It has nowhere to put an argPos 0, since you don't have args, 
therefore the first argument can't really exist, and should go in argPos 1. If 
that turns out to be it, I should definitely document it.

Original comment by ndmitch...@gmail.com on 30 Nov 2013 at 10:15

GoogleCodeExporter commented 8 years ago
I'm not sure simply documenting it is the best course.  It violates the "least 
surprise" principle i think.  It gave me a false confidence that 1 was the 
correct index.  Probably it would be more sensible to fail with error than to 
re-interpret the argPos indexes as starting at 1 instead of 0.

Original comment by oh.hello...@gmail.com on 30 Nov 2013 at 10:33

GoogleCodeExporter commented 8 years ago
I agree that if I were doing it afresh, failing might be the right course. 
However, changing it now might break programs relying on CmdArgs, and since the 
change wouldn't appear at compile time, it would be an unpleasant upgrade 
experience. I've tidied up the docs, so hopefully that will save people time in 
future.

Original comment by ndmitch...@gmail.com on 5 Dec 2013 at 9:46

GoogleCodeExporter commented 8 years ago
Released in 0.10.6

Original comment by ndmitch...@gmail.com on 5 Dec 2013 at 10:01