Clay Examples

This document contains a number of examples of interacting with Clay using its various tasks. Sections correspond to the general details in the API Reference document.

Most examples will either use |pass to just send a task or the following thread to send a task and take the resulting gift. You can save the following thread to the /ted directory of the %base desk on a fake ship:

send-task-take-gift.hoon

/-  spider
/+  strandio
=,  strand=strand:spider
^-  thread:spider
|=  arg=vase
=/  m  (strand ,vase)
^-  form:m
=/  uarg  !<  (unit task:clay)  arg
?~  uarg
  (strand-fail:strand %no-arg ~)
=/  =task:clay  u.uarg
=/  =card:agent:gall  [%pass /foo %arvo %c task]
;<  ~  bind:m  (send-raw-card:strandio card)
;<  res=[wire sign-arvo]  bind:m  take-sign-arvo:strandio
~&  +>:res
(pure:m !>(~))

%warp

See the Read and Subscribe section of the API Reference document for general details.

%sing

Here we'll look at reading files by passing Clay a %warp task with a %sing $rave and receiving a %writ gift containing the data in response.

Using the send-task-take-gift.hoon thread, let's try reading gen/hood/hi.hoon:

You should see something like this as the output:

The $cage in the $riot of the %writ contains the file's data due to our use of an %x $care. It needn't be %x though. If we change it to %u, for example, we'll get a ? $cage instead:

Here's a breakdown of the task we sent:

%next

Here we'll look at subscribing to the next version of a file by passing Clay a %warp task with a %next $rave and receiving a %writ gift when the file changes.

Using the send-task-take-gift.hoon thread, let's subscribe to the next version of foo.txt:

Now, in unix, create a file called foo.txt in the root of the $base directory of your ship. In the dojo, hit backspace to disconnect the thread from the dojo prompt and run |commit %base. You should see something like:

As you can see, the $riot in the %writ includes a $cage with the data of /foo/txt due to our use of an %x $care.

Now run the thread again, and this time delete the file in unix and again |commit %base in the dojo. You should see:

You can see the $riot is just ~ due to the file being deleted.

Here's a breakdown of the task we sent:

%mult

Here we'll look at subscribing to the next version of multiple files by passing Clay a %warp task with a %mult $rave and receiving a %wris gift when any of the files change.

This thread will subscribe to /foo/txt with an %x $care and /bar/txt with a %u $care. It will print out the %wris it gets back from Clay.

sub-mult.hoon

Save the above to ted/sub-mult.hoon, |commit %base and run with -sub-mult. Now, create foo.txt and bar.txt in your base directory, hit backspace in the dojo to disconnect the thread and run |commit %base. You should see something like:

You'll notice that, unlike a %writ, the %wris doesn't give you the data. It merely tells you the $cares and $paths of the files that changed. If you need to actually get the data, you can just scry or send a request for the files in question.

Now, run the thread again, open bar.txt in an editor, modify its contents, save it and |commit %base. You'll notice you didn't receive a %wris. This is because we subscribed to /bar/txt with %u care and its existence didn't change.

Lastly, delete foo.txt and |commit %base. You should see something like:

As you can see, a relevant change to any of the subscribed files will trigger a response, not just when all of them change.

Here's a breakdown of the task we sent:

%many

Here we'll look at subscribing to a range of changes to a desk by passing Clay a %warp task with a %many $rave and receiving %writ gifts when changes occur.

This thread will subscribe to changes to your %base desk for the next three minutes. The track is %.y so it will only inform you of changes, not send the full $nako. It will only get updates if the specified file exists. It contains a main-loop that will take an arbitrary number of $signs and print them out in the dojo. Since it never ends, you'll need to stop it with the :spider|kill command in the dojo.

sub-many.hoon

Make sure foo.txt doesn't exist in the root of your %base desk. Save this to ted/sub-many.hoon, |commit %base, run it like -sub-many /foo/txt, and hit backspace in the dojo to free up the dojo prompt. Now, add a file called bar.txt to your desk and |commit %base. You should see something like:

Notice you've received no %writ from Clay. This is because /foo/txt doesn't exist. Now, create foo.txt and |commit %base again. You should see:

Now that /foo/txt exists it will inform you of updates. Note that if you delete /foo/txt again it will again stop sending updates.

Now try adding baz.txt:

Now wait until the three minutes is up and try making a change, for example deleting baz.txt:

You can see that along with the normal %writ it's also sent a second %writ with a null $riot to indicate the subscription has ended. This is because it has now passed the end of the range of $cases to which you subscribed.

Run :spider|kill to stop the thread.

Here's a breakdown of the task we sent:

Cancel Subscription

Here we'll look at cancelling a subscription by sending Clay a %warp task with a null (unit rave) in the $riff.

This thread will subscribe to the %next version of /foo/txt, then immediately cancel the subscription and wait for a response to print (which it will never receive).

stop-sub.hoon

Save the above to /ted/stop-sub.hoon, |commit %base, run it with -stop-sub and hit backspace to detach it from the dojo prompt. Now, add foo.txt to the root of your %base desk and |commit %base. You should see:

As you can see we've received no %writ. We can thus conclude the subscription has successfully been cancelled.

Run :spider|kill to stop the thread.

Here's a breakdown of the task we sent:

%info

See the Write and Modify section of the API Reference document for general details.

%ins

Here we'll look at adding a file by sending Clay a %info task containing a %ins $miso.

Let's try adding a foo.txt file with 'foo' as its contents:

If you have a look in the base of your pier you'll see there's now a file called foo.txt with the text foo in it.

We've created the $cage of the content like [%txt !>(~['foo'])], if you want to write something besides a text file you'd just give it the appropriate $mark and $vase.

Here's a breakdown of the task we sent:

%del

Here we'll look at deleting a file by sending Clay a %info task containing a %del $miso.

Let's try deleting the foo.txt file created in the previous example:

If you have a look in the base of your pier you'll see the foo.txt file is now gone.

Here's a breakdown of the task we sent:

%mut

Identical to the %ins example, just replace %ins with %mut.

Multiple Changes

Here we'll look at changing multiple files in one request by sending Clay a %info task containing multiple $miso in the $soba.

Since $soba is just a +list of $miso, you can add a bunch of $miso and they'll all be applied. This thread adds three files and then deletes them. Here there's only one type of $miso in each request but you could mix different types together too.

multi-change.hoon

Save to ted/multi-change.hoon, |commit %base, and run:

Manage Mounts

See the Manage Mounts section of the API Reference document for general details.

%boat

Here we'll look at requesting the list of existing mount points on a ship by sending Clay a %boat task and receiving a %hill gift.

Using the send-task-take-gift.hoon thread, let's make such a request:

%mont

Here we'll look at mounting desks, directories and files to unix by sending Clay a %mont task.

Let's first try mounting our %landscape desk:

If you look in your pier, you should now see a /landscape folder which contains the contents of that desk.

If we make a %boat request as detailed in the %boat section, we'll now see the mount point listed:

Note the mount point doesn't need to match a desk, file, or directory. We can also do:

And you'll now see that there's a /wibbly-wobbly folder with the contents of the %base desk. You'll also notice we can mount the same file or directory more than once. There's no problem having %base mounted to both $base and /wibbly-wobbly. The only requirement is that their mount points be unique.

Let's try mounting a subdirectory and a single folder:

If you look in your pier you'll now see a /gen folder with the contents of /gen and a hi.hoon file by itself. Notice how the file extension has been automatically added.

%ogre

Here we'll look at unmounting desks, directories and files by sending Clay a %ogre task.

Let's unmount what we mounted in the %mont section. First we'll unmount the %landscape desk:

Our custom mount point %wibbly-wobbly:

And the single hi.hoon we previously mounted by specifying its mount point %hi:

If we specify a non-existent mount point it will fail with an error printed to the dojo like:

If we give it an unmounted $beam it will not print an error but still won't work.

%dirk

Here we'll look at committing changed files by sending Clay a %dirk task.

This task performs the same function as the |commit dojo command.

With your %base desk mounted, try adding a file and send a %dirk to commit the change:

Clay will print the changed files to the dojo with a leading +, - or : to indicate a new file, deleted file and changed file respectively.

If you have the same desk mounted to multiple points, a committed change in one mount will also update the others.

Merge Desks

See the Merge Desks section of the API Reference document for general details.

%merg

Here we'll look at merging desks by sending Clay a %merg task and receiving a %mere gift in response.

First, using the send-task-take-gift.hoon thread, let's try creating a new desk:

Now if we scry for our desks we'll see %foo is there:

Next, we'll create a merge conflict and try a couple of things. Mount %foo with |mount /=foo=, then add a foo.txt to both desks but with different text in each and |commit them.

Now we'll try merging %base into %foo with a %mate strategy:

As you can see, the merge has failed. Let's try again with a %meld strategy:

Now the merge has succeeded and the %mere notes the file with a merge conflict. If we try with a %only-that strategy:

...you can see it's overwritten the /foo/txt in the %foo desk and the %mere now has an empty +set, indicating no merge conflicts.

Next, let's look at subscribing for future changes. Since the $case is specified explicitly in the %merge task, we can set it in the future:

Now change the text in the foo.txt in the %base desk, hit backspace to detach the thread and |commit %base. After the two minutes pass you should see:

You can also specify it by revision number or label.

Permissions

See the Permissions section of the API Reference document for general details.

%perm

Here we'll look at setting permissions by sending Clay a %perm task.

First, let's allow ~nes to read /gen/hood/hi/hoon:

...and we'll do a %p scry to see that the permission was set:

You can see that ~nes is now in the read whitelist. Next, let's try a write permission:

You can see ~nes can now write to /ted:

Since we've set it for the whole /ted directory, if we check a file inside it we'll see it also has this permission:

...and you'll notice that src tells us it's inherited the rule from /ted.

Now let's try setting both read and write permissions:

Lastly, let's look at deleting a permission rule we've previously set. To do that, we just send a null (unit rule) in the $rite.

For example, to remove a read permission (or write if you specify %w):

...and to remove both read and write at the same time:

As you can see it's back to the default inherited from /.

Here's a breakdown of a %perm task:

%cred

Here we'll look at creating a permission group by sending Clay a %cred task.

Let's create a group called 'foo' with a few ships:

We'll check it with the next kind of task: %crew.

%crew

Here we'll look at retrieving permission groups by sending Clay a %crew task and receiving a %cruz gift in response.

Let's check, using the send-task-take-gift.hoon thread, for the permission group created in the %cred example:

%crow

Here we'll look at retrieving a list of all files and directories in all desks which have permissions set for a group by sending Clay a %crow task and receiving a %croz gift in response.

First we'll set a couple of permissions for the foo group we created in the %cred section:

Notice we use a %.n in the $whom to indicate a group rather than the %.y of a ship.

Now we'll use the send-task-take-gift.hoon thread to try %crow:

Foreign Ships

See the Foreign Ships section of the API Reference document for general details.

%warp - Remote

Here we'll look at reading files on a foreign ship by sending Clay a %warp task with a foreign ship in the wer field and receiving a %writ gift in response.

We'll use a fake ~nes as the the foreign ship and a fake ~zod as the local ship.

First we'll set permissions on the foreign ship. Create a file called foo.txt in the %base of ~nes, then send a %perm request to allow ~zod to read and write the file:

If we scry the file for its permissions with a %p $care, we'll see ~zod is now whitelisted:

Back on ~zod: Using the send-task-take-gift.hoon thread, send a %x read request for /foo/txt on ~nes like:

As you can see, we've received a %writ containing the requested data just as we would with a local request. Let's try a %u:

If we send a %d request however, it will crash:

%merg - Remote

To merge a foreign desk into a local one, you just send Clay a %merg task (as you would for a local merge) and specify the foreign ship in the her field. For an example, see the %merg section.

The foreign ship will respond only if correct permissions have been set. See the %perm section for an example.

Last updated