Skip to content

Field selection #1226

@rgoldberg

Description

@rgoldberg

Field-Selection Options

--fields … & associated options allow commands that support --json to:

  • Select fields
  • Order fields
  • Rename fields
  • Format field values
  • Sort rows

--fields … & associated options affect all output formats (currently: tabular
& JSON).

Remove --price from search after field addition implemented.

Custom EBNF Syntax Definition

This custom flavor of EBNF (Extended Backus-Naur Form) is later used to describe
the command-line syntax for field-selection options & their values.

All values are case-sensitive.

Wildcard / EBNF Placeholder

*

Literal Text

"*"

"" is the escape for a literal ".

Value Description

{*}

* describes valid literal values, e.g., {non-negative integer}.

Value Placeholder (aka Non-Terminal Symbol)

<*>

* is the name of the value's type.

Standard-Escaping Text Placeholder

<text>

Non-empty string input that is literal except for \-escaped characters.

  • \ escapes the following character to itself (e.g., \n results in a literal
    n).
  • \ must be escaped unless it is the final character.
  • Whitespace is significant.

Required-Escaping Text Placeholder

<text\*>
<text\\*>
<text\*\\*>

Extends <text> specifying additional characters that must be escaped:

  • Characters in \* must be escaped when they are the first character.
  • Characters in \\* must be escaped everywhere.

Example

<text\@.+-\\=:/,>
  • @, ., + & - must be escaped if first.
  • \, =, :, / & , must be escaped throughout.

Grouping

( * )

Optional Singleton (0 or 1)

[ * ]

Optional Repetition (0 or More)

*…

Choice

* | *

Conditional Joiner

* _ * _ *

The central * is required iff non-empty content exists to both its left &
right within the same production.

Headers Option Spec

Controls the visibility & format of the headers row.

headers-option ::= "--no-headers" | "--headers" [ "=" <headers-format> ]

Standard: --no-headers

<headers-format> is reserved for future implementation (e.g., csv, bold,
underline).

Fields Option Spec

Contexts

A context exists for each command in a command stack:

Command Stack Most Specific Context Least Specific Context
mas config mas.config mas
mas list mas.list mas
mas lookup mas.lookup mas
mas outdated mas.outdated mas
mas search mas.search mas

The context stack for each command is ordered from most specific to least
specific context (e.g., the context stack for mas outdated is
mas.outdated, mas).

Field Specs

Configure how a field is included in the output, containing:

  • Required field name
  • Optional output label (defaults to the field name)
  • Optional value formatting (default formatting based on field name)
  • Optional row sorting

Field Spec Lists

A field spec list is an ordered group of field specs.

Effective List

The field spec list actually used for output for a command line.

Named Field Spec Lists

Field spec lists stored in a persistent configuration under a case-sensitive
name that is unique for a context.

mas provides Immutable Standard Named Field Spec
Lists
.

Users can define named field spec lists in any context.

Named field spec lists are found by:

  • Returning the first named field spec list found with a given name while
    iterating through the context stack for the current command from most to least
    specific context.
  • If no match is found, an error is reported.
Immutable Standard Named Field Spec Lists

Provided for each leaf command:

  • standard: The command's default tabular output field specs.
  • all: Field specs for all of the command's fields.

Provided for mas:

  • none (alias empty): No field specs.
Base List

The base named field spec list for computing the effective list.

The base list is set to:

  • A named field spec list referenced in the command line.
  • If no named field spec list is referenced in the command line: a
    user-configured per-output-format per-command default base list.
  • If no default base list is configured by the user: standard for tabular
    output & all for JSON output.

Fields Option

fields-option ::= "--fields " ( <standalone-spec> | <based-spec> )

The effective list is:

  • If <fields-option> is omitted: the default base list.
  • If --fields <standalone-spec> is supplied: sourced solely from
    <standalone-spec>; this is the equivalent of the base list being set to
    none.
  • If --fields <based-spec> is supplied: sourced from a base list as modified
    by the <based-spec>.

<standalone-spec> & <based-spec> are overlaid on top of the base list for
the current command line only; they do not persistently affect named field spec
lists.

Standalone Spec

standalone-spec             ::= <first-standalone-field-spec> [ "," <subsequent-standalone-field-spec> ]…
first-standalone-field-spec ::= <first-standalone-field-name> <field-modifiers>
first-standalone-field-name ::= <text\@.+-\\=:/,>

subsequent-standalone-field-spec ::= <subsequent-standalone-field-name> <field-modifiers>
subsequent-standalone-field-name ::= <text\\=:/,>

Each field spec in a <standalone-spec> appends a new output for its field.

Based Spec

based-spec ::= [ <base-list-section> ] _ "," _ [ <edits-section> ] _ "," _ [ <appends-section> ] _ "," _ [ <removals-section> ]
  • Computes the effective list from a resolved base list adjusted by
    modifications from the command line.
  • If <base-list-section> is omitted, the default base list is used.
  • Removals take precedence over everything else.
Base List Selection
base-list-section    ::= <base-list-prefix> [ <field-spec-list-name> ]
base-list-prefix     ::= "@"
field-spec-list-name ::= <text\\,>
  • If <field-spec-list-name> is omitted, the base list is all.
  • If no field spec list is named <field-spec-list-name> in the context stack,
    an error is reported.
In-Place Edits
edits-section ::= <edits-prefix> <first-edit-field-spec> [ "," <subsequent-edit-field-spec> ]…
edits-prefix  ::= "."

first-edit-field-spec ::= <first-edit-field-name> <field-modifiers>
first-edit-field-name ::= <text\\=:/,>

subsequent-edit-field-spec ::= <subsequent-edit-field-name> <field-modifiers>
subsequent-edit-field-name ::= <text\+-\\=:/,>
Appends (Moves & Additions)
appends-section ::= <appends-prefix> <first-append-field-spec> [ "," <subsequent-append-field-spec> ]…
appends-prefix  ::= "+"

first-append-field-spec ::= [ <addition-indicator> ] <first-append-field-name> <field-modifiers>
addition-indicator      ::= "+"
first-append-field-name ::= <text\+\\=:/,>

subsequent-append-field-spec ::= [ <addition-indicator> ] <subsequent-append-field-name> <field-modifiers>
subsequent-append-field-name ::= <text\+-\\=:/,>
  • Appends field specs to the base list. If a field spec already exists for the
    field name, and if the field spec:
    • Does not have an <addition-indicator>, then the existing field is moved to
      be appended to the effective list.
    • Has an <addition-indicator>, then a new output is appended for the same
      field.
  • The rightmost field spec for the same field takes precedence.
Removals
removals-section   ::= <removals-prefix> <removed-field-name> [ "," <removed-field-name> ]…
removals-prefix    ::= "-"
removed-field-name ::= <text\\,>
  • Removes field specs for the specified fields from the effective list.

Field Modifiers

field-modifiers ::= [ <label-part> ] [ <format-part> ] [ <sort-part> ]
Labelling
label-part ::= "=" [ <label> ]
label      ::= <text\\:/,>
  • An empty label (=) clears any inherited label for the field.
  • A field without an effective label uses its field name as its label.
  • Labels are used as:
    • Headers for tabular output.
    • Keys for JSON output.
Formatting
format-part   ::= ":" [ <format> ]
format        ::= <format-type> [ ":" <format-config> ]
format-type   ::= <text\\:/,>
format-config ::= <text\\/,>

Pre-existing <format-type>s:

  • default (used if no <format-section> was supplied): user-configurable
    default formatting per field name per context
  • standard: formatting used for default if none was configured by the user
  • verbatim (used if no <format> was supplied): outputs field value verbatim
    from input
  • "hidden": omits field from output; useful to sort by the field without
    displaying it
  • "by-value-map" [ ":" <value-map-name> ]: formats values by mapping from
    their respective values to a format. The value map name defaults to default,
    which maps to a per-command user-configurable value map name, which defaults
    to standard if not set by the user
Sorting
sort-part       ::= "/" [ <sort-spec> ]
sort-spec       ::= <sort-priority> [ <sort-option> ]…
sort-priority   ::= {non-negative integer}
sort-option     ::= <sort-direction>
sort-direction  ::= <sort-ascending> | <sort-descending>
sort-ascending  ::= "a"
sort-descending ::= "d"
  • An empty sort (/) clears inherited sorting for the field.
  • A field without an effective sort spec does not affect row sorting.
  • A field with an effective sort spec takes sort precedence over fields:
    • With a numerically higher <sort-priority>.
    • To its right with the same <sort-priority>.
  • If multiple mutually exclusive <sort-option>s are supplied (e.g.,
    <sort-ascending> & <sort-descending>), the rightmost takes precedence.
  • <sort-direction> defaults to <sort-ascending>.

Metadata

Metadata

Assignees

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions