The Fluidinfo Shell, Fish, already includes Unix-inspired commands for many tag-management tasks including listing tags and namespaces (ls), removing them (rm), creating them (touch and mkns/mkdir) as well an analogue of the Unix chmod permissions-changing command (perms). What about copying and renaming?
The Unix command for renaming files is mv (short for move). I imagine this is briefly confusing for newcomers to Unix, but the command is actually well named when all its functions are considered. In Unix, to rename a file from foo to bar one says:
mv foo bar
The same form can be used to rename a directory, say from private to secret:
mv private secret
The true appropriateness of the name mv becomes apparent only when the command is used for it third form, in which the destination is an existing directory. If etc is such an existing directory then
mv foo etc
will move foo into the directory etc; or, if you prefer, it renames foo as etc/foo. The same thing happens with a directory, i.e.
mv private etc
will move the directory private into etc as etc/private. We can also move several files at the same time:
mv foo private etc
will move both foo and private to etc., which is handy.
Should Fish do something similar?
I generally think of tags as being attached to objects, sometimes with values, pretty much exactly as the diagrams generated by http://abouttag.appspot.com show them. Here’s an example for Citizen Kane.
(You can generate this live, in a modern browser, by visiting here).
And I think of the (abstract) tags and namespaces as living in a tree, exactly like the directory structure in a hierarchical file system. Something like this, where the yellow folder icons represent namespaces and the tags are red.
The analogy can even be extended further by thinking of the value on a tag as being like a file’s contents; this seems particularly apt in cases where the tag values really do correspond to file contents, as is the case with Fish’s documentation. Using a pair of tricks stolen from Nicholas Tollervery (@ntoll), the documentation is actually stored in Fluidinfo, with the content of the index.html file stored in a tag called index.html under the fish namespace. So the full path for the tag that stores the front page of Fish’s documentation is fish/index.html and this (concrete) tag is stored on the object with the about tag fish. The URL for the documentation is then http://fluiddb.fluidinfo.com/about/fish/fish/index.html. The second “trick” is to set the MIME type of the value of fish/index.html on the fish object to text/html, which causes Fluidinfo to serve the content with that MIME type, so that as far as the internet is concerned, http://fluiddb.fluidinfo.com/about/fish/fish/index.html is regular HTML web content. The same applies to all the other pages. It will come as no surprise to learn that the fish documentation is published programmatically, and that I have vague plans to add a publish command to Fish to allow a directory tree of files to be uploaded to Fluidinfo as a set of tags on namespaces on a nominated object.
It will not have escaped your attention in this digression, that a crucial difference between a file in a filesystem and a tag in Fluidinfo is that the tag may have arbitrarily many different values, each attached to a different object. It’s like having your file system partially replicated on every computer in the world, with different content on the subset of files stored on each.
This suggests a different way of thinking about the relationship between the tag hierarchy and objects, which is really the way that Fluidinfo’s end-points use them. In this view, each object has a partial copy of the (abstract) tag hierarchy instantiated on it, with values that are specific (and hopefully appropriate) to that object.
This is neatly illustrated by looking at a recursive listing of the fish user’s top-level namespace:
$ fish ls -R fish: _static/ h p tags.html a help.html perms.html test.html about.html i pwd.html touch.html abouttag.html index.html pwn.html u amazon.html install.html q unixlike.html b j r untag.html c k rm.html v cli.html l s version.html commands.html ls.html search.html w count.html m searchindex.js whoami.html d mkdir.html shell-fish.html x e mkns.html show.html y f n su.html z g normalize.html t index.html o tag.htmlfish/_static: basic.css default.css fish-doc-logo.png pygments.css def.css doctools.js jquery.js searchtools.js
All the tags that look like filenames (the ones containing a dot) are tags that exist in exactly one place—on the object with the about tag fish. (They could occur in multiple places, however. For example, I could publish the full set of documentation to version-numbered objects fish v3.12, fish v3.11 etc., rather than constantly replacing the old with the new, as I do now.)
The other tags (those with single-letter names) are there to allow anyone playing with the online version of Fish (shell-fish) to tag things with a set of different tags, and might exist on any set of objects in Fluidinfo.
In this view, the full path for a concrete tag can be expressed either in terms of its about tag (if it has one) or its ID. In the case of fish/index.html, the only concrete instantiation taht exists today lives under the /about endpoint, at
or, for those of you who prefer UUIDs, under the /objects endpoint, at
This suggests an alternative possible syntax for moving concrete tags. We could recast
mv -a 'film:citizen kane' /rating -b 'film:citizen kane (1941)' star-rating
mv '/about/film:citizen kane/njr/rating' '/about/film:citizen kane (1941)/star-rating'
This approach is not without its attractions. It is rather elegant and unambiguous, and it completely eliminates the need for flags in this case, which can hardly fail to be a benefit. On balance, however, I think it’s probably not the way to go. It feels somewhat inconsistent with thre rest of Fish, it forces me to put the username in (which I don’t really want to do) and—to me—it feels slightly inverted (if logical). There’s also a potential problem that there’s technically ambiguity with respect to a potential user called about, but that probably isn’t such a worry.
But the more important reason is that I dont want to have to repeat the object specification if I do something like
mv '/about/film:citizen kane (1941)/njr/rating' '/about/film:citizen kane (1941)/star-rating'
In that case, the -a tag feels much better, and that seems like a strong reason for with with either -a and -b or repeated -a flags when shifting between different objects.
So at the moment I’m leaning strongly towards the first suggestions introduced above, using -a and -b as required. As ever, however, I’m interested in opinions. I expect it will be a while before I get around to implementing this anyway.