@@ -0,0 +1,356 @@
10+# Using Urbit from Unix
12+With `urb` at your Unix command line, you can execute hoon, run
13+dojo commands, and more. Additionally, with `fuse`, you can
14+inspect the urbit namespace.
21+These commands are in the a [separate
22+repo](https://github.com/urbit/urb). Clone this repo to get the
25+You'll also need the `requests` and `fuse` libraries for python.
26+If you have `pip`, you can just run:
29+pip install requests fuse-python
32+Otherwise, on Ubuntu, run:
35+apt-get install python-requests python-fuse
38+Then you can either run the python commands from the git repo, or
39+put them somewhere in your path.
43+`urb` transfers data from a source to a sink. Examples of data
44+sources include literal data, a file, a URL, or some
45+tranformation of another source. Examples of data sinks are
46+stdout, output file, POST request, or dojo command.
48+Here are some examples. This takes the literal data "hello
49+world" and sends it to stdout (the default sink).
51+ urb --data 'hello world'
53+Let's run some hoon code at the dojo.
55+ urb --dojo '(add 2 2)'
57+Let's convert a markdown file to html.
59+ urb --data @@file.md -m md -m html
61+Mount the `%home` desk. This syncs the `home` desk into the pier
64+ urb --dojo '+hood/mount /=home=' --app hood
68+Sources can be any of the following:
70+- `-d, --dojo command` runs a dojo command. This is commonly
71+ naked hoon code, but it can also be a generator, or any of the
72+ other ways the dojo gets data.
74+- `-D, --data text` is literal text data, as a cord.
76+- `-c, --clay path` pulls data from Urbit's filesystem.
78+- `-u, --url url` pulls data from a URL.
80+- `-m, --mark mark source` converts the output from another source to
81+ a new 'mark' (datatype).
83+- `-H, --hoon code source` transforms the output of another
84+ source by running it through some hoon code.
86+- `[source-0 source-1 ...]`. Sources can be combined into tuples
87+ of different sources.
89+Any of the arguments to a source (except in the "compound
90+sources" `--mark` and `--hoon`) can be replaced by `-` to
91+represent stdin or `@@filename` to pull data in from a Unix file.
92+Thus, `urb [-D @@file1 -D - -D @@file2]` is equivalent to Unix's
95+Additionally, if no source is specified, `--data -` (stdin as
96+literal text data) is assumed.
100+- `-s, --stdout` outputs to stdout. This is the default.
102+- `-f, --output-file path` writes to a unix file.
104+- `-C, --output-clay path` writes to Urbit's filesystem.
106+- `-U, --output-url url` sends a POST request with the data to
109+- `-p, --app app` sends the data to an urbit app.
111+- `-x, --command` outputs to a literal dojo command.
115+Urbit's namespace is accessible through the `fuse` command.
116+`fuse` takes all the normal FUSE arguments, which you can see
117+with `fuse -h`. Generally, you just run `fuse MOUNT-POINT`.
119+When accessing the namespace through `fuse`, everything is
120+read-only. If you want to write to Clay, mount a desk, as
123+Let's look first in the Clay portion of the Urbit namespace.
124+Assume we've mounted to `./pt`.
127+ app arvo gen lib mar ren sec sur web
128+ $ ls ./pt/c/=/=/=/arvo
129+ ames behn clay dill eyre ford gall hoon zuse
131+Those `=`s aren't decorative. The first `=` means "current
132+ship", the second "current desk", and the third "current
133+revision". Let's try something a little more exciting.
135+This runs the Unix `diff` command on the first and current
136+versions of the `app/gh/hoon` file, showing all the changes we've
140+$ diff pt/c/=/=/{1,=}/app/gh/hoon
142+< (malt (turn issues |=(issue:gh [(rsh 3 2 (scot %ui number)) ~])))
144+> %- malt ^- (list {@ta $~})
145+> :- [%gh-list-issues ~]
146+> (turn issues |=(issue:gh [(rsh 3 2 (scot %ui number)) ~]))
148+< read-y=(read-get /issues)
150+> read-y=(read-static %gh-list-issues ~)
151+> sigh-x=sigh-list-issues-x
152+> sigh-y=sigh-list-issues-y
154+> ^- place :: /issues/mine/<mark>
155+> :* guard={$issues $mine @t $~}
157+> read-y=|=(pax/path [ost %diff %arch `0vsen.tinel ~])
159+< ^- place :: /issues/by-repo/<user>/<repo>
161+> ^- place :: /issues/by-repo/<user>/<repo>/<number>
163+< read-y=(read-static ~)
168+> ?: ((sane %tas) -.+>+>.pax)
170+> (read-static %gh-issue ~)
173+> sigh-y=sigh-strange
175+> ^- place :: /issues/by-repo/<u>/<r>/<n>/<mark>
176+> :* guard={$issues $by-repo @t @t @t @t $~}
178+> read-y=|=(pax/path [ost %diff %arch `0vsen.tinel ~])
179+> sigh-x=sigh-strange
182+Urbit's namespace is not just revisioned, but global. Here's a
183+diff of our version of `arvo/gall/hoon` compared to the one on
187+$ diff pt/c/{~bud,=}/=/=/arvo/gall/hoon
193+> =+ `path`(flop tyl)
195+> [mar=i tyl=(flop t)]
197+< ((slog leaf+"peek find fail" >tyl< ~) [~ ~])
199+> ((slog leaf+"peek find fail" >tyl< >mar< ~) [~ ~])
208+Besides Clay, the namespace contains Gall apps. One common usage
209+of the app namespace is to expose APIs. For example, if you
210+start the `%gh` app (`|start %gh`), you can do things like `cat`
211+an issue from a repository.
214+$ cat pt/g/=/gh/=/issues/by-repo/philipcmonktest/testing/7/txt
215+title: big news! (#7)
217+creator: philipcmonktest
218+created-at: 2016-03-24T22:27:33Z
219+assignee: philipcmonktest
220+labels: invalid, wontfix, help wanted
222+url: https://api.github.com/repos/philipcmonktest/testing/issues/7
224+Yup, that's it. i mean, maybe it's a bit longer than that.
226+But you get the point, right?
231+Or all open issues for a repository.
234+$ cat pt/g/=/gh/=/issues/by-repo/philipcmonktest/testing/txt
235+title: i found a bug! (#11)
237+creator: philipcmonktest
238+created-at: 2016-04-14T23:14:49Z
242+url: https://api.github.com/repos/philipcmonktest/testing/issues/11
245+----------------------------------------
246+title: more newz (#8)
248+creator: philipcmonktest
249+created-at: 2016-03-24T22:29:16Z
253+url: https://api.github.com/repos/philipcmonktest/testing/issues/8
255+Yup, that's it. i mean, maybe it's a bit longer than that.
257+But you get the point, right?
260+----------------------------------------
261+title: big news! (#7)
263+creator: philipcmonktest
264+created-at: 2016-03-24T22:27:33Z
265+assignee: philipcmonktest
266+labels: invalid, wontfix, help wanted
268+url: https://api.github.com/repos/philipcmonktest/testing/issues/7
270+Yup, that's it. i mean, maybe it's a bit longer than that.
272+But you get the point, right?
275+----------------------------------------
276+title: something different (#4)
278+creator: philipcmonktest
279+created-at: 2016-01-26T21:45:08Z
280+assignee: philipcmonktest
281+labels: duplicate, help wanted, question, bug
283+url: https://api.github.com/repos/philipcmonktest/testing/issues/4
286+Don't like the textual format? How about we get the raw JSON
287+(and prettyprint it).
290+$ cat pt/g/=/gh/=/issues/by-repo/philipcmonktest/testing/7/json | python -m json.tool
293+ "avatar_url": "https://avatars.githubusercontent.com/u/16787461?v=3",
294+ "events_url": "https://api.github.com/users/philipcmonktest/events{/privacy}",
295+ "followers_url": "https://api.github.com/users/philipcmonktest/followers",
296+ "following_url": "https://api.github.com/users/philipcmonktest/following{/other_user}",
297+ "gists_url": "https://api.github.com/users/philipcmonktest/gists{/gist_id}",
299+ "html_url": "https://github.com/philipcmonktest",
301+ "login": "philipcmonktest",
302+ "organizations_url": "https://api.github.com/users/philipcmonktest/orgs",
303+ "received_events_url": "https://api.github.com/users/philipcmonktest/received_events",
304+ "repos_url": "https://api.github.com/users/philipcmonktest/repos",
305+ "site_admin": false,
306+ "starred_url": "https://api.github.com/users/philipcmonktest/starred{/owner}{/repo}",
307+ "subscriptions_url": "https://api.github.com/users/philipcmonktest/subscriptions",
309+ "url": "https://api.github.com/users/philipcmonktest"
311+ "body": "Yup, that's it. i mean, maybe it's a bit longer than that.\r\n\r\nBut you get the point, right?\r\n\r\nCode `is` cool!",
315+ "comments_url": "https://api.github.com/repos/philipcmonktest/testing/issues/7/comments",
316+ "created_at": "2016-03-24T22:27:33Z",
317+ "events_url": "https://api.github.com/repos/philipcmonktest/testing/issues/7/events",
318+ "html_url": "https://github.com/philipcmonktest/testing/issues/7",
324+ "url": "https://api.github.com/repos/philipcmonktest/testing/labels/wontfix"
327+ "labels_url": "https://api.github.com/repos/philipcmonktest/testing/issues/7/labels{/name}",
331+ "repository_url": "https://api.github.com/repos/philipcmonktest/testing",
333+ "title": "big news!",
334+ "updated_at": "2016-03-24T22:27:33Z",
335+ "url": "https://api.github.com/repos/philipcmonktest/testing/issues/7",
337+ "avatar_url": "https://avatars.githubusercontent.com/u/16787461?v=3",
338+ "events_url": "https://api.github.com/users/philipcmonktest/events{/privacy}",
339+ "followers_url": "https://api.github.com/users/philipcmonktest/followers",
340+ "following_url": "https://api.github.com/users/philipcmonktest/following{/other_user}",
341+ "gists_url": "https://api.github.com/users/philipcmonktest/gists{/gist_id}",
343+ "html_url": "https://github.com/philipcmonktest",
345+ "login": "philipcmonktest",
346+ "organizations_url": "https://api.github.com/users/philipcmonktest/orgs",
347+ "received_events_url": "https://api.github.com/users/philipcmonktest/received_events",
348+ "repos_url": "https://api.github.com/users/philipcmonktest/repos",
349+ "site_admin": false,
350+ "starred_url": "https://api.github.com/users/philipcmonktest/starred{/owner}{/repo}",
351+ "subscriptions_url": "https://api.github.com/users/philipcmonktest/subscriptions",
353+ "url": "https://api.github.com/users/philipcmonktest"