Skip to content

CLI task arguments #1

Description

@bitprophet

See also: Fabric #69

Problem

Need to allow parameterization of tasks as invoked via the CLI (tasks invoked via Python are simply passing regular args/kwargs or their list/dict counterparts.) Sub-problem: translating strings/flag existence into Python types such as lists, booleans etc.

Current implementation in Fabric is fab taskname:positional_arg_value,keyword_arg=kwarg_value,.... Some other tools use "regular" CLI flags, e.g. paver taskname -F value.

"Custom"/"attached" args

Pluses:

  • Works great for multi-task invokes, zero ambiguity about which param values go to which tasks
  • Supports positional arguments well

Minuses:

  • Requires custom parsing, which may lead to bugs and at the very least increases code maintenance burden
  • Slight documentation burden -- requires users to learn how that custom parsing works, re: need for escaping (esp. how that meshes with normal shell escapes) and etc.

"Regular" flag args

Pluses:

  • Can (probably) just use argparse
  • Many users already familiar with it

Minuses:

  • Doesn't mesh well with multi-task invokes unless we:
    • enforce BSD-style "order matters" (not even sure argparse can do this? EDIT: perhaps with subcommands, if >1 subcommand can be invoked at a time)
    • or use an ugly "task delimiter" syntax like invoke task1 --arg1 --next task2 --arg2 (again, can argparse do this?)
    • or hope/pray that all simultaneously-invoked tasks have zero overlap in their kwargs and no positional args are ever needed.
      • How common is this? If we assume flags nix any possibility of positional args and that this is OK, it could be reasonable to assume two or three tasks called together would all have different names for their kwargs. Maybe.
  • Namespace clashes with core (non task related) flags such as -c/--collection
    • This also requires order-matters, or simply limiting the user-allowed namespace
    • Limiting the namespace also presents backwards compatibility problems -- if version 1.1 lacks a --foo flag and a user declares mytask(foo='bar'), and then we unknowingly add --foo to core in 1.2, that user's code will break.
  • May require more setup on the user side, re: explicitly declaring each task's args/kwargs via decorators or whatnot
    • Though we could introspect the function signature and automatically create some, if needed
  • Doesn't allow for positional arguments unless we go the delimiter route.

Potential solutions

  • Continue using Fabric's "custom parsing" solution pretty much as-is
    • See above re: pluses/minuses
  • Try coming up with a "better" custom parsing solution/syntax, if there are any
    • What do other tools like Make, Rake, Thor etc use?
      • Thor uses regular flags + positional arguments, seems to simply ignore the "multiple tasks vs one task + positional args" problem, and uses "pass all flags to all tasks" to handle multi-task invocation.
        • Don't like this very much -- it "works" but has the "all tasks invoked must have different args" requirement mentioned above.
      • make uses shell environment variables, which is similar to how Thor treats flags -- every task is going to get the same values for any overlapping names.
      • Rake uses custom parsing like we do, but uses taskname[args, here] instead of taskname:args,here. I find this actually worse than the colon we use, because some shells like zsh treat square-brackets specially and need extra escaping/quoting.
  • Allow custom parsing everywhere, but also allow use of flag args in single-task invocations
    • Plus: gives flag lovers what they want
    • Minus: "more than one way to do it" and its problems (newbie confusion, more code/bugs, more docs to write.)
  • Use flags 100% of the time, relying on ordering or delimiting flags to handle multi-task invocations
    • See above re: pluses/minuses
    • Possibly use argparse subcommands, but AFAIK those are again targeted at using a single subcommand per invoke.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions