Command line argument formatting for flag values

Summary

This proposal seeks to address Guild’s hard-coded scheme for command line flag arguments, which does not accommodate short-form options and other script-specific alternatives. We suggest that a new arg-template flag attribute is added, which specifies how the flag value is formatted as command line arguments to the script.

This is not a breaking change.

This proposal is awaiting feedback.

Problem

Guild always uses the long-format option when specifying command line arguments for flag values. Consider the following Guild command:

guild run train.py foo=123

This causes the following command to be used when running train.py:

python -m train --foo 123

Even with a Guild file, there is no easy way to change this behavior. At the time of this proposal, the only way to correct for this is to use base arguments in the main spec. Here’s an operation that uses a single dash instead of the double dash.

train:
  main: train -foo ${foo}
  flags:
    foo:
      arg-skip: yes

Note the added work here:

  • Specify all of the alternative format flags in main
  • Prevent the manually specified flags from appearing again in the command using arg-skip

Proposed Approach

The above problem can be solved using a new arg-template flag attribute.

train:
  flags:
    foo:
      arg-template: -foo {value}

In cases where all flags follow the same argument formatting convention (e.g. single dash vs double-dash), a new flag-defaults attribute can be used to specify the arg format for all flags by default.

train:
  flag-defaults:
    arg-template: -{name} {value}

Alternative Approaches

Use arg-name to specify a short-form version

The arg-name flag attribute is used to specify the name of the argument that precedes the flag value in the command. E.g. if a flag is named learning-rate the default option is --learning-rate. arg-name can be used to change that to, say, lr:

train:
  flags:
    learning-rate:
      arg-name: lr

In this case, the command line argument will be --lr (double-dash).

If, on the other hand, the arg-name value included leading dashes, these could be used specify short formats:

train:
  flags:
    learning-rate:
      arg-name: -lr

I think this approach is weaker for the following reasons:

  • Not as flexible. The main proposal above supports any variable of formats, including {name}={value}.
  • It’s a bit obscure—feels like a hack to me.

Use arg-style to specify an pre-defined format option

Support the following pre-defined arg-style options:

  • long
  • short
  • assign

These would correspond to the following templates:

Style Template
long --{name} {value}
short -{name} {value}
assign {name}={value}

Advantages:

  • Arguably simpler than specifying a template

Disadvantages:

  • Not as flexible. We may end up having to add arg-template to support edge cases and be right back we started.

This approach is compatible with the primary proposal—both flag attributes can be supported.