Adam,


  Here are more details on my proposal.

  This is still a bit rough, but hopefully there is enough
  here to make the idea more specific for everybody.



  SYNTAX
  ======
        
        % gradle [  -<short_flag> | --<long_flag> ]*    \
                 [ [+]?<task> -<task>* ]*               \ 
                 [ <subproj_path>                       \
                     [ [+|-]?<task_within_subproj> ]+ 
                 ]*


        Given:

            *    means "any number of times"  (including none)
            +    means "at least one"
            ?    means "zero or one"  
            |    means "or"
          [...]  denotes a logical grouping
          <...>  denotes a placeholder for a name  
                 (e.g: <task> could be the task named "test")



  EXAMPLES
  ========

   [1]  Use quiet flag (in either its short or long form), 
        and run task moo:

          %  gradle -q      moo
          %  gradle --quiet moo


   [2]  Run the tasks egg, hen, foo, and bar:

          %  gradle  egg bar


   [3]  Run egg task (skipping the hen task this normally implies),
        and also run the bar task:
                
          %  gradle   egg -hen  bar 
          %  gradle  +egg -hen +bar       # same as:  egg -hen bar

        Note that when you use '-', sometimes using the decorative '+' 
        makes it easy to see what's going on.  However, This '+' is just 
        there to make things more readable;  being sloppy should have
        no ill consequences:

          %  gradle  +egg -hen  bar        # same as:  egg -hen bar
          %  gradle   egg -hen +bar        # same as:  egg -hen bar



   [4]  Use -q and -s flag, run moo, but skip cow.
        Note: Flags can be grouped and flag order doesn't 
             matter.  Because all flags must appear before 
             tasks, and skipped tags can't appear prior to 
             tasks (or subproject paths), there's never any 
             ambiguity about whether something that starts 
             with a '-' is a flag or a task.

          %  gradle -q -s   moo -cow
          %  gradle -qs     moo -cow
          %  gradle -sq     moo -cow
          %  gradle -q -s   moo -cow
          %  gradle -qs    +moo -cow
          %  gradle -sq    +moo -cow


   [5]  Run moo in the main project, and
        within the /foo/bar project run hello and dew but skip chew and
        within the /egg/hen project run sun and fun:

         %  gradle -q  moo /foo/bar hello -dew chew  /egg/hen   fun sun

        
   [6]  Run the /abc dir task.
        Note:  you don't usually need to run dir tasks from the
               command line, but if that's necessary, you can do
               so by prefixing their name with ':'. 

         %  gradle :/abc

   

   [7]  Run the abc/def dir task and the moo task:
         % gradle :abc/def  moo
        

   [8]  Run the moo task and the abc/def dir task
        ... and within the foo/bar project: 
             run the egg task and the xxx/yyy dir task
             but not the xxx/zzz dir task
        ... and within the foo/zoo project: 
            run the fun task 
        ... and in the top-level project,
            run the crazy_example task:

         % gradle :abc/def  foo/bar egg :xxx/yyy -:/xxx/zzz  \
                            foo/zoo fun                      \
                            /       crazy_example
        
                            


   DEFINITIONS
   ===========
    

   Let:   
        <short_flag>    A single-letter flag (or a group of them)

                            Example #1:  '-q'     
                            Example #2:  '-qs'

                        
        <long_flag>     A multi-letter flag

                            Example:  '--quiet'



        <subproj_path>  The absolute or relative path to a subproject.
                        A <subproj_path> is string containing at least
                        one '/' character, and does not begin with 
                        '+', '-', or ":'.   Further, it must not contain
                        the substrings:  '/+', '/-', or '/:'.

                            Example #1:     foo/bar
                            Example #2:     foo/bar/
                            Example #3:     /foo/bar
                            Example #4:     /foo/bar/


        <task>          A task name.  Task names may be prefixed 
                        by '-', which indicates a skipped task.
                        The '+' prefix is purely decorative, but
                        may make it easier for a human reader to 
                        see that a task name is being specified,
                        and that it is not skipped.   

                            Example #1:     moo
                            Example #2:    +moo
                            Example #3:    -moo
                        
                        Advanced usage:   dir tasks on the command line
                            You don't need to run dir tasks directly on
                            the command line very often, but if you needed
                            to to that, you'd prefix the dir task by ':'.
                            Thus, to run the dir task /x/y but not /x/z, 
                            you could say:     %  gradle  :/x/y  -:/x/z
                            or equivalently:   %  gradle +:/x/y  -:/x/z



   DETAILS
   =======

   Let's discect the following syntax pattern bit by bit:

        % gradle [  -<short_flag> | --<long_flag> ]*    \
                 [ [+]?<task> -<task>* ]*               \ 
                 [ <subproj_path>                       \
                     [ [+|-]?<task_within_subproj> ]+ 
                 ]*


    o   [  -<short_flag> | --<long_flag> ]*    
            Short flags and long flags may appear in any order, 
            and you may have any number of them (including none);
            however, they must come first.


    o   [ [+]?<task> -<task>* ]*
            You may any number of tasks that don't have a project
            name prefixing them  (including no tasks);  however, if
            you do supply a list, at least one non-skipped task
            must come first.  If you do have a non-skipped task,
            the '+' is entirely optional.


     o   [ <subproj_path> [ [+|-]?<task_within_subproj> ]+ ]*
            You may supply any nubmer of tuples of the form:

               <subproj_path> [ [+|-]?<task_within_subproj> ]+

             However, if you do supply a <subproj_path>, you must
             specify at least one task within it.  These tasks
             may be skipped or non-skipped (and again, if non-skipped
             the '+' is purely optional).



> The first command line argument is optional and specifies the current 
> project. It can be either the project directory, a build file, or a 
> project path. If not specified, it defaults to the current directory. It 
> is a shortcut for (or replacement for) the --project-dir and --buildfile 
> command-line options.



    The proposal allows for an arbitrary number 
    of top-level tasks (including none) followed by 
    an arbitrary number of project & task tuples
    (including none).


> >One thing I like very much is -test instead of -Dskip.test


   :)
   Thanks.


> Me too. How would we distinguish between these task exclusions and 
> command-line options? Would we keep the system property stuff? Does 
> -test exclude the dependencies of the test task as well?

 
   The only case where this is could ever be a problem 
   as far a human reader's ability to parse the command
   line goes is when you've got 1-letter skipped tasks
   and short (1-letter flags).  As 1-letter tasks are rare, 
   and skipping them even more so, I don't consider this 
   a practical usability issue.

   It would NEVER be a problem for the command line parser
   because at least one non-skipped tasks must precede 
   an excluded task, and all flags must precede all tasks.

   Thus, suppose one day, gradle were to add the short flag -x,
   and some user had two tasks x and y where y dependsOn x.
   Now consider the following:

        % gradle  -x y -x

   This means:

         Run gradle with the -x flag
         and execute the y task
         but skip the x task.

   Due to the ordering constraint on tasks, if you said:

        % gradle  -x -x y

   That would mean:   

         Run gradle with the -x flag 
         and the -x flag                        (!!!)
         and execute the y task

   Most flags make no sense when doubled up, but some do 
   (like  -v -v means "very verbose" on some programs).

   That said, I think that the ordering constraint 
   that you can't have a negated tasks first in the list
   after the flags isn't particularly bad because people
   tend to think  "this, but not that", rather than 
   "not that but this".

   Hence, the case of people accidentally putting a negated
   task first after the flags isn't likely to happen in 
   real life very often... so the nice aspects of this 
   syntax (brevity & expressiveness) seem to greatly outweigh
   the chance of real-world confusion over what's an task name
   and what's a flag.   


   Programmatically, if you have a subproject '/x/y'  
   a task named 'z' within this subproject could
   have the absolute name:   /x/y/+z

   Note that because dir tasks are prefixed with ':'
   the relative dir task foo/bar within project /x/y 
   would have the absolute name:   /x/y/+:foo/bar
   and the absolute dir task /foo/bar within prject /x/y
   would have the absolute name:  /x/y/+:/foo/bar

   My guess is that in the real world, people probably won't
   do stuff much more complex than example [5], but I wanted 
   to make sure nothing blows up in the more convoluted cases
   (hence the overkill).    When it comes to the userguide,
   I'd probably want to re-work the explanation to make the 
   99% case leap out more... but this is for you!  

   Let me know what you think.

                Cheers,
                -Jon


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply via email to