Context Manager

The Context Manger offers a way to interact with short-to-medium-term context in and across script executions.

Context Manager
Photo by Mr Cup / Fabien Barral / Unsplash

We've just finished up a context manager for GroveOS! This will help set a temporary context (or memory) during script executions. In essence it's a sort of global variable, except this variable is global to the GroveOS instance you're currently running. It's distinct from the .env file as this context is meant to be dynamic, flexibly-typed, and semi-persistent in nature.

It's a simple file, a structured dataset that can be written to and read from like an in-memory database connection (indeed, what are all other databases but files that are written to and read from).

Here's an example context:

Name: Pisgah National Forest
State: North Carolina
Sections: 2
Note the GNU Recutils formatting

Why it's needed

Sometimes you need to write and read context during a script's execution that may evolve over the script's lifecycle. With .cache/context.rec, we can store structured contextual data to be accessed downstream within a single script or across many distinct script calls.

It's a nice hybrid between "long-term storage in a database" (requires defining a rigid and persistent schema) and an "in-memory variable" (requires export-ing for other scripts to use it). Think of it like your office desktop – you may have temporary files that you are working with in the moment. You could store them in some file cabinet, but we aren't resting, we're working!

While at work, it's more convenient to just have your materials out in front of you in a flexibly typed manner. You don't have to think about where or how to categorize your working context upon every step of work in a given day.

Finally, from a script author perspective, it's easier and more elegant to write call/ctx with simple arguments rather than "remember to define a $CTX variable in each script", "write out the filepath of some persistent dataset file", "cat the contents of stored data", etc.


How it works

The script call/ctx, has a few usage modes that help you interface with .cache/context.rec (a GNU Recutils database file).

Broad Selection & Declaration

The simplest interaction is calling the script with no arguments to show the current context.

Select 👇

call/ctx

Of course, that will return nothing the first time you run it. This is because we don't have active context yet, but we can easily set it up via an unflagged positional argument or piped in via stdin.

call/ctx 'Name: Matthew\nAge: 33\nOccupation: Software Developer'

# or

call/ctx <<<EOF
Name: Matthew
Age: 33
Occupation: Software Developer
EOF

# or

echo -e 'Name: Matthew\nAge: 33\nOccupation: Software Developer' | call/ctx
Note: when you declare the context, the script will return the context as confirmation. You can silence the output by passing -S.

Specific Selection

We can select data from our context using -e, -p, and -P.

Pick 👇
Use -p to pick a field and its value.

call/ctx -p Age
Age: 33

Pull 👇
Use -P to pull a value from a given field.

call/ctx -P Age
33
Note: If you have multiple records in the dataset, empty lines will delimit each record. Use -C to collapse those empty lines and delimit by newline instead.

Express 👇
Use -e to declare an selection expression (useful if you have multiple records in context).

call/ctx -e "Age > 32"
Name: Matthew
Age: 33
Occupation: Software Developer

Modify Context

We can modify the context using redeclares, -f, -s, -a, and -d (to overwrite, set, append, and delete data and fields).

Overwrite 👇
To fully overwrite, just redeclare fresh context (just like above).

call/ctx <<<EOF
Name: Matthew
Age: 34
Occupation: Software Developer
EOF

...or we can more selectively declare modification, using -f for field name and -s for set value. This is simpler and keeps the other fields intact.

call/ctx -f Age -s 34

Append 👇
Use -a to append a field.

call/ctx -f Location -a "Asheville, NC"

Delete a field 👇
Use -d to delete a field.

call/ctx -f Age -d

In the end, it's simple – we're just selecting from and writing to a special Recutils dataset (as we would with recsel or recset). Since we're just working in the scope of temporary context, we can use the call/ctx shorthand without needing verbose recutils calls and other scaffolding.

Using call/ctx gives us an expressive yet simple interface to short-to-medium-term context needs. 🙌

Subscribe to the newsletter