WOODY'S
FINDINGS

What's new in Scout (command-line) 4.0.0?

Checkout the project page

This page deals with the scout command-line tool. To find out what's new in the Swift package, please refer to this page.

New command-line features list


Breaking changes


Set/Add group values

It’s now possible to set or add a group value to a path. An array is a list of values separated by commas and enclosed by square brackets. A dictionary is a list of (key, value) parts separated by double points. Those values are separated by commas and enclosed by squared brackets.

Some examples

Set Tom colors to an array made of strings (automatically inferred).

scout add -i People.json -f json "Tom.colors=[Blue, White, Yellow]"

Set Robert weekdays to a dictionary of integers (automatically inferred).

scout add -i People.json -f json "Robert.weekdays=[monday: 5, thirsday: 3]"

It’s possible to nest values in each other. Although it’s not recommenced to nest too much, this can be useful when the value is built programmatically.

Set Robert weekdays to a dictionary of arrays

scout add -i People.json -f json \
"Robert.weekdays=[monday: [1, 2], thirsday: [3, 4]]"

Do note that type inferring still work. This is why it’s not needed in the examples to clearly specify the type. It’s still possible also to force a type, like a string rather than an integer. For instance

scout add -i People.json -f json "Robert.scores=['123', '456']"

To force a string is done by enclosing with ”/” or ”’” like /23/ or '89'. Forcing a real (Plist only) is done by enclosing with tildes ”~” like ~23~.


Empty group values

As adding a value to a path will no more create dictionaries or arrays on the fly, the new method is to add empty arrays or dictionaries. To do so, specify [] for an empty array and {} for an empty dictionary.

For instance, to add a new empty array to Robert scores.

scout add -i People.json -f json "Robert.scores=[]"

And to add a new dictionary for Robert weekdays.

scout add -i People.json -f json "Robert.weekdays={}"

Add new values

I believe this will provide a clearer and more robust interface to add new value. If it’s possible to specify arrays and dictionaries directly with the new syntax, it might be safer or easier to do it programmatically (in a loop for example).

colors=(Red White Blue)
scout add -m $file -f $format "Tom.colors=[]"

for color in $colors; do
    scout add -m $file -f $format "Tom.colors[#]=$color"
done

Work with Zsh arrays

Add arrays

It’s possible set or add an array from Zsh directly by enclosing it with square brackets.

colors=(Red White Blue)
scout add -i People.json -f json "Tom.colors=[$colorsArray]"

Set associative arrays

The same is true for associatives arrays which are a counterpart of dictionaries. To specify a dictionary to Scout, it’s possible to provide a Zsh associative array as a list of key values enclosed with curl brackets.

declare -A ducks=(Riri 10 Fifi 20 Loulou 30)
dict=${(@kv)ducks}
scout add -i $file -f $format "Tom.ducks={$dict}"

Get an array or dictionary in Zsh

Zsh integration goes in the other way with two new export functions. To get a 1-dimension array from the data, the option —export|-e can be used with the array option and by enclosing the result with brackets.

hobbies=("${(@f)$(scout read -i People.json -f json "Robert.hobbies" -e array)}")
echo $hobbies[1] # video games

The same goes for dictionaries to associative arrays with the dictionary option.

declare -A movie=("${(@f)$(scout read -i People.json -f json "Suzanne.movies[0]" -e dictionary)}")
echo $movie[title] # Tomorrow is so far

XML attributes

When working with XML and the read features, Scout will allow to read an attribute with a key element.

For instance with the following XML.

<Tom score="20">
    <height>175</height>
    <age>68</age>
</Tom>

It’s now possible to read the score value.

scout read -i File.json -f json "Tom.score"
<Tom score="20">
    <height>175</height>
    <age>68</age>
</Tom>

The following will output 20

scout read -i File.json -f json "Tom.score"

When the following will output 68.

scout read -i File.json -f json "Tom.[1]"

CSV import

A new CSV import feature is available to convert a CSV input as JSON, Plist, YAML or XML. A cool feature when working with named headers is that they will be treated as paths. This can shape very precisely the structure of the converted data. For instance, the following CSV

name.first;name.last;hobbies[0];hobbies[1]
Robert;Roni;acting;driving
Suzanne;Calvin;singing;play
Tom;Cattle;surfing;watching movies

will be converted to the following Json structure.

[
  {
    "hobbies" : [
      "acting",
      "driving"
    ],
    "name" : {
      "first" : "Robert",
      "last" : "Roni"
    }
  },
  {
    "hobbies" : [
      "singing",
      "play"
    ],
    "name" : {
      "first" : "Suzanne",
      "last" : "Calvin"
    }
  },
  {
    "name" : {
      "first" : "Tom",
      "last" : "Cattle"
    },
    "hobbies" : [
      "surfing",
      "watching movies"
    ]
  }
]

When there are no headers, the input will be treated as a one or two dimension(s) array.

scout csv -i people.csv -s ";" -f json --headers

The headers|--no-headers flag is needed to specify whether the CSV string begins with named headers. It’s also possible to use the standard input to provide the CSV data.