diff --git a/bin/brass.pill b/bin/brass.pill index 72a256ae6b..cc8c83ed8b 100644 --- a/bin/brass.pill +++ b/bin/brass.pill @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:29a948ebcf5d82577b3d1271cb8d0c6cf1fa8b63a324ad2ef43e73ad5dcfe62c -size 4846052 +oid sha256:f738f60e9e028081864f317106f623d2f21a5fe5c2f6fdd83576e22d21a8c6a6 +size 14862847 diff --git a/bin/ivory.pill b/bin/ivory.pill index 3bdc23eabc..829304a932 100644 --- a/bin/ivory.pill +++ b/bin/ivory.pill @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6c9cec5d3dd639a82b1b867375225e6becb9f234338ef0a4cb2626ae72ba8944 -size 1265620 +oid sha256:9fbfbe75a6685df444621ebd27677716fd0abf7113020f3274c3b5c209e3616e +size 1304972 diff --git a/bin/solid.pill b/bin/solid.pill index f125db3892..bc6fa88e92 100644 --- a/bin/solid.pill +++ b/bin/solid.pill @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:657e130a063598dc9e4800039f6dde1e7e4b7a3c56e57561a46a4f06641da48e -size 17337052 +oid sha256:581c9b713aa12126f3a618d75bf4254bb431f633fbfc76941663391d3d13cdb0 +size 16742515 diff --git a/nix/ops/test/builder.sh b/nix/ops/test/builder.sh index 4a852ab3f5..2746797abf 100644 --- a/nix/ops/test/builder.sh +++ b/nix/ops/test/builder.sh @@ -22,50 +22,59 @@ trap shutdown EXIT herb ./ship -p hood -d '+hood/mass' -# Start the test app +# Run the unit tests and then print scrollback +herb ./ship -d '~& ~ ~& %test-unit-start ~' +herb ./ship -d '####-test %/tests' +herb ./ship -d '~& ~ ~& %test-unit-end ~' + +# Start and run the test app herb ./ship -p hood -d '+hood/start %test' -# Run the %cores tests -herb ./ship -d '~& ~ ~& %start-test-cores ~' -herb ./ship -p test -d ':- %cores /' -herb ./ship -d '~& %finish-test-cores ~' +herb ./ship -d '~& ~ ~& %test-agents-start ~' +herb ./ship -p test -d '%agents' +herb ./ship -d '~& ~ ~& %test-agents-end ~' +herb ./ship -d '~& ~ ~& %test-generators-start ~' +herb ./ship -p test -d '%generators' +herb ./ship -d '~& ~ ~& %test-generators-end ~' + +herb ./ship -d '~& ~ ~& %test-marks-start ~' +herb ./ship -p test -d '%marks' +herb ./ship -d '~& ~ ~& %test-marks-end ~' + +# compact the loom, comparing memory use before and after herb ./ship -p hood -d '+hood/mass' -# Run the %renders tests -herb ./ship -d '~& ~ ~& %start-test-renders ~' -herb ./ship -p test -d ':- %renders /' -herb ./ship -d '~& %finish-test-renders ~' - -# Run the test generator -herb ./ship -d '+test, =seed `@uvI`(shaz %reproducible)' > test-generator-output - -cat test-generator-output || true - -herb ./ship -p hood -d '+hood/mass' - -herb ./ship -d '~& ~ ~& %start-pack ~' +herb ./ship -d '~& ~ ~& %pack-start ~' herb ./ship -p hood -d '+hood/pack' -herb ./ship -d '~& ~ ~& %finish-pack ~' +herb ./ship -d '~& ~ ~& %pack-end ~' + +herb ./ship -p hood -d '+hood/mass' shutdown # Collect output -cp urbit-output test-cores-output -cp urbit-output test-renders-output +cp urbit-output test-output-unit +cp urbit-output test-output-agents +cp urbit-output test-output-generators +cp urbit-output test-output-marks rm urbit-output -sed -i '0,/start-test-renders/d' test-renders-output -sed -i '/finish-test-renders/,$d' test-renders-output +sed -i '0,/test-unit-start/d' test-output-unit +sed -i '/test-unit-end/,$d' test-output-unit -sed -i '0,/start-test-cores/d' test-cores-output -sed -i '/finish-test-cores/,$d' test-cores-output +sed -i '0,/test-agents-start/d' test-output-agents +sed -i '/test-agents-end/,$d' test-output-agents + +sed -i '0,/test-generators-start/d' test-output-generators +sed -i '/test-generators-end/,$d' test-output-generators + +sed -i '0,/test-marks-start/d' test-output-marks +sed -i '/test-marks-end/,$d' test-output-marks mkdir $out -cp test-renders-output $out/renders -cp test-cores-output $out/cores -cp test-generator-output $out/generator +cp -r test-output-* $out/ set +x diff --git a/pkg/arvo/app/aqua.hoon b/pkg/arvo/app/aqua.hoon index b10b9556a0..748a2ee2f5 100644 --- a/pkg/arvo/app/aqua.hoon +++ b/pkg/arvo/app/aqua.hoon @@ -163,7 +163,9 @@ $ =. snap +.p.poke-result =. ..abet-pe (publish-event tym ue) - =. ..abet-pe (handle-effects ((list ovum) -.p.poke-result)) + =. ..abet-pe + ~| ova=-.p.poke-result + (handle-effects ;;((list ovum) -.p.poke-result)) $ :: :: Peek @@ -380,13 +382,12 @@ %c %clay %d %dill %e %eyre - %f %ford %g %gall %j %jael %g %gall == =/ pax - /(scot %p our.hid)/home/(scot %da now.hid)/sys/vane/[vane] + /(scot %p our.hid)/work/(scot %da now.hid)/sys/vane/[vane] =/ txt .^(@ %cx (weld pax /hoon)) [/vane/[vane] [%veer v pax txt]] => .(this ^+(this this)) @@ -400,7 +401,7 @@ :_ ~ %- unix-event %- %*(. file-ovum:pill-lib directories slim-dirs) - /(scot %p our.hid)/home/(scot %da now.hid) + /(scot %p our.hid)/work/(scot %da now.hid) =^ ms all-state (poke-pill pil) (emit-cards ms) :: diff --git a/pkg/arvo/app/chat-cli.hoon b/pkg/arvo/app/chat-cli.hoon index 20065b4843..959a1f2707 100644 --- a/pkg/arvo/app/chat-cli.hoon +++ b/pkg/arvo/app/chat-cli.hoon @@ -451,6 +451,7 @@ :: ++ parser |^ + %+ stag | %+ knee *command |. ~+ =- ;~(pose ;~(pfix mic -) message) ;~ pose diff --git a/pkg/arvo/app/chat-hook.hoon b/pkg/arvo/app/chat-hook.hoon index 0005f07f7b..3e1156be5a 100644 --- a/pkg/arvo/app/chat-hook.hoon +++ b/pkg/arvo/app/chat-hook.hoon @@ -14,11 +14,17 @@ +$ versioned-state $% state-0 state-1 + state-2 + == +:: ++$ state-2 + $: %2 + state-base == :: +$ state-1 $: %1 - loaded-cards=(list card) + loaded-cards=* state-base == +$ state-0 [%0 state-base] @@ -39,7 +45,7 @@ $% [%chat-update update:store] == -- -=| state-1 +=| state-2 =* state - :: %- agent:dbug @@ -66,29 +72,30 @@ ^- (quip card _this) |^ =/ old !<(versioned-state old-vase) - ?: ?=(%1 -.old) - :_ this(state old) - %+ murn ~(tap by wex.bol) - |= [[=wire =ship =term] *] - ^- (unit card) - ?. &(?=([%mailbox *] wire) =(our.bol ship) =(%chat-store term)) - ~ - `[%pass wire %agent [our.bol %chat-store] %leave ~] - :: path structure ugprade logic - :: - =/ keys=(set path) (scry:cc (set path) %chat-store /keys) - =/ upgraded-state - %* . *state-1 - synced synced - invite-created invite-created - allow-history allow-history - loaded-cards - %- zing - ^- (list (list card)) - %+ turn ~(tap in keys) generate-cards - == - :_ this(state upgraded-state) - loaded-cards.upgraded-state + =^ moves state + ^- (quip card state-2) + ?: ?=(%2 -.old) + ^- (quip card state-2) + `old + :: + ?: ?=(%1 -.old) + ^- (quip card state-2) + :_ [%2 +>.old] + %+ murn ~(tap by wex.bol) + |= [[=wire =ship =term] *] + ^- (unit card) + ?. &(?=([%mailbox *] wire) =(our.bol ship) =(%chat-store term)) + ~ + `[%pass wire %agent [our.bol %chat-store] %leave ~] + ^- (quip card state-2) + :: path structure ugprade logic + :: + =/ keys=(set path) (scry:cc (set path) %chat-store /keys) + :_ [%2 +.old] + %- zing + ^- (list (list card)) + (turn ~(tap in keys) generate-cards) + [moves this] :: ++ generate-cards |= old-chat=path @@ -234,10 +241,7 @@ ?+ mark (on-poke:def mark vase) %json (poke-json:cc !<(json vase)) %chat-action (poke-chat-action:cc !<(action:store vase)) - %noun - ?: =(%store-load q.vase) - [loaded-cards.state state(loaded-cards ~)] - [~ state] + %noun [~ state] :: %chat-hook-action (poke-chat-hook-action:cc !<(action:hook vase)) @@ -459,7 +463,7 @@ (chats-of-group pax) |= chat=path ^- (list card) - =/ owner (~(get by synced) chat) + =/ owner (~(get by synced.state) chat) ?~ owner ~ ?. =(u.owner our.bol) ~ %- zing diff --git a/pkg/arvo/app/chat-store.hoon b/pkg/arvo/app/chat-store.hoon index b37b1f0445..70daf9ecfe 100644 --- a/pkg/arvo/app/chat-store.hoon +++ b/pkg/arvo/app/chat-store.hoon @@ -5,17 +5,20 @@ |% +$ card card:agent:gall +$ versioned-state - $% state-zero - state-one - state-two + $% state-0 + state-1 + state-2 == :: -+$ state-zero [%0 =inbox:store] -+$ state-one [%1 =inbox:store] -+$ state-two [%2 =inbox:store] ++$ state-0 [%0 =inbox:store] ++$ state-1 [%1 =inbox:store] ++$ state-2 [%2 =inbox:store] ++$ admin-action + $% [%trim ~] + == -- :: -=| state-two +=| state-2 =* state - :: %- agent:dbug @@ -33,15 +36,25 @@ ++ on-save !>(state) ++ on-load |= old-vase=vase + ^- (quip card _this) + |^ =/ old !<(versioned-state old-vase) - ?: ?=(%2 -.old) - [~ this(state old)] - =/ reversed-inbox=inbox:store - %- ~(run by inbox.old) + =? old ?=(%0 -.old) + (old-to-2 inbox.old) + =? old ?=(%1 -.old) + (old-to-2 inbox.old) + :_ this(state [%2 inbox.old]) + [%pass /trim %agent [our.bowl %chat-store] %poke %noun !>([%trim ~])]~ + :: + ++ old-to-2 + |= =inbox:store + ^- state-2 + :- %2 + %- ~(run by inbox) |= =mailbox:store ^- mailbox:store [config.mailbox (flop envelopes.mailbox)] - [~ this(state [%2 reversed-inbox])] + -- :: ++ on-poke ~/ %chat-store-poke @@ -52,6 +65,7 @@ ?+ mark (on-poke:def mark vase) %json (poke-json:cc !<(json vase)) %chat-action (poke-chat-action:cc !<(action:store vase)) + %noun [~ (poke-noun:cc !<(admin-action vase))] == [cards this] :: @@ -148,6 +162,32 @@ [~ ~ %noun !>((swag [start (sub end start)] envelopes))] == :: +++ poke-noun + |= nou=admin-action + ^- _state + ~& %trimming-chat-store + %_ state + inbox + %- ~(urn by inbox) + |= [=path mailbox:store] + ^- mailbox:store + =/ [a=* out=(list envelope:store)] + %+ roll envelopes + |= $: =envelope:store + o=[[hav=(set serial:store) curr=@] out=(list envelope:store)] + == + ?: (~(has in hav.o) uid.envelope) + [[hav.o curr.o] out.o] + :- + ^- [(set serial:store) @] + [(~(put in hav.o) uid.envelope) +(curr.o)] + ^- (list envelope:store) + [envelope(number curr.o) out.o] + =/ len (lent out) + ~? !=(len (lent envelopes)) [path [%old (lent envelopes)] [%new len]] + [[len len] (flop out)] + == +:: ++ poke-json |= jon=json ^- (quip card _state) @@ -197,8 +237,11 @@ [~ state] =. letter.envelope.action (evaluate-letter [author letter]:envelope.action) =^ envelope u.mailbox (prepend-envelope u.mailbox envelope.action) - :- (send-diff path.action action(envelope envelope)) - state(inbox (~(put by inbox) path.action u.mailbox)) + :_ state(inbox (~(put by inbox) path.action u.mailbox)) + ?: =((mod number.envelope 5.000) 0) + :- [%pass /trim %agent [our.bol %chat-store] %poke %noun !>([%trim ~])] + (send-diff path.action action(envelope envelope)) + (send-diff path.action action(envelope envelope)) :: ++ handle-messages |= act=action:store @@ -213,6 +256,7 @@ |- ^- (quip card _state) ?~ envelopes.act :_ state(inbox (~(put by inbox) path.act u.mailbox)) + :- [%pass /trim %agent [our.bol %chat-store] %poke %noun !>([%trim ~])] %+ send-diff path.act [%messages path.act 0 (lent evaluated-envelopes) evaluated-envelopes] =. letter.i.envelopes.act (evaluate-letter [author letter]:i.envelopes.act) diff --git a/pkg/arvo/app/chat-view.hoon b/pkg/arvo/app/chat-view.hoon index 5dbd0a9e55..2a13eb8d3f 100644 --- a/pkg/arvo/app/chat-view.hoon +++ b/pkg/arvo/app/chat-view.hoon @@ -1,19 +1,19 @@ :: chat-view: sets up chat JS client, paginates data, and combines commands :: into semantic actions for the UI :: -/- *permission-store, - *permission-hook, - *group-store, - *invite-store, - *metadata-store, - *permission-group-hook, - *chat-hook, - *metadata-hook, - *rw-security, - hook=chat-hook -/+ *server, default-agent, verb, dbug, - store=chat-store, - view=chat-view +/- *permission-store +/- *permission-hook +/- *group-store +/- *invite-store +/- *metadata-store +/- *permission-group-hook +/- *chat-hook +/- *metadata-hook +/- *rw-security +/- hook=chat-hook +/+ *server, default-agent, verb, dbug +/+ store=chat-store +/+ view=chat-view :: ~% %chat-view-top ..is ~ |% @@ -96,7 +96,9 @@ ++ truncated-inbox ^- inbox:store =/ =inbox:store - .^(inbox:store %gx /=chat-store/(scot %da now.bol)/all/noun) + =/ our (scot %p our.bol) + =/ now (scot %da now.bol) + .^(inbox:store %gx /[our]/chat-store/[now]/all/noun) %- ~(run by inbox) |= =mailbox:store ^- mailbox:store @@ -403,7 +405,12 @@ ++ chat-scry |= pax=path ^- (unit mailbox:store) - =. pax ;:(weld /=chat-store/(scot %da now.bol)/mailbox pax /noun) + =. pax + ;: weld + /(scot %p our.bol)/chat-store/(scot %da now.bol)/mailbox + pax + /noun + == .^((unit mailbox:store) %gx pax) :: ++ maybe-group-from-chat diff --git a/pkg/arvo/app/contact-hook.hoon b/pkg/arvo/app/contact-hook.hoon index 2415380ec1..b5a2b83fb8 100644 --- a/pkg/arvo/app/contact-hook.hoon +++ b/pkg/arvo/app/contact-hook.hoon @@ -456,20 +456,30 @@ ++ contacts-scry |= pax=path ^- (unit contacts) - =. pax ;:(weld /=contact-store/(scot %da now.bol)/contacts pax /noun) + =. pax + ;: weld + /(scot %p our.bol)/contact-store/(scot %da now.bol)/contacts + pax + /noun + == .^((unit contacts) %gx pax) :: ++ invite-scry |= uid=serial ^- (unit invite) =/ pax - /=invite-store/(scot %da now.bol)/invite/contacts/(scot %uv uid)/noun + ;: weld + /(scot %p our.bol)/invite-store/(scot %da now.bol) + /invite/contacts/(scot %uv uid)/noun + == .^((unit invite) %gx pax) :: ++ group-scry |= pax=path - ^- (unit group) - .^((unit group) %gx ;:(weld /=group-store/(scot %da now.bol) pax /noun)) + .^ (unit group) + %gx + ;:(weld /(scot %p our.bol)/group-store/(scot %da now.bol) pax /noun) + == :: ++ pull-wire |= pax=path diff --git a/pkg/arvo/app/contact-view.hoon b/pkg/arvo/app/contact-view.hoon index f30f85b504..e6fc820c9f 100644 --- a/pkg/arvo/app/contact-view.hoon +++ b/pkg/arvo/app/contact-view.hoon @@ -1,14 +1,15 @@ :: contact-view: sets up contact JS client and combines commands :: into semantic actions for the UI :: -/- *group-store, - *group-hook, - *invite-store, - *contact-hook, - *metadata-store, - *metadata-hook, - *permission-group-hook, - *permission-hook +/- *group-store +/- *group-hook +/- *invite-store +/- *contact-hook +/- *metadata-store +/- *metadata-hook +/- *permission-group-hook +/- *permission-hook +:: /+ *server, *contact-json, default-agent, dbug |% +$ versioned-state @@ -256,11 +257,16 @@ :: ++ all-scry ^- rolodex - .^(rolodex %gx /=contact-store/(scot %da now.bol)/all/noun) + .^(rolodex %gx /(scot %p our.bol)/contact-store/(scot %da now.bol)/all/noun) :: ++ contact-scry |= pax=path ^- (unit contact) - =. pax ;:(weld /=contact-store/(scot %da now.bol)/contact pax /noun) + =. pax + ;: weld + /(scot %p our.bol)/contact-store/(scot %da now.bol)/contact + pax + /noun + == .^((unit contact) %gx pax) -- diff --git a/pkg/arvo/app/debug/index.html b/pkg/arvo/app/debug/index.html index b16e317b03..eb37ada11d 100644 --- a/pkg/arvo/app/debug/index.html +++ b/pkg/arvo/app/debug/index.html @@ -12,8 +12,8 @@
- - + + diff --git a/pkg/arvo/app/dojo.hoon b/pkg/arvo/app/dojo.hoon index bba65e646c..3a56309f49 100644 --- a/pkg/arvo/app/dojo.hoon +++ b/pkg/arvo/app/dojo.hoon @@ -23,10 +23,10 @@ poy/(unit dojo-project) :: working $: :: sur: structure imports :: - sur=(list cable:ford) + sur=(list cable:clay) :: lib: library imports :: - lib=(list cable:ford) + lib=(list cable:clay) == var/(map term cage) :: variable state old/(set term) :: used TLVs @@ -89,7 +89,7 @@ $: mad/dojo-command :: operation num/@ud :: number of tasks cud/(unit dojo-source) :: now solving - pux/(unit path) :: ford working + pux/(unit path) :: working pro/(unit vase) :: prompting loop per/(unit sole-edit) :: pending reverse job/(map @ud dojo-build) :: problems @@ -100,6 +100,17 @@ -- => |% +:: TODO: move to zuse? copied from clay +:: +++ with-face |=([face=@tas =vase] vase(p [%face face p.vase])) +++ with-faces + =| res=(unit vase) + |= vaz=(list [face=@tas =vase]) + ^- vase + ?~ vaz (need res) + =/ faz (with-face i.vaz) + =. res `?~(res faz (slop faz u.res)) + $(vaz t.vaz) :: |parser-at: parsers for dojo expressions using :dir as working directory :: ++ parser-at @@ -177,13 +188,13 @@ :: ++ parse-cables %+ cook - |= cables=(list cable:ford) + |= cables=(list cable:clay) :+ 0 %ex ^- hoon :: :- %clsg %+ turn cables - |= cable=cable:ford + |= cable=cable:clay ^- hoon :: :+ %clhp @@ -194,7 +205,7 @@ (most ;~(plug com gaw) parse-cable) :: ++ parse-cable - %+ cook |=(a=cable:ford a) + %+ cook |=(a=cable:clay a) ;~ pose (stag ~ ;~(pfix tar sym)) (cook |=([face=term tis=@ file=term] [`face file]) ;~(plug sym tis sym)) @@ -312,23 +323,22 @@ dir dir(r [%da now.hid]) :: - ++ he-disc `disc:ford`[p q]:he-beam ++ he-beak `beak`[p q r]:he-beam - ++ he-rail `rail:ford`[[p q] s]:he-beam ++ he-parser (parser-at our.hid he-beam) :: ++ dy :: project work |_ dojo-project :: ++ dy-abet +>(poy `+<) :: resolve ++ dy-amok +>(poy ~) :: terminate - ++ dy-ford :: send work to ford - |= [way=wire schematic=schematic:ford] + :: +dy-sing: make a clay read request + :: + ++ dy-sing + |= [way=wire =care:clay =path] ^+ +>+> - ?> ?=($~ pux) - :: pin all builds to :now.hid so they don't get cached forever - :: + ?> ?=(~ pux) %- he-card(poy `+>+<(pux `way)) - [%pass way %arvo %f %build live=%.n schematic] + =/ [=ship =desk =case:clay] he-beak + [%pass way %arvo %c %warp ship desk ~ %sing care case path] :: ++ dy-request |= [way=wire =request:http] @@ -348,12 +358,8 @@ :: really shoud stop the thread as well :: [%pass u.pux %agent [our.hid %spider] %leave ~] - [%pass u.pux %arvo %f %kill ~] - :: - ++ dy-slam :: call by ford - |= {way/wire gat/vase sam/vase} - ^+ +>+> - (dy-ford way `schematic:ford`[%call [%$ %noun gat] [%$ %noun sam]]) + =/ [=ship =desk =case:clay] he-beak + [%pass u.pux %arvo %c %warp ship desk ~] :: ++ dy-errd :: reject change, abet |= {rev/(unit sole-edit) err/@u} @@ -479,7 +485,11 @@ ?: |(?=(^ per) ?=(^ pux) ?=(~ pro)) ~& %dy-no-prompt (dy-diff %bel ~) - (dy-slam /dial u.pro !>(txt)) + =/ res (mule |.((slam u.pro !>(txt)))) + ?: ?=(%| -.res) + %- (slog >%dy-done< p.res) + (dy-rash %bel ~) :: TODO: or +dy-abet(per ~) ? + (dy-made-dial %noun p.res) :: ++ dy-cast |* {typ/_* bun/vase} @@ -516,13 +526,13 @@ $lib %_ . lib - ((dy-cast (list cable:ford) !>(*(list cable:ford))) q.cay) + ((dy-cast (list cable:clay) !>(*(list cable:clay))) q.cay) == :: $sur %_ . sur - ((dy-cast (list cable:ford) !>(*(list cable:ford))) q.cay) + ((dy-cast (list cable:clay) !>(*(list cable:clay))) q.cay) == :: $dir =+ ^= pax ^- path @@ -637,7 +647,12 @@ ~& %dy-edit-busy =^ lic say (~(transmit sole say) dat) (dy-diff %mor [%det lic] [%bel ~] ~) - (dy-slam(per `dat) /edit u.pro !>((tufa buf.say))) + => .(per `dat) + =/ res (mule |.((slam u.pro !>((tufa buf.say))))) + ?: ?=(%| -.res) + %- (slog >%dy-edit< p.res) + (dy-rash %bel ~) :: TODO: or +dy-abet(per ~) ? + (dy-made-edit %noun p.res) :: ++ dy-type :: sole action |= act/sole-action @@ -657,43 +672,78 @@ !>(~) (slop (dy-vase p.i.src) $(src t.src)) :: - ++ dy-silk-vase |=(vax/vase [%$ %noun vax]) :: vase to silk - ++ dy-silk-sources :: arglist to silk - |= src/(list dojo-source) - ^- schematic:ford - [%$ %noun (dy-sore src)] - :: - ++ dy-silk-config :: configure - |= {cay/cage cig/dojo-config} - ^- [wire schematic:ford] + ++ dy-run-generator + !. + |= [cay=cage cig=dojo-config] + ^+ +>+> ?. (~(nest ut [%cell [%atom %$ ~] %noun]) | p.q.cay) - :: - :: naked gate + :: naked generator; takes one argument :: ?. &(?=({* ~} p.cig) ?=(~ q.cig)) ~|(%one-argument !!) - :- /noun - :+ %call [%$ %noun q.cay] - [%$ %noun (dy-vase p.i.p.cig)] - :: + =/ res (mule |.((slam q.cay (dy-vase p.i.p.cig)))) + ?: ?=(%| -.res) + (he-diff(poy ~) %tan p.res) :: TODO: or +dy-rash ? + (dy-hand %noun p.res) :: normal generator :: - :- ?+ -.q.q.cay ~|(%bad-gen ~_((sell (slot 2 q.cay)) !!)) - $say /gent - $ask /dial + :: A normal generator takes as arguments: + :: - event args: date, entropy, beak (network location) + :: - positional arguments, as a list + :: - optional keyword arguments, as name-value pairs + :: + :: The generator is a pair of a result mark and a gate. + :: TODO: test %ask generators + :: + =/ wat (mule |.(!<(?(%ask %say) (slot 2 q.cay)))) + ?: ?=(%| -.wat) + (he-diff(poy ~) %tan p.wat) + =- =/ res (mule -) + ?: ?=(%| -.res) + (he-diff(poy ~) %tan leaf+"dojo: generator failure" p.res) + ?- p.wat + %ask (dy-made-dial %noun p.res) + %say (dy-made-gent %noun p.res) == - =+ gat=(slot 3 q.cay) - :+ %call [%$ %noun gat] - :+ [%$ %noun !>([now=now.hid eny=eny.hid bec=he-beak])] - (dy-silk-sources p.cig) - :+ %mute [%$ %noun (fall (slew 27 gat) !>(~))] - ^- (list [wing schematic:ford]) - %+ turn ~(tap by q.cig) - |= {a/term b/(unit dojo-source)} - ^- [wing schematic:ford] - :- [a ~] - :+ %$ %noun - ?~(b !>([~ ~]) (dy-vase p.u.b)) + :: gat: generator gate + :: som: default gat sample + :: ven: event arguments + :: poz: positional arguments + :: kev: key-value named arguments + :: kuv: default keyword arguments + :: sam: fully populated sample + :: rog: default gat sample + :: + |. ^- vase + =/ gat=vase (slot 3 q.cay) + =/ som=vase (slot 6 gat) + =/ ven=vase !>([now=now.hid eny=eny.hid bec=he-beak]) + =/ poz=vase (dy-sore p.cig) + =/ kev=vase + =/ kuv=(unit vase) (slew 7 som) + ?: =(~ q.cig) + (fall kuv !>(~)) + =/ soz=(list [var=term vax=vase]) + %~ tap by + %- ~(run by q.cig) + |=(val=(unit dojo-source) ?~(val !>([~ ~]) (dy-vase p.u.val))) + ~| keyword-arg-failure+~(key by q.cig) + %+ slap + (with-faces kuv+(need kuv) rep+(with-faces soz) ~) + :+ %cncb [%kuv]~ + %+ turn soz + |= [var=term *] + ^- [wing hoon] + [[var]~ [%wing var %rep ~]] + :: + =/ sam=vase :(slop ven poz kev) + ?. (~(nest ut p.som) | p.sam) + ~> %slog.1^leaf+"dojo: nest-need" + ~> %slog.0^(skol p.som) + ~> %slog.1^leaf+"dojo: nest-have" + ~> %slog.0^(skol p.sam) + !! + (slam gat sam) :: ++ dy-made-dial :: dialog product |= cag/cage @@ -742,51 +792,81 @@ ++ dy-make :: build step ^+ +> ?> ?=(^ cud) - =+ bil=q.u.cud :: XX =* - ?: ?=($ur -.bil) - (dy-request /hand `request:http`[%'GET' p.bil ~ ~]) - ?: ?=($te -.bil) - (dy-wool-poke p.bil q.bil) - %- dy-ford - ^- [path schematic:ford] - ?- -.bil - $ge (dy-silk-config (dy-cage p.p.p.bil) q.p.bil) - $dv [/hand [%core [he-disc (weld /hoon (flop p.bil))]]] - $ex [/hand (dy-mare p.bil)] - $sa [/hand [%bunt he-disc p.bil]] - $as [/hand [%cast he-disc p.bil [%$ (dy-cage p.q.bil)]]] - $do [/hand [%call (dy-mare p.bil) [%$ (dy-cage p.q.bil)]]] - $tu :- /hand - :+ %$ %noun - |- ^- vase - ?~ p.bil !! - =+ hed=(dy-vase p.i.p.bil) - ?~ t.p.bil hed - (slop hed $(p.bil t.p.bil)) + =/ bil q.u.cud + ?- -.bil + %ur (dy-request /hand `request:http`[%'GET' p.bil ~ ~]) + %te (dy-wool-poke p.bil q.bil) + %ex (dy-mere p.bil) + %dv (dy-sing hand+p.bil %a (snoc p.bil %hoon)) + %ge (dy-run-generator (dy-cage p.p.p.bil) q.p.bil) + %sa + =+ .^(=dais:clay cb+(en-beam:format he-beak /[p.bil])) + (dy-hand p.bil bunt:dais) + :: + %as + =/ cag=cage (dy-cage p.q.bil) + =+ .^(=tube:clay cc+(en-beam:format he-beak /[p.bil]/[p.cag])) + (dy-hand p.bil (tube q.cag)) + :: + %do + =/ gat (dy-eval p.bil) + ?: ?=(%| -.gat) + (he-diff(poy ~) %tan p.gat) + =/ res (mule |.((slam q.p.gat (dy-vase p.q.bil)))) + ?: ?=(%| -.res) + (he-diff(poy ~) %tan p.res) + (dy-hand %noun p.res) + :: + %tu + %+ dy-hand %noun + |- ^- vase + ?~ p.bil !! + =/ hed (dy-vase p.i.p.bil) + ?~ t.p.bil hed + (slop hed $(p.bil t.p.bil)) == + :: +dy-hoon-var: if input is a dojo variable lookup, perform it :: - ++ dy-hoon-mark :: XX architect + :: If the expression is a bare reference to a Dojo variable, + :: produce that variable's value; otherwise, produce ~. + :: + ++ dy-hoon-var =+ ^= ope |= gen/hoon ^- hoon ?: ?=(?($sgld $sgbn) -.gen) $(gen q.gen) =+ ~(open ap gen) ?.(=(gen -) $(gen -) gen) - |= gen/hoon ^- (unit mark) + |= gen/hoon ^- (unit cage) =. gen (ope gen) ?: ?=({$cnts {@ ~} ~} gen) - (bind (~(get by var) i.p.gen) head) + (~(get by var) i.p.gen) ~ + :: +dy-mere: execute hoon and complete construction step :: - ++ dy-mare :: build expression - |= gen/hoon - ^- schematic:ford - =+ too=(dy-hoon-mark gen) - =- ?~(too - [%cast he-disc u.too -]) - :+ %ride gen - :- [%$ he-hoon-head] - :^ %plan he-rail `coin`blob+** - `scaffold:ford`[he-rail zuse sur lib ~ ~] + ++ dy-mere + |= =hoon + =/ res (dy-eval hoon) + ?: ?=(%| -.res) + (he-diff(poy ~) %tan p.res) + (dy-hand p.res) + :: +dy-eval: run hoon source against the dojo subject + :: + :: TODO: use /lib and /sur imports to construct subject + :: + ++ dy-eval + |= =hoon + ^- (each cage tang) + ?^ val=(dy-hoon-var hoon) + &+u.val + !. + %- mule |. + :- %noun + =/ vaz=(list [term vase]) + (turn ~(tap by var) |=([lal=term cag=cage] [lal q.cag])) + =/ sut (slop !>([our=our now=now eny=eny]:hid) !>(..zuse)) + =? sut ?=(^ vaz) (slop (with-faces vaz) sut) + (slap sut hoon) :: ++ dy-step :: advance project |= nex/@ud @@ -875,38 +955,17 @@ :- %pro [& %$ (weld he-prow ?~(buf "> " "< "))] :: - ++ he-made :: result from ford - |= $: way=wire - date=@da - $= result - $% [%complete build-result=build-result:ford] - [%incomplete =tang] - == == + ++ he-writ + |= [way=wire =riot:clay] ^+ +> ?> ?=(^ poy) =< he-pine - ?- -.result - %incomplete - (he-diff(poy ~) %tan tang.result) - :: - %complete - ?- -.build-result.result - :: - %success - :: - %. (result-to-cage:ford build-result.result) - =+ dye=~(. dy u.poy(pux ~)) - ?+ way !! - {$hand ~} dy-hand:dye - {$dial ~} dy-made-dial:dye - {$gent ~} dy-made-gent:dye - {$noun ~} dy-made-noun:dye - {$edit ~} dy-made-edit:dye - == - :: - %error - (he-diff(poy ~) %tan message.build-result.result) - == == + ?+ way !! + [%hand *] + ?~ riot + (he-diff(poy ~) %tan >%generator-build-fail< >(snoc t.way %hoon)< ~) + (~(dy-hand dy u.poy(pux ~)) noun+!<(vase q.r.u.riot)) + == :: ++ he-unto :: result from agent |= {way/wire cit/sign:agent:gall} @@ -1449,7 +1508,7 @@ =^ moves state =< he-abet ?+ +<.sign-arvo ~|([%dojo-bad-take +<.sign-arvo] !!) - %made (he-made:he-full t.wire +>.sign-arvo) + %writ (he-writ:he-full t.wire +>.sign-arvo) %http-response (he-http-response:he-full t.wire +>.sign-arvo) == [moves ..on-init] diff --git a/pkg/arvo/app/file-server.hoon b/pkg/arvo/app/file-server.hoon index c20ce198f9..adc4e7125c 100644 --- a/pkg/arvo/app/file-server.hoon +++ b/pkg/arvo/app/file-server.hoon @@ -139,7 +139,7 @@ :* (scot %p our.bowl) q.byk.bowl (scot %da now.bowl) - -.u.clay-path + (lowercase -.u.clay-path) == ?. .^(? %cu scry-path) [not-found:gen %.n] =/ file (as-octs:mimes:html .^(@ %cx scry-path)) @@ -151,6 +151,17 @@ [~ %png] (png-response:gen file) == :: + ++ lowercase + |= upper=(list @t) + %+ turn upper + |= word=@t + %- crip + %+ turn (rip 3 word) + |= char=@t + ?. &((gte char 'A') (lte char 'Z')) + char + (add char ^~((sub 'a' 'A'))) + :: ++ get-clay-path |= pax=path ^- (unit [path ?]) diff --git a/pkg/arvo/app/goad.hoon b/pkg/arvo/app/goad.hoon index b3b04f030a..5e34f2151e 100644 --- a/pkg/arvo/app/goad.hoon +++ b/pkg/arvo/app/goad.hoon @@ -3,30 +3,15 @@ ^- agent:gall => |% - ++ warp - |= =bowl:gall - [%pass /clay %arvo %c %warp our.bowl %home ~ %next %z da+now.bowl /sys] - :: - ++ wait - |= =bowl:gall - [%pass /behn %arvo %b %wait +(now.bowl)] - :: ++ goad |= force=? :~ [%pass /gall %arvo %g %goad force ~] == -- -:: |_ =bowl:gall +* this . def ~(. (default-agent this %|) bowl) -++ on-init - :: subscribe to /sys and do initial goad - :: - [[(warp bowl) (wait bowl) ~] this] :: -++ on-save on-save:def -++ on-load on-load:def ++ on-poke |= [=mark =vase] ?: ?=([%noun * %go] +<) @@ -35,32 +20,19 @@ [(goad &) this] (on-poke:def mark vase) :: -++ on-watch on-watch:def -++ on-leave on-leave:def -++ on-peek on-peek:def -++ on-agent on-agent:def ++ on-arvo - |= [=wire =sign-arvo] - ?+ wire (on-arvo:def wire sign-arvo) - [%clay ~] - :: on writ, wait - :: - ?> ?=(%writ +<.sign-arvo) - :_ this - :~ (warp bowl) - (wait bowl) - == - :: - [%behn ~] - :: on wake, goad - :: - ?> ?=(%wake +<.sign-arvo) - ?^ error.sign-arvo - :_ this :_ ~ - [%pass /dill %arvo %d %flog %crud %goad-fail u.error.sign-arvo] - %- (slog leaf+"goad: recompiling all apps" ~) - [(goad &) this] + |= [wir=wire sin=sign-arvo] + ?+ wir (on-arvo:def wir sin) + [%clay ~] `this + [%behn ~] `this :: backcompat == :: +++ on-agent on-agent:def ++ on-fail on-fail:def +++ on-init on-init:def +++ on-leave on-leave:def +++ on-load on-load:def +++ on-peek on-peek:def +++ on-save on-save:def +++ on-watch on-watch:def -- diff --git a/pkg/arvo/app/group-hook.hoon b/pkg/arvo/app/group-hook.hoon index ebc19456d9..c560b450f6 100644 --- a/pkg/arvo/app/group-hook.hoon +++ b/pkg/arvo/app/group-hook.hoon @@ -68,7 +68,7 @@ ?. (~(has by synced.state) t.path) (on-watch:def path) =/ scry-path=^path - :(welp /=group-store/(scot %da now.bowl) t.path /noun) + :(welp /(scot %p our.bowl)/group-store/(scot %da now.bowl) t.path /noun) =/ grp=(unit group) .^((unit group) %gx scry-path) ?~ grp @@ -242,8 +242,13 @@ :: ++ group-scry |= pax=path - ^- (unit group) - .^((unit group) %gx ;:(weld /=group-store/(scot %da now.bol) pax /noun)) + .^ (unit group) + %gx + (scot %p our.bol) + %group-store + (scot %da now.bol) + (weld pax /noun) + == :: ++ update-subscribers |= [pax=path diff=group-update] diff --git a/pkg/arvo/app/hood.hoon b/pkg/arvo/app/hood.hoon index a210877243..e85a03e0a2 100644 --- a/pkg/arvo/app/hood.hoon +++ b/pkg/arvo/app/hood.hoon @@ -1,228 +1,107 @@ -:: :: :: -:::: /hoon/hood/app :: :: - :: :: :: -/? 310 :: zuse version -/- *sole -/+ sole, :: libraries - :: XX these should really be separate apps, as - :: none of them interact with each other in - :: any fashion; however, to reduce boot-time - :: complexity and work around the current - :: non-functionality of end-to-end acknowledgments, - :: they have been bundled into :hood - :: - :: |command handlers - hood-helm, hood-kiln, hood-drum, hood-write -:: :: :: -:::: :: :: - :: :: :: +/+ default-agent +/+ drum=hood-drum, helm=hood-helm, kiln=hood-kiln |% -++ hood-module - :: each hood module follows this general shape - => |% - +$ part [%module %0 pith] - +$ pith ~ - ++ take - |~ [wire sign-arvo] - *(quip card:agent:gall part) - ++ take-agent - |~ [wire gift:agent:gall] - *(quip card:agent:gall part) - ++ poke - |~ [mark vase] - *(quip card:agent:gall part) - -- - |= [bowl:gall own=part] - |_ moz=(list card:agent:gall) - ++ abet [(flop moz) own] - -- ++$ state + $: %7 + drum=state:drum + helm=state:helm + kiln=state:kiln + == ++$ any-state + $% state + [ver=?(%1 %2 %3 %4 %5 %6) lac=(map @tas fin-any-state)] + == ++$ any-state-tuple + $: drum=any-state:drum + helm=any-state:helm + kiln=any-state:kiln + == ++$ fin-any-state + $% [%drum any-state:drum] + [%helm any-state:helm] + [%kiln any-state:kiln] + [%write *] :: gets deleted + == -- -:: :: :: -:::: :: :: state handling - :: :: :: -!: -=> |% :: - ++ hood-old :: unified old-state - {?($1 $2 $3 $4 $5 $6) lac/(map @tas hood-part-old)} - ++ hood-1 :: unified state - {$6 lac/(map @tas hood-part)} :: - ++ hood-good :: extract specific - =+ hed=$:hood-head - |@ ++ $ - |: paw=$:hood-part - ?- hed - $drum ?>(?=($drum -.paw) `part:hood-drum`paw) - $helm ?>(?=($helm -.paw) `part:hood-helm`paw) - $kiln ?>(?=($kiln -.paw) `part:hood-kiln`paw) - $write ?>(?=($write -.paw) `part:hood-write`paw) - == - -- - ++ hood-head _-:$:hood-part :: initialize state - ++ hood-make :: - =+ $:{our/@p hed/hood-head} :: - |@ ++ $ - ?- hed - $drum (make:hood-drum our) - $helm *part:hood-helm - $kiln *part:hood-kiln - $write *part:hood-write - == - -- - ++ hood-part-old hood-part :: old state for ++prep - ++ hood-port :: state transition - |: paw=$:hood-part-old ^- hood-part :: - paw :: - :: :: - ++ hood-part :: current module state - $% {$drum $2 pith-2:hood-drum} :: - {$helm $0 pith:hood-helm} :: - {$kiln $0 pith:hood-kiln} :: - {$write $0 pith:hood-write} :: - == :: - -- :: -:: :: :: -:::: :: :: app proper - :: :: :: ^- agent:gall -=| hood-1 :: module states -=> |% - ++ help - |= hid/bowl:gall - |% - ++ able :: find+make part - =+ hed=$:hood-head - |@ ++ $ - =+ rep=(~(get by lac) hed) - =+ par=?^(rep u.rep `hood-part`(hood-make our.hid hed)) - ((hood-good hed) par) - -- - :: - ++ ably :: save part - =+ $:{(list) hood-part} - |@ ++ $ - [+<- (~(put by lac) +<+< +<+)] - -- - :: :: :: - :::: :: :: generic handling - :: :: :: - ++ prep - |= old/(unit hood-old) ^- (quip _!! _+>) - :- ~ - ?~ old +> - +>(lac (~(run by lac.u.old) hood-port)) - :: - ++ poke-hood-load :: recover lost brain - |= dat/hood-part - ?> =(our.hid src.hid) - ~& loaded+-.dat - [~ (~(put by lac) -.dat dat)] - :: - :: - ++ from-module :: create wrapper - |* _[identity=%module start=..$ finish=_abet]:(hood-module) - =- [wrap=- *start] :: usage (wrap handle-arm):from-foo - |* handle/_finish - |= a=_+<.handle - =. +>.handle (start hid (able identity)) - ^- (quip card:agent:gall _lac) - %- ably - ^- (quip card:agent:gall hood-part) - (handle a) - :: per-module interface wrappers - ++ from-drum (from-module %drum [..$ _se-abet]:(hood-drum)) - ++ from-helm (from-module %helm [..$ _abet]:(hood-helm)) - ++ from-kiln (from-module %kiln [..$ _abet]:(hood-kiln)) - ++ from-write (from-module %write [..$ _abet]:(hood-write)) - -- - -- -|_ hid/bowl:gall :: gall environment +=| =state +|_ =bowl:gall ++* this . + def ~(. (default-agent this %|) bowl) + drum-core (drum bowl drum.state) + helm-core (helm bowl helm.state) + kiln-core (kiln bowl kiln.state) +:: +++ on-fail on-fail:def ++ on-init - `..on-init -:: -++ on-save - !>([%6 lac]) + ^- step:agent:gall + =^ d drum.state on-init:drum-core + [d this] :: +++ on-leave on-leave:def +++ on-peek on-peek:def +++ on-save !>(state) ++ on-load |= =old-state=vase - =/ old-state !<(hood-old old-state-vase) - =^ cards lac - =. lac lac.old-state - ?- -.old-state - %1 ((wrap on-load):from-drum:(help hid) %1) - %2 ((wrap on-load):from-drum:(help hid) %2) - %3 ((wrap on-load):from-drum:(help hid) %3) - %4 ((wrap on-load):from-drum:(help hid) %4) - %5 ((wrap on-load):from-drum:(help hid) %5) - %6 `lac + ^- step:agent:gall + =+ !<(old=any-state old-state-vase) + =/ tup=any-state-tuple + ?+ -.old +.old + ?(%1 %2 %3 %4 %5 %6) + :* =-(?>(?=(%drum -<) ->) (~(got by lac.old) %drum)) + =-(?>(?=(%helm -<) ->) (~(got by lac.old) %helm)) + =-(?>(?=(%kiln -<) ->) (~(got by lac.old) %kiln)) + == == - [cards ..on-init] + =^ d drum.state (on-load:drum-core -.old drum.tup) + =^ h helm.state (on-load:helm-core -.old helm.tup) + =^ k kiln.state (on-load:kiln-core -.old kiln.tup) + [:(weld d h k) this] :: ++ on-poke |= [=mark =vase] - ^- (quip card:agent:gall agent:gall) - =/ h (help hid) - =^ cards lac - ?: =(%helm (end 3 4 mark)) - ((wrap poke):from-helm:h mark vase) - ?: =(%drum (end 3 4 mark)) - ((wrap poke):from-drum:h mark vase) - ?: =(%kiln (end 3 4 mark)) - ((wrap poke):from-kiln:h mark vase) - ?: =(%write (end 3 5 mark)) - ((wrap poke):from-write:h mark vase) - :: XX should rename and move to libs - :: - ?+ mark ~|([%poke-hood-bad-mark mark] !!) - %hood-load (poke-hood-load:h !<(hood-part vase)) - %atom ((wrap poke-atom):from-helm:h !<(@ vase)) - %dill-belt ((wrap poke-dill-belt):from-drum:h !<(dill-belt:dill vase)) - %dill-blit ((wrap poke-dill-blit):from-drum:h !<(dill-blit:dill vase)) - %hood-sync ((wrap poke-sync):from-kiln:h !<([desk ship desk] vase)) - == - [cards ..on-init] + ^- step:agent:gall + |^ + =/ fin (end 3 4 mark) + ?: =(%drum fin) poke-drum + ?: =(%helm fin) poke-helm + ?: =(%kiln fin) poke-kiln + :: + ?+ mark (on-poke:def mark vase) + %atom poke-helm(mark %helm-atom) + %dill-belt poke-drum(mark %drum-dill-belt) + %dill-blit poke-drum(mark %drum-dill-blit) + %hood-sync poke-kiln(mark %kiln-sync) + %write-sec-atom poke-helm(mark %helm-write-sec-atom) + == + ++ poke-drum =^(c drum.state (poke:drum-core mark vase) [c this]) + ++ poke-helm =^(c helm.state (poke:helm-core mark vase) [c this]) + ++ poke-kiln =^(c kiln.state (poke:kiln-core mark vase) [c this]) + -- :: ++ on-watch |= =path - =/ h (help hid) - =^ cards lac - ?+ path ~|([%hood-bad-path wire] !!) - [%drum *] ((wrap peer):from-drum:h t.path) - == - [cards ..on-init] -:: -++ on-leave - |= path - `..on-init -:: -++ on-peek - |= path - *(unit (unit cage)) + ^- step:agent:gall + ?+ path (on-watch:def +<) + [%drum *] =^(c drum.state (peer:drum-core +<) [c this]) + == :: ++ on-agent |= [=wire =sign:agent:gall] - =/ h (help hid) - =^ cards lac - ?+ wire ~|([%hood-bad-wire wire] !!) - [%helm *] ((wrap take-agent):from-helm:h wire sign) - [%kiln *] ((wrap take-agent):from-kiln:h wire sign) - [%drum *] ((wrap take-agent):from-drum:h wire sign) - [%write *] ((wrap take-agent):from-write:h wire sign) - == - [cards ..on-init] + ^- step:agent:gall + ?+ wire ~|([%hood-bad-wire wire] !!) + [%drum *] =^(c drum.state (take-agent:drum-core +<) [c this]) + [%helm *] =^(c helm.state (take-agent:helm-core +<) [c this]) + [%kiln *] =^(c kiln.state (take-agent:kiln-core +<) [c this]) + == +:: TODO: symmetry between adding and stripping wire prefixes :: ++ on-arvo - |= [=wire =sign-arvo] - =/ h (help hid) - =^ cards lac - ?+ wire ~|([%hood-bad-wire wire] !!) - [%helm *] ((wrap take):from-helm:h t.wire sign-arvo) - [%drum *] ((wrap take):from-drum:h t.wire sign-arvo) - [%kiln *] ((wrap take-general):from-kiln:h t.wire sign-arvo) - [%write *] ((wrap take):from-write:h t.wire sign-arvo) - == - [cards ..on-init] -:: -++ on-fail - |= [term tang] - `..on-init + |= [=wire syn=sign-arvo] + ^- step:agent:gall + ?+ wire ~|([%hood-bad-wire wire] !!) + [%drum *] =^(c drum.state (take-arvo:drum-core t.wire syn) [c this]) + [%helm *] =^(c helm.state (take-arvo:helm-core t.wire syn) [c this]) + [%kiln *] =^(c kiln.state (take-arvo:kiln-core t.wire syn) [c this]) + == -- diff --git a/pkg/arvo/app/invite-hook.hoon b/pkg/arvo/app/invite-hook.hoon index 22cb95b299..2e4cef97b9 100644 --- a/pkg/arvo/app/invite-hook.hoon +++ b/pkg/arvo/app/invite-hook.hoon @@ -100,14 +100,22 @@ |= pax=path ^- (unit invitatory) =. pax - ;:(weld /=invite-store/(scot %da now.bowl)/invitatory pax /noun) + ;: weld + /(scot %p our.bowl)/invite-store/(scot %da now.bowl)/invitatory + pax + /noun + == .^((unit invitatory) %gx pax) :: ++ invite-scry |= [pax=path uid=serial] ^- (unit invite) =. pax - ;:(weld /=invite-store/(scot %da now.bowl)/invite pax /(scot %uv uid)/noun) + ;: weld + /(scot %p our.bowl)/invite-store/(scot %da now.bowl)/invite + pax + /(scot %uv uid)/noun + == .^((unit invite) %gx pax) -- diff --git a/pkg/arvo/app/invite-view.hoon b/pkg/arvo/app/invite-view.hoon new file mode 100644 index 0000000000..666ed54730 --- /dev/null +++ b/pkg/arvo/app/invite-view.hoon @@ -0,0 +1,17 @@ +/+ default-agent +^- agent:gall +|_ =bowl:gall ++* this . + def ~(. (default-agent this %|) bowl) + step `step:agent:gall`[~ this] +++ on-init on-init:def +++ on-save on-save:def +++ on-load on-load:def +++ on-poke |=(* step) +++ on-watch on-watch:def +++ on-leave |=(* step) +++ on-peek |=(* ~) +++ on-agent |=(* step) +++ on-arvo |=(* step) +++ on-fail on-fail:def +-- diff --git a/pkg/arvo/app/landscape/img/Chat.png b/pkg/arvo/app/landscape/img/.png similarity index 100% rename from pkg/arvo/app/landscape/img/Chat.png rename to pkg/arvo/app/landscape/img/.png diff --git a/pkg/arvo/app/landscape/img/chat.png b/pkg/arvo/app/landscape/img/chat.png new file mode 100644 index 0000000000..58223a5d63 Binary files /dev/null and b/pkg/arvo/app/landscape/img/chat.png differ diff --git a/pkg/arvo/app/landscape/img/ChatSwitcherClosed.png b/pkg/arvo/app/landscape/img/chatswitcherclosed.png similarity index 100% rename from pkg/arvo/app/landscape/img/ChatSwitcherClosed.png rename to pkg/arvo/app/landscape/img/chatswitcherclosed.png diff --git a/pkg/arvo/app/landscape/img/ChatSwitcherLink.png b/pkg/arvo/app/landscape/img/chatswitcherlink.png similarity index 100% rename from pkg/arvo/app/landscape/img/ChatSwitcherLink.png rename to pkg/arvo/app/landscape/img/chatswitcherlink.png diff --git a/pkg/arvo/app/landscape/img/Chevron.png b/pkg/arvo/app/landscape/img/chevron.png similarity index 100% rename from pkg/arvo/app/landscape/img/Chevron.png rename to pkg/arvo/app/landscape/img/chevron.png diff --git a/pkg/arvo/app/landscape/img/CodeEval.png b/pkg/arvo/app/landscape/img/codeeval.png similarity index 100% rename from pkg/arvo/app/landscape/img/CodeEval.png rename to pkg/arvo/app/landscape/img/codeeval.png diff --git a/pkg/arvo/app/landscape/img/Dojo.png b/pkg/arvo/app/landscape/img/dojo.png similarity index 100% rename from pkg/arvo/app/landscape/img/Dojo.png rename to pkg/arvo/app/landscape/img/dojo.png diff --git a/pkg/arvo/app/landscape/img/Favicon.png b/pkg/arvo/app/landscape/img/favicon.png similarity index 100% rename from pkg/arvo/app/landscape/img/Favicon.png rename to pkg/arvo/app/landscape/img/favicon.png diff --git a/pkg/arvo/app/landscape/img/Icon-Home.png b/pkg/arvo/app/landscape/img/icon-home.png similarity index 100% rename from pkg/arvo/app/landscape/img/Icon-Home.png rename to pkg/arvo/app/landscape/img/icon-home.png diff --git a/pkg/arvo/app/landscape/img/ImageUpload.png b/pkg/arvo/app/landscape/img/imageupload.png similarity index 100% rename from pkg/arvo/app/landscape/img/ImageUpload.png rename to pkg/arvo/app/landscape/img/imageupload.png diff --git a/pkg/arvo/app/landscape/img/Link.png b/pkg/arvo/app/landscape/img/link.png similarity index 100% rename from pkg/arvo/app/landscape/img/Link.png rename to pkg/arvo/app/landscape/img/link.png diff --git a/pkg/arvo/app/landscape/img/Links.png b/pkg/arvo/app/landscape/img/links.png similarity index 100% rename from pkg/arvo/app/landscape/img/Links.png rename to pkg/arvo/app/landscape/img/links.png diff --git a/pkg/arvo/app/landscape/img/Publish.png b/pkg/arvo/app/landscape/img/publish.png similarity index 100% rename from pkg/arvo/app/landscape/img/Publish.png rename to pkg/arvo/app/landscape/img/publish.png diff --git a/pkg/arvo/app/landscape/img/Send.png b/pkg/arvo/app/landscape/img/send.png similarity index 100% rename from pkg/arvo/app/landscape/img/Send.png rename to pkg/arvo/app/landscape/img/send.png diff --git a/pkg/arvo/app/landscape/img/Spinner.png b/pkg/arvo/app/landscape/img/spinner.png similarity index 100% rename from pkg/arvo/app/landscape/img/Spinner.png rename to pkg/arvo/app/landscape/img/spinner.png diff --git a/pkg/arvo/app/language-server.hoon b/pkg/arvo/app/language-server.hoon index 26eb6e06ff..3ad37f5166 100644 --- a/pkg/arvo/app/language-server.hoon +++ b/pkg/arvo/app/language-server.hoon @@ -101,7 +101,7 @@ =^ cards state ?+ sign-arvo (on-arvo:def wire sign-arvo) [%e %bound *] `state - [%f *] (handle-build:lsp wire +.sign-arvo) + [%c *] (handle-build:lsp wire +.sign-arvo) == [cards this] :: @@ -192,13 +192,10 @@ ^- (quip card _state) ~& > %lsp-shutdown :_ *state-zero - %- zing %+ turn ~(tap in ~(key by builds)) |= uri=@t - :+ [%pass /ford/[uri] %arvo %f %kill ~] - [%pass /ford/[uri]/deps %arvo %f %kill ~] - ~ + [%pass /ford/[uri] %arvo %c %warp our.bow %home ~] :: ++ handle-did-close |= [uri=@t version=(unit @)] @@ -210,10 +207,7 @@ =. builds (~(del by builds) uri) :_ state - :~ - [%pass /ford/[uri] %arvo %f %kill ~] - [%pass /ford/[uri]/deps %arvo %f %kill ~] - == + [%pass /ford/[uri] %arvo %c %warp our.bow %home ~]~ :: ++ handle-did-save |= [uri=@t version=(unit @)] @@ -240,43 +234,25 @@ `state :: ++ handle-build - |= [=path =gift:able:ford] + |= [=path =gift:able:clay] ^- (quip card _state) - ?. ?=([%made *] gift) - [~ state] - ?. ?=([%complete *] result.gift) - [~ state] + ?> ?=([%writ *] gift) =/ uri=@t (snag 1 path) - =/ =build-result:ford - build-result.result.gift - ?+ build-result [~ state] - :: - [%success %plan *] - =. preludes - (~(put by preludes) uri -:vase.build-result) + =; res=(quip card _state) + [(snoc -.res (build-file | uri path)) +.res] + ?~ p.gift [~ state] - :: - [%success %core *] - =. builds - (~(put by builds) uri vase.build-result) - =. ford-diagnostics - (~(del by ford-diagnostics) uri) - :_ state - (give-rpc-notification (get-diagnostics uri)) - :: - [%error *] - =/ error-ranges=(list =range:lsp-sur) - (get-errors-from-tang:build uri message.build-result) - ?~ error-ranges - [~ state] - =. ford-diagnostics - %+ ~(put by ford-diagnostics) - uri - [i.error-ranges 1 'Build Error']~ - :_ state - (give-rpc-notification (get-diagnostics uri)) - == + =. builds + (~(put by builds) uri q.r.u.p.gift) + =. ford-diagnostics + (~(del by ford-diagnostics) uri) + =+ .^(=open:clay %cs /(scot %p our.bow)/home/(scot %da now.bow)/open) + =/ =type -:(open (uri-to-path:build uri)) + =. preludes + (~(put by preludes) uri type) + :_ state + (give-rpc-notification (get-diagnostics uri)) :: ++ get-diagnostics |= uri=@t @@ -287,20 +263,14 @@ (~(gut by ford-diagnostics) uri ~) (get-parser-diagnostics uri) :: -++ get-build-deps - |= [=path buf=wall] - ^- schematic:ford - =/ parse=(like scaffold:ford) - %+ (lsp-parser [byk.bow path]) [1 1] - (zing (join "\0a" buf)) - =/ =scaffold:ford - ?~ q.parse *scaffold:ford - p.u.q.parse - :* %plan - [[our.bow %home] (flop path)] - *coin - scaffold(sources `(list hoon)`~[[%cnts ~[[%& 1]] ~]]) - == +++ build-file + |= [eager=? uri=@t =path] + ^- card + =/ =rave:clay + ?: eager + [%sing %a da+now.bow path] + [%next %a da+now.bow path] + [%pass /ford/[uri] %arvo %c %warp our.bow %home `rave] :: ++ handle-did-open |= item=text-document-item:lsp-sur @@ -311,18 +281,10 @@ (~(put by bufs) uri.item buf) =/ =path (uri-to-path:build uri.item) - =/ =schematic:ford - [%core [our.bow %home] (flop path)] - =/ dep-schematic=schematic:ford - (get-build-deps path buf) :_ state %+ weld (give-rpc-notification (get-diagnostics uri.item)) - ^- (list card) - :~ - [%pass /ford/[uri.item] %arvo %f %build live=%.y schematic] - [%pass /ford/[uri.item]/deps %arvo %f %build live=%.y dep-schematic] - == + [(build-file & uri.item path) ~] :: ++ get-parser-diagnostics |= uri=@t @@ -330,7 +292,7 @@ =/ t=tape (zing (join "\0a" `wall`(~(got by bufs) uri))) =/ parse - (lily:auto t (lsp-parser *beam)) + (lily:auto t (lsp-parser (uri-to-path:build uri))) ?. ?=(%| -.parse) ~ =/ loc=position:lsp-sur diff --git a/pkg/arvo/app/lens.hoon b/pkg/arvo/app/lens.hoon index b9e3d46855..73004cb27b 100644 --- a/pkg/arvo/app/lens.hoon +++ b/pkg/arvo/app/lens.hoon @@ -1,7 +1,6 @@ /- lens, *sole /+ base64, *server, default-agent -/= lens-mark /: /===/mar/lens/command - /!noun/ +/= lens-mark /mar/lens/command :: TODO: ask clay to build a $tube =, format |% :: +lens-out: json or named octet-stream @@ -15,7 +14,6 @@ job=(unit [eyre-id=@ta com=command:lens]) == == -:: -- :: =| =state diff --git a/pkg/arvo/app/link-listen-hook.hoon b/pkg/arvo/app/link-listen-hook.hoon index 42711b2fd4..d90c98de5d 100644 --- a/pkg/arvo/app/link-listen-hook.hoon +++ b/pkg/arvo/app/link-listen-hook.hoon @@ -14,8 +14,8 @@ :: to expede this process, we prod other potential listeners when we add :: them to our metadata+groups definition. :: -/- link-listen-hook, *metadata-store, *link, group-store -/+ mdl=metadata, default-agent, verb, dbug +/- *link, listen-hook=link-listen-hook, *metadata-store, group-store +/+ mdl=metadata, default-agent, verb, dbug, store=link-store :: ~% %link-listen-hook-top ..is ~ |% @@ -167,7 +167,7 @@ ?> (team:title [our src]:bowl) =^ cards state ~| p.vase - (handle-listen-action:do !<(action:link-listen-hook vase)) + (handle-listen-action:do !<(action:listen-hook vase)) [cards this] == :: @@ -218,7 +218,7 @@ :: user actions & updates :: ++ handle-listen-action - |= =action:link-listen-hook + |= =action:listen-hook ^- (quip card _state) ::NOTE no-opping where appropriate happens further down the call stack. :: we *could* no-op here, as %watch when we're already listening should @@ -250,7 +250,7 @@ $(cards (weld cards more-cards), groups t.groups) :: ++ send-update - |= =update:link-listen-hook + |= =update:listen-hook ^- card [%give %fact ~[/listening] %link-listen-update !>(update)] :: @@ -500,11 +500,11 @@ ?+ mark ~|([dap.bowl %unexpected-mark mark] !!) %link-initial %- handle-link-initial - [who.target where.target !<(initial vase)] + [who.target where.target !<(initial:store vase)] :: %link-update %- handle-link-update - [who.target where.target !<(update vase)] + [who.target where.target !<(update:store vase)] == == :: @@ -546,7 +546,7 @@ group-path :: ++ do-link-action - |= [=wire =action] + |= [=wire =action:store] ^- card :* %pass wire @@ -558,7 +558,7 @@ == :: ++ handle-link-initial - |= [who=ship where=path =initial] + |= [who=ship where=path =initial:store] ^- (quip card _state) ?> =(src.bowl who) ?+ -.initial ~|([dap.bowl %unexpected-initial -.initial] !!) @@ -580,7 +580,7 @@ == :: ++ handle-link-update - |= [who=ship where=path =update] + |= [who=ship where=path =update:store] ^- (quip card _state) ?> =(src.bowl who) :_ state @@ -594,11 +594,11 @@ :: %annotations %+ turn notes.update - |= =note + |= =^note ^- card %+ do-link-action [%forward %annotation (scot %p who) where] - [%read where url.update who note] + [%read where url.update `comment`[who note]] == :: ++ take-forward-sign diff --git a/pkg/arvo/app/link-proxy-hook.hoon b/pkg/arvo/app/link-proxy-hook.hoon index 2c89c90d07..aeaa4b2470 100644 --- a/pkg/arvo/app/link-proxy-hook.hoon +++ b/pkg/arvo/app/link-proxy-hook.hoon @@ -19,8 +19,8 @@ :: when adding support for new paths, the only things you'll likely want :: to touch are +permitted, +initial-response, & +kick-proxies. :: -/- group-store, *metadata-store -/+ *link, metadata, default-agent, verb, dbug +/- *link, group-store, *metadata-store +/+ store=link-store, metadata, default-agent, verb, dbug ~% %link-proxy-hook-top ..is ~ |% +$ state-0 @@ -269,7 +269,7 @@ ++ initial-response |= =path ^- card - =; =initial + =; =initial:store [%give %fact ~ %link-initial !>(initial)] ?+ path !! [%local-pages ^] diff --git a/pkg/arvo/app/link-store.hoon b/pkg/arvo/app/link-store.hoon index 9828e57310..fed3d1206a 100644 --- a/pkg/arvo/app/link-store.hoon +++ b/pkg/arvo/app/link-store.hoon @@ -50,7 +50,8 @@ :: ? :: /seen/wood-url/some-path have we seen this here :: -/+ *link, default-agent, verb, dbug +/- *link +/+ store=link-store, default-agent, verb, dbug :: |% +$ state-0 @@ -101,8 +102,8 @@ =^ cards state ?+ mark (on-poke:def mark vase) ::TODO move json conversion into mark once mark performance improves - %json (do-action:do (action:de-json !<(json vase))) - %link-action (do-action:do !<(action vase)) + %json (do-action:do (action:dejs:store !<(json vase))) + %link-action (do-action:do !<(action:store vase)) == [cards this] :: @@ -121,7 +122,7 @@ :: [%y ?(%annotations %discussions) *] =/ [spath=^path surl=url] - (break-discussion-path t.t.path) + (break-discussion-path:store t.t.path) =- ``noun+!>(-) :: ?: =(~ surl) @@ -174,22 +175,22 @@ |^ ?+ path (on-watch:def path) [%local-pages *] %+ give %link-initial - ^- initial + ^- initial:store [%local-pages (get-local-pages:do t.path)] :: [%submissions *] %+ give %link-initial - ^- initial + ^- initial:store [%submissions (get-submissions:do t.path)] :: [%annotations *] %+ give %link-initial - ^- initial + ^- initial:store [%annotations (get-annotations:do t.path)] :: [%discussions *] %+ give %link-initial - ^- initial + ^- initial:store [%discussions (get-discussions:do t.path)] :: [%seen ~] @@ -218,7 +219,7 @@ :: writing :: ++ do-action - |= =action + |= =action:store ^- (quip card _state) ?- -.action %save (save-page +.action) @@ -284,8 +285,8 @@ :+ %give %fact :+ :~ /annotations [%annotations %$ path] - [%annotations (build-discussion-path url)] - [%annotations (build-discussion-path path url)] + [%annotations (build-discussion-path:store url)] + [%annotations (build-discussion-path:store path url)] == %link-update !>([%annotations path url [note]~]) @@ -324,11 +325,11 @@ ?: ?=(^ (find ~[submission] submissions.links)) [| submissions.links] :- & - (submissions:merge submissions.links ~[submission]) + (submissions:merge:store submissions.links ~[submission]) =. by-group (~(put by by-group) path links) :: add submission to global sites :: - =/ =site (site-from-url url.submission) + =/ =site (site-from-url:store url.submission) =. by-site (~(add ja by-site) site [path submission]) :: send updates to subscribers :: @@ -354,7 +355,7 @@ ?: ?=(^ (find ~[comment] comments.discussion)) [| comments.discussion] :- & - (comments:merge comments.discussion ~[comment]) + (comments:merge:store comments.discussion ~[comment]) =. urls (~(put by urls) url discussion) =. discussions (~(put by discussions) path urls) :: send updates to subscribers @@ -365,8 +366,8 @@ :+ %give %fact :+ :~ /discussions [%discussions '' path] - [%discussions (build-discussion-path url)] - [%discussions (build-discussion-path path url)] + [%discussions (build-discussion-path:store url)] + [%discussions (build-discussion-path:store path url)] == %link-update !>([%discussions path url [comment]~]) @@ -420,7 +421,7 @@ |= =path ^- ? =/ [=^path =url] - (break-discussion-path path) + (break-discussion-path:store path) %. url %~ has in seen:(~(gut by by-group) path *links) @@ -430,7 +431,7 @@ |= =path ^- (per-path-url notes) =/ args=[=^path =url] - (break-discussion-path path) + (break-discussion-path:store path) |^ ?~ path :: all paths :: @@ -460,7 +461,7 @@ |= =path ^- (per-path-url comments) =/ args=[=^path =url] - (break-discussion-path path) + (break-discussion-path:store path) |^ ?~ path :: all paths :: diff --git a/pkg/arvo/app/link-view.hoon b/pkg/arvo/app/link-view.hoon index 23bbb3b515..8e65410315 100644 --- a/pkg/arvo/app/link-view.hoon +++ b/pkg/arvo/app/link-view.hoon @@ -10,12 +10,12 @@ :: /json/[n]/submission/[wood-url]/[collection] nth matching submission :: /json/seen mark-as-read updates :: -/- *link-view, - *invite-store, group-store, - link-listen-hook, - group-hook, permission-hook, permission-group-hook, - metadata-hook, contact-view -/+ *link, metadata, *server, default-agent, verb, dbug +/- *link, view=link-view +/- *invite-store, group-store +/- listen-hook=link-listen-hook +/- group-hook, permission-hook, permission-group-hook +/- metadata-hook, contact-view +/+ store=link-store, metadata, *server, default-agent, verb, dbug ~% %link-view-top ..is ~ :: |% @@ -89,10 +89,10 @@ :_ this ?+ mark (on-poke:def mark vase) %link-action - [(handle-action:do !<(action vase)) ~] + [(handle-action:do !<(action:store vase)) ~] :: %link-view-action - (handle-view-action:do !<(view-action vase)) + (handle-view-action:do !<(action:view vase)) == :: ++ on-watch @@ -117,11 +117,11 @@ :: [%submission @ ^] :_ this - (give-specific-submission:do p (break-discussion-path t.t.t.path)) + (give-specific-submission:do p (break-discussion-path:store t.t.t.path)) :: [%discussions @ ^] :_ this - (give-initial-discussions:do p (break-discussion-path t.t.t.path)) + (give-initial-discussions:do p (break-discussion-path:store t.t.t.path)) == :: ++ on-agent @@ -145,7 +145,7 @@ :: %link-update :_ this - :- (send-update:do !<(update vase)) + :- (send-update:do !<(update:store vase)) ?: =(/discussions wire) ~ ~[give-tile-data:do] == @@ -221,12 +221,12 @@ == :: ++ handle-action - |= =action + |= =action:store ^- card [%pass /action %agent [our.bowl %link-store] %poke %link-action !>(action)] :: ++ handle-view-action - |= act=view-action + |= act=action:view ^- (list card) ?- -.act %create (handle-create +.act) @@ -235,7 +235,7 @@ == :: ++ handle-create - |= [=path title=@t description=@t members=create-members real-group=?] + |= [=path title=@t description=@t members=create-members:view real-group=?] ^- (list card) =/ group-path=^path ?- -.members @@ -273,7 +273,7 @@ :: %^ do-poke %link-listen-hook %link-listen-action - !> ^- action:link-listen-hook + !> ^- action:listen-hook [%watch path] == ?: ?=(%group -.members) ~ @@ -453,6 +453,7 @@ [%give %kick ~ ~]~ =; =json [%give %fact ~ %json !>(json)] + %+ frond:enjs:format 'link-update' %+ frond:enjs:format 'initial-submissions' %- pairs:enjs:format %+ turn @@ -486,7 +487,7 @@ submissions |= =submission ^- json - =/ =json (submission:en-json submission) + =/ =json (submission:enjs:store submission) ?> ?=([%o *] json) :: add in seen status :: @@ -494,7 +495,7 @@ %+ ~(put by p.json) 'seen' :- %b %+ scry-for ? - [%seen (build-discussion-path path url.submission)] + [%seen (build-discussion-path:store path url.submission)] :: add in comment count :: =; comment-count=@ud @@ -507,18 +508,19 @@ =- (~(got by (~(got by -) path)) url.submission) %+ scry-for (per-path-url comments) :- %discussions - (build-discussion-path path url.submission) + (build-discussion-path:store path url.submission) :: ++ give-specific-submission |= [n=@ud =path =url] :_ [%give %kick ~ ~]~ =; =json [%give %fact ~ %json !>(json)] + %+ frond:enjs:format 'link-update' %+ frond:enjs:format 'submission' ^- json =; sub=(unit submission) ?~ sub ~ - (submission:en-json u.sub) + (submission:enjs:store u.sub) =/ =submissions =- (~(got by -) path) %+ scry-for (map ^path submissions) @@ -538,35 +540,39 @@ [%give %kick ~ ~]~ =; =json [%give %fact ~ %json !>(json)] + %+ frond:enjs:format 'link-update' %+ frond:enjs:format 'initial-discussions' %^ page-to-json p %+ get-paginated `p =- (~(got by (~(got by -) path)) url) %+ scry-for (per-path-url comments) - [%discussions (build-discussion-path path url)] - comment:en-json + [%discussions (build-discussion-path:store path url)] + comment:enjs:store :: ++ send-update - |= =update + |= =update:store ^- card ?+ -.update ~|([dap.bowl %unexpected-update -.update] !!) %submissions %+ give-json - (update:en-json update) + %+ frond:enjs:format 'link-update' + (update:enjs:store update) :~ /json/0/submissions (weld /json/0/submissions path.update) == :: %discussions %+ give-json - (update:en-json update) + %+ frond:enjs:format 'link-update' + (update:enjs:store update) :_ ~ %+ weld /json/0/discussions - (build-discussion-path [path url]:update) + (build-discussion-path:store [path url]:update) :: %observation %+ give-json - (update:en-json update) + %+ frond:enjs:format 'link-update' + (update:enjs:store update) ~[/json/seen] == :: diff --git a/pkg/arvo/app/metadata-hook.hoon b/pkg/arvo/app/metadata-hook.hoon index 1ae813f5d6..39dfa7b8fb 100644 --- a/pkg/arvo/app/metadata-hook.hoon +++ b/pkg/arvo/app/metadata-hook.hoon @@ -47,7 +47,7 @@ :: %metadata-action [(poke-action:hc !<(metadata-action vase)) this] - == + == :: ++ on-watch |= =path @@ -162,7 +162,12 @@ ++ metadata-scry |= pax=^path ^- associations - =. pax ;:(weld /=metadata-store/(scot %da now.bowl)/group pax /noun) + =. pax + ;: weld + /(scot %p our.bowl)/metadata-store/(scot %da now.bowl)/group + pax + /noun + == .^(associations %gx pax) -- :: @@ -240,7 +245,7 @@ ^- ? =. pax ;: weld - /=permission-store/(scot %da now.bowl)/permitted + /(scot %p our.bowl)/permission-store/(scot %da now.bowl)/permitted [(scot %p ship) pax] /noun == diff --git a/pkg/arvo/app/metadata-store.hoon b/pkg/arvo/app/metadata-store.hoon index 8e52aaa41c..e50bdcdb23 100644 --- a/pkg/arvo/app/metadata-store.hoon +++ b/pkg/arvo/app/metadata-store.hoon @@ -61,9 +61,27 @@ ^- (quip card _this) ?> (team:title our.bowl src.bowl) =^ cards state - ?: ?=(%metadata-action mark) + ?+ mark (on-poke:def mark vase) + %metadata-action (poke-metadata-action:mc !<(metadata-action vase)) - (on-poke:def mark vase) + %noun + =/ val=(each [%cleanup path] tang) + (mule |.(!<([%cleanup path] vase))) + ?. ?=(%& -.val) + (on-poke:def mark vase) + =/ group=path +.p.val + =/ res=(set resource) (~(get ju group-indices) group) + =. group-indices (~(del by group-indices) group) + :- ~ + %+ roll ~(tap in res) + |= [r=resource out=_state] + =. resource-indices.out (~(del by resource-indices.out) r) + =. app-indices.out + %- ~(del ju app-indices.out) + [app-name.r group app-path.r] + =. associations.out (~(del by associations.out) group r) + out + == [cards this] :: ++ on-watch diff --git a/pkg/arvo/app/permission-group-hook.hoon b/pkg/arvo/app/permission-group-hook.hoon index f3e7935b3c..d3ca08863e 100644 --- a/pkg/arvo/app/permission-group-hook.hoon +++ b/pkg/arvo/app/permission-group-hook.hoon @@ -202,7 +202,8 @@ ++ group-scry |= pax=path ^- (unit group) - .^((unit group) %gx ;:(weld /=group-store/(scot %da now.bowl) pax /noun)) + =/ bek=path /(scot %p our.bowl)/group-store/(scot %da now.bowl) + .^((unit group) %gx :(weld bek pax /noun)) :: ++ add-members |= [pax=path mem=(set ship) perms=(set path)] diff --git a/pkg/arvo/app/permission-hook.hoon b/pkg/arvo/app/permission-hook.hoon index f5cbe1f115..7c55bdc682 100644 --- a/pkg/arvo/app/permission-hook.hoon +++ b/pkg/arvo/app/permission-hook.hoon @@ -296,7 +296,12 @@ ++ permission-scry |= pax=path ^- permission - =. pax ;:(weld /=permission-store/(scot %da now.bowl)/permission pax /noun) + =. pax + ;: weld + /(scot %p our.bowl)/permission-store/(scot %da now.bowl)/permission + pax + /noun + == (need .^((unit permission) %gx pax)) :: ++ permitted diff --git a/pkg/arvo/app/ping.hoon b/pkg/arvo/app/ping.hoon index 6be1ddddea..f666efd314 100644 --- a/pkg/arvo/app/ping.hoon +++ b/pkg/arvo/app/ping.hoon @@ -71,7 +71,7 @@ ++ stop-ping-ship |= [our=@p now=@da =ship =old=rift =ship-state] ^- (quip card _state) - =+ .^(=new=rift %j /=rift/(scot %da now)/(scot %p ship)) + =+ .^(=new=rift %j /(scot %p our)/rift/(scot %da now)/(scot %p ship)) :: if nothing's changed about us, don't cancel :: ?: ?& =(old-rift new-rift) @@ -96,7 +96,7 @@ (send-ping our now ship) :: ;< new-state=_state (rind card state) - =+ .^(=rift %j /=rift/(scot %da now)/(scot %p ship)) + =+ .^(=rift %j /(scot %p our)/rift/(scot %da now)/(scot %p ship)) :_ state(ships (~(put by ships.state) ship rift %idle ~)) [%pass /jael/(scot %p ship) %arvo %j %public-keys (silt ship ~)]~ =. state new-state diff --git a/pkg/arvo/app/publish.hoon b/pkg/arvo/app/publish.hoon index a96d2c873c..57f38b2ea5 100644 --- a/pkg/arvo/app/publish.hoon +++ b/pkg/arvo/app/publish.hoon @@ -1,13 +1,13 @@ -/- *publish, - *group-store, - *group-hook, - *permission-hook, - *permission-group-hook, - *permission-store, - *invite-store, - *metadata-store, - *metadata-hook, - *rw-security +/- *publish +/- *group-store +/- *group-hook +/- *permission-hook +/- *permission-group-hook +/- *permission-store +/- *invite-store +/- *metadata-store +/- *metadata-hook +/- *rw-security /+ *server, *publish, cram, default-agent, dbug :: ~% %publish ..is ~ @@ -127,7 +127,6 @@ :: cards ;: weld - (kill-builds pubs.zero) kick-cards init-cards (move-files old-subs) @@ -225,21 +224,6 @@ [~ subs] [[%give %kick paths ~]~ subs] :: - ++ kill-builds - |= pubs=(map @tas collection-zero) - ^- (list card) - %- zing - %+ turn ~(tap by pubs) - |= [col-name=@tas col-data=collection-zero] - ^- (list card) - :- [%pass /collection/[col-name] %arvo %f %kill ~] - %- zing - %+ turn ~(tap by pos.col-data) - |= [pos-name=@tas *] - :~ [%pass /post/[col-name]/[pos-name] %arvo %f %kill ~] - [%pass /comments/[col-name]/[pos-name] %arvo %f %kill ~] - == - :: ++ send-invites |= [book=@tas subscribers=(set @p)] ^- (list card) @@ -431,8 +415,13 @@ [%subscribe @ @ ~] =/ who=@p (slav %p i.t.wir) =/ book=@tas i.t.t.wir + =/ wen=(unit @da) (get-last-update:main who book) + =/ pax=path + ?~ wen + /notebook/[book] + /notebook/[book]/(scot %da u.wen) :_ this - [%pass wir %agent [who %publish] %watch /notebook/[book]]~ + [%pass wir %agent [who %publish] %watch pax]~ :: [%permissions ~] :_ this @@ -518,6 +507,59 @@ :: |_ bol=bowl:gall :: +++ get-last-update + |= [host=@p book-name=@tas] + ^- (unit @da) + =/ book (~(get by books) host book-name) + ?~ book ~ + =/ wen date-created.u.book + %- some + %- ~(rep by notes.u.book) + |= [[@tas =note] out=_wen] + ^- @da + %+ max out + %+ max last-edit.note + %- ~(rep by comments.note) + |= [[@da =comment] out=_out] + (max date-created.comment out) +:: +++ get-notebook-from-date + |= [host=@p book-name=@tas wen=@da] + ^- notebook + =/ book (~(got by books) host book-name) + %= book + notes + %- ~(rep by notes.book) + |= [[nom=@tas not=note] out=(map @tas note)] + ^- (map @tas note) + ?: (gth last-edit.not wen) + (~(put by out) nom not) + =. comments.not + %- ~(rep by comments.not) + |= [[nam=@da com=comment] out=(map @da comment)] + ?: (gth date-created.com wen) + (~(put by out) nam com) + out + ?~ comments.not + out + (~(put by out) nom not) + == +:: +++ merge-notebooks + |= [base=notebook diff=notebook] + ^- notebook + %= diff + notes + %- ~(rep by notes.diff) + |= [[nom=@tas not=note] out=_notes.base] + =/ base-note=(unit note) (~(get by out) nom) + ?~ base-note + (~(put by out) nom not) + =. comments.u.base-note + (~(uni by comments.u.base-note) comments.not) + (~(put by out) nom u.base-note) + == +:: ++ read-paths |= ran=rant:clay ^- (quip card _state) @@ -857,6 +899,19 @@ %.n == :: +++ get-subscriber-paths + |= [book-name=@tas who=@p] + ^- (list path) + %+ roll ~(val by sup.bol) + |= [[whom=@p pax=path] out=(list path)] + ?. =(who whom) + out + ?. ?=([%notebook @ *] pax) + out + ?. =(i.t.pax book-name) + out + [pax out] +:: ++ handle-permission-update |= upd=permission-update ^- (quip card _state) @@ -877,7 +932,7 @@ %+ turn ~(tap in who.upd) |= who=@p ?. (allowed who %read u.book) - [%give %kick [/notebook/[u.book]]~ `who]~ + [%give %kick (get-subscriber-paths u.book who) `who]~ ?: ?|(?=(%remove -.upd) (is-managed path.upd)) ~ =/ uid (sham %publish who u.book eny.bol) @@ -913,11 +968,15 @@ :: ++ watch-notebook |= pax=path - ?> ?=([%notebook @ ~] pax) + ?> ?=([%notebook @ *] pax) =/ book-name i.t.pax ?. (allowed src.bol %read book-name) ~|("not permitted" !!) - =/ book (~(got by books) our.bol book-name) + =/ book + ?: ?=([%notebook @ @ ~] pax) + =/ wen=@da (slav %da i.t.t.pax) + (get-notebook-from-date our.bol book-name wen) + (~(got by books) our.bol book-name) =/ delta=notebook-delta [%add-book our.bol book-name book] :_ state @@ -1070,7 +1129,11 @@ ^- [(list card) write=path read=path] ?> ?=(^ group-path.group) =/ scry-path - ;:(weld /=group-store/(scot %da now.bol) group-path.group /noun) + ;: weld + /(scot %p our.bol)/group-store/(scot %da now.bol) + group-path.group + /noun + == =/ grp .^((unit ^group) %gx scry-path) ?: use-preexisting.group ?~ grp !! @@ -1766,7 +1829,7 @@ %+ turn ~(tap in dif-peeps) |= who=@p ^- card - [%give %kick [/notebook/[book.act]]~ `who] + [%give %kick (get-subscriber-paths book.act who) `who] == :: ++ get-subscribers @@ -1910,6 +1973,8 @@ date-created.data.del == == + =? data.del (~(has by books) host.del book.del) + (merge-notebooks (~(got by books) host.del book.del) data.del) =^ cards state (emit-updates-and-state host.del book.del data.del del sty) :_ state diff --git a/pkg/arvo/app/shoe.hoon b/pkg/arvo/app/shoe.hoon index 504365c591..83f24b9d6b 100644 --- a/pkg/arvo/app/shoe.hoon +++ b/pkg/arvo/app/shoe.hoon @@ -40,8 +40,8 @@ :: ++ command-parser |= sole-id=@ta - ^+ |~(nail *(like command)) - (cold ~ (jest 'demo')) + ^+ |~(nail *(like [? command])) + (cold [& ~] (jest 'demo')) :: ++ tab-list |= sole-id=@ta diff --git a/pkg/arvo/app/spider.hoon b/pkg/arvo/app/spider.hoon index cac00c6607..a6286ba8cb 100644 --- a/pkg/arvo/app/spider.hoon +++ b/pkg/arvo/app/spider.hoon @@ -12,15 +12,34 @@ $~ [*thread-form ~] [=thread-form kid=(map tid trie)] :: -+$ trying ?(%find %build %none) ++$ trying ?(%build %none) +$ state $: starting=(map yarn [=trying =vase]) running=trie tid=(map tid yarn) == :: ++$ clean-slate-any + $^ clean-slate-ket + $% clean-slate-sig + clean-slate + == +:: +$ clean-slate - $: starting=(map yarn [=trying =vase]) + $: %1 + starting=(map yarn [=trying =vase]) + running=(list yarn) + tid=(map tid yarn) + == +:: ++$ clean-slate-ket + $: starting=(map yarn [trying=?(%build %find %none) =vase]) + running=(list yarn) + tid=(map tid yarn) + == +:: ++$ clean-slate-sig + $: starting=~ running=(list yarn) tid=(map tid yarn) == @@ -87,9 +106,10 @@ == :: ++ tap-yarn - =| =yarn |= =trie - ^- (list [=^yarn =thread-form]) + %- flop :: preorder + =| =yarn + |- ^- (list [=^yarn =thread-form]) %+ welp ?~ yarn ~ @@ -116,12 +136,17 @@ ++ on-init on-init:def ++ on-save clean-state:sc ++ on-load + |^ |= old-state=vase - =+ !<(=clean-slate old-state) - =. tid.state tid.clean-slate + =+ !<(any=clean-slate-any old-state) + =? any ?=(^ -.any) (old-to-1 any) + =? any ?=(~ -.any) (old-to-1 any) + ?> ?=(%1 -.any) + :: + =. tid.state tid.any =/ yarns=(list yarn) - %+ welp running.clean-slate - ~(tap in ~(key by starting.clean-slate)) + %+ welp running.any + ~(tap in ~(key by starting.any)) |- ^- (quip card _this) ?~ yarns `this @@ -130,10 +155,18 @@ =^ cards-2 this $(yarns t.yarns) [(weld cards-1 cards-2) this] + :: + ++ old-to-1 + |= old=clean-slate-ket + ^- clean-slate + 1+old(starting (~(run by starting.old) |=([* v=vase] none+v))) + -- :: ++ on-poke |= [=mark =vase] ^- (quip card _this) + ?: ?=(%spider-kill mark) + (on-load on-save) =^ cards state ?+ mark (on-poke:def mark vase) %spider-input (on-poke-input:sc !<(input vase)) @@ -182,7 +215,6 @@ =^ cards state ?+ wire (on-arvo:def wire sign-arvo) [%thread @ *] (handle-sign:sc i.t.wire t.t.wire sign-arvo) - [%find @ ~] (handle-find:sc i.t.wire sign-arvo) [%build @ ~] (handle-build:sc i.t.wire sign-arvo) == [cards this] @@ -243,33 +275,15 @@ ~| [%already-starting yarn] !! :: - =: starting.state (~(put by starting.state) yarn [%find vase]) + =: starting.state (~(put by starting.state) yarn [%build vase]) tid.state (~(put by tid.state) new-tid yarn) == + =/ pax=path + ~| no-file-for-thread+file + (need (get-fit:clay [our q.byk da+now]:bowl %ted file)) =/ =card - =/ =schematic:ford [%path [our.bowl %home] %ted file] - [%pass /find/[new-tid] %arvo %f %build live=%.n schematic] - [[card ~] state] -:: -++ handle-find - |= [=tid =sign-arvo] - ^- (quip card ^state) - =/ =yarn (~(got by tid.state) tid) - =. starting.state - (~(jab by starting.state) yarn |=([=trying =vase] [%none vase])) - ?> ?=([%f %made *] sign-arvo) - ?: ?=(%incomplete -.result.sign-arvo) - (thread-fail-not-running tid %find-thread-incomplete tang.result.sign-arvo) - =/ =build-result:ford build-result.result.sign-arvo - ?: ?=(%error -.build-result) - (thread-fail-not-running tid %find-thread-error message.build-result) - ?. ?=([%path *] +.build-result) - (thread-fail-not-running tid %find-thread-strange ~) - =. starting.state - (~(jab by starting.state) yarn |=([=trying =vase] [%build vase])) - =/ =card - =/ =schematic:ford [%core rail.build-result] - [%pass /build/[tid] %arvo %f %build live=%.n schematic] + :+ %pass /build/[new-tid] + [%arvo %c %warp our.bowl %home ~ %sing %a da+now.bowl pax] [[card ~] state] :: ++ handle-build @@ -278,16 +292,14 @@ =/ =yarn (~(got by tid.state) tid) =. starting.state (~(jab by starting.state) yarn |=([=trying =vase] [%none vase])) - ?> ?=([%f %made *] sign-arvo) - ?: ?=(%incomplete -.result.sign-arvo) - (thread-fail-not-running tid %build-thread-incomplete tang.result.sign-arvo) - =/ =build-result:ford build-result.result.sign-arvo - ?: ?=(%error -.build-result) - (thread-fail-not-running tid %build-thread-error message.build-result) - =/ =cage (result-to-cage:ford build-result) - ?. ?=(%noun p.cage) - (thread-fail-not-running tid %build-thread-strange >p.cage< ~) - =/ maybe-thread (mule |.(!<(thread q.cage))) + ~| sign+[- +<]:sign-arvo + ?> ?=([?(%b %c) %writ *] sign-arvo) + =/ =riot:clay p.sign-arvo + ?~ riot + (thread-fail-not-running tid %build-thread-error *tang) + ?. ?=(%vase p.r.u.riot) + (thread-fail-not-running tid %build-thread-strange >[p q]:u.riot< ~) + =/ maybe-thread (mule |.(!<(thread !<(vase q.r.u.riot)))) ?: ?=(%| -.maybe-thread) (thread-fail-not-running tid %thread-not-thread ~) (start-thread yarn p.maybe-thread) @@ -368,15 +380,13 @@ :: ++ thread-fail-not-running |= [=tid =term =tang] + ^- (quip card ^state) =/ =yarn (~(got by tid.state) tid) :_ state(starting (~(del by starting.state) yarn)) - %- welp :_ (thread-say-fail tid term tang) - =/ =trying trying:(~(got by starting.state) yarn) - ?- trying - %find [%pass /find/[tid] %arvo %f %kill ~]~ - %build [%pass /build/[tid] %arvo %f %kill ~]~ - %none ~ - == + =/ moz (thread-say-fail tid term tang) + ?. ?=([~ %build *] (~(get by starting.state) yarn)) + moz + :_(moz [%pass /build/[tid] %arvo %c %warp our.bowl %home ~]) :: ++ thread-say-fail |= [=tid =term =tang] @@ -388,7 +398,7 @@ ++ thread-fail |= [=yarn =term =tang] ^- (quip card ^state) - %- (slog leaf+"strand {} failed" leaf+ tang) + :: %- (slog leaf+"strand {} failed" leaf+ tang) =/ =tid (yarn-to-tid yarn) =/ fail-cards (thread-say-fail tid term tang) =^ cards state (thread-clean yarn) @@ -464,5 +474,5 @@ :: ++ clean-state !> ^- clean-slate - state(running (turn (tap-yarn running.state) head)) + 1+state(running (turn (tap-yarn running.state) head)) -- diff --git a/pkg/arvo/app/test.hoon b/pkg/arvo/app/test.hoon index 000f418033..06f695d255 100644 --- a/pkg/arvo/app/test.hoon +++ b/pkg/arvo/app/test.hoon @@ -1,40 +1,20 @@ /+ default-agent -:: +!: |% +$ card card:agent:gall -+$ test - $% [%arvo ~] ::UNIMPLEMENTED - [%marks ~] ::UNIMPLEMENTED - [%cores p=path] - [%hoons p=path] - [%names p=path] - [%renders p=path] ++$ test ?(%agents %marks %generators) ++$ state + $: app=(set path) + app-ok=? + mar=(set path) + mar-ok=? + gen=(set path) + gen-ok=? == -- -:: -|% -++ join - |= {a/cord b/(list cord)} - ?~ b '' - (rap 3 |-([i.b ?~(t.b ~ [a $(b t.b)])])) -:: -++ fake-fcgi [%many [%blob *cred:eyre] $+[%n ~] ~] -++ build-core - |= [=disc:ford a=spur b=(list spur)] - ^- card - ~& >> (flop a) - :* %pass a-core+a - %arvo %f %build - live=| - ^- schematic:ford - :- [%core disc %hoon a] - [%$ %cont !>(b)] - == --- -:: -=, ford =, format ^- agent:gall +=| =state |_ =bowl:gall +* this . def ~(. (default-agent this %|) bowl) @@ -44,121 +24,136 @@ ++ on-load on-load:def ++ on-poke |= [=mark =vase] - :_ this + ^- [(list card) _this] |^ - =+ !<(a=test vase) - ?- -.a - %arvo ~|(%stub !!) ::basically double solid? - %hoons ~&((list-hoons p.a ~) ~) - %names ~&((list-names p.a) ~) - %marks ~|(%stub !!) ::TODO restore historical handler - %renders ~&(%all-renderers-are-disabled ~) - %cores - =/ spurs [- +]:(list-hoons p.a skip=(sy /sys /ren /tests ~)) - [(build-core [p q]:byk.bowl spurs) ~] + =+ !<(=test vase) + ?- test + %marks test-marks + %agents test-agents + %generators test-generators == :: - ++ now-beak %_(byk.bowl r [%da now.bowl]) - ++ list-hoons - |= [under=path skipping=(set spur)] ^- (list spur) - =/ sup (flop under) - ~& [%findining-hoons under=under] - |- ^- (list spur) - %- zing - %+ turn - =- (sort ~(tap by -) aor) - dir:.^(arch %cy (en-beam now-beak sup)) - |= [a=knot ~] ^- (list spur) - =. sup [a sup] - ?: (~(has in skipping) (flop sup)) - ~&(> [(flop sup) %out-of-scope] ~) - =/ ded (~(get by skip-completely) (flop sup)) - ?^ ded - ~&(> [(flop sup) %skipped `tape`u.ded] ~) - ?~ [fil:.^(arch %cy (en-beam now-beak [%hoon sup]))] - ^$ - ~& (flop sup) - [sup ^$] - :: - ++ list-names - |= a/path ^- (list term) - =/ hon (list-hoons a ~) - %+ turn hon - |= b=spur - (join '-' (slag 1 (flop b))) - :: - ++ skip-completely - ^~ ^- (map path tape) - %- my :~ ::TODO don't hardcode - :- /ren/run "not meant to be called except on a (different) hoon file" - :- /ren/test-gen "temporarily disabled" + ++ test-marks + =| fex=(list card) + ^+ [fex this] + ?> =(~ mar.state) + =. mar-ok.state %.y + =+ .^(paz=(list path) ct+(en-beam now-beak /mar)) + |- ^+ [fex this] + ?~ paz [fex this] + =/ xap=path (flop i.paz) + ?. ?=([%hoon *] xap) + $(paz t.paz) + =/ mak=^mark + %- crip + %+ turn (tail (spud (tail (flop (tail xap))))) + |=(c=@tD `@tD`?:(=('/' c) '-' c)) + =/ sing=card + :+ %pass /build/mar/[mak] + [%arvo %c %warp our.bowl %home ~ %sing %b da+now.bowl /[mak]] + %_ $ + paz t.paz + fex [sing fex] + mar.state (~(put in mar.state) /mar/[mak]) == + :: + ++ test-agents + =| fex=(list card) + ^+ [fex this] + ?> =(~ app.state) + =. app-ok.state %.y + =+ .^(app-arch=arch cy+(en-beam now-beak /app)) + =/ daz ~(tap in ~(key by dir.app-arch)) + |- ^+ [fex this] + ?~ daz [fex this] + =/ dap-pax=path /app/[i.daz]/hoon + =/ dap-arch .^(arch cy+(en-beam now-beak (flop dap-pax))) + ?~ fil.dap-arch + $(daz t.daz) + =/ sing=card + :+ %pass /build/app/[i.daz] + [%arvo %c %warp our.bowl %home ~ %sing %a da+now.bowl dap-pax] + %_ $ + daz t.daz + fex [sing fex] + app.state (~(put in app.state) /app/[i.daz]) + == + :: + ++ test-generators + =| fex=(list card) + ^+ [fex this] + ?> =(~ gen.state) + =. gen-ok.state %.y + =+ .^(paz=(list path) ct+(en-beam now-beak /gen)) + |- ^+ [fex this] + ?~ paz [fex this] + =/ xap=path (flop i.paz) + ?. ?=([%hoon *] xap) + $(paz t.paz) + =/ sing=card + :+ %pass build+i.paz + [%arvo %c %warp our.bowl %home ~ %sing %a da+now.bowl i.paz] + %_ $ + paz t.paz + fex [sing fex] + gen.state (~(put in gen.state) i.paz) + == + :: + ++ now-beak %_(byk.bowl r [%da now.bowl]) -- -:: -:: ++ on-watch on-watch:def ++ on-leave on-leave:def ++ on-peek on-peek:def ++ on-agent on-agent:def ++ on-arvo |= [=wire =sign-arvo] - |^ - :_ this - ^- (list card) - ?. ?=([%a-core *] wire) + ^- [(list card) _this] + ?. ?=([%build *] wire) (on-arvo:def wire sign-arvo) - ?. ?=(%made +<.sign-arvo) + ?. ?=(%writ +<.sign-arvo) (on-arvo:def wire sign-arvo) - =/ =spur t.wire - =/ res result.sign-arvo - ?: ?=([%incomplete *] res) - ~& incomplete-core+spur - ((slog tang.res) ~) - ?. ?=([%complete %success *] res) - ~& unsuccessful-core+spur - ((slog message.build-result.res) ~) - ?> ?=(^ +<.build-result.res) - %- (slog (report-error spur head.build-result.res)) - =/ nex=(list ^spur) - =< p - ;; [%success %$ %cont * p=(list ^spur)] - tail.build-result.res - ?~ nex ~&(%cores-tested ~) - [(build-core [p q]:byk.bowl nex) ~] + =/ =path t.wire + ?+ path ~|(path+path !!) + [%app *] + =/ ok + ?~ p.sign-arvo | + (~(nest ut -:!>(*agent:gall)) | -:!<(vase q.r.u.p.sign-arvo)) + ~& ?: ok + agent-built+path + agent-failed+path + =? app-ok.state !ok %.n + =. app.state (~(del in app.state) path) + ~? =(~ app.state) + ?: app-ok.state + %all-agents-built + %some-agents-failed + [~ this] :: - ++ report-error - |= [=spur bud=build-result] - ^- tang - =/ should-fail (~(get by failing) (flop spur)) - ?- -.bud - %success - ?~ should-fail ~ - :~ leaf+"warn: expected failure, {<`tape`u.should-fail>}" - leaf+"warn: built succesfully" - ?: ?=(%bake +<.bud) - (sell q.cage.bud) - ?> ?=(%core +<.bud) - (sell vase.bud) - == - :: - %error - ?^ should-fail - ~[>[%failed-known `tape`(weld "TODO: " u.should-fail)]<] - (flop message.bud) - == + [%mar *] + =/ ok ?=(^ p.sign-arvo) + ~& ?: ok + mark-built+path + mark-failed+path + =? mar-ok.state !ok %.n + =. mar.state (~(del in mar.state) path) + ~? =(~ mar.state) + ?: mar-ok.state + %all-marks-built + %some-marks-failed + [~ this] :: - ++ failing - ^~ ^- (map path tape) - %- my :~ ::TODO don't hardcode - :: - :- /gen/al "compiler types out-of-date" - :- /gen/musk "compiler types out-of-date" - :: - :- /gen/cosmetic "incomplete" - :- /gen/lust "incomplete" - :- /gen/scantastic "incomplete" - == - -- -:: + [%gen *] + =/ ok ?=(^ p.sign-arvo) + ~& ?: ok + generator-built+path + generator-failed+path + =? gen-ok.state !ok %.n + =. gen.state (~(del in gen.state) path) + ~? =(~ gen.state) + ?: gen-ok.state + %all-generators-built + %some-generators-failed + [~ this] + == ++ on-fail on-fail:def -- diff --git a/pkg/arvo/gen/acme/domain-validation.hoon b/pkg/arvo/gen/acme/domain-validation.hoon index a1b4c2c05c..477317e810 100644 --- a/pkg/arvo/gen/acme/domain-validation.hoon +++ b/pkg/arvo/gen/acme/domain-validation.hoon @@ -20,7 +20,13 @@ [[%404 ~] ~] =/ challenge=@t i.t.t.q.p.u.url =/ response - .^((unit @t) %gx /=acme/(scot %da now)/domain-validation/[challenge]/noun) + .^ (unit @t) + %gx + (scot %p p.bek) + %acme + (scot %da now) + /domain-validation/[challenge]/noun + == ?~ response [[%404 ~] ~] :- [200 ['content-type' 'text/html']~] diff --git a/pkg/arvo/gen/azimuth-block.hoon b/pkg/arvo/gen/azimuth-block.hoon index dfb108ee7c..6b42aa8d84 100644 --- a/pkg/arvo/gen/azimuth-block.hoon +++ b/pkg/arvo/gen/azimuth-block.hoon @@ -4,6 +4,11 @@ :: processed only those blocks which are this number minus 30. :: :- %say -|= [[now=@da *] *] +|= [[now=@da @ our=@p ^] *] :- %tang -[>.^(@ud %gx /=eth-watcher/(scot %da now)/block/azimuth-tracker/noun)< ~] +=; block=@ud + [leaf+(scow %ud block)]~ +.^ @ud + %gx + /(scot %p our)/eth-watcher/(scot %da now)/block/azimuth-tracker/noun +== diff --git a/pkg/arvo/gen/azimuth-sources.hoon b/pkg/arvo/gen/azimuth-sources.hoon index bdcb57cd77..e143eeaee0 100644 --- a/pkg/arvo/gen/azimuth-sources.hoon +++ b/pkg/arvo/gen/azimuth-sources.hoon @@ -1,5 +1,5 @@ :: List azimuth sources :- %say -|= [[now=@da *] *] +|= [[now=@da @ our=@p ^] *] :- %noun -.^(state-eth-node:jael j//=sources/(scot %da now)) +.^(state-eth-node:jael j//(scot %p our)/sources/(scot %da now)) diff --git a/pkg/arvo/gen/hello.hoon b/pkg/arvo/gen/hello.hoon index 41a2c1cf81..b2a75750e9 100644 --- a/pkg/arvo/gen/hello.hoon +++ b/pkg/arvo/gen/hello.hoon @@ -2,6 +2,7 @@ :: :::: /hoon/hello/gen :: +:: TODO: reinstate /? 310 :: :::: diff --git a/pkg/arvo/gen/hood/autoload.hoon b/pkg/arvo/gen/hood/autoload.hoon deleted file mode 100644 index f31fe68d56..0000000000 --- a/pkg/arvo/gen/hood/autoload.hoon +++ /dev/null @@ -1,14 +0,0 @@ -:: Helm: Disable/enable/toggle auto-reload of kernel components -:: -:::: /hoon/autoload/hood/gen - :: -/? 310 -:: -:::: - :: -:- %say -|= $: {now/@da eny/@uvJ bec/beak} - {arg/?(~ {? ~}) ~} - == -:- %kiln-autoload -`(unit ?)`?~(arg ~ `-.arg) diff --git a/pkg/arvo/gen/hood/keep-ford.hoon b/pkg/arvo/gen/hood/keep-ford.hoon deleted file mode 100644 index 30bac8cdf5..0000000000 --- a/pkg/arvo/gen/hood/keep-ford.hoon +++ /dev/null @@ -1,13 +0,0 @@ -:: Kiln: resize Ford cache -:: -:::: - :: -/? 310 -:: -:::: - !: -:- %say -|= $: [now=@da eny=@uvJ bec=beak] - [[compiler-cache-size=@ud build-cache-size=@ud ~] ~] - == -[%kiln-keep-ford compiler-cache-size build-cache-size] diff --git a/pkg/arvo/gen/hood/load.hoon b/pkg/arvo/gen/hood/load.hoon deleted file mode 100644 index 238e48bc6d..0000000000 --- a/pkg/arvo/gen/hood/load.hoon +++ /dev/null @@ -1,15 +0,0 @@ -:: Hood, generic: load named hood component's state from backup -:: -:::: /hoon/load/hood/gen - :: -/? 310 -:: -:::: - :: -:- %say -|= $: {now/@da eny/@uvJ byk/beak} - {{dap/term pas/@uw ~} ~} - == -:- %hood-load -~| %hood-load-stub -!! diff --git a/pkg/arvo/gen/hood/ota.hoon b/pkg/arvo/gen/hood/ota.hoon new file mode 100644 index 0000000000..c91f5b9f3a --- /dev/null +++ b/pkg/arvo/gen/hood/ota.hoon @@ -0,0 +1,14 @@ +:: Kiln: Continuously merge local desk from (optionally-)foreign one +:: +:::: /hoon/ota/hood/gen + :: +/? 310 +:: +:::: + :: +:- %say +|= $: [now=@da eny=@uvJ bec=beak] + [arg=?(~ [her=@p sud=@tas ~]) ~] + == +:- %kiln-ota +?~(arg ~ `[her sud]:arg) diff --git a/pkg/arvo/gen/hood/overload.hoon b/pkg/arvo/gen/hood/overload.hoon deleted file mode 100644 index 5be499e2d6..0000000000 --- a/pkg/arvo/gen/hood/overload.hoon +++ /dev/null @@ -1,13 +0,0 @@ -:: Kiln: regularly clear %ford cache XX find relevant leak -:: -:::: /hoon/overload/hood/gen - :: -/? 310 -:: -:::: - :: -:- %say -|= $: {now/@da eny/@uvJ bec/beak} - {{recur/@dr start/@da ~} ~} - == -[%kiln-overload recur start] diff --git a/pkg/arvo/gen/hood/reboot.hoon b/pkg/arvo/gen/hood/reboot.hoon index cce93c26f9..f9afb0a3c7 100644 --- a/pkg/arvo/gen/hood/reboot.hoon +++ b/pkg/arvo/gen/hood/reboot.hoon @@ -10,4 +10,4 @@ |= $: {now/@da eny/@uvJ bec/beak} {arg/~ ~} == -[%helm-reload ~[%z %a %b %c %d %e %f %g %i %j]] +[%helm-reload ~[%z %a %b %c %d %e %g %i %j]] diff --git a/pkg/arvo/gen/hood/rf.hoon b/pkg/arvo/gen/hood/rf.hoon deleted file mode 100644 index c1b6fa0614..0000000000 --- a/pkg/arvo/gen/hood/rf.hoon +++ /dev/null @@ -1,13 +0,0 @@ -:: Helm: Reload %ford -:: -:::: /hoon/rf/hood/gen - :: -/? 310 -:: -:::: - :: -:- %say -|= $: {now/@da eny/@uvJ bec/beak} - {arg/~ ~} - == -[%helm-reload ~[%f]] diff --git a/pkg/arvo/gen/hood/static.hoon b/pkg/arvo/gen/hood/static.hoon deleted file mode 100644 index 0cd26f14b4..0000000000 --- a/pkg/arvo/gen/hood/static.hoon +++ /dev/null @@ -1,79 +0,0 @@ -:: Serve static files -/? 309 -:: -/= pre-process - /^ (map path [@tas @t]) - /: /===/web/static-site /* - /| /; |=(@t [%html +<]) /&html&/!hymn/ - /; |=(@t [%html +<]) /&html&/&elem&/udon/ - :: XX /lib/down-jet/parse is broken - :: /; |=(@t [%html +<]) /&html&/&hymn&/&down&/md/ - /; |=(@t [%raw +<]) /atom/ - == -:: -~& %finished-preprocessing -:- %say -|= $: [now=@da eny=@uv bec=beak] - ~ - ~ - == -=> -|% -++ convert-link - |= [pre=tape link=tape] - =/ parsed=(unit (list coin)) - %+ rust link - ;~ pose - ;~(pfix net (more net nuck:so)) - (more net nuck:so) - == - ?~ parsed - link - ^- tape - %+ welp - =< + - %^ spin u.parsed pre - |= [c=coin s=path] - ^- [* out=tape] - ?> ?=([%$ dime] c) - [0 (weld "{s}/" (scow +.c))] - :: - ".html" -:: -++ convert-file - |= [pre=tape fil=tape] - ^- tape - =/ idc=(list @ud) (fand "" b)) - =/ old-link=tape (scag c b) - =/ new-link=tape (convert-link pre old-link) - =/ new-file=tape :(welp a new-link (slag c b)) - =/ new-f (sub (lent new-link) (lent old-link)) - [0 (add f new-f) new-file] --- -:: -:- %dill-blit -=/ trio /(scot %p p.bec)/[q.bec]/(scot r.bec) -=/ dirs .^((list path) %ct (weld trio /web/static-site)) -:: -:- %mor -%+ roll dirs -|= [pax=path out=(list [%sav path @t])] -=/ path-prefix=path (scag (dec (lent pax)) pax) -=/ pre=[@tas @t] (~(got by pre-process) path-prefix) -:_ out -:- %sav -?: =(%raw -.pre) - [pax +.pre] -:: find and update links -=/ root=tape - ?~ path-prefix "" - (slag 1 (spud (scag 1 (flop path-prefix)))) -=/ fil=tape (convert-file root (trip +.pre)) -[(weld path-prefix /[-.pre]) (crip fil)] diff --git a/pkg/arvo/gen/hood/wipe-ford.hoon b/pkg/arvo/gen/hood/wipe-ford.hoon deleted file mode 100644 index 4261e871b7..0000000000 --- a/pkg/arvo/gen/hood/wipe-ford.hoon +++ /dev/null @@ -1,14 +0,0 @@ -:: Kiln: wipe ford cache -:: -:::: /hoon/wipe-ford/hood/gen - :: -/? 310 -:: -:::: - !: -:- %say -|= $: [now=@da eny=@uvJ bec=beak] - [percent=@ud ~] - ~ - == -[%kiln-wipe-ford percent] diff --git a/pkg/arvo/gen/keys.hoon b/pkg/arvo/gen/keys.hoon index 38f9aa6b16..955c848a4b 100644 --- a/pkg/arvo/gen/keys.hoon +++ b/pkg/arvo/gen/keys.hoon @@ -1,8 +1,11 @@ :: Print keys for a ship :: :- %say -|= [[now=time *] [=ship ~] ~] +|= [[now=time @ our=ship ^] [her=ship ~] ~] +=/ our (scot %p our) +=/ now (scot %da now) +=/ her (scot %p her) :* %noun - life=.^((unit @ud) %j /=lyfe/(scot %da now)/(scot %p ship)) - rift=.^((unit @ud) %j /=ryft/(scot %da now)/(scot %p ship)) + life=.^((unit @ud) %j /[our]/lyfe/[now]/[her]) + rift=.^((unit @ud) %j /[our]/ryft/[now]/[her]) == diff --git a/pkg/arvo/gen/link-store/note.hoon b/pkg/arvo/gen/link-store/note.hoon index 7f26a3b595..6b3651ad69 100644 --- a/pkg/arvo/gen/link-store/note.hoon +++ b/pkg/arvo/gen/link-store/note.hoon @@ -1,6 +1,6 @@ :: link-store|note: write a note on a link in a path :: -/- *link +/- *link-store, *link :- %say |= $: [now=@da eny=@uvJ =beak] [[=path =url note=@t ~] ~] diff --git a/pkg/arvo/gen/link-store/save.hoon b/pkg/arvo/gen/link-store/save.hoon index 3a3304b3d1..59a5c6012e 100644 --- a/pkg/arvo/gen/link-store/save.hoon +++ b/pkg/arvo/gen/link-store/save.hoon @@ -1,6 +1,6 @@ :: link-store|save: save a link to a path :: -/- *link +/- *link-store, *link :- %say |= $: [now=@da eny=@uvJ =beak] [[=path title=@t =url ~] ~] diff --git a/pkg/arvo/gen/metal.hoon b/pkg/arvo/gen/metal.hoon index 1eb3e579d3..e62dd279fd 100644 --- a/pkg/arvo/gen/metal.hoon +++ b/pkg/arvo/gen/metal.hoon @@ -207,10 +207,6 @@ :: (vent %e /vane/eyre) :: - :: sys/vane/ford: build - :: - (vent %f /vane/ford) - :: :: sys/vane/gall: applications :: (vent %g /vane/gall) diff --git a/pkg/arvo/gen/spider/tree.hoon b/pkg/arvo/gen/spider/tree.hoon index 48d3455d19..eabafffa9a 100644 --- a/pkg/arvo/gen/spider/tree.hoon +++ b/pkg/arvo/gen/spider/tree.hoon @@ -1,10 +1,13 @@ :: List running threads /- spider :- %say -|= [[now=@da *] ~ *] +|= [[now=@da @ our=@p ^] ~ *] :- %tang =/ tree - .^((list (list tid:spider)) %gx /=spider/(scot %da now)/tree/noun) + .^ (list (list tid:spider)) + %gx + /(scot %p our)/spider/(scot %da now)/tree/noun + == %+ turn tree |= yarn=(list tid:spider) >`path`yarn< diff --git a/pkg/arvo/gen/test.hoon b/pkg/arvo/gen/test.hoon deleted file mode 100644 index 9d9998d70e..0000000000 --- a/pkg/arvo/gen/test.hoon +++ /dev/null @@ -1,83 +0,0 @@ -:: Run tests -/+ test-runner -/= all-tests - /^ (map path (list test-arm:test-runner)) - /: /===/tests - /* /test-gen/ -:: -|% -++ main - |= [defer=? tests=(list test:test-runner)] - ^- tang - :: - %- zing - %+ turn tests - |= [=path test-func=test-func:test-runner] - ^- tang - :: - =/ test-results=tang (run-test path test-func) - :: if :defer is set, produce errors; otherwise print them and produce ~ - :: - ?: defer - test-results - ((slog (flop test-results)) ~) -:: -++ run-test - :: executes an individual test. - |= [pax=path test=test-func:test-runner] - ^- tang - =+ name=(spud pax) - =+ run=(mule test) - ?- -.run - %| :: the stack is already flopped for output? - ;: weld - p.run - `tang`[[%leaf (weld "CRASHED " name)] ~] - == - %& ?: =(~ p.run) - [[%leaf (weld "OK " name)] ~] - :: Create a welded list of all failures indented. - %- flop - ;: weld - `tang`[[%leaf (weld "FAILED " name)] ~] - ::TODO indent - :: %+ turn p:run - :: |= {i/tape} - :: ^- tank - :: [%leaf (weld " " i)] - p.run - == - == -:: +filter-tests-by-prefix -:: -++ filter-tests-by-prefix - |= [prefix=path tests=(list test:test-runner)] - ^+ tests - :: - =/ prefix-length=@ud (lent prefix) - :: - %+ skim tests - :: - |= [=path *] - =(prefix (scag prefix-length path)) --- -:: -:- %say -|= $: [now=@da eny=@uvJ bec=beak] - [filter=$?(~ [pax=path ~])] - [defer=_& seed=?(~ @uvJ)] - == -:: start printing early if we're not deferring output -:: -~? !defer %tests-compiled -:- %tang -:: use empty path prefix if unspecified -:: -=/ prefix=path ?~(filter ~ pax.filter) -:: -=/ filtered-tests=(list test:test-runner) - %+ filter-tests-by-prefix - prefix - (resolve-test-paths:test-runner all-tests) -:: -(main defer filtered-tests) diff --git a/pkg/arvo/gen/timers.hoon b/pkg/arvo/gen/timers.hoon index f53710f587..a28eeb177a 100644 --- a/pkg/arvo/gen/timers.hoon +++ b/pkg/arvo/gen/timers.hoon @@ -1,5 +1,5 @@ :: Find list of currently running Behn timers :- %say -|= * +|= [[now=@da eny=@uvJ bec=beak] ~ ~] :- %tang -[>.^((list [date=@da =duct]) %b /=timers=)< ~] +[>.^((list [date=@da =duct]) %b (en-beam:format [p.bec %timers r.bec] /))< ~] diff --git a/pkg/arvo/gen/trouble.hoon b/pkg/arvo/gen/trouble.hoon index 3ab8d718e8..58df96e1eb 100644 --- a/pkg/arvo/gen/trouble.hoon +++ b/pkg/arvo/gen/trouble.hoon @@ -7,8 +7,9 @@ :- %noun =< :~ - [%base-hash .^(@uv %cz (pathify ~.base ~))] + [%base-hash base-hash] [%home-hash .^(@uv %cz (pathify ~.home ~))] + [%kids-hash .^(@uv %cz (pathify ~.kids ~))] :: (info %our our) (info %sponsor sponsor) @@ -40,4 +41,9 @@ life=lyfe rift=ryft == +:: +++ base-hash + =/ parent (scot %p (sein:title our now our)) + =+ .^(=cass:clay %cs /[parent]/kids/1/late/foo) + .^(@uv %cz /[parent]/kids/(scot %ud ud.cass)) -- diff --git a/pkg/arvo/lib/hood/drum.hoon b/pkg/arvo/lib/hood/drum.hoon index 71cc5f26df..86601df014 100644 --- a/pkg/arvo/lib/hood/drum.hoon +++ b/pkg/arvo/lib/hood/drum.hoon @@ -1,33 +1,16 @@ -:: :: :: -:::: /hoon/drum/hood/lib :: :: - :: :: :: -/? 310 :: version -/- *sole -/+ sole -:: :: :: -:::: :: :: - :: :: :: -|% :: :: -++ part {$drum $2 pith-2} :: -++ part-old {$drum $1 pith-1} :: -:: :: -++ pith-1 :: pre-style - %+ cork pith-2 :: - |:($:pith-2 +<(bin ((map bone source-1)))) :: -:: :: -++ source-1 :: - %+ cork source :: - |:($:source +<(mir ((pair @ud (list @c))))) :: style-less mir -:: :: +/- *sole +/+ sole +|% ++$ any-state $%(state) ++$ state [%2 pith-2] +:: ++ pith-2 :: $: eel/(set gill:gall) :: connect to ray/(set well:gall) :: fur/(map dude:gall (unit server)) :: servers bin/(map bone source) :: terminals == :: -:: :: :: -:::: :: :: - :: :: :: +:: :: ++ server :: running server $: syd/desk :: app identity cas/case :: boot case @@ -72,7 +55,7 @@ :: :: :: |% ++ deft-apes :: default servers - |= [our/ship lit/?] + |= [our=ship lit=?] %- ~(gas in *(set well:gall)) ^- (list well:gall) :: boot all default apps off the home desk @@ -122,41 +105,34 @@ == :: ++ deft-fish :: default connects - |= our/ship + |= our=ship %- ~(gas in *(set gill:gall)) ^- (list gill:gall) [[our %dojo] [our %chat-cli]~] :: -++ make :: initial part - |= our/ship - ^- part - :* %drum - %2 - eel=(deft-fish our) - ray=~ - fur=~ - bin=~ - == -:: -:: ++ en-gill :: gill to wire - |= gyl/gill:gall + |= gyl=gill:gall ^- wire [%drum %phat (scot %p p.gyl) q.gyl ~] :: ++ de-gill :: gill from wire - |= way/wire ^- gill:gall - ?>(?=({@ @ ~} way) [(slav %p i.way) i.t.way]) + |= way=wire ^- gill:gall + ?>(?=([@ @ ~] way) [(slav %p i.way) i.t.way]) -- +:: TODO: remove .ost :: -:::: - :: -|= {hid/bowl:gall part} :: main drum work +|= [hid=bowl:gall state] +=* sat +<+ =/ ost 0 =+ (~(gut by bin) ost *source) =* dev - -|_ {moz/(list card:agent:gall) biz/(list dill-blit:dill)} -+* this . +=| moz=(list card:agent:gall) +=| biz=(list dill-blit:dill) +|% +++ this . ++$ state ^state :: proxy ++$ any-state ^any-state :: proxy +++ on-init se-abet:this(eel (deft-fish our.hid)) ++ diff-sole-effect-phat :: app event |= {way/wire fec/sole-effect} =< se-abet =< se-view @@ -172,14 +148,15 @@ (se-text "[{}, driving {}]") :: ++ poke-set-boot-apps :: - |= lit/? - ^- (quip card:agent:gall part) + |= lit=? + ^- (quip card:agent:gall ^state) :: We do not run se-abet:se-view here because that starts the apps, :: and some apps are not ready to start (eg Talk crashes because the :: terminal has width 0). It appears the first message to drum must :: be the peer. :: - [~ +<+.^$(ray (deft-apes our.hid lit))] + =. ray (deft-apes our.hid lit) + [~ sat] :: ++ poke-dill-belt :: terminal event |= bet/dill-belt:dill @@ -193,7 +170,7 @@ ++ poke-start :: start app |= wel/well:gall =< se-abet =< se-view - (se-born wel) + (se-born & wel) :: ++ poke-link :: connect app |= gyl/gill:gall @@ -216,38 +193,40 @@ ++ poke |= [=mark =vase] ?+ mark ~|([%poke-drum-bad-mark mark] !!) - %drum-put =;(f (f !<(_+<.f vase)) poke-put) - %drum-link =;(f (f !<(_+<.f vase)) poke-link) - %drum-unlink =;(f (f !<(_+<.f vase)) poke-unlink) + %drum-dill-belt =;(f (f !<(_+<.f vase)) poke-dill-belt) + %drum-dill-blit =;(f (f !<(_+<.f vase)) poke-dill-blit) %drum-exit =;(f (f !<(_+<.f vase)) poke-exit) - %drum-start =;(f (f !<(_+<.f vase)) poke-start) + %drum-link =;(f (f !<(_+<.f vase)) poke-link) + %drum-put =;(f (f !<(_+<.f vase)) poke-put) %drum-set-boot-apps =;(f (f !<(_+<.f vase)) poke-set-boot-apps) + %drum-start =;(f (f !<(_+<.f vase)) poke-start) + %drum-unlink =;(f (f !<(_+<.f vase)) poke-unlink) == :: ++ on-load - |= ver=?(%1 %2 %3 %4 %5) + |= [hood-version=?(%1 %2 %3 %4 %5 %6 %7) old=any-state] =< se-abet =< se-view - =? . (lte ver %4) - =. ver %5 - =. ..on-load - =< (se-emit %pass /kiln %arvo %g %sear ~wisrut-nocsub) - =< (se-born %home %goad) - =< (se-born %home %metadata-store) - =< (se-born %home %metadata-hook) - =< (se-born %home %contact-store) - =< (se-born %home %contact-hook) - =< (se-born %home %contact-view) - =< (se-born %home %link-store) - =< (se-born %home %link-proxy-hook) - =< (se-born %home %link-listen-hook) - =< (se-born %home %link-view) - =< (se-born %home %s3-store) - (se-born %home %file-server) - . - ?> ?=(%5 ver) - => (se-born %home %file-server) - => (se-drop:(se-pull our.hid %dojo) | our.hid %dojo) - (se-drop:(se-pull our.hid %chat-cli) | our.hid %chat-cli) + =. sat old + =. dev (~(gut by bin) ost *source) + =? ..on-load (lte hood-version %4) + ~> %slog.0^leaf+"drum: starting os1 agents" + => (se-born | %home %s3-store) + => (se-born | %home %link-view) + => (se-born | %home %link-listen-hook) + => (se-born | %home %link-store) + => (se-born | %home %link-proxy-hook) + => (se-born | %home %contact-view) + => (se-born | %home %contact-hook) + => (se-born | %home %contact-store) + => (se-born | %home %metadata-hook) + => (se-born | %home %metadata-store) + => (se-born | %home %goad) + ~> %slog.0^leaf+"drum: resubscribing to %dojo and %chat-cli" + => (se-drop:(se-pull our.hid %dojo) | our.hid %dojo) + (se-drop:(se-pull our.hid %chat-cli) | our.hid %chat-cli) + =? ..on-load (lte hood-version %5) + (se-born | %home %file-server) + ..on-load :: ++ reap-phat :: ack connect |= {way/wire saw/(unit tang)} @@ -260,7 +239,7 @@ :: (se-drop & gyl) :: -++ take :: +++ take-arvo |= [=wire =sign-arvo] %+ take-onto wire ?> ?=(%onto +<.sign-arvo) @@ -314,10 +293,9 @@ :::: :: :: :: :: :: ++ se-abet :: resolve - ^- (quip card:agent:gall part) - =* pith +<+.$ + ^- (quip card:agent:gall state) =. . se-subze:se-adze:se-adit - :_ pith(bin (~(put by bin) ost dev)) + :_ sat(bin (~(put by bin) ost dev)) ^- (list card:agent:gall) ?~ biz (flop moz) :_ (flop moz) @@ -345,7 +323,7 @@ (se-text "activated app {(trip p.wel)}/{(trip q.wel)}") =. this %- se-emit - [%pass wire %arvo %g %conf [our.hid q.wel] our.hid p.wel] + [%pass wire %arvo %g %conf q.wel] $(servers t.servers) :: ++ priorities @@ -466,9 +444,10 @@ ta-abet:(ta-belt:(se-tame u.gul) bet) :: ++ se-born :: new server - |= wel/well:gall + |= [print-on-repeat=? wel=well:gall] ^+ +> ?: (~(has in ray) wel) + ?. print-on-repeat +> (se-text "[already running {}/{}]") %= +> ray (~(put in ray) wel) diff --git a/pkg/arvo/lib/hood/helm.hoon b/pkg/arvo/lib/hood/helm.hoon index b1471a1fe1..c742effce9 100644 --- a/pkg/arvo/lib/hood/helm.hoon +++ b/pkg/arvo/lib/hood/helm.hoon @@ -1,55 +1,45 @@ -:: :: :: -:::: /hoon/helm/hood/lib :: :: - :: :: :: -/? 310 :: version -/- sole -/+ pill -:: :: :: -:::: :: :: - :: :: :: -|% :: :: -++ part {$helm $0 pith} :: helm state -++ pith :: helm content - $: hoc/(map bone session) :: consoles - == :: -++ session :: - $: say/sole-share:sole :: console state - mud/(unit (sole-dialog:sole @ud)) :: console dialog - mass-timer/{way/wire nex/@da tim/@dr} - == :: -:: :: :: -:::: :: :: - :: :: :: -++ hood-reset :: reset command - $~ :: -++ helm-verb :: reset command - $~ :: -++ hood-reload :: reload command - (list term) :: --- :: -:: :: :: -:::: :: :: - :: :: :: -|: $:{bowl:gall part} :: main helm work -=/ ost 0 -=+ sez=(~(gut by hoc) ost $:session) -=| moz=(list card:agent:gall) +/+ pill +=* card card:agent:gall |% -++ abet - [(flop moz) %_(+<+.$ hoc (~(put by hoc) ost sez))] ++$ any-state $%(state state-0) ++$ state + $: %1 + mass-timer=[way=wire nex=@da tim=@dr] + == ++$ state-0 [%0 hoc=(map bone session-0)] ++$ session-0 + $: say=* + mud=* + mass-timer=[way=wire nex=@da tim=@dr] + == :: -++ emit - |= card:agent:gall - %_(+> moz [+< moz]) +++ state-0-to-1 + |= s=state-0 + ^- state + [%1 mass-timer:(~(got by hoc.s) 0)] +-- +|= [=bowl:gall sat=state] +=| moz=(list card) +|% +++ this . ++$ state ^state :: proxy ++$ any-state ^any-state :: proxy +++ abet [(flop moz) sat] +++ flog |=(=flog:dill (emit %pass /di %arvo %d %flog flog)) +++ emit |=(card this(moz [+< moz])) +:: +emil: emit multiple cards :: -++ flog - |= =flog:dill - (emit %pass /di %arvo %d %flog flog) +++ emil + |= caz=(list card) + ^+ this + ?~(caz this $(caz t.caz, this (emit i.caz))) :: -++ emil :: return cards - |= (list card:agent:gall) - ^+ +> - ?~(+< +> $(+< t.+<, +> (emit i.+<))) +++ on-load + |= [hood-version=?(%1 %2 %3 %4 %5 %6 %7) old=any-state] + =< abet + =? old ?=(%0 -.old) (state-0-to-1 old) + ?> ?=(%1 -.old) + this(sat old) :: ++ poke-rekey :: rotate private keys |= des=@t @@ -60,17 +50,33 @@ =< abet ?~ sed ~& %invalid-private-key - +>.$ - ?. =(our who.u.sed) + this + ?. =(our.bowl who.u.sed) ~& [%wrong-private-key-ship who.u.sed] - +>.$ + this (emit %pass / %arvo %j %rekey lyf.u.sed key.u.sed) :: +++ ames-secret + ^- @t + =; pax (crip +:<.^(@p %j pax)>) + /(scot %p our.bowl)/code/(scot %da now.bowl)/(scot %p our.bowl) +:: +++ poke-sec-atom + |= [hot=host:eyre dat=@] + ?> ?=(%& -.hot) + =. p.hot (scag 2 p.hot) :: ignore subdomain + =. dat (scot %uw (en:crub:crypto ames-secret dat)) + =- abet:(emit %pass /write %arvo %c %info -) + =/ byk=path (en-beam:format byk.bowl(r da+now.bowl) ~) + =+ .^(=tube:clay cc+(welp byk /mime/atom)) + =/ =cage atom+(tube !>([/ (as-octs:mimes:html dat)])) + (foal:space:userlib :(welp byk sec+p.hot /atom) cage) +:: ++ poke-moon :: rotate moon keys |= sed=(unit [=ship =udiff:point:able:jael]) =< abet ?~ sed - +>.$ + this (emit %pass / %arvo %j %moon u.sed) :: ++ poke-mass @@ -79,13 +85,13 @@ :: ++ poke-automass |= recur=@dr - =. mass-timer.sez - [/helm/automass (add now recur) recur] - abet:(emit %pass way.mass-timer.sez %arvo %b %wait nex.mass-timer.sez) + =. mass-timer.sat + [/helm/automass (add now.bowl recur) recur] + abet:(emit %pass way.mass-timer.sat %arvo %b %wait nex.mass-timer.sat) :: ++ poke-cancel-automass |= ~ - abet:(emit %pass way.mass-timer.sez %arvo %b %rest nex.mass-timer.sez) + abet:(emit %pass way.mass-timer.sat %arvo %b %rest nex.mass-timer.sat) :: ++ poke-pack |= ~ =< abet @@ -97,11 +103,11 @@ %- (slog u.error) ~& %helm-wake-automass-fail abet - =. nex.mass-timer.sez (add now tim.mass-timer.sez) + =. nex.mass-timer.sat (add now.bowl tim.mass-timer.sat) =< abet %- emil :~ [%pass /heft %arvo %d %flog %crud %hax-heft ~] - [%pass way.mass-timer.sez %arvo %b %wait nex.mass-timer.sez] + [%pass way.mass-timer.sat %arvo %b %wait nex.mass-timer.sat] == :: ++ poke-send-hi @@ -119,14 +125,14 @@ ?: =(%fail mes) ~& %poke-hi-fail !! - abet:(flog %text "< {}: {(trip mes)}") + abet:(flog %text "< {}: {(trip mes)}") :: ++ poke-atom |= ato/@ =+ len=(scow %ud (met 3 ato)) =+ gum=(scow %p (mug ato)) =< abet - (flog %text "< {}: atom: {len} bytes, mug {gum}") + (flog %text "< {}: atom: {len} bytes, mug {gum}") :: ++ coup-hi |= {pax/path cop/(unit tang)} =< abet @@ -138,7 +144,7 @@ |: $:{syd/desk all/(list term)} =< abet %- emil %+ turn all - =+ top=`path`/(scot %p our)/[syd]/(scot %da now) + =+ top=`path`/(scot %p our.bowl)/[syd]/(scot %da now.bowl) =/ van/(list {term ~}) :- zus=[%zuse ~] ~(tap by dir:.^(arch %cy (welp top /sys/vane))) @@ -161,14 +167,15 @@ :: Trigger with |reset. :: ++ poke-reset - |= hood-reset + |= hood-reset=~ =< abet %- emil ^- (list card:agent:gall) - =/ top=path /(scot %p our)/home/(scot %da now)/sys - =/ hun .^(@ %cx (welp top /hoon/hoon)) - =/ arv .^(@ %cx (welp top /arvo/hoon)) - :- [%pass /reset %arvo %d %flog %lyra `@t`hun `@t`arv] + =/ top=path /(scot %p our.bowl)/home/(scot %da now.bowl)/sys + =/ hun .^(@t %cx (welp top /hoon/hoon)) + =/ arv .^(@t %cx (welp top /arvo/hoon)) + ~! *task:able:dill + :- [%pass /reset %arvo %d %flog %lyra `hun arv] %+ turn (module-ova:pill top) |=([=wire =flog:dill] [%pass wire %arvo %d %flog flog]) @@ -200,23 +207,25 @@ ++ poke |= [=mark =vase] ?+ mark ~|([%poke-helm-bad-mark mark] !!) + %helm-ames-sift =;(f (f !<(_+<.f vase)) poke-ames-sift) + %helm-ames-verb =;(f (f !<(_+<.f vase)) poke-ames-verb) + %helm-ames-wake =;(f (f !<(_+<.f vase)) poke-ames-wake) + %helm-atom =;(f (f !<(_+<.f vase)) poke-atom) + %helm-automass =;(f (f !<(_+<.f vase)) poke-automass) + %helm-cancel-automass =;(f (f !<(_+<.f vase)) poke-cancel-automass) %helm-hi =;(f (f !<(_+<.f vase)) poke-hi) + %helm-knob =;(f (f !<(_+<.f vase)) poke-knob) %helm-mass =;(f (f !<(_+<.f vase)) poke-mass) + %helm-moon =;(f (f !<(_+<.f vase)) poke-moon) %helm-pack =;(f (f !<(_+<.f vase)) poke-pack) + %helm-rekey =;(f (f !<(_+<.f vase)) poke-rekey) %helm-reload =;(f (f !<(_+<.f vase)) poke-reload) %helm-reload-desk =;(f (f !<(_+<.f vase)) poke-reload-desk) %helm-reset =;(f (f !<(_+<.f vase)) poke-reset) %helm-send-hi =;(f (f !<(_+<.f vase)) poke-send-hi) - %helm-ames-sift =;(f (f !<(_+<.f vase)) poke-ames-sift) - %helm-ames-verb =;(f (f !<(_+<.f vase)) poke-ames-verb) - %helm-ames-wake =;(f (f !<(_+<.f vase)) poke-ames-wake) - %helm-verb =;(f (f !<(_+<.f vase)) poke-verb) - %helm-knob =;(f (f !<(_+<.f vase)) poke-knob) - %helm-rekey =;(f (f !<(_+<.f vase)) poke-rekey) - %helm-automass =;(f (f !<(_+<.f vase)) poke-automass) - %helm-cancel-automass =;(f (f !<(_+<.f vase)) poke-cancel-automass) - %helm-moon =;(f (f !<(_+<.f vase)) poke-moon) %helm-serve =;(f (f !<(_+<.f vase)) poke-serve) + %helm-verb =;(f (f !<(_+<.f vase)) poke-verb) + %helm-write-sec-atom =;(f (f !<(_+<.f vase)) poke-sec-atom) == :: ++ take-agent @@ -230,7 +239,7 @@ |= [wir=wire success=? binding=binding:eyre] =< abet (flog %text "bound: {}") :: -++ take +++ take-arvo |= [=wire =sign-arvo] ?+ wire ~|([%helm-bad-take-wire wire +<.sign-arvo] !!) [%automass *] %+ take-wake-automass t.wire diff --git a/pkg/arvo/lib/hood/kiln.hoon b/pkg/arvo/lib/hood/kiln.hoon index e61ec47895..e3bfb0fe2d 100644 --- a/pkg/arvo/lib/hood/kiln.hoon +++ b/pkg/arvo/lib/hood/kiln.hoon @@ -1,67 +1,66 @@ -:: :: :: -:::: /hoon/kiln/hood/lib :: :: - :: :: :: -/? 310 :: version -:: :: :: -:::: :: :: - :: :: :: =, clay =, space:userlib =, format -|% :: :: -++ part {$kiln $0 pith} :: kiln state -++ pith :: :: - $: rem/(map desk per-desk) :: - syn/(map kiln-sync let/@ud) :: - autoload-on/? :: - cur-hoon/@uvI :: - cur-arvo/@uvI :: - cur-zuse/@uvI :: - cur-vanes/(map @tas @uvI) :: - commit-timer/{way/wire nex/@da tim/@dr mon=term} - == :: -++ per-desk :: per-desk state - $: auto/? :: escalate on failure - gem/germ :: strategy - her/@p :: from ship - sud/@tas :: from desk - cas/case :: at case - == :: -:: :: :: -:::: :: :: - :: :: :: -++ kiln-commit term :: -++ kiln-mount :: - $: pax/path :: - pot/term :: - == :: -++ kiln-unmount $@(term {knot path}) :: -++ kiln-sync :: - $: syd/desk :: - her/ship :: - sud/desk :: - == :: -++ kiln-unsync :: - $: syd/desk :: - her/ship :: - sud/desk :: - == :: -++ kiln-merge :: - $: syd/desk :: - ali/ship :: - sud/desk :: - cas/case :: - gim/?($auto germ) :: - == :: --- :: -:: :: :: -:::: :: :: - :: :: :: -|= {bowl:gall part} :: main kiln work +|% ++$ state [%1 pith-1] ++$ any-state + $% state + [%0 pith-0] + == ++$ pith-1 :: + $: rem=(map desk per-desk) :: + syn=(map kiln-sync let=@ud) :: + ota=(unit [=ship =desk =aeon]) :: + commit-timer=[way=wire nex=@da tim=@dr mon=term] :: + == :: ++$ pith-0 :: + $: rem=(map desk per-desk) :: + syn=(map kiln-sync let=@ud) :: + autoload-on=? :: + cur-hoon=@uvI :: + cur-arvo=@uvI :: + cur-zuse=@uvI :: + cur-vanes=(map @tas @uvI) :: + commit-timer=[way=wire nex=@da tim=@dr mon=term] :: + == ++$ per-desk :: per-desk state + $: auto=? :: escalate on failure + gem=germ :: strategy + her=@p :: from ship + sud=@tas :: from desk + cas=case :: at case + == ++$ kiln-commit term :: ++$ kiln-mount :: + $: pax=path :: + pot=term :: + == ++$ kiln-unmount $@(term [knot path]) :: ++$ kiln-sync :: + $: syd=desk :: + her=ship :: + sud=desk :: + == ++$ kiln-unsync :: + $: syd=desk :: + her=ship :: + sud=desk :: + == ++$ kiln-merge :: + $: syd=desk :: + ali=ship :: + sud=desk :: + cas=case :: + gim=?($auto germ) :: + == +-- +|= [bowl:gall state] ?> =(src our) -|_ moz/(list card:agent:gall) +|_ moz=(list card:agent:gall) ++$ state ^state :: proxy ++$ any-state ^any-state :: proxy ++ abet :: resolve - [(flop moz) `part`+<+.$] + [(flop moz) `state`+<+.$] :: ++ emit |= card:agent:gall @@ -74,9 +73,37 @@ :: ++ render |= {mez/tape sud/desk who/ship syd/desk} - :^ %palm [" " ~ ~ ~] leaf+mez + :^ %palm [" " ~ ~ ~] leaf+(weld "kiln: " mez) ~[leaf+"from {}" leaf+"on {}" leaf+"to {}"] :: +++ on-load + |= [hood-version=?(%1 %2 %3 %4 %5 %6 %7) old=any-state] + =< abet + =? . ?=(%0 -.old) + =/ recognized-ota=(unit [syd=desk her=ship sud=desk]) + =/ syncs=(list [[syd=desk her=ship sud=desk] =aeon]) + ~(tap by syn.old) + |- ^- (unit [syd=desk her=ship sud=desk]) + ?~ syncs + ~ + ?: &(=(%base syd.i.syncs) !=(our her.i.syncs) =(%kids sud.i.syncs)) + `[syd her sud]:i.syncs + $(syncs t.syncs) + :: + =. +<+.$.abet + =- old(- %1, |3 [ota=~ commit-timer.old], syn -) + ?~ recognized-ota + syn + (~(del by syn) [syd her sud]:u.recognized-ota) + :: + =? ..abet ?=(^ recognized-ota) + (poke-internal:update `[her sud]:u.recognized-ota) + +(old +<+.$.abet) + :: + ?> ?=(%1 -.old) + =. +<+.$.abet old + ..abet +:: ++ poke-commit |= [mon/kiln-commit auto=?] =< abet @@ -127,6 +154,180 @@ abet:(spam (render "already tracking" [sud her syd]:hos) ~) abet:abet:start-track:(auto hos) :: +++ update + |% + ++ make-wire + |= =path + ?> ?=(^ ota) + %- welp + :_ path + /kiln/ota/(scot %p ship.u.ota)/[desk.u.ota]/(scot %ud aeon.u.ota) + :: + ++ check-ota + |= =wire + ?~ ota + | + ?& ?=([@ @ @ *] wire) + =(i.wire (scot %p ship.u.ota)) + =(i.t.wire desk.u.ota) + =(i.t.t.wire (scot %ud aeon.u.ota)) + == + :: + ++ render + |= [mez=tape error=(unit (pair term tang))] + %+ spam + ?~ ota + leaf+mez + :^ %palm [" " ~ ~ ~] leaf+(weld "kiln: " mez) + ~[leaf+"from {}" leaf+"on {}"] + ?~ error + ~ + [>p.u.error< q.u.error] + :: + ++ render-ket + |= [mez=tape error=(unit (pair term tang))] + ?> ?=(^ ota) + =< ?>(?=(^ ota) .) + %+ spam + :^ %palm [" " ~ ~ ~] leaf+(weld "kiln: " mez) + ~[leaf+"from {}" leaf+"on {}"] + ?~ error + ~ + [>p.u.error< q.u.error] + :: + :: If destination desk doesn't exist, need a %init merge. If this is + :: its first revision, it probably doesn't have a mergebase yet, so + :: use %that. + :: + ++ get-germ + |= =desk + =+ .^(=cass:clay %cw /(scot %p our)/home/(scot %da now)) + ?- ud.cass + %0 %init + %1 %that + * %mate + == + :: + ++ poke + |= arg=(unit [=ship =desk]) + abet:(poke-internal arg) + :: + ++ poke-internal + |= arg=(unit [=ship =desk]) + ^+ ..abet + =? ..abet =(arg (bind ota |=([=ship =desk =aeon] [ship desk]))) + (render "restarting OTA sync" ~) + =? ..abet ?=(^ ota) + =. ..abet (render-ket "cancelling OTA sync" ~) + ..abet(ota ~) + ?~ arg + ..abet + =. ota `[ship.u.arg desk.u.arg *aeon] + =. ..abet (render "starting OTA sync" ~) + %: emit + %pass (make-wire /find) %arvo %c + %warp ship.u.arg desk.u.arg `[%sing %y ud+1 /] + == + :: + ++ take + |= [=wire =sign-arvo] + ^+ ..abet + ?> ?=(^ ota) + ?. (check-ota wire) + ..abet + ?. ?=([@ @ @ @ *] wire) + ..abet + ?+ i.t.t.t.wire ~&([%strange-ota-take t.t.t.wire] ..abet) + %find (take-find sign-arvo) + %sync (take-sync sign-arvo) + %download (take-download sign-arvo) + %merge-home (take-merge-home sign-arvo) + %merge-kids (take-merge-kids sign-arvo) + == + :: + ++ take-find + |= =sign-arvo + ?> ?=(%writ +<.sign-arvo) + ?> ?=(^ ota) + =. ..abet (render-ket "activated OTA" ~) + %: emit + %pass (make-wire /sync) %arvo %c + %warp ship.u.ota desk.u.ota `[%sing %w da+now /] + == + :: + ++ take-sync + |= =sign-arvo + ?> ?=(%writ +<.sign-arvo) + ?> ?=(^ ota) + ?~ p.sign-arvo + =. ..abet (render-ket "OTA cancelled (1), retrying" ~) + (poke-internal `[ship desk]:u.ota) + =. ..abet (render-ket "downloading OTA update" ~) + =? aeon.u.ota ?=($w p.p.u.p.sign-arvo) + ud:;;(cass:clay q.q.r.u.p.sign-arvo) + %: emit + %pass (make-wire /download) %arvo %c + %warp ship.u.ota desk.u.ota `[%sing %v ud+aeon.u.ota /] + == + :: + ++ take-download + |= =sign-arvo + ^+ ..abet + ?> ?=(%writ +<.sign-arvo) + ?> ?=(^ ota) + ?~ p.sign-arvo + =. ..abet (render-ket "OTA cancelled (2), retrying" ~) + (poke-internal `[ship desk]:u.ota) + =. ..abet (render-ket "finished downloading OTA" ~) + =. aeon.u.ota +(aeon.u.ota) + =/ =germ (get-germ %home) + =. ..abet (render-ket "applying OTA to %home" ~) + %- emil + :~ :* %pass (make-wire /merge-home) %arvo %c + %merg %home ship.u.ota desk.u.ota ud+(dec aeon.u.ota) germ + == + :* %pass (make-wire /sync) %arvo %c + %warp ship.u.ota desk.u.ota `[%sing %z ud+aeon.u.ota /] + == + == + :: + ++ take-merge-home + |= =sign-arvo + ?> ?=(%mere +<.sign-arvo) + ?> ?=(^ ota) + ?: ?=([%| %ali-unavailable *] p.sign-arvo) + =. ..abet + =/ =tape "OTA to %home failed, maybe because sunk; restarting" + (render-ket tape `p.p.sign-arvo) + (poke-internal `[ship desk]:u.ota) + :: + ?: ?=(%| -.p.sign-arvo) + =/ =tape "OTA to %home failed, waiting for next revision" + (render-ket tape `p.p.sign-arvo) + =. ..abet (render-ket "OTA to %home succeeded" ~) + =. ..abet (render-ket "applying OTA to %kids" ~) + =/ =germ (get-germ %kids) + %: emit + %pass (make-wire /merge-kids) %arvo %c + %merg %kids ship.u.ota desk.u.ota ud+(dec aeon.u.ota) germ + == + :: + ++ take-merge-kids + |= =sign-arvo + ?> ?=(%mere +<.sign-arvo) + ?> ?=(^ ota) + ?: ?=([%| %ali-unavailable *] p.sign-arvo) + =. ..abet + =/ =tape "OTA to %kids failed, maybe because sunk; restarting" + (render-ket tape `p.p.sign-arvo) + (poke-internal `[ship desk]:u.ota) + :: + ?- -.p.sign-arvo + %& (render-ket "OTA to %kids succeeded" ~) + %| (render-ket "OTA to %kids failed" `p.p.sign-arvo) + == + -- +:: ++ poke-sync :: |= hos/kiln-sync ?: (~(has by syn) hos) @@ -136,6 +337,10 @@ ++ poke-syncs :: print sync config |= ~ =< abet %- spam + :- :- %leaf + ?~ ota + "OTAs disabled" + "OTAs from {} on {}" ?: =(0 ~(wyt by syn)) [%leaf "no syncs configured"]~ %+ turn ~(tap in ~(key by syn)) @@ -190,127 +395,30 @@ =/ =rite [%r ~ ?:(pub %black %white) ~] [%pass /kiln/permission %arvo %c [%perm syd pax rite]] :: -++ poke-autoload |=(lod/(unit ?) abet:(poke:autoload lod)) -++ poke-start-autoload |=(~ abet:start:autoload) ++ poke |= [=mark =vase] ?+ mark ~|([%poke-kiln-bad-mark mark] !!) - %kiln-commit =;(f (f !<(_+<.f vase)) poke-commit) %kiln-autocommit =;(f (f !<(_+<.f vase)) poke-autocommit) + %kiln-cancel =;(f (f !<(_+<.f vase)) poke-cancel) + %kiln-cancel-autocommit =;(f (f !<(_+<.f vase)) poke-cancel-autocommit) + %kiln-commit =;(f (f !<(_+<.f vase)) poke-commit) + %kiln-gall-sear =;(f (f !<(_+<.f vase)) poke-gall-sear) + %kiln-goad-gall =;(f (f !<(_+<.f vase)) poke-goad-gall) %kiln-info =;(f (f !<(_+<.f vase)) poke-info) %kiln-label =;(f (f !<(_+<.f vase)) poke-label) - %kiln-cancel =;(f (f !<(_+<.f vase)) poke-cancel) + %kiln-merge =;(f (f !<(_+<.f vase)) poke-merge) %kiln-mount =;(f (f !<(_+<.f vase)) poke-mount) + %kiln-ota =;(f (f !<(_+<.f vase)) poke:update) + %kiln-permission =;(f (f !<(_+<.f vase)) poke-permission) %kiln-rm =;(f (f !<(_+<.f vase)) poke-rm) %kiln-schedule =;(f (f !<(_+<.f vase)) poke-schedule) - %kiln-track =;(f (f !<(_+<.f vase)) poke-track) %kiln-sync =;(f (f !<(_+<.f vase)) poke-sync) %kiln-syncs =;(f (f !<(_+<.f vase)) poke-syncs) - %kiln-wipe-ford =;(f (f !<(_+<.f vase)) poke-wipe-ford) - %kiln-keep-ford =;(f (f !<(_+<.f vase)) poke-keep-ford) - %kiln-autoload =;(f (f !<(_+<.f vase)) poke-autoload) - %kiln-overload =;(f (f !<(_+<.f vase)) poke-overload) - %kiln-goad-gall =;(f (f !<(_+<.f vase)) poke-goad-gall) - %kiln-gall-sear =;(f (f !<(_+<.f vase)) poke-gall-sear) - %kiln-wash-gall =;(f (f !<(_+<.f vase)) poke-wash-gall) + %kiln-track =;(f (f !<(_+<.f vase)) poke-track) %kiln-unmount =;(f (f !<(_+<.f vase)) poke-unmount) %kiln-unsync =;(f (f !<(_+<.f vase)) poke-unsync) - %kiln-permission =;(f (f !<(_+<.f vase)) poke-permission) - %kiln-cancel-autocommit =;(f (f !<(_+<.f vase)) poke-cancel-autocommit) - %kiln-start-autoload =;(f (f !<(_+<.f vase)) poke-start-autoload) - %kiln-merge =;(f (f !<(_+<.f vase)) poke-merge) == :: -++ autoload - |% - ++ emit - |= a/card:agent:gall - +>(..autoload (^emit a)) - :: - ++ tracked-vanes - ^- (list @tas) - ~[%ames %behn %clay %dill %eyre %ford %gall %iris %jael] - :: - ++ our-home /(scot %p our)/home/(scot %da now) - ++ sys-hash |=(pax/path .^(@uvI %cz :(welp our-home /sys pax))) - ++ hash-vane - |= syd/@tas ^- (pair term @uvI) - [syd (sys-hash /vane/[syd]/hoon)] - :: - ++ rehash-vanes - ^+ cur-vanes - (malt (turn tracked-vanes hash-vane)) - :: - :: - ++ poke - |= lod/(unit ?) - ?^ lod - ..autoload(autoload-on u.lod) - =. autoload-on !autoload-on - (spam leaf+"turned autoload {?:(autoload-on "on" "off")}" ~) - :: - ++ start - =. cur-hoon (sys-hash /hoon/hoon) - =. cur-arvo (sys-hash /arvo/hoon) - =. cur-zuse (sys-hash /zuse/hoon) - =. cur-vanes rehash-vanes - subscribe-next - :: - ++ subscribe-next - %- emit - [%pass /kiln/autoload %arvo %c [%warp our %home `[%next %z da+now /sys]]] - :: - ++ writ =>(check-new subscribe-next) - ++ check-new - ?. autoload-on - ..check-new - =/ new-hoon (sys-hash /hoon/hoon) - =/ new-arvo (sys-hash /arvo/hoon) - ?: |(!=(new-hoon cur-hoon) !=(new-arvo cur-arvo)) - =. cur-hoon new-hoon - =. cur-arvo new-arvo - =. cur-vanes rehash-vanes - (emit %pass /kiln/reload/hoon %agent [our %hood] %poke %helm-reset !>(~)) - :: XX updates cur-vanes? - =/ new-zuse (sys-hash /zuse/hoon) - ?: !=(new-zuse cur-zuse) - =. cur-zuse new-zuse - =. cur-vanes rehash-vanes - =/ =cage [%helm-reload !>([%zuse tracked-vanes])] - (emit [%pass /kiln/reload/zuse %agent [our %hood] %poke cage]) - (roll tracked-vanes load-vane) - :: - ++ load-vane - =< %_(. con ..load-vane) - |: $:{syd/@tas con/_.} - =. +>.$ con - =/ new-vane q:(hash-vane syd) - ?: =(`new-vane (~(get by cur-vanes) syd)) - +>.$ - =. cur-vanes (~(put by cur-vanes) syd new-vane) - =/ =cage [%helm-reload !>(~[syd])] - (emit %pass /kiln/reload/[syd] %agent [our %hood] %poke cage) - :: - ++ coup-reload - |= {way/wire saw/(unit tang)} - ~? ?=(^ saw) [%kiln-reload-lame u.saw] - +>.$ - -- -:: -++ poke-overload - :: +poke-overload: wipes ford cache at {start}, and then every {recur}. - |= [recur=@dr start=@da] - ?> (gte start now) - abet:(emit %pass /kiln/overload/(scot %dr recur) %arvo %b [%wait start]) -:: -++ poke-wipe-ford - |=(percent=@ud abet:(emit %pass /kiln %arvo %f [%wipe percent])) -:: -++ poke-keep-ford - |= [compiler-cache-size=@ud build-cache-size=@ud] - =< abet - (emit %pass /kiln %arvo %f [%keep compiler-cache-size build-cache-size]) -:: ++ poke-goad-gall |= [force=? agent=(unit dude:gall)] abet:(emit %pass /kiln %arvo %g %goad force agent) @@ -319,8 +427,6 @@ |= =ship abet:(emit %pass /kiln %arvo %g %sear ship) :: -++ poke-wash-gall |=(* abet:(emit %pass /kiln %arvo %g [%wash ~])) -:: ++ done |= {way/wire saw/(unit error:ames)} ~? ?=(^ saw) [%kiln-nack u.saw] @@ -331,33 +437,27 @@ ?+ wire ~|([%kiln-bad-take-agent wire -.sign] !!) [%kiln %fancy *] ?> ?=(%poke-ack -.sign) (take-coup-fancy t.t.wire p.sign) - [%kiln %reload *] ?> ?=(%poke-ack -.sign) - (take-coup-reload t.t.wire p.sign) [%kiln %spam *] ?> ?=(%poke-ack -.sign) (take-coup-spam t.t.wire p.sign) == :: -++ take-general +++ take-arvo |= [=wire =sign-arvo] ?- wire [%sync %merg *] %+ take-mere-sync t.t.wire ?>(?=(%mere +<.sign-arvo) +>.sign-arvo) - [%autoload *] %+ take-writ-autoload t.wire - ?>(?=(%writ +<.sign-arvo) +>.sign-arvo) [%find-ship *] %+ take-writ-find-ship t.wire ?>(?=(%writ +<.sign-arvo) +>.sign-arvo) [%sync *] %+ take-writ-sync t.wire ?>(?=(%writ +<.sign-arvo) +>.sign-arvo) - [%overload *] %+ take-wake-overload t.wire - ?>(?=(%wake +<.sign-arvo) +>.sign-arvo) [%autocommit *] %+ take-wake-autocommit t.wire ?>(?=(%wake +<.sign-arvo) +>.sign-arvo) + [%ota *] abet:(take:update t.wire sign-arvo) * - ?+ +<.sign-arvo ~|([%kiln-bad-take-card +<.sign-arvo] !!) + ?+ +<.sign-arvo + ((slog leaf+"kiln: strange card {<+<.sign-arvo wire>}" ~) abet) %done %+ done wire ?>(?=(%done +<.sign-arvo) +>.sign-arvo) - %made %+ take-made wire - ?>(?=(%made +<.sign-arvo) +>.sign-arvo) %mere %+ take-mere wire ?>(?=(%mere +<.sign-arvo) +>.sign-arvo) == @@ -367,26 +467,10 @@ |= {way/wire are/(each (set path) (pair term tang))} abet:abet:(mere:(take way) are) :: -++ take-made - |= [way=wire date=@da result=made-result:ford] - :: hack for |overload - :: - :: We might have gotten an ignorable response back for our cache priming - :: ford call. If it matches our magic wire, ignore it. - :: - ?: =(/prime/cache way) - ~& %cache-primed - abet - abet:abet:(made:(take way) date result) -:: ++ take-coup-fancy :: |= {way/wire saw/(unit tang)} abet:abet:(coup-fancy:(take way) saw) :: -++ take-coup-reload :: - |= {way/wire saw/(unit tang)} - abet:(coup-reload:autoload way saw) -:: ++ take-coup-spam :: |= {way/wire saw/(unit tang)} ~? ?=(^ saw) [%kiln-spam-lame u.saw] @@ -400,6 +484,8 @@ her=(slav %p i.t.way) sud=(slav %tas i.t.t.way) == + ?. (~(has by syn) hos) + abet abet:abet:(mere:(auto hos) mes) :: ++ take-writ-find-ship :: @@ -410,6 +496,8 @@ her=(slav %p i.t.way) sud=(slav %tas i.t.t.way) == + ?. (~(has by syn) hos) + abet abet:abet:(take-find-ship:(auto hos) rot) :: ++ take-writ-sync :: @@ -420,24 +508,9 @@ her=(slav %p i.t.way) sud=(slav %tas i.t.t.way) == - abet:abet:(writ:(auto hos) rot) -:: -++ take-writ-autoload - |= {way/wire rot/riot} - ?> ?=(~ way) - ?> ?=(^ rot) - abet:writ:autoload -:: -++ take-wake-overload - |= {way/wire error=(unit tang)} - ?^ error - %- (slog u.error) - ~& %kiln-take-wake-overload-fail + ?. (~(has by syn) hos) abet - ?> ?=({@ ~} way) - =+ tym=(slav %dr i.way) - ~& %wake-overload-deprecated - abet + abet:abet:(writ:(auto hos) rot) :: ++ take-wake-autocommit |= [way=wire error=(unit tang)] @@ -526,7 +599,7 @@ .^(cass:clay %cw /(scot %p our)/[syd]/(scot %da now)) ?: =(0 ud.cass) %init - ?:((gth 3 ud.cass) %that %mate) + ?:((gth 2 ud.cass) %that %mate) =< %- spam ?: =(our her) ~ [(render "beginning sync" sud her syd) ~] @@ -534,7 +607,7 @@ :: ++ mere |= mes=(each (set path) (pair term tang)) - ?: ?=([%| %bad-fetch-ali *] mes) + ?: ?=([%| %ali-unavailable *] mes) =. +>.$ %^ spam leaf+"merge cancelled, maybe because sunk; restarting" @@ -585,15 +658,6 @@ ~| %kiln-work-fail . :: - ++ ford-fail - |=(tan/tang ~|(%ford-fail (mean tan))) - :: - ++ unwrap-tang - |* res/(each * tang) - ?: ?=(%& -.res) - p.res - (ford-fail p.res) - :: ++ perform :: ^+ . (blab [%pass /kiln/[syd] %arvo %c [%merg syd her sud cas gem]] ~) @@ -621,10 +685,7 @@ ++ coup-fancy |= saw/(unit tang) ?~ saw - => (spam leaf+"%melding %{(trip sud)} into scratch space" ~) - %- blab :_ ~ - =/ note [%merg (cat 3 syd '-scratch') her sud cas gem] - [%pass /kiln/[syd] %arvo %c note] + +> =+ :- "failed to set up conflict resolution scratch space" "I'm out of ideas" lose:(spam leaf+-< leaf+-> u.saw) @@ -638,35 +699,60 @@ =+ "merged with strategy {}" win:(spam leaf+- ?~(p.are ~ [>`(set path)`p.are< ~])) :: ~? > =(~ p.are) [%mere-no-conflict syd] - =+ "mashing conflicts" - => .(+>.$ (spam leaf+- ~)) + => .(+>.$ (spam leaf+"mashing conflicts" ~)) =+ tic=(cat 3 syd '-scratch') - %- blab :_ ~ - =, ford - :* %pass /kiln/[syd] %arvo %f - :* %build live=%.n - ^- schematic - :- %list - ^- (list schematic) - :: ~& > kiln-mashing+[p.are syd=syd +<.abet] - %+ turn ~(tap in p.are) - |= pax/path - ^- [schematic schematic] - :- [%$ %path -:!>(*path) pax] - =/ base=schematic [%scry %c %x `rail`[[our tic] (flop pax)]] - ?> ?=([%da @] cas) - =/ alis=schematic - [%pin p.cas `schematic`[%scry %c %x [[our syd] (flop pax)]]] - =/ bobs=schematic - [%scry %c %x [[our syd] (flop pax)]] - =/ dali=schematic [%diff [our syd] base alis] - =/ dbob=schematic [%diff [our syd] base bobs] - =/ for=mark - =+ (slag (dec (lent pax)) pax) - ?~(- %$ i.-) - ^- schematic - [%mash [our tic] for [[her sud] for dali] [[our syd] for dbob]] - == == + =/ notations=(list [path (unit [mark vase])]) + %+ turn ~(tap in p.are) + |= =path + =/ =mark -:(flop path) + =/ =dais .^(dais %cb /(scot %p our)/[syd]/(scot cas)/[mark]) + =/ base .^(vase %cr (weld /(scot %p our)/[tic]/(scot cas) path)) + =/ ali .^(vase %cr (weld /(scot %p her)/[sud]/(scot cas) path)) + =/ bob .^(vase %cr (weld /(scot %p our)/[syd]/(scot cas) path)) + =/ ali-dif (~(diff dais base) ali) + =/ bob-dif (~(diff dais base) bob) + =/ mash (~(mash dais base) [her sud ali-dif] [our syd bob-dif]) + :- path + ?~ mash + ~ + `[mark (~(pact dais base) u.mash)] + =/ [annotated=(list [path *]) unnotated=(list [path *])] + (skid notations |=([* v=*] ?=(^ v))) + =/ tic=desk (cat 3 syd '-scratch') + =/ tan=(list tank) + %- zing + ^- (list (list tank)) + :~ %- tape-to-tanks + """ + done setting up scratch space in {<[tic]>} + please resolve the following conflicts and run + |merge {} our {<[tic]>} + """ + %^ tanks-if-any + "annotated conflicts in:" (turn annotated head) + "" + %^ tanks-if-any + "unannotated conflicts in:" (turn unnotated head) + """ + some conflicts could not be annotated. + for these, the scratch space contains + the most recent common ancestor of the + conflicting content. + """ + == + =< win + %- blab:(spam tan) + :_ ~ + :* %pass /kiln/[syd] %arvo %c + %info + tic %& + %+ murn notations + |= [=path dif=(unit [=mark =vase])] + ^- (unit [^path miso]) + ?~ dif + ~ + `[path %mut mark.u.dif vase.u.dif] + == =+ "failed to merge with strategy meld" lose:(spam leaf+- >p.p.are< q.p.are) ?: ?=(%& -.are) @@ -706,7 +792,11 @@ => =+ :- "%mate merge failed with conflicts," "setting up scratch space at %{(trip tic)}" [tic=tic (spam leaf+-< leaf+-> q.p.are)] - (fancy-merge tic our syd %init) + =. ..mere (fancy-merge tic our syd %init) + => (spam leaf+"%melding %{(trip sud)} into scratch space" ~) + %- blab :_ ~ + =/ note [%merg (cat 3 syd '-scratch') her sud cas gem] + [%pass /kiln/[syd] %arvo %c note] == :: ++ tape-to-tanks @@ -717,68 +807,5 @@ |= {a/tape b/(list path) c/tape} ^- (list tank) ?: =(~ b) ~ (welp (tape-to-tanks "\0a{c}{a}") >b< ~) - :: - ++ made - |= [date=@da result=made-result:ford] - :: |= {dep/@uvH reg/gage:ford} - ^+ +> - :: - ?: ?=([%incomplete *] result) - =+ "failed to mash" - lose:(spam leaf+- tang.result) - ?: ?=([%complete %error *] result) - =+ "failed to mash" - lose:(spam leaf+- message.build-result.result) - ?> ?=([%complete %success %list *] result) - =/ can=(list (pair path (unit miso))) - %+ turn results.build-result.result - |= res=build-result:ford - ^- (pair path (unit miso)) - ?> ?=([%success ^ *] res) - ~! res - =+ pax=(result-to-cage:ford head.res) - =+ dif=(result-to-cage:ford tail.res) - :: - ?. ?=($path p.pax) - ~| "strange path mark: {}" - !! - [;;(path q.q.pax) ?:(?=($null p.dif) ~ `[%dif dif])] - :: ~& > kiln-made+[(turn can head) syd=syd +<.abet] - =+ notated=(skid can |=({path a/(unit miso)} ?=(^ a))) - =+ annotated=(turn `(list (pair path *))`-.notated head) - =+ unnotated=(turn `(list (pair path *))`+.notated head) - =+ `desk`(cat 3 syd '-scratch') - =/ tan=(list tank) - %- zing - ^- (list (list tank)) - :~ %- tape-to-tanks - """ - done setting up scratch space in {<[-]>} - please resolve the following conflicts and run - |merge {} our {<[-]>} - """ - %^ tanks-if-any - "annotated conflicts in:" annotated - "" - %^ tanks-if-any - "unannotated conflicts in:" unnotated - """ - some conflicts could not be annotated. - for these, the scratch space contains - the most recent common ancestor of the - conflicting content. - - """ - == - =< win - %- blab:(spam tan) - :_ ~ - :* %pass /kiln/[syd] %arvo %c - :* %info - (cat 3 syd '-scratch') %& - %+ murn can - |= {p/path q/(unit miso)} - `(unit (pair path miso))`?~(q ~ `[p u.q]) - == == -- -- diff --git a/pkg/arvo/lib/hood/write.hoon b/pkg/arvo/lib/hood/write.hoon deleted file mode 100644 index b958711ffb..0000000000 --- a/pkg/arvo/lib/hood/write.hoon +++ /dev/null @@ -1,143 +0,0 @@ -:: File writer module -:: -:::: /hoon/write/hood/lib - :: -/? 310 -=, format -=* as-octs as-octs:mimes:html -=, space:userlib -|% -+$ part {$write $0 pith} :: no state -+$ pith ~ --- -:: -:::: - :: -|% -++ data $%({$json json} {$mime mime}) --- -:: -:::: - :: -|= {bowl:gall part} -=* par +<+ -|_ moz/(list card:agent:gall) -++ abet [(flop moz) `part`par] -++ emit - |= =card:agent:gall - %_(+> moz :_(moz card)) -:: -++ beak-now byk(r [%da now]) -++ poke-wipe - |= sup/path ^+ abet :: XX determine extension, beak - =+ ext=%md - ?~ (file (en-beam beak-now [ext sup])) - ~|(not-found+[ext `path`(flop sup)] !!) - =- abet:(emit %pass /write %arvo %c %info -) - (fray (en-beam beak-now [ext sup])) -:: -++ poke-tree - |= {sup/path mim/mime} ^+ abet :: XX determine extension, beak - (poke--data [`%md (flop sup)] %mime mim) -:: -++ poke-paste - |= {typ/?($hoon $md $txt) txt/@t} ^+ abet - (poke--data [`typ /web/paste/(scot %da now)] %mime / (as-octs txt)) -:: -++ poke-comment - |= {sup/path him/ship txt/@t} ^+ abet - =+ pax=(welp (flop sup) /comments/(scot %da now)) - =. txt - %+ rap 3 :~ - '## `' (scot %p him) '`' - '\0a' txt - == - (poke--data [`%md pax] %mime / (as-octs txt)) -:: -++ poke-fora-post - |= {sup/path him/ship hed/@t txt/@t} ^+ abet - =+ pax=(welp (flop sup) /posts/(cat 3 (scot %da now) '~')) - =. txt - %- crip - """ - --- - type: post - date: {} - title: {(trip hed)} - author: {} - navsort: bump - navuptwo: true - comments: reverse - --- - - {(trip txt)} - """ - (poke--data [`%md pax] %mime / (as-octs txt)) -:: -++ ames-secret - ^- @t - =- (crip +:<.^(@p %j pax)>) - pax=/(scot %p our)/code/(scot %da now)/(scot %p our) -:: -++ poke-sec-atom - |= {hot/host:eyre dat/@} - ?> ?=(%& -.hot) - =. p.hot (scag 2 p.hot) :: ignore subdomain - =. dat (scot %uw (en:crub:crypto ames-secret dat)) - (poke--data [`%atom [%sec p.hot]] %mime / (as-octs dat)) -:: -++ poke--data - |= {{ext/(unit @t) pax/path} dat/data} ^+ abet - ?~ ext $(ext [~ -.dat]) - =+ cay=?-(-.dat $json [-.dat !>(+.dat)], $mime [-.dat !>(+.dat)]) - ?: =(u.ext -.dat) - (made pax now [%complete %success %$ cay]) - =< abet - %- emit :* - %pass write+pax %arvo %f - %build - live=%.n :: XX defer %nice - ^- schematic:ford :: SYNTAX ERROR AT START OF LINE? - =/ =beak beak-now - [%cast [p q]:beak u.ext [%$ cay]] - == -:: -++ poke - |= [=mark =vase] - ?+ mark ~|([%poke-write-bad-mark mark] !!) - %write-sec-atom =;(f (f !<(_+<.f vase)) poke-sec-atom) - %write-paste =;(f (f !<(_+<.f vase)) poke-paste) - %write-tree =;(f (f !<(_+<.f vase)) poke-tree) - %write-wipe =;(f (f !<(_+<.f vase)) poke-wipe) - == -:: -++ made - |= [pax=wire date=@da result=made-result:ford] - ^+ abet - :: |= {pax/wire @ res/gage:ford} ^+ abet - :: ?. =(our src) - :: ~|(foreign-write/[our=our src=src] !!) - ?: ?=(%incomplete -.result) - (mean tang.result) - :: - =/ build-result build-result.result - :: - ?: ?=([%error *] build-result) - (mean message.build-result) - :: - =/ =cage (result-to-cage:ford build-result) - :: - =- abet:(emit %pass /write %arvo %c %info -) - :: - (foal :(welp (en-beam beak-now ~) pax /[-.cage]) cage) -:: -++ take :: - |= [=wire =sign-arvo] - %+ made wire - ?> ?=(%made +<.sign-arvo) - +>.sign-arvo -:: -++ take-agent - |= [=wire =sign:agent:gall] - ~|([%write-bad-take-agent wire -.sign] !!) --- diff --git a/pkg/arvo/lib/language-server/complete.hoon b/pkg/arvo/lib/language-server/complete.hoon index 42f1f419d3..b42b65448d 100644 --- a/pkg/arvo/lib/language-server/complete.hoon +++ b/pkg/arvo/lib/language-server/complete.hoon @@ -248,15 +248,15 @@ :: ++ get-id |= [pos=@ud txt=tape] - ^- [forward=(unit term) backward=(unit term) id=(unit term)] - =/ forward=(unit term) - %+ scan `tape`(slag pos txt) - ;~(sfix (punt sym) (star ;~(pose prn (just `@`10)))) - =/ backward=(unit term) + ^- [forward=(unit @t) backward=(unit @t) id=(unit @t)] + =/ seek + ;~(sfix (punt (cook crip (star prn))) (star ;~(pose prn (just `@`10)))) + =/ forward=(unit @t) + (scan (slag pos txt) seek) + =/ backward=(unit @t) %- (lift |=(t=@tas (swp 3 t))) - %+ scan `tape`(flop (scag pos txt)) - ;~(sfix (punt sym) (star ;~(pose prn (just `@`10)))) - =/ id=(unit term) + (scan (flop (scag pos txt)) seek) + =/ id=(unit @t) ?~ forward ?~ backward ~ @@ -338,13 +338,13 @@ ~? > debug %start-magick =/ magicked txt:(insert-magic pos code) ~? > debug %start-parsing - =/ res (lily magicked (language-server-parser *beam)) + =/ res (lily magicked (language-server-parser *path)) ?: ?=(%| -.res) ~? > debug [%parsing-error p.res] [%| p.res] :- %& ~? > debug %parsed-good - ((cury tab-list-hoon sut) tssg+sources.p.res) + ((cury tab-list-hoon sut) hoon.p.res) :: :: Generators ++ tab-generators diff --git a/pkg/arvo/lib/language-server/parser.hoon b/pkg/arvo/lib/language-server/parser.hoon index 57d3b21a1c..4564c22f0d 100644 --- a/pkg/arvo/lib/language-server/parser.hoon +++ b/pkg/arvo/lib/language-server/parser.hoon @@ -1,204 +1,85 @@ :: lifted directly from ford, should probably be in zuse -=< parse-scaffold -=, ford +=, clay +=< pile-rule |% -++ parse-scaffold - |= src-beam=beam - :: - =/ hoon-parser (vang & (en-beam:format src-beam)) - |^ :: - %+ cook - |= a=[@ud (list ^cable) (list ^cable) (list ^crane) (list hoon)] - ^- scaffold - [[[p q] s]:src-beam a] - :: - %+ ifix [gay gay] - ;~ plug - :: parses the zuse version, eg "/? 309" - :: - ;~ pose - (ifix [;~(plug net wut gap) gap] dem) - (easy zuse) - == - :: pareses the structures, eg "/- types" - :: - ;~ pose - (ifix [;~(plug net hep gap) gap] (most ;~(plug com gaw) cable)) - (easy ~) - == - :: parses the libraries, eg "/+ lib1, lib2" - :: - ;~ pose - (ifix [;~(plug net lus gap) gap] (most ;~(plug com gaw) cable)) - (easy ~) - == - :: - (star ;~(sfix crane gap)) - :: - (most gap tall:hoon-parser) - == - :: +beam: parses a hood path and converts it to a beam - :: - ++ beam - %+ sear de-beam:format - ;~ pfix - net - (sear plex (stag %clsg poor)):hoon-parser - == - :: +cable: parses a +^cable, a reference to something on the filesystem - :: - :: This parses: - :: - :: `library` -> wraps `library` around the library `library` - :: `face=library` -> wraps `face` around the library `library` - :: `*library` -> exposes `library` directly to the subject - :: - ++ cable - %+ cook |=(a=^cable a) +++ pile-rule + |= pax=path + %- full + %+ ifix [gay gay] + %+ cook |=(pile +<) + ;~ pfix + :: parse optional /? and ignore + :: ;~ pose - (stag ~ ;~(pfix tar sym)) - (cook |=([face=term tis=@ file=term] [`face file]) ;~(plug sym tis sym)) - (cook |=(a=term [`a a]) sym) + (cold ~ ;~(plug net wut gap dem gap)) + (easy ~) == - :: +crane: all runes that start with / which aren't /?, /-, /+ or //. :: - ++ crane - =< apex - :: whether we allow tall form - =| allow-tall-form=? - :: - |% - ++ apex - %+ knee *^crane |. ~+ - ;~ pfix net - ;~ pose - :: `/~` hoon literal - :: - (stag %fssg ;~(pfix sig hoon)) - :: `/$` process query string - :: - (stag %fsbc ;~(pfix bus hoon)) - :: `/|` first of many options that succeeds - :: - (stag %fsbr ;~(pfix bar parse-alts)) - :: `/=` wrap a face around a crane - :: - (stag %fsts ;~(pfix tis parse-face)) - :: `/.` null terminated list - :: - (stag %fsdt ;~(pfix dot parse-list)) - :: `/,` switch by path - :: - (stag %fscm ;~(pfix com parse-switch)) - :: `/&` pass through a series of mark - :: - (stag %fspm ;~(pfix pad parse-pipe)) - :: `/_` run a crane on each file in the current directory - :: - (stag %fscb ;~(pfix cab subcrane)) - :: `/;` passes date through a gate - :: - (stag %fssm ;~(pfix mic parse-gate)) - :: `/:` evaluate at path - :: - (stag %fscl ;~(pfix col parse-at-path)) - :: `/^` cast - :: - (stag %fskt ;~(pfix ket parse-cast)) - :: `/*` run a crane on each file with current path as prefix - :: - (stag %fstr ;~(pfix tar subcrane)) - :: `/!mark/ evaluate as hoon, then pass through mark - :: - (stag %fszp ;~(pfix zap ;~(sfix sym net))) - :: `/mark/` passes current path through :mark - :: - (stag %fszy ;~(sfix sym net)) + ;~ plug + ;~ pose + ;~ sfix + %+ cook |=((list (list taut)) (zing +<)) + %+ more gap + ;~ pfix ;~(plug net hep gap) + (most ;~(plug com gaw) taut-rule) + == + gap == + (easy ~) == - :: +parse-alts: parse a set of alternatives :: - ++ parse-alts - %+ wide-or-tall - (ifix [lit rit] (most ace subcrane)) - ;~(sfix (star subcrane) gap duz) - :: +parse-face: parse a face around a subcrane - :: - ++ parse-face - %+ wide-or-tall - ;~(plug sym ;~(pfix tis subcrane)) - ;~(pfix gap ;~(plug sym subcrane)) - :: +parse-list: parse a null terminated list of cranes - :: - ++ parse-list - %+ wide-or-tall - fail - ;~(sfix (star subcrane) gap duz) - :: +parse-switch: parses a list of [path crane] - :: - ++ parse-switch - %+ wide-or-tall - fail - =- ;~(sfix (star -) gap duz) - ;~(pfix gap net ;~(plug static-path subcrane)) - :: +parse-pipe: parses a pipe of mark conversions - :: - ++ parse-pipe - %+ wide-or-tall - ;~(plug (plus ;~(sfix sym pad)) subcrane) - =+ (cook |=(a=term [a ~]) sym) - ;~(pfix gap ;~(plug - subcrane)) - :: +parse-gate: parses a gate applied to a crane - :: - ++ parse-gate - %+ wide-or-tall - ;~(plug ;~(sfix wide:hoon-parser mic) subcrane) - ;~(pfix gap ;~(plug tall:hoon-parser subcrane)) - :: +parse-at-path: parses a late bound bath - :: - ++ parse-at-path - %+ wide-or-tall - ;~(plug ;~(sfix late-bound-path col) subcrane) - ;~(pfix gap ;~(plug late-bound-path subcrane)) - :: +parse-cast: parses a mold and then the subcrane to apply that mold to - :: - ++ parse-cast - %+ wide-or-tall - ;~(plug ;~(sfix wyde:hoon-parser ket) subcrane) - ;~(pfix gap ;~(plug till:hoon-parser subcrane)) - :: +subcrane: parses a subcrane - :: - ++ subcrane - %+ wide-or-tall - apex(allow-tall-form |) - ;~(pfix gap apex) - :: +wide-or-tall: parses tall form hoon if :allow-tall-form is %.y - :: - ++ wide-or-tall - |* [wide=rule tall=rule] - ?. allow-tall-form wide - ;~(pose wide tall) - :: +hoon: parses hoon as an argument to a crane - :: - ++ hoon - %+ wide-or-tall - (ifix [lac rac] (stag %cltr (most ace wide:hoon-parser))) - ;~(pfix gap tall:hoon-parser) - -- - :: +static-path: parses a path - :: - ++ static-path - (sear plex (stag %clsg (more net hasp))):hoon-parser - :: +late-bound-path: a path whose time varies - :: - ++ late-bound-path - ;~ pfix net - %+ cook |=(a=truss a) - => hoon-parser - ;~ plug - (stag ~ gash) - ;~(pose (stag ~ ;~(pfix cen porc)) (easy ~)) + ;~ pose + ;~ sfix + %+ cook |=((list (list taut)) (zing +<)) + %+ more gap + ;~ pfix ;~(plug net lus gap) + (most ;~(plug com gaw) taut-rule) + == + gap + == + (easy ~) == + :: + ;~ pose + ;~ sfix + %+ cook |=((list [face=term =path]) +<) + %+ more gap + ;~ pfix ;~(plug net tis gap) + %+ cook |=([term path] +<) + ;~(plug sym ;~(pfix ;~(plug gap net) (more net urs:ab))) + == + gap + == + (easy ~) + == + :: + ;~ pose + ;~ sfix + %+ cook |=((list [face=term =mark =path]) +<) + %+ more gap + ;~ pfix ;~(plug net tar gap) + %+ cook |=([term mark path] +<) + ;~ plug + sym + ;~(pfix ;~(plug gap cen) sym) + ;~(pfix ;~(plug gap net) (more net urs:ab)) + == + == + gap + == + (easy ~) + == + :: + %+ cook |=(huz=(list hoon) `hoon`tssg+huz) + (most gap tall:(vang & pax)) == - -- + == +:: +++ taut-rule + %+ cook |=(taut +<) + ;~ pose + (stag ~ ;~(pfix tar sym)) + ;~(plug (stag ~ sym) ;~(pfix tis sym)) + (cook |=(a=term [`a a]) sym) + == -- diff --git a/pkg/arvo/lib/link.hoon b/pkg/arvo/lib/link-store.hoon similarity index 98% rename from pkg/arvo/lib/link.hoon rename to pkg/arvo/lib/link-store.hoon index 599e0f077c..494fa8c8f4 100644 --- a/pkg/arvo/lib/link.hoon +++ b/pkg/arvo/lib/link-store.hoon @@ -1,7 +1,10 @@ :: link: social bookmarking :: -/- *link +/- sur=link-store, *link :: +^? +=< [. sur] +=, sur |% ++ site-from-url |= =url @@ -92,8 +95,9 @@ [a b] -- :: -++ en-json +++ enjs =, enjs:format + ^? |% ++ update |= upd=^update @@ -166,8 +170,9 @@ == -- :: -++ de-json +++ dejs =, dejs:format + ^? |% :: +action: json into action :: diff --git a/pkg/arvo/lib/ph/io.hoon b/pkg/arvo/lib/ph/io.hoon index 3f750c7b0a..58400579d8 100644 --- a/pkg/arvo/lib/ph/io.hoon +++ b/pkg/arvo/lib/ph/io.hoon @@ -46,7 +46,11 @@ :: probably the best option because the thread can delay until it :: gets a positive ack on the subscription. :: - ;< ~ bind:m (sleep ~s0) + :: Threads might not get built until a %writ is dripped back to + :: spider. Drips are at +(now), so we sleep until two clicks in the + :: future. + :: + ;< ~ bind:m (sleep `@dr`2) (pure:m ~) :: ++ end-test @@ -150,7 +154,7 @@ :: hit the first of these cases, and other ships will hit the :: second. :: - ?: ?| (f "clay: committed initial filesystem (all)") + ?: ?| (f ":dojo>") (f "is your neighbor") == (pure:m ~) @@ -212,13 +216,18 @@ |= [her=ship =desk extra=@t] =/ m (strand ,@t) ^- form:m + (touch her desk /sur/aquarium/hoon extra) +:: +:: Modify path on the given ship +:: +++ touch + |= [her=ship =desk pax=path extra=@t] + =/ m (strand ,@t) + ^- form:m ~& > "touching file on {}/{}" ;< ~ bind:m (mount her desk) ;< our=@p bind:m get-our ;< now=@da bind:m get-time - =/ host-pax - /(scot %p our)/home/(scot %da now)/sur/aquarium/hoon - =/ pax /sur/aquarium/hoon =/ aqua-pax ;: weld /i/(scot %p her)/cx/(scot %p her)/[desk]/(scot %da now) @@ -229,7 +238,7 @@ %^ cat 3 '=> . ' %^ cat 3 extra (need (scry-aqua:util (unit @) our now aqua-pax)) - ;< ~ bind:m (send-events (insert-file:util her desk host-pax warped)) + ;< ~ bind:m (send-events (insert-files:util her desk [pax warped] ~)) (pure:m warped) :: :: Check /sur/aquarium/hoon on the given has the given contents. @@ -237,6 +246,13 @@ ++ check-file-touched |= [=ship =desk warped=@t] =/ m (strand ,~) + (check-touched ship desk /sur/aquarium/hoon warped) +:: +:: Check path on the given desk has the given contents. +:: +++ check-touched + |= [=ship =desk pax=path warped=@t] + =/ m (strand ,~) ~& > "checking file touched on {}/{}" ;< ~ bind:m (mount ship desk) ^- form:m @@ -250,7 +266,6 @@ :: ?. &(=(ship her) ?=(?(%init %ergo %doze) -.q.unix-effect)) loop - =/ pax /sur/aquarium/hoon =/ aqua-pax ;: weld /i/(scot %p ship)/cx/(scot %p ship)/[desk]/(scot %da now) diff --git a/pkg/arvo/lib/ph/util.hoon b/pkg/arvo/lib/ph/util.hoon index 51a51344c8..c9bd6dc63e 100644 --- a/pkg/arvo/lib/ph/util.hoon +++ b/pkg/arvo/lib/ph/util.hoon @@ -45,14 +45,16 @@ :: :: Inject a file into a ship :: -++ insert-file - |= [who=ship des=desk pax=path txt=@t] +++ insert-files + |= [who=ship des=desk files=(list [=path txt=@t])] ^- (list aqua-event) - ?> ?=([@ @ @ *] pax) - =/ file [/text/plain (as-octs:mimes:html txt)] + =/ input + %+ turn files + |= [=path txt=@t] + [path ~ /text/plain (as-octs:mimes:html txt)] %+ send-events-to who :~ - [//sync/0v1n.2m9vh %into des | [t.t.t.pax `file]~] + [//sync/0v1n.2m9vh %into des | input] == :: :: Checks whether the given event is a dojo output blit containing the diff --git a/pkg/arvo/lib/pill.hoon b/pkg/arvo/lib/pill.hoon index ee77daaedc..06493edc8c 100644 --- a/pkg/arvo/lib/pill.hoon +++ b/pkg/arvo/lib/pill.hoon @@ -2,12 +2,12 @@ :: ^? |% -:: +module-ova: vane load operations. -:: -:: sys: full path to /sys directory :: +$ pill - [boot-ova=* kernel-ova=(list unix-event) userspace-ova=(list unix-event)] + $: boot-ova=* + kernel-ova=(list unix-event) + userspace-ova=(list unix-event) + == :: +$ unix-event %+ pair wire @@ -16,42 +16,24 @@ [%boot ? $%($>(%fake task:able:jael) $>(%dawn task:able:jael))] unix-task == +:: +module-ova: vane load operations +:: +:: sys: full path to /sys directory :: ++ module-ova |= sys=path ^- (list [wire [%veer term path cord]]) %+ turn ^- (list (pair term path)) - :~ :: sys/zuse: standard library - :: - [%$ /zuse] - :: sys/vane/ames: network - :: - [%a /vane/ames] - :: sys/vane/behn: timer - :: - [%b /vane/behn] - :: sys/vane/clay: revision control - :: - [%c /vane/clay] - :: sys/vane/dill: console - :: - [%d /vane/dill] - :: sys/vane/eyre: http server - :: - [%e /vane/eyre] - :: sys/vane/ford: build - :: - [%f /vane/ford] - :: sys/vane/gall: applications - :: - [%g /vane/gall] - :: sys/vane/iris: http client - :: - [%i /vane/iris] - :: sys/vane/kale: security - :: - [%j /vane/jael] + :~ [%$ /zuse] :: standard library + [%a /vane/ames] :: network + [%b /vane/behn] :: timer + [%c /vane/clay] :: revision control + [%d /vane/dill] :: console + [%e /vane/eyre] :: http server + [%g /vane/gall] :: applications + [%i /vane/iris] :: http client + [%j /vane/jael] :: identity and security == |= [=term =path] =/ pax (weld sys path) @@ -59,25 +41,22 @@ [[%vane path] [%veer term pax txt]] :: +file-ovum: userspace filesystem load :: -:: bas: full path to / directory +:: bas: full path to / directory :: ++ file-ovum - =/ directories - `(list path)`~[/app /ted /gen /lib /mar /ren /sec /sur /sys /tests /web] + =/ directories=(list path) + :~ /app :: %gall applications + /gen :: :dojo generators + /lib :: libraries + /mar :: mark definitions + /sur :: structures + /sys :: system files + /ted :: :spider strands + /tests :: unit tests + /web :: %eyre web content + == |= bas=path ^- unix-event - :: - :: /app %gall applications - :: /gen :dojo generators - :: /lib %ford libraries - :: /mar %ford marks - :: /ren %ford renderers - :: /sec %eyre security drivers - :: /sur %ford structures - :: /sys system files - :: /tests unit tests - :: /web %eyre web content - :: %. directories |= :: sal: all spurs to load from :: diff --git a/pkg/arvo/lib/shoe.hoon b/pkg/arvo/lib/shoe.hoon index 3727c4624b..2bffc2f7a7 100644 --- a/pkg/arvo/lib/shoe.hoon +++ b/pkg/arvo/lib/shoe.hoon @@ -35,14 +35,20 @@ |* command-type=mold $_ ^| |_ bowl:gall + :: +command-parser: input parser for a specific session + :: + :: if the head of the result is true, instantly run the command + :: ++ command-parser |~ sole-id=@ta - |~(nail *(like command-type)) + |~(nail *(like [? command-type])) + :: +tab-list: autocomplete options for the session (to match +command-parser) :: ++ tab-list |~ sole-id=@ta :: (list [@t tank]) *(list (option:auto tank)) + :: +on-command: called when a valid command is run :: ++ on-command |~ [sole-id=@ta command=command-type] @@ -106,9 +112,11 @@ |* [shoe=* command-type=mold] |_ =bowl:gall ++ command-parser - (easy *command-type) + |= sole-id=@ta + (easy *[? command-type]) :: ++ tab-list + |= sole-id=@ta ~ :: ++ on-command @@ -193,9 +201,9 @@ (~(gut by soles) sole-id *sole-share) |^ =^ [cards=(list card) =_cli-state] shoe ?- -.dat.act - %det [(apply-edit +.dat.act) shoe] + %det (apply-edit +.dat.act) %clr [[~ cli-state] shoe] - %ret run-command + %ret try-command %tab [(tab +.dat.act) shoe] == :- (deal cards) @@ -208,15 +216,19 @@ :: ++ apply-edit |= =sole-change - ^- (quip card _cli-state) + ^+ [[*(list card) cli-state] shoe] =^ inverse cli-state (~(transceive sole cli-state) sole-change) :: res: & for fully parsed, | for parsing failure at location :: - =/ res=(each (unit) @ud) + =/ res=(each (unit [run=? cmd=command-type]) @ud) %+ rose (tufa buf.cli-state) (command-parser:og sole-id) - ?: ?=(%& -.res) [~ cli-state] + ?: ?=(%& -.res) + ?. &(?=(^ p.res) run.u.p.res) + [[~ cli-state] shoe] + (run-command cmd.u.p.res) + :_ shoe :: parsing failed :: ?. &(?=(%del -.inverse) =(+(p.inverse) (lent buf.cli-state))) @@ -234,14 +246,18 @@ [%err p.res] :: cursor to error location == :: - ++ run-command + ++ try-command ^+ [[*(list card) cli-state] shoe] - =/ cmd=(unit command-type) + =/ res=(unit [? cmd=command-type]) %+ rust (tufa buf.cli-state) (command-parser:og sole-id) - ?~ cmd - [[[(effect %bel ~)]~ cli-state] shoe] - =^ cards shoe (on-command:og sole-id u.cmd) + ?^ res (run-command cmd.u.res) + [[[(effect %bel ~)]~ cli-state] shoe] + :: + ++ run-command + |= cmd=command-type + ^+ [[*(list card) cli-state] shoe] + =^ cards shoe (on-command:og sole-id cmd) :: clear buffer :: =^ clear cli-state (~(transmit sole cli-state) [%set ~]) @@ -251,7 +267,6 @@ [%det clear] == :: - ::NOTE cargo-culted ++ tab |= pos=@ud ^- (quip card _cli-state) @@ -271,7 +286,9 @@ %+ add pos (met 3 (fall forward '')) =| cards=(list card) - =? cards ?=(^ options) + :: only render the option list if we couldn't complete anything + :: + =? cards &(?=(~ to-send) ?=(^ options)) [(effect %tab options) cards] |- ^- (quip card _cli-state) ?~ to-send diff --git a/pkg/arvo/lib/strandio.hoon b/pkg/arvo/lib/strandio.hoon index 6493111543..db9db877e3 100644 --- a/pkg/arvo/lib/strandio.hoon +++ b/pkg/arvo/lib/strandio.hoon @@ -26,6 +26,12 @@ |= tin=strand-input:strand `[%done bowl.tin] :: +++ get-beak + =/ m (strand ,beak) + ^- form:m + |= tin=strand-input:strand + `[%done [our q.byk da+now]:bowl.tin] +:: ++ get-time =/ m (strand ,@da) ^- form:m @@ -380,6 +386,93 @@ ;< ~ bind:m (send-request (hiss-to-request:html hiss)) take-maybe-sigh :: +:: +build-fail: build the source file at the specified $beam +:: +++ build-file + |= [[=ship =desk =case] =spur] + =* arg +< + =/ m (strand ,vase) + ^- form:m + ;< =riot:clay bind:m + (warp ship desk ~ %sing %a case (flop spur)) + ?~ riot + (strand-fail %build-file >arg< ~) + ?> =(%vase p.r.u.riot) + (pure:m !<(vase q.r.u.riot)) +:: +build-mark: build a mark definition to a $dais +:: +++ build-mark + |= [[=ship =desk =case] mak=mark] + =* arg +< + =/ m (strand ,dais:clay) + ^- form:m + ;< =riot:clay bind:m + (warp ship desk ~ %sing %b case /[mak]) + ?~ riot + (strand-fail %build-mark >arg< ~) + ?> =(%dais p.r.u.riot) + (pure:m !<(dais:clay q.r.u.riot)) +:: +build-cast: build a mark conversion gate ($tube) +:: +++ build-cast + |= [[=ship =desk =case] =mars:clay] + =* arg +< + =/ m (strand ,tube:clay) + ^- form:m + ;< =riot:clay bind:m + (warp ship desk ~ %sing %c case /[a.mars]/[b.mars]) + ?~ riot + (strand-fail %build-cast >arg< ~) + ?> =(%tube p.r.u.riot) + (pure:m !<(tube:clay q.r.u.riot)) +:: +:: Read from Clay +:: +++ warp + |= [=ship =riff:clay] + =/ m (strand ,riot:clay) + ;< ~ bind:m (send-raw-card %pass /warp %arvo %c %warp ship riff) + (take-writ /warp) +:: +++ read-file + |= [[=ship =desk =case:clay] =spur] + =* arg +< + =/ m (strand ,cage) + ;< =riot:clay bind:m (warp ship desk ~ %sing %x case (flop spur)) + ?~ riot + (strand-fail %read-file >arg< ~) + (pure:m r.u.riot) +:: +++ check-for-file + |= [[=ship =desk =case:clay] =spur] + =/ m (strand ,?) + ;< =riot:clay bind:m (warp ship desk ~ %sing %x case (flop spur)) + (pure:m ?=(^ riot)) +:: +++ list-tree + |= [[=ship =desk =case:clay] =spur] + =* arg +< + =/ m (strand ,(list path)) + ;< =riot:clay bind:m (warp ship desk ~ %sing %t case (flop spur)) + ?~ riot + (strand-fail %list-tree >arg< ~) + (pure:m !<((list path) q.r.u.riot)) +:: +:: Take Clay read result +:: +++ take-writ + |= =wire + =/ m (strand ,riot:clay) + ^- form:m + |= tin=strand-input:strand + ?+ in.tin `[%skip ~] + ~ `[%wait ~] + [~ %sign * ?(%b %c) %writ *] + ?. =(wire wire.u.in.tin) + `[%skip ~] + `[%done +>.sign-arvo.u.in.tin] + == +:: :: Queue on skip, try next on fail %ignore :: ++ main-loop @@ -487,6 +580,12 @@ ;< ~ bind:m (flog-text i.wall) loop(wall t.wall) :: +++ trace + |= =tang + =/ m (strand ,~) + ^- form:m + (pure:m ((slog tang) ~)) +:: ++ app-message |= [app=term =cord =tang] =/ m (strand ,~) diff --git a/pkg/arvo/lib/test/ford-external.hoon b/pkg/arvo/lib/test/ford-external.hoon deleted file mode 100644 index 304dfa69ff..0000000000 --- a/pkg/arvo/lib/test/ford-external.hoon +++ /dev/null @@ -1,267 +0,0 @@ -/+ *test -=, ford -|% -:: +expect-schematic: assert a +schematic:ford is what we expect -:: -:: Since Ford requests contain types, we can't do simple -:: equality checking. This function handles all the different -:: kinds of +schematic:ford, dealing with types as necessary. -:: -++ expect-schematic - |= [expected=schematic actual=schematic] - ^- tang - :: - ?^ -.expected - ?. ?=(^ -.actual) - [%leaf "expected autocons, but got {<-.actual>}"]~ - :: - %+ weld - $(expected head.expected, actual head.actual) - $(expected tail.expected, actual tail.actual) - :: - ?- -.expected - %$ - ?. ?=(%$ -.actual) - [%leaf "expected %$, but got {<-.actual>}"]~ - :: - %+ weld - (expect-eq !>(p.literal.expected) !>(p.literal.actual)) - (expect-eq q.literal.expected q.literal.actual) - :: - %pin - :: - ?. ?=(%pin -.actual) - [%leaf "expected %pin, but got {<-.actual>}"]~ - :: - %+ weld - (expect-eq !>(date.expected) !>(date.actual)) - $(expected schematic.expected, actual schematic.actual) - :: - %alts - :: - ?. ?=(%alts -.actual) - [%leaf "expected %alts, but got {<-.actual>}"]~ - :: - |- ^- tang - ?~ choices.expected - :: make sure there aren't any extra :choices in :actual - :: - ?~ choices.actual - ~ - [%leaf "actual had more choices than expected"]~ - :: :expected isn't empty yet; make sure :actual isn't either - :: - ?~ choices.actual - [%leaf "expected had more choices than actual"]~ - :: recurse on the first sub-schematic - :: - %+ weld - ^$(expected i.choices.expected, actual i.choices.actual) - $(choices.expected t.choices.expected, choices.actual t.choices.actual) - :: - %bake - (expect-eq [schematic-type expected] [schematic-type actual]) - :: - %bunt - (expect-eq [schematic-type expected] [schematic-type actual]) - :: - %call - :: - ?. ?=(%call -.actual) - [%leaf "expected %call, but got {<-.actual>}"]~ - :: - %+ weld - $(expected gate.expected, actual gate.actual) - $(expected sample.expected, actual sample.actual) - :: - %cast - :: - ?. ?=(%cast -.actual) - [%leaf "expected %cast, but got {<-.actual>}"]~ - :: - ;: weld - (expect-eq !>(disc.expected) !>(disc.actual)) - (expect-eq !>(mark.expected) !>(mark.actual)) - $(expected input.expected, actual input.actual) - == - :: - %core - (expect-eq [schematic-type expected] [schematic-type actual]) - :: - %diff - :: - ?. ?=(%diff -.actual) - [%leaf "expected %diff, but got {<-.actual>}"]~ - :: - ;: weld - (expect-eq !>(disc.expected) !>(disc.actual)) - $(expected start.expected, actual start.actual) - $(expected end.expected, actual end.actual) - == - :: - %dude - :: - ?. ?=(%dude -.actual) - [%leaf "expected %dude, but got {<-.actual>}"]~ - :: - %+ weld - (expect-eq !>(error.expected) !>(error.actual)) - $(expected attempt.expected, actual attempt.actual) - :: - %hood - (expect-eq [schematic-type expected] [schematic-type actual]) - :: - %join - :: - ?. ?=(%join -.actual) - [%leaf "expected %join, but got {<-.actual>}"]~ - :: - ;: weld - (expect-eq !>(disc.expected) !>(disc.actual)) - (expect-eq !>(mark.expected) !>(mark.actual)) - $(expected first.expected, actual first.actual) - $(expected second.expected, actual second.actual) - == - :: - %list - :: - ?. ?=(%list -.actual) - [%leaf "expected %list, but got {<-.actual>}"]~ - :: - |- ^- tang - ?~ schematics.expected - :: make sure there aren't any extra :schematics in :actual - :: - ?~ schematics.actual - ~ - [%leaf "actual had more schematics than expected"]~ - :: :expected isn't empty yet; make sure :actual isn't either - :: - ?~ schematics.actual - [%leaf "expected had more schematics than actual"]~ - :: - %+ weld - ^$(expected i.schematics.expected, actual i.schematics.actual) - :: - %_ $ - schematics.expected t.schematics.expected - schematics.actual t.schematics.actual - == - :: - %mash - :: - ?. ?=(%mash -.actual) - [%leaf "expected %mash, but got {<-.actual>}"]~ - :: - ;: weld - (expect-eq !>(disc.expected) !>(disc.actual)) - (expect-eq !>(mark.expected) !>(mark.actual)) - (expect-eq !>(disc.first.expected) !>(disc.first.actual)) - (expect-eq !>(mark.first.expected) !>(mark.first.actual)) - (expect-eq !>(disc.second.expected) !>(disc.second.actual)) - (expect-eq !>(mark.second.expected) !>(mark.second.actual)) - $(expected schematic.first.expected, actual schematic.first.actual) - $(expected schematic.second.expected, actual schematic.second.actual) - == - :: - %mute - :: - ?. ?=(%mute -.actual) - [%leaf "expected %mute, but got {<-.actual>}"]~ - :: - %+ weld $(expected subject.expected, actual subject.actual) - :: - |- ^- tang - ?~ mutations.expected - :: make sure there aren't any extra :mutations in :actual - :: - ?~ mutations.actual - ~ - [%leaf "actual had more mutations than expected"]~ - :: :expected isn't empty yet; make sure :actual isn't either - :: - ?~ mutations.actual - [%leaf "expected had more mutations than actual"]~ - :: - ;: weld - (expect-eq !>(p.i.mutations.expected) !>(p.i.mutations.actual)) - ^$(expected q.i.mutations.expected, actual q.i.mutations.actual) - %_ $ - mutations.expected t.mutations.expected - mutations.actual t.mutations.actual - == - == - :: - %pact - :: - ?. ?=(%pact -.actual) - [%leaf "expected %pact, but got {<-.actual>}"]~ - :: - ;: weld - (expect-eq !>(disc.expected) !>(disc.actual)) - $(expected start.expected, actual start.actual) - $(expected diff.expected, actual diff.actual) - == - :: - %path - (expect-eq [schematic-type expected] [schematic-type actual]) - :: - %plan - (expect-eq [schematic-type expected] [schematic-type actual]) - :: - %reef - (expect-eq [schematic-type expected] [schematic-type actual]) - :: - %ride - :: - ?. ?=(%ride -.actual) - [%leaf "expected %ride, but got {<-.actual>}"]~ - :: - %+ weld - (expect-eq !>(formula.expected) !>(formula.actual)) - $(expected subject.expected, actual subject.actual) - :: - %same - :: - ?. ?=(%same -.actual) - [%leaf "expected %same, but got {<-.actual>}"]~ - :: - $(expected schematic.expected, actual schematic.actual) - :: - %scry - (expect-eq [schematic-type expected] [schematic-type actual]) - :: - %slim - :: - ?. ?=(%slim -.actual) - [%leaf "expected %slim, but got {<-.actual>}"]~ - :: - %+ weld - (expect-eq !>(formula.expected) !>(formula.actual)) - :: - %+ expect-eq - !>(`?`%.y) - ^- vase - :- -:!>(*?) - ^- ? - (~(nest ut subject-type.expected) | subject-type.actual) - :: - %slit - :: - ?. ?=(%slit -.actual) - [%leaf "expected %slit, but got {<-.actual>}"]~ - :: - %+ weld - (expect-eq gate.expected gate.actual) - (expect-eq sample.expected sample.actual) - :: - ?(%vale %volt) - (expect-eq [schematic-type expected] [schematic-type actual]) - :: - %walk - (expect-eq [schematic-type expected] [schematic-type actual]) - == -:: +schematic-type: the +type for +schematic:ford -:: -++ schematic-type ^~ `type`-:!>(*schematic:ford) --- diff --git a/pkg/arvo/lib/test/ford.hoon b/pkg/arvo/lib/test/ford.hoon deleted file mode 100644 index d5121cf37e..0000000000 --- a/pkg/arvo/lib/test/ford.hoon +++ /dev/null @@ -1,341 +0,0 @@ -/+ *test -:: -/= ford-vane /: /===/sys/vane/ford /!noun/ -:: -/= hoon-scry /: /===/sys/hoon /hoon/ -/= arvo-scry /: /===/sys/arvo /hoon/ -/= zuse-scry /: /===/sys/zuse /hoon/ -/= txt-scry /: /===/mar/txt /hoon/ -/= diff-scry /: /===/mar/txt-diff /hoon/ -:: -!: -=, ford -=, format -:: -=/ test-pit=vase !>(..zuse) -=/ ford-gate (ford-vane test-pit) -:: -|% -++ verify-post-made - |= $: move=move:ford-gate - =duct - =type - date=@da - title=@tas - contents=tape - == - ^- tang - :: - ?> ?=([* %give %made @da %complete %success ^ *] move) - =/ result build-result.result.p.card.move - ?> ?=([%success %scry %noun type-a=* @tas *] head.result) - ?> ?=([%success ^ *] tail.result) - ?> ?=([%success %ride type-title-a=* %post-a] head.tail.result) - ?> ?=([%success %ride type-title-b=* %post-b] tail.tail.result) - :: - ;: welp - %+ expect-eq - !> duct - !> duct.move - :: - %+ expect-eq - !> date - !> date.p.card.move - :: - %+ expect-eq - !> [%success %scry %noun *^type [title=title contents=contents]] - !> head.result(p.q.cage *^type) - :: - %+ expect-eq - !> & - !> (~(nest ut p.q.cage.head.result) | type) - :: - %+ expect-eq - !> 'post-a' - vase.head.tail.result - :: - %+ expect-eq - !> 'post-b' - vase.tail.tail.result - == -++ scry-with-results - |= results=(map [=term =beam] cage) - |= [* (unit (set monk)) =term =beam] - ^- (unit (unit cage)) - :: - =/ date=@da ?>(?=(%da -.r.beam) p.r.beam) - :: - ?^ reef=((scry-reef date) +<.$) - reef - :: - ~| scry-with-results+[term=term beam=beam] - :: - [~ ~ (~(got by results) [term beam])] -:: +scry-with-results-and-failures -:: -++ scry-with-results-and-failures - |= results=(map [=term =beam] (unit cage)) - |= [* (unit (set monk)) =term =beam] - ^- (unit (unit cage)) - :: - =/ date=@da ?>(?=(%da -.r.beam) p.r.beam) - :: - ?^ reef=((scry-reef date) +<.$) - reef - :: - ~| scry-with-results+[term=term beam=beam] - :: - [~ (~(got by results) [term beam])] -:: +scry-succeed: produces a scry function with a known request and answer -:: -++ scry-succeed - |= [date=@da result=cage] ^- sley - |= [* (unit (set monk)) =term =beam] - ^- (unit (unit cage)) - :: - ?^ reef=((scry-reef date) +<.$) - reef - :: - ~| scry-succeed+[beam+beam term+term] - ?> =(term %cx) - ?> =(beam [[~nul %desk %da date] /bar/foo]) - :: - [~ ~ result] -:: +scry-fail: produces a scry function with a known request and failed answer -:: -++ scry-fail - |= date=@da ^- sley - |= [* (unit (set monk)) =term =beam] - ^- (unit (unit cage)) - :: - ?^ reef=((scry-reef date) +<.$) - reef - :: - ~| scry-fail+[beam+beam term+term] - ?> =(term %cx) - ?> =(beam [[~nul %desk %da date] /bar/foo]) - :: - [~ ~] -:: +scry-block: produces a scry function with known request and blocked answer -:: -++ scry-block - |= date=@da ^- sley - |= [* (unit (set monk)) =term =beam] - ^- (unit (unit cage)) - :: - ?^ reef=((scry-reef date) +<.$) - reef - :: - ~| scry-block+[beam+beam term+term] - ?> =(term %cx) - ?> =(beam [[~nul %desk %da date] /bar/foo]) - :: - ~ -:: +scry-blocks: block on a file at multiple dates; does not include %reef -:: -++ scry-blocks - |= dates=(set @da) ^- sley - |= [* (unit (set monk)) =term =beam] - ^- (unit (unit cage)) - :: - ~| scry-block+[beam+beam term+term] - ?> =(term %cx) - ?> ?=([%da @da] r.beam) - ?> (~(has in dates) p.r.beam) - :: - ~ -:: +scry-is-forbidden: makes sure ford does not attempt to scry -:: -++ scry-is-forbidden ^- sley - |= [* (unit (set monk)) =term =beam] - ^- (unit (unit cage)) - :: - =/ date=@da ?>(?=(%da -.r.beam) p.r.beam) - :: - ?^ reef=((scry-reef date) +<.$) - reef - :: - ~| scry-is-forbidden+[beam+beam term+term] - !! -:: -++ scry-reef - |= date=@da ^- sley - |= [* (unit (set monk)) =term =beam] - ^- (unit (unit cage)) - :: - =- ?~ res=(~(get by -) [term beam]) - ~ - `res - :: - (with-reef date ~) -:: -++ with-reef - |= [date=@da scry-results=(map [term beam] cage)] - ^+ scry-results - %- ~(gas by scry-results) - :~ :- [%cx [[~nul %home %da date] /hoon/hoon/sys]] - [%hoon !>(hoon-scry)] - :- [%cx [[~nul %home %da date] /hoon/arvo/sys]] - [%hoon !>(arvo-scry)] - :- [%cx [[~nul %home %da date] /hoon/zuse/sys]] - [%hoon !>(zuse-scry)] - :: - :- [%cw [[~nul %home %da date] /hoon/hoon/sys]] - [%cass !>([ud=1 da=date])] - == -:: -++ with-reef-unit - |= [date=@da scry-results=(map [term beam] (unit cage))] - ^+ scry-results - %- ~(gas by scry-results) - :~ :- [%cx [[~nul %home %da date] /hoon/hoon/sys]] - `[%noun !>(~)] - :- [%cx [[~nul %home %da date] /hoon/arvo/sys]] - `[%noun !>(~)] - :- [%cx [[~nul %home %da date] /hoon/zuse/sys]] - `[%noun !>(~)] - :: - :- [%cw [[~nul %home %da date] /hoon/hoon/sys]] - `[%cass !>([ud=1 da=date])] - == -:: -++ ford-call - |= $: ford-gate=_ford-gate - now=@da - scry=sley - call-args=[=duct type=* wrapped-task=(hobo task:able:ford-gate)] - expected-moves=(list move:ford-gate) - == - ^- [tang _ford-gate] - :: - =/ ford (ford-gate our=~nul now=now eny=`@`0xdead.beef scry=scry) - :: - =^ moves ford-gate - %- call:ford [duct ~ type wrapped-task]:call-args - :: - =/ output=tang - %+ expect-eq - !> expected-moves - !> moves - :: - [output ford-gate] -:: -++ ford-take - |= $: ford-gate=_ford-gate - now=@da - scry=sley - take-args=[=wire =duct wrapped-sign=(hypo sign:ford-gate)] - expected-moves=(list move:ford-gate) - == - ^- [tang _ford-gate] - :: - =/ ford (ford-gate our=~nul now=now eny=`@`0xdead.beef scry=scry) - :: - =^ moves ford-gate - %- take:ford [wire duct ~ wrapped-sign]:take-args - :: - =/ output=tang - %+ expect-eq - !> expected-moves - !> moves - :: - [output ford-gate] -:: +ford-call-with-comparator -:: -:: Sometimes we can't just do simple comparisons between the moves statements -:: and must instead specify a gate that performs the comparisons. -:: -++ ford-call-with-comparator - |= $: ford-gate=_ford-gate - now=@da - scry=sley - call-args=[=duct type=* wrapped-task=(hobo task:able:ford-gate)] - move-comparator=$-((list move:ford-gate) tang) - == - ^- [tang _ford-gate] - :: - =/ ford (ford-gate our=~nul now=now eny=`@`0xdead.beef scry=scry) - :: - =^ moves ford-gate - %- call:ford [duct ~ type wrapped-task]:call-args - :: - =/ output=tang (move-comparator moves) - :: - [output ford-gate] -:: +ford-take-with-comparator -:: -++ ford-take-with-comparator - |= $: ford-gate=_ford-gate - now=@da - scry=sley - take-args=[=wire =duct wrapped-sign=(hypo sign:ford-gate)] - move-comparator=$-((list move:ford-gate) tang) - == - ^- [tang _ford-gate] - :: - =/ ford (ford-gate our=~nul now=now eny=`@`0xdead.beef scry=scry) - :: - =^ moves ford-gate - %- take:ford [wire duct ~ wrapped-sign]:take-args - :: - =/ output=tang (move-comparator moves) - :: - [output ford-gate] -:: +expect-cage: assert that the actual cage has the right mark and vase -:: -++ expect-cage - |= [mark=term expected=vase actual=cage] - %+ weld - %+ expect-eq - !> mark - !> p.actual - :: - (expect-eq expected q.actual) -:: +expect-ford-empty: assert that ford's state is one empty ship -:: -:: At the end of every test, we want to assert that we have cleaned up all -:: state. -:: -++ expect-ford-empty - |= [ford-gate=_ford-gate ship=@p] - ^- tang - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=scry-is-forbidden - call-args=[duct=~[/empty] type=~ [%keep 0 0]] - expected-moves=~ - == - :: - =/ ford *ford-gate - =/ state state.ax.+>+<.ford - :: - =/ default-state *ford-state:ford - :: - =. max-size.compiler-cache.state max-size.compiler-cache.default-state - =. max-size.queue.build-cache.state max-size.queue.build-cache.default-state - =. next-anchor-id.build-cache.state 0 - :: - %+ welp results1 - :: - ?: =(default-state state) - ~ - :: - =/ build-state=(list tank) - %- zing - %+ turn ~(tap by builds.state) - |= [build=build:ford build-status=build-status:ford] - :~ [%leaf (build-to-tape:ford build)] - [%leaf "requesters: {}"] - [%leaf "clients: {<~(tap in ~(key by clients.build-status))>}"] - == - :: - =/ braces [[' ' ' ' ~] ['{' ~] ['}' ~]] - :: - :~ [%leaf "failed to cleanup"] - [%leaf "builds.state:"] - [%rose braces build-state] - == --- diff --git a/pkg/arvo/lib/test/runner.hoon b/pkg/arvo/lib/test/runner.hoon index da61c3c74a..75d6d2d5f6 100644 --- a/pkg/arvo/lib/test/runner.hoon +++ b/pkg/arvo/lib/test/runner.hoon @@ -10,6 +10,45 @@ +$ test-func (trap tang) -- |% +++ run-test + :: executes an individual test. + |= [pax=path test=test-func] + ^- [ok=? =tang] + =+ name=(spud pax) + =+ run=(mule test) + ?- -.run + %| :- %| :: the stack is already flopped for output? + ;: weld + p.run + `tang`[[%leaf (weld "CRASHED " name)] ~] + == + %& ?: =(~ p.run) + &+[[%leaf (weld "OK " name)] ~] + :: Create a welded list of all failures indented. + :- %| + %- flop + ;: weld + `tang`[[%leaf (weld "FAILED " name)] ~] + ::TODO indent + :: %+ turn p:run + :: |= {i/tape} + :: ^- tank + :: [%leaf (weld " " i)] + p.run + == + == +:: +filter-tests-by-prefix +:: +++ filter-tests-by-prefix + |= [prefix=path tests=(list test)] + ^+ tests + :: + =/ prefix-length=@ud (lent prefix) + :: + %+ skim tests + :: + |= [=path *] + =(prefix (scag prefix-length path)) :: +resolve-test-paths: add test names to file paths to form full identifiers :: ++ resolve-test-paths diff --git a/pkg/arvo/mar/acme/order.hoon b/pkg/arvo/mar/acme/order.hoon index a43c30cc62..17a9a01b21 100644 --- a/pkg/arvo/mar/acme/order.hoon +++ b/pkg/arvo/mar/acme/order.hoon @@ -2,6 +2,11 @@ :::: /mar/acme/order/hoon :: |_ a=(set (list @t)) +++ grad %noun +++ grow + |% + ++ noun a + -- ++ grab |% ++ noun (set (list @t)) diff --git a/pkg/arvo/mar/azimuth/update.hoon b/pkg/arvo/mar/azimuth/update.hoon index 45b0e6727a..580a8d7615 100644 --- a/pkg/arvo/mar/azimuth/update.hoon +++ b/pkg/arvo/mar/azimuth/update.hoon @@ -1,6 +1,11 @@ :: |_ upd=update:azimuth :: +++ grad %noun +++ grow + |% + ++ noun upd + -- ++ grab :: convert from |% ++ noun update:azimuth :: from %noun diff --git a/pkg/arvo/mar/chat/action.hoon b/pkg/arvo/mar/chat/action.hoon index 1f6f8cc5ba..9f9565eb84 100644 --- a/pkg/arvo/mar/chat/action.hoon +++ b/pkg/arvo/mar/chat/action.hoon @@ -1,5 +1,10 @@ /+ *chat-store |_ act=action +++ grad %noun +++ grow + |% + ++ noun act + -- ++ grab |% ++ noun action diff --git a/pkg/arvo/mar/chat/hook-action.hoon b/pkg/arvo/mar/chat/hook-action.hoon index 19e80101c1..03564a41b3 100644 --- a/pkg/arvo/mar/chat/hook-action.hoon +++ b/pkg/arvo/mar/chat/hook-action.hoon @@ -1,5 +1,10 @@ /+ *chat-hook |_ act=action +++ grad %noun +++ grow + |% + ++ noun act + -- ++ grab |% ++ noun action diff --git a/pkg/arvo/mar/chat/hook-update.hoon b/pkg/arvo/mar/chat/hook-update.hoon index 7a52fa154b..b5e31a9ef0 100644 --- a/pkg/arvo/mar/chat/hook-update.hoon +++ b/pkg/arvo/mar/chat/hook-update.hoon @@ -1,7 +1,9 @@ /+ *chat-hook |_ upd=update +++ grad %noun ++ grow |% + ++ noun upd ++ json (update:enjs upd) -- :: diff --git a/pkg/arvo/mar/chat/update.hoon b/pkg/arvo/mar/chat/update.hoon index 59a14653ef..b5dab99552 100644 --- a/pkg/arvo/mar/chat/update.hoon +++ b/pkg/arvo/mar/chat/update.hoon @@ -1,7 +1,9 @@ /+ *chat-store |_ upd=update +++ grad %noun ++ grow |% + ++ noun upd ++ json (update:enjs upd) -- :: diff --git a/pkg/arvo/mar/chat/view-action.hoon b/pkg/arvo/mar/chat/view-action.hoon index 1306f25625..cc33eb67bd 100644 --- a/pkg/arvo/mar/chat/view-action.hoon +++ b/pkg/arvo/mar/chat/view-action.hoon @@ -1,5 +1,10 @@ /+ *chat-view |_ act=action +++ grad %noun +++ grow + |% + ++ noun act + -- ++ grab |% ++ noun action diff --git a/pkg/arvo/mar/contact/action.hoon b/pkg/arvo/mar/contact/action.hoon index c280b6e13c..a756fb8102 100644 --- a/pkg/arvo/mar/contact/action.hoon +++ b/pkg/arvo/mar/contact/action.hoon @@ -1,5 +1,10 @@ /+ *contact-json |_ act=contact-action +++ grad %noun +++ grow + |% + ++ noun act + -- ++ grab |% ++ noun contact-action diff --git a/pkg/arvo/mar/contact/hook-update.hoon b/pkg/arvo/mar/contact/hook-update.hoon index a1bdebd7bf..481582282c 100644 --- a/pkg/arvo/mar/contact/hook-update.hoon +++ b/pkg/arvo/mar/contact/hook-update.hoon @@ -1,7 +1,9 @@ /+ *contact-json |_ upd=contact-hook-update +++ grad %noun ++ grow |% + ++ noun upd ++ json (hook-update-to-json upd) -- :: diff --git a/pkg/arvo/mar/contact/initial.hoon b/pkg/arvo/mar/contact/initial.hoon index 837a105a50..0bf1d3e8d8 100644 --- a/pkg/arvo/mar/contact/initial.hoon +++ b/pkg/arvo/mar/contact/initial.hoon @@ -1,8 +1,10 @@ /+ *contact-json |_ rolo=rolodex :: +++ grad %noun ++ grow |% + ++ noun +<.grow ++ json (rolodex-to-json rolo) -- :: diff --git a/pkg/arvo/mar/contact/update.hoon b/pkg/arvo/mar/contact/update.hoon index b53a54f991..75e5931255 100644 --- a/pkg/arvo/mar/contact/update.hoon +++ b/pkg/arvo/mar/contact/update.hoon @@ -1,7 +1,9 @@ /+ *contact-json |_ upd=contact-update +++ grad %noun ++ grow |% + ++ noun upd ++ json (update-to-json upd) -- :: diff --git a/pkg/arvo/mar/dill/belt.hoon b/pkg/arvo/mar/dill/belt.hoon index 36493d256a..05a2ddb9d3 100644 --- a/pkg/arvo/mar/dill/belt.hoon +++ b/pkg/arvo/mar/dill/belt.hoon @@ -9,6 +9,11 @@ =, sole |_ dill-belt:dill :: +++ grad %noun +++ grow + |% + ++ noun +<.grow + -- ++ grab :: convert from |% ++ json diff --git a/pkg/arvo/mar/dill/blit.hoon b/pkg/arvo/mar/dill/blit.hoon index 699f5906ed..2dc0acd7a8 100644 --- a/pkg/arvo/mar/dill/blit.hoon +++ b/pkg/arvo/mar/dill/blit.hoon @@ -6,6 +6,7 @@ =, sole =, enjs:format |_ dib/dill-blit:dill +++ grad %noun :: ++ grab :: convert from |% @@ -13,6 +14,7 @@ -- ++ grow |% + ++ noun dib ++ json ^- ^json ?+ -.dib ~|(unsupported-blit+-.dib !!) diff --git a/pkg/arvo/mar/dns/address.hoon b/pkg/arvo/mar/dns/address.hoon index 51fc29ad8e..c8e709f136 100644 --- a/pkg/arvo/mar/dns/address.hoon +++ b/pkg/arvo/mar/dns/address.hoon @@ -1,5 +1,10 @@ /- *dns |_ address +++ grad %noun +++ grow + |% + ++ noun +<.grow + -- ++ grab |% ++ noun address diff --git a/pkg/arvo/mar/dns/binding.hoon b/pkg/arvo/mar/dns/binding.hoon index ec9f5b66e5..6f10d17f56 100644 --- a/pkg/arvo/mar/dns/binding.hoon +++ b/pkg/arvo/mar/dns/binding.hoon @@ -1,5 +1,10 @@ /- *dns |_ binding +++ grad %noun +++ grow + |% + ++ noun +<.grow + -- ++ grab |% ++ noun binding diff --git a/pkg/arvo/mar/dns/complete.hoon b/pkg/arvo/mar/dns/complete.hoon index 9b22572bcc..cbe67c6f09 100644 --- a/pkg/arvo/mar/dns/complete.hoon +++ b/pkg/arvo/mar/dns/complete.hoon @@ -1,5 +1,10 @@ /- *dns |_ [ship binding] +++ grad %noun +++ grow + |% + ++ noun +<.grow + -- ++ grab |% +$ noun [ship binding] diff --git a/pkg/arvo/mar/drum-put.hoon b/pkg/arvo/mar/drum-put.hoon index d1dc4b86af..956c3f4b14 100644 --- a/pkg/arvo/mar/drum-put.hoon +++ b/pkg/arvo/mar/drum-put.hoon @@ -4,6 +4,11 @@ /? 310 |_ {path @} :: +++ grad %noun +++ grow + |% + ++ noun +<.grow + -- ++ grab :: convert from |% ++ noun {path @} :: clam from %noun diff --git a/pkg/arvo/mar/elem.hoon b/pkg/arvo/mar/elem.hoon index eccb4a580e..b8fb3a7fd7 100644 --- a/pkg/arvo/mar/elem.hoon +++ b/pkg/arvo/mar/elem.hoon @@ -6,13 +6,13 @@ =, html |_ own/manx :: +++ grad %mime ++ grow :: convert to |% ++ hymn ;html:(head body:"+{own}") :: convert to %hymn ++ html (crip (en-xml hymn)) :: convert to %html ++ mime [/text/html (as-octs html)] :: convert to %mime -- -++ garb /snip :: grabbed by ++ grab |% :: convert from ++ noun manx :: clam from %noun -- -- diff --git a/pkg/arvo/mar/eth-watcher-poke.hoon b/pkg/arvo/mar/eth-watcher-poke.hoon index b1658d2c12..798acc4b44 100644 --- a/pkg/arvo/mar/eth-watcher-poke.hoon +++ b/pkg/arvo/mar/eth-watcher-poke.hoon @@ -1,5 +1,10 @@ /- *eth-watcher |_ poke +++ grad %noun +++ grow + |% + ++ noun +<.grow + -- ++ grab |% ++ noun poke diff --git a/pkg/arvo/mar/file-server/action.hoon b/pkg/arvo/mar/file-server/action.hoon index 1ebabf589c..dbacde4665 100644 --- a/pkg/arvo/mar/file-server/action.hoon +++ b/pkg/arvo/mar/file-server/action.hoon @@ -1,5 +1,10 @@ /- *file-server |_ act=action +++ grad %noun +++ grow + |% + ++ noun act + -- ++ grab |% ++ noun action diff --git a/pkg/arvo/mar/file-server/update.hoon b/pkg/arvo/mar/file-server/update.hoon index 81e3b703c9..5bd4677f8f 100644 --- a/pkg/arvo/mar/file-server/update.hoon +++ b/pkg/arvo/mar/file-server/update.hoon @@ -1,7 +1,9 @@ /+ *file-server |_ upd=update +++ grad %noun ++ grow |% + ++ noun upd ++ json (update:enjs upd) -- ++ grab diff --git a/pkg/arvo/mar/front.hoon b/pkg/arvo/mar/front.hoon index 1a636649f9..c0e61be06b 100644 --- a/pkg/arvo/mar/front.hoon +++ b/pkg/arvo/mar/front.hoon @@ -7,8 +7,10 @@ :: |_ all/(map knot cord) :: +++ grad %noun ++ grow :: convert to |% + ++ noun all ++ json :- %o %- ~(run by all) diff --git a/pkg/arvo/mar/group/action.hoon b/pkg/arvo/mar/group/action.hoon index 1534ff941c..b351bd7c8d 100644 --- a/pkg/arvo/mar/group/action.hoon +++ b/pkg/arvo/mar/group/action.hoon @@ -1,6 +1,11 @@ /+ *group-json =, dejs:format |_ act=group-action +++ grad %noun +++ grow + |% + ++ noun act + -- ++ grab |% ++ noun group-action diff --git a/pkg/arvo/mar/group/hook-action.hoon b/pkg/arvo/mar/group/hook-action.hoon index d5c0892a6b..8a5a250e80 100644 --- a/pkg/arvo/mar/group/hook-action.hoon +++ b/pkg/arvo/mar/group/hook-action.hoon @@ -1,6 +1,11 @@ /- *group-hook =, dejs:format |_ act=group-hook-action +++ grad %noun +++ grow + |% + ++ noun act + -- ++ grab |% ++ noun group-hook-action diff --git a/pkg/arvo/mar/group/update.hoon b/pkg/arvo/mar/group/update.hoon index de99721469..ceb67d1e24 100644 --- a/pkg/arvo/mar/group/update.hoon +++ b/pkg/arvo/mar/group/update.hoon @@ -1,11 +1,13 @@ /+ *group-json |_ upd=group-update +++ grad %noun ++ grab |% ++ noun group-update -- ++ grow |% + ++ noun upd ++ json =, enjs:format ^- ^json diff --git a/pkg/arvo/mar/helm-hi.hoon b/pkg/arvo/mar/helm-hi.hoon index 345fdcd31c..940c91cfe1 100644 --- a/pkg/arvo/mar/helm-hi.hoon +++ b/pkg/arvo/mar/helm-hi.hoon @@ -6,6 +6,7 @@ =, format |_ txt/cord :: +++ grad %mime ++ grab :: convert from |% ++ noun @t :: clam from %noun diff --git a/pkg/arvo/mar/hoon.hoon b/pkg/arvo/mar/hoon.hoon index ade9f38bbb..cd582f8a7b 100644 --- a/pkg/arvo/mar/hoon.hoon +++ b/pkg/arvo/mar/hoon.hoon @@ -1,4 +1,3 @@ -:: :::: /hoon/hoon/mar :: /? 310 diff --git a/pkg/arvo/mar/htm.hoon b/pkg/arvo/mar/htm.hoon index 80f4f6bf11..98f2ab819c 100644 --- a/pkg/arvo/mar/htm.hoon +++ b/pkg/arvo/mar/htm.hoon @@ -4,8 +4,10 @@ /? 310 |_ own/manx :: +++ grad %noun ++ grow :: convert to |% + ++ noun own ++ hymn own -- ++ grab |% :: convert from diff --git a/pkg/arvo/mar/html.hoon b/pkg/arvo/mar/html.hoon index e2a7af113e..c6aeef3bc0 100644 --- a/pkg/arvo/mar/html.hoon +++ b/pkg/arvo/mar/html.hoon @@ -6,14 +6,16 @@ :::: compute :: =, html +^| |_ htm/@t -:: ++ grow :: convert to + ^? |% :: ++ mime [/text/html (met 3 htm) htm] :: to %mime ++ hymn (need (de-xml htm)) :: to %hymn -- :: -++ grab |% :: convert from +++ grab ^? + |% :: convert from ++ noun @t :: clam from %noun ++ mime |=({p/mite q/octs} q.q) :: retrieve form $mime -- diff --git a/pkg/arvo/mar/httr.hoon b/pkg/arvo/mar/httr.hoon index 2a54a26a7f..f9ae1fb0a4 100644 --- a/pkg/arvo/mar/httr.hoon +++ b/pkg/arvo/mar/httr.hoon @@ -7,10 +7,12 @@ =, format =, html |_ hit/httr +++ grad %noun ++ grow |% ++ wall (turn wain trip) ++ wain (to-wain cord) ++ json (need (de-json cord)) ++ cord q:octs + ++ noun hit ++ octs ~| hit ?> =(2 (div p.hit 100)) diff --git a/pkg/arvo/mar/hymn.hoon b/pkg/arvo/mar/hymn.hoon index 50005b6f55..a56e3a0cf0 100644 --- a/pkg/arvo/mar/hymn.hoon +++ b/pkg/arvo/mar/hymn.hoon @@ -6,6 +6,7 @@ =, html |_ own/manx :: +++ grad %mime ++ grow :: convert to |% ++ html (crip (en-xml own)) :: convert to %html diff --git a/pkg/arvo/mar/invite/action.hoon b/pkg/arvo/mar/invite/action.hoon index 5265671c21..a0baf8b6d1 100644 --- a/pkg/arvo/mar/invite/action.hoon +++ b/pkg/arvo/mar/invite/action.hoon @@ -1,6 +1,11 @@ /+ *invite-json =, dejs:format |_ act=invite-action +++ grad %noun +++ grow + |% + ++ noun act + -- ++ grab |% ++ noun invite-action diff --git a/pkg/arvo/mar/invite/update.hoon b/pkg/arvo/mar/invite/update.hoon index 7ee747de91..534e304d88 100644 --- a/pkg/arvo/mar/invite/update.hoon +++ b/pkg/arvo/mar/invite/update.hoon @@ -1,7 +1,9 @@ /+ *invite-json |_ upd=invite-update +++ grad %noun ++ grow |% + ++ noun upd ++ json (update-to-json upd) -- :: diff --git a/pkg/arvo/mar/json/rpc/response.hoon b/pkg/arvo/mar/json/rpc/response.hoon index 17134ffdb6..9f91469d0e 100644 --- a/pkg/arvo/mar/json/rpc/response.hoon +++ b/pkg/arvo/mar/json/rpc/response.hoon @@ -3,6 +3,11 @@ :: |_ res=response :: +++ grad %noun +++ grow + |% + ++ noun res + -- ++ grab :: convert from |% ++ noun response :: from noun diff --git a/pkg/arvo/mar/language-server/rpc/notification.hoon b/pkg/arvo/mar/language-server/rpc/notification.hoon index 9f47189db7..88fdaa8c1b 100644 --- a/pkg/arvo/mar/language-server/rpc/notification.hoon +++ b/pkg/arvo/mar/language-server/rpc/notification.hoon @@ -1,6 +1,7 @@ /- *language-server /+ lsp-json=language-server-json |_ not=all:notification +++ grad %noun ++ grab |% ++ noun not @@ -10,6 +11,7 @@ -- ++ grow |% + ++ noun not ++ json (notification:enjs:lsp-json not) -- diff --git a/pkg/arvo/mar/language-server/rpc/request.hoon b/pkg/arvo/mar/language-server/rpc/request.hoon index 80efda8873..48db6b7eae 100644 --- a/pkg/arvo/mar/language-server/rpc/request.hoon +++ b/pkg/arvo/mar/language-server/rpc/request.hoon @@ -1,6 +1,11 @@ /- *language-server /+ lsp-json=language-server-json |_ req=all:request +++ grad %noun +++ grow + |% + ++ noun req + -- ++ grab |% ++ noun req diff --git a/pkg/arvo/mar/language-server/rpc/response.hoon b/pkg/arvo/mar/language-server/rpc/response.hoon index c2390e8752..f82408b877 100644 --- a/pkg/arvo/mar/language-server/rpc/response.hoon +++ b/pkg/arvo/mar/language-server/rpc/response.hoon @@ -2,8 +2,10 @@ /+ lsp=language-server-json |_ res=all:response :: +++ grad %noun ++ grow |% + ++ noun res ++ json (response:enjs:lsp res) -- :: diff --git a/pkg/arvo/mar/launch/action.hoon b/pkg/arvo/mar/launch/action.hoon index 594ca5e646..ef67d57e8f 100644 --- a/pkg/arvo/mar/launch/action.hoon +++ b/pkg/arvo/mar/launch/action.hoon @@ -1,5 +1,10 @@ /+ *launch-store |_ act=action +++ grad %noun +++ grow + |% + ++ noun act + -- ++ grab |% ++ noun action diff --git a/pkg/arvo/mar/launch/update.hoon b/pkg/arvo/mar/launch/update.hoon index afe1758d32..79484384a1 100644 --- a/pkg/arvo/mar/launch/update.hoon +++ b/pkg/arvo/mar/launch/update.hoon @@ -1,7 +1,9 @@ /+ *launch-store |_ upd=update +++ grad %noun ++ grow |% + ++ noun upd ++ json (update:enjs upd) -- :: diff --git a/pkg/arvo/mar/lens/command.hoon b/pkg/arvo/mar/lens/command.hoon index 9080780270..b8f0532f2e 100644 --- a/pkg/arvo/mar/lens/command.hoon +++ b/pkg/arvo/mar/lens/command.hoon @@ -1,5 +1,10 @@ /- lens |_ com/command:lens +++ grad %noun +++ grow + |% + ++ noun com + -- ++ grab |% ++ noun command:lens diff --git a/pkg/arvo/mar/link/action.hoon b/pkg/arvo/mar/link/action.hoon index 608d4c4755..f02dfdd357 100644 --- a/pkg/arvo/mar/link/action.hoon +++ b/pkg/arvo/mar/link/action.hoon @@ -1,8 +1,9 @@ :: link: subscription updates :: ::TODO this should include json conversion once mark performance improves -/+ *link +/+ *link-store |_ =action +++ grad %noun ++ grow |% ++ noun action @@ -11,6 +12,6 @@ ++ grab |% ++ noun ^action - ++ json action:de-json + ++ json action:dejs -- -- diff --git a/pkg/arvo/mar/link/initial.hoon b/pkg/arvo/mar/link/initial.hoon index ad73c1667a..488dc1869a 100644 --- a/pkg/arvo/mar/link/initial.hoon +++ b/pkg/arvo/mar/link/initial.hoon @@ -1,7 +1,8 @@ :: link: initial subscription result :: -/- *link +/- *link-store |_ =initial +++ grad %noun ++ grow |% ++ noun initial diff --git a/pkg/arvo/mar/link/listen-action.hoon b/pkg/arvo/mar/link/listen-action.hoon index b14c4ac1e0..49910ccd6d 100644 --- a/pkg/arvo/mar/link/listen-action.hoon +++ b/pkg/arvo/mar/link/listen-action.hoon @@ -3,6 +3,7 @@ /- *link-listen-hook =, dejs:format |_ act=action +++ grad %noun ++ grab |% ++ noun action diff --git a/pkg/arvo/mar/link/listen-poke.hoon b/pkg/arvo/mar/link/listen-poke.hoon index b7ece7a388..14e44e8c17 100644 --- a/pkg/arvo/mar/link/listen-poke.hoon +++ b/pkg/arvo/mar/link/listen-poke.hoon @@ -1,6 +1,7 @@ :: link-listen-poke: prod another listener into paying attention :: |_ =path +++ grad %noun ++ grow |% ++ noun path diff --git a/pkg/arvo/mar/link/listen-update.hoon b/pkg/arvo/mar/link/listen-update.hoon index 3f4252d521..ecffba9e5b 100644 --- a/pkg/arvo/mar/link/listen-update.hoon +++ b/pkg/arvo/mar/link/listen-update.hoon @@ -3,6 +3,7 @@ /- *link-listen-hook =, dejs:format |_ upd=update +++ grad %noun ++ grab |% ++ noun update diff --git a/pkg/arvo/mar/link/update.hoon b/pkg/arvo/mar/link/update.hoon index f48600d77a..a71624a710 100644 --- a/pkg/arvo/mar/link/update.hoon +++ b/pkg/arvo/mar/link/update.hoon @@ -1,7 +1,8 @@ :: link: subscription updates :: -/- *link +/- *link-store |_ =update +++ grad %noun ++ grow |% ++ noun update diff --git a/pkg/arvo/mar/link/view-action.hoon b/pkg/arvo/mar/link/view-action.hoon index f32241a346..cb261d32e0 100644 --- a/pkg/arvo/mar/link/view-action.hoon +++ b/pkg/arvo/mar/link/view-action.hoon @@ -1,9 +1,14 @@ /- *link-view =, dejs:format -|_ act=view-action +|_ act=action +++ grad %noun +++ grow + |% + ++ noun act + -- ++ grab |% - ++ noun view-action + ++ noun action ++ json |^ %- of :~ %create^create @@ -34,9 +39,4 @@ (cu sy (ar (su ;~(pfix sig fed:ag)))) -- -- -:: -++ grow - |% - ++ noun act - -- -- diff --git a/pkg/arvo/mar/metadata/action.hoon b/pkg/arvo/mar/metadata/action.hoon index 396979bf42..e7a7668e13 100644 --- a/pkg/arvo/mar/metadata/action.hoon +++ b/pkg/arvo/mar/metadata/action.hoon @@ -1,6 +1,11 @@ /+ *metadata-json =, dejs:format |_ act=metadata-action +++ grad %noun +++ grow + |% + ++ noun act + -- ++ grab |% ++ noun metadata-action diff --git a/pkg/arvo/mar/metadata/update.hoon b/pkg/arvo/mar/metadata/update.hoon index 653ea91a1f..aed47bd2dd 100644 --- a/pkg/arvo/mar/metadata/update.hoon +++ b/pkg/arvo/mar/metadata/update.hoon @@ -1,7 +1,9 @@ /+ *metadata-json |_ upd=metadata-update +++ grad %noun ++ grow |% + ++ noun upd ++ json (update-to-json upd) -- :: diff --git a/pkg/arvo/mar/mime.hoon b/pkg/arvo/mar/mime.hoon index 83bf171285..f5b1850a00 100644 --- a/pkg/arvo/mar/mime.hoon +++ b/pkg/arvo/mar/mime.hoon @@ -3,19 +3,23 @@ :: /? 310 :: +^| |_ own/mime ++ grow + ^? |% ++ jam `@`q.q.own -- :: ++ grab :: convert from + ^? |% +$ noun mime :: clam from %noun ++ tape |=(a/_"" [/application/x-urb-unknown (as-octt:mimes:html a)]) -- ++ grad + ^? |% ++ form %mime ++ diff |=(mime +<) diff --git a/pkg/arvo/mar/noun.hoon b/pkg/arvo/mar/noun.hoon index e80ac367ba..906ab54329 100644 --- a/pkg/arvo/mar/noun.hoon +++ b/pkg/arvo/mar/noun.hoon @@ -8,4 +8,11 @@ ++ grab |% ++ noun * -- +++ grad + |% + ++ form %noun + ++ diff |=(* +<) + ++ pact |=(* +<) + ++ join |=([* *] *(unit *)) + -- -- diff --git a/pkg/arvo/mar/path.hoon b/pkg/arvo/mar/path.hoon index f9c4cac063..d3952babb5 100644 --- a/pkg/arvo/mar/path.hoon +++ b/pkg/arvo/mar/path.hoon @@ -1,4 +1,9 @@ |_ pax/path +++ grad %noun +++ grow + |% + ++ noun pax + -- ++ grab |% ++ noun path diff --git a/pkg/arvo/mar/permission/action.hoon b/pkg/arvo/mar/permission/action.hoon index f316b3d71b..a5670a5514 100644 --- a/pkg/arvo/mar/permission/action.hoon +++ b/pkg/arvo/mar/permission/action.hoon @@ -1,6 +1,11 @@ /+ *permission-json =, dejs:format |_ act=permission-action +++ grad %noun +++ grow + |% + ++ noun act + -- ++ grab |% ++ noun permission-action diff --git a/pkg/arvo/mar/permission/group-hook-action.hoon b/pkg/arvo/mar/permission/group-hook-action.hoon index e80a0e38fe..f68dc793ec 100644 --- a/pkg/arvo/mar/permission/group-hook-action.hoon +++ b/pkg/arvo/mar/permission/group-hook-action.hoon @@ -1,6 +1,11 @@ /- *permission-group-hook /+ *permission-json |_ act=permission-group-hook-action +++ grad %noun +++ grow + |% + ++ noun act + -- ++ grab |% ++ noun permission-group-hook-action diff --git a/pkg/arvo/mar/permission/hook-action.hoon b/pkg/arvo/mar/permission/hook-action.hoon index 44df95f951..3706fee33d 100644 --- a/pkg/arvo/mar/permission/hook-action.hoon +++ b/pkg/arvo/mar/permission/hook-action.hoon @@ -1,5 +1,10 @@ /- *permission-hook |_ act=permission-hook-action +++ grad %noun +++ grow + |% + ++ noun act + -- ++ grab |% ++ noun permission-hook-action diff --git a/pkg/arvo/mar/permission/update.hoon b/pkg/arvo/mar/permission/update.hoon index 0c183203c7..fed5550392 100644 --- a/pkg/arvo/mar/permission/update.hoon +++ b/pkg/arvo/mar/permission/update.hoon @@ -1,7 +1,10 @@ /+ *permission-json |_ upd=permission-update +:: +++ grad %noun ++ grow |% + ++ noun upd ++ json (update-to-json upd) -- :: diff --git a/pkg/arvo/mar/publish/action.hoon b/pkg/arvo/mar/publish/action.hoon index 6128eeed61..2e5c1ce3c1 100644 --- a/pkg/arvo/mar/publish/action.hoon +++ b/pkg/arvo/mar/publish/action.hoon @@ -6,8 +6,10 @@ :: |_ act=action :: +++ grad %noun ++ grow |% + ++ noun act ++ tank >act< -- :: diff --git a/pkg/arvo/mar/publish/info.hoon b/pkg/arvo/mar/publish/info.hoon index 731e6e568e..cb28e7e72a 100644 --- a/pkg/arvo/mar/publish/info.hoon +++ b/pkg/arvo/mar/publish/info.hoon @@ -31,7 +31,7 @@ ++ old-parser ;~ plug (key-val (jest 'owner: ~') fed:ag) - (key-val (jest 'title: ') (cook crip (star qit))) + (key-val (jest 'title: ') (cook crip (star prn))) (key-val (jest 'filename: ') sym) %+ key-val (jest 'comments: ') ;~(pose (jest %open) (jest %closed) (jest %none)) @@ -45,8 +45,8 @@ == ++ new-parser ;~ plug - (key-val (jest 'title: ') (cook crip (star qit))) - (key-val (jest 'description: ') (cook crip (star qit))) + (key-val (jest 'title: ') (cook crip (star prn))) + (key-val (jest 'description: ') (cook crip (star prn))) %+ key-val (jest 'comments: ') (cook |=(a=@ =(%on a)) ;~(pose (jest %on) (jest %off))) (key-val (jest 'writers: ') ;~(pfix net (more net urs:ab))) diff --git a/pkg/arvo/mar/publish/notebook-delta.hoon b/pkg/arvo/mar/publish/notebook-delta.hoon index 76d693efc0..59c73a0030 100644 --- a/pkg/arvo/mar/publish/notebook-delta.hoon +++ b/pkg/arvo/mar/publish/notebook-delta.hoon @@ -6,6 +6,11 @@ :: |_ del=notebook-delta :: +++ grad %noun +++ grow + |% + ++ noun del + -- ++ grab |% ++ noun notebook-delta diff --git a/pkg/arvo/mar/publish/primary-delta.hoon b/pkg/arvo/mar/publish/primary-delta.hoon index ff1b9bf6a6..d2b01052d3 100644 --- a/pkg/arvo/mar/publish/primary-delta.hoon +++ b/pkg/arvo/mar/publish/primary-delta.hoon @@ -5,12 +5,14 @@ :: |_ del=primary-delta :: +++ grad %noun ++ grab |% ++ noun primary-delta -- ++ grow |% + ++ noun del ++ json %+ frond:enjs:format %publish-update %+ frond:enjs:format -.del diff --git a/pkg/arvo/mar/purl.hoon b/pkg/arvo/mar/purl.hoon index 72714c132d..148ef1d742 100644 --- a/pkg/arvo/mar/purl.hoon +++ b/pkg/arvo/mar/purl.hoon @@ -4,9 +4,13 @@ /? 310 =, eyre |_ url/purl +++ grad %noun :: -++ grow |% ++ hiss [url %get ~ ~] - -- +++ grow + |% + ++ noun url + ++ hiss [url %get ~ ~] + -- ++ grab :: convert from |% ++ noun purl :: clam from %noun diff --git a/pkg/arvo/mar/s3/action.hoon b/pkg/arvo/mar/s3/action.hoon index fc2abb6401..9dec004d70 100644 --- a/pkg/arvo/mar/s3/action.hoon +++ b/pkg/arvo/mar/s3/action.hoon @@ -1,5 +1,10 @@ /+ *s3-json |_ act=action +++ grad %noun +++ grow + |% + ++ noun act + -- ++ grab |% ++ noun action diff --git a/pkg/arvo/mar/s3/update.hoon b/pkg/arvo/mar/s3/update.hoon index afcdceb911..3a1b4dbd5b 100644 --- a/pkg/arvo/mar/s3/update.hoon +++ b/pkg/arvo/mar/s3/update.hoon @@ -1,7 +1,9 @@ /+ *s3-json |_ upd=update +++ grad %noun ++ grow |% + ++ noun upd ++ json (update-to-json upd) -- :: diff --git a/pkg/arvo/mar/snip.hoon b/pkg/arvo/mar/snip.hoon index 5f6cdf1838..e6eb3225ee 100644 --- a/pkg/arvo/mar/snip.hoon +++ b/pkg/arvo/mar/snip.hoon @@ -43,6 +43,7 @@ :: =, mimes:html |_ {hed/marl tal/marl} +++ grad %mime :: ++ grow :: convert to |% diff --git a/pkg/arvo/mar/sole/action.hoon b/pkg/arvo/mar/sole/action.hoon index ebde86216d..58c87cbe74 100644 --- a/pkg/arvo/mar/sole/action.hoon +++ b/pkg/arvo/mar/sole/action.hoon @@ -9,6 +9,11 @@ =, sole |_ sole-action :: +++ grad %noun +++ grow + |% + ++ noun +<.grad + -- ++ grab :: convert from |% ++ json diff --git a/pkg/arvo/mar/sole/effect.hoon b/pkg/arvo/mar/sole/effect.hoon index 34bfee687f..edf4f64571 100644 --- a/pkg/arvo/mar/sole/effect.hoon +++ b/pkg/arvo/mar/sole/effect.hoon @@ -43,6 +43,7 @@ :: |_ sef/sole-effect :: +++ grad %noun ++ grab :: convert from |% ++ noun sole-effect :: clam from %noun @@ -50,6 +51,7 @@ ++ grow =, enjs |% + ++ noun sef ++ json ^- ^json ?+ -.sef diff --git a/pkg/arvo/mar/spider/stop.hoon b/pkg/arvo/mar/spider/stop.hoon index e3c4d65d23..9051542d7c 100644 --- a/pkg/arvo/mar/spider/stop.hoon +++ b/pkg/arvo/mar/spider/stop.hoon @@ -1,5 +1,6 @@ /- *spider |_ stop=[=tid nice=?] +++ grad %noun ++ grab |% ++ noun ,[=tid nice=?] diff --git a/pkg/arvo/mar/tang.hoon b/pkg/arvo/mar/tang.hoon index 0fa3471a50..6847515430 100644 --- a/pkg/arvo/mar/tang.hoon +++ b/pkg/arvo/mar/tang.hoon @@ -5,9 +5,10 @@ :: =, format |_ tan/(list tank) -:: +++ grad %noun ++ grow |% + ++ noun tan ++ elem =- ;pre:code:"{(of-wall -)}" ^- wall %- zing ^- (list wall) diff --git a/pkg/arvo/mar/txt-diff.hoon b/pkg/arvo/mar/txt-diff.hoon index e457594b04..5471acc16a 100644 --- a/pkg/arvo/mar/txt-diff.hoon +++ b/pkg/arvo/mar/txt-diff.hoon @@ -4,6 +4,11 @@ /? 310 |_ txt-diff/(urge:clay cord) :: +++ grad %noun +++ grow + |% + ++ noun txt-diff + -- ++ grab :: convert from |% ++ noun (urge:clay cord) :: make from %noun diff --git a/pkg/arvo/mar/txt.hoon b/pkg/arvo/mar/txt.hoon index f87f58fe80..808a59aa1a 100644 --- a/pkg/arvo/mar/txt.hoon +++ b/pkg/arvo/mar/txt.hoon @@ -55,7 +55,7 @@ |=(cud/(urge cord) [i.bob cud]) %+ bind $(ali t.ali, p.i.bob (sub p.i.bob p.i.ali)) |=(cud/(urge cord) [i.ali cud]) - :: + :: %| ?: =(p.i.ali (lent p.i.bob)) %+ bind $(ali t.ali, bob t.bob) @@ -68,7 +68,12 @@ :: %| ?- -.i.bob - %| ~ + %| + ?. =(i.ali i.bob) + ~ + %+ bind $(ali t.ali, bob t.bob) + |=(cud/(urge cord) [i.ali cud]) + :: %& ?: =(p.i.bob (lent p.i.ali)) %+ bind $(ali t.ali, bob t.bob) diff --git a/pkg/arvo/mar/urb.hoon b/pkg/arvo/mar/urb.hoon index d1edbfb004..a579ee01fd 100644 --- a/pkg/arvo/mar/urb.hoon +++ b/pkg/arvo/mar/urb.hoon @@ -6,6 +6,7 @@ =, html |_ own/manx :: +++ grad %mime ++ grow :: convert to |% ++ hymn ;html:(head body:"+{own}") :: convert to %hymn diff --git a/pkg/arvo/mar/urbit.hoon b/pkg/arvo/mar/urbit.hoon index 901d8807e7..9b7bb4e1cc 100644 --- a/pkg/arvo/mar/urbit.hoon +++ b/pkg/arvo/mar/urbit.hoon @@ -9,4 +9,9 @@ |% ++ noun @p -- +++ grow + |% + ++ noun her + -- +++ grad %noun -- diff --git a/pkg/arvo/mar/verb/event.hoon b/pkg/arvo/mar/verb/event.hoon index f596d8e6db..f595e4d35d 100644 --- a/pkg/arvo/mar/verb/event.hoon +++ b/pkg/arvo/mar/verb/event.hoon @@ -1,6 +1,7 @@ /- verb =, dejs:format |_ =event:verb +++ grad %noun ++ grab |% ++ noun event:verb diff --git a/pkg/arvo/mar/x-htm.hoon b/pkg/arvo/mar/x-htm.hoon index 0bdff8444c..c4c1a6b20f 100644 --- a/pkg/arvo/mar/x-htm.hoon +++ b/pkg/arvo/mar/x-htm.hoon @@ -1,4 +1,5 @@ |_ a=manx +++ grad %noun ++ grab |% ++ noun manx @@ -6,5 +7,6 @@ ++ grow |% ++ htm a + ++ noun a -- -- diff --git a/pkg/arvo/mar/x-htm/elem.hoon b/pkg/arvo/mar/x-htm/elem.hoon index c0210fd110..93ff4dbdcc 100644 --- a/pkg/arvo/mar/x-htm/elem.hoon +++ b/pkg/arvo/mar/x-htm/elem.hoon @@ -1,3 +1,11 @@ |_ a=manx -++ grab |% ++ noun manx --- -- +++ grad %noun +++ grab + |% + ++ noun manx + -- +++ grow + |% + ++ noun a + -- +-- diff --git a/pkg/arvo/mar/xml.hoon b/pkg/arvo/mar/xml.hoon index 26ed90e501..01ac140fbf 100644 --- a/pkg/arvo/mar/xml.hoon +++ b/pkg/arvo/mar/xml.hoon @@ -9,6 +9,7 @@ =, html |_ xml/@t :: +++ grad %mime ++ grow :: convert to |% :: ++ mime [/application/xml (as-octs xml)] :: to %mime diff --git a/pkg/arvo/sur/link-store.hoon b/pkg/arvo/sur/link-store.hoon new file mode 100644 index 0000000000..2646190394 --- /dev/null +++ b/pkg/arvo/sur/link-store.hoon @@ -0,0 +1,50 @@ +:: link-store: store specific types +:: +/- *link +^? +|% +:: +:: +action: local actions +:: ++$ action + $% :: user actions + :: + :: %save: save page to path on our ship + :: + [%save =path title=@t =url] + :: %note: save a note for a url + :: + [%note =path =url udon=@t] + :: %seen: mark item as read (~ for all in path) + :: + [%seen =path url=(unit url)] + :: hook actions + :: + :: %hear: hear about page at path on other ship + :: + [%hear =path submission] + :: %read: hear about note on url from ship + :: + [%read =path =url comment] + == +:: +:: +initial: local result +:: ++$ initial + $% [%local-pages pages=(map path pages)] + [%submissions submissions=(map path submissions)] + [%annotations notes=(per-path-url notes)] + [%discussions comments=(per-path-url comments)] + == +:: +update: local updates +:: +::NOTE we include paths/urls to support the "subscribed to all" case +:: ++$ update + $% [%local-pages =path =pages] + [%submissions =path =submissions] + [%annotations =path =url =notes] + [%discussions =path =url =comments] + [%observation =path urls=(set url)] + == +-- diff --git a/pkg/arvo/sur/link-view.hoon b/pkg/arvo/sur/link-view.hoon index ae1d40221c..db3e2f4a97 100644 --- a/pkg/arvo/sur/link-view.hoon +++ b/pkg/arvo/sur/link-view.hoon @@ -1,7 +1,7 @@ :: link-view: encapsulating link management :: |% -++ view-action +++ action $% :: %create: create a new link collection :: :: with specified metadata and group. %ships creates a new group, diff --git a/pkg/arvo/sur/link.hoon b/pkg/arvo/sur/link.hoon index bfa4d04987..20b30a98cc 100644 --- a/pkg/arvo/sur/link.hoon +++ b/pkg/arvo/sur/link.hoon @@ -46,48 +46,4 @@ ++ per-path-url |$ [value] (map path (map url value)) -:: -:: +action: local actions -:: -+$ action - $% :: user actions - :: - :: %save: save page to path on our ship - :: - [%save =path title=@t =url] - :: %note: save a note for a url - :: - [%note =path =url udon=@t] - :: %seen: mark item as read (~ for all in path) - :: - [%seen =path url=(unit url)] - :: hook actions - :: - :: %hear: hear about page at path on other ship - :: - [%hear =path submission] - :: %read: hear about note on url from ship - :: - [%read =path =url comment] - == -:: -:: +initial: local result -:: -+$ initial - $% [%local-pages pages=(map path pages)] - [%submissions submissions=(map path submissions)] - [%annotations notes=(per-path-url notes)] - [%discussions comments=(per-path-url comments)] - == -:: +update: local updates -:: -::NOTE we include paths/urls to support the "subscribed to all" case -:: -+$ update - $% [%local-pages =path =pages] - [%submissions =path =submissions] - [%annotations =path =url =notes] - [%discussions =path =url =comments] - [%observation =path urls=(set url)] - == -- diff --git a/pkg/arvo/sys/arvo.hoon b/pkg/arvo/sys/arvo.hoon index 0bbf9622f8..f9b34e9764 100644 --- a/pkg/arvo/sys/arvo.hoon +++ b/pkg/arvo/sys/arvo.hoon @@ -1,9 +1,8 @@ :::::: :::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::: :::::: Postface :::::: :::::: :::::::::::::::::::::::::::::::::::::::::::::::::::::: -~> %slog.[0 leaf+"%arvo-assembly"] -=- ~> %slog.[0 leaf+"%arvo-assembled"] - - +~> %slog.[0 leaf+"arvo: assembly"] +~< %slog.[0 leaf+"arvo: assembled"] =< :: :: Arvo formal interface :: @@ -14,7 +13,7 @@ :: |= [now=@da ovo=*] ^- * - ~> %slog.[0 leaf+"arvo-event"] + ~> %slog.[0 leaf+"arvo: formal event"] .(+> +:(poke now ovo)) :::::: :::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::: :::::: volume 3, Arvo models and skeleton :::::: @@ -170,7 +169,7 @@ == -- => -~% %hex +> ~ +~% %hex ..ut ~ |% :::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :: section 3bE, Arvo core :: @@ -257,7 +256,7 @@ +$ ovum [=wire =card] -- :: - ~% %part +> ~ + ~% %part ..part ~ |% :: +| %utilities @@ -532,22 +531,27 @@ => |% :: $germ: worklist source and bar stack :: $plan: worklist + :: $debt: in-progress state :: +$ germ [vane=term bars=(list duct)] +$ plan (pair germ (list move)) + +$ debt + $~ [~ ~ *germ ~] + $: :: run: list of worklists + :: out: pending output + :: gem: worklist metadata + :: dud: propagate error + :: + run=(list plan) + out=(list ovum) + gem=germ + dud=(unit goof) + == -- :: - ~% %le +>+> ~ - =| $: :: run: list of worklists - :: out: pending output - :: gem: worklist metadata - :: dud: propagate error - :: - run=(list plan) - out=(list ovum) - gem=germ - dud=(unit goof) - == + ~% %le part ~ + =| debt + =* nub - :: |_ $: our=ship now=@da @@ -557,13 +561,29 @@ van=(map term vane) == +* this . + ++ plot run.nub + ++ then |=(paz=(list plan) this(run (weld run paz))) + ++ abed |=(nib=debt this(nub nib)) :: +abet: finalize loop :: + :: .ovo: optional effect to arvo itself + :: + :: If ovo is ~, the loop is over; produce ova. + :: Else, produce u.ovo and the unfinished .nub internal state. + :: ++ abet - ^- (pair (list ovum) (list (pair term vane))) - :- (flop out) - %+ sort - ~(tap by van) + |= ovo=(unit ovum) + ^- $: %+ each (list ovum) + $: fec=ovum + nub=debt + == + van=(list (pair term vane)) + == + :- ?~ ovo + &+(flop out) + |+[u.ovo nub] + :: + %+ sort ~(tap by van) |=([[a=@tas *] [b=@tas *]] (aor a b)) :: +emit: enqueue a worklist with source :: @@ -621,20 +641,24 @@ :: +loop: until done :: ++ loop - ^+ this + ^- abet ?~ run - this + (abet ~) ?: =(~ q.i.run) :: XX TMI loop(run t.run) =. dud ~ =. gem p.i.run - =^ mov q.i.run q.i.run - loop:(step mov) + =^ mov=move q.i.run q.i.run + => .(run `(list plan)`run) :: XX TMI + =^ ovo=(unit ovum) this (step mov) + ?~ ovo + loop + (abet `u.ovo) :: +step: advance the loop one step by routing a move :: ++ step |= =move - ^+ this + ^- [(unit ovum) _this] :: ~? &(!lac ?=(^ dud)) %goof :: @@ -660,7 +684,7 @@ :: :: cons source onto wire, and wire onto duct :: - (call [[vane.gem wire] duct] vane task) + `(call [[vane.gem wire] duct] vane task) :: :: %slip: lateral move :: @@ -673,7 +697,7 @@ :- (runt [(lent bars.gem) '|'] "") [%slip vane.gem (symp +>-.task) duct] :: - (call duct vane task) + `(call duct vane task) :: :: %give: return move :: @@ -707,7 +731,7 @@ (symp +>-.gift) duct.move :: - (take duct wire vane gift) + `(take duct wire vane gift) :: :: %hurl: action with error :: @@ -717,6 +741,30 @@ ball.move wite.ball.move == == + :: +whey: measure memory usage + :: + ++ whey + ^- (list mass) + =/ von + %+ turn + (sort ~(tap by van) |=([[a=@tas *] [b=@tas *]] (aor a b))) + |=([lal=@tas =vane] (cat 3 %vane- lal)^vane) + :: + :~ :+ %reports %| + %+ turn von + =/ bem=beam [[our %home da+now] /whey] + |= [lal=@tas =vane] + =/ met (need (need (peek ** ~ (rsh 3 5 lal) bem))) + lal^|+;;((list mass) q.q.met) + :: + :+ %caches %| + %+ turn von + |=([lal=@tas =vane] lal^&+worm.vane) + :: + :+ %dregs %| + %+ turn von + |=([lal=@tas =vane] lal^&+vase.vane) + == :: +peek: read from the entire namespace :: ++ peek @@ -727,7 +775,6 @@ :: XX identity is defaulted to ship from beam :: => .(fur ?^(fur fur `[[%& p.bed] ~ ~])) - :: :: XX vane and care are concatenated :: =/ lal (end 3 1 ron) @@ -739,8 +786,11 @@ :: ++ xeno |= [=wire gift=maze] - ^+ this - this(out [[wire ;;(card q.p.gift)] out]) + ^- [(unit ovum) _this] + =/ ovo=ovum [wire ;;(card q.p.gift)] + ?: ?=(?(%lyra %veer %wack %verb %whey) -.card.ovo) + [`ovo this] + [~ this(out [ovo out])] :: +call: advance to target :: ++ call @@ -795,8 +845,6 @@ ++ ruck :: update vase |= {pax/path txt/@ta} ^+ +> - =- ?:(?=(%| -.res) ((slog p.res) +>.$) p.res) - ^= res %- mule |. :: XX should use real entropy and the real date :: =/ arg=vane-sample @@ -846,13 +894,12 @@ pax=path txt=@ta == - =- ?:(?=(%| -.res) ((slog p.res) ~) (some p.res)) - ^= res %- mule |. - ~| [%failed-vint lal] + =; res ?-(-.res %& p.res, %| (mean leaf+"vint: {}" p.res)) + %- mule |. =+ gen=(rain pax txt) - ~& [%vane-parsed `@p`(mug gen)] + ~> %slog.[0 leaf+"vane: parsed {(scow p+(mug gen))}"] =+ pro=(vent who lal vil bud [(slym (slap bud gen) bud) *worm]) - ~& [%vane-compiled `@p`(mug pro)] + ~> %slog.[0 leaf+"vane: compiled {(scow p+(mug pro))}"] prime:pro :: ++ viol :: vane tools @@ -928,8 +975,9 @@ ?^ who u.who =/ fip=ship (dec (bex 128)) - ~>(%slog.[0 leaf+"arvo: larval identity {(scow %p fip)}"] fip) - =. ..veer (veer our now q.ovo) + ~> %slog.[0 leaf+"arvo: larval identity {(scow %p fip)}"] + fip + =. soul (veer our now q.ovo) +>.$(bod ?^(bod bod `bud.^poke)) :: add entropy :: @@ -949,9 +997,10 @@ ?. &(?=(^ who) ?=(^ eny) ?=(^ bod)) [~ +>.$] ~> %slog.[0 leaf+"arvo: metamorphosis"] + ~< %slog.[0 leaf+"arvo: metamorphosed"] =/ nyf (turn vanes.^poke |=([label=@tas =vane] [label vase.vane])) - (load u.who now u.eny ova=~ u.bod nyf) + (load u.who now u.eny *pram u.bod nyf) :: ++ wish |= txt=* :: 22 ?> ?=(@ txt) @@ -968,215 +1017,110 @@ bud=vase :: %zuse vanes=(list [label=@tas =vane]) :: modules == :: -=< :: Arvo structural interface - :: - |% - ++ come |= [@ @ @ (list ovum) vise pone] :: 4 - ^- [(list ovum) _+>] - ~& %hoon-come - =^ rey +>+ (^come +<) - [rey +>.$] - :: - ++ load |= [@ @ @ (list ovum) vase pane] :: 10 - ^- [(list ovum) _+>] - ~& %hoon-load - =^ rey +>+ (^load +<) - [rey +>.$] - :: - ++ peek |= * :: 46 - =/ rob (^peek ;;([@da path] +<)) - ?~ rob ~ - ?~ u.rob ~ - [~ u.u.rob] - :: - ++ poke |= * :: 47 - => .(+< ;;([now=@da ovo=ovum] +<)) - =^ ova +>+.$ (^poke now ovo) - =| out=(list ovum) - |- ^- [(list ovum) *] - ?~ ova - [(flop out) +>.^$] - :: upgrade the kernel - :: - ?: ?=(%lyra -.q.i.ova) - %+ fall - (vega now t.ova ;;([@ @] +.q.i.ova)) - [~ +>.^$] - :: iterate over effects, handling those on arvo proper - :: and passing the rest through as output - :: - =^ vov +>+.^$ (feck now i.ova) - =? out ?=(^ vov) [+.vov out] - $(ova t.ova) - :: - ++ wish |=(* (^wish ;;(@ta +<))) :: 22 - -- -:: Arvo implementation core +:: produce an interface that vere understands +:: +=< arvo +:: soul: arvo implementation core :: |% -++ come :: load incompatible - |= [who=ship now=@da yen=@ ova=(list ovum) dub=vise nyf=pone] - ^+ [ova +>] - =/ fyn (turn nyf |=([a=@tas b=vise] [a (slim b)])) - (load who now yen ova (slim dub) fyn) +++ soul . +:: arvo: structural interface core :: -++ load :: load compatible - |= [who=ship now=@da yen=@ ova=(list ovum) dub=vase nyf=pane] - ^+ [ova +>] +++ arvo + |% + ++ come |= [@ @ @ pram vise pone] :: 4 + (come:soul +<) + :: + ++ load |= [@ @ @ pram vase pane] :: 10 + (load:soul +<) + :: + ++ peek |= * :: 46 + =/ rob (^peek ;;([@da path] +<)) + ?~ rob ~ + ?~ u.rob ~ + [~ u.u.rob] + :: + ++ poke |= * :: 47 + => .(+< ;;([now=@da ovo=ovum] +<)) + (poke:soul now ovo) + :: + ++ wish |=(* (^wish ;;(@ta +<))) :: 22 + -- +:: $pram: upgradeable state +:: +dram: upgrade $pram, compatible +:: ++$ pram + $~ [%~2020.6.28 nub=*debt:le:part] + $% [%~2020.6.28 nub=debt:le:part] + (list ovum) + == +++ dram + |= ram=pram + ^- pram + ?: ?=([%~2020.6.28 *] ram) + ram + ~| ram+ram + =| nub=debt:le:part + =/ =plan:le:part + :- [%$ ~] + %+ turn ;;((list ovum) ram) + |= ovo=ovum + ^- move + [[p.ovo]~ %give %& %noun q.ovo] + [%~2020.6.28 nub(run [plan]~)] +:: $prim: old $pram +:: +drum: upgrade $prim to $pram, incompatible +:: ++$ prim pram +++ drum |=(prim +<) +:: +come: load incompatible +:: +++ come + |= [who=ship now=@da yen=@ rim=prim dub=vise nyf=pone] + ^- [(list ovum) *] + ~| %come + =/ fyn (turn nyf |=([a=@tas b=vise] [a (slim b)])) + =/ rum (drum rim) + (load who now yen rum (slim dub) fyn) +:: +load: load compatible, notifying vanes +:: +++ load + |= [who=ship now=@da yen=@ ram=pram dub=vase nyf=pane] + ^- [(list ovum) *] + ~| %load =: our who eny yen bud dub vanes (turn nyf |=({a/@tas b/vise} [a [b *worm]])) == - =| out=(list ovum) - |- ^- [(list ovum) _+>.^$] - ?~ ova - [(flop out) +>.^$] - :: iterate over effects, handling those on arvo proper - :: and passing the rest through as output - :: - :: In practice, the pending effects after an upgrade - :: are the %veer moves to install %zuse and the vanes, - :: plus a %vega notification that the upgrade is complete. - :: - :: N.B. this implementation assumes that %vega will be - :: at the end of :ova. - :: - ?: ?=(%vega -.q.i.ova) - =^ zef=(list ovum) vanes - =< abet:loop - %. i.ova - %~ spam le:part - [our now eny lac vil (~(gas by *(map term vane)) vanes)] - :: - $(out [i.ova out], ova (weld t.ova zef)) - :: - =^ vov +>.^$ (feck now i.ova) - =? out ?=(^ vov) [+.vov out] - $(ova t.ova) + =. ram (dram ram) + ?> ?=([%~2020.6.28 *] ram) + =/ run plot:(spam:(lead now ~) [//arvo %vega ~]) + (leap now (then:(lead now `nub.ram) run)) +:: +peek: external inspect :: -++ peek :: external inspect +++ peek |= {now/@da hap/path} ^- (unit (unit)) ?~ hap [~ ~ hoon-version] - %. [[151 %noun] hap] - %- sloy - %~ peek le:part - [our now eny lac vil (~(gas by *(map term vane)) vanes)] + ?: =(hap /whey) + ``mass+(whey now) + ((sloy peek:(lead now ~)) [[151 %noun] hap]) +:: +poke: external apply :: -++ poke :: external apply +++ poke |= [now=@da ovo=ovum] =. eny (shaz (cat 3 eny now)) - ^- [(list ovum) _+>.$] - :: - :: These external events are actually effects on arvo proper. - :: They can also be produced as the effects of other events. - :: In either case, they fall through here to be handled - :: after the fact in +feck. - :: - ?: ?=(?(%veer %verb %wack %warn) -.q.ovo) - [[ovo ~] +>.$] - :: - :: These external events (currently only %trim) are global - :: notifications, spammed to every vane - :: - ?: ?=(%trim -.q.ovo) - => .(ovo ;;((pair wire [%trim p=@ud]) ovo)) - =^ zef vanes - ^- (pair (list ovum) (list (pair term vane))) - =< abet:loop - %. ovo - %~ spam le:part - [our now eny lac vil (~(gas by *(map term vane)) vanes)] - :: clear compiler caches if high-priority - :: - =? vanes =(0 p.q.ovo) - ~> %slog.[0 leaf+"arvo: trim: clearing caches"] - (turn vanes |=([a=@tas =vane] [a vase.vane *worm])) - [zef +>.$] - :: - :: Error notifications are unwrapped and routed as usual - :: - ?: ?=(%crud p.q.ovo) - ?. ?=(^ q.q.ovo) - ~|([%unknown-crud q.ovo] !!) - :: - =^ zef vanes - =* el - ~(. le:part [our now eny lac vil (~(gas by *(map term vane)) vanes)]) - :: - =< abet:loop - ?@ -.q.q.ovo - :: - :: legacy %crud, directly routed - :: - (poke:el (dint p.ovo) ovo) - :: - :: modern %crud, unwrapped and routed w/ $goof - :: - =/ =goof ;;(goof -.q.q.ovo) - =/ =curd ;;(curd +.q.q.ovo) - (crud:el (dint p.ovo) goof p.ovo curd) - :: - [zef +>.$] - :: Normal events are routed to a single vane - :: - =^ zef vanes - =< abet:loop - %. [(dint p.ovo) ovo] - %~ poke le:part - [our now eny lac vil (~(gas by *(map term vane)) vanes)] - :: - [zef +>.$] -:: +feck: handle an arvo effect -:: -++ feck - |= [now=@da ovo=ovum] - ^- [(unit ovum) _+>.$] + ~| poke+-.q.ovo + |- ^- [(list ovum) *] ?+ -.q.ovo - :: pass through unrecognized effect - :: - [[~ ovo] +>.$] - :: toggle event verbose event printfs - :: - %verb - [~ +>.$(lac !lac)] - :: install %zuse or vane - :: - %veer - [~ (veer our now q.ovo)] - :: add data to memory profile - :: - %mass - =. q.q.ovo - :- %userspace - :- %| - :~ hoon+&+pit - zuse+&+bud - :+ %caches %| - %+ turn - %+ sort vanes - |=([a=[lab=@tas *] b=[lab=@tas *]] (aor lab.a lab.b)) - |=([label=@tas =vane] [(cat 3 %vane- label) %& worm.vane]) - q.q.ovo - :+ %vases %| - %+ turn - %+ sort vanes - |=([a=[lab=@tas *] b=[lab=@tas *]] (aor lab.a lab.b)) - |=([label=@tas =vane] [(cat 3 %vane- label) %& vase.vane]) - dot+&+. - == - [[~ ovo] +>.$] - :: add entropy - :: - %wack - ?> ?=(@ q.q.ovo) - =. eny (shaz (cat 3 eny q.q.ovo)) - [~ +>.$] - :: learn of event-replacement failure + :: Normal events are routed to a single vane + :: + (leap now (poke:(lead now ~) (dint p.ovo) ovo)) + :: Print warning and no-op. :: %warn - :_ +>.$ + :_ arvo ?. ?=(^ +.q.ovo) ~ =/ msg=tape @@ -1187,70 +1131,183 @@ =/ rep %- mule |. ((slog (tang +>.q.ovo)) ~) - ?.(?=(%& -.rep) ~ p.rep) + ~ + :: Process these events just as if they had come from a vane + :: + ?(%lyra %veer %verb %wack %whey) (feck now ovo *debt:le:part) + :: These external events (currently only %trim) are global + :: notifications, spammed to every vane + :: + %trim + => .(ovo ;;((pair wire [%trim p=@ud]) ovo)) + =^ zef vanes loop:(spam:(lead now ~) ovo) + :: clear compiler caches if high-priority + :: + =? vanes =(0 p.q.ovo) + ~> %slog.[0 leaf+"arvo: trim: clearing caches"] + (turn vanes |=([a=@tas =vane] [a vase.vane *worm])) + ?: ?=(%& -.zef) + [p.zef arvo] + (feck now [fec nub]:p.zef) + :: Error notifications are unwrapped and routed as usual + :: + %crud + ?. ?=(^ q.q.ovo) + ~|([%unknown-crud q.ovo] !!) + :: + %+ leap now + ?@ -.q.q.ovo + :: legacy %crud, directly routed + :: + (poke:(lead now ~) (dint p.ovo) ovo) + :: modern %crud, unwrapped and routed w/ $goof + :: + =/ =goof ;;(goof -.q.q.ovo) + =/ =curd ;;(curd +.q.q.ovo) + (crud:(lead now ~) (dint p.ovo) goof p.ovo curd) == +:: +lead: initialize +le core :: -++ vega :: reboot kernel +++ lead + |= [now=@da nub=(unit debt:le:part)] + ^+ le:part + ~| lead+.?(nub) + =; el + ?~ nub el + (abed:el u.nub) + ~(. le:part our now eny lac vil (~(gas by *(map term vane)) vanes)) +:: +leap: run vane loop and handle effects +:: +++ leap + |= [now=@da el=_le:part] + ^- [(list ovum) *] + ~| %leap + =^ zef vanes loop:el + ?: ?=(%& -.zef) + [p.zef arvo] + (feck now [fec nub]:p.zef) +:: +whey: report memory usage +:: +++ whey + |= now=@da + ^- mass + :+ %arvo %| + :~ hoon+&+pit + zuse+&+bud + vane+|+whey:(lead now ~) + == +:: +feck: handle an effect from a vane +:: +++ feck + |= [now=@da ovo=ovum nub=debt:le:part] + ^- [(list ovum) *] + ~| feck+-.q.ovo + ?: ?=(%lyra -.q.ovo) + (vega now nub ;;([(unit @) @] +.q.ovo)) + ?+ -.q.ovo ~|(bad-fec+-.q.ovo !!) + :: produce memory usage report + :: + %whey + =. out.nub [[p.ovo mass+(whey now)] out.nub] + (leap now (lead now `nub)) + :: %verb: toggle event verbose event printfs + :: + %verb + =. lac !lac + (leap now (lead now `nub)) + :: %veer: install %zuse or vane + :: + %veer + =. soul (veer our now q.ovo) + (leap now (lead now `nub)) + :: %wack: add entropy + :: + %wack + ?> ?=(@ q.q.ovo) + =. eny (shaz (cat 3 eny q.q.ovo)) + (leap now (lead now `nub)) + == +:: +vega: reboot kernel +:: +++ vega |= $: :: now: current date - :: ova: actions to process after reboot - :: hun: hoon.hoon source + :: nub: vane continuation state + :: hun: hoon.hoon source, or ~ if unchanged :: arv: arvo.hoon source :: now=@da - ova=(list ovum) - hun=@t + nub=debt:le:part + hun=(unit @t) van=@t == - ^- (unit (pair (list ovum) *)) - :: virtualize; dump error if we fail - :: - =- ?:(?=(%| -.res) ((slog p.res) ~) `p.res) - ^= res %- mule |. :: produce a new kernel and an effect list :: - ^- (pair (list ovum) *) - :: compile the hoon.hoon source with the current compiler + ^- [(list ovum) *] + :: go metacircular as hint to vere to run in new memory arena :: - =/ raw - ~& [%hoon-compile `@p`(mug hun)] - (road |.((ride %noun hun))) - :: activate the new compiler gate, producing +ride + =; res ?-(-.res %& p.res, %| (mean leaf+"vega: ruin" p.res)) + %- mule |. + :: obtain hoon compiler data :: - =/ cop .*(0 +.raw) - :: find the hoon version number of the new kernel + :: Arvo is compiled against the hoon.hoon vase with its outer +ride + :: gate stripped off, leaving the main core. :: - =/ nex - (@ .*(cop q:(~(mint ut p.raw) %noun [%limb %hoon-version]))) - ?> |(=(nex hoon-version) =(+(nex) hoon-version)) - :: if we're upgrading language versions, recompile the compiler + :: hyp: hoon core type + :: hoc: hoon core + :: cop: compiler gate + :: lod: can we use the +load arm? (language-compatible upgrade) :: - :: hot: raw compiler formula - :: - =^ hot=* cop - ?: =(nex hoon-version) - [raw cop] - ~& [%hoon-compile-upgrade nex] - %- road |. - =/ hot (slum cop [%noun hun]) - [hot .*(0 +.hot)] - :: extract the hoon core from the outer gate (+ride) - :: - =/ hoc .*(cop [%0 7]) - :: compute the type of the hoon.hoon core - :: - =/ hyp -:(slum cop [-.hot '+>']) + =/ [hyp=* hoc=* cop=* lod=?] + :: if no new hoon.hoon source, use current compiler + :: + ?~ hun + [-:!>(+>:ride) +>:ride ride &] + :: compile new hoon.hoon source with the current compiler + :: + =/ raw + ~> %slog.[0 leaf+"vega: compiling hoon"] + (road |.((ride %noun u.hun))) + :: activate the new compiler gate, producing +ride + :: + =/ cop .*(0 +.raw) + :: find the hoon version number of the new kernel + :: + =/ nex + (@ .*(cop q:(~(mint ut p.raw) %noun [%limb %hoon-version]))) + ?> |(=(nex hoon-version) =(+(nex) hoon-version)) + :: if we're upgrading language versions, recompile the compiler + :: + =^ hot=* cop + ?: =(nex hoon-version) + [raw cop] + ~> %slog.[0 leaf+"vega: recompiling hoon {}k"] + ~& [%hoon-compile-upgrade nex] + %- road |. + =/ hot (slum cop [%noun hun]) + [hot .*(0 +.hot)] + :: extract the hoon core from the outer gate (+ride) + :: + =/ hoc .*(cop [%0 7]) + :: compute the type of the hoon.hoon core + :: + =/ hyp -:(slum cop [-.hot '+>']) + :: + [hyp hoc cop =(nex hoon-version)] :: compile arvo :: =/ rav - ~& [%arvo-compile `@p`(mug hyp) `@p`(mug van)] - (road |.((slum cop [hyp van]))) + ~> %slog.[0 leaf+"vega: compiling kernel {(scow %p (mug hyp))}"] + %- road |. + (slum cop [hyp van]) :: activate arvo, and extract the arvo core from the outer gate :: + ~> %slog.[0 leaf+"vega: extracting core"] =/ voc .*(hoc [%7 +.rav %0 7]) :: entry gate: ++load for the normal case, ++come for upgrade :: =/ gat - =/ arm ?:(=(nex hoon-version) 'load' 'come') + =/ arm ?:(lod 'load' 'come') + ~> %slog.[0 leaf+"vega: +{(trip arm)}"] :: compute the type of the arvo.hoon core :: =/ vip -:(slum cop [-.rav '+>']) @@ -1266,52 +1323,54 @@ :* our now eny - :: tack a notification onto the pending effects - :: - (weld ova [`ovum`[//arvo %vega ~] ~]) + [%~2020.6.28 nub] bud (turn vanes |=([label=@tas =vane] [label vase.vane])) == :: call into the new kernel :: + ~> %slog.[0 leaf+"vega: evolving"] + ~< %slog.[0 leaf+"vega: evolution"] =/ out (slum gat sam) :: add types to the product :: - [((list ovum) -.out) +.out] + ;;([(list ovum) *] out) :: +veer: install %zuse or a vane :: :: Identity is in the sample so the larval stage -:: can use this as well. +:: can use this too. :: ++ veer |= [who=ship now=@da fav=curd] - => .(fav ;;({$veer lal/@ta pax/path txt/@t} fav)) - =- ?:(?=(%| -.res) ((slog p.res) +>.$) p.res) - ^= res %- mule |. + ^+ soul + => .(fav ;;([%veer lal=@tas pax=path txt=@t] fav)) + =; res ?-(-.res %& p.res, %| (mean leaf+"veer: {}" p.res)) + %- mule |. ?: =(%$ lal.fav) - ~& [%tang pax.fav `@p`(mug txt.fav)] + ~> %slog.[0 leaf+"zuse: {(scow p+(mug txt.fav))}"] =+ gen=(rain pax.fav txt.fav) =+ vax=(slap pit gen) - +>.^$(bud vax) - %_ +>.^$ + soul(bud vax) + %_ soul vanes |- ^+ vanes ?~ vanes - ~& [%vane `@tas`lal.fav pax.fav `@p`(mug txt.fav)] - =+ vin=(vint who lal.fav vil bud pax.fav txt.fav) - ?~ vin - vanes - [[lal.fav vane:u.vin] vanes] + ~> %slog.[0 leaf+"vane: {} {(scow p+(mug txt.fav))}"] + =/ vin (vint who lal.fav vil bud pax.fav txt.fav) + [[lal.fav vane.vin] vanes] ?. =(lal.fav label.i.vanes) [i.vanes $(vanes t.vanes)] - ~& [%vane `@tas`lal.fav pax.fav `@p`(mug txt.fav)] + ~> %slog.[0 leaf+"vane: {} {(scow p+(mug txt.fav))}"] :_ t.vanes :- label.i.vanes - ~| [%failed-vane-activation now lal.fav] - vane:(ruck:(vent who lal.fav vil bud [vase.vane.i.vanes *worm]) pax.fav txt.fav) + ~| [%failed-vane-activation lal.fav] + =< vane + %. [pax txt]:fav + ruck:(vent who lal.fav vil bud [vase.vane.i.vanes *worm]) == +:: +wish: external compute :: -++ wish :: external compute +++ wish |= txt/@ q:(slap bud (ream txt)) -- diff --git a/pkg/arvo/sys/hoon.hoon b/pkg/arvo/sys/hoon.hoon index 209d54ca48..824b3a2cd2 100644 --- a/pkg/arvo/sys/hoon.hoon +++ b/pkg/arvo/sys/hoon.hoon @@ -12015,9 +12015,17 @@ =+ gun=(~(mint ut typ) %noun gen) [p.gun (slum q.gat q.sam)] :: +:: +slab: states whether you can access an arm in a type. +:: +:: -- way: the access type ($vial): read, write, or read-and-write. +:: The fourth case of $vial, %free, is not permitted because it would +:: allow you to discover "private" information about a type, +:: information which you could not make use of in (law-abiding) hoon anyway. +:: ++ slab :: test if contains - |= {cog/@tas typ/type} - =(& -:(~(find ut typ) %free [cog ~])) + |= [way=?(%read %rite %both) cog=@tas typ=type] + ?= [%& *] + (~(fond ut typ) way ~[cog]) :: ++ slap |= {vax/vase gen/hoon} ^- vase :: untyped vase .* @@ -14361,11 +14369,10 @@ ++ ride :: end-to-end compiler |= {typ/type txt/@} ^- (pair type nock) - ~> %slog.[0 leaf/"ride-parsing"] + ~> %slog.[0 leaf/"ride: parsing"] =/ gen (ream txt) - ~> %slog.[0 leaf/"ride-compiling"] - =- ~> %slog.[0 leaf/"ride-compiled"] - - + ~> %slog.[0 leaf/"ride: compiling"] + ~< %slog.[0 leaf/"ride: compiled"] (~(mint ut typ) %noun gen) :: :::: 5e: caching compiler diff --git a/pkg/arvo/sys/vane/ames.hoon b/pkg/arvo/sys/vane/ames.hoon index 0baaccccac..acfe13b8bb 100644 --- a/pkg/arvo/sys/vane/ames.hoon +++ b/pkg/arvo/sys/vane/ames.hoon @@ -376,6 +376,16 @@ veb=_veb-all-off == :: ++$ queued-event-1 + $% [%call =duct type=* wrapped-task=(hobo task-1)] + [%take =wire =duct type=* =sign] + == +:: ++$ task-1 + $% [%wegh ~] + task + == +:: +$ ames-state-1 $: peers=(map ship ship-state-1) =unix=duct @@ -520,45 +530,81 @@ :: lifecycle arms; mostly pass-throughs to the contained adult ames :: ++ scry scry:adult-core - ++ stay [%3 %larva queued-events ames-state.adult-gate] + ++ stay [%4 %larva queued-events ames-state.adult-gate] ++ load + |^ |= $= old - $% $: %3 - $% [%larva events=_queued-events state=_ames-state.adult-gate] + $% $: %4 + $% $: %larva + events=(qeu queued-event) + state=_ames-state.adult-gate + == + [%adult state=_ames-state.adult-gate] + == == + :: + $: %3 + $% $: %larva + events=(qeu queued-event-1) + state=_ames-state.adult-gate + == [%adult state=_ames-state.adult-gate] == == :: $: %2 - $% [%larva events=_queued-events state=ames-state-2] + $% [%larva events=(qeu queued-event-1) state=ames-state-2] [%adult state=ames-state-2] == == :: - $% [%larva events=_queued-events state=ames-state-1] + $% [%larva events=(qeu queued-event-1) state=ames-state-1] [%adult state=ames-state-1] == == ?- old + [%4 %adult *] (load:adult-core %4 state.old) [%3 %adult *] (load:adult-core %3 state.old) [%2 %adult *] (load:adult-core %2 state.old) [%adult *] (load:adult-core %1 state.old) :: - [%3 %larva *] + [%4 %larva *] ~> %slog.1^leaf/"ames: larva: load" =. queued-events events.old + =. adult-gate (load:adult-core %4 state.old) + larval-gate + :: + [%3 %larva *] + ~> %slog.1^leaf/"ames: larva: load" + =. queued-events (queued-events-1-to-4 events.old) =. adult-gate (load:adult-core %3 state.old) larval-gate :: [%2 %larva *] ~> %slog.1^leaf/"ames: larva: load" - =. queued-events events.old + =. queued-events (queued-events-1-to-4 events.old) =. adult-gate (load:adult-core %2 state.old) larval-gate :: [%larva *] ~> %slog.0^leaf/"ames: larva: load" - =. queued-events events.old + =. queued-events (queued-events-1-to-4 events.old) =. adult-gate (load:adult-core %1 state.old) larval-gate == + :: + ++ queued-events-1-to-4 + |= events=(qeu queued-event-1) + ^- (qeu queued-event) + %- ~(gas to *(qeu queued-event)) + ^- (list queued-event) + %+ murn ~(tap to events) + |= e=queued-event-1 + ^- (unit queued-event) + ?. ?=(%call -.e) + `e + ?: ?=([%wegh ~] wrapped-task.e) + ~ + ?: ?=([%soft %wegh ~] wrapped-task.e) + ~ + `e + -- -- :: adult ames, after metamorphosis from larva :: @@ -602,7 +648,6 @@ %stir (on-stir:event-core arg.task) %trim on-trim:event-core %vega on-vega:event-core - %wegh on-wegh:event-core %plea (on-plea:event-core [ship plea]:task) == :: @@ -634,7 +679,7 @@ [moves ames-gate] :: +stay: extract state before reload :: -++ stay [%3 %adult ames-state] +++ stay [%4 %adult ames-state] :: +load: load in old state after reload :: ++ load @@ -642,13 +687,15 @@ $% [%1 ames-state-1] [%2 ames-state-2] [%3 ^ames-state] + [%4 ^ames-state] == |^ ^+ ames-gate :: =? old-state ?=(%1 -.old-state) %2^(state-1-to-2 +.old-state) =? old-state ?=(%2 -.old-state) %3^(state-2-to-3 +.old-state) + =? old-state ?=(%3 -.old-state) %4^+.old-state :: - ?> ?=(%3 -.old-state) + ?> ?=(%4 -.old-state) ames-gate(ames-state +.old-state) :: ++ state-1-to-2 @@ -702,6 +749,13 @@ ?. =(%$ ren) [~ ~] ?. =([%& our] why) [~ ~] + ?: =(tyl /whey) + =/ maz=(list mass) + =+ [known alien]=(skid ~(val by peers.ames-state) |=(^ =(%known +<-))) + :~ peers-known+&+known + peers-alien+&+alien + == + ``mass+!>(maz) ?+ syd ~ %peers ?^ tyl [~ ~] @@ -1375,20 +1429,6 @@ ^+ event-core :: (emit unix-duct.ames-state %give %turf turfs) - :: +on-wegh: produce memory usage report - :: - ++ on-wegh - ^+ event-core - :: - =+ [known alien]=(skid ~(val by peers.ames-state) |=(^ =(%known +<-))) - :: - %- emit - :^ duct %give %mass - :+ %ames %| - :~ peers-known+&+known - peers-alien+&+alien - dot+&+ames-state - == :: +on-born: handle unix process restart :: ++ on-born @@ -1404,9 +1444,10 @@ (emit unix-duct.ames-state %give %turf turfs) :: +on-trim: handle request to free memory :: +on-vega: handle kernel reload + :: +on-trim: handle request to free memory :: - ++ on-trim event-core ++ on-vega event-core + ++ on-trim event-core :: +enqueue-alien-todo: helper to enqueue a pending request :: :: Also requests key and life from Jael on first request. @@ -2963,16 +3004,13 @@ |= [=symmetric-key plaintext=shut-packet] ^- @ :: - =. meat.plaintext - ?. ?& ?=(%& -.meat.plaintext) - (gth (met 13 fragment.p.meat.plaintext) 1) - == - meat.plaintext - %= meat.plaintext + =? meat.plaintext + ?& ?=(%& -.meat.plaintext) + (gth (met 13 fragment.p.meat.plaintext) 1) + == + %_ meat.plaintext fragment.p - %^ end 13 1 - %^ rsh 13 fragment-num.p.meat.plaintext - fragment.p.meat.plaintext + (cut 13 [[fragment-num 1] fragment]:p.meat.plaintext) == (en:crub:crypto symmetric-key (jam plaintext)) :: +decrypt: decrypt packet content to a $shut-packet or die diff --git a/pkg/arvo/sys/vane/behn.hoon b/pkg/arvo/sys/vane/behn.hoon index a9dcfa8b7c..380f8d1b66 100644 --- a/pkg/arvo/sys/vane/behn.hoon +++ b/pkg/arvo/sys/vane/behn.hoon @@ -140,16 +140,6 @@ :: =< set-unix-wake (emit-vane-wake(timers.state later-timers) duct.timer ~) - :: +wegh: produce memory usage report for |mass - :: - ++ wegh - ^+ [moves state] - :_ state :_ ~ - :^ duct %give %mass - :+ %behn %| - :~ timers+&+timers.state - dot+&+state - == :: %utilities :: ::+| @@ -301,7 +291,6 @@ %vega vega:event-core %wait (wait:event-core date=p.task) %wake (wake:event-core error=~) - %wegh wegh:event-core == [moves behn-gate] :: +load: migrate an old state to a new behn version @@ -392,6 +381,11 @@ :: ?. ?=(%& -.why) ~ + ?: &(=(ren %$) =(tyl /whey)) + =/ maz=(list mass) + :~ timers+&+timers.state + == + ``mass+!>(maz) ?. ?=(%timers syd) [~ ~] =/ tiz=(list [@da duct]) diff --git a/pkg/arvo/sys/vane/clay.hoon b/pkg/arvo/sys/vane/clay.hoon index d4c08fd220..1389d79f8a 100644 --- a/pkg/arvo/sys/vane/clay.hoon +++ b/pkg/arvo/sys/vane/clay.hoon @@ -88,6 +88,8 @@ hit/(map aeon tako) :: versions by id lab/(map @tas aeon) :: labels mim/(map path mime) :: mime cache + fod/ford-cache :: ford cache + fer/(unit reef-cache) :: reef cache == :: :: :: Commit state. @@ -107,6 +109,21 @@ mut/(list (trel path lobe cage)) :: mutations == :: :: +:: Ford cache +:: ++$ ford-cache + $: vases=(map path [res=vase dez=(set path)]) + marks=(map mark [res=dais dez=(set path)]) + casts=(map mars [res=tube dez=(set path)]) + == +:: $reef-cache: built system files +:: ++$ reef-cache + $: hoon=vase + arvo=vase + zuse=vase + == +:: :: Hash of a blob, for lookup in the object store (lat.ran) :: ++ lobe @uvI :: blob ref @@ -134,8 +151,7 @@ :: location). :: -- `hez` is the unix duct that %ergo's should be sent to. :: -- `cez` is a collection of named permission groups. -:: -- `cue` is a queue of requests to perform in later events. -:: -- `tip` is the date of the last write; if now, enqueue incoming requests. +:: -- `pud` is an update that's waiting on a kernel upgrade :: ++ raft :: filesystem $: rom=room :: domestic @@ -144,46 +160,10 @@ mon=(map term beam) :: mount points hez=(unit duct) :: sync duct cez=(map @ta crew) :: permission groups - cue=(qeu [=duct =task:able]) :: queued requests - act=active-write :: active write + pud=(unit [=desk =yoki]) :: pending update + pun=(list move) :: upgrade moves == :: :: -:: Currently active write -:: -++ active-write - %- unit - $: hen=duct - req=task:able - $= eval-data - $% [%commit commit=eval-form:eval:commit-clad] - [%merge merge=eval-form:eval:merge-clad] - [%mount mount=eval-form:eval:mount-clad] - == - == -:: -:: The clad monad for commits. -:: -:: -- `dome` is the new dome -- each writer has a lock on the dome for -:: that desk -:: -- `rang` is a superset of the global rang, but we uni:by it into -:: the global rang because other things might add stuff to it. -:: Thus, writers do *not* have a lock on the global rang. -:: -++ commit-clad (clad ,[dome rang]) -:: -:: The clad monad for merges. -:: -:: Same as +commit-clad, except includes a set of paths documenting the -:: conflicts encountered in the merge. -:: -++ merge-clad (clad ,[(set path) dome rang]) -:: -:: The clad monad for mounts. -:: -:: Just a new mount point and mime cache. -:: -++ mount-clad (clad ,[new-mon=(pair term beam) mim=(map path mime)]) -:: :: Object store. :: :: Maps of commit hashes to commits and content hashes to content. @@ -239,8 +219,6 @@ bom/(map @ud {p/duct q/rave}) :: outstanding fod/(map duct @ud) :: current requests haw/(map mood (unit cage)) :: simple cache - pud/update-qeu :: active updates - pur/request-map :: active requests == :: :: :: Result of a subscription @@ -253,22 +231,6 @@ [%blub ~] == :: -:: The clad monad for foreign updates. -:: -:: Same as +commit-clad, except includes `lim`, as in +rede. Null if -:: subscription ended. -:: -++ update-clad (clad ,(unit [lim=@da dome rang])) -++ update-qeu - $: waiting=(qeu [inx=@ud rut=(unit rand)]) - eval-data=(unit [inx=@ud rut=(unit rand) =eval-form:eval:update-clad]) - == -:: -:: The clad monad for foreign simple requests -:: -++ request-clad (clad ,cage) -++ request-map ,(map inx=@ud [=rand =eval-form:eval:request-clad]) -:: :: Domestic ship. :: :: `hun` is the duct to dill, and `dos` is a collection of our desks. @@ -303,170 +265,6 @@ $: rus=(map desk rede) :: neighbor desks == :: -:: Hash of a commit, for lookup in the object store (hut.ran) -:: -++ tako @ :: yaki ref -:: -:: Commit. -:: -:: List of parents, content, hash of self, and time commited. -:: -++ yaki :: snapshot - $: p/(list tako) :: parents - q/(map path lobe) :: fileset - r/tako :: - :: :: XX s? - t/@da :: date - == :: -:: -:: Unvalidated blob -:: -++ plop blob :: unvalidated blob -:: -:: The clay monad, for easier-to-follow state machines. -:: -:: The best way to think about a clad is that it's a transaction that -:: may take multiple arvo events, and may send notes to other vanes to -:: get information. -:: -+$ clad-input [now=@da new-rang=rang =sign] -:: -:: notes: notes to send immediately. These will go out even if a -:: later stage of the process fails, so they shouldn't have any -:: semantic effect on the rest of the system. Path is -:: included exclusively for documentation and |verb. -:: effects: moves to send after the process ends. -:: wait: don't move on, stay here. The next sign should come back -:: to this same callback. -:: cont: continue process with new callback. -:: fail: abort process; don't send effects -:: done: finish process; send effects -:: -++ clad-output-raw - |* a=mold - $~ [~ ~ %done *a] - $: notes=(list [path note]) - effects=(list move) - $= next - $% [%wait ~] - [%cont self=(clad-form-raw a)] - [%fail err=(pair term tang)] - [%done value=a] - == - == -:: -++ clad-form-raw - |* a=mold - $-(clad-input (clad-output-raw a)) -:: -++ clad-fail - |= err=(pair term tang) - |= clad-input - [~ ~ %fail err] -:: -++ clad-init-sign `sign`[%y %init-clad ~] -:: -++ clad - |* a=mold - |% - ++ output (clad-output-raw a) - ++ form (clad-form-raw a) - ++ pure - |= arg=a - ^- form - |= clad-input - [~ ~ %done arg] - :: - ++ bind - |* b=mold - |= [m-b=(clad-form-raw b) fun=$-(b form)] - ^- form - |= input=clad-input - =/ b-res=(clad-output-raw b) - (m-b input) - ^- output - :+ notes.b-res effects.b-res - ?- -.next.b-res - %wait [%wait ~] - %cont [%cont ..$(m-b self.next.b-res)] - %fail [%fail err.next.b-res] - %done [%cont (fun value.next.b-res)] - == - :: - :: The clad monad must be evaluted in a particular way to maintain - :: its monadic character. +take:eval implements this. - :: - ++ eval - |% - :: Indelible state of a clad - :: - +$ eval-form - $: effects=(list move) - =form - == - :: - :: Convert initial form to eval-form - :: - ++ from-form - |= =form - ^- eval-form - [~ form] - :: - :: The cases of results of +take - :: - +$ eval-result - $% [%next ~] - [%fail err=(pair term tang)] - [%done value=a] - == - :: - :: Take a new sign and run the clad against it - :: - ++ take - :: moves: accumulate throughout recursion the moves to be - :: produced now - =| moves=(list move) - |= [=eval-form =duct =our=wire =clad-input] - ^- [[(list move) =eval-result] _eval-form] - :: run the clad callback - :: - =/ =output (form.eval-form clad-input) - :: add notes to moves - :: - =. moves - %+ welp - moves - %+ turn notes.output - |= [=path =note] - [duct %pass (weld our-wire path) note] - :: add effects to list to be produced when done - :: - =. effects.eval-form - (weld effects.eval-form effects.output) - :: if done, produce effects - :: - =? moves ?=(%done -.next.output) - %+ welp - moves - effects.eval-form - :: case-wise handle next steps - :: - ?- -.next.output - %wait [[moves %next ~] eval-form] - %fail [[moves %fail err.next.output] eval-form] - %done [[moves %done value.next.output] eval-form] - %cont - :: recurse to run continuation with initialization move - :: - %_ $ - form.eval-form self.next.output - sign.clad-input clad-init-sign - == - == - -- - -- -:: -:: ++ move {p/duct q/(wind note gift:able)} :: local move ++ note :: out request $-> $~ [%b %wait *@da] :: @@ -483,6 +281,7 @@ $: %c :: to %clay $> $? %info :: internal edit %merg :: merge desks + %pork :: %warp :: %werp :: == :: @@ -491,12 +290,8 @@ $: %d :: to %dill $>(%flog task:able:dill) :: == :: - $: %f :: to %ford - $> $? %build :: - %keep :: - %wipe :: - == :: - task:able:ford :: + $: %g :: to %gall + $>(%deal task:able:gall) :: == :: $: %j :: by %jael $>(%public-keys task:able:jael) :: @@ -504,10 +299,7 @@ ++ riot (unit rant) :: response+complete ++ sign :: in result $<- $~ [%b %wake ~] :: - $% $: %y :: - $% [%init-clad ~] :: - == == :: - $: %a :: by %ames + $% $: %a :: by %ames $> $? %boon :: response %done :: (n)ack %lost :: lost boon @@ -525,9 +317,6 @@ == :: gift:able :: == :: - $: %f :: by %ford - $>(%made gift:able:ford) :: - == :: $: %j :: by %jael $>(%public-keys gift:able:jael) :: == :: @@ -544,49 +333,52 @@ ++ sort-by-head |=([a=(pair path *) b=(pair path *)] (aor p.a p.b)) :: -:: Just send a note. +:: By convention: paf == (weld pax pat) :: -++ just-do - |= [=path =note] - =/ m (clad ,~) - ^- form:m - |= clad-input - [[path note]~ ~ %done ~] -:: -:: Wait for ford to respond -:: -++ expect-ford - =/ m (clad ,made-result:ford) - ^- form:m - |= clad-input - ?: ?=(%init-clad +<.sign) - [~ ~ %wait ~] - ?: ?=(%made +<.sign) - [~ ~ %done result.sign] - ~| [%expected-made got=+<.sign] - !! -:: -:: Wait for clay to respond -:: -:: This setup where we take in a new-rang in +clad-input but only -:: apply it when calling +expect-clay is suspicious. I'm not sure -:: what's the best approach to reading in potentially new state that -:: we also may have changed but haven't committed. -:: -++ expect-clay - |= ran=rang - =/ m (clad ,[riot rang]) - ^- form:m - |= clad-input - ?: ?=(%init-clad +<.sign) - [~ ~ %wait ~] - ?: ?=(%writ +<.sign) - =/ uni-rang=rang - :- (~(uni by hut.new-rang) hut.ran) - (~(uni by lat.new-rang) lat.ran) - [~ ~ %done p.sign uni-rang] - ~| [%expected-writ got=+<.sign] - !! +++ mode-to-commit + |= [hat=(map path lobe) pax=path all=? mod=mode] + ^- [deletes=(set path) changes=(map path cage)] + =/ deletes + %- silt + %+ turn + ^- (list path) + %+ weld + ^- (list path) + %+ murn mod + |= [pat=path mim=(unit mime)] + ^- (unit path) + ?^ mim + ~ + `pat + ^- (list path) + ?. all + ~ + =+ mad=(malt mod) + =+ len=(lent pax) + =/ descendants=(list path) + %+ turn + %+ skim ~(tap by hat) + |= [paf=path lob=lobe] + =(pax (scag len paf)) + |= [paf=path lob=lobe] + (slag len paf) + %+ skim + descendants + |= pat=path + (~(has by mad) pat) + |= pat=path + (weld pax pat) + :: + =/ changes + %- malt + %+ murn mod + |= [pat=path mim=(unit mime)] + ^- (unit [path cage]) + ?~ mim + ~ + `[(weld pax pat) %mime !>(u.mim)] + :: + [deletes changes] -- => ~% %clay + ~ |% @@ -610,1980 +402,514 @@ |= [=wove ducts=(set duct)] [ducts (print-wove wove)] :: -:: -:: Make a new commit with the given +nori of changes. -:: -++ commit - :: Global constants. These do not change during a commit. - :: - |= $: our=ship - syd=desk - wen=@da - mon=(map term beam) - hez=(unit duct) - hun=duct - == - |^ - :: Initial arguments - :: - |= [lem=nori original-dome=dome ran=rang] - =/ m commit-clad - ^- form:m - ?: ?=(%| -.lem) - :: If the change is just adding a label, handle it directly. - :: - =. original-dome - (execute-label:(state:util original-dome original-dome ran) p.lem) - =/ e (cor original-dome ran) - ;< ~ bind:m (print-changes:e %| p.lem) - (pure:m dom:e ran:e) - :: - :: Else, collect the data, apply it, fill in our local cache, let - :: unix know, and print a notification to the screen. - :: - =/ e (cor original-dome ran) - ;< [=dork mim=(map path mime)] bind:m (fill-dork:e wen p.lem) - ;< [=suba e=_*cor] bind:m (apply-dork:e wen dork) - ;< e=_*cor bind:m checkout-new-state:e - ;< mim=(map path mime) bind:m (ergo-changes:e suba mim) - ;< ~ bind:m (print-changes:e %& suba) - =. mim.dom.e mim - (pure:m dom:e ran:e) - :: - :: A stateful core, where the global state is a dome and a rang. - :: - :: These are the global state variables that an edit may change. - :: - ++ cor - |= [dom=dome ran=rang] - =/ original-dome dom - |% - ++ this-cor . - ++ sutil (state:util original-dome dom ran) - :: - :: Collect all the insertions, deletions, diffs, and mutations - :: which are requested. - :: - :: Sends them through ford for casting, patching, and diffing so - :: that the produced dork has all the relevant cages filled in. - :: - :: Also fills in the mime cache. Often we need to convert to mime - :: anyway to send (back) to unix, so we just keep it around rather - :: than recalculating it. This is less necessary than before - :: because of the ford cache. - :: - ++ fill-dork - |= [wen=@da =soba] - =/ m (clad ,[=dork mim=(map path mime)]) - ^- form:m - =| $= nuz - $: del=(list (pair path miso)) - ins=(list (pair path miso)) - dif=(list (pair path miso)) - mut=(list (pair path miso)) - ink=(list (pair path miso)) - == - :: - =. nuz - |- ^+ nuz - ?~ soba nuz - :: - ?- -.q.i.soba - %del $(soba t.soba, del.nuz [i.soba del.nuz]) - %dif $(soba t.soba, dif.nuz [i.soba dif.nuz]) - %ins - =/ pax=path p.i.soba - =/ mar=mark p.p.q.i.soba - :: - :: We store `%hoon` files directly to `ink` so that we add - :: them without requiring any mark definitions. `%hoon` - :: files have to be treated specially to make the - :: bootstrapping sequence work, since the mark definitions - :: are themselves `%hoon` files. - :: - ?: ?& ?=([%hoon *] (flop pax)) - ?=(%mime mar) - == - $(soba t.soba, ink.nuz [i.soba ink.nuz]) - $(soba t.soba, ins.nuz [i.soba ins.nuz]) - :: - %mut - =/ pax=path p.i.soba - =/ mis=miso q.i.soba - ?> ?=(%mut -.mis) - =/ cag=cage p.mis - :: if :mis has the %mime mark and it's the same as cached, no-op - :: - ?: ?. =(%mime p.cag) - %.n - ?~ cached=(~(get by mim.dom) pax) - %.n - =(q:;;(mime q.q.cag) q.u.cached) - :: - $(soba t.soba) - :: if the :mis mark is the target mark and the value is the same, no-op - :: - ?: =/ target-mark=mark =+(spur=(flop pax) ?~(spur !! i.spur)) - ?. =(target-mark p.cag) - %.n - :: - =/ stored (need (need (read-x:sutil & let.dom pax))) - =/ stored-cage=cage ?>(?=(%& -.stored) p.stored) - :: - =(q.q.stored-cage q.q.cag) - :: - $(soba t.soba) - :: the value differs from what's stored, so register mutation - :: - $(soba t.soba, mut.nuz [i.soba mut.nuz]) - == - :: sort each section alphabetically for determinism - :: - =. nuz :* - (sort del.nuz sort-by-head) - (sort ins.nuz sort-by-head) - (sort dif.nuz sort-by-head) - (sort mut.nuz sort-by-head) - (sort ink.nuz sort-by-head) - == - =/ ink - %+ turn ink.nuz - |= {pax/path mis/miso} - ^- (pair path cage) - ?> ?=($ins -.mis) - =+ =>((flop pax) ?~(. %$ i)) - [pax - [%atom %t ~] ;;(@t +>.q.q.p.mis)] - :: - =/ mim - :: add the new files to the new mime cache - :: - %- malt - ^- (list (pair path mime)) - ;: weld - ^- (list (pair path mime)) - %+ murn ins.nuz - |= {pax/path mis/miso} - ^- (unit (pair path mime)) - ?> ?=($ins -.mis) - ?. ?=($mime p.p.mis) - ~ - `[pax ;;(mime q.q.p.mis)] - :: - ^- (list (pair path mime)) - %+ murn ink.nuz - |= {pax/path mis/miso} - ^- (unit (pair path mime)) - ?> ?=($ins -.mis) - ?> ?=($mime p.p.mis) - `[pax ;;(mime q.q.p.mis)] - :: - ^- (list (pair path mime)) - %+ murn mut.nuz - |= {pax/path mis/miso} - ^- (unit (pair path mime)) - ?> ?=($mut -.mis) - ?. ?=($mime p.p.mis) - ~ - `[pax ;;(mime q.q.p.mis)] - == - :: - ;< ins=(list (pair path cage)) bind:m (calc-inserts wen ins.nuz) - ;< dif=(list (trel path lobe cage)) bind:m (calc-diffs wen dif.nuz) - ;< mut=(list (trel path lobe cage)) bind:m (calc-mutates wen mut.nuz) - %+ pure:m - ^- dork - [del=(turn del.nuz head) ink ins dif mut] - mim - :: - :: Build the list of insertions by casting to the correct mark. - :: - ++ calc-inserts - |= [wen=@da ins=(list (pair path miso))] - =/ m (clad (list (pair path cage))) - ^- form:m - ;< ~ bind:m - %+ just-do /inserts - :* %f %build live=%.n %pin wen %list - ^- (list schematic:ford) - %+ turn ins - |= [pax=path mis=miso] - ?> ?=($ins -.mis) - :- [%$ %path -:!>(*path) pax] - =+ =>((flop pax) ?~(. %$ i)) - [%cast [our syd] - [%$ p.mis]] - == - ;< res=made-result:ford bind:m expect-ford - ^- form:m - |= clad-input - :^ ~ ~ %done - ^- (list (pair path cage)) - %+ turn (made-result-to-success-cages:util res) - |= {pax/cage cay/cage} - ?. ?=($path p.pax) - ~|(%clay-take-inserting-strange-path-mark !!) - [;;(path q.q.pax) cay] - :: - :: Build the list of diffs by apply the given diffs to the existing - :: data. - :: - ++ calc-diffs - |= [wen=@da dif=(list (pair path miso))] - =/ m (clad (list (trel path lobe cage))) - ^- form:m - ;< ~ bind:m - %+ just-do /diffs - :* %f %build live=%.n %pin wen %list - ^- (list schematic:ford) - %+ turn dif - |= {pax/path mis/miso} - ?> ?=($dif -.mis) - =+ (need (need (read-x:sutil & let.dom pax))) - ?> ?=(%& -<) - :- [%$ %path -:!>(*path) pax] - [%pact [our syd] [%$ p.-] [%$ p.mis]] - == - ;< res=made-result:ford bind:m expect-ford - ^- form:m - |= clad-input - :^ ~ ~ %done - ^- (list (trel path lobe cage)) - =/ dig=(map path cage) - %- malt - (turn dif |=({pax/path mis/miso} ?>(?=($dif -.mis) [pax p.mis]))) - %+ turn (made-result-to-cages:util res) - |= {pax/cage cay/cage} - ^- (pair path (pair lobe cage)) - ?. ?=($path p.pax) - ~|(%clay-take-diffing-strange-path-mark !!) - =+ paf=;;(path q.q.pax) - [paf (page-to-lobe:sutil [p q.q]:cay) (~(got by dig) paf)] - :: - :: Build the list of mutations by casting to the correct mark and - :: diffing against the existing data. - :: - ++ calc-mutates - |= [wen=@da mut=(list (pair path miso))] - =/ m (clad (list (trel path lobe cage))) - ^- form:m - ;< ~ bind:m - %+ just-do /casts - :* %f %build live=%.n %pin wen %list - ::~ [her syd %da wen] %tabl - ^- (list schematic:ford) - %+ turn mut - |= {pax/path mis/miso} - ?> ?=($mut -.mis) - :- [%$ %path -:!>(*path) pax] - =/ mar - %- lobe-to-mark:sutil - (~(got by q:(aeon-to-yaki:sutil let.dom)) pax) - [%cast [our syd] mar [%$ p.mis]] - == - ;< res=made-result:ford bind:m expect-ford - ;< hashes=(map path lobe) bind:m - |= clad-input - =/ cat=(list (pair path cage)) - %+ turn (made-result-to-cages:util res) - |= {pax/cage cay/cage} - ?. ?=($path p.pax) - ~|(%castify-bad-path-mark !!) - [;;(path q.q.pax) cay] - :_ :+ ~ %done - ^- (map path lobe) - %- malt - %+ turn cat - |= {pax/path cay/cage} - [pax (page-to-lobe:sutil [p q.q]:cay)] - ^- (list [path note]) - :_ ~ - :* /mutates - %f %build live=%.n %pin wen %list - ^- (list schematic:ford) - %+ turn cat - |= {pax/path cay/cage} - :- [%$ %path -:!>(*path) pax] - =/ scheme - %^ lobe-to-schematic:sutil [our syd] pax - (~(got by q:(aeon-to-yaki:sutil let.dom)) pax) - [%diff [our syd] scheme [%$ cay]] - == - ;< res=made-result:ford bind:m expect-ford - %- pure:m - ^- (list (trel path lobe cage)) - %+ murn (made-result-to-cages:util res) - |= {pax/cage cay/cage} - ^- (unit (pair path (pair lobe cage))) - ?. ?=($path p.pax) - ~|(%clay-take-mutating-strange-path-mark !!) - ?: ?=($null p.cay) - ~ - =+ paf=;;(path q.q.pax) - `[paf (~(got by hashes) paf) cay] - :: - :: Collect the relevant data from dok and run +execute-changes to - :: apply them to our state. - :: - ++ apply-dork - |= [wen=@da =dork] - =/ m (clad ,[=suba _this-cor]) - ^- form:m - =/ sim=(list (pair path misu)) - ;: weld - ^- (list (pair path misu)) - (turn del.dork |=(pax/path [pax %del ~])) - :: - ^- (list (pair path misu)) - (turn ink.dork |=({pax/path cay/cage} [pax %ins cay])) - :: - ^- (list (pair path misu)) - (turn ins.dork |=({pax/path cay/cage} [pax %ins cay])) - :: - ^- (list (pair path misu)) - (turn dif.dork |=({pax/path cal/{lobe cage}} [pax %dif cal])) - :: - ^- (list (pair path misu)) - (turn mut.dork |=({pax/path cal/{lobe cage}} [pax %dif cal])) - == - =/ res=(unit [=dome =rang]) - (execute-changes:sutil wen sim) - ?~ res - (clad-fail %dork-fail ~) - =: dom dome.u.res - ran rang.u.res - == - (pure:m sim this-cor) - :: - :: Take the map of paths to lobes, convert to blobs, and save the - :: resulting ankh to the dome. - :: - ++ checkout-new-state - =/ m (clad ,_this-cor) - ^- form:m - ;< ~ bind:m - %+ just-do /checkout - =/ new-yaki (aeon-to-yaki:sutil let.dom) - :* %f %build live=%.n %list - ^- (list schematic:ford) - %+ turn (sort ~(tap by q.new-yaki) sort-by-head) - |= {a/path b/lobe} - ^- schematic:ford - :- [%$ %path-hash !>([a b])] - (lobe-to-schematic:sutil [our syd] a b) - == - ;< res=made-result:ford bind:m expect-ford - ?. ?=([%complete %success *] res) - =/ message (made-result-as-error:ford res) - (clad-fail %checkout-fail leaf+"clay patch failed" message) - :: - =/ cat/(list (trel path lobe cage)) - %+ turn (made-result-to-cages:util res) - |= {pax/cage cay/cage} - ?. ?=($path-hash p.pax) - ~|(%patch-bad-path-mark !!) - [-< -> +]:[;;({path lobe} q.q.pax) cay] - =. ank.dom (map-to-ankh:sutil (malt cat)) - (pure:m this-cor) - :: - :: Choose which changes must be synced to unix, and do so. We - :: convert to mime before dropping the ergo event to unix. - :: - ++ ergo-changes - |= [=suba mim=(map path mime)] - =/ m (clad ,mim=(map path mime)) - ^- form:m - ?~ hez (pure:m mim) - =+ must=(must-ergo:util our syd mon (turn suba head)) - ?: =(~ must) - (pure:m mim) - =/ all-paths/(set path) - %+ roll - (turn ~(tap by must) (corl tail tail)) - |= {pak/(set path) acc/(set path)} - (~(uni in acc) pak) - =/ changes (malt suba) - ;< ~ bind:m - %+ just-do /ergo - :* %f %build live=%.n %list - ^- (list schematic:ford) - %+ turn ~(tap in all-paths) - |= a/path - ^- schematic:ford - :- [%$ %path !>(a)] - =+ b=(~(got by changes) a) - ?: ?=($del -.b) - [%$ %null !>(~)] - =+ (~(get by mim) a) - ?^ - [%$ %mime !>(u.-)] - :^ %cast [our syd] %mime - =/ x (need (need (read-x:sutil & let.dom a))) - ?: ?=(%& -<) - [%$ p.x] - (lobe-to-schematic:sutil [our syd] a p.x) - == - ;< res=made-result:ford bind:m expect-ford - ?: ?=([%incomplete *] res) - (clad-fail %ergo-fail-incomplete leaf+"clay ergo incomplete" tang.res) - ?. ?=([%complete %success *] res) - (clad-fail %ergo-fail leaf+"clay ergo failed" message.build-result.res) - =/ changes=(map path (unit mime)) - %- malt ^- mode - %+ turn (made-result-to-cages:util res) - |= [pax=cage mim=cage] - ?. ?=($path p.pax) - ~|(%ergo-bad-path-mark !!) - :- ;;(path q.q.pax) - ?. ?=($mime p.mim) - ~ - `;;(mime q.q.mim) - =. mim (apply-changes-to-mim:util mim changes) - ;< ~ bind:m (give-ergo:util u.hez our syd mon changes) - (pure:m mim) - :: - :: Print a summary of changes to dill. - :: - ++ print-changes - |= lem=nuri - =/ m (clad ,~) - ^- form:m - :: skip full change output for initial filesystem - :: - ?: ?& =(%base syd) - |(=(1 let.dom) =(2 let.dom)) - ?=([%& ^] lem) - == - =/ msg=tape - %+ weld - "clay: committed initial filesystem" - ?:(=(1 let.dom) " (hoon)" " (all)") - |= clad-input - :- ~ :_ [%done ~] - [hun %pass / %d %flog %text msg]~ - :: - =+ pre=`path`~[(scot %p our) syd (scot %ud let.dom)] - ?- -.lem - %| (print-to-dill '=' %leaf :(weld (trip p.lem) " " (spud pre))) - %& - |- ^- form:m - ?~ p.lem (pure:m ~) - ;< ~ bind:m - %+ print-to-dill - ?-(-.q.i.p.lem $del '-', $ins '+', $dif ':') - :+ %rose ["/" "/" ~] - %+ turn (weld pre p.i.p.lem) - |= a/cord - ?: ((sane %ta) a) - [%leaf (trip a)] - [%leaf (dash:us (trip a) '\'' ~)] - ^$(p.lem t.p.lem) - == - :: - :: Send a tank straight to dill for printing. - :: - ++ print-to-dill - |= {car/@tD tan/tank} - =/ m (clad ,~) - ^- form:m - |= clad-input - :- ~ :_ [%done ~] - [hun %give %note car tan]~ - -- - -- -:: -:: This transaction respresents a currently running merge. We always -:: say we're merging from 'ali' to 'bob'. The basic steps, not all of -:: which are always needed, are: -:: -:: -- fetch ali's desk -:: -- diff ali's desk against the mergebase -:: -- diff bob's desk against the mergebase -:: -- merge the diffs -:: -- build the new state -:: -- "checkout" (apply to actual `++dome`) the new state -:: -- "ergo" (tell unix about) any changes -:: -++ merge - :: Global constants. These do not change during a merge. - :: - |= $: our=ship - wen=@da - ali-disc=(pair ship desk) - bob-disc=(pair ship desk) - cas=case - mon=(map term beam) - hez=(unit duct) - == - :: Run ford operations on ali unless it's a foreign desk - :: - =/ ford-disc=disc:ford - ?: =(p.ali-disc p.bob-disc) - ali-disc - bob-disc - |^ - :: Initial arguments - :: - |= [gem=germ dom=dome ran=rang] - =/ m merge-clad - ^- form:m - =/ e (cor dom ran) - ;< [bob=(unit yaki) gem=germ] bind:m (get-bob:e gem) - ;< [ali=yaki e=_*cor] bind:m fetch-ali:e - ;< $= res - %- unit - $: conflicts=(set path) - bop=(map path cage) - new=yaki - erg=(map path ?) - e=_*cor - == - bind:m - (merge:e gem cas ali bob) - ?~ res - :: if no changes, we're done - :: - (pure:m ~ dom:e ran:e) - =. e e.u.res - ;< e=_*cor bind:m (checkout:e gem cas bob new.u.res bop.u.res) - ;< mim=(map path mime) bind:m (ergo:e gem cas mon erg.u.res new.u.res) - =. mim.dom.e mim - (pure:m conflicts.u.res dom:e ran:e) - :: - :: A stateful core, where the global state is a dome and a rang. - :: - :: These are the global state variables that a merge may change. - :: - ++ cor - |= [dom=dome ran=rang] - =/ original-dome dom - |% - ++ this-cor . - ++ sutil (state:util original-dome dom ran) - :: - :: Fetch the local disk, if it's there. - :: - ++ get-bob - |= gem=germ - =/ m (clad ,[bob=(unit yaki) gem=germ]) - ^- form:m - ?: &(=(0 let.dom) !?=(?(%init %that) gem)) - (error:he cas %no-bob-disc ~) - ?: =(0 let.dom) - (pure:m ~ %init) - =/ tak (~(get by hit.dom) let.dom) - ?~ tak - (error:he cas %no-bob-version ~) - =/ bob (~(get by hut.ran) u.tak) - ?~ bob - (error:he cas %no-bob-commit ~) - (pure:m `u.bob gem) - :: - :: Tell clay to get the state at the requested case for ali's desk. - :: - ++ fetch-ali - =/ m (clad ,[ali=yaki e=_this-cor]) - ^- form:m - ;< ~ bind:m - %+ just-do /fetch-ali - [%c %warp p.ali-disc q.ali-disc `[%sing %v cas /]] - ;< [rot=riot r=rang] bind:m (expect-clay ran) - =. ran r - ?~ rot - (error:he cas %bad-fetch-ali ~) - =/ ali-dome - ;; $: ank=* - let=@ud - hit=(map @ud tako) - lab=(map @tas @ud) - == - q.q.r.u.rot - ?: =(0 let.ali-dome) - (error:he cas %no-ali-disc ~) - =/ tak (~(get by hit.ali-dome) let.ali-dome) - ?~ tak - (error:he cas %no-ali-version ~) - =/ ali (~(get by hut.ran) u.tak) - ?~ ali - (error:he cas %no-ali-commit ~) - (pure:m u.ali this-cor) - :: - :: Produce null if nothing to do; else perform merge - :: - ++ merge - |= [gem=germ cas=case ali=yaki bob=(unit yaki)] - =/ m - %- clad - %- unit - $: conflicts=(set path) - bop=(map path cage) - new=yaki - erg=(map path ?) - e=_this-cor - == - ^- form:m - ?- gem - :: - :: If this is an %init merge, we set the ali's commit to be bob's, and - :: we checkout the new state. - :: - $init - %^ pure:m ~ ~ - :^ ~ - ali - (~(run by q.ali) |=(lobe %&)) - this-cor(hut.ran (~(put by hut.ran) r.ali ali)) - :: - :: If this is a %this merge, we check to see if ali's and bob's commits - :: are the same, in which case we're done. Otherwise, we check to see - :: if ali's commit is in the ancestry of bob's, in which case we're - :: done. Otherwise, we create a new commit with bob's data plus ali - :: and bob as parents. - :: - $this - =/ bob (need bob) - ?: =(r.ali r.bob) - (pure:m ~) - ?: (~(has in (reachable-takos:sutil r.bob)) r.ali) - (pure:m ~) - =/ new (make-yaki:sutil [r.ali r.bob ~] q.bob wen) - %^ pure:m ~ ~ - :^ ~ - new - ~ - this-cor(hut.ran (~(put by hut.ran) r.new new)) - :: - :: If this is a %that merge, we check to see if ali's and bob's commits - :: are the same, in which case we're done. Otherwise, we create a new - :: commit with ali's data plus ali and bob as parents. - :: - $that - =/ bob (need bob) - ?: =(r.ali r.bob) - (pure:m ~) - =/ new (make-yaki:sutil [r.ali r.bob ~] q.ali wen) - %^ pure:m ~ ~ - :^ ~ - new - %- malt ^- (list {path ?}) - %+ murn ~(tap by (~(uni by q.bob) q.ali)) - |= {pax/path lob/lobe} - ^- (unit {path ?}) - =+ a=(~(get by q.ali) pax) - =+ b=(~(get by q.bob) pax) - ?: =(a b) - ~ - `[pax !=(~ a)] - this-cor(hut.ran (~(put by hut.ran) r.new new)) - :: - :: If this is a %fine merge, we check to see if ali's and bob's commits - :: are the same, in which case we're done. Otherwise, we check to see - :: if ali's commit is in the ancestry of bob's, in which case we're - :: done. Otherwise, we check to see if bob's commit is in the ancestry - :: of ali's. If not, this is not a fast-forward merge, so we error - :: out. If it is, we add ali's commit to bob's desk and checkout. - :: - $fine - =/ bob (need bob) - ?: =(r.ali r.bob) - (pure:m ~) - ?: (~(has in (reachable-takos:sutil r.bob)) r.ali) - (pure:m ~) - ?. (~(has in (reachable-takos:sutil r.ali)) r.bob) - (error:he cas %bad-fine-merge ~) - %^ pure:m ~ ~ - :^ ~ - ali - %- malt ^- (list {path ?}) - %+ murn ~(tap by (~(uni by q.bob) q.ali)) - |= {pax/path lob/lobe} - ^- (unit {path ?}) - =+ a=(~(get by q.ali) pax) - =+ b=(~(get by q.bob) pax) - ?: =(a b) - ~ - `[pax !=(~ a)] - this-cor - :: - :: If this is a %meet, %mate, or %meld merge, we may need to - :: fetch more data. If this merge is either trivial or a - :: fast-forward, we short-circuit to either ++done or the %fine - :: case. - :: - :: Otherwise, we find the best common ancestor(s) with - :: ++find-merge-points. If there's no common ancestor, we error - :: out. Additionally, if there's more than one common ancestor - :: (i.e. this is a criss-cross merge), we error out. Something - :: akin to git's recursive merge should probably be used here, - :: but it isn't. - :: - :: Once we have our single best common ancestor (merge base), we - :: store it in bas. If this is a %mate or %meld merge, we diff - :: both against the mergebase, merge the conflicts, and build the - :: new commit. - :: - :: Otherwise (i.e. this is a %meet merge), we create a list of - :: all the changes between the mergebase and ali's commit and - :: store it in ali-diffs, and we put a similar list for bob's - :: commit in bob-diffs. Then we create bof, which is the a set - :: of changes in both ali and bob's commits. If this has any - :: members, we have conflicts, which is an error in a %meet - :: merge, so we error out. - :: - :: Otherwise, we merge the merge base data with ali's data and - :: bob's data, which produces the data for the new commit. - :: - ?($meet $mate $meld) - =/ bob (need bob) - ?: =(r.ali r.bob) - (pure:m ~) - ?. (~(has by hut.ran) r.bob) - (error:he cas %bad-bob-tako >r.bob< ~) - ?: (~(has in (reachable-takos:sutil r.bob)) r.ali) - (pure:m ~) - ?: (~(has in (reachable-takos:sutil r.ali)) r.bob) - $(gem %fine) - =+ r=(find-merge-points:he ali bob) - ?~ r - (error:he cas %merge-no-merge-base ~) - ?. ?=({* ~ ~} r) - =+ (lent ~(tap in `(set yaki)`r)) - (error:he cas %merge-criss-cross >[-]< ~) - =/ bas n.r - ?: ?=(?($mate $meld) gem) - ;< ali-diffs=cane bind:m (diff-bas ali bob bas) - ;< bob-diffs=cane bind:m (diff-bas bob ali bas) - ;< bof=(map path (unit cage)) bind:m - (merge-conflicts can.ali-diffs can.bob-diffs) - ;< $: conflicts=(set path) - bop=(map path cage) - new=yaki - erg=(map path ?) - e=_this-cor - == - bind:m - (build gem ali bob bas ali-diffs bob-diffs bof) - (pure:m `[conflicts bop new erg e]) - =/ ali-diffs=cane (calc-diffs:he ali bas) - =/ bob-diffs=cane (calc-diffs:he bob bas) - =/ bof=(map path *) - %- %~ int by - %- ~(uni by `(map path *)`new.ali-diffs) - %- ~(uni by `(map path *)`cal.ali-diffs) - %- ~(uni by `(map path *)`can.ali-diffs) - `(map path *)`old.ali-diffs - %- ~(uni by `(map path *)`new.bob-diffs) - %- ~(uni by `(map path *)`cal.bob-diffs) - %- ~(uni by `(map path *)`can.bob-diffs) - `(map path *)`old.bob-diffs - ?. =(~ bof) - (error:he cas %meet-conflict >~(key by bof)< ~) - =/ old=(map path lobe) - %+ roll ~(tap by (~(uni by old.ali-diffs) old.bob-diffs)) - =< .(old q.bas) - |= {{pax/path ~} old/(map path lobe)} - (~(del by old) pax) - =/ hat=(map path lobe) - %- ~(uni by old) - %- ~(uni by new.ali-diffs) - %- ~(uni by new.bob-diffs) - %- ~(uni by cal.ali-diffs) - cal.bob-diffs - =/ del=(map path ?) - (~(run by (~(uni by old.ali-diffs) old.bob-diffs)) |=(~ %|)) - =/ new (make-yaki:sutil [r.ali r.bob ~] hat wen) - %^ pure:m ~ ~ - :^ ~ - new - %- ~(uni by del) - ^- (map path ?) - %. |=(lobe %&) - ~(run by (~(uni by new.ali-diffs) cal.ali-diffs)) - this-cor(hut.ran (~(put by hut.ran) r.new new)) - == - :: - :: Diff a commit against the mergebase. - :: - ++ diff-bas - |= [yak=yaki yuk=yaki bas=yaki] - =/ m (clad ,cane) - ^- form:m - ;< ~ bind:m - %+ just-do /diff-bas - :* %f %build live=%.n %pin wen - %list - ^- (list schematic:ford) - %+ murn ~(tap by q.bas) - |= {pax/path lob/lobe} - ^- (unit schematic:ford) - =+ a=(~(get by q.yak) pax) - ?~ a - ~ - ?: =(lob u.a) - ~ - =+ (~(get by q.yuk) pax) - ?~ - - ~ - ?: =(u.a u.-) - ~ - :- ~ - =/ disc ford-disc - :- [%$ %path !>(pax)] - :^ %diff ford-disc - (lobe-to-schematic:sutil disc pax lob) - (lobe-to-schematic:sutil disc pax u.a) - == - ;< res=made-result:ford bind:m expect-ford - =+ tay=(made-result-to-cages-or-error:util res) - ?: ?=(%| -.tay) - (error:he cas %diff-ali-bad-made leaf+"merge diff ali failed" p.tay) - =+ can=(cages-to-map:util p.tay) - ?: ?=(%| -.can) - (error:he cas %diff-ali p.can) - %- pure:m - :* %- molt - %+ skip ~(tap by q.yak) - |= {pax/path lob/lobe} - (~(has by q.bas) pax) - :: - %- molt ^- (list (pair path lobe)) - %+ murn ~(tap by q.bas) - |= {pax/path lob/lobe} - ^- (unit (pair path lobe)) - =+ a=(~(get by q.yak) pax) - =+ b=(~(get by q.yuk) pax) - ?. ?& ?=(^ a) - !=([~ lob] a) - =([~ lob] b) - == - ~ - `[pax +.a] - :: - p.can - :: - %- malt ^- (list {path ~}) - %+ murn ~(tap by q.bas) - |= {pax/path lob/lobe} - ?. =(~ (~(get by q.yak) pax)) - ~ - (some pax ~) - == - :: - :: Merge diffs that are on the same file. - :: - ++ merge-conflicts - |= [conflicts-ali=(map path cage) conflicts-bob=(map path cage)] - =/ m (clad ,bof=(map path (unit cage))) - ^- form:m - ;< ~ bind:m - %+ just-do /merge-conflicts - :* %f %build live=%.n %list - ^- (list schematic:ford) - %+ turn - ~(tap by (~(int by conflicts-ali) conflicts-bob)) - |= {pax/path *} - ^- schematic:ford - =+ cal=(~(got by conflicts-ali) pax) - =+ cob=(~(got by conflicts-bob) pax) - =/ her - =+ (slag (dec (lent pax)) pax) - ?~(- %$ i.-) - :- [%$ %path !>(pax)] - [%join [p.bob-disc q.bob-disc] her [%$ cal] [%$ cob]] - == - ;< res=made-result:ford bind:m expect-ford - =+ tay=(made-result-to-cages-or-error:util res) - ?: ?=(%| -.tay) - (error:he cas %merge-bad-made leaf+"merging failed" p.tay) - =+ can=(cages-to-map:util p.tay) - ?: ?=(%| -.can) - (error:he cas %merge p.can) - %- pure:m - (~(run by p.can) (flit |=({a/mark ^} !?=($null a)))) - :: - :: Apply the patches in bof to get the new merged content. - :: - :: Gather all the changes between ali's and bob's commits and the - :: mergebase. This is similar to the %meet of ++merge, except - :: where they touch the same file, we use the merged versions. - :: - ++ build - |= $: gem=germ - ali=yaki - bob=yaki - bas=yaki - dal=cane - dob=cane - bof=(map path (unit cage)) - == - =/ m - %- clad - $: conflicts=(set path) - bop=(map path cage) - new=yaki - erg=(map path ?) - e=_this-cor - == - ^- form:m - ;< ~ bind:m - %+ just-do /build - :* %f %build live=%.n %list - ^- (list schematic:ford) - %+ murn ~(tap by bof) - |= {pax/path cay/(unit cage)} - ^- (unit schematic:ford) - ?~ cay - ~ - :- ~ - :- [%$ %path !>(pax)] - =+ (~(get by q.bas) pax) - ?~ - - ~| %mate-strange-diff-no-base - !! - :* %pact - [p.bob-disc q.bob-disc] - (lobe-to-schematic:sutil ford-disc pax u.-) - [%$ u.cay] - == - == - ;< res=made-result:ford bind:m expect-ford - =+ tay=(made-result-to-cages-or-error:util res) - ?: ?=(%| -.tay) - (error:he cas %build-bad-made leaf+"delta building failed" p.tay) - =/ bop (cages-to-map:util p.tay) - ?: ?=(%| -.bop) - (error:he cas %built p.bop) - =/ both-patched p.bop - =/ con=(map path *) :: 2-change conflict - %- molt - %+ skim ~(tap by bof) - |=({pax/path cay/(unit cage)} ?=(~ cay)) - =/ cab=(map path lobe) :: conflict base - %- ~(urn by con) - |= {pax/path *} - (~(got by q.bas) pax) - =. con :: change+del conflict - %- ~(uni by con) - %- malt ^- (list {path *}) - %+ skim ~(tap by old.dal) - |= {pax/path ~} - ?: (~(has by new.dob) pax) - ~| %strange-add-and-del - !! - (~(has by can.dob) pax) - =. con :: change+del conflict - %- ~(uni by con) - %- malt ^- (list {path *}) - %+ skim ~(tap by old.dob) - |= {pax/path ~} - ?: (~(has by new.dal) pax) - ~| %strange-del-and-add - !! - (~(has by can.dal) pax) - =. con :: add+add conflict - %- ~(uni by con) - %- malt ^- (list {path *}) - %+ skip ~(tap by (~(int by new.dal) new.dob)) - |= {pax/path *} - =((~(got by new.dal) pax) (~(got by new.dob) pax)) - ?: &(?=($mate gem) ?=(^ con)) - =+ (turn ~(tap by `(map path *)`con) |=({path *} >[+<-]<)) - (error:he cas %mate-conflict -) - =/ old=(map path lobe) :: oldies but goodies - %+ roll ~(tap by (~(uni by old.dal) old.dob)) - =< .(old q.bas) - |= {{pax/path ~} old/(map path lobe)} - (~(del by old) pax) - =/ can=(map path cage) :: content changes - %- molt - ^- (list (pair path cage)) - %+ murn ~(tap by bof) - |= {pax/path cay/(unit cage)} - ^- (unit (pair path cage)) - ?~ cay - ~ - `[pax u.cay] - =^ hot lat.ran :: new content - ^- {(map path lobe) (map lobe blob)} - %+ roll ~(tap by can) - =< .(lat lat.ran) - |= {{pax/path cay/cage} hat/(map path lobe) lat/(map lobe blob)} - =+ ^= bol - =+ (~(get by q.bas) pax) - ?~ - - ~| %mate-strange-diff-no-base - !! - %^ make-delta-blob:sutil - (page-to-lobe:sutil [p q.q]:(~(got by both-patched) pax)) - [(lobe-to-mark:sutil u.-) u.-] - [p q.q]:cay - :- (~(put by hat) pax p.bol) - ?: (~(has by lat) p.bol) - lat - (~(put by lat) p.bol bol) - :: ~& old=(~(run by old) mug) - :: ~& newdal=(~(run by new.dal) mug) - :: ~& newdob=(~(run by new.dob) mug) - :: ~& caldal=(~(run by cal.dal) mug) - :: ~& caldob=(~(run by cal.dob) mug) - :: ~& hot=(~(run by hot) mug) - :: ~& cas=(~(run by cas) mug) - =/ hat=(map path lobe) :: all the content - %- ~(uni by old) - %- ~(uni by new.dal) - %- ~(uni by new.dob) - %- ~(uni by cal.dal) - %- ~(uni by cal.dob) - %- ~(uni by hot) - cab - =/ del=(map path ?) - (~(run by (~(uni by old.dal) old.dob)) |=(~ %|)) - =/ new (make-yaki:sutil [r.ali r.bob ~] hat wen) - %- pure:m - :* (silt (turn ~(tap by con) head)) - both-patched - new - :: - %- ~(uni by del) - ^- (map path ?) - %. |=(lobe %&) - %~ run by - %- ~(uni by new.dal) - %- ~(uni by cal.dal) - %- ~(uni by cab) - hot - :: - this-cor(hut.ran (~(put by hut.ran) r.new new)) - == - :: - :: Convert new commit into actual data (i.e. blobs rather than - :: lobes). Apply the new commit to our state - :: - ++ checkout - |= [gem=germ cas=case bob=(unit yaki) new=yaki bop=(map path cage)] - =/ m (clad ,_this-cor) - ^- form:m - ;< ~ bind:m - =/ val=beak - ?: ?=($init gem) - [p.ali-disc q.ali-disc cas] - [p.bob-disc q.bob-disc da+wen] - %+ just-do /checkout - :* %f %build live=%.n %pin wen %list - ^- (list schematic:ford) - %+ murn ~(tap by q.new) - |= {pax/path lob/lobe} - ^- (unit schematic:ford) - ?: (~(has by bop) pax) - ~ - :+ ~ - [%$ %path !>(pax)] - (merge-lobe-to-schematic:he (fall bob *yaki) ford-disc pax lob) - == - ;< res=made-result:ford bind:m expect-ford - =+ tay=(made-result-to-cages-or-error:util res) - ?: ?=(%| -.tay) - (error:he cas %checkout-bad-made leaf+"merge checkout failed" p.tay) - =+ can=(cages-to-map:util p.tay) - ?: ?=(%| -.can) - (error:he cas %checkout p.can) - =. let.dom +(let.dom) - =. hit.dom (~(put by hit.dom) let.dom r.new) - =. ank.dom - %- map-to-ankh:sutil - %- ~(run by (~(uni by bop) p.can)) - |=(cage [(page-to-lobe:sutil p q.q) +<]) - (pure:m this-cor) - :: - :: Cast all the content that we're going to tell unix about to - :: %mime, then tell unix. - :: - ++ ergo - |= [gem=germ cas=case mon=(map term beam) erg=(map path ?) new=yaki] - =/ m (clad ,mim=(map path mime)) - ^- form:m - =+ must=(must-ergo:util our q.bob-disc mon (turn ~(tap by erg) head)) - ?: =(~ must) - (pure:m mim.dom) - =/ sum=(set path) - =+ (turn ~(tap by must) (corl tail tail)) - %+ roll - - |= {pak/(set path) acc/(set path)} - (~(uni in acc) pak) - =/ val=beak - ?: ?=($init gem) - [p.ali-disc q.ali-disc cas] - [p.bob-disc q.bob-disc da+wen] - ;< ~ bind:m - %+ just-do /ergo - :* %f %build live=%.n %pin wen %list - ^- (list schematic:ford) - %+ turn ~(tap in sum) - |= a/path - ^- schematic:ford - :- [%$ %path !>(a)] - =+ b=(~(got by erg) a) - ?. b - [%$ %null !>(~)] - =/ disc ford-disc :: [p q]:val - :^ %cast ford-disc %mime - (lobe-to-schematic:sutil disc a (~(got by q.new) a)) - == - ;< res=made-result:ford bind:m expect-ford - =+ tay=(made-result-to-cages-or-error:util res) - ?: ?=(%| -.tay) - (error:he cas %ergo-bad-made leaf+"merge ergo failed" p.tay) - =+ =| nac=mode - |- ^- tan=$^(mode {p/term q/tang}) - ?~ p.tay nac - =* pax p.i.p.tay - ?. ?=($path p.pax) - [%ergo >[%expected-path got=p.pax]< ~] - =* mim q.i.p.tay - =+ mit=?.(?=($mime p.mim) ~ `;;(mime q.q.mim)) - $(p.tay t.p.tay, nac :_(nac [;;(path q.q.pax) mit])) - ?: ?=([@ *] tan) (error:he cas tan) - =/ changes=(map path (unit mime)) (malt tan) - =/ mim (apply-changes-to-mim:util mim.dom changes) - ?~ hez - (error:he cas %ergo-no-hez ~) - ;< ~ bind:m (give-ergo:util u.hez our q.bob-disc mon changes) - (pure:m mim) - :: - :: A small set of helper functions to assist in merging. - :: - ++ he - |% - :: - :: Cancel the merge gracefully and produce an error. - :: - ++ error - |= [cas=case err=term tan=(list tank)] - (clad-fail err >ali-disc< >bob-disc< >cas< tan) - :: - ++ calc-diffs - |= [hed=yaki bas=yaki] - ^- cane - :* %- molt - %+ skip ~(tap by q.hed) - |= {pax/path lob/lobe} - (~(has by q.bas) pax) - :: - %- molt - %+ skip ~(tap by q.hed) - |= {pax/path lob/lobe} - =+ (~(get by q.bas) pax) - |(=(~ -) =([~ lob] -)) - :: - ~ - :: - %- malt ^- (list {path ~}) - %+ murn ~(tap by q.bas) - |= {pax/path lob/lobe} - ^- (unit (pair path ~)) - ?. =(~ (~(get by q.hed) pax)) - ~ - `[pax ~] - == - :: - :: Create a schematic to turn a lobe into a blob. - :: - :: We short-circuit if we already have the content somewhere. - :: - ++ merge-lobe-to-schematic - |= [bob=yaki disc=disc:ford pax=path lob=lobe] - ^- schematic:ford - =+ lol=(~(get by q.bob) pax) - |- ^- schematic:ford - ?: =([~ lob] lol) - =+ (need (need (read-x:sutil & let.dom pax))) - ?> ?=(%& -<) - [%$ p.-] - :: ?: =([~ lob] lal) - :: [%$ +:(need fil.ank:(descend-path:(zu:sutil ank:(need alh)) pax))] - =+ bol=(~(got by lat.ran) lob) - ?- -.bol - $direct (page-to-schematic:sutil disc q.bol) - $delta - [%pact disc $(lob q.q.bol) (page-to-schematic:sutil disc r.bol)] - == - :: - :: Find the most recent common ancestor(s). - :: - ++ find-merge-points - |= {p/yaki q/yaki} :: maybe need jet - ^- (set yaki) - %- reduce-merge-points - =+ r=(reachable-takos:sutil r.p) - |- ^- (set yaki) - ?: (~(has in r) r.q) (~(put in *(set yaki)) q) - %+ roll p.q - |= {t/tako s/(set yaki)} - ?: (~(has in r) t) - (~(put in s) (tako-to-yaki:sutil t)) :: found - (~(uni in s) ^$(q (tako-to-yaki:sutil t))) :: traverse - :: - :: Helper for ++find-merge-points. - :: - ++ reduce-merge-points - |= unk/(set yaki) :: maybe need jet - =| gud/(set yaki) - =+ ^= zar - ^- (map tako (set tako)) - %+ roll ~(tap in unk) - |= {yak/yaki qar/(map tako (set tako))} - (~(put by qar) r.yak (reachable-takos:sutil r.yak)) - |- - ^- (set yaki) - ?~ unk gud - =+ bun=(~(del in `(set yaki)`unk) n.unk) - ?: %+ levy ~(tap by (~(uni in gud) bun)) - |= yak/yaki - !(~(has in (~(got by zar) r.yak)) r.n.unk) - $(gud (~(put in gud) n.unk), unk bun) - $(unk bun) - -- - -- - -- -:: -:: Mount a beam to unix -:: -++ mount - |= $: our=ship - syd=desk - wen=@da - hez=duct - dom=dome - ran=rang - == - |^ - |= [pot=term bem=beam mon=(map term beam)] - =/ m mount-clad - ^- form:m - =/ old-mon (~(get by mon) pot) - ?^ old-mon - (clad-fail %already-mounted >u.old-mon< ~) - =. mon (~(put by mon) pot bem) - ;< changes=(map path (unit mime)) bind:m (cast-to-mime bem) - ;< ~ bind:m (ergo changes mon) - =/ mim (apply-changes-to-mim:util mim.dom changes) - (pure:m [pot bem] mim) - :: - ++ sutil (state:util dom dom ran) - :: Initializes a new mount point. - :: - ++ cast-to-mime - |= bem=beam - =/ m (clad ,(map path (unit mime))) - ^- form:m - =* pax s.bem - =/ =aeon (need (case-to-aeon-before:sutil wen r.bem)) - =/ must - =/ all (turn ~(tap by q:(aeon-to-yaki:sutil aeon)) head) - (skim all |=(paf/path =(pax (scag (lent pax) paf)))) - ?~ must - (pure:m ~) - ;< ~ bind:m - %+ just-do /ergoing - :* %f %build live=%.n %list - ^- (list schematic:ford) - %+ turn `(list path)`must - |= a/path - :- [%$ %path !>(a)] - :^ %cast [our %home] %mime - =+ (need (need (read-x:sutil & aeon a))) - ?: ?=(%& -<) - [%$ p.-] - (lobe-to-schematic:sutil [our %home] a p.-) - == - ;< res=made-result:ford bind:m expect-ford - ?: ?=([%incomplete *] res) - (clad-fail %ergo-fail-incomplete leaf+"clay ergo incomplete" tang.res) - ?. ?=([%complete %success *] res) - (clad-fail %ergo-fail leaf+"clay ergo failed" message.build-result.res) - %- pure:m - %- malt ^- mode - %+ turn (made-result-to-cages:util res) - |= [pax=cage mim=cage] - ?. ?=($path p.pax) - ~|(%ergo-bad-path-mark !!) - :- ;;(path q.q.pax) - ?. ?=($mime p.mim) - ~ - `;;(mime q.q.mim) - :: - :: Send changes to unix - :: - ++ ergo - |= [changes=(map path (unit mime)) mon=(map term beam)] - (give-ergo:util hez our syd mon changes) - -- -:: -:: A simple foreign request. -:: -++ foreign-request - |= $: our=ship - her=ship - syd=desk - wen=@da - == - |^ - |= [=rave =rand] - =/ m request-clad - ^- form:m - ?- p.p.rand - $d ~| %totally-temporary-error-please-replace-me !! - $p ~| %requesting-foreign-permissions-is-invalid !! - $t ~| %requesting-foreign-directory-is-vaporware !! - $u ~| %prolly-poor-idea-to-get-rang-over-network !! - $v ~| %weird-shouldnt-get-v-request-from-network !! - $z ~| %its-prolly-not-reasonable-to-request-ankh !! - $x (validate-x [p.p q.p q r]:rand) - :: - $y - (pure:m [p.r.rand !>(;;(arch q.r.rand))]) - :: - $w - %- pure:m - :- p.r.rand - ?+ p.r.rand ~| %strange-w-over-nextwork !! - $cass !>(;;(cass q.r.rand)) - $null [[%atom %n ~] ~] - $nako !>(~|([%molding [&1 &2 &3]:q.r.rand] ;;(nako q.r.rand))) - == - == - :: - :: Make sure that incoming data is of the mark it claims to be. - :: - ++ validate-x - |= [car=care cas=case pax=path peg=page] - =/ m (clad ,cage) - ;< ~ bind:m - %+ just-do /foreign-x - [%f %build live=%.n %pin wen (vale-page:util [our %home] peg)] - ;< res=made-result:ford bind:m expect-ford - ^- form:m - ?. ?=([%complete %success *] res) - =/ message (made-result-as-error:ford res) - (clad-fail %validate-foreign-x-failed message) - (pure:m (result-to-cage:ford build-result.res)) - -- -:: -:: A full foreign update. Validate and apply to our local cache of -:: their state. -:: -++ foreign-update - |= $: our=ship - her=ship - syd=desk - wen=@da - == - |^ - |= [=moat rand=(unit rand) lim=@da dom=dome ran=rang] - =/ m update-clad - ^- form:m - ?~ rand - (pure:m ~) - =/ lem ?.(?=(%da -.to.moat) lim p.to.moat) - ?> ?=(%nako p.r.u.rand) - =/ nako ;;(nako q.r.u.rand) - ?: =(0 let.dom) - ;< [dom=dome ran=rang] bind:m (apply-foreign-update nako dom ran) - (pure:m ~ lem dom ran) - ;< blobs=(set blob) bind:m (validate-plops bar.nako) - ;< [dom=dome ran=rang] bind:m - (apply-foreign-update nako(bar blobs) dom ran) - (pure:m ~ lem dom ran) - :: - :: Make sure that incoming data is of the mark it claims to be. - :: - ++ validate-plops - |= plops=(set plop) - =/ m (clad ,(set blob)) - ^- form:m - ;< ~ bind:m - %+ just-do /validate-plops - :* %f %build live=%.n %pin wen - %list - ^- (list schematic:ford) - %+ turn ~(tap in plops) - |= a/plop - ?- -.a - $direct - :- [%$ %blob !>([%direct p.a *page])] - (vale-page:util [our %home] p.q.a q.q.a) - :: - $delta - :- [%$ %blob !>([%delta p.a q.a *page])] - (vale-page:util [our %home] p.r.a q.r.a) - == - == - ;< res=made-result:ford bind:m expect-ford - =/ cages (made-result-to-cages-or-error:util res) - ?: ?=(%| -.cages) - (clad-fail %validate-plops-failed p.cages) - =| blobs=(list blob) - |- ^- form:m - ?~ p.cages - (pure:m (silt blobs)) - =* bob p.i.p.cages - =* cay q.i.p.cages - ?. ?=(%blob p.bob) - (clad-fail %validate-plops-not-blob >p.bob< ~) - =/ new-blob=blob - =/ blob ;;(blob q.q.bob) - ?- -.blob - %delta [-.blob p.blob q.blob p.cay q.q.cay] - %direct [-.blob p.blob p.cay q.q.cay] - == - $(p.cages t.p.cages, blobs [new-blob blobs]) - :: - :: When we get a %w foreign update, store this in our state. - :: - :: We get the commits and blobs from the nako and add them to our object - :: store, then we update the map of aeons to commits and the latest aeon. - :: - ++ apply-foreign-update - |= [=nako dom=dome ran=rang] - =/ m (clad ,[dome rang]) - ^- form:m - :: hit: updated commit-hashes by @ud case - :: - =/ hit (~(uni by hit.dom) gar.nako) - :: nut: new commit-hash/commit pairs - :: - =/ nut - (turn ~(tap in lar.nako) |=(=yaki [r.yaki yaki])) - :: hut: updated commits by hash - :: - =/ hut (~(uni by (malt nut)) hut.ran) - :: nat: new blob-hash/blob pairs - :: - =/ nat - (turn ~(tap in bar.nako) |=(=blob [p.blob blob])) - :: lat: updated blobs by hash - :: - =/ lat (~(uni by (malt nat)) lat.ran) - :: traverse updated state and sanity check - :: - =+ ~| :* %bad-foreign-update - [gar=gar let=let.nako nut=(turn nut head) nat=(turn nat head)] - [hitdom=hit.dom letdom=let.dom] - == - ?: =(0 let.nako) - ~ - =/ =aeon 1 - |- ^- ~ - =/ =tako - ~| [%missing-aeon aeon] (~(got by hit) aeon) - =/ =yaki - ~| [%missing-tako tako] (~(got by hut) tako) - =+ %+ turn - ~(tap by q.yaki) - |= [=path =lobe] - ~| [%missing-blob path lobe] - ?> (~(has by lat) lobe) - ~ - ?: =(let.nako aeon) - ~ - $(aeon +(aeon)) - :: produce updated state - :: - =: let.dom (max let.nako let.dom) - hit.dom hit - hut.ran hut - lat.ran lat - == - (pure:m dom ran) - -- -:: -:: An assortment of useful functions, used in +commit, +merge, and +de -:: -++ util +++ fusion + => |% - :: Takes a list of changed paths and finds those paths that are inside a - :: mount point (listed in `mon`). + :: +an: $ankh interface door :: - :: Output is a map of mount points to {length-of-mounted-path set-of-paths}. - :: - ++ must-ergo - |= [our=ship syd=desk mon=(map term beam) can/(list path)] - ^- (map term (pair @ud (set path))) - %- malt ^- (list (trel term @ud (set path))) - %+ murn ~(tap by mon) - |= {nam/term bem/beam} - ^- (unit (trel term @ud (set path))) - =- ?~(- ~ `[nam (lent s.bem) (silt `(list path)`-)]) - %+ skim can - |= pax/path - &(=(p.bem our) =(q.bem syd) =((flop s.bem) (scag (lent s.bem) pax))) - :: - :: Send changes to unix - :: - ++ give-ergo - |= $: hez=duct - our=ship - syd=desk - mon=(map term beam) - changes=(map path (unit mime)) - == - =/ m (clad ,~) - ^- form:m - =/ must (must-ergo our syd mon (turn ~(tap by changes) head)) - |= clad-input - :- ~ :_ [%done ~] - %+ turn ~(tap by must) - |= [pot=term len=@ud pak=(set path)] - :* hez %give %ergo pot - %+ turn ~(tap in pak) - |= pax=path - [(slag len pax) (~(got by changes) pax)] - == - :: - :: Add or remove entries to the mime cache - :: - ++ apply-changes-to-mim - |= [mim=(map path mime) changes=(map path (unit mime))] - ^- (map path mime) - =/ changes-l=(list [pax=path change=(unit mime)]) - ~(tap by changes) - |- ^- (map path mime) - ?~ changes-l - mim - ?~ change.i.changes-l - $(changes-l t.changes-l, mim (~(del by mim) pax.i.changes-l)) - $(changes-l t.changes-l, mim (~(put by mim) [pax u.change]:i.changes-l)) - :: - :: Create a schematic to validate a page. - :: - :: If the mark is %hoon, we short-circuit the validation for bootstrapping - :: purposes. - :: - ++ vale-page - |= [=disc:ford a=page] - ^- schematic:ford - ?. ?=($hoon p.a) [%vale disc a] - ?. ?=(@t q.a) [%dude >%weird-hoon< %ride [%zpzp ~] %$ *cage] - [%$ p.a [%atom %t ~] q.a] - :: - :: Crashes on ford failure - :: - ++ ford-fail |=(tan/tang ~|(%ford-fail (mean tan))) - :: - :: Takes either a result or a stack trace. If it's a stack trace, we crash; - :: else, we produce the result. - :: - ++ unwrap-tang - |* res/(each * tang) - ?:(?=(%& -.res) p.res (mean p.res)) - :: - :: Parse a gage to a list of pairs of cages, crashing on error. - :: - :: Composition of ++gage-to-cages-or-error and ++unwrap-tang. Maybe same as - :: ++gage-to-success-cages? - :: - ++ made-result-to-cages - |= result=made-result:ford - ^- (list (pair cage cage)) - (unwrap-tang (made-result-to-cages-or-error result)) - :: - :: Same as ++gage-to-cages-or-error except crashes on error. Maybe same as - :: ++gage-to-cages? - :: - ++ made-result-to-success-cages - |= result=made-result:ford - ^- (list (pair cage cage)) - ?. ?=([%complete %success %list *] result) - (ford-fail >%strange-ford-result< ~) - :: process each row in the list, filtering out errors + ++ an + |_ nak=ankh + :: +get: produce file at path :: - %+ murn results.build-result.result - |= row=build-result:ford - ^- (unit [cage cage]) - :: - ?: ?=([%error *] row) - ~& [%clay-whole-build-failed message.row] - ~ - ?: ?=([%success [%error *] *] row) - ~& [%clay-first-failure message.head.row] - ~ - ?: ?=([%success [%success *] [%error *]] row) - ~& %clay-second-failure - %- (slog message.tail.row) - ~ - ?. ?=([%success [%success *] [%success *]] row) - ~ - `[(result-to-cage:ford head.row) (result-to-cage:ford tail.row)] - :: - :: Expects a single-level gage (i.e. a list of pairs of cages). If the - :: result is of a different form, or if some of the computations in the gage - :: failed, we produce a stack trace. Otherwise, we produce the list of pairs - :: of cages. - :: - ++ made-result-to-cages-or-error - |= result=made-result:ford - ^- (each (list (pair cage cage)) tang) - :: - ?: ?=([%incomplete *] result) - (mule |.(`~`(ford-fail tang.result))) - ?. ?=([%complete %success %list *] result) - (mule |.(`~`(ford-fail >%strange-ford-result -.build-result.result< ~))) - =/ results=(list build-result:ford) - results.build-result.result - =< ?+(. [%& .] {@ *} .) - |- - ^- ?((list [cage cage]) (each ~ tang)) - ?~ results ~ - :: - ?. ?=([%success ^ *] i.results) - (mule |.(`~`(ford-fail >%strange-ford-result< ~))) - ?: ?=([%error *] head.i.results) - (mule |.(`~`(ford-fail message.head.i.results))) - ?: ?=([%error *] tail.i.results) - (mule |.(`~`(ford-fail message.tail.i.results))) - :: - =+ $(results t.results) - ?: ?=([@ *] -) - - :_ - - [(result-to-cage:ford head.i.results) (result-to-cage:ford tail.i.results)] - :: - :: Assumes the list of pairs of cages is actually a listified map of paths - :: to cages, and converts it to (map path cage) or a stack trace on error. - :: - ++ cages-to-map - |= tay/(list (pair cage cage)) - =| can/(map path cage) - |- ^- (each (map path cage) tang) - ?~ tay [%& can] - =* pax p.i.tay - ?. ?=($path p.pax) - (mule |.(`~`~|([%expected-path got=p.pax] !!))) - $(tay t.tay, can (~(put by can) ;;(path q.q.pax) q.i.tay)) - :: - :: Useful functions which operate on a dome and a rang. - :: - :: `original-dome` is the dome which we had when the transaction - :: started. This is used as a lobe-to-blob cache in - :: +lobe-to-schematic so we don't have to recalculate the blobs for - :: files which haven't changed. - :: - ++ state - |= [original-dome=dome dom=dome ran=rang] - |% - :: These convert between aeon (version number), tako (commit hash), yaki - :: (commit data structure), lobe (content hash), and blob (content). - ++ aeon-to-tako ~(got by hit.dom) - ++ aeon-to-yaki |=(=aeon (tako-to-yaki (aeon-to-tako aeon))) - ++ lobe-to-blob ~(got by lat.ran) - ++ tako-to-yaki ~(got by hut.ran) - ++ lobe-to-mark - |= a/lobe - => (lobe-to-blob a) - ?- - - $delta p.q - $direct p.q - == - :: - :: Create a schematic out of a page (which is a [mark noun]). - :: - ++ page-to-schematic - |= [disc=disc:ford a=page] - ^- schematic:ford - ?. ?=($hoon p.a) [%volt disc a] - :: %hoon bootstrapping - [%$ p.a [%atom %t ~] q.a] - :: - :: Create a schematic out of a lobe (content hash). - :: - ++ lobe-to-schematic (cury lobe-to-schematic-p &) - ++ lobe-to-schematic-p - =. dom original-dome - |= [local=? disc=disc:ford pax=path lob=lobe] - ^- schematic:ford - :: - =/ hat/(map path lobe) - ?: =(let.dom 0) - ~ - q:(aeon-to-yaki let.dom) - =+ lol=`(unit lobe)`?.(local `0vsen.tinel (~(get by hat) pax)) - |- ^- schematic:ford - ?: =([~ lob] lol) - =+ (need (need (read-x & let.dom pax))) - ?> ?=(%& -<) - [%$ p.-] - =+ bol=(~(got by lat.ran) lob) - ?- -.bol - $direct (page-to-schematic disc q.bol) - $delta ~| delta+q.q.bol - [%pact disc $(lob q.q.bol) (page-to-schematic disc r.bol)] - == - :: - :: Hash a page to get a lobe. - :: - ++ page-to-lobe |=(page (shax (jam +<))) - :: - :: Make a direct blob out of a page. - :: - ++ make-direct-blob - |= p/page - ^- blob - [%direct (page-to-lobe p) p] - :: - :: Make a delta blob out of a lobe, mark, lobe of parent, and page of diff. - :: - ++ make-delta-blob - |= {p/lobe q/{p/mark q/lobe} r/page} - ^- blob - [%delta p q r] - :: - :: Make a commit out of a list of parents, content, and date. - :: - ++ make-yaki - |= {p/(list tako) q/(map path lobe) t/@da} - ^- yaki - =+ ^= has - %^ cat 7 (sham [%yaki (roll p add) q t]) - (sham [%tako (roll p add) q t]) - [p q has t] - :: - ++ case-to-date - |= [now=@da =case] - ^- @da - :: if the case is already a date, use it. - :: - ?: ?=([%da *] case) - p.case - :: translate other cases to dates - :: - =/ aey (case-to-aeon-before now case) - ?~ aey `@da`0 - ?: =(0 u.aey) `@da`0 - t:(aeon-to-yaki u.aey) - :: - :: Reduce a case to an aeon (version number) - :: - :: We produce null if we can't yet reduce the case for whatever - :: resaon (usually either the time or aeon hasn't happened yet or - :: the label hasn't been created). - :: - ++ case-to-aeon-before - |= [lim=@da lok=case] - ^- (unit aeon) - ?- -.lok - $da - ?: (gth p.lok lim) ~ - |- ^- (unit aeon) - ?: =(0 let.dom) [~ 0] :: avoid underflow - ?: %+ gte p.lok - =< t - ~| [%letdom let=let.dom hit=hit.dom hut=~(key by hut.ran)] - ~| [%getdom (~(get by hit.dom) let.dom)] - %- aeon-to-yaki - let.dom - [~ let.dom] - $(let.dom (dec let.dom)) - :: - $tas (~(get by lab.dom) p.lok) - $ud ?:((gth p.lok let.dom) ~ [~ p.lok]) - == - :: - :: Convert a map of paths to data into an ankh. - :: - ++ map-to-ankh - |= hat/(map path (pair lobe cage)) - ^- ankh - %+ roll ~(tap by hat) - |= {{pat/path lob/lobe zar/cage} ank/ankh} - ^- ankh - ?~ pat - ank(fil [~ lob zar]) - =+ nak=(~(get by dir.ank) i.pat) - %= ank - dir %+ ~(put by dir.ank) i.pat - $(pat t.pat, ank (fall nak *ankh)) - == - :: - :: Update the object store with new blobs. - :: - :: Must uni the old-lat into the new-lat so that if we recreate - :: the same blob hash, we use the old blob not the new one. Else - :: you get mutually recurring %delta blobs. - ++ add-blobs - |= [new-blobs=(map path blob) old-lat=(map lobe blob)] - ^- (map lobe blob) - =/ new-lat=(map lobe blob) - %- malt - %+ turn - ~(tap by new-blobs) - |= [=path =blob] - [p.blob blob] - (~(uni by new-lat) old-lat) - :: - :: Apply a change list, creating the commit and applying it to - :: the current state. - :: - ++ execute-changes - |= [wen=@da lem=suba] - ^- (unit [dome rang]) - =/ parent - ?: =(0 let.dom) + ++ get + |= =path + ^- (unit cage) + ?~ path + ?~ fil.nak ~ - [(aeon-to-tako let.dom)]~ - =/ new-blobs (apply-changes lem) - =. lat.ran (add-blobs new-blobs lat.ran) - =/ new-lobes (~(run by new-blobs) |=(=blob p.blob)) - =/ new-yaki (make-yaki parent new-lobes wen) - :: if no changes and not first commit or merge, abort - ?. ?| =(0 let.dom) - !=((lent p.new-yaki) 1) - !=(q.new-yaki q:(aeon-to-yaki let.dom)) - == - ~ - =: let.dom +(let.dom) - hit.dom (~(put by hit.dom) +(let.dom) r.new-yaki) - hut.ran (~(put by hut.ran) r.new-yaki new-yaki) - == - `[dom ran] - :: - :: Apply label to current revision - :: - ++ execute-label - |= lab=@tas - ?< (~(has by lab.dom) lab) - dom(lab (~(put by lab.dom) lab let.dom)) - :: - :: Apply a list of changes against the current state and produce - :: the new state. - :: - ++ apply-changes :: apply-changes - |= [change-files=(list [p=path q=misu])] - ^- (map path blob) - =+ ^= old-files :: current state - ?: =(let.dom 0) :: initial commit - ~ :: has nothing - =< q - %- aeon-to-yaki - let.dom - =; new-files=(map path blob) - =+ sar=(silt (turn change-files head)) :: changed paths - %+ roll ~(tap by old-files) :: find unchanged - =< .(bat new-files) - |= [[pax=path gar=lobe] bat=(map path blob)] - ?: (~(has in sar) pax) :: has update - bat - %+ ~(put by bat) pax - ~| [pax gar (lent ~(tap by lat.ran))] - (lobe-to-blob gar) :: use original - %+ roll change-files - |= {{pax/path mys/misu} new-files/(map path blob)} - ^+ new-files - ?- -.mys - $ins :: insert if not exist - ?: (~(has by new-files) pax) - ~|([%ins-new-files pax] !!) - ?: (~(has by old-files) pax) - ~|([%ins-old-files pax] !!) - %+ ~(put by new-files) pax - %- make-direct-blob - ?: &(?=($mime -.p.mys) =([%hoon ~] (slag (dec (lent pax)) pax))) - `page`[%hoon +.+.q.q.p.mys] - [p q.q]:p.mys - :: - $del :: delete if exists - ?> |((~(has by old-files) pax) (~(has by new-files) pax)) - (~(del by new-files) pax) - :: - $dif :: mutate, must exist - =+ ber=(~(get by new-files) pax) :: XX typed - =+ her==>((flop pax) ?~(. %$ i)) - ?~ ber - =+ har=(~(get by old-files) pax) - ?~ har !! - %+ ~(put by new-files) pax - (make-delta-blob p.mys [(lobe-to-mark u.har) u.har] [p q.q]:q.mys) - :: XX check vase !evil - :: XX of course that's a problem, p.u.ber isn't in rang since it - :: was just created. We shouldn't be sending multiple - :: diffs - :: %+ ~(put by bar) pax - :: %^ make-delta-blob p.mys - :: [(lobe-to-mark p.u.ber) p.u.ber] - :: [p q.q]:q.mys - :: :: XX check vase !evil - ~|([%two-diffs-for-same-file pax] !!) - == - :: - :: Traverse parentage and find all ancestor hashes - :: - ++ reachable-takos :: reachable - |= p/tako - ^- (set tako) - =+ y=(tako-to-yaki p) - %+ roll p.y - =< .(s (~(put in *(set tako)) p)) - |= {q/tako s/(set tako)} - ?: (~(has in s) q) :: already done - s :: hence skip - (~(uni in s) ^$(p q)) :: otherwise traverse - :: - :: Get the data at a node. - :: - :: If it's in our ankh (current state cache), we can just produce - :: the result. Otherwise, we've got to look up the node at the - :: aeon to get the content hash, use that to find the blob, and use - :: the blob to get the data. We also special-case the hoon mark - :: for bootstrapping purposes. - :: - ++ read-x - |= [local=? yon=aeon pax=path] - ^- (unit (unit (each cage lobe))) - ?: =(0 yon) - [~ ~] - =+ tak=(~(get by hit.dom) yon) - ?~ tak + `q.u.fil.nak + ?~ kid=(~(get by dir.nak) i.path) ~ - ?: &(local =(yon let.dom)) + $(nak u.kid, path t.path) + -- + ++ with-face |=([face=@tas =vase] vase(p [%face face p.vase])) + ++ with-faces + =| res=(unit vase) + |= vaz=(list [face=@tas =vase]) + ^- vase + ?~ vaz (need res) + =/ faz (with-face i.vaz) + =. res `?~(res faz (slop faz u.res)) + $(vaz t.vaz) + -- + |% + :: +wrap: external wrapper + :: + ++ wrap + |* [* state:ford] + [+<- +<+>-] :: cache.state + :: + ++ ford + !. + => |% + +$ build + $% [%file =path] + [%mark =mark] + [%cast =mars] + [%vale =path] + == + +$ state + $: baked=(map path cage) + cache=ford-cache + stack=(list (set path)) + cycle=(set build) + == + +$ args + $: bud=vase + =ankh + deletes=(set path) + changes=(map path (each page lobe)) + file-store=(map lobe blob) + =ford-cache + == + -- + |= args + :: nub: internal mutable state for this computation + :: + =| nub=state + =. cache.nub ford-cache + |% + :: +pop-stack: pop build stack, copying deps downward + :: + ++ pop-stack + ^- [(set path) _stack.nub] + =^ top=(set path) stack.nub stack.nub + =? stack.nub ?=(^ stack.nub) + stack.nub(i (~(uni in i.stack.nub) top)) + [top stack.nub] + :: + ++ get-value + |= =path + ^- [cage state] + ~| %error-validating^path + ?^ got=(~(get by baked.nub) path) + [u.got nub] + =; [res=cage bun=state] + =. nub bun + =. baked.nub (~(put by baked.nub) path res) + [res nub] + ?: (~(has in cycle.nub) vale+path) + ~|(cycle+vale+path^stack.nub !!) + =. cycle.nub (~(put in cycle.nub) vale+path) + ?^ change=(~(get by changes) path) + =^ page nub + ?: ?=(%& -.u.change) + [p.u.change nub] + ~| %ugly-lobe^p.u.change^path + (lobe-to-page p.u.change) + =^ cage nub (validate-page path page) + [cage nub] + ?< (~(has in deletes) path) + ~| %file-not-found^path + :_(nub (need (~(get an ankh) path))) + :: +get-mark: build a mark definition + :: + ++ get-mark + |= mak=mark + ^- [dais state] + ~| %error-building-mark^mak + ?^ got=(~(get by marks.cache.nub) mak) + =? stack.nub ?=(^ stack.nub) + stack.nub(i (~(uni in i.stack.nub) dez.u.got)) + [res.u.got nub] + ?: (~(has in cycle.nub) mark+mak) + ~|(cycle+mark+mak^stack.nub !!) + =. cycle.nub (~(put in cycle.nub) mark+mak) + =. stack.nub [~ stack.nub] + =; res=[=dais nub=state] + =. nub nub.res + =^ top stack.nub pop-stack + =. marks.cache.nub (~(put by marks.cache.nub) mak [dais.res top]) + [dais.res nub] + =^ cor=vase nub (build-fit %mar mak) + =/ gad=vase (slap cor %limb %grad) + ?@ q.gad + =+ !<(mok=mark gad) + =^ deg=dais nub $(mak mok) + =^ tub=tube nub (get-cast mak mok) + =^ but=tube nub (get-cast mok mak) + :_ nub + ^- dais + |_ sam=vase + ++ bunt (slap cor $+6) + ++ diff + |= new=vase + ^- vase + (~(diff deg (tub sam)) (tub new)) + ++ form form:deg + ++ join join:deg + ++ mash mash:deg + ++ pact + |= diff=vase + ^+ sam + (but (~(pact deg (tub sam)) diff)) + ++ vale + |= =noun + ^+ sam + (slam (slap cor ^~((ream 'noun:grab'))) !>(noun)) + ++ volt + |= =noun + ^+ sam + [p:bunt noun] + -- + :_ nub + =+ !<(fom=mark (slap gad %limb %form)) + ^- dais + |_ sam=vase + ++ bunt (slap cor $+6) + ++ diff + |= new=vase + ^- vase + %+ slap + (with-faces cor+cor sam+sam new+new ~) + ^~((ream '(diff:~(grad cor sam) new)')) + ++ form fom + ++ join + |= [a=vase b=vase] + ^- (unit (unit vase)) + ?: =(q.a q.b) + ~ + =; res `?~(q.res ~ `(slap res ^~((ream '?~(. !! u)')))) + (slam (slap cor ^~((ream 'join:grad'))) (slop a b)) + ++ mash + |= [a=[=ship =desk diff=vase] b=[=ship =desk diff=vase]] + ^- (unit vase) + ?: =(q.diff.a q.diff.b) + ~ :- ~ - %+ bind - fil.ank:(descend-path:(zu ank.dom) pax) - |=(a/{p/lobe q/cage} [%& q.a]) - =+ yak=(tako-to-yaki u.tak) - =+ lob=(~(get by q.yak) pax) - ?~ lob - [~ ~] - =+ mar=(lobe-to-mark u.lob) - ?. ?=($hoon mar) - [~ ~ %| u.lob] - :^ ~ ~ %& - :+ mar [%atom %t ~] - |- ^- @t :: (urge cord) would be faster - =+ bol=(lobe-to-blob u.lob) - ?: ?=($direct -.bol) - ;;(@t q.q.bol) - ?> ?=($delta -.bol) - =+ txt=$(u.lob q.q.bol) - ?> ?=($txt-diff p.r.bol) - =+ dif=;;((urge cord) q.r.bol) - =, format - =+ pac=(of-wain (lurk:differ (to-wain (cat 3 txt '\0a')) dif)) - ?~ pac - '' - (end 3 (dec (met 3 pac)) pac) - :: - :: Traverse an ankh. - :: - ++ zu :: filesystem - |= ank/ankh :: filesystem state - =| ram/path :: reverse path into - |% - ++ descend :: descend - |= lol/@ta - ^+ +> - =+ you=(~(get by dir.ank) lol) - +>.$(ram [lol ram], ank ?~(you [~ ~] u.you)) - :: - ++ descend-path :: descend recursively - |= way/path - ^+ +> - ?~(way +> $(way t.way, +> (descend i.way))) + %+ slam (slap cor ^~((ream 'mash:grad'))) + %+ slop + :(slop !>(ship.a) !>(desk.a) diff.a) + :(slop !>(ship.b) !>(desk.b) diff.b) + ++ pact + |= diff=vase + ^+ sam + %+ slap + (with-faces cor+cor sam+sam diff+diff ~) + ^~((ream '(pact:~(grad cor sam) diff)')) + ++ vale + |= =noun + ^+ sam + (slam (slap cor ^~((ream 'noun:grab'))) !>(noun)) + ++ volt + |= =noun + ^+ sam + [p:bunt noun] -- + :: +get-cast: produce a $tube mark conversion gate from .a to .b + :: + ++ get-cast + |= [a=mark b=mark] + ^- [tube state] + ~| error-building-cast+[a b] + ?: =([%mime %hoon] [a b]) + :_ nub + |= sam=vase + =+ !<(=mime sam) + !>(q.q.mime) + ?^ got=(~(get by casts.cache.nub) [a b]) + =? stack.nub ?=(^ stack.nub) + stack.nub(i (~(uni in i.stack.nub) dez.u.got)) + [res.u.got nub] + ?: (~(has in cycle.nub) cast+[a b]) + ~|(cycle+cast+[a b]^stack.nub !!) + =. stack.nub [~ stack.nub] + =; res=[=tube nub=state] + =. nub nub.res + =^ top stack.nub pop-stack + =. casts.cache.nub (~(put by casts.cache.nub) [a b] [tube.res top]) + [tube.res nub] + :: try +grow; is there a +grow core with a .b arm? + :: + =^ old=vase nub (build-fit %mar a) + ?: =/ ram (mule |.((slap old ^~((ream 'grow'))))) + ?: ?=(%| -.ram) %.n + =/ lab (mule |.((slob b p.p.ram))) + ?: ?=(%| -.lab) %.n + p.lab + :: +grow core has .b arm; use that + :: + :_ nub + ^- tube + |= sam=vase + ^- vase + %+ slap + (with-faces old+old sam+sam ~) + %- ream + ;: (cury cat 3) + '!: ' + '~! old=old ' + '~! sam=sam ' + b ':~(grow old sam)' + == + :: try direct +grab + :: + =^ new=vase nub (build-fit %mar b) + =/ rab (mule |.((slap new (ream (cat 3 a ':grab'))))) + ?: &(?=(%& -.rab) ?=(^ q.p.rab)) + :_(nub |=(sam=vase ~|([%grab a b] (slam p.rab sam)))) + :: try +jump + :: + =/ jum (mule |.((slap old (ream (cat 3 b ':jump'))))) + ?: ?=(%& -.jum) + (compose-casts a !<(mark p.jum) b) + :: try indirect +grab + :: + ?: ?=(%& -.rab) + (compose-casts a !<(mark p.rab) b) + ~|(no-cast-from+[a b] !!) + :: + ++ compose-casts + |= [x=mark y=mark z=mark] + ^- [tube state] + =^ uno=tube nub (get-cast x y) + =^ dos=tube nub (get-cast y z) + :_(nub |=(sam=vase (dos (uno sam)))) + :: + ++ lobe-to-page + |= =lobe + ^- [page state] + =/ =blob (~(got by file-store) lobe) + |- ^- [page state] + ?- -.blob + %direct [q.blob nub] + %delta + =/ [[=mark =parent=^lobe] diff=page] [q r]:blob + =^ parent-page nub $(blob (~(got by file-store) parent-lobe)) + =^ =cage nub (run-pact parent-page diff) + [[p q.q]:cage nub] + == + :: + ++ validate-page + |= [=path =page] + ^- [cage state] + ~| validate-page-fail+path^from+p.page + =/ mak=mark (head (flop path)) + ?: =(mak p.page) + (page-to-cage page) + =^ [mark vax=vase] nub (page-to-cage page) + =^ =tube nub (get-cast p.page mak) + :_(nub [mak (tube vax)]) + :: + ++ page-to-cage + |= =page + ^- [cage state] + ?: =(%hoon p.page) + :_(nub [%hoon -:!>(*@t) q.page]) + ?: =(%mime p.page) + :_(nub [%mime !>(;;(mime q.page))]) + =^ =dais nub (get-mark p.page) + :_(nub [p.page (vale:dais q.page)]) + :: + ++ cast-path + |= [=path mak=mark] + ^- [cage state] + =/ mok (head (flop path)) + ~| error-casting-path+[path mok mak] + =^ cag=cage nub (get-value path) + ?: =(mok mak) + [cag nub] + =^ =tube nub (get-cast mok mak) + ~| error-running-cast+[path mok mak] + :_(nub [mak (tube q.cag)]) + :: + ++ run-pact + |= [old=page diff=page] + ^- [cage state] + ?: ?=(%hoon p.old) + =/ txt=wain (to-wain:format ;;(@t q.old)) + =+ ;;(dif=(urge cord) q.diff) + =/ new=@t (of-wain:format (lurk:differ txt dif)) + :_(nub [%hoon !>(new)]) + =^ dys=dais nub (get-mark p.old) + =^ syd=dais nub (get-mark p.diff) + :_(nub [p.old (~(pact dys (vale:dys q.old)) (vale:syd q.diff))]) + :: + ++ prelude + |= =path + ^- vase + =^ cag=cage nub (get-value path) + ?> =(%hoon p.cag) + =/ tex=tape (trip !<(@t q.cag)) + =/ =pile (parse-pile path tex) + =. hoon.pile !,(*hoon .) + =^ res=vase nub (run-pile pile) + res + :: + ++ build-file + |= =path + ^- [vase state] + ~| %error-building^path + ?^ got=(~(get by vases.cache.nub) path) + =? stack.nub ?=(^ stack.nub) + stack.nub(i (~(uni in i.stack.nub) dez.u.got)) + [res.u.got nub] + ?: (~(has in cycle.nub) file+path) + ~|(cycle+file+path^stack.nub !!) + =. cycle.nub (~(put in cycle.nub) file+path) + =. stack.nub [(sy path ~) stack.nub] + =^ cag=cage nub (get-value path) + ?> =(%hoon p.cag) + =/ tex=tape (trip !<(@t q.cag)) + =/ =pile (parse-pile path tex) + =^ res=vase nub (run-pile pile) + =^ top stack.nub pop-stack + =. vases.cache.nub (~(put by vases.cache.nub) path [res top]) + [res nub] + :: + ++ run-pile + |= =pile + =^ sut=vase nub (run-tauts bud %sur sur.pile) + =^ sut=vase nub (run-tauts sut %lib lib.pile) + =^ sut=vase nub (run-raw sut raw.pile) + =^ sut=vase nub (run-bar sut bar.pile) + =/ res=vase (road |.((slap sut hoon.pile))) + [res nub] + :: + ++ parse-pile + |= [pax=path tex=tape] + ^- pile + =/ [=hair res=(unit [=pile =nail])] ((pile-rule pax) [1 1] tex) + ?^ res pile.u.res + %- mean %- flop + =/ lyn p.hair + =/ col q.hair + :~ leaf+"syntax error at [{} {}] in {}" + leaf+(trip (snag (dec lyn) (to-wain:format (crip tex)))) + leaf+(runt [(dec col) '-'] "^") + == + :: + ++ pile-rule + |= pax=path + %- full + %+ ifix [gay gay] + %+ cook |=(pile +<) + ;~ pfix + :: parse optional /? and ignore + :: + ;~ pose + (cold ~ ;~(plug net wut gap dem gap)) + (easy ~) + == + :: + ;~ plug + ;~ pose + ;~ sfix + %+ cook |=((list (list taut)) (zing +<)) + %+ more gap + ;~ pfix ;~(plug net hep gap) + (most ;~(plug com gaw) taut-rule) + == + gap + == + (easy ~) + == + :: + ;~ pose + ;~ sfix + %+ cook |=((list (list taut)) (zing +<)) + %+ more gap + ;~ pfix ;~(plug net lus gap) + (most ;~(plug com gaw) taut-rule) + == + gap + == + (easy ~) + == + :: + ;~ pose + ;~ sfix + %+ cook |=((list [face=term =path]) +<) + %+ more gap + ;~ pfix ;~(plug net tis gap) + %+ cook |=([term path] +<) + ;~(plug sym ;~(pfix ;~(plug gap net) (more net urs:ab))) + == + gap + == + (easy ~) + == + :: + ;~ pose + ;~ sfix + %+ cook |=((list [face=term =mark =path]) +<) + %+ more gap + ;~ pfix ;~(plug net tar gap) + %+ cook |=([term mark path] +<) + ;~ plug + sym + ;~(pfix ;~(plug gap cen) sym) + ;~(pfix ;~(plug gap net) (more net urs:ab)) + == + == + gap + == + (easy ~) + == + :: + %+ cook |=(huz=(list hoon) `hoon`tssg+huz) + (most gap tall:(vang & pax)) + == + == + :: + ++ taut-rule + %+ cook |=(taut +<) + ;~ pose + (stag ~ ;~(pfix tar sym)) + ;~(plug (stag ~ sym) ;~(pfix tis sym)) + (cook |=(a=term [`a a]) sym) + == + :: + ++ run-tauts + |= [sut=vase wer=?(%lib %sur) taz=(list taut)] + ^- [vase state] + ?~ taz [sut nub] + =^ pin=vase nub (build-fit wer pax.i.taz) + =? p.pin ?=(^ face.i.taz) [%face u.face.i.taz p.pin] + $(sut (slop pin sut), taz t.taz) + :: + ++ run-raw + |= [sut=vase raw=(list [face=term =path])] + ^- [vase state] + ?~ raw [sut nub] + =^ pin=vase nub (build-file (snoc path.i.raw %hoon)) + =. p.pin [%face face.i.raw p.pin] + $(sut (slop pin sut), raw t.raw) + :: + ++ run-bar + |= [sut=vase bar=(list [face=term =mark =path])] + ^- [vase state] + ?~ bar [sut nub] + =^ =cage nub (cast-path [path mark]:i.bar) + =. p.q.cage [%face face.i.bar p.q.cage] + $(sut (slop q.cage sut), bar t.bar) + :: + :: +build-fit: build file at path, maybe converting '-'s to '/'s in path + :: + ++ build-fit + |= [pre=@tas pax=@tas] + ^- [vase state] + (build-file (fit-path pre pax)) + :: + :: +fit-path: find path, maybe converting '-'s to '/'s + :: + :: Try '-' before '/', applied left-to-right through the path, + :: e.g. 'a-foo/bar' takes precedence over 'a/foo-bar'. + :: + ++ fit-path + |= [pre=@tas pax=@tas] + ^- path + =/ paz (segments pax) + |- ^- path + ?~ paz ~|(no-file+pre^pax !!) + =/ pux=path pre^(snoc i.paz %hoon) + ?: (~(has in deletes) pux) + $(paz t.paz) + ?: (~(has by changes) pux) + pux + ?^ (~(get an ankh) pux) + pux + $(paz t.paz) -- -- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: @@ -2675,13 +1001,12 @@ :: ++ aver |= {for/(unit ship) mun/mood} - ^- (unit (unit (each cage lobe))) + ^- [(unit (unit (each cage lobe))) ford-cache] =+ ezy=?~(ref ~ (~(get by haw.u.ref) mun)) ?^ ezy - `(bind u.ezy |=(a/cage [%& a])) + :_(fod.dom.red `(bind u.ezy |=(a/cage [%& a]))) =+ nao=(case-to-aeon case.mun) - :: ~& [%aver-mun nao [%from syd lim case.mun]] - ?~(nao ~ (read-at-aeon:ze for u.nao mun)) + ?~(nao [~ fod.dom.red] (read-at-aeon:ze for u.nao mun)) :: :: Queue a move. :: @@ -2723,23 +1048,65 @@ :: the latter case we fetch the data at the lobe and produce that. :: ++ blab - |= {hen/duct mun/mood dat/(each cage lobe)} + |= [hen=duct mun=mood dat=(each cage lobe)] ^+ +> - ?: ?=(%& -.dat) - %- emit - :* hen %slip %b %drip - !>([%writ ~ [care.mun case.mun syd] path.mun p.dat]) - == - %- emit - :* hen %pass [%blab care.mun (scot case.mun) syd path.mun] - %f %build live=%.n %pin - (case-to-date case.mun) - (lobe-to-schematic [her syd] path.mun p.dat) - == + =^ =cage fod.dom + ?: ?=(%& -.dat) + [p.dat fod.dom] + =^ =page fod.dom + %- wrap:fusion + (lobe-to-page:(ford:fusion static-ford-args) p.dat) + =^ =cage fod.dom + %- wrap:fusion + (page-to-cage:(ford:fusion static-ford-args) page) + [cage fod.dom] + =/ gift [%writ ~ [care.mun case.mun syd] path.mun cage] + ?: ?=(^ ref) + (emit hen %slip %b %drip !>(gift)) + (emit hen %give gift) :: - ++ case-to-date (cury case-to-date:util lim) - ++ case-to-aeon (cury case-to-aeon-before:util lim) - ++ lobe-to-schematic (cury lobe-to-schematic-p:util ?=(~ ref)) + ++ case-to-date + |= =case + ^- @da + :: if the case is already a date, use it. + :: + ?: ?=([%da *] case) + p.case + :: translate other cases to dates + :: + =/ aey (case-to-aeon-before lim case) + ?~ aey `@da`0 + ?: =(0 u.aey) `@da`0 + t:(aeon-to-yaki:ze u.aey) + :: + ++ case-to-aeon (cury case-to-aeon-before lim) + :: + :: Reduce a case to an aeon (version number) + :: + :: We produce null if we can't yet reduce the case for whatever + :: resaon (usually either the time or aeon hasn't happened yet or + :: the label hasn't been created). + :: + ++ case-to-aeon-before + |= [lim=@da lok=case] + ^- (unit aeon) + ?- -.lok + $da + ?: (gth p.lok lim) ~ + |- ^- (unit aeon) + ?: =(0 let.dom) [~ 0] :: avoid underflow + ?: %+ gte p.lok + =< t + ~| [%letdom let=let.dom hit=hit.dom hut=~(key by hut.ran)] + ~| [%getdom (~(get by hit.dom) let.dom)] + %- aeon-to-yaki:ze + let.dom + [~ let.dom] + $(let.dom (dec let.dom)) + :: + $tas (~(get by lab.dom) p.lok) + $ud ?:((gth p.lok let.dom) ~ [~ p.lok]) + == :: ++ blas |= {hen/duct das/(set mood)} @@ -2748,8 +1115,12 @@ :: translate the case to a date :: =/ cas [%da (case-to-date case.n.das)] - =- (emit hen %slip %b %drip !>([%wris cas -])) - (~(run in `(set mood)`das) |=(m/mood [care.m path.m])) + =/ res + (~(run in `(set mood)`das) |=(m/mood [care.m path.m])) + =/ gift [%wris cas res] + ?: ?=(^ ref) + (emit hen %slip %b %drip !>(gift)) + (emit hen %give gift) :: :: Give next step in a subscription. :: @@ -2766,7 +1137,9 @@ :: ++ blub |= hen/duct - (emit hen %slip %b %drip !>([%writ ~])) + ?: ?=(^ ref) + (emit hen %slip %b %drip !>([%writ ~])) + (emit hen %give %writ ~) :: :: Lifts a function so that a single result can be fanned out over a set of :: subscriber ducts. @@ -2789,6 +1162,9 @@ ++ balk-all (duct-lift balk) ++ bleb-all (duct-lift bleb) :: + ++ static-ford-args + [zuse:(need fer.dom) ank.dom ~ ~ lat.ran fod.dom] + :: :: Transfer a request to another ship's clay. :: ++ send-over-ames @@ -2903,6 +1279,1213 @@ == == :: + :: Porcelain commit + :: + ++ info + |= [deletes=(set path) changes=(map path cage)] + ^+ ..park + ?: =(0 let.dom) + ?> ?=(~ deletes) + =/ data=(map path (each page lobe)) + (~(run by changes) |=(=cage &+[p q.q]:cage)) + (park | &+[~ data] *rang) + :: + =/ parent-tako=tako (aeon-to-tako:ze let.dom) + =/ data=(map path (each page lobe)) + =/ parent-yaki (tako-to-yaki:ze parent-tako) + =/ after-deletes + %- ~(dif by q.parent-yaki) + (malt (turn ~(tap in deletes) |=(=path [path *lobe]))) + =/ after=(map path (each page lobe)) + (~(run by after-deletes) |=(=lobe |+lobe)) + %- ~(uni by after) + ^- (map path (each page lobe)) + (~(run by changes) |=(=cage &+[p q.q]:cage)) + :: + =/ =yuki [~[parent-tako] data] + (park | &+yuki *rang) + :: + :: Unix commit + :: + ++ into + |= [pax=path all=? mod=(list [pax=path mim=(unit mime)])] + ^+ ..park + :: filter out unchanged, cached %mime values + :: + =. mod + %+ skip mod + |= [pax=path mim=(unit mime)] + ?~ mim + | + ?~ mum=(~(get by mim.dom) pax) + | + :: TODO: check mimetype + :: + =(q.u.mim q.u.mum) + =/ =yaki + ?: =(0 let.dom) + *yaki + (~(got by hut.ran) (~(got by hit.dom) let.dom)) + (info (mode-to-commit q.yaki pax all mod)) + :: + :: Plumbing commit + :: + :: Guaranteed to finish in one event. + :: + :: XX needs to check that head is ancestor of tako + :: XX needs to check tako in rang + :: XX needs to check that commit doesn't have same date + :: + ++ park + =/ check-sane | + |^ + |= [updated=? =yoki =rang] + ^+ ..park + =: hut.ran (~(uni by hut.rang) hut.ran) + lat.ran (~(uni by lat.rang) lat.ran) + == + =/ new-data=(map path (each page lobe)) + ?- -.yoki + %& q.p.yoki + %| (~(run by q.p.yoki) |=(=lobe |+lobe)) + == + =/ old-lobes=(map path lobe) + ?: =(0 let.dom) + ~ + q:(aeon-to-yaki:ze let.dom) + =/ [deletes=(set path) changes=(map path (each page lobe))] + (get-changes old-lobes new-data) + ~| [from=let.dom deletes=deletes changes=~(key by changes)] + :: + :: promote ford cache + :: promote and fill in ankh + :: promote and fill in mime cache + :: + =/ sys-changes (need-sys-update changes) + ?: ?& =(%home syd) + !updated + |(!=(~ sys-changes) !=(~ (need-vane-update changes))) + == + (sys-update yoki new-data changes) + =. ..park + %- emil + =/ changed=(set path) ~(key by changes) + =/ existed=(set path) ~(key by old-lobes) + %^ print deletes + (~(int in changed) existed) + (~(dif in changed) existed) + :: clear caches if zuse reloaded + :: + =/ is-zuse-new=? !=(~ sys-changes) + =. fod.dom + ?: is-zuse-new + *ford-cache + (promote-ford fod.dom deletes ~(key by changes)) + =. fer.dom `(build-reef fer.dom ~(key by changes) new-data) + =? ank.dom is-zuse-new *ankh + =? changes is-zuse-new + (changes-for-upgrade old-lobes deletes changes) + :: + =/ =args:ford:fusion + [zuse:(need fer.dom) ank.dom deletes changes lat.ran fod.dom] + :: + =^ change-cages ford-cache.args + (checkout-changes args changes) + =/ sane-continuation (sane-changes changes change-cages) + =/ new-blobs=(map lobe blob) + %- malt + %+ turn ~(tap by change-cages) + |= [=path =lobe =cage] + [lobe %direct lobe [p q.q]:cage] + =/ data=(map path lobe) + %- ~(urn by new-data) + |= [=path value=(each page lobe)] + ?- -.value + %| p.value + %& lobe:(~(got by change-cages) path) + == + =/ =yaki + ?- -.yoki + %& (make-yaki p.p.yoki data now) + %| ?> =(data q.p.yoki) + p.yoki + == + =: let.dom +(let.dom) + hit.dom (~(put by hit.dom) +(let.dom) r.yaki) + hut.ran (~(put by hut.ran) r.yaki yaki) + lat.ran (~(uni by new-blobs) lat.ran) + == + =. file-store.args lat.ran + :: + =^ ankh ford-cache.args + (checkout-ankh args deletes change-cages ank.dom) + =/ null (sane-ankh sane-continuation ankh) + =. ankh.args ankh + =. ank.dom ankh + =^ mim ford-cache.args + (checkout-mime args deletes ~(key by changes)) + =. mim.dom (apply-changes-to-mim mim.dom mim) + =. fod.dom ford-cache.args + :: + wake:(ergo mim) + :: + :: Find which files changed or were deleted + :: + ++ get-changes + |= [old=(map path lobe) new=(map path (each page lobe))] + ^- [deletes=(set path) changes=(map path (each page lobe))] + =/ old=(map path (each page lobe)) + (~(run by old) |=(=lobe |+lobe)) + :* %- silt ^- (list path) + %+ murn ~(tap by (~(uni by old) new)) + |= [=path *] + ^- (unit ^path) + =/ a (~(get by new) path) + =/ b (~(get by old) path) + ?: |(=(a b) !=(~ a)) + ~ + `path + :: + %- malt ^- (list [path (each page lobe)]) + %+ murn ~(tap by (~(uni by old) new)) + |= [=path *] + ^- (unit [^path (each page lobe)]) + =/ a (~(get by new) path) + =/ b (~(get by old) path) + ?: |(=(a b) ?=(~ a)) + ~ + `[path u.a] + == + :: Find all files for full desk rebuild + :: + ++ changes-for-upgrade + |= $: old=(map path lobe) + deletes=(set path) + changes=(map path (each page lobe)) + == + ^+ changes + =. old + %+ roll ~(tap in deletes) + |= [pax=path old=_old] + (~(del by old) pax) + =/ pre=_changes (~(run by old) |=(lob=lobe |+lob)) + (~(uni by pre) changes) + :: + :: Keep any parts of the ford cache whose dependencies didn't change + :: + :: Make sure to invalidate any paths whose '-'s or '/'s could be + :: converted in an import; i.e. /mar, /lib, and /sur hoon files. + :: + ++ promote-ford + |= [=ford-cache deletes=(set path) changes=(set path)] + ^+ ford-cache + =/ invalid=(set path) (~(uni in deletes) changes) + =. invalid + %- ~(gas in invalid) + %- zing + %+ turn ~(tap in invalid) + |= pax=path + ^- (list path) + =/ xap=path (flop pax) + ?. &(=(%hoon (head xap)) ?=([?(%mar %sur %lib) @ @ *] pax)) + ~ + =- (turn - |=(suf=path [i.pax (snoc suf %hoon)])) + %- segments + %- crip + =/ xup (tail xap) :: lose %hoon extension + =/ pux (tail (flop xup)) :: lose static prefix + %+ turn (tail (spud pux)) :: lose leading '/' + |=(c=@tD `@tD`?:(=('/' c) '-' c)) :: convert '/' to '-' + :: + :* ((invalidate path vase) vases.ford-cache invalid) + ((invalidate mark dais) marks.ford-cache invalid) + ((invalidate mars tube) casts.ford-cache invalid) + == + :: + ++ invalidate + |* [key=mold value=mold] + |= [cache=(map key [value dez=(set path)]) invalid=(set path)] + =/ builds=(list [key value dez=(set path)]) ~(tap by cache) + |- ^+ cache + ?~ builds + ~ + ?: ?=(^ (~(int in dez.i.builds) invalid)) + $(builds t.builds) + (~(put by $(builds t.builds)) i.builds) + :: + ++ build-reef + |= $: fer=(unit reef-cache) + invalid=(set path) + data=(map path (each page lobe)) + == + ^- reef-cache + ?: =(%home syd) + [!>(..ride) !>(..is) !>(..zuse)] + |^ + ?: |(?=(~ fer) (~(has in invalid) /sys/hoon/hoon)) + =/ [home=? hoon=vase] + ?: (same-as-home /sys/hoon/hoon) + &+!>(..ride) + |+build-hoon + :- hoon + =/ [home=? arvo=vase] + ?: &(home (same-as-home /sys/arvo/hoon)) + &+!>(..is) + |+(build-arvo hoon) + :- arvo + ?: &(home (same-as-home /sys/zuse/hoon)) + !>(..zuse) + (build-zuse arvo) + :- hoon.u.fer + ?: (~(has in invalid) /sys/arvo/hoon) + =/ [home=? arvo=vase] + ?: &((same-as-home /sys/hoon/hoon) (same-as-home /sys/arvo/hoon)) + &+!>(..is) + |+(build-arvo hoon.u.fer) + :- arvo + ?: &(home (same-as-home /sys/zuse/hoon)) + !>(..zuse) + (build-zuse arvo) + :- arvo.u.fer + ?: (~(has in invalid) /sys/zuse/hoon) + ?: ?& (same-as-home /sys/hoon/hoon) + (same-as-home /sys/arvo/hoon) + (same-as-home /sys/zuse/hoon) + == + !>(..zuse) + (build-zuse arvo.u.fer) + zuse.u.fer + :: + ++ build-hoon + %- road |. + ~> %slog.0^leaf+"clay: building hoon on {}" + =/ gen + ~> %mean.%hoon-parse-fail + (path-to-hoon data /sys/hoon/hoon) + ~> %mean.%hoon-compile-fail + (slot 7 (slap !>(0) gen)) + :: + ++ build-arvo + |= hoon=vase + %- road |. + ~> %slog.0^leaf+"clay: building arvo on {}" + =/ gen + ~> %mean.%arvo-parse-fail + (path-to-hoon data /sys/arvo/hoon) + ~> %mean.%arvo-compile-fail + (slap (slap hoon gen) (ream '..is')) + :: + ++ build-zuse + |= arvo=vase + %- road |. + ~> %slog.0^leaf+"clay: building zuse on {}" + =/ gen + ~> %mean.%zuse-parse-fail + (path-to-hoon data /sys/zuse/hoon) + ~> %mean.%zuse-compile-fail + (slap arvo gen) + :: + ++ same-as-home + |= =path + ^- ? + =/ our-lobe=lobe + =/ datum (~(got by data) path) + ?- -.datum + %& (page-to-lobe %hoon (page-to-cord p.datum)) + %| p.datum + == + =/ =dome dom:(~(got by dos.rom) %home) + =/ =yaki (~(got by hut.ran) (~(got by hit.dome) let.dome)) + =(`our-lobe (~(get by q.yaki) path)) + -- + :: + ++ page-to-cord + |= =page + ^- @t + ?+ p.page ~|([%sys-bad-mark p.page] !!) + %hoon ;;(@t q.page) + %mime q.q:;;(mime q.page) + == + :: + ++ path-to-hoon + |= [data=(map path (each page lobe)) =path] + (rain path (path-to-cord data path)) + :: + ++ path-to-cord + |= [data=(map path (each page lobe)) =path] + ^- @t + =/ datum (~(got by data) path) + ?- -.datum + %& (page-to-cord p.datum) + %| (lobe-to-cord p.datum) + == + :: + ++ lobe-to-cord + |= =lobe + ^- @t + =- ?:(?=(%& -<) p.- (of-wain:format p.-)) + |- ^- (each @t wain) + =/ =blob (~(got by lat.ran) lobe) + ?- -.blob + %direct [%& ;;(@t q.q.blob)] + %delta + :- %| + %+ lurk:differ + =- ?:(?=(%| -<) p.- (to-wain:format p.-)) + $(lobe q.q.blob) + ;;((urge cord) q.r.blob) + == + :: + :: Updated q.yaki + :: + ++ checkout-changes + |= [=ford=args:ford:fusion changes=(map path (each page lobe))] + =/ cans=(list [=path change=(each page lobe)]) ~(tap by changes) + |- ^- [(map path [=lobe =cage]) ford-cache] + ?~ cans + [~ ford-cache.ford-args] + =^ cage ford-cache.ford-args + :: ~> %slog.[0 leaf+"clay: validating {(spud path.i.cans)}"] + %- wrap:fusion + (get-value:(ford:fusion ford-args) path.i.cans) + =/ =lobe + ?- -.change.i.cans + %| p.change.i.cans + :: Don't use p.change.i.cans because that's before casting to + :: the correct mark. + :: + %& (page-to-lobe [p q.q]:cage) + == + =^ so-far ford-cache.ford-args $(cans t.cans) + [(~(put by so-far) path.i.cans lobe cage) ford-cache.ford-args] + :: + :: Update ankh + :: + ++ checkout-ankh + |= $: =ford=args:ford:fusion + deletes=(set path) + changes=(map path [lobe cage]) + =ankh + == + ^+ [ankh ford-cache.ford-args] + :: Delete + :: + =. ankh + =/ dels ~(tap in deletes) + |- ^- ^ankh + =* outer-loop $ + ?~ dels + ankh + =. ankh + |- ^- ^ankh + =* inner-loop $ + ?~ i.dels + ankh(fil ~) + %= ankh + dir + %+ ~(put by dir.ankh) i.i.dels + %= inner-loop + i.dels t.i.dels + ankh (~(gut by dir.ankh) i.i.dels *^ankh) + == + == + outer-loop(dels t.dels) + :: Add/change + :: + =/ cans=(list [=path =lobe =cage]) ~(tap by changes) + |- ^+ [ankh ford-cache.ford-args] + =* outer-loop $ + ?~ cans + [ankh ford-cache.ford-args] + =^ new-ankh ford-cache.ford-args + |- ^+ [ankh ford-cache.ford-args] + =* inner-loop $ + ?^ path.i.cans + =^ child-ankh ford-cache.ford-args + %= inner-loop + path.i.cans t.path.i.cans + ankh (~(gut by dir.ankh) i.path.i.cans *^ankh) + == + :- ankh(dir (~(put by dir.ankh) i.path.i.cans child-ankh)) + ford-cache.ford-args + [ankh(fil `[lobe.i.cans cage.i.cans]) ford-cache.ford-args] + =. ankh new-ankh + outer-loop(cans t.cans) + :: + :: Print notification to console + :: + ++ print + |= [deletes=(set path) changes=(set path) additions=(set path)] + ^- (list move) + ?~ hun + ~ + ?: =(0 let.dom) + ~ + |^ + ;: weld + (paths-to-notes '-' deletes) + (paths-to-notes ':' changes) + (paths-to-notes '+' additions) + == + :: + ++ paths-to-notes + |= [prefix=@tD paths=(set path)] + %+ turn ~(tap in paths) + |= =path + [u.hun %give %note prefix (path-to-tank path)] + :: + ++ path-to-tank + |= =path + =/ pre=^path ~[(scot %p our) syd (scot %ud +(let.dom))] + :+ %rose ["/" "/" ~] + %+ turn (weld pre path) + |= a=cord + ^- tank + ?: ((sane %ta) a) + [%leaf (trip a)] + [%leaf (dash:us (trip a) '\'' ~)] + -- + :: + :: Check sanity + :: + ++ sane-changes + |= $: changes=(map path (each page lobe)) + change-cages=(map path [lobe cage]) + == + ^- (unit [(map path [lobe cage]) args:ford:fusion]) + ?. check-sane + ~ + =/ tak=(unit tako) (~(get by hit.dom) let.dom) + ?~ tak + ~ + =/ =yaki (~(got by hut.ran) u.tak) + :: Assert all blobs hash to their lobe + :: + =/ foo + %- ~(urn by lat.ran) + |= [=lobe =blob] + ?: ?=(%delta -.blob) + ~ + =/ actual-lobe=^lobe `@uv`(page-to-lobe q.blob) + ~| [lobe p.blob actual-lobe] + ?> &(=(lobe p.blob) =(lobe actual-lobe)) + ~ + :: Assert we calculated the same change-cages w/o cache + :: + :: XX remove deletes + :: + =/ all-changes=(map path (each page lobe)) + =/ original=(map path (each page lobe)) + (~(run by q.yaki) |=(=lobe |+lobe)) + (~(uni by original) changes) + =/ =args:ford:fusion + [zuse:(need fer.dom) *ankh ~ all-changes lat.ran *ford-cache] + =^ all-change-cages ford-cache.args + (checkout-changes args all-changes) + =/ ccs=(list [=path =lobe =cage]) ~(tap by change-cages) + |- ^+ *sane-changes + ?^ ccs + ?. =(`[lobe cage]:i.ccs (~(get by all-change-cages) path.i.ccs)) + ~| not-same-cages+path.i.ccs + !! + $(ccs t.ccs) + `[all-change-cages args] + :: + ++ sane-ankh + |= $: $= cont + (unit [all-changes=(map path [lobe cage]) =ford=args:ford:fusion]) + =test=ankh + == + ?. check-sane + ~ + :: Assert all new lobes are reachable. + :: + :: Needs to run after dome is updated + :: + =/ tak=(unit tako) (~(get by hit.dom) let.dom) + ?~ tak + ~ + =/ =yaki (~(got by hut.ran) u.tak) + =/ files=(list [=path =lobe]) ~(tap by q.yaki) + |- ^+ *sane-ankh + ?^ files + ?. (~(has by lat.ran) lobe.i.files) + ~| missing-lobe=[path lobe] + !! + $(files t.files) + :: + :: Assert we can rebuild the ankh + :: + ?~ cont + ~ + =+ u.cont + =^ ankh ford-cache.ford-args + (checkout-ankh ford-args ~ all-changes *ankh) + =| =path + |- ^- ~ + =* loop $ + =/ fil (bind fil.ankh |=([=lobe =cage] [lobe p.cage q.q.cage])) + =/ test (bind fil.ankh |=([=lobe =cage] [lobe p.cage q.q.cage])) + ?. =(fil test) + ~| [%not-same-file path ?=(~ fil.ankh) ?=(~ fil.test-ankh)] + ~| ?~(fil.ankh ~ [[p p.q]:u.fil.ankh `@uv`(page-to-lobe [p q.q]:q.u.fil.ankh)]) + ~| ?~(fil.test-ankh ~ [[p p.q]:u.fil.test-ankh `@uv`(page-to-lobe [p q.q]:q.u.fil.test-ankh)]) + !! + ?. =(~(key by dir.ankh) ~(key by dir.test-ankh)) + ~| [%not-same-children path ~(key by dir.ankh) ~(key by dir.test-ankh)] + !! + =< ~ + %+ turn ~(tap by dir.ankh) + |= [=@ta =child=^ankh] + ~| sane-ankh=[path ta] + %= loop + path (snoc path ta) + ankh child-ankh + test-ankh (~(got by dir.test-ankh) ta) + == + :: + :: Find /sys changes; does not reload on first commit + :: + ++ need-sys-update + |= changes=(map path (each page lobe)) + ^- (map path (each page lobe)) + ~+ + ?: =(0 let.dom) + ~ + %- malt + %+ skim ~(tap by changes) + |= [=path *] + ?| =(/sys/hoon/hoon path) + =(/sys/arvo/hoon path) + =(/sys/zuse/hoon path) + == + :: + ++ need-vane-update + |= changes=(map path (each page lobe)) + ^- (map path (each page lobe)) + ~+ + ?: =(0 let.dom) + ~ + %- malt + %+ skim ~(tap by changes) + |= [=path *] + =(/sys/vane (scag 2 path)) + :: + :: Delay current update until sys update is complete + :: + ++ sys-update + |= $: =yoki + data=(map path (each page lobe)) + changes=(map path (each page lobe)) + == + ^+ ..park + =/ updates + %- ~(uni by (need-sys-update changes)) + (need-vane-update changes) + ?> =(~ pud) + =. pud `[syd yoki] + |^ %. [hen %slip %c %pork ~] + =< emit + ?: (~(has by updates) /sys/hoon/hoon) + (reset &) + ?: (~(has by updates) /sys/arvo/hoon) + (reset |) + ?: (~(has by updates) /sys/zuse/hoon) + reboot + =/ vanes=(list [=path *]) ~(tap by updates) + |- ^+ ..park + ?~ vanes + ..park + ?. ?=([%sys %vane * %hoon ~] path.i.vanes) + ~& [%strange-sys-update path.i.vanes] + $(vanes t.vanes) + =. ..park (reload i.t.t.path.i.vanes) + $(vanes t.vanes) + :: + ++ reset + |= new-hoon=? + ^+ ..park + ?. new-hoon + =/ arvo=@t (path-to-cord data /sys/arvo/hoon) + =. ..park (pass-lyra hoon=~ arvo) + reboot + =/ hoon=@t (path-to-cord data /sys/hoon/hoon) + =/ arvo=@t (path-to-cord data /sys/arvo/hoon) + =. ..park (pass-lyra `hoon arvo) + reboot + :: + ++ pass-lyra + |= [hoon=(unit @t) arvo=@t] + ^+ ..park + (emit hen %pass /reset %d %flog %lyra hoon arvo) + :: + ++ reboot + =/ zuse=@t (path-to-cord data /sys/zuse/hoon) + =. ..park + %- emit + [hen %pass /reboot %d %flog %veer %$ /sys/zuse/hoon zuse] + reload-all + :: + ++ reload-all + =/ vanes=(list term) + ~[%ames %behn %clay %dill %eyre %gall %iris %jael] + |- ^+ ..park + ?~ vanes + ..park + =. ..park (reload i.vanes) + $(vanes t.vanes) + :: + ++ reload + |= =term + =/ vane=@t (path-to-cord data /sys/vane/[term]/hoon) + %- emit + =/ tip (end 3 1 term) + =/ =path /sys/vane/[term]/hoon + [hen %pass /reload %d %flog %veer tip path vane] + -- + -- + :: + :: We always say we're merging from 'ali' to 'bob'. The basic steps, + :: not all of which are always needed, are: + :: + :: -- fetch ali's desk, async in case it's remote + :: -- diff ali's desk against the mergebase + :: -- diff bob's desk against the mergebase + :: -- merge the diffs + :: -- commit + :: + ++ start-merge + |= [=ali=ship =ali=desk =case =germ] + ^+ ..start-merge + =/ =wire /merge/[syd]/(scot %p ali-ship)/[ali-desk]/[germ] + (emit hen %pass wire %c %warp ali-ship ali-desk `[%sing %v case /]) + :: + ++ merge + |= [=ali=ship =ali=desk =germ =riot] + ^+ ..merge + |^ + ?~ riot + (done %| %ali-unavailable >[ali-ship ali-desk germ]< ~) + =/ ali-dome=dome:clay !<(dome:clay q.r.u.riot) + =/ ali-yaki=yaki (~(got by hut.ran) (~(got by hit.ali-dome) let.ali-dome)) + =/ bob-yaki=(unit yaki) + ?~ let.dom + ~ + (~(get by hut.ran) (~(got by hit.dom) let.dom)) + =/ merge-result (merge-by-germ ali-yaki bob-yaki) + ?: ?=(%| -.merge-result) + (done %| p.merge-result) + ?~ p.merge-result + (done %& ~) + =. ..merge (done %& conflicts.u.p.merge-result) + (park | new.u.p.merge-result ~ lat.u.p.merge-result) + :: + ++ done + |= result=(each (set path) (pair term tang)) + ^+ ..merge + (emit hen %give %mere result) + :: + +$ merge-result [conflicts=(set path) new=yoki lat=(map lobe blob)] + ++ merge-by-germ + |= [=ali=yaki bob-yaki=(unit yaki)] + ^- (each (unit merge-result) [term tang]) + :: + :: If this is an %init merge, we set the ali's commit to be + :: bob's. + :: + ?: ?=(%init germ) + &+`[conflicts=~ new=|+ali-yaki lat=~] + :: + =/ bob-yaki (need bob-yaki) + |^ + ^- (each (unit merge-result) [term tang]) + ?- germ + :: + :: If this is a %this merge, we check to see if ali's and bob's + :: commits are the same, in which case we're done. Otherwise, we + :: check to see if ali's commit is in the ancestry of bob's, in + :: which case we're done. Otherwise, we create a new commit with + :: bob's data plus ali and bob as parents. + :: + %this + ?: =(r.ali-yaki r.bob-yaki) + &+~ + ?: (~(has in (reachable-takos:ze r.bob-yaki)) r.ali-yaki) + &+~ + :* %& ~ + conflicts=~ + new=&+[[r.bob-yaki r.ali-yaki ~] (to-yuki q.bob-yaki)] + lat=~ + == + :: + :: If this is a %that merge, we check to see if ali's and bob's + :: commits are the same, in which case we're done. Otherwise, we + :: create a new commit with ali's data plus ali and bob as + :: parents. + :: + %that + ?: =(r.ali-yaki r.bob-yaki) + &+~ + :* %& ~ + conflicts=~ + new=&+[[r.bob-yaki r.ali-yaki ~] (to-yuki q.ali-yaki)] + lat=~ + == + :: + :: If this is a %fine merge, we check to see if ali's and bob's + :: commits are the same, in which case we're done. Otherwise, we + :: check to see if ali's commit is in the ancestry of bob's, in + :: which case we're done. Otherwise, we check to see if bob's + :: commit is in the ancestry of ali's. If not, this is not a + :: fast-forward merge, so we error out. If it is, we add ali's + :: commit to bob's desk and checkout. + :: + %fine + ?: =(r.ali-yaki r.bob-yaki) + &+~ + ?: (~(has in (reachable-takos:ze r.bob-yaki)) r.ali-yaki) + &+~ + ?. (~(has in (reachable-takos:ze r.ali-yaki)) r.bob-yaki) + :~ %| %bad-fine-merge + leaf+"tried fast-forward but is not ancestor or descendant" + == + &+`[conflicts=~ new=|+ali-yaki lat=~] + :: + ?(%meet %mate %meld) + ?: =(r.ali-yaki r.bob-yaki) + &+~ + ?: (~(has in (reachable-takos:ze r.bob-yaki)) r.ali-yaki) + &+~ + ?: (~(has in (reachable-takos:ze r.ali-yaki)) r.bob-yaki) + $(germ %fine) + =/ merge-points find-merge-points + ?~ merge-points + :~ %| %merge-no-merge-base + leaf+"consider a %this or %that merge to get a mergebase" + == + =/ merge-point=yaki n.merge-points + ?. ?=(%meet germ) + =/ ali-diffs=cane (diff-base ali-yaki bob-yaki merge-point) + =/ bob-diffs=cane (diff-base bob-yaki ali-yaki merge-point) + =/ bof=(map path (unit cage)) + (merge-conflicts can.ali-diffs can.bob-diffs) + (build ali-yaki bob-yaki merge-point ali-diffs bob-diffs bof) + =/ ali-diffs=cane (calc-diffs ali-yaki merge-point) + =/ bob-diffs=cane (calc-diffs bob-yaki merge-point) + =/ both-diffs=(map path *) + %- %~ int by + %- ~(uni by `(map path *)`new.ali-diffs) + %- ~(uni by `(map path *)`cal.ali-diffs) + %- ~(uni by `(map path *)`can.ali-diffs) + `(map path *)`old.ali-diffs + %- ~(uni by `(map path *)`new.bob-diffs) + %- ~(uni by `(map path *)`cal.bob-diffs) + %- ~(uni by `(map path *)`can.bob-diffs) + `(map path *)`old.bob-diffs + ?. =(~ both-diffs) + :~ %| %meet-conflict + >~(key by both-diffs)< + leaf+"consider a %mate merge" + == + =/ not-deleted=(map path lobe) + %+ roll ~(tap by (~(uni by old.ali-diffs) old.bob-diffs)) + =< .(not-deleted q.merge-point) + |= [[pax=path ~] not-deleted=(map path lobe)] + (~(del by not-deleted) pax) + =/ hat=(map path lobe) + %- ~(uni by not-deleted) + %- ~(uni by new.ali-diffs) + %- ~(uni by new.bob-diffs) + %- ~(uni by cal.ali-diffs) + cal.bob-diffs + :* %& ~ + conflicts=~ + new=&+[[r.bob-yaki r.ali-yaki ~] (to-yuki hat)] + lat=~ + == + == + :: + ++ to-yuki + |= m=(map path lobe) + ^- (map path (each page lobe)) + (~(run by m) |=(=lobe |+lobe)) + :: + :: Find the most recent common ancestor(s). + :: + :: Pretty sure this could be a lot more efficient. + :: + ++ find-merge-points + ^- (set yaki) + %- reduce-merge-points + =+ r=(reachable-takos:ze r.ali-yaki) + |- ^- (set yaki) + ~! bob-yaki + ?: (~(has in r) r.bob-yaki) (~(put in *(set yaki)) bob-yaki) + %+ roll p.bob-yaki + |= [t=tako s=(set yaki)] + ?: (~(has in r) t) + (~(put in s) (~(got by hut.ran) t)) + (~(uni in s) ^$(bob-yaki (~(got by hut.ran) t))) + :: + :: Eliminate redundant merge-point candidates + :: + ++ reduce-merge-points + |= unk=(set yaki) + =| gud=(set yaki) + =/ zar=(map tako (set tako)) + %+ roll ~(tap in unk) + |= [yak=yaki qar=(map tako (set tako))] + (~(put by qar) r.yak (reachable-takos:ze r.yak)) + |- + ^- (set yaki) + ?~ unk gud + =+ bun=(~(del in `(set yaki)`unk) n.unk) + ?: %+ levy ~(tap by (~(uni in gud) bun)) + |= yak=yaki + !(~(has in (~(got by zar) r.yak)) r.n.unk) + $(gud (~(put in gud) n.unk), unk bun) + $(unk bun) + :: + :: The set of changes between the mergebase and one of the desks + :: being merged + :: + :: -- `new` is the set of files in the new desk and not in the + :: mergebase. + :: -- `cal` is the set of changes in the new desk from the + :: mergebase except for any that are also in the other new desk. + :: -- `can` is the set of changes in the new desk from the + :: mergebase that are also in the other new desk (potential + :: conflicts). + :: -- `old` is the set of files in the mergebase and not in the + :: new desk. + :: + +$ cane + $: new=(map path lobe) + cal=(map path lobe) + can=(map path cage) + old=(map path ~) + == + :: + :: Calculate cane knowing there are no files changed by both + :: desks + :: + ++ calc-diffs + |= [hed=yaki bas=yaki] + ^- cane + :* %- molt + %+ skip ~(tap by q.hed) + |= [pax=path lob=lobe] + (~(has by q.bas) pax) + :: + %- molt + %+ skip ~(tap by q.hed) + |= [pax=path lob=lobe] + =+ (~(get by q.bas) pax) + |(=(~ -) =([~ lob] -)) + :: + ~ + :: + %- malt ^- (list [path ~]) + %+ murn ~(tap by q.bas) + |= [pax=path lob=lobe] + ^- (unit (pair path ~)) + ?. =(~ (~(get by q.hed) pax)) + ~ + `[pax ~] + == + :: + :: Diff yak against bas where different from yuk + :: + ++ diff-base + |= [yak=yaki yuk=yaki bas=yaki] + ^- cane + =/ new=(map path lobe) + %- malt + %+ skip ~(tap by q.yak) + |= [=path =lobe] + (~(has by q.bas) path) + :: + =/ cal=(map path lobe) + %- malt ^- (list [path lobe]) + %+ murn ~(tap by q.bas) + |= [pax=path lob=lobe] + ^- (unit (pair path lobe)) + =+ a=(~(get by q.yak) pax) + =+ b=(~(get by q.yuk) pax) + ?. ?& ?=(^ a) + !=([~ lob] a) + =([~ lob] b) + == + ~ + `[pax +.a] + :: + =/ can=(map path cage) + %- malt + %+ murn ~(tap by q.bas) + |= [=path =lobe] + ^- (unit [^path cage]) + =/ in-yak (~(get by q.yak) path) + ?~ in-yak + ~ + ?: =(lobe u.in-yak) + ~ + =/ in-yuk (~(get by q.yuk) path) + ?~ in-yuk + ~ + ?: =(lobe u.in-yuk) + ~ + ?: =(u.in-yak u.in-yuk) + ~ + `[path (diff-lobes lobe u.in-yak)] + :: + =/ old=(map path ~) + %- malt ^- (list [path ~]) + %+ murn ~(tap by q.bas) + |= [pax=path lob=lobe] + ?. =(~ (~(get by q.yak) pax)) + ~ + (some pax ~) + :: + [new cal can old] + :: + :: These can/should save their caches + :: + ++ lobe-to-cage + |= =lobe + ^- cage + =^ =page fod.dom + %- wrap:fusion + (lobe-to-page:(ford:fusion static-ford-args) lobe) + =^ =cage fod.dom + %- wrap:fusion + (page-to-cage:(ford:fusion static-ford-args) page) + cage + :: + ++ get-dais + |= =mark + ^- dais + =^ =dais fod.dom + %- wrap:fusion + (get-mark:(ford:fusion static-ford-args) mark) + dais + :: + :: Diff two files on bob-desk + :: + ++ diff-lobes + |= [=a=lobe =b=lobe] + ^- cage + =/ a-cage (lobe-to-cage a-lobe) + =/ b-cage (lobe-to-cage b-lobe) + ?> =(p.a-cage p.b-cage) + =/ =dais (get-dais p.a-cage) + [form:dais (~(diff dais q.a-cage) q.b-cage)] + :: + :: Merge diffs that are on the same file. + :: + ++ merge-conflicts + |= [ali-conflicts=(map path cage) bob-conflicts=(map path cage)] + ^- (map path (unit cage)) + %- ~(urn by (~(int by ali-conflicts) bob-conflicts)) + |= [=path *] + ^- (unit cage) + =/ cal=cage (~(got by ali-conflicts) path) + =/ cob=cage (~(got by bob-conflicts) path) + =/ =mark + =+ (slag (dec (lent path)) path) + ?~(- %$ i.-) + =/ =dais (get-dais mark) + =/ res=(unit (unit vase)) (~(join dais bunt:dais) q.cal q.cob) + ?~ res + `[form:dais q.cob] + ?~ u.res + ~ + `[form:dais u.u.res] + :: + :: Apply the patches in bof to get the new merged content. + :: + :: Gather all the changes between ali's and bob's commits and the + :: mergebase. This is similar to the %meet of ++merge, except + :: where they touch the same file, we use the merged versions. + :: + ++ build + |= $: ali=yaki + bob=yaki + bas=yaki + dal=cane + dob=cane + bof=(map path (unit cage)) + == + ^- (each (unit merge-result) [term tang]) + =/ both-patched=(map path cage) + %- malt + %+ murn ~(tap by bof) + |= [=path cay=(unit cage)] + ^- (unit [^path cage]) + ?~ cay + ~ + :+ ~ path + =+ (~(get by q.bas) path) + ?~ - + ~| %mate-strange-diff-no-base + !! + =/ =cage (lobe-to-cage u.-) + =/ =dais (get-dais p.cage) + ?> =(p.u.cay form.dais) + :- p.cage + (~(pact dais q.cage) q.u.cay) + =/ con=(map path *) :: 2-change conflict + %- molt + %+ skim ~(tap by bof) + |=([pax=path cay=(unit cage)] ?=(~ cay)) + =/ cab=(map path lobe) :: conflict base + %- ~(urn by con) + |= [pax=path *] + (~(got by q.bas) pax) + =. con :: change+del conflict + %- ~(uni by con) + %- malt ^- (list [path *]) + %+ skim ~(tap by old.dal) + |= [pax=path ~] + ?: (~(has by new.dob) pax) + ~| %strange-add-and-del + !! + (~(has by can.dob) pax) + =. con :: change+del conflict + %- ~(uni by con) + %- malt ^- (list [path *]) + %+ skim ~(tap by old.dob) + |= [pax=path ~] + ?: (~(has by new.dal) pax) + ~| %strange-del-and-add + !! + (~(has by can.dal) pax) + =. con :: add+add conflict + %- ~(uni by con) + %- malt ^- (list [path *]) + %+ skip ~(tap by (~(int by new.dal) new.dob)) + |= [pax=path *] + =((~(got by new.dal) pax) (~(got by new.dob) pax)) + ?: &(?=(%mate germ) ?=(^ con)) + [%| %mate-conflict ~] + =/ old=(map path lobe) :: oldies but goodies + %+ roll ~(tap by (~(uni by old.dal) old.dob)) + =< .(old q.bas) + |= [[pax=path ~] old=(map path lobe)] + (~(del by old) pax) + =/ [hot=(map path lobe) lat=(map lobe blob)] :: new content + %+ roll ~(tap by both-patched) + |= [[pax=path cay=cage] hat=(map path lobe) lat=(map lobe blob)] + =/ =blob [%direct (page-to-lobe [p q.q]:cay) [p q.q]:cay] + :- (~(put by hat) pax p.blob) + ?: (~(has by lat) p.blob) + lat + (~(put by lat) p.blob blob) + =/ hat=(map path lobe) :: all the content + %- ~(uni by old) + %- ~(uni by new.dal) + %- ~(uni by new.dob) + %- ~(uni by cal.dal) + %- ~(uni by cal.dob) + %- ~(uni by hot) + cab + =/ del=(map path ?) + (~(run by (~(uni by old.dal) old.dob)) |=(~ %|)) + =/ new &+[[r.bob r.ali ~] (~(run by hat) |=(=lobe |+lobe))] + :* %& ~ + (silt (turn ~(tap by con) head)) + new + lat + == + -- + -- + :: + :: Update mime cache + :: + ++ checkout-mime + |= $: =ford=args:ford:fusion + deletes=(set path) + changes=(set path) + == + ^- [(map path (unit mime)) ford-cache] + =/ mim=(map path (unit mime)) + =/ dels=(list path) ~(tap by deletes) + |- ^- (map path (unit mime)) + ?~ dels + ~ + (~(put by $(dels t.dels)) i.dels ~) + =/ cans=(list path) ~(tap by changes) + |- ^- [(map path (unit mime)) ford-cache] + ?~ cans + [mim ford-cache.ford-args] + =^ cage ford-cache.ford-args + ~| mime-cast-fail+i.cans + (wrap:fusion (cast-path:(ford:fusion ford-args) i.cans %mime)) + =^ mim ford-cache.ford-args $(cans t.cans) + [(~(put by mim) i.cans `!<(mime q.cage)) ford-cache.ford-args] + :: + :: Add or remove entries to the mime cache + :: + ++ apply-changes-to-mim + |= [mim=(map path mime) changes=(map path (unit mime))] + ^- (map path mime) + =/ changes-l=(list [pax=path change=(unit mime)]) + ~(tap by changes) + |- ^- (map path mime) + ?~ changes-l + mim + ?~ change.i.changes-l + $(changes-l t.changes-l, mim (~(del by mim) pax.i.changes-l)) + $(changes-l t.changes-l, mim (~(put by mim) [pax u.change]:i.changes-l)) + :: + :: Emit update to unix sync + :: + ++ ergo + |= mim=(map path (unit mime)) + ^+ ..park + =/ must (must-ergo her syd mon (turn ~(tap by mim) head)) + %- emil + %+ turn ~(tap by must) + |= [pot=term len=@ud pak=(set path)] + :* (need hez) %give %ergo pot + %+ turn ~(tap in pak) + |= pax=path + [(slag len pax) (~(got by mim) pax)] + == + :: + :: Output is a map of mount points to {length-of-mounted-path set-of-paths}. + :: + ++ must-ergo + |= [our=ship syd=desk mon=(map term beam) can/(list path)] + ^- (map term (pair @ud (set path))) + %- malt ^- (list (trel term @ud (set path))) + %+ murn ~(tap by mon) + |= {nam/term bem/beam} + ^- (unit (trel term @ud (set path))) + =- ?~(- ~ `[nam (lent s.bem) (silt `(list path)`-)]) + %+ skim can + |= pax/path + &(=(p.bem our) =(q.bem syd) =((flop s.bem) (scag (lent s.bem) pax))) + :: + :: Mount a beam to unix + :: + ++ mount + |= [pot=term =case =spur] + ^+ ..mount + =/ old-mon (~(get by mon) pot) + ?^ old-mon + %- (slog >%already-mounted< >u.old-mon< ~) + ..mount + =. mon (~(put by mon) pot [her syd case] spur) + =/ =yaki (~(got by hut.ran) (~(got by hit.dom) let.dom)) + =/ changes (~(run by q.yaki) |=(=lobe |+lobe)) + =/ =args:ford:fusion + [zuse:(need fer.dom) ank.dom ~ changes lat.ran fod.dom] + =^ mim ford-cache.args + (checkout-mime args ~ ~(key by changes)) + =. mim.dom (apply-changes-to-mim mim.dom mim) + =. fod.dom ford-cache.args + (ergo mim) + :: :: Set permissions for a node. :: ++ perm @@ -2998,203 +2581,16 @@ ++ start-request |= [for=(unit ship) rav=rave] ^+ ..start-request - =/ [new-sub=(unit rove) sub-results=(list sub-result)] - (try-fill-sub for (rave-to-rove rav)) + =^ [new-sub=(unit rove) sub-results=(list sub-result)] fod.dom + (try-fill-sub for (rave-to-rove rav)) =. ..start-request (send-sub-results sub-results [hen ~ ~]) ?~ new-sub ..start-request (duce for u.new-sub) :: - :: Continue committing - :: - ++ take-commit - |= =sign - ^+ +> - =/ m commit-clad - ?~ act - ~|(%no-active-write !!) - ?. ?=(%commit -.eval-data.u.act) - ~|(%active-not-commit !!) - =^ r=[moves=(list move) =eval-result:eval:m] commit.eval-data.u.act - (take:eval:m commit.eval-data.u.act hen /commit/[syd] now ran sign) - => .(+>.$ (emil moves.r)) :: TMI - ?- -.eval-result.r - %next +>.$ - %fail (fail-commit err.eval-result.r) - %done (done-commit value.eval-result.r) - == - :: - :: Don't release effects or apply state changes; print error - :: - ++ fail-commit - |= err=(pair term tang) - ^+ +> - =? +>.$ ?=(^ q.err) - %- emit - :* (need hun) %give %note - '!' %rose [" " "" ""] - leaf+"clay commit error" - leaf+(trip p.err) - q.err - == - finish-write - :: - :: Release effects and apply state changes - :: - ++ done-commit - |= [=dome =rang] - ^+ +> - =: dom dome - hut.ran (~(uni by hut.rang) hut.ran) - lat.ran (~(uni by lat.rang) lat.ran) - == - =. +>.$ wake - finish-write - :: - :: Continue merging - :: - ++ take-merge - |= =sign - ^+ +> - =/ m merge-clad - ?~ act - ~|(%no-active-write !!) - ?. ?=(%merge -.eval-data.u.act) - ~|(%active-not-merge !!) - =^ r=[moves=(list move) =eval-result:eval:m] merge.eval-data.u.act - (take:eval:m merge.eval-data.u.act hen /merge/[syd] now ran sign) - => .(+>.$ (emil moves.r)) :: TMI - ?- -.eval-result.r - %next +>.$ - %fail (fail-merge err.eval-result.r) - %done (done-merge value.eval-result.r) - == - :: - :: Don't release effects or apply state changes; print error - :: - ++ fail-merge - |= err=(pair term tang) - ^+ +> - =. +>.$ - (emit [hen %slip %b %drip !>([%mere %| err])]) - finish-write - :: - :: Release effects and apply state changes - :: - ++ done-merge - |= [conflicts=(set path) =dome =rang] - ^+ +> - =. +>.$ (emit [hen %slip %b %drip !>([%mere %& conflicts])]) - =: dom dome - hut.ran (~(uni by hut.rang) hut.ran) - lat.ran (~(uni by lat.rang) lat.ran) - == - =. +>.$ wake - finish-write - :: - :: Continue mounting - :: - ++ take-mount - |= =sign - ^+ +> - =/ m mount-clad - ?~ act - ~|(%no-active-write !!) - ?. ?=(%mount -.eval-data.u.act) - ~|(%active-not-mount !!) - =^ r=[moves=(list move) =eval-result:eval:m] mount.eval-data.u.act - (take:eval:m mount.eval-data.u.act hen /mount/[syd] now ran sign) - => .(+>.$ (emil moves.r)) :: TMI - ?- -.eval-result.r - %next +>.$ - %fail (fail-mount err.eval-result.r) - %done (done-mount value.eval-result.r) - == - :: - :: Don't release effects or apply state changes; print error - :: - ++ fail-mount - |= err=(pair term tang) - ^+ +> - %- (slog leaf+"mount failed" leaf+(trip p.err) q.err) - finish-write - :: - :: Release effects and apply state changes - :: - ++ done-mount - |= [new-mon=(pair term beam) mim=(map path mime)] - ^+ +> - =: mon (~(put by mon) new-mon) - mim.dom mim - == - finish-write - :: - :: Start next item in write queue - :: - ++ finish-write - ^+ . - =. act ~ - ?~ cue - . - =/ =duct duct:(need ~(top to cue)) - (emit [duct %pass /queued-request %b %wait now]) - :: - :: Continue foreign request - :: - ++ take-foreign-request - |= [inx=@ud =sign] - ^+ +> - =/ m request-clad - ?> ?=(^ ref) - ?~ request=(~(get by pur.u.ref) inx) - ~|(%no-active-foreign-request !!) - =^ r=[moves=(list move) =eval-result:eval:m] eval-form.u.request - %- take:eval:m - :* eval-form.u.request - hen - /foreign-request/(scot %p her)/[syd]/(scot %ud inx) - now - ran - sign - == - => .(+>.$ (emil moves.r)) :: TMI - ?- -.eval-result.r - %next +>.$ - %fail (fail-foreign-request inx rand.u.request err.eval-result.r) - %done (done-foreign-request inx rand.u.request value.eval-result.r) - == - :: - :: Fail foreign request - :: - ++ fail-foreign-request - |= [inx=@ud =rand err=(pair term tang)] - ^+ +> - %- (slog leaf+"foreign request failed" leaf+(trip p.err) q.err) - ?> ?=(^ ref) - =/ =mood [p.p q.p q]:rand - =: haw.u.ref (~(put by haw.u.ref) mood ~) - bom.u.ref (~(del by bom.u.ref) inx) - fod.u.ref (~(del by fod.u.ref) hen) - == - wake - :: - :: Finish foreign request - :: - ++ done-foreign-request - |= [inx=@ud =rand =cage] - ^+ +> - ?> ?=(^ ref) - =/ =mood [p.p q.p q]:rand - =: haw.u.ref (~(put by haw.u.ref) mood `cage) - bom.u.ref (~(del by bom.u.ref) inx) - fod.u.ref (~(del by fod.u.ref) hen) - == - wake - :: :: Called when a foreign ship answers one of our requests. :: - :: If it's a `%many` request, start a `+foreign-update`. Else start - :: a `+foreign-request`. + :: If it's a `%many` request, process in +take-foreign-update :: :: After updating ref (our request manager), we handle %x, %w, and %y :: responses. For %x, we call ++validate-x to validate the type of @@ -3208,13 +2604,7 @@ ?~ ruv +>.$ =/ rav=rave q.u.ruv ?: ?=(%many -.rav) - :: add to update queue - :: - =. waiting.pud.u.ref - (~(put to waiting.pud.u.ref) inx rut) - :: start update if nothing active - :: - start-next-foreign-update + (take-foreign-update inx rut) ?~ rut :: nothing here, so cache that :: @@ -3223,102 +2613,155 @@ ?. ?=($sing -.rav) haw.u.ref (~(put by haw.u.ref) mood.rav ~) == - :: something here, so kick off a validator + |^ + =/ result=(unit cage) (validate u.rut) + =/ =mood [p.p q.p q]:u.rut + =: haw.u.ref (~(put by haw.u.ref) mood result) + bom.u.ref (~(del by bom.u.ref) inx) + fod.u.ref (~(del by fod.u.ref) hen) + == + wake + :: something here, so validate :: - =. pur.u.ref - %+ ~(put by pur.u.ref) - inx - :- u.rut - %- from-form:eval:request-clad - ((foreign-request our her syd now) rav u.rut) - (take-foreign-request inx clad-init-sign) + ++ validate + |= =rand + ^- (unit cage) + ?- p.p.rand + $a ~| %no-big-ford-builds-across-network-for-now !! + $b ~| %i-guess-you-ought-to-build-your-own-marks !! + $c ~| %casts-should-be-compiled-on-your-own-ship !! + $d ~| %totally-temporary-error-please-replace-me !! + $p ~| %requesting-foreign-permissions-is-invalid !! + $r ~| %no-cages-please-they-are-just-way-too-big !! + $s ~| %please-dont-get-your-takos-over-a-network !! + $t ~| %requesting-foreign-directory-is-vaporware !! + $u ~| %prolly-poor-idea-to-get-rang-over-network !! + $v ~| %weird-shouldnt-get-v-request-from-network !! + $z `(validate-z r.rand) + $w `(validate-w r.rand) + $x (validate-x [p.p q.p q r]:rand) + $y `[p.r.rand !>(;;(arch q.r.rand))] + == + :: + :: Make sure the incoming data is a %w response + :: + ++ validate-w + |= =page + ^- cage + :- p.page + ?+ p.page ~| %strange-w-over-nextwork !! + $cass !>(;;(cass q.page)) + $null [[%atom %n ~] ~] + $nako !>(~|([%molding [&1 &2 &3]:q.page] ;;(nako q.page))) + == + :: + :: Make sure that incoming data is of the mark it claims to be. + :: + ++ validate-x + |= [car=care cas=case pax=path peg=page] + ^- (unit cage) + =/ vale-result + %- mule |. + %- wrap:fusion + (page-to-cage:(ford:fusion static-ford-args) peg) + ?: ?=(%| -.vale-result) + %- (slog >%validate-x-failed< p.vale-result) + ~ + `-.p.vale-result + :: + :: Make sure the incoming data is a %z response + :: + ++ validate-z + |= =page + ^- cage + ?> ?=(%uvi p.page) + :- p.page + !>(;;(@uvI q.page)) + -- :: - :: Continue foreign update + :: A full foreign update. Validate and apply to our local cache of + :: their state. :: ++ take-foreign-update - |= =sign - ^+ +> - =/ m update-clad + |= [inx=@ud rut=(unit rand)] + ^+ ..take-foreign-update ?> ?=(^ ref) - ?~ eval-data.pud.u.ref - ~|(%no-active-foreign-update !!) - =* ed u.eval-data.pud.u.ref - =/ inx inx.ed - =^ r=[moves=(list move) =eval-result:eval:m] - eval-form.u.eval-data.pud.u.ref - %- take:eval:m - :* eval-form.ed - hen - /foreign-update/(scot %p her)/[syd] - now - ran - sign - == - => .(+>.$ (emil moves.r)) :: TMI - ?- -.eval-result.r - %next +>.$ - %fail (fail-foreign-update inx err.eval-result.r) - %done (done-foreign-update inx value.eval-result.r) - == - :: - :: Fail foreign update - :: - ++ fail-foreign-update - |= [inx=@ud err=(pair term tang)] - ^+ +> - %- (slog leaf+"foreign update failed" leaf+(trip p.err) q.err) - ?> ?=(^ ref) - =: bom.u.ref (~(del by bom.u.ref) inx) - fod.u.ref (~(del by fod.u.ref) hen) - == - =. +>.$ =<(?>(?=(^ ref) .) wake) - =. eval-data.pud.u.ref ~ - start-next-foreign-update - :: - :: Finish foreign update - :: - ++ done-foreign-update - |= [inx=@ud res=(unit [new-lim=@da =new=dome =new=rang])] - ^+ +> - ?> ?=(^ ref) - =: bom.u.ref (~(del by bom.u.ref) inx) - fod.u.ref (~(del by fod.u.ref) hen) - == - ?~ res - wake - =: lim new-lim.u.res - dom new-dome.u.res - ran new-rang.u.res - == - =. +>.$ =<(?>(?=(^ ref) .) wake) - =. eval-data.pud.u.ref ~ - start-next-foreign-update - :: - :: Kick off the the next foreign update in the queue - :: - ++ start-next-foreign-update - ^+ . - ?> ?=(^ ref) - ?. =(~ eval-data.pud.u.ref) - . - ?: =(~ waiting.pud.u.ref) - . - =^ next=[inx=@ud rut=(unit rand)] waiting.pud.u.ref - ~(get to waiting.pud.u.ref) - =/ ruv (~(get by bom.u.ref) inx.next) + =/ ruv (~(get by bom.u.ref) inx) ?~ ruv - ~& [%clay-foreign-update-lost her syd inx.next] - start-next-foreign-update + ~& [%clay-foreign-update-lost her syd inx] + ..take-foreign-update =. hen p.u.ruv =/ =rave q.u.ruv ?> ?=(%many -.rave) - =. eval-data.pud.u.ref - :- ~ - :+ inx.next - rut.next - %- from-form:eval:update-clad - ((foreign-update our her syd now) moat.rave rut.next lim dom ran) - (take-foreign-update clad-init-sign) + |^ + ?~ rut + done + =. lim ?.(?=(%da -.to.moat.rave) lim p.to.moat.rave) + ?> ?=(%nako p.r.u.rut) + =/ nako ;;(nako q.r.u.rut) + =. ..take-foreign-update + =< ?>(?=(^ ref) .) + (apply-foreign-update nako) + done + :: + ++ done + =: bom.u.ref (~(del by bom.u.ref) inx) + bom.u.ref (~(del by bom.u.ref) hen) + == + =<(?>(?=(^ ref) .) wake) + :: + :: When we get a %w foreign update, store this in our state. + :: + :: We get the commits and blobs from the nako and add them to our + :: object store, then we update the map of aeons to commits and the + :: latest aeon. + :: + ++ apply-foreign-update + |= =nako + ^+ ..take-foreign-update + :: hit: updated commit-hashes by @ud case + :: nut: new commit-hash/commit pairs + :: hut: updated commits by hash + :: nat: new blob-hash/blob pairs + :: lat: updated blobs by hash + :: + =/ hit (~(uni by hit.dom) gar.nako) + =/ nut (turn ~(tap in lar.nako) |=(=yaki [r.yaki yaki])) + =/ hut (~(uni by (malt nut)) hut.ran) + =/ nat (turn ~(tap in bar.nako) |=(=blob [p.blob blob])) + =/ lat (~(uni by (malt nat)) lat.ran) + :: traverse updated state and sanity check + :: + =+ ~| :* %bad-foreign-update + [gar=gar.nako let=let.nako nut=(turn nut head) nat=(turn nat head)] + [hitdom=hit.dom letdom=let.dom] + == + ?: =(0 let.nako) + ~ + =/ =aeon 1 + |- ^- ~ + =/ =tako + ~| [%missing-aeon aeon] (~(got by hit) aeon) + =/ =yaki + ~| [%missing-tako tako] (~(got by hut) tako) + =+ %+ turn + ~(tap by q.yaki) + |= [=path =lobe] + ~| [%missing-blob path lobe] + ?> (~(has by lat) lobe) + ~ + ?: =(let.nako aeon) + ~ + $(aeon +(aeon)) + :: produce updated state + :: + =: let.dom (max let.nako let.dom) + hit.dom hit + hut.ran hut + lat.ran lat + == + ..take-foreign-update + -- :: :: fire function if request is in future :: @@ -3397,8 +2840,8 @@ :: drop forgotten roves :: $(old-subs t.old-subs) - =/ [new-sub=(unit rove) sub-results=(list sub-result)] - (try-fill-sub wove.i.old-subs) + =^ [new-sub=(unit rove) sub-results=(list sub-result)] fod.dom + (try-fill-sub wove.i.old-subs) =. ..wake (send-sub-results sub-results ducts.i.old-subs) =. new-subs ?~ new-sub @@ -3410,7 +2853,7 @@ :: ++ try-fill-sub |= [for=(unit ship) rov=rove] - ^- [new-sub=(unit rove) (list sub-result)] + ^- [[new-sub=(unit rove) (list sub-result)] ford-cache] ?- -.rov %sing =/ cache-value=(unit (unit cage)) @@ -3418,6 +2861,7 @@ ?^ cache-value :: if we have a result in our cache, produce it :: + :_ fod.dom :- ~ ?~ u.cache-value [%blub ~]~ @@ -3426,10 +2870,10 @@ :: =/ aeon=(unit aeon) (case-to-aeon case.mood.rov) ?~ aeon - [`rov ~] + [[`rov ~] fod.dom] :: we have the appropriate aeon, so read in the data :: - =/ value=(unit (unit (each cage lobe))) + =^ value=(unit (unit (each cage lobe))) fod.dom (read-at-aeon:ze for u.aeon mood.rov) ?~ value :: We don't have the data directly, which is potentially @@ -3437,12 +2881,12 @@ :: ?: =(0 u.aeon) ~& [%clay-sing-indirect-data-0 `path`[syd '0' path.mood.rov]] - [~ ~] + [[~ ~] fod.dom] ~& [%clay-sing-indirect-data desk=syd mood=mood.rov aeon=u.aeon] - [`rov ~] + [[`rov ~] fod.dom] :: we have the data, so we produce the results :: - [~ [%balk u.value mood.rov]~] + [[~ [%balk u.value mood.rov]~] fod.dom] :: :: %next is just %mult with one path, so we pretend %next = %mult here. :: @@ -3466,41 +2910,48 @@ ?> ?=(%mult -.rov) :: we will either respond or store the maybe updated request. :: - =; res=(each (map mood (unit (each cage lobe))) rove) + =; [res=(each (map mood (unit (each cage lobe))) rove) fod=ford-cache] + :_ fod ?: ?=(%& -.res) (respond p.res) (store p.res) :: recurse here on next aeon if possible/needed. :: - |- ^- (each (map mood (unit (each cage lobe))) rove) + |- ^- [(each (map mood (unit (each cage lobe))) rove) ford-cache] :: if we don't have an aeon yet, see if we have one now. :: ?~ aeon.rov =/ aeon=(unit aeon) (case-to-aeon case.mool.rov) :: if we still don't, wait. :: - ?~ aeon |+rov + ?~ aeon [|+rov fod.dom] :: if we do, update the request and retry. :: $(aeon.rov `+(u.aeon), old-cach.rov ~, new-cach.rov ~) :: if old isn't complete, try filling in the gaps. :: - =? old-cach.rov !(complete old-cach.rov) + =^ o fod.dom + ?: (complete old-cach.rov) + [old-cach.rov fod.dom] (read-unknown mool.rov(case [%ud (dec u.aeon.rov)]) old-cach.rov) + =. old-cach.rov o :: if the next aeon we want to compare is in the future, wait again. :: =/ next-aeon=(unit aeon) (case-to-aeon [%ud u.aeon.rov]) - ?~ next-aeon |+rov + ?~ next-aeon [|+rov fod.dom] :: if new isn't complete, try filling in the gaps. :: - =? new-cach.rov !(complete new-cach.rov) + =^ n fod.dom + ?: (complete new-cach.rov) + [new-cach.rov fod.dom] (read-unknown mool.rov(case [%ud u.aeon.rov]) new-cach.rov) + =. new-cach.rov n :: if they're still not both complete, wait again. :: ?. ?& (complete old-cach.rov) (complete new-cach.rov) == - |+rov + [|+rov fod.dom] :: both complete, so check if anything has changed :: =/ changes=(map mood (unit (each cage lobe))) @@ -3539,7 +2990,7 @@ :: if there are any changes, send response. if none, move on to :: next aeon. :: - ?^ changes &+changes + ?^ changes [&+changes fod.dom] $(u.aeon.rov +(u.aeon.rov), new-cach.rov ~) :: :: check again later @@ -3584,6 +3035,7 @@ :: ++ read-unknown |= [=mool hav=(map (pair care path) cach)] + ^- [_hav ford-cache] =? hav ?=(~ hav) %- malt ^- (list (pair (pair care path) cach)) %+ turn @@ -3591,12 +3043,22 @@ |= [c=care p=path] ^- [[care path] cach] [[c p] ~] - %- ~(urn by hav) - |= [[c=care p=path] o=cach] - ?^(o o (aver for c case.mool p)) + |- ^+ [hav fod.dom] + ?~ hav [hav fod.dom] + =^ lef fod.dom $(hav l.hav) + =. l.hav lef + =^ rig fod.dom $(hav r.hav) + =. r.hav rig + =/ [[=care =path] =cach] n.hav + ?^ cach + [hav fod.dom] + =^ q fod.dom (aver for care case.mool path) + =. q.n.hav q + [hav fod.dom] -- :: %many + :_ fod.dom =/ from-aeon (case-to-aeon from.moat.rov) ?~ from-aeon :: haven't entered the relevant range, so do nothing @@ -3678,9 +3140,6 @@ :: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :: - :: The useful utility functions that are common to several cores - :: - ++ util (state:[^util] dom dom ran) :: :: Other utility functions :: @@ -3695,7 +3154,13 @@ ++ aeon-to-yaki |=(=aeon (tako-to-yaki (aeon-to-tako aeon))) ++ lobe-to-blob ~(got by lat.ran) ++ tako-to-yaki ~(got by hut.ran) - ++ page-to-lobe page-to-lobe:util + ++ lobe-to-mark + |= a/lobe + => (lobe-to-blob a) + ?- - + $delta p.q + $direct p.q + == :: :: Checks whether two pieces of data (either cages or lobes) are the same. :: @@ -3746,6 +3211,23 @@ [~ ~] (data-twixt-takos (~(get by hit.dom) a) (aeon-to-tako b)) :: + :: Traverse parentage and find all ancestor hashes + :: + ++ reachable-takos :: reachable + |= p/tako + ^- (set tako) + =| s=(set tako) + |- ^- (set tako) + =. s (~(put in s) p) + =+ y=(tako-to-yaki p) + |- ^- (set tako) + ?~ p.y + s + ?: (~(has in s) i.p.y) + $(p.y t.p.y) + =. s ^$(p i.p.y) + $(p.y t.p.y) + :: :: Gets the data between two commit hashes, assuming the first is an :: ancestor of the second. :: @@ -3756,11 +3238,11 @@ ++ data-twixt-takos |= {a/(unit tako) b/tako} ^- {(set yaki) (set plop)} - =+ old=?~(a ~ (reachable-takos:util u.a)) + =+ old=?~(a ~ (reachable-takos u.a)) =/ yal/(set tako) %- silt %+ skip - ~(tap in (reachable-takos:util b)) + ~(tap in (reachable-takos b)) |=(tak/tako (~(has in old) tak)) :- (silt (turn ~(tap in yal) tako-to-yaki)) (silt (turn ~(tap in (new-lobes (new-lobes ~ old) yal)) lobe-to-blob)) @@ -3787,6 +3269,63 @@ $delta (~(put in $(lob q.q.gar)) lob) == :: + :: Probably can get rid of the cache checks because they happen in + :: ford + :: + ++ read-a + !. + |= [=aeon =path] + ^- [(unit (unit (each cage lobe))) ford-cache] + ?. =(aeon let.dom) + [~ fod.dom] + =/ cached=(unit [=vase *]) (~(get by vases.fod.dom) path) + ?^ cached + :_(fod.dom [~ ~ %& %vase !>(vase.u.cached)]) + =/ x (read-x aeon path) + ?~ x + [~ fod.dom] + ?~ u.x + [[~ ~] fod.dom] + :: should never happen at current aeon + ?: ?=(%| -.u.u.x) + [~ fod.dom] + =^ =vase fod.dom + %- wrap:fusion + (build-file:(ford:fusion static-ford-args) path) + :_(fod.dom [~ ~ %& %vase !>(vase)]) + :: + ++ read-b + !. + |= [=aeon =path] + ^- [(unit (unit (each cage lobe))) ford-cache] + ?. =(aeon let.dom) + [~ fod.dom] + ?. ?=([@ ~] path) + [[~ ~] fod.dom] + =/ cached=(unit [=dais *]) (~(get by marks.fod.dom) i.path) + ?^ cached + :_(fod.dom [~ ~ %& %dais !>(dais.u.cached)]) + =^ =dais fod.dom + %- wrap:fusion + (get-mark:(ford:fusion static-ford-args) i.path) + :_(fod.dom [~ ~ %& %dais !>(dais)]) + :: + ++ read-c + !. + |= [=aeon =path] + ^- [(unit (unit (each cage lobe))) ford-cache] + ?. =(aeon let.dom) + [~ fod.dom] + ?. ?=([@ @ ~] path) + [[~ ~] fod.dom] + =/ cached=(unit [=tube *]) (~(get by casts.fod.dom) [i i.t]:path) + ?^ cached + :_(fod.dom [~ ~ %& %tube !>(tube.u.cached)]) + =^ =tube fod.dom + %- wrap:fusion + (get-cast:(ford:fusion static-ford-args) [i i.t]:path) + :_(fod.dom [~ ~ %& %tube !>(tube)]) + :: :: Gets the permissions that apply to a particular node. :: :: If the node has no permissions of its own, we use its parent's. @@ -3858,6 +3397,83 @@ ?: =(%black mod.rul) !in-list in-list + :: +content-hash: get hash of contents (%cz hash) + :: + ++ content-hash + |= [=yaki pax=path] + ^- @uvI + =+ len=(lent pax) + =/ descendants/(list (pair path lobe)) + %+ turn + %+ skim ~(tap by (~(del by q.yaki) pax)) + |= {paf/path lob/lobe} + =(pax (scag len paf)) + |= {paf/path lob/lobe} + [(slag len paf) lob] + =+ us=(~(get by q.yaki) pax) + ?: &(?=(~ descendants) ?=(~ us)) + *@uvI + %+ roll + ^- (list (pair path lobe)) + [[~ ?~(us *lobe u.us)] descendants] + |=({{path lobe} @uvI} (shax (jam +<))) + :: +read-r: %x wrapped in a vase + :: + ++ read-r + |= [yon=aeon pax=path] + ^- (unit (unit cage)) + =/ x (read-x yon pax) + ?~ x ~ + ?~ u.x [~ ~] + ?> ?=(%& -.u.u.x) + ``[p.p.u.u.x !>(q.p.u.u.x)] + :: +read-s: produce yaki or blob for given tako or lobe + :: + ++ read-s + |= [yon=aeon pax=path] + ^- (unit (unit cage)) + ?. ?=([?(%yaki %blob %hash %cage %open %late) * ~] pax) + `~ + ?- i.pax + %yaki + =/ yak=(unit yaki) (~(get by hut.ran) (slav %uv i.t.pax)) + ?~ yak + ~ + ``yaki+[-:!>(*yaki) u.yak] + :: + %blob + =/ bol=(unit blob) (~(get by lat.ran) (slav %uv i.t.pax)) + ?~ bol + ~ + ``blob+[-:!>(*blob) u.bol] + :: + %hash + =/ yak=(unit yaki) (~(get by hut.ran) (slav %uv i.t.pax)) + ?~ yak + ~ + ``uvi+[-:!>(*@uvI) (content-hash u.yak /)] + :: + %cage + :: should save ford cache + :: + =/ =lobe (slav %uv i.t.pax) + =^ =page fod.dom + %- wrap:fusion + (lobe-to-page:(ford:fusion static-ford-args) lobe) + =^ =cage fod.dom + %- wrap:fusion + (page-to-cage:(ford:fusion static-ford-args) page) + ``cage+[-:!>(*^cage) cage] + :: + %open + ``open+!>(prelude:(ford:fusion static-ford-args)) + :: + %late + :^ ~ ~ %cass + ?~ let.dom + !>([0 *@da]) + !>([let.dom t:(~(got by hut.ran) (~(got by hit.dom) let.dom))]) + == :: +read-t: produce the list of paths within a yaki with :pax as prefix :: ++ read-t @@ -3917,7 +3533,7 @@ |= {yon/aeon pax/path} ^- (unit (unit {$dome (hypo dome:clay)})) ?: (lth yon let.dom) - :* ~ ~ %dome -:!>(%dome) + :* ~ ~ %dome -:!>(*dome:clay) ^- dome:clay :* ank=`[[%ank-in-old-v-not-implemented *ankh] ~ ~] let=yon @@ -3943,9 +3559,51 @@ ?: =(0 u.aey) `@da`0 t:(aeon-to-yaki u.aey) :: - :: Gets the data at a node. + :: Get the data at a node. :: - ++ read-x (cury read-x:util ?=(~ ref)) + :: If it's in our ankh (current state cache), we can just produce + :: the result. Otherwise, we've got to look up the node at the + :: aeon to get the content hash, use that to find the blob, and use + :: the blob to get the data. We also special-case the hoon mark + :: for bootstrapping purposes. + :: + ++ read-x + |= [yon=aeon pax=path] + ^- (unit (unit (each cage lobe))) + ?: =(0 yon) + [~ ~] + =+ tak=(~(get by hit.dom) yon) + ?~ tak + ~ + ?: &(?=(~ ref) =(yon let.dom)) + :- ~ + %+ bind + fil.ank:(descend-path:(zu ank.dom) pax) + |=(a/{p/lobe q/cage} [%& q.a]) + =+ yak=(tako-to-yaki u.tak) + =+ lob=(~(get by q.yak) pax) + ?~ lob + [~ ~] + =+ mar=(lobe-to-mark u.lob) + :: should convert any lobe to cage + :: + ?. ?=($hoon mar) + [~ ~ %| u.lob] + :^ ~ ~ %& + :+ mar [%atom %t ~] + |- ^- @t :: (urge cord) would be faster + =+ bol=(lobe-to-blob u.lob) + ?: ?=($direct -.bol) + ;;(@t q.q.bol) + ?> ?=($delta -.bol) + =+ txt=$(u.lob q.q.bol) + ?> ?=($txt-diff p.r.bol) + =+ dif=;;((urge cord) q.r.bol) + =, format + =+ pac=(of-wain (lurk:differ (to-wain (cat 3 txt '\0a')) dif)) + ?~ pac + '' + (end 3 (dec (met 3 pac)) pac) :: :: Gets an arch (directory listing) at a node. :: @@ -3985,30 +3643,7 @@ =+ tak=(~(get by hit.dom) yon) ?~ tak ~ - =+ yak=(tako-to-yaki u.tak) - =+ len=(lent pax) - :: ~& read-z+[yon=yon qyt=~(wyt by q.yak) pax=pax] - =/ descendants/(list (pair path lobe)) - :: ~& %turning - :: =- ~& %turned - - %+ turn - :: ~& %skimming - :: =- ~& %skimmed - - %+ skim ~(tap by (~(del by q.yak) pax)) - |= {paf/path lob/lobe} - =(pax (scag len paf)) - |= {paf/path lob/lobe} - [(slag len paf) lob] - =+ us=(~(get by q.yak) pax) - ^- (unit (unit {$uvi (hypo @uvI)})) - :^ ~ ~ %uvi - :- -:!>(*@uvI) - ?: &(?=(~ descendants) ?=(~ us)) - *@uvI - %+ roll - ^- (list (pair path lobe)) - [[~ ?~(us *lobe u.us)] descendants] - |=({{path lobe} @uvI} (shax (jam +<))) + [~ ~ %uvi -:!>(*@uvI) (content-hash (tako-to-yaki u.tak) pax)] :: :: Get a value at an aeon. :: @@ -4019,11 +3654,18 @@ :: ++ read-at-aeon :: read-at-aeon:ze |= [for=(unit ship) yon=aeon mun=mood] :: seek and read - ^- (unit (unit (each cage lobe))) + ^- [(unit (unit (each cage lobe))) ford-cache] + =* fod fod.dom ?. |(?=(~ for) (may-read u.for care.mun yon path.mun)) - ~ + [~ fod] + :: virtualize to catch and produce deterministic failures + :: + !. + =- ?:(?=(%& -<) p.- ((slog p.-) [[~ ~] fod])) + %- mule |. ?- care.mun %d + :_ fod :: XX this should only allow reads at the current date :: ?: !=(our her) @@ -4032,16 +3674,37 @@ ~&(%no-cd-path [~ ~]) [~ ~ %& %noun !>(~(key by dos.rom.ruf))] :: - %p (read-p path.mun) - %t (bind (read-t yon path.mun) (lift |=(a=cage [%& a]))) - %u (read-u yon path.mun) - %v (bind (read-v yon path.mun) (lift |=(a/cage [%& a]))) - %w (read-w case.mun) - %x (read-x yon path.mun) - %y (bind (read-y yon path.mun) (lift |=(a/cage [%& a]))) - %z (bind (read-z yon path.mun) (lift |=(a/cage [%& a]))) + %a (read-a yon path.mun) + %b (read-b yon path.mun) + %c (read-c yon path.mun) + %p :_(fod (read-p path.mun)) + %r :_(fod (bind (read-r yon path.mun) (lift |=(a=cage [%& a])))) + %s :_(fod (bind (read-s yon path.mun) (lift |=(a=cage [%& a])))) + %t :_(fod (bind (read-t yon path.mun) (lift |=(a=cage [%& a])))) + %u :_(fod (read-u yon path.mun)) + %v :_(fod (bind (read-v yon path.mun) (lift |=(a/cage [%& a])))) + %w :_(fod (read-w case.mun)) + %x :_(fod (read-x yon path.mun)) + %y :_(fod (bind (read-y yon path.mun) (lift |=(a/cage [%& a])))) + %z :_(fod (bind (read-z yon path.mun) (lift |=(a/cage [%& a])))) == - ++ zu zu:util + :: Traverse an ankh. + :: + ++ zu :: filesystem + |= ank/ankh :: filesystem state + =| ram/path :: reverse path into + |% + ++ descend :: descend + |= lol/@ta + ^+ +> + =+ you=(~(get by dir.ank) lol) + +>.$(ram [lol ram], ank ?~(you [~ ~] u.you)) + :: + ++ descend-path :: descend recursively + |= way/path + ^+ +> + ?~(way +> $(way t.way, +> (descend i.way))) + -- -- -- -- @@ -4059,11 +3722,10 @@ :: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: =| :: instrument state - $: ver=%2 :: vane version + $: ver=%3 :: vane version ruf=raft :: revision tree == :: |= [our=ship now=@da eny=@uvJ ski=sley] :: current invocation -^? :: opaque core |% :: ++ call :: handle request |= $: hen=duct @@ -4082,48 +3744,6 @@ ?< ?=(%crud -.req) [%crud -.req tang.u.dud] :: - :: only one of these should be going at once, so queue - :: - ?: ?=(?(%info %merg %mont) -.req) - :: If there's an active write or a queue, enqueue - :: - :: We only want one active write so each can be a clean - :: transaction. We don't intercept `%into` because it - :: immediately translates itself into one or two `%info` calls. - :: - ?: |(!=(~ act.ruf) !=(~ cue.ruf)) - =. cue.ruf (~(put to cue.ruf) [hen req]) - :: ~& :* %clall-enqueing - :: cue=(turn ~(tap to cue.ruf) |=([=duct =task:able] [duct -.task])) - :: ^= act - :: ?~ act.ruf - :: ~ - :: [hen req -.eval-data]:u.act.ruf - :: == - [~ ..^$] - :: If the last commit happened in this event, enqueue - :: - :: Without this, two commits could have the same date, which - :: would make clay violate referential transparency. - :: - =/ =desk des.req - =/ =dojo (~(gut by dos.rom.ruf) desk *dojo) - ?: =(0 let.dom.dojo) - (handle-task hen req) - =/ sutil (state:util dom.dojo dom.dojo ran.ruf) - =/ last-write=@da t:(aeon-to-yaki:sutil let.dom.dojo) - ?: !=(last-write now) - (handle-task hen req) - =. cue.ruf (~(put to cue.ruf) [hen req]) - =/ wait-behn [hen %pass /queued-request %b %wait now] - [[wait-behn ~] ..^$] - (handle-task hen req) -:: -:: Handle a task, without worrying about write queueing -:: -++ handle-task - |= [hen=duct req=task:able] - ^- [(list move) _..^$] ?- -.req %boat :_ ..^$ @@ -4172,42 +3792,29 @@ [[[hen %slip %d %flog req] ~] ..^$] :: %drop - ~? =(~ act.ruf) - [%clay-idle cue-length=~(wyt in cue.ruf)] - ~? ?=(^ act.ruf) - [%clay-cancelling hen -.req -.eval-data]:u.act.ruf - =. act.ruf ~ - ?: =(~ cue.ruf) - [~ ..^$] - ?: =(%force des.req) - =^ queued cue.ruf ~(get to cue.ruf) - ~& [%dropping-hard [duct -.task]:p.queued cue-length=~(wyt in cue.ruf)] - [~ ..^$] - =/ =duct duct:(need ~(top to cue.ruf)) - [[duct %pass /queued-request %b %wait now]~ ..^$] + ~& %clay-idle + [~ ..^$] :: %info - ?: =(%$ des.req) - ~|(%info-no-desk !!) - =. act.ruf - =/ =dojo (~(gut by dos.rom.ruf) des.req *dojo) - =/ writer=form:commit-clad - %- %- commit - :* our - des.req - now - mon.ruf - hez.ruf - hun.rom.ruf - == - :* dit.req - dom.dojo - ran.ruf - == - `[hen req %commit (from-form:eval:commit-clad writer)] + ?: ?=(%| -.dit.req) + ~| %labelling-not-implemented + !! + =/ [deletes=(set path) changes=(map path cage)] + =/ =soba p.dit.req + =| deletes=(set path) + =| changes=(map path cage) + |- ^+ [deletes changes] + ?~ soba + [deletes changes] + ?- -.q.i.soba + %del $(soba t.soba, deletes (~(put in deletes) p.i.soba)) + %ins $(soba t.soba, changes (~(put by changes) [p p.q]:i.soba)) + %mut $(soba t.soba, changes (~(put by changes) [p p.q]:i.soba)) + %dif ~|(%dif-not-implemented !!) + == =^ mos ruf =/ den ((de our now ski hen ruf) our des.req) - abet:(take-commit:den clad-init-sign) + abet:(info:den deletes changes) [mos ..^$] :: %init @@ -4215,79 +3822,34 @@ :: %into =. hez.ruf `hen - :_ ..^$ =+ bem=(~(get by mon.ruf) des.req) ?: &(?=(~ bem) !=(%$ des.req)) ~|([%bad-mount-point-from-unix des.req] !!) =/ bem/beam ?^ bem u.bem - [[our %base %ud 1] ~] + [[our %home %ud 1] ~] =/ dos (~(get by dos.rom.ruf) q.bem) ?~ dos !! :: fire next in queue - ?: =(0 let.dom.u.dos) - =+ cos=(mode-to-soba ~ s.bem all.req fis.req) - =/ [one=soba two=soba] - %+ skid cos - |= [a=path b=miso] - ?& ?=(%ins -.b) - ?=(%mime p.p.b) - ?=([%hoon ~] (slag (dec (lent a)) a)) - == - :~ [hen %pass /one %c %info q.bem %& one] - [hen %pass /two %c %info q.bem %& two] - == - =+ yak=(~(got by hut.ran.ruf) (~(got by hit.dom.u.dos) let.dom.u.dos)) - =+ cos=(mode-to-soba q.yak (flop s.bem) all.req fis.req) - [hen %pass /both %c %info q.bem %& cos]~ + =^ mos ruf + =/ den ((de our now ski hen ruf) our q.bem) + abet:(into:den (flop s.bem) all.req fis.req) + [mos ..^$] :: %merg :: direct state up ?: =(%$ des.req) ~&(%merg-no-desk !!) - =. act.ruf - =/ =dojo (~(gut by dos.rom.ruf) des.req *dojo) - =/ writer=form:merge-clad - %- %- merge - :* our - now - [her dem]:req - [our des.req] - cas.req - mon.ruf - hez.ruf - == - :* how.req - dom.dojo - ran.ruf - == - `[hen req %merge (from-form:eval:merge-clad writer)] =^ mos ruf =/ den ((de our now ski hen ruf) our des.req) - abet:(take-merge:den clad-init-sign) + abet:(start-merge:den her.req dem.req cas.req how.req) [mos ..^$] :: %mont =. hez.ruf ?^(hez.ruf hez.ruf `[[%$ %sync ~] ~]) - =. act.ruf - =/ =dojo (~(gut by dos.rom.ruf) q.bem.req *dojo) - =/ writer=form:mount-clad - %- %- mount - :* our - q.bem.req - now - (need hez.ruf) - dom.dojo - ran.ruf - == - :* des.req - bem.req - mon.ruf - == - `[hen req %mount (from-form:eval:mount-clad writer)] =^ mos ruf =/ den ((de our now ski hen ruf) p.bem.req q.bem.req) - abet:(take-mount:den clad-init-sign) + abet:(mount:den pot.req r.bem.req s.bem.req) [mos ..^$] :: %dirk @@ -4297,8 +3859,7 @@ ?. (~(has by mon.ruf) des.req) ~& [%not-mounted des.req] [~ ..^$] - :- ~[[u.hez.ruf %give %dirk des.req]] - ..^$ + [~[[u.hez.ruf %give %dirk des.req]] ..^$] :: %ogre ?~ hez.ruf @@ -4321,6 +3882,20 @@ (skim ~(tap by mon.ruf) (corl (cury test pot) tail)) |= {pon/term bem/beam} [u.hez.ruf %give %ogre pon] + :: + %park + =^ mos ruf + =/ den ((de our now ski hen ruf) our des.req) + abet:(park:den | [yok ran]:req) + [mos ..^$] + :: + %pork + =/ [syd=desk =yoki] (need pud.ruf) + =. pud.ruf ~ + =^ mos ruf + =/ den ((de our now ski hen ruf) our syd) + abet:(park:den & yoki *rang) + [mos ..^$] :: %perm =^ mos ruf @@ -4330,7 +3905,26 @@ :: %trim [~ ..^$] :: - %vega [~ ..^$] + %vega + :: wake all desks, then send pending notifications + :: + =^ wake-moves ..^$ + =/ desks=(list [=ship =desk]) + %+ welp + (turn ~(tap by dos.rom.ruf) |=([=desk *] [our desk])) + %- zing + %+ turn ~(tap by hoy.ruf) + |= [=ship =rung] + %+ turn ~(tap by rus.rung) + |= [=desk *] + [ship desk] + |- ^+ [*(list move) ..^^$] + ?~ desks + [~ ..^^$] + =^ moves-1 ..^^$ $(desks t.desks) + =^ moves-2 ruf abet:wake:((de our now ski hen ruf) [ship desk]:i.desks) + [(weld moves-1 moves-2) ..^^$] + [(welp wake-moves pun.ruf) ..^$(pun.ruf ~)] :: ?(%warp %werp) :: capture whether this read is on behalf of another ship @@ -4365,31 +3959,241 @@ [%foreign-warp (scot %p her) t.pax] [hen %pass wire %c %werp her our ryf] == - :: - %wegh - :_ ..^$ :_ ~ - :^ hen %give %mass - :+ %clay %| - :~ domestic+&+rom.ruf - foreign+&+hoy.ruf - :+ %object-store %| - :~ commits+&+hut.ran.ruf - blobs+&+lat.ran.ruf - == - dot+&+ruf - == == :: ++ load !: - |= [%2 =raft] - ..^$(ruf raft) + |^ + |= old=any-state + ~! [old=old new=*state-3] + =? old ?=(%2 -.old) (load-2-to-3 old) + ?> ?=(%3 -.old) + ..^^$(ruf +.old) + :: + ++ load-2-to-3 + |= =state-2 + ^- state-3 + |^ + =- state-2(- %3, rom rom.-, hoy hoy.-, |7 [pud=~ pun.-]) + :+ ^- pun=(list move) + %+ welp + ?~ act.state-2 + ~ + ?. =(%merge -.eval-data.u.act.state-2) + ~ + =/ err + :- %ford-fusion + [leaf+"active merge canceled due to upgrade to ford fusion" ~] + [hen.u.act.state-2 %slip %b %drip !>([%mere %| err])]~ + ^- (list move) + %+ murn ~(tap to cue.state-2) + :: use ^ so we don't have to track definition of +task + :: + |= [=duct task=^] + ^- (unit move) + ?. =(%merg -.task) + ~& "queued clay write canceled due to upgrade to ford fusion:" + ~& [duct [- +<]:task] + ~ + =/ err + :- %ford-fusion + [leaf+"queued merge canceled due to upgrade to ford fusion" ~] + `[duct %slip %b %drip !>([%mere %| err])] + ^- rom=room + :- hun.rom.state-2 + %- ~(urn by dos.rom.state-2) + |= [=desk =dojo-2] + ^- dojo + =- dojo-2(dom -) + ^- dome + =/ fer=(unit reef-cache) + ?~ let.dom.dojo-2 + ~ + =/ =yaki + (~(got by hut.ran.state-2) (~(got by hit.dom.dojo-2) let.dom.dojo-2)) + `(build-reef desk q.yaki) + [ank let hit lab mim fod=*ford-cache fer=fer]:[dom.dojo-2 .] + ^- hoy=(map ship rung) + %- ~(run by hoy.state-2) + |= =rung-2 + ^- rung + %- ~(run by rus.rung-2) + |= =rede-2 + ^- rede + =- rede-2(ref ref.-, dom dom.-) + :- ^- dom=dome + [ank let hit lab mim fod=*ford-cache fer=~]:[dom.rede-2 .] + ^- ref=(unit rind) + ?~ ref.rede-2 + ~ + :: TODO: somehow call +wake later to notify subscribers + :- ~ + ^- rind + =/ rin=rind [nix bom fod haw]:u.ref.rede-2 + =. rin + =/ pur=(list [inx=@ud =rand *]) ~(tap by pur.u.ref.rede-2) + |- ^+ rin + ?~ pur rin + =/ =mood [p.p q.p q]:rand.i.pur + =: haw.rin (~(put by haw.rin) mood ~) + bom.rin (~(del by bom.rin) inx.i.pur) + fod.rin ?~ got=(~(get by bom.rin) inx.i.pur) + fod.rin + (~(del by fod.rin) p.u.got) + == + $(pur t.pur) + =/ pud ~(tap to waiting.pud.u.ref.rede-2) + |- ^+ rin + ?~ pud rin + =: bom.rin (~(del by bom.rin) inx.i.pud) + fod.rin ?~ got=(~(get by bom.rin) inx.i.pud) + fod.rin + (~(del by fod.rin) p.u.got) + == + $(pud t.pud) + :: + ++ build-reef + |= [=desk data=(map path lobe)] + ^- reef-cache + ~> %slog.0^leaf+"clay: building reef on {}" + ?: =(%home desk) + [!>(..ride) !>(..is) !>(..zuse)] + |^ + =/ [home=? hoon=vase] + ?: (same-as-home /sys/hoon/hoon) + &+!>(..ride) + |+build-hoon + :- hoon + =/ [home=? arvo=vase] + ?: &(home (same-as-home /sys/arvo/hoon)) + &+!>(..is) + |+(build-arvo hoon) + :- arvo + ?: &(home (same-as-home /sys/zuse/hoon)) + !>(..zuse) + (build-zuse arvo) + :: + ++ build-hoon + %- road |. + ~> %slog.0^leaf+"clay: building hoon on {}" + =/ gen + ~> %mean.%hoon-parse-fail + %+ rain /sys/hoon/hoon + (lobe-to-cord (~(got by data) /sys/hoon/hoon)) + ~> %mean.%hoon-compile-fail + (slot 7 (slap !>(0) gen)) + :: + ++ build-arvo + |= hoon=vase + %- road |. + ~> %slog.0^leaf+"clay: building arvo on {}" + =/ gen + ~> %mean.%arvo-parse-fail + %+ rain /sys/arvo/hoon + (lobe-to-cord (~(got by data) /sys/arvo/hoon)) + ~> %mean.%arvo-compile-fail + (slap (slap hoon gen) (ream '..is')) + :: + ++ build-zuse + |= arvo=vase + %- road |. + ~> %slog.0^leaf+"clay: building zuse on {}" + =/ gen + ~> %mean.%zuse-parse-fail + %+ rain /sys/zuse/hoon + (lobe-to-cord (~(got by data) /sys/zuse/hoon)) + ~> %mean.%zuse-compile-fail + (slap arvo gen) + :: + ++ same-as-home + |= =path + ^- ? + =/ our-lobe=lobe (~(got by data) path) + =/ =dome-2 dom:(~(got by dos.rom.state-2) %home) + =/ =yaki (~(got by hut.ran.state-2) (~(got by hit.dome-2) let.dome-2)) + =(`our-lobe (~(get by q.yaki) path)) + :: + ++ lobe-to-cord + |= =lobe + ^- @t + =- ?:(?=(%& -<) p.- (of-wain:format p.-)) + |- ^- (each @t wain) + =/ =blob (~(got by lat.ran.state-2) lobe) + ?- -.blob + %direct [%& ;;(@t q.q.blob)] + %delta + :- %| + %+ lurk:differ + =- ?:(?=(%| -<) p.- (to-wain:format p.-)) + $(lobe q.q.blob) + ~| diff=r.blob + ;;((urge cord) q.r.blob) + == + -- + -- + :: + +$ any-state $%(state-3 state-2) + +$ state-3 [%3 raft] + +$ state-2 + $: %2 + rom=room-2 :: domestic + hoy=(map ship rung-2) :: foreign + ran=rang :: hashes + mon=(map term beam) :: mount points + hez=(unit duct) :: sync duct + cez=(map @ta crew) :: permission groups + cue=(qeu [=duct task=^]) :: queued requests + act=active-write-2 :: active write + == :: + +$ room-2 + $: hun/duct :: terminal duct + dos/(map desk dojo-2) :: native desk + == :: + +$ dojo-2 + $: qyx/cult :: subscribers + dom/dome-2 :: desk state + per/regs :: read perms per path + pew/regs :: write perms per path + == + +$ dome-2 + $: ank/ankh :: state + let/aeon :: top id + hit/(map aeon tako) :: versions by id + lab/(map @tas aeon) :: labels + mim/(map path mime) :: mime cache + == :: + +$ rung-2 rus=(map desk rede-2) + +$ rede-2 + $: lim/@da :: complete to + ref/(unit rind-2) :: outgoing requests + qyx/cult :: subscribers + dom/dome-2 :: revision state + per/regs :: read perms per path + pew/regs :: write perms per path + == :: + +$ rind-2 + $: nix/@ud :: request index + bom/(map @ud {p/duct q/rave}) :: outstanding + fod/(map duct @ud) :: current requests + haw/(map mood (unit cage)) :: simple cache + pud/update-qeu-2 :: active updates + pur/request-map-2 :: active requests + == :: + +$ request-map-2 (map inx=@ud [=rand eval-form=*]) + +$ update-qeu-2 + $: waiting=(qeu [inx=@ud rut=(unit rand)]) + eval-data=(unit [inx=@ud rut=(unit rand) eval-form=*]) + == + +$ active-write-2 (unit [hen=duct req=* eval-data=^]) + -- :: ++ scry :: inspect |= {fur/(unit (set monk)) ren/@tas why/shop syd/desk lot/coin tyl/path} ^- (unit (unit cage)) ?. ?=(%& -.why) ~ =* his p.why + ?: &(=(ren %$) =(tyl /whey)) + ``mass+!>(whey) :: ~& scry+[ren `path`[(scot %p his) syd ~(rent co lot) tyl]] :: =- ~& %scry-done - =+ luk=?.(?=(%$ -.lot) ~ ((soft case) p.lot)) @@ -4407,38 +4211,56 @@ ?: =(p.m his) ~ `p.m =/ den ((de our now ski [/scryduct ~] ruf) his syd) - =+ (aver:den for u.run u.luk tyl) - ?~ - - - ?~ u.- - - ?: ?=(%& -.u.u.-) ``p.u.u.- + =/ result (mule |.(-:(aver:den for u.run u.luk tyl))) + ?: ?=(%| -.result) + %- (slog >%clay-scry-fail< p.result) + ~ + ?~ p.result ~ + ?~ u.p.result [~ ~] + :: should convert %| case to cage + :: + ?: ?=(%& -.u.u.p.result) ``p.u.u.p.result ~ :: -++ stay [ver ruf] +:: We clear the ford cache by replacing it with its bunt as a literal. +:: This nests within +ford-cache without reference to +type, +hoon, or +:: anything else in the sample of cache objects. Otherwise we would be +:: contravariant in the those types, which makes them harder to change. +:: +++ stay + :- ver + %= ruf + dos.rom + %- ~(run by dos.rom.ruf) + |= =dojo + dojo(fod.dom [~ ~ ~]) + :: + hoy + %- ~(run by hoy.ruf) + |= =rung + %= rung + rus + %- ~(run by rus.rung) + |= =rede + rede(fod.dom [~ ~ ~]) + == + == +:: ++ take :: accept response |= [tea=wire hen=duct dud=(unit goof) hin=(hypo sign)] ^+ [*(list move) ..^$] ?^ dud ~|(%clay-take-dud (mean tang.u.dud)) :: - ?: ?=([%commit @ *] tea) + ?: ?=([%merge @ @ @ @ ~] tea) + ?> ?=(%writ +<.q.hin) =* syd i.t.tea + =/ ali-ship (slav %p i.t.t.tea) + =* ali-desk i.t.t.t.tea + =/ germ (germ i.t.t.t.t.tea) =^ mos ruf - =/ den ((de our now ski hen ruf) our syd) - abet:(take-commit:den q.hin) - [mos ..^$] - :: - ?: ?=([%merge @ *] tea) - =* syd i.t.tea - =^ mos ruf - =/ den ((de our now ski hen ruf) our syd) - abet:(take-merge:den q.hin) - [mos ..^$] - :: - ?: ?=([%mount @ *] tea) - =* syd i.t.tea - =^ mos ruf - =/ den ((de our now ski hen ruf) our syd) - abet:(take-mount:den q.hin) + =/ den ((de our now ski hen ruf) our i.t.tea) + abet:(merge:den ali-ship ali-desk germ p.q.hin) [mos ..^$] :: ?: ?=([%foreign-warp *] tea) @@ -4446,39 +4268,6 @@ :_ ..^$ [hen %give %boon `(unit rand)`(bind `riot`p.q.hin rant-to-rand)]~ :: - ?: ?=([%foreign-request @ @ @ *] tea) - =/ her (slav %p i.t.tea) - =/ syd (slav %tas i.t.t.tea) - =/ inx (slav %ud i.t.t.t.tea) - =^ mos ruf - =/ den ((de our now ski hen ruf) her syd) - abet:(take-foreign-request:den inx q.hin) - [mos ..^$] - :: - ?: ?=([%foreign-update @ @ *] tea) - =/ her (slav %p i.t.tea) - =/ syd (slav %tas i.t.t.tea) - =^ mos ruf - =/ den ((de our now ski hen ruf) her syd) - abet:(take-foreign-update:den q.hin) - [mos ..^$] - :: - ?: ?=([%blab care @ @ *] tea) - ?> ?=(%made +<.q.hin) - ?. ?=([%complete %success *] result.q.hin) - ~| %blab-fail - ~> %mean.|.((made-result-as-error:ford result.q.hin)) - !! :: interpolate ford fail into stack trace - :_ ..^$ :_ ~ - :* hen %slip %b %drip !> - :* %writ ~ - ^- [care case @tas] - [i.t.tea ;;(case +>:(slay i.t.t.tea)) i.t.t.t.tea] - :: - `path`t.t.t.t.tea - `cage`(result-to-cage:ford build-result.result.q.hin) - == == - :: ?: ?=([%warp-index @ @ @ ~] tea) ?+ +<.q.hin ~| %clay-warp-index-strange !! %done @@ -4532,29 +4321,17 @@ ~(tap in ducts) =/ cancel-moves=(list move) %+ turn cancel-ducts - |= =duct - [duct %slip %b %drip !>([%writ ~])] - :: Clear ford cache - :: - =/ clear-ford-cache-moves=(list move) - :~ [hen %pass /clear/keep %f %keep 0 1] - [hen %pass /clear/wipe %f %wipe 100] - [hen %pass /clear/kep %f %keep 2.048 64] - == + |=(=duct [duct %slip %b %drip !>([%writ ~])]) :: delete local state of foreign desk :: =. hoy.ruf (~(del by hoy.ruf) who) - [(weld clear-ford-cache-moves cancel-moves) ..^$] + [cancel-moves ..^$] :: ?- -.+.q.hin %public-keys ~|([%public-keys-raw tea] !!) - %init-clad - ~|(%clad-not-real !!) - :: %crud [[[hen %slip %d %flog +.q.hin] ~] ..^$] :: - %made ~|(%clay-raw-ford !!) %mere ?: ?=(%& -.p.+.q.hin) ~& 'initial merge succeeded' @@ -4574,34 +4351,23 @@ ?^ error.q.hin [[hen %slip %d %flog %crud %wake u.error.q.hin]~ ..^$] :: - ?: ?=([%tyme @ @ ~] tea) - =/ her (slav %p i.t.tea) - =/ syd (slav %tas i.t.t.tea) - =^ mos ruf - =/ den ((de our now ski hen ruf) her syd) - abet:wake:den - [mos ..^$] - :: - =^ queued cue.ruf ~(get to cue.ruf) - :: - =/ queued-duct=duct -.queued - =/ queued-task=task:able +.queued - :: - :: ~& :* %clay-waking - :: queued-duct - :: hen - :: ?~(cue.ruf /empty -:(need ~(top to cue.ruf))) - :: == - ~| [%mismatched-ducts %queued queued-duct %timer hen] - ?> =(hen queued-duct) - :: - (handle-task hen queued-task) + ?. ?=([%tyme @ @ ~] tea) + ~& [%clay-strange-timer tea] + [~ ..^$] + =/ her (slav %p i.t.tea) + =/ syd (slav %tas i.t.t.tea) + =^ mos ruf + =/ den ((de our now ski hen ruf) her syd) + abet:wake:den + [mos ..^$] :: :: handled in the wire dispatcher :: %boon !! %lost !! - %writ !! + %writ + %- (slog leaf+"clay: strange writ (expected on upgrade to Fusion)" ~) + [~ ..^$] :: %done ?~ error=error.q.hin @@ -4614,43 +4380,23 @@ |= rant ^- rand [p q [p q.q]:r] +:: +whey: produce memory usage report :: -++ mode-to-soba - |= {hat/(map path lobe) pax/path all/? mod/mode} - ^- soba - %+ weld - ^- (list (pair path miso)) - ?. all - ~ - =+ mad=(malt mod) - =+ len=(lent pax) - =/ descendants/(list path) - %+ turn - %+ skim ~(tap by hat) - |= {paf/path lob/lobe} - =(pax (scag len paf)) - |= {paf/path lob/lobe} - (slag len paf) - %+ murn - descendants - |= pat/path - ^- (unit (pair path {$del ~})) - ?: (~(has by mad) pat) - ~ - `[(weld pax pat) %del ~] - ^- (list (pair path miso)) - %+ murn mod - |= {pat/path mim/(unit mime)} - ^- (unit (pair path miso)) - =+ paf=(weld pax pat) - ?~ mim - =+ (~(get by hat) paf) - ?~ - - ~& [%deleting-already-gone pax pat] - ~ - `[paf %del ~] - =+ (~(get by hat) paf) - ?~ - - `[paf %ins %mime -:!>(*mime) u.mim] - `[paf %mut %mime -:!>(*mime) u.mim] +++ whey + ^- (list mass) + =/ domestic + %+ turn (sort ~(tap by dos.rom.ruf) aor) + |= [=desk =dojo] + :+ desk %| + :~ ankh+&+ank.dom.dojo + mime+&+mim.dom.dojo + ford+&+fod.dom.dojo + == + :~ domestic+|+domestic + foreign+&+hoy.ruf + :+ %object-store %| + :~ commits+&+hut.ran.ruf + blobs+&+lat.ran.ruf + == + == -- diff --git a/pkg/arvo/sys/vane/dill.hoon b/pkg/arvo/sys/vane/dill.hoon index a3597c7370..64d64bbba6 100644 --- a/pkg/arvo/sys/vane/dill.hoon +++ b/pkg/arvo/sys/vane/dill.hoon @@ -8,21 +8,10 @@ -- :: => |% :: console protocol ++ axle :: - $: $2 :: + $: %3 :: hey/(unit duct) :: default duct dug/(map duct axon) :: conversations lit/? :: boot in lite mode - dog/_| :: auto-goad - $= hef :: other weights - $: a/(unit mass) :: - b/(unit mass) :: - c/(unit mass) :: - e/(unit mass) :: - f/(unit mass) :: - g/(unit mass) :: - i/(unit mass) :: - j/(unit mass) :: - == :: $= veb :: vane verbosities $~ (~(put by *(map @tas log-level)) %hole %soft) :: quiet packet crashes (map @tas log-level) :: @@ -43,20 +32,10 @@ ++ move {p/duct q/(wind note gift:able)} :: local move ++ note :: out request $-> $~ [%d %verb ~] :: - $% $: %a :: - $>(%wegh task:able:ames) :: - == :: - $: %b :: - $> $? %wait :: - %wegh :: - == :: - task:able:behn :: - == :: - $: %c :: + $% $: %c :: $> $? %merg :: merge desks %perm :: change permissions %warp :: wait for clay hack - %wegh :: memory measure == :: task:able:clay :: == :: @@ -71,46 +50,27 @@ == :: task:able:dill :: == :: - $: %e :: - $>(%wegh task:able:eyre) :: - == :: - $: %f :: - $>(%wegh task:able:ford) :: - == :: $: %g :: $> $? %conf :: %deal :: %goad :: - %wegh :: == :: task:able:gall :: == :: - $: %i :: - $>(%wegh task:able:iris) :: - == :: $: %j :: $> $? %dawn :: %fake :: - %wegh :: == :: task:able:jael :: == == :: ++ sign :: in result $<- $~ [%j %init *@p] :: - $% $: %a :: - $% $>(%mass gift:able:ames) :: - == == :: - $: %b :: - $% $> $? %mass :: - %wake :: - == :: - gift:able:behn :: - $>(%writ gift:able:clay) :: XX %slip + $% $: %b :: + $% $>(%writ gift:able:clay) :: XX %slip $>(%mere gift:able:clay) :: XX %slip == == :: $: %c :: - $> $? %mass :: - %mere :: + $> $? %mere :: %note :: %writ :: == :: @@ -119,25 +79,14 @@ $: %d :: $>(%blit gift:able:dill) :: == :: - $: %e :: - $>(%mass gift:able:eyre) :: - == :: - $: %f :: - $>(%mass gift:able:ford) :: - == :: $: %g :: - $> $? %mass :: - %onto :: + $> $? %onto :: %unto :: == :: gift:able:gall :: == :: - $: %i :: - $>(%mass gift:able:iris) :: - == :: $: %j :: $> $? %init :: - %mass :: == :: gift:able:jael :: == == :: @@ -154,52 +103,19 @@ ^- {(list move) axle} [(flop moz) all(dug (~(put by dug.all) hen +<+))] :: - ++ auto :: stage automation - ^+ . - ?. dog.all . - =. dog.all | - (pass /auto/one [%b %wait +(now)]) - :: - ++ auto-wake :: resume automation - |= [=wire error=(unit tang)] - ?+ wire - ?~ error - ~|(behn-bad-wake+wire !!) - (crud %wake u.error) - :: - [%auto %one ~] - ?~ error - ~& %behn-goad - (pass / [%g %goad force=| ~]) - :: %goad crashed, wait again, then force - :: - ~& %behn-goad-retry - %. [/auto/two [%b %wait +(now)]] - pass:(crud %goad u.error) - :: - [%auto %two ~] - ?~ error - ~& %behn-goad-again - (pass / [%g %goad force=& ~]) - :: %goad crashed again, bail out - :: - ~& %behn-goad-fail - (crud %goad u.error) - == - :: ++ call :: receive input |= kyz/task:able ^+ +> ?+ -.kyz ~& [%strange-kiss -.kyz] +> $flow +> $harm +> - $hail auto:(send %hey ~) + $hail (send %hey ~) $belt (send `dill-belt`p.kyz) $text (from %out (tuba p.kyz)) $crud :: (send `dill-belt`[%cru p.kyz q.kyz]) (crud p.kyz q.kyz) $blew (send %rez p.p.kyz q.p.kyz) - $heft heft + $heft (dump %whey ~) $lyra (dump kyz) $pack (dump kyz) $veer (dump kyz) @@ -334,17 +250,6 @@ ~ '9' == -- - :: - ++ heft - =< (pass /heft/ames [%a %wegh ~]) - =< (pass /heft/behn [%b %wegh ~]) - =< (pass /heft/clay [%c %wegh ~]) - =< (pass /heft/eyre [%e %wegh ~]) - =< (pass /heft/ford [%f %wegh ~]) - =< (pass /heft/gall [%g %wegh ~]) - =< (pass /heft/iris [%i %wegh ~]) - =< (pass /heft/jael [%j %wegh ~]) - . :: XX move :: ++ sein @@ -355,22 +260,19 @@ [[151 %noun] %j our %sein da+now /(scot %p who)] :: ++ init :: initialize - (pass /merg/home [%c %merg %home our %base da+now %init]) + (pass /merg/home [%c %merg %kids our %home da+now %init]) :: ++ mere :: continue init ^+ . =/ myt (flop (fall tem ~)) =/ can (clan:title our) =. tem ~ - =. +> (pass / [%g %conf [[our ram] our %home]]) - =. +> (sync %home our %base) + =. +> (pass / %g %conf ram) =? +> ?=(?($earl $duke $king) can) - (sync %base (sein our) %kids) - =? +> ?=(?($duke $king $czar) can) - :: make kids desk publicly readable, so syncs work. - :: - (show %kids):(sync %kids our %base) - =. +> autoload + (ota (sein our) %kids) + :: make kids desk publicly readable, so syncs work. + :: + =. +> (show %kids) =. +> hood-set-boot-apps =. +> peer |- ^+ +>+ @@ -380,7 +282,7 @@ ++ into :: preinitialize |= gyl/(list gill) =. tem `(turn gyl |=(a/gill [%yow a])) - (pass / [%c %warp our %base `[%sing %y [%ud 1] /]]) + (pass / [%c %warp our %home `[%sing %y [%ud 1] /]]) :: ++ send :: send action |= bet/dill-belt @@ -399,20 +301,14 @@ |= des/desk (pass /show [%c %perm des / r+`[%black ~]]) :: - ++ sync - |= syn/{desk ship desk} - (deal /sync [%poke %hood-sync -:!>(syn) syn]) - :: - ++ autoload - (deal /autoload [%poke %kiln-start-autoload [%atom %n `~] ~]) + ++ ota + |= syn=[ship desk] + (deal /sync %poke %kiln-ota !>(`syn)) :: ++ take :: receive |= {tea/wire sih/sign} ^+ +> ?- sih - {?($a $b $c $e $f $g $i $j) $mass *} - (wegh -.sih p.sih) - :: [%j %init *] :: pass thru to unix :: @@ -449,58 +345,7 @@ :: {$d $blit *} (done +.sih) - :: - {$b $wake *} - (auto-wake tea error.sih) == - :: +wegh: receive a memory report from a vane and maybe emit full report - :: - ++ wegh - |= [lal=?(%a %b %c %e %f %g %i %j) mas=mass] - ^+ +> - :: update our listing of vane responses with this new one - :: - =. hef.all - ?- lal - %a ~?(?=(^ a.hef.all) %double-mass-a hef.all(a `mas)) - %b ~?(?=(^ b.hef.all) %double-mass-b hef.all(b `mas)) - %c ~?(?=(^ c.hef.all) %double-mass-c hef.all(c `mas)) - %e ~?(?=(^ e.hef.all) %double-mass-e hef.all(e `mas)) - %f ~?(?=(^ f.hef.all) %double-mass-f hef.all(f `mas)) - %g ~?(?=(^ g.hef.all) %double-mass-g hef.all(g `mas)) - %i ~?(?=(^ i.hef.all) %double-mass-i hef.all(i `mas)) - %j ~?(?=(^ j.hef.all) %double-mass-j hef.all(j `mas)) - == - :: if not all vanes have responded yet, no-op - :: - ?. ?& ?=(^ a.hef.all) - ?=(^ b.hef.all) - ?=(^ c.hef.all) - ?=(^ e.hef.all) - ?=(^ f.hef.all) - ?=(^ g.hef.all) - ?=(^ i.hef.all) - ?=(^ j.hef.all) - == - +>.$ - :: clear vane reports from our state before weighing ourself - :: - :: Otherwise, the state of vanes printed after this one get absorbed - :: into Dill's %dot catchall report. - :: - =/ ven=(list mass) ~[u.a u.b u.c u.e u.f u.g u.i u.j]:hef.all - => .(hef.all [~ ~ ~ ~ ~ ~ ~ ~]) - :: wegh ourself now that our state doesn't include other masses - :: - =/ self=mass - :+ %dill %| - :~ hey+&+hey.all - dug+&+dug.all - dot+&+all - == - :: produce the memory report for all vanes - :: - (done %mass %vanes %| [self ven]) -- :: ++ ax :: make ++as @@ -591,7 +436,7 @@ => |% :: without .dog :: - ++ axle-one + ++ axle-1 $: $1 hey/(unit duct) dug/(map duct axon) @@ -610,15 +455,36 @@ $~ (~(put by *(map @tas log-level)) %hole %soft) (map @tas log-level) == + ++ axle-2 + $: %2 + hey/(unit duct) + dug/(map duct axon) + lit/? + dog/_| + $= hef + $: a/(unit mass) + b/(unit mass) + c/(unit mass) + e/(unit mass) + f/(unit mass) + g/(unit mass) + i/(unit mass) + j/(unit mass) + == + $= veb + $~ (~(put by *(map @tas log-level)) %hole %soft) + (map @tas log-level) + == :: - ++ axle-both - $%(axle-one axle) + ++ axle-any + $%(axle-1 axle-2 axle) -- :: - |= old=axle-both + |= old=axle-any ?- -.old %1 $(old [%2 [hey dug lit dog=& hef veb]:old]) - %2 ..^$(all old) + %2 $(old [%3 [hey dug lit veb]:old]) + %3 ..^$(all old) == :: ++ scry @@ -626,6 +492,12 @@ ^- (unit (unit cage)) ?. ?=(%& -.why) ~ =* his p.why + ?: &(=(ren %$) =(tyl /whey)) + =/ maz=(list mass) + :~ hey+&+hey.all + dug+&+dug.all + == + ``mass+!>(maz) [~ ~] :: ++ stay all diff --git a/pkg/arvo/sys/vane/eyre.hoon b/pkg/arvo/sys/vane/eyre.hoon index 5e21a9e750..5585f49980 100644 --- a/pkg/arvo/sys/vane/eyre.hoon +++ b/pkg/arvo/sys/vane/eyre.hoon @@ -19,7 +19,7 @@ :: card=(wind note gift:able) == -:: +note: private request from http-server to another vane +:: +note: private request from eyre to another vane :: +$ note $% :: %b: to behn @@ -37,14 +37,6 @@ :: $% [%flog =flog:dill] == == - :: %f: to ford - :: - $: %f - :: - :: - $% [%build live=? schematic=schematic:ford] - [%kill ~] - == == :: %g: to gall :: $: %g @@ -52,7 +44,7 @@ :: $>(%deal task:able:gall) == == -:: +sign: private response from another vane to ford +:: +sign: private response from another vane to eyre :: +$ sign $% :: %b: from behn @@ -62,13 +54,6 @@ :: $% [%wake error=(unit tang)] == == - :: %f: from ford - :: - $: %f - :: - :: - $% [%made date=@da result=made-result:ford] - == == :: %g: from gall :: $: %g @@ -468,13 +453,13 @@ :: =/ code-as-tape=tape (format-ud-as-integer code) =/ message=tape - ?: =(code 400) - "Bad Request" - ?: =(code 403) - "Forbidden" - ?: =(code 404) - "Not Found" - "Unknown Error" + ?+ code "{} Error" + %400 "Bad Request" + %403 "Forbidden" + %404 "Not Found" + %405 "Method Not Allowed" + %500 "Internal Server Error" + == :: %- as-octs:mimes:html %- crip @@ -739,17 +724,17 @@ :: otherwise, do a straight comparison :: =(u.binding u.host) -:: +path-matches: returns %.y if :prefix is a prefix of :full +:: +find-suffix: returns [~ /tail] if :full is (weld :prefix /tail) :: -++ path-matches +++ find-suffix |= [prefix=path full=path] - ^- ? + ^- (unit path) ?~ prefix - %.y + `full ?~ full - %.n + ~ ?. =(i.prefix i.full) - %.n + ~ $(prefix t.prefix, full t.full) :: +simplified-url-parser: returns [(each @if @t) (unit port=@ud)] :: @@ -803,7 +788,8 @@ (fall (forwarded-for header-list.request) address) :: =/ host (get-header:http 'host' header-list.request) - =/ action (get-action-for-binding host url.request) + =/ [=action suburl=@t] + (get-action-for-binding host url.request) :: =/ authenticated (request-is-logged-in:authentication request) :: record that we started an asynchronous response @@ -814,19 +800,50 @@ (~(put by connections.state) duct connection) :: ?- -.action - :: %gen + =/ bek=beak [our desk.generator.action da+now] + =/ sup=spur (flop path.generator.action) + =/ ski (scry [%141 %noun] ~ %ca bek sup) + =/ cag=cage (need (need ski)) + ?> =(%vase p.cag) + =/ gat=vase !<(vase q.cag) + =/ res=(each vase tang) + %- mule |. + %+ slam + %+ slam gat + !>([now=now eny=eny bek=bek]) + !>([authenticated request]) + ?: ?=(%| -.res) + =+ connection=(~(got by connections.state) duct) + %^ return-static-data-on-duct 500 'text/html' + %: internal-server-error + authenticated.inbound-request.connection + url.request.inbound-request.connection + p.res + == + =/ result !<(simple-payload:http p.res) + :: ensure we have a valid content-length header :: - =- [[duct %pass /run-build %f %build live=%.n schematic=-]~ state] + :: We pass on the response and the headers the generator produces, but + :: ensure that we have a single content-length header set correctly in + :: the returned if this has a body, and has no content-length if there + :: is no body returned to the client. :: - :+ %call - :+ %call - [%core [[our desk.generator.action] (flop path.generator.action)]] - :: TODO: Figure out what goes in generators. We need to slop the - :: prelude with the arguments passed in. + =. headers.response-header.result + ?~ data.result + (delete-header:http 'content-length' headers.response-header.result) :: - [%$ %noun !>([[now=now eny=eny bek=[our desk.generator.action [%da now]]] ~ ~])] - [%$ %noun !>([authenticated request])] + %^ set-header:http 'content-length' + (crip (format-ud-as-integer p.u.data.result)) + headers.response-header.result + :: + %- handle-response + ^- http-event:http + :* %start + response-header.result + data.result + complete=%.y + == :: %app :_ state @@ -840,11 +857,71 @@ :: %channel (handle-request:by-channel secure authenticated address request) + :: + %scry + (handle-scry authenticated address request(url suburl)) :: %four-oh-four %^ return-static-data-on-duct 404 'text/html' (error-page 404 authenticated url.request ~) == + :: +handle-scry: respond with scry result, 404 or 500 + :: + ++ handle-scry + |= [authenticated=? =address =request:http] + |^ ^- (quip move server-state) + ?. authenticated + (error-response 403 ~) + ?. =(%'GET' method.request) + (error-response 405 "may only GET scries") + :: make sure the path contains an app to scry into + :: + =+ req=(parse-request-line url.request) + ?. ?=(^ site.req) + (error-response 400 "scry path must start with app name") + :: attempt the scry that was asked for + :: + =/ res=(unit (unit cage)) + (do-scry %gx i.site.req (snoc t.site.req (fall ext.req %mime))) + ?~ res (error-response 500 "failed scry") + ?~ u.res (error-response 404 "no scry result") + =* mark p.u.u.res + =* vase q.u.u.res + :: attempt to find conversion gate to mime + :: + =/ tub=(unit tube:clay) + (find-tube mark %mime) + ?~ tub (error-response 500 "no tube from {(trip mark)} to mime") + :: attempt conversion, then send results + :: + =/ mym=(each mime tang) + (mule |.(!<(mime (u.tub vase)))) + ?- -.mym + %| (error-response 500 "failed tube from {(trip mark)} to mime") + %& %+ return-static-data-on-duct 200 + [(rsh 3 1 (spat p.p.mym)) q.p.mym] + == + :: + ++ find-tube + |= [from=mark to=mark] + ^- (unit tube:clay) + ?: =(from to) `(bake same vase) + =/ tub=(unit (unit cage)) + (do-scry %cc %home /[from]/[to]) + ?. ?=([~ ~ %tube *] tub) ~ + `!<(tube:clay q.u.u.tub) + :: + ++ do-scry + |= [care=term =desk =path] + ^- (unit (unit cage)) + (scry [%141 %noun] ~ care [our desk da+now] (flop path)) + :: + ++ error-response + |= [status=@ud =tape] + ^- (quip move server-state) + %^ return-static-data-on-duct status 'text/html' + (error-page status authenticated url.request tape) + -- :: +subscribe-to-app: subscribe to app and poke it with request data :: ++ subscribe-to-app @@ -874,11 +951,7 @@ =. connections.state (~(del by connections.state) duct) :: ?- -.action.u.connection - :: - %gen - :_ state - [duct %pass /run-build %f %kill ~]~ - :: + %gen [~ state] %app :_ state :_ ~ @@ -893,8 +966,8 @@ %channel on-cancel-request:by-channel :: - %four-oh-four - :: it should be impossible for a 404 page to be asynchronous + ?(%scry %four-oh-four) + :: it should be impossible for a scry or 404 page to be asynchronous :: !! == @@ -1183,10 +1256,10 @@ :: lookup the session id by duct :: ?~ maybe-channel-id=(~(get by duct-to-key.channel-state.state) duct) - ~& [%canceling-nonexistent-channel duct] + ~> %slog.[0 leaf+"eyre: no channel to cancel {}"] [~ state] :: - ~& [%canceling-cancel duct] + ~> %slog.[0 leaf+"eyre: canceling {}"] :: =/ maybe-session (~(get by session.channel-state.state) u.maybe-channel-id) @@ -1704,58 +1777,6 @@ :: [duc %pass channel-wire [%g %deal [our ship] app %leave ~]] -- - :: +handle-ford-response: translates a ford response for the outside world - :: - ++ handle-ford-response - |= made-result=made-result:ford - ^- [(list move) server-state] - :: - =+ connection=(~(got by connections.state) duct) - :: - ?: ?=(%incomplete -.made-result) - %^ return-static-data-on-duct 500 'text/html' - :: - %- internal-server-error :* - authenticated.inbound-request.connection - url.request.inbound-request.connection - tang.made-result - == - :: - ?: ?=(%error -.build-result.made-result) - %^ return-static-data-on-duct 500 'text/html' - :: - %- internal-server-error :* - authenticated.inbound-request.connection - url.request.inbound-request.connection - message.build-result.made-result - == - :: - =/ =cage (result-to-cage:ford build-result.made-result) - :: - =/ result=simple-payload:http ;;(simple-payload:http q.q.cage) - :: ensure we have a valid content-length header - :: - :: We pass on the response and the headers the generator produces, but - :: ensure that we have a single content-length header set correctly in - :: the returned if this has a body, and has no content-length if there - :: is no body returned to the client. - :: - =. headers.response-header.result - ?~ data.result - (delete-header:http 'content-length' headers.response-header.result) - :: - %^ set-header:http 'content-length' - (crip (format-ud-as-integer p.u.data.result)) - headers.response-header.result - :: - %- handle-response - :: - ^- http-event:http - :* %start - response-header.result - data.result - complete=%.y - == :: +handle-gall-error: a call to +poke-http-response resulted in a %coup :: ++ handle-gall-error @@ -1930,7 +1951,7 @@ :: ++ get-action-for-binding |= [raw-host=(unit @t) url=@t] - ^- action + ^- [=action suburl=@t] :: process :raw-host :: :: If we are missing a 'Host:' header, if that header is a raw IP @@ -1978,14 +1999,21 @@ |- :: ?~ bindings - [%four-oh-four ~] + [[%four-oh-four ~] url] :: - ?: ?& (host-matches site.binding.i.bindings raw-host) - (path-matches path.binding.i.bindings parsed-url) - == - action.i.bindings + ?. (host-matches site.binding.i.bindings raw-host) + $(bindings t.bindings) + ?~ suffix=(find-suffix path.binding.i.bindings parsed-url) + $(bindings t.bindings) :: - $(bindings t.bindings) + :- action.i.bindings + %^ cat 3 + %+ roll + ^- (list @t) + (join '/' (flop ['' u.suffix])) + (cury cat 3) + ?~ ext.request-line '' + (cat 3 '.' u.ext.request-line) -- :: ++ forwarded-for @@ -2080,6 +2108,7 @@ :~ [[~ /~/login] duct [%authentication ~]] [[~ /~/logout] duct [%logout ~]] [[~ /~/channel] duct [%channel ~]] + [[~ /~/scry] duct [%scry ~]] == [~ http-server-gate] :: %trim: in response to memory pressure @@ -2223,20 +2252,6 @@ %disconnect =. server-state.ax (remove-binding:server binding.task) [~ http-server-gate] - :: - %wegh - :_ http-server-gate - :~ :* duct - %give - %mass - ^- mass - :+ %eyre %| - :~ bindings+&+bindings.server-state.ax - auth+&+authentication-state.server-state.ax - connections+&+connections.server-state.ax - channels+&+channel-state.server-state.ax - axle+&+ax - == == == == :: ++ take @@ -2265,7 +2280,6 @@ :: %run-app-request run-app-request %watch-response watch-response - %run-build run-build %sessions sessions %channel channel %acme acme-ack @@ -2336,15 +2350,6 @@ (handle-response http-event) [moves http-server-gate] :: - ++ run-build - :: - ?> ?=([%f %made *] sign) - :: - =/ event-args [[our eny duct now scry-gate] server-state.ax] - =/ handle-ford-response handle-ford-response:(per-server-event event-args) - =^ moves server-state.ax (handle-ford-response result.sign) - [moves http-server-gate] - :: ++ channel :: =/ event-args [[our eny duct now scry-gate] server-state.ax] @@ -2454,6 +2459,11 @@ [[~ /~/logout] [/e/load/logout]~ [%logout ~]] bindings.server-state.old ~? !success [%e %failed-to-setup-logout-endpoint] + =^ success bindings.server-state.old + %+ insert-binding + [[~ /~/scry] [/e/load/scry]~ [%scry ~]] + bindings.server-state.old + ~? !success [%e %failed-to-setup-scry-endpoint] %_ $ date.old %~2020.5.29 sessions.authentication-state.server-state.old ~ @@ -2472,6 +2482,15 @@ =* who p.why ?. ?=(%$ ren) [~ ~] + ?: =(tyl /whey) + =/ maz=(list mass) + :~ bindings+&+bindings.server-state.ax + auth+&+authentication-state.server-state.ax + connections+&+connections.server-state.ax + channels+&+channel-state.server-state.ax + axle+&+ax + == + ``mass+!>(maz) ?. ?=(%$ -.lot) [~ ~] ?. =(our who) diff --git a/pkg/arvo/sys/vane/ford.hoon b/pkg/arvo/sys/vane/ford.hoon index 37ef5fdde3..65567bff2f 100644 --- a/pkg/arvo/sys/vane/ford.hoon +++ b/pkg/arvo/sys/vane/ford.hoon @@ -1,6368 +1,10 @@ -:: ford: build system vane !: -:: Ford is a functional reactive build system. -:: -:: A Ford build is a function of the Urbit namespace and a date that -:: produces marked, typed data or an error. -:: -:: The function in the definition of a build is called a "schematic," -:: and it's represented by a Hoon data structure with twenty-five sub-types. -:: A schematic is a (possibly trivial) DAG of sub-builds to be performed. -:: The different schematic sub-types transform the results of their -:: sub-builds in different ways. -:: -:: We call the date in the definition of a build the "formal date" to -:: distinguish it from the time at which the build was performed. -:: -:: Each build is referentially transparent with respect to its formal date: -:: ask to run that function on the namespace and a particular formal date, -:: and Ford will always produce the same result. -:: -:: We can now say Ford is a functional build system, since each build is a -:: function. We have not yet explained how it's a functional reactive build -:: system. With Ford, you can subscribe to results of a build. Ford tracks -:: the result of a "live" build consisting of a static schematic and the -:: ever-changing current date. Whenever this live build's result changes, -:: Ford sends you the new result and the formal date of the build (the date -:: which would cause the same result if you asked Ford to build that -:: schematic again). This is a push-based FRP paradigm. -:: -:: The implementation is event-driven, like the rest of Urbit. While -:: performing a build, Ford registers each namespace access as a dependency -:: and also notes whether the dependency is "live," meaning the path within -:: the namespace updates with time. For example a live Clay dependency would -:: update the +case within the +beam over time. -:: -:: A request to perform a build without subscribing to its future changes is -:: called a "once build." -:: -:: After finishing a build, Ford subscribes to updates on the build's -:: dependencies. For now, this just means it subscribes to Clay for file -:: changes. Whenever any of the files in the subscription have new contents, -:: Clay will notify Ford, which will then rerun any live builds that depend -:: on any of the changed files and send its subscribers the new results. -:: -:: This matches the semantics of live builds defined above. If someone had -:: asked for a build of the schematic with a formal date d2 just before the -:: changed Clay files, Ford would respond with the result of the previous -:: build with formal date d1, which would still be an accurate -:: representation of the schematic's result at d2, since Ford knows none of -:: its dependencies changed between d1 and d2. -:: -:: Note that Ford can only calculate dependencies after running a build, -:: not before. This is because Ford can be thought of as an interpreter for -:: schematics, rather than a compiler, in the sense that it can't have a -:: dependency-gathering step followed by a build step. The dependencies of -:: some schematics must be calculated based on results, e.g. the %alts -:: schematic, which tries a sequence of sub-builds until one succeeds. If -:: the first sub-build succeeds, the build depends only on that first -:: sub-build, but if the first fails and the second succeeds, the build -:: depends on both. -:: -:: This dynamicity implies we don't know what we depend on until we depend -:: on it. Most build systems have this property, but this part of Ford's -:: job is easier than for most Unix-based build systems: Ford draws all -:: resources from an immutable namespace, and it can track every access of -:: that namespace. -:: -:: Ford might produce a build's result asynchronously, in a subsequent Arvo -:: event. This happens when accessing the namespace doesn't complete -:: synchronously, such as when grabbing a file from another ship. Ford -:: guarantees it will respond with build results in chronological order -:: using the formal date, not the order in which the builds completed. -:: -:: Ford does not guarantee it will notify a subscriber of a changed build -:: only once per change. In common usage it will not send duplicate -:: notifications, but it might if its cache was recently wiped. -:: -:: Ford uses dependency tracking, caching, and results of previous builds -:: to eliminate excess work. When rerunning a live build, Ford "promotes" -:: previous results to the new time if the build's dependencies hvaen't -:: changed since the previous build's formal date. Ford does this check -:: for each build in a tree of sub-builds under the "root build," which -:: is the build that was requested directly. -:: -:: In addition to the main %build +task sub-type, Ford also supports -:: four other commands: -:: -:: %kill: cancel a build -:: -:: A once build in progress will be canceled, including all of its -:: sub-builds that aren't part of any other builds. -:: -:: A live build's subscriptions will be canceled, its completed results -:: will be deleted, and its dependency tracking information will be -:: deleted. If a rebuild is in progress, it will be canceled. -:: -:: %keep: resize caches -:: -:: Ford maintains two caches: a :compiler-cache that stores -:: content-addressed compiler operations, such as parsing, compiling, -:: and type inference; and a :build-cache that stores previously -:: completed build trees along with their results and dependency tracking. -:: -:: The %keep command resets the maximum sizes of these caches, deleting -:: entries if necessary. -:: -:: %wipe: decimate storage -:: -:: The %wipe command removes build results from storage to free memory. -:: It deletes the specified percentage of build results, in LRU -:: (Least Recently Used) order. It also removes entries from the compiler -:: cache. It does not remove dependency tracking information. -:: -:: %wegh: report memory usage -:: -:: Like all vanes, Ford can also be asked to produce a human-readable -:: report of its memory usage. Nock cannot calculate its own memory use -:: directly, so instead we produce the nouns themselves, which the runtime -:: "weighs" based on its memory model. -:: -:: For details on Ford's implementation, consult Ford's vane interface core -:: near the bottom of the file. -:: -:: pit: a +vase of the hoon+zuse kernel, which is a deeply nested core -:: |= pit=vase -:: -=, contain -=, ford -:: ford internal data structures -:: -=> =~ +|= [our=ship now=@da eny=@uvJ ski=sley] |% -:: +move: arvo moves that ford can emit -:: -+= move - :: - $: :: duct: request identifier - :: - =duct - :: card: move contents; either a +note or a +gift:able - :: - card=(wind note gift:able) - == -:: +note: private request from ford to another vane -:: -+$ note - $~ [%c %warp *@p *riff:clay] - $% :: %c: to clay - :: - $: %c - :: %warp: internal (intra-ship) file request - :: - $>(%warp task:able:clay) - == == -:: +sign: private response from another vane to ford -:: -+$ sign - $~ [%c %writ *riot:clay] - $? :: %c: from clay - :: - :: XX also from behn due to %slip asynchronicity - :: - $: ?(%b %c) - $> $? :: %writ: internal (intra-ship) file response - :: - %writ - :: %wris: response to %mult; many changed files - :: - %wris - == - gift:able:clay - == == --- -|% -:: +axle: overall ford state, tagged by version -:: -+= axle - $% [%~2018.12.13 state=ford-state] - [%~2020.2.21 state=ford-state] - == -:: +ford-state: all state that ford maintains -:: -+= ford-state - $: :: builds: per-build state machine for all builds - :: - :: Ford holds onto all in-progress builds that were either directly - :: requested by a duct (root builds) or that are dependencies - :: (sub-builds) of a directly requested build. - :: - :: It also stores the last completed version of each live build tree - :: (root build and sub-builds), and any cached builds. - :: - builds=(map build build-status) - :: ducts: per-duct state machine for all incoming ducts (build requests) - :: - :: Ford tracks every duct that has requested a build until it has - :: finished dealing with that request. - :: - :: For live ducts, we store the duct while we repeatedly run new - :: versions of the live build it requested until it is explicitly - :: canceled by the requester. - :: - :: A once (non-live) duct, on the other hand, will be removed - :: as soon as the requested build has been completed. - :: - ducts=(map duct duct-status) - :: builds-by-schematic: all attempted builds, sorted by time - :: - :: For each schematic we've attempted to build at any time, - :: list the formal dates of all build attempts, sorted newest first. - :: - builds-by-schematic=(map schematic (list @da)) - :: pending-scrys: outgoing requests for static resources - :: - pending-scrys=(request-tracker scry-request) - :: pending-subscriptions: outgoing subscriptions on live resources - :: - pending-subscriptions=(request-tracker subscription) - :: build-cache: fifo queue of completed root builds - :: - $= build-cache - $: :: next-anchor-id: incrementing identifier for cache anchors - :: - next-anchor-id=@ud - :: queue: fifo queue of root builds identified by anchor id - :: - queue=(capped-queue build-cache-key) - == - :: compiler-cache: clock based cache of build results - :: - compiler-cache=(clock compiler-cache-key build-result) - == -:: +anchor: something which holds on to builds -:: -:: An anchor is a reference which keeps builds. This is either a %duct, in -:: which case the build is live because a duct is waiting for a response, or -:: a %cache, in which case the anchor is a cached build. -:: -:: When a duct would be removed from a build, the %duct anchor is replaced -:: with a %cache anchor. This %cache anchor refers to a FIFO queue of cached -:: builds. -:: -+= anchor - $% :: %duct: this is anchored on a duct - :: - [%duct =duct] - :: %cache: this is anchored to a cache entry - :: - [%cache id=@ud] - == -:: +build-status: current data for a build, including construction status -:: -:: +build-status stores the construction status of a build as a finite state -:: machine (:state). It stores links to dependent sub-builds in :subs, and -:: per-duct client builds in :clients. -:: -+= build-status - $: :: requesters: ducts for whom this build is the root build - :: - requesters=(set anchor) - :: clients: per duct information for this build - :: - clients=(jug anchor build) - :: subs: sub-builds of this build, for whom this build is a client - :: - subs=(map build build-relation) - :: state: a state machine for tracking the build's progress - :: - $= state - $% $: :: %untried: build has not been started yet - :: - %untried ~ - == - $: :: %blocked: build blocked on either sub-builds or resource - :: - :: If we're in this state and there are no blocks in :subs, - :: then we're blocked on a resource. - :: - %blocked ~ - == - $: :: %unblocked: we were blocked but now we aren't - :: - %unblocked ~ - == - $: :: %complete: build has finished running and has a result - :: - %complete - :: build-record: the product of the build, possibly tombstoned - :: - =build-record - == == == -:: +duct-status: information relating a build to a duct -:: -+= duct-status - $: :: live: whether this duct is being run live - :: - $= live - $% [%once in-progress=@da] - $: %live - :: - :: - in-progress=(unit @da) - :: the last subscription we made - :: - :: This can possibly have an empty set of resources, in which - :: we never sent a move. - :: - :: NOTE: This implies that a single live build can only depend - :: on live resources from a single disc. We don't have a - :: working plan for fixing this and will need to think very - :: hard about the future. - :: - last-sent=(unit [date=@da subscription=(unit subscription)]) - == == - :: root-schematic: the requested build for this duct - :: - root-schematic=schematic - == -:: +build-relation: how do two builds relate to each other? -:: -:: A +build-relation can be either :verified or not, and :blocked or not. -:: It is a symmetric relation between two builds, in the sense that both -:: the client and the sub will store the same relation, just pointing to -:: the other build. -:: -:: If it's not :verified, then the relation is a guess based on previous -:: builds. These guesses are used to ensure that we hold onto builds we -:: expect to be used in future builds. Each time we run +make on a build, -:: it might produce new :verified sub-builds, which may have been unverified -:: until then. Once a build completes, any unverified sub-builds must be -:: cleaned up, since it turned out they weren't used by the build after all. -:: -:: :blocked is used to note that a build can't be completed until that -:: sub-build has been completed. A relation can be :blocked but not :verified -:: if we're trying to promote a build, but we haven't run all its sub-builds -:: yet. In that case, we'll try to promote or run the sub-build in order to -:: determine whether we can promote the client. Until the sub-build has been -:: completed, the client is provisionally blocked on the sub-build. -:: -+= build-relation - $: :: verified: do we know this relation is real, or is it only a guess? - :: - verified=? - :: is this build blocked on this other build? - :: - blocked=? - == -:: +build-record: information associated with the result of a completed +build -:: -+= build-record - $% $: :: %tombstone: the build's result has been wiped - :: - %tombstone ~ - == - $: :: %value: we have the +build-result - :: - %value - :: last-accessed: last time we looked at the result - :: - :: This is used for LRU cache reclamation. - :: - last-accessed=@da - :: build-result: the stored value of the build's product - :: - =build-result - == == -:: +build: a referentially transparent request for a build -:: -:: Each unique +build will always produce the same +build-result -:: when run (if it completes). A live build consists of a sequence of -:: instances of +build with the same :schematic and increasing :date. -:: -+= build - $: :: date: the formal date of this build; unrelated to time of execution - :: - date=@da - :: schematic: the schematic that determines how to run this build - :: - =schematic - == -:: +request-tracker: generic tracker and multiplexer for pending requests -:: -++ request-tracker - |* request-type=mold - %+ map request-type - $: :: waiting: ducts blocked on this request - :: - waiting=(set duct) - :: originator: the duct that kicked off the request - :: - originator=duct - == -:: +subscription: a single subscription to changes on a set of resources -:: -+= subscription - $: :: date: date this was made - :: - date=@da - :: disc: ship and desk for all :resources - :: - =disc - :: resources: we will be notified if any of these resources change - :: - resources=(set resource) - == -:: +scry-request: parsed arguments to a scry operation -:: -+= scry-request - $: :: vane: the vane from which to make the request - :: - :: If we add other vanes in the future, this will become a fork type. - :: For now, though, Ford only knows how to make asynchronous scry - :: requests to Clay. - :: - vane=%c - :: care: type of request - :: - care=care:clay - :: beam: request path - :: - =beam - == -:: +compiler-cache-key: content addressable build definitions -:: -+= compiler-cache-key - $% [%call gate=vase sample=vase] - [%hood =beam txt=@t] - [%ride formula=hoon subject=vase] - [%slim subject-type=type formula=hoon] - [%slit gate=type sample=type] - == -:: +build-cache-key: key for the fifo cache of completed build trees -:: -+= build-cache-key - $: :: id: incrementing identifier for an +anchor - :: - id=@ud - :: root-build: the root build associated with this anchor - :: - root-build=build - == -:: +build-receipt: result of running +make -:: -:: A +build-receipt contains all information necessary to perform the -:: effects and state mutations indicated by a call to +make. If :build -:: succeeded, :result will be %build-result; otherwise, it will be %blocks. -:: -:: After +make runs on a batch of builds, the resulting +build-receipt's are -:: applied one at a time. -:: -+= build-receipt - $: :: build: the build we worked on - :: - =build - :: result: the outcome of this build - :: - $= result - $% :: %build-result: the build produced a result - :: - $: %build-result - =build-result - == - :: %blocks: the build blocked on the following builds or resource - :: - $: %blocks - :: builds: builds that :build blocked on - :: - builds=(list build) - == - == - :: sub-builds: subbuilds of :build - :: - :: While running +make on :build, we need to keep track of any - :: sub-builds that we try to access so we can keep track of - :: component linkages and cache access times. - :: - sub-builds=(list build) - :: cache-access: if not ~, cache this result as :compiler-cache-key. - :: - cache-access=(unit [=compiler-cache-key new=?]) - == --- -=, format -|% -:: +tear: split a +term into segments delimited by `-` -:: -:: Example: -:: ``` -:: dojo> (tear 'foo-bar-baz') -:: ['foo' 'bar' 'baz'] -:: ``` -:: -++ tear - |= a=term - ^- (list term) - :: sym-no-heps: a parser for terms with no heps and a leading letter - :: - =/ sym-no-heps (cook crip ;~(plug low (star ;~(pose low nud)))) - :: - (fall (rush a (most hep sym-no-heps)) /[a]) -:: +segments: compute all paths from :path-part, replacing some `/`s with `-`s -:: -:: For example, when passed a :path-part of 'foo-bar-baz', -:: the product will contain: -:: ``` -:: dojo> (segments 'foo-bar-baz') -:: [/foo/bar/baz /foo/bar-baz /foo-bar/baz /foo-bar-baz] -:: ``` -:: -++ segments - |= path-part=@tas - ^- (list path) - :: - =/ join |=([a=@tas b=@tas] (crip "{(trip a)}-{(trip b)}")) - :: - =/ torn=(list @tas) (tear path-part) - :: - |- ^- (list (list @tas)) - :: - ?< ?=(~ torn) - :: - ?: ?=([@ ~] torn) - ~[torn] - :: - %- zing - %+ turn $(torn t.torn) - |= s=(list @tas) - ^- (list (list @tas)) - :: - ?> ?=(^ s) - ~[[i.torn s] [(join i.torn i.s) t.s]] -:: +build-to-tape: convert :build to a printable format -:: -:: Builds often contain the standard library and large types, so -:: this function should always be called when trying to print a +build. -:: -++ build-to-tape - |= =build - ^- tape - ~+ - :: - =/ enclose |=(tape "[{+<}]") - =/ date=@da date.build - =/ =schematic schematic.build - :: - %- enclose - %+ welp (trip (scot %da date)) - %+ welp " " - :: - ?+ -.schematic - :(welp "[" (trip -.schematic) " {<`@uvI`(mug schematic)>}]") - :: - %$ - "literal" - :: - ^ - %- enclose - ;:(welp $(build [date head.schematic]) " " $(build [date tail.schematic])) - :: - %alts - ;: welp - %+ roll choices.schematic - |= [choice=^schematic txt=_"[alts"] - :(welp txt " " ^$(schematic.build choice)) - :: - "]" - == - :: - %core - :(welp "[core " (spud (en-beam (rail-to-beam source-path.schematic))) "]") - :: - %hood - :(welp "[hood " (spud (en-beam (rail-to-beam source-path.schematic))) "]") - :: - %plan - ;: welp - "[plan " - (spud (en-beam (rail-to-beam path-to-render.schematic))) - "]" - == - :: - %scry - (spud (en-beam (extract-beam resource.schematic ~))) - :: - :: %slim - :: "slim {} {}" - :: - %vale - ;: welp - "[vale [" - (trip (scot %p ship.disc.schematic)) - " " - (trip desk.disc.schematic) - "] " - (trip mark.schematic) - "]" - == - == -:: +rail-to-beam: convert :rail to a +beam, filling in the case with `[%ud 0]` -:: -++ rail-to-beam - |= =rail - ^- beam - [[ship.disc.rail desk.disc.rail [%ud 0]] spur.rail] -:: +rail-to-path: pretty-printable rail -:: -++ rail-to-path - |= =rail - ^- path - (en-beam (rail-to-beam rail)) -:: +unify-jugs: make a new jug, unifying sets for all keys -:: -:: Example: -:: ``` -:: dojo> %+ unify-jugs -:: (~(gas by *(jug @tas @ud)) ~[[%a (sy 1 2 ~)] [%b (sy 4 5 ~)]]) -:: (~(gas by *(jug @tas @ud)) ~[[%b (sy 5 6 ~)] [%c (sy 7 8 ~)]]) -:: -:: {[p=%a q={1 2 3}] [p=%b q={4 5 6}] [p=%c q={7 8}]} -:: ``` -:: -++ unify-jugs - |* [a=(jug) b=(jug)] - ^+ a - :: - =/ tapped ~(tap by b) - :: - |- ^+ a - ?~ tapped a - :: - =/ key p.i.tapped - =/ vals ~(tap in q.i.tapped) - :: - =. a - |- ^+ a - ?~ vals a - :: - $(vals t.vals, a (~(put ju a) key i.vals)) - :: - $(tapped t.tapped) -:: +path-to-resource: decode a +resource from a +wire -:: -++ path-to-resource - |= =path - ^- (unit resource) - :: - =/ scry-request=(unit scry-request) (path-to-scry-request path) - ?~ scry-request - ~ - =+ [vane care bem]=u.scry-request - =/ =beam bem - =/ =rail [disc=[p.beam q.beam] spur=s.beam] - `[vane care rail] -:: +scry-request-to-path: encode a +scry-request in a +wire -:: -:: Example: -:: ``` -:: dojo> %- scry-request-to-path -:: [%c %x [[~zod %home [%da ~2018.1.1]] /hoon/bar]]) -:: -:: /cx/~zod/home/~2018.1.1/bar/hoon -:: ``` -:: -++ scry-request-to-path - |= =scry-request - ^- path - =/ =term (cat 3 [vane care]:scry-request) - [term (en-beam beam.scry-request)] -:: +path-to-scry-request: parse :path's components into :vane, :care, and :rail -:: -++ path-to-scry-request - |= =path - ^- (unit scry-request) - :: - ?~ path - ~ - ?~ vane=((soft ,%c) (end 3 1 i.path)) - ~ - ?~ care=((soft care:clay) (rsh 3 1 i.path)) - ~ - ?~ beam=(de-beam t.path) - ~ - ?. ?=(%da -.r.u.beam) - ~ - `[u.vane u.care u.beam] -:: +scry-request-to-build: convert a +scry-request to a %scry build -:: -++ scry-request-to-build - |= =scry-request - ^- build - :: we only operate on dates, not other kinds of +case:clay - :: - ?> ?=(%da -.r.beam.scry-request) - :: - =, scry-request - [p.r.beam [%scry [vane care `rail`[[p q] s]:beam]]] -:: +extract-beam: obtain a +beam from a +resource -:: -:: Fills case with [%ud 0] for live resources if :date is `~`. -:: For once resources, ignore :date. -:: -++ extract-beam - |= [=resource date=(unit @da)] ^- beam - :: - =/ =case ?~(date [%ud 0] [%da u.date]) - :: - =, rail.resource - [[ship.disc desk.disc case] spur] -:: +extract-disc: obtain a +disc from a +resource -:: -++ extract-disc - |= =resource ^- disc - disc.rail.resource -:: +get-sub-schematics: find any schematics contained within :schematic -:: -++ get-sub-schematics - |= =schematic - ^- (list ^schematic) - ?- -.schematic - ^ ~[head.schematic tail.schematic] - %$ ~ - %pin ~[schematic.schematic] - %alts choices.schematic - %bake ~ - %bunt ~ - %call ~[gate.schematic sample.schematic] - %cast ~[input.schematic] - %core ~ - %diff ~[start.schematic end.schematic] - %dude ~[attempt.schematic] - %hood ~ - %join ~[first.schematic second.schematic] - %list schematics.schematic - %mash ~[schematic.first.schematic schematic.second.schematic] - %mute [subject.schematic (turn mutations.schematic tail)] - %pact ~[start.schematic diff.schematic] - %path ~ - %plan ~ - %reef ~ - %ride ~[subject.schematic] - %same ~[schematic.schematic] - %scry ~ - %slim ~ - %slit ~ - %vale ~ - %volt ~ - %walk ~ - == -:: +by-schematic: door for manipulating :by-schematic.builds.ford-state -:: -:: The :dates list for each key in :builds is sorted in reverse -:: chronological order. These operations access and mutate keys and values -:: of :builds and maintain that sort order. -:: -++ by-schematic - |_ builds=(map schematic (list @da)) - :: +put: add a +build to :builds - :: - :: If :build already exists in :builds, this is a no-op. - :: Otherwise, replace the value at the key :schematic.build - :: with a new :dates list that contains :date.build. - :: - ++ put - |= =build - ^+ builds - %+ ~(put by builds) schematic.build - :: - =/ dates (~(gut by builds) schematic.build ~) - |- - ^+ dates - ?~ dates - [date.build ~] - ?: =(i.dates date.build) - dates - ?: (gth date.build i.dates) - [date.build dates] - [i.dates $(dates t.dates)] - :: +del: remove a +build from :builds - :: - :: Removes :build from :builds by replacing the value at - :: the key :schematic.build with a new :dates list with - :: :date.build omitted. If the resulting :dates list is - :: empty, then remove the key-value pair from :builds. - :: - ++ del - |= =build - ^+ builds - =. builds - %+ ~(jab by builds) schematic.build - |= dates=(list @da) - ~| build+build - =/ date-index (need (find [date.build]~ dates)) - (oust [date-index 1] dates) - :: if :builds has an empty entry for :build, delete it - :: - =? builds - =(~ (~(got by builds) schematic.build)) - (~(del by builds) schematic.build) - :: - builds - :: +find-previous: find the most recent older build with :schematic.build - :: - ++ find-previous - |= =build - ^- (unit ^build) - :: - =/ dates=(list @da) (~(gut by builds) schematic.build ~) - :: - |- ^- (unit ^build) - ?~ dates ~ - :: - ?: (lth i.dates date.build) - `[i.dates schematic.build] - $(dates t.dates) - :: +find-next: find the earliest build of :schematic.build later than :build - :: - ++ find-next - |= =build - ^- (unit ^build) - :: - =/ dates=(list @da) (flop (~(gut by builds) schematic.build ~)) - :: - |- ^- (unit ^build) - ?~ dates ~ - :: - ?: (gth i.dates date.build) - `[i.dates schematic.build] - $(dates t.dates) - -- -:: +get-request-ducts: all ducts waiting on this request -:: -++ get-request-ducts - |* [tracker=(request-tracker) request=*] - ^- (list duct) - :: - ?~ val=(~(get by tracker) request) - ~ - ~(tap in waiting.u.val) -:: +put-request: associates a +duct with a request -:: -++ put-request - |* [tracker=(request-tracker) request=* =duct] - :: - %+ ~(put by tracker) request - ?~ existing=(~(get by tracker) request) - [(sy duct ~) duct] - u.existing(waiting (~(put in waiting.u.existing) duct)) -:: +del-request: remove a duct and produce the originating duct if empty -:: -++ del-request - |* [tracker=(request-tracker) request=* =duct] - ^- [(unit ^duct) _tracker] - :: remove :duct from the existing :record of this :request - :: - =/ record (~(got by tracker) request) - =. waiting.record (~(del in waiting.record) duct) - :: if no more ducts wait on :request, delete it - :: - ?^ waiting.record - [~ (~(put by tracker) request record)] - [`originator.record (~(del by tracker) request)] -:: +parse-scaffold: produces a parser for a hoon file with +crane instances -:: -:: Ford parses a superset of hoon which contains additional runes to -:: represent +crane s. This parses to a +scaffold. -:: -:: src-beam: +beam of the source file we're parsing -:: -++ parse-scaffold - |= src-beam=beam - :: - =/ hoon-parser (vang & (en-beam src-beam)) - |^ :: - %+ cook - |= a=[@ud (list ^cable) (list ^cable) (list ^crane) (list hoon)] - ^- scaffold - [[[p q] s]:src-beam a] - :: - %+ ifix [gay gay] - ;~ plug - :: parses the zuse version, eg "/? 309" - :: - ;~ pose - (ifix [;~(plug net wut gap) gap] dem) - (easy zuse) - == - :: pareses the structures, eg "/- types" - :: - ;~ pose - (ifix [;~(plug net hep gap) gap] (most ;~(plug com gaw) cable)) - (easy ~) - == - :: parses the libraries, eg "/+ lib1, lib2" - :: - ;~ pose - (ifix [;~(plug net lus gap) gap] (most ;~(plug com gaw) cable)) - (easy ~) - == - :: - (star ;~(sfix crane gap)) - :: - (most gap tall:hoon-parser) - == - :: +beam: parses a hood path and converts it to a beam - :: - ++ beam - %+ sear de-beam - ;~ pfix - net - (sear plex (stag %clsg poor)):hoon-parser - == - :: +cable: parses a +^cable, a reference to something on the filesystem - :: - :: This parses: - :: - :: `library` -> wraps `library` around the library `library` - :: `face=library` -> wraps `face` around the library `library` - :: `*library` -> exposes `library` directly to the subject - :: - ++ cable - %+ cook |=(a=^cable a) - ;~ pose - (stag ~ ;~(pfix tar sym)) - (cook |=([face=term tis=@ file=term] [`face file]) ;~(plug sym tis sym)) - (cook |=(a=term [`a a]) sym) - == - :: +crane: all runes that start with / which aren't /?, /-, /+ or //. - :: - ++ crane - =< apex - :: whether we allow tall form - =| allow-tall-form=? - :: - |% - ++ apex - %+ knee *^crane |. ~+ - ;~ pfix net - ;~ pose - :: `/~` hoon literal - :: - (stag %fssg ;~(pfix sig hoon)) - :: `/$` process query string - :: - (stag %fsbc ;~(pfix bus hoon)) - :: `/|` first of many options that succeeds - :: - (stag %fsbr ;~(pfix bar parse-alts)) - :: `/=` wrap a face around a crane - :: - (stag %fsts ;~(pfix tis parse-face)) - :: `/.` null terminated list - :: - (stag %fsdt ;~(pfix dot parse-list)) - :: `/,` switch by path - :: - (stag %fscm ;~(pfix com parse-switch)) - :: `/&` pass through a series of mark - :: - (stag %fspm ;~(pfix pad parse-pipe)) - :: `/_` run a crane on each file in the current directory - :: - (stag %fscb ;~(pfix cab subcrane)) - :: `/;` passes date through a gate - :: - (stag %fssm ;~(pfix mic parse-gate)) - :: `/:` evaluate at path - :: - (stag %fscl ;~(pfix col parse-at-path)) - :: `/^` cast - :: - (stag %fskt ;~(pfix ket parse-cast)) - :: `/*` run a crane on each file with current path as prefix - :: - (stag %fstr ;~(pfix tar subcrane)) - :: `/!mark/ evaluate as hoon, then pass through mark - :: - (stag %fszp ;~(pfix zap ;~(sfix sym net))) - :: `/mark/` passes current path through :mark - :: - (stag %fszy ;~(sfix sym net)) - == - == - :: +parse-alts: parse a set of alternatives - :: - ++ parse-alts - %+ wide-or-tall - (ifix [lit rit] (most ace subcrane)) - ;~(sfix (star subcrane) gap duz) - :: +parse-face: parse a face around a subcrane - :: - ++ parse-face - %+ wide-or-tall - ;~(plug sym ;~(pfix tis subcrane)) - ;~(pfix gap ;~(plug sym subcrane)) - :: +parse-list: parse a null terminated list of cranes - :: - ++ parse-list - %+ wide-or-tall - fail - ;~(sfix (star subcrane) gap duz) - :: +parse-switch: parses a list of [path crane] - :: - ++ parse-switch - %+ wide-or-tall - fail - =- ;~(sfix (star -) gap duz) - ;~(pfix gap net ;~(plug static-path subcrane)) - :: +parse-pipe: parses a pipe of mark conversions - :: - ++ parse-pipe - %+ wide-or-tall - ;~(plug (plus ;~(sfix sym pad)) subcrane) - =+ (cook |=(a=term [a ~]) sym) - ;~(pfix gap ;~(plug - subcrane)) - :: +parse-gate: parses a gate applied to a crane - :: - ++ parse-gate - %+ wide-or-tall - ;~(plug ;~(sfix wide:hoon-parser mic) subcrane) - ;~(pfix gap ;~(plug tall:hoon-parser subcrane)) - :: +parse-at-path: parses a late bound bath - :: - ++ parse-at-path - %+ wide-or-tall - ;~(plug ;~(sfix late-bound-path col) subcrane) - ;~(pfix gap ;~(plug late-bound-path subcrane)) - :: +parse-cast: parses a mold and then the subcrane to apply that mold to - :: - ++ parse-cast - %+ wide-or-tall - ;~(plug ;~(sfix wyde:hoon-parser ket) subcrane) - ;~(pfix gap ;~(plug till:hoon-parser subcrane)) - :: +subcrane: parses a subcrane - :: - ++ subcrane - %+ wide-or-tall - apex(allow-tall-form |) - ;~(pfix gap apex) - :: +wide-or-tall: parses tall form hoon if :allow-tall-form is %.y - :: - ++ wide-or-tall - |* [wide=rule tall=rule] - ?. allow-tall-form wide - ;~(pose wide tall) - :: +hoon: parses hoon as an argument to a crane - :: - ++ hoon - %+ wide-or-tall - (ifix [lac rac] (stag %cltr (most ace wide:hoon-parser))) - ;~(pfix gap tall:hoon-parser) - -- - :: +static-path: parses a path - :: - ++ static-path - (sear plex (stag %clsg (more net hasp))):hoon-parser - :: +late-bound-path: a path whose time varies - :: - ++ late-bound-path - ;~ pfix net - %+ cook |=(a=truss a) - => hoon-parser - ;~ plug - (stag ~ gash) - ;~(pose (stag ~ ;~(pfix cen porc)) (easy ~)) - == - == - -- -:: +per-event: per-event core; main build engine -:: -:: This arm produces a gate that when called with state and event -:: information produces the core of Ford's main build engine. -:: -:: The main build engine core has the following entry points: -:: -:: +start-build start performing a build -:: +rebuild rerun a live build at a new date -:: +unblock continue a build that was waiting on a resource -:: +cancel stop trying to run a build and delete its tracking info -:: +wipe wipe the build storage to free memory -:: +keep resize caches, deleting entries if necessary -:: -:: The main internal arm is +execute-loop, which is called from +start-build, -:: +rebuild, and +unblock. +execute defines Ford's build loop. -:: -++ per-event - :: moves: the moves to be sent out at the end of this event, reversed - :: - =| moves=(list move) - :: scry-results: responses to scry's to handle in this event - :: - :: If a value is `~`, the requested resource is not available. - :: Otherwise, the value will contain a +cage. - :: - =| scry-results=(map scry-request (unit cage)) - :: next-builds: builds to perform in the next iteration - :: - =| next-builds=(set build) - :: candidate-builds: builds which might go into next-builds - :: - =| candidate-builds=(set build) - :: gate that produces the +per-event core from event information - :: - :: Produces a core containing Ford's main build engine. - :: - ~% %f ..is ~ - |= [[our=@p =duct now=@da scry=sley] state=ford-state] - :: - ~% %per-event + ~ - |% - :: +finalize: extract moves and state from the +per-event core - :: - :: Run once at the end of processing an event. - :: - ++ finalize - ^- [(list move) ford-state] - [(flop moves) state] - :: |entry-points: externally fired arms - :: - ::+| entry-points - :: - :: +start-build: perform a fresh +build, either live or once - :: - :: This might complete the build, or the build might block on one or more - :: requests for resources. Calls +execute-loop. - :: - ++ start-build - ~/ %start-build - |= [=build live=?] - ^- [(list move) ford-state] - :: - =< finalize - :: associate :duct with :build in :ducts.state - :: - =. ducts.state - %+ ~(put by ducts.state) duct - :_ schematic.build - ?: live - [%live in-progress=`date.build last-sent=~] - [%once in-progress=date.build] - :: register a state machine for :build in :builds.state - :: - =. state (add-build build) - :: :anchor: the reason we hold onto the root of this build tree - :: - =/ =anchor [%duct duct] - :: register :duct as an anchor in :requesters.build-status - :: - :: This establishes :build as the root build for :duct. - :: - =. builds.state - %+ ~(jab by builds.state) build - |= =build-status - build-status(requesters (~(put in requesters.build-status) anchor)) - :: copy :anchor into any preexisting descendants - :: - :: Sub-builds will reference :build in their :clients.build-status, - :: using `[%duct duct]` as the key. Some sub-builds might already - :: exist if we've already started running :build, so make sure they - :: know who their daddy is. - :: - =. builds.state (add-anchor-to-subs anchor build) - :: run +execute on :build in a loop until it completes or blocks - :: - (execute-loop (sy [build ~])) - :: +rebuild: rebuild a live build based on +resource updates - :: - :: For every changed resource, run the %scry build for that - :: for that resource. Then rebuild upward using the main +execute-loop - :: until all relevant builds either complete or block on external - :: resources. Use dependency tracking information from the previous - :: run of this live build to inform the dependency tracking for this - :: new rebuild. - :: - ++ rebuild - ~/ %rebuild - |= $: =subscription - new-date=@da - =disc - care-paths=(set [care=care:clay =path]) - == - ^- [(list move) ford-state] - :: - ~| [%rebuilding new-date disc] - :: - =< finalize - :: mark this subscription as complete now that we've heard a response - :: - =. pending-subscriptions.state - +:(del-request pending-subscriptions.state subscription duct) - :: for every changed resource, create a %scry build - :: - =/ builds=(list build) - %+ turn ~(tap in care-paths) - |= [care=care:clay =path] - ^- build - :: - [new-date [%scry [%c care rail=[disc spur=(flop path)]]]] - :: sanity check; only rebuild live builds, not once builds - :: - =/ duct-status (~(got by ducts.state) duct) - ?> ?=(%live -.live.duct-status) - :: sanity check; only rebuild once we've completed the previous one - :: - ?> ?=(~ in-progress.live.duct-status) - ?> ?=(^ last-sent.live.duct-status) - :: set the in-progress date for this new build - :: - =. ducts.state - %+ ~(put by ducts.state) duct - duct-status(in-progress.live `new-date) - :: copy the previous build's tree as provisional sub-builds - :: - :: This provides an upward rebuild path from leaves to root, - :: so that once the %scry builds complete, we'll know to rebuild - :: their clients. This process will continue up through rebuilding - :: the root build. - :: - :: If the build at this new date ends up with a different set of - :: dependencies from its previous incarnation, provisional sub-builds - :: that weren't actually used will be removed in - :: +cleanup-orphaned-provisional-builds. - :: - =/ old-root=build - [date.u.last-sent.live.duct-status root-schematic.duct-status] - :: - =. state - :: - ~| [%duct-doesnt-refer-to-real-build live.duct-status] - ~| [%missing-build (build-to-tape old-root)] - ~| [%dates (~(get by builds-by-schematic.state) root-schematic.duct-status)] - ?> (~(has by builds.state) old-root) - :: - (copy-build-tree-as-provisional old-root new-date=new-date) - :: gather all the :builds, forcing reruns - :: - :: The normal +gather logic would promote the previous results - :: for these %scry builds, since we have subscriptions on them. - :: We pass `force=%.y` to ensure the builds get enqueued instead - :: of promoted. - :: - =. ..execute (gather (sy builds) force=%.y) - :: rebuild resource builds at the new date - :: - :: This kicks off the main build loop, which will first build - :: :builds, then rebuild upward toward the root. If the whole - :: build tree completes synchronously, then this will produce - :: %made moves at the end of this event. Otherwise, it will - :: block on resources and complete during a later event. - :: - (execute-loop ~) - :: +unblock: continue builds that had blocked on :resource - :: - :: A build can be stymied temporarily if it depends on a resource - :: that must be fetched asynchronously. +unblock is called when - :: we receive a response to a resource request that blocked a build. - :: - :: We pick up the build from where we left off, starting with the - :: %scry build that blocked on this resource last time we tried it. - :: - ++ unblock - ~/ %unblock - |= [=scry-request scry-result=(unit cage)] - ^- [(list move) ford-state] - :: - =< finalize - :: place :scry-result in :scry-results.per-event - :: - :: We don't want to call the actual +scry function again, - :: because we already tried that in a previous event and it - :: had no synchronous answer. This +unblock call is a result - :: of the response to the asynchronous request we made to - :: retrieve that resource from another vane. - :: - :: Instead, we'll intercept any calls to +scry by looking up - :: the arguments in :scry-results.per-event. This is ok because - :: in this function we attempt to run every +build that had - :: blocked on the resource, so the information is guaranteed - :: to be used during this event before it goes out of scope. - :: - =. scry-results (~(put by scry-results) scry-request scry-result) - :: mark this +scry-request as complete now that we have a response - :: - =. pending-scrys.state - +:(del-request pending-scrys.state scry-request duct) - :: update :unblocked-build's state machine to reflect its new status - :: - =/ unblocked-build=build (scry-request-to-build scry-request) - =. builds.state - %+ ~(jab by builds.state) unblocked-build - |= =build-status - build-status(state [%unblocked ~]) - :: jump into the main build loop, starting with :unblocked-build - :: - (execute-loop (sy unblocked-build ~)) - :: +wipe: forcibly decimate build results from the state - :: - :: +wipe decimates both the :compiler-cache and the results in - :: :builds.state. It removes the specified percentage of build results - :: from the state. For simplicity, it considers the weight of each - :: compiler cache line to be equal to the weight of a build result. - :: - :: It deletes cache entries before dipping into :builds.state; it only - :: converts entries in :builds.state to %tombstone's if there aren't - :: enough entries in the compiler cache to sate the request's bloodlust. - :: - :: When deleting results from :builds.state, it first sorts them by - :: their :last-accessed date so that the stalest builds are deleted first. - :: We do not touch the :build-cache directly, but because the results - :: of the builds in :build-cache live in :builds.state, the results of - :: both FIFO-cached builds and active builds are all sorted and trimmed. - :: - ++ wipe - ~/ %wipe - |= percent-to-remove=@ud - ^+ state - :: removing 0% is the same as doing nothing, so do nothing - :: - ?: =(0 percent-to-remove) - ~& %wipe-no-op - state - :: - ~| [%wipe percent-to-remove=percent-to-remove] - ?> (lte percent-to-remove 100) - :: find all completed builds, sorted by :last-accessed date - :: - =/ completed-builds=(list build) - =- (turn - head) - %+ sort - :: filter for builds with a stored +build-result - :: - %+ skim ~(tap by builds.state) - |= [=build =build-status] - ^- ? - :: - ?=([%complete %value *] state.build-status) - :: sort by :last-accessed date - :: - |= [[* a=build-status] [* b=build-status]] - ^- ? - :: - ?> ?=([%complete %value *] state.a) - ?> ?=([%complete %value *] state.b) - :: - %+ lte - last-accessed.build-record.state.a - last-accessed.build-record.state.b - :: determine how many builds should remain after decimation - :: - :: This formula has the property that repeated applications - :: of +wipe with anything other than 100% retention rate will - :: always eventually remove every build. - :: - =/ num-completed-builds=@ud - (add (lent completed-builds) size.compiler-cache.state) - =/ percent-to-keep=@ud (sub 100 percent-to-remove) - =/ num-to-keep=@ud (div (mul percent-to-keep num-completed-builds) 100) - =/ num-to-remove=@ud (sub num-completed-builds num-to-keep) - :: - |^ ^+ state - :: - =+ cache-size=size.compiler-cache.state - ?: (lte num-to-remove cache-size) - (remove-from-cache num-to-remove) - =. compiler-cache.state - %~ purge - (by-clock compiler-cache-key build-result) - compiler-cache.state - (tombstone-builds (sub num-to-remove cache-size)) - :: - ++ remove-from-cache - |= count=@ud - %_ state - compiler-cache - %- %~ trim - (by-clock compiler-cache-key build-result) - compiler-cache.state - count - == - :: - ++ tombstone-builds - |= num-to-remove=@ud - :: - ~| [%wipe num-to-remove=num-to-remove] - :: the oldest :num-to-remove builds are considered stale - :: - =/ stale-builds (scag num-to-remove completed-builds) - :: iterate over :stale-builds, replacing with %tombstone's - :: - |- ^+ state - ?~ stale-builds state - :: replace the build's entry in :builds.state with a %tombstone - :: - =. builds.state - =< builds - %+ update-build-status i.stale-builds - |= =build-status - build-status(state [%complete %tombstone ~]) - :: - $(stale-builds t.stale-builds) - -- - :: +keep: resize caches - :: - :: Ford maintains two caches: a :build-cache for caching previously - :: completed build trees, and a :compiler-cache for caching various - :: compiler operations that tend to be shared among multiple builds. - :: - :: To handle this command, we reset the maximum sizes of both of - :: these caches, removing entries from the caches if necessary. - :: - ++ keep - ~/ %keep - |= [compiler-cache-size=@ud build-cache-size=@ud] - ^+ state - :: pop old builds out of :build-cache and remove their cache anchors - :: - =^ pops queue.build-cache.state - %. build-cache-size - ~(resize (to-capped-queue build-cache-key) queue.build-cache.state) - :: - =. state - |- ^+ state - ?~ pops state - :: - =. state (remove-anchor-from-root root-build.i.pops [%cache id.i.pops]) - :: - $(pops t.pops) - :: resize the :compiler-cache - :: - %_ state - compiler-cache - %- %~ resize - (by-clock compiler-cache-key build-result) - compiler-cache.state - compiler-cache-size - == - :: +cancel: cancel a build - :: - :: When called on a live build, removes all tracking related to the live - :: build, and no more %made moves will be sent for that build. - :: - :: When called on a once build, removes all tracking related to the once - :: build, and that build will never be completed or have a %made sent. - :: - :: When called on a build that isn't registered in :state, such as a - :: completed once build, or a build that has already been canceled, - :: prints and no-ops. - :: - ++ cancel ^+ [moves state] - :: - =< finalize - :: - ?~ duct-status=(~(get by ducts.state) duct) - ~& [%no-build-for-duct duct] - ..execute - :: :duct is being canceled, so remove it unconditionally - :: - =. ducts.state (~(del by ducts.state) duct) - :: if the duct was not live, cancel any in-progress builds - :: - ?: ?=(%once -.live.u.duct-status) - :: - =/ root-build=build [in-progress.live root-schematic]:u.duct-status - :: - =. ..execute (cancel-scrys root-build) - =. state (remove-anchor-from-root root-build [%duct duct]) - ..execute - :: if the duct was live and has an unfinished build, cancel it - :: - =? ..execute ?=(^ in-progress.live.u.duct-status) - :: - =/ root-build=build [u.in-progress.live root-schematic]:u.duct-status - :: - =. ..execute (cancel-scrys root-build) - =. state (remove-anchor-from-root root-build [%duct duct]) - ..execute - :: if there is no completed build for the live duct, we're done - :: - ?~ last-sent=last-sent.live.u.duct-status - ..execute - :: there is a completed build for the live duct, so delete it - :: - =/ root-build=build [date.u.last-sent root-schematic.u.duct-status] - :: - =. state (remove-anchor-from-root root-build [%duct duct]) - :: - ?~ subscription.u.last-sent - ..execute - (cancel-clay-subscription u.subscription.u.last-sent) - :: +cancel-scrys: cancel all blocked %scry sub-builds of :root-builds - :: - ++ cancel-scrys - |= root-build=build - ^+ ..execute - :: - =/ blocked-sub-scrys ~(tap in (collect-blocked-sub-scrys root-build)) - :: - |- ^+ ..execute - ?~ blocked-sub-scrys ..execute - :: - =. ..execute (cancel-scry-request i.blocked-sub-scrys) - :: - $(blocked-sub-scrys t.blocked-sub-scrys) - :: +move-root-to-cache: replace :duct with a %cache anchor in :build's tree - :: - ++ move-root-to-cache - ~/ %move-root-to-cache - |= =build - ^+ state - :: obtain the new cache id and increment the :next-anchor-id in the state - :: - =^ new-id next-anchor-id.build-cache.state - =/ id=@ud next-anchor-id.build-cache.state - [id +(id)] - :: replace the requester in the root build - :: - =. builds.state - %+ ~(jab by builds.state) build - |= =build-status - %_ build-status - requesters - =- (~(del in -) [%duct duct]) - =- (~(put in -) [%cache new-id]) - requesters.build-status - == - :: enqueue :build into cache, possibly popping and deleting a stale build - :: - =^ oldest queue.build-cache.state - %. [new-id build] - ~(put (to-capped-queue build-cache-key) queue.build-cache.state) - :: - =? state - ?=(^ oldest) - (remove-anchor-from-root root-build.u.oldest [%cache id.u.oldest]) - :: recursively replace :clients in :build and descendants - :: - |- ^+ state - :: - =/ client-status=build-status (got-build build) - =/ subs=(list ^build) ~(tap in ~(key by subs.client-status)) - :: - |- ^+ state - ?~ subs state - :: - =. builds.state - %+ ~(jab by builds.state) i.subs - |= =build-status - %_ build-status - clients - :: if we've already encountered :i.subs, don't overwrite - :: - ?: (~(has by clients.build-status) [%cache new-id]) - clients.build-status - :: - =/ old-clients-on-duct (~(get ju clients.build-status) [%duct duct]) - :: - =- (~(del by -) [%duct duct]) - =- (~(put by -) [%cache new-id] old-clients-on-duct) - clients.build-status - == - :: - =. state ^$(build i.subs) - :: - $(subs t.subs) - :: +remove-anchor-from-root: remove :anchor from :build's tree - :: - ++ remove-anchor-from-root - ~/ %remove-anchor-from-root - |= [=build =anchor] - ^+ state - :: - =. builds.state - %+ ~(jab by builds.state) build - |= =build-status - build-status(requesters (~(del in requesters.build-status) anchor)) - :: - =. builds.state (remove-anchor-from-subs build anchor) - :: - (cleanup build) - :: +remove-anchor-from-subs: recursively remove :anchor from sub-builds - :: - ++ remove-anchor-from-subs - ~/ %remove-anchor-from-subs - |= [=build =anchor] - ^+ builds.state - :: - =/ =build-status (got-build build) - =/ subs=(list ^build) ~(tap in ~(key by subs.build-status)) - =/ client=^build build - :: - |- ^+ builds.state - ?~ subs builds.state - :: - =/ sub-status=^build-status (got-build i.subs) - :: - =. clients.sub-status - (~(del ju clients.sub-status) anchor client) - :: - =. builds.state (~(put by builds.state) i.subs sub-status) - :: - =? builds.state !(~(has by clients.sub-status) anchor) - :: - ^$(build i.subs) - :: - $(subs t.subs) - :: +add-anchors-to-build-subs: for each sub, add all of :build's anchors - :: - ++ add-anchors-to-build-subs - ~/ %add-anchors-to-build-subs - |= =build - ^+ state - :: - =/ =build-status (got-build build) - =/ new-anchors - ~(tap in (~(put in ~(key by clients.build-status)) [%duct duct])) - =/ subs ~(tap in ~(key by subs.build-status)) - :: - =. state - |- - ^+ state - ?~ subs state - :: - =. state (add-build i.subs) - :: - $(subs t.subs) - :: - =. builds.state - |- ^+ builds.state - ?~ new-anchors builds.state - :: - =. builds.state (add-anchor-to-subs i.new-anchors build) - :: - $(new-anchors t.new-anchors) - :: - state - :: +add-anchor-to-subs: attach :duct to :build's descendants - :: - ++ add-anchor-to-subs - ~/ %add-anchor-to-subs - |= [=anchor =build] - ^+ builds.state - :: - =/ =build-status (got-build build) - =/ subs=(list ^build) ~(tap in ~(key by subs.build-status)) - =/ client=^build build - :: - |- ^+ builds.state - ?~ subs builds.state - :: - =/ sub-status=^build-status (got-build i.subs) - :: - =/ already-had-anchor=? (~(has by clients.sub-status) anchor) - :: - =. clients.sub-status - (~(put ju clients.sub-status) anchor client) - :: - =. builds.state (~(put by builds.state) i.subs sub-status) - :: - =? builds.state !already-had-anchor ^$(build i.subs) - :: - $(subs t.subs) - :: +copy-build-tree-as-provisional: prepopulate new live build - :: - :: Make a provisional copy of the completed old root build tree at the - :: :new time. - :: - ++ copy-build-tree-as-provisional - ~/ %copy-build-tree-as-provisional - |= [old-root=build new-date=@da] - ^+ state - ~| [old-root=(build-to-tape old-root) new-date=new-date] - :: - =/ old-client=build old-root - =/ new-client=build old-client(date new-date) - =. state (add-build new-client) - :: - =. builds.state - %+ ~(jab by builds.state) new-client - |= =build-status - build-status(requesters (~(put in requesters.build-status) [%duct duct])) - :: - =< copy-node - :: - |% - ++ copy-node - ^+ state - :: - =/ old-build-status=build-status (got-build old-client) - :: - =/ old-subs=(list build) ~(tap in ~(key by subs.old-build-status)) - =/ new-subs=(list build) (turn old-subs |=(a=build a(date new-date))) - :: - =. builds.state - (add-subs-to-client new-client new-subs [verified=%.n blocked=%.y]) - :: - |- - ^+ state - ?~ old-subs - state - :: - =. state (add-client-to-sub i.old-subs) - =. state - copy-node(old-client i.old-subs, new-client i.old-subs(date new-date)) - :: - $(old-subs t.old-subs) - :: - ++ add-client-to-sub - |= old-sub=build - ^+ state - :: - =/ new-sub old-sub(date new-date) - =. state (add-build new-sub) - :: - =. builds.state - %+ ~(jab by builds.state) new-sub - |= =build-status - %_ build-status - clients (~(put ju clients.build-status) [%duct duct] new-client) - == - :: - state - -- - :: +add-subs-to-client: register :new-subs as subs of :new-client - :: - ++ add-subs-to-client - ~/ %add-subs-to-client - |= [new-client=build new-subs=(list build) =build-relation] - ^+ builds.state - :: - %+ ~(jab by builds.state) new-client - |= =build-status - %_ build-status - subs - %- ~(gas by subs.build-status) - %+ murn new-subs - |= sub=build - ^- (unit (pair build ^build-relation)) - :: - ?^ (~(get by subs.build-status) sub) - ~ - `[sub build-relation] - == - :: |construction: arms for performing builds - :: - ::+| construction - :: - :: +execute-loop: +execute repeatedly until there's no more work to do - :: - :: Keep running +execute until all relevant builds either complete or - :: block on external resource requests. See +execute for details of each - :: loop execution. - :: - :: This implementation is for simplicity. In the longer term, we'd - :: like to just perform a single run through +execute and set a Behn timer - :: to wake us up immediately. This has the advantage that Ford stops hard - :: blocking the main Urbit event loop, letting other work be done. - :: - ++ execute-loop !. - ~/ %execute-loop - |= builds=(set build) - ^+ ..execute - :: - =. ..execute (execute builds) - :: - ?: ?& ?=(~ next-builds) - ?=(~ candidate-builds) - == - ..execute - :: - $(builds ~) - :: +execute: main recursive construction algorithm - :: - :: Performs the three step build process: First, figure out which builds - :: we're going to run this loop through the ford algorithm. Second, run - :: the gathered builds, possibly in parallel. Third, apply the - :: +build-receipt algorithms to the ford state. - :: - ++ execute - ~/ %execute - |= builds=(set build) - ^+ ..execute - :: - =. ..execute (gather builds force=%.n) - :: - =^ build-receipts ..execute run-builds - :: - (reduce build-receipts) - :: +gather: collect builds to be run in a batch - :: - :: The +gather phase is the first of the three parts of +execute. In - :: +gather, we look through each item in :candidate-builds. If we - :: should run the candidate build this cycle through the +execute loop, we - :: place it in :next-builds. +gather runs until it has no more candidates. - :: - ++ gather !. - ~/ %gather - |= [builds=(set build) force=?] - ^+ ..execute - :: add builds that were triggered by incoming event to the candidate list - :: - =. candidate-builds (~(uni in candidate-builds) builds) - :: - |^ ^+ ..execute - :: - ?: =(~ candidate-builds) - ..execute - :: - =/ next=build - ?< ?=(~ candidate-builds) - n.candidate-builds - =. candidate-builds (~(del in candidate-builds) next) - :: - $(..execute (gather-build next)) - :: +gather-build: looks at a single candidate build - :: - :: This gate inspects a single build. It might move it to :next-builds, - :: or promote it using an old build. It also might add this build's - :: sub-builds to :candidate-builds. - :: - ++ gather-build - |= =build - ^+ ..execute - ~| [%duct duct] - =/ duct-status (~(got by ducts.state) duct) - :: if we already have a result for this build, don't rerun the build - :: - =^ current-result builds.state (access-build-record build) - :: - ?: ?=([~ %value *] current-result) - (on-build-complete build) - :: place :build in :builds.state if it isn't already there - :: - =. state (add-build build) - :: ignore blocked builds - :: - =/ =build-status (got-build build) - ?: ?=(%blocked -.state.build-status) - =. state (add-anchors-to-build-subs build) - :: - =/ sub-scrys=(list scry-request) - ~(tap in (collect-blocked-sub-scrys build)) - :: - =. pending-scrys.state - |- ^+ pending-scrys.state - ?~ sub-scrys pending-scrys.state - :: - =. pending-scrys.state - (put-request pending-scrys.state i.sub-scrys duct) - :: - $(sub-scrys t.sub-scrys) - :: - ..execute - :: old-build: most recent previous build with :schematic.build - :: - =/ old-build=(unit ^build) - ?: ?& ?=(%live -.live.duct-status) - ?=(^ last-sent.live.duct-status) - == - :: check whether :build was run as part of the last live build tree - :: - :: If we had build this schematic as part of the build tree - :: during the last run of this live build, then we can compare - :: our result to that build. It might not be the most recent, - :: but if our sub-builds have the same results as they did then, - :: we can promote them. This is especially helpful for a %scry - :: build, because we don't have to make a new request for the - :: resource if the last live build subscribed to it. - :: - :: Otherwise, default to looking up the most recent build of this - :: schematic in :builds-by-schematic.state. We'll have to rerun - :: any %scry sub-builds, but other than that, we should still be - :: able to promote its result if its sub-builds have the same - :: results as ours. - :: - =/ possible-build=^build - [date.u.last-sent.live.duct-status schematic.build] - ?: (~(has by builds.state) possible-build) - `possible-build - (~(find-previous by-schematic builds-by-schematic.state) build) - (~(find-previous by-schematic builds-by-schematic.state) build) - :: if no previous builds exist, we need to run :build - :: - ?~ old-build - (add-build-to-next build) - :: - =/ old-build-status=^build-status (got-build u.old-build) - :: selectively promote scry builds - :: - :: We can only promote a scry if it's not forced and we ran the same - :: scry schematic as a descendant of the root build schematic at the - :: last sent time for this duct. - :: - ?: ?& ?=(%scry -.schematic.build) - ?| force - ?! - ?& ?=(%live -.live.duct-status) - ?=(^ last-sent.live.duct-status) - :: - =/ subscription=(unit subscription) - subscription.u.last-sent.live.duct-status - :: - ?~ subscription - %.n - %- ~(has in resources.u.subscription) - resource.schematic.build - == == == - (add-build-to-next build) - :: if we don't have :u.old-build's result cached, we need to run :build - :: - =^ old-build-record builds.state (access-build-record u.old-build) - ?. ?=([~ %value *] old-build-record) - (add-build-to-next build) - :: - =. old-build-status (got-build u.old-build) - :: - =/ old-subs=(list ^build) ~(tap in ~(key by subs.old-build-status)) - =/ new-subs=(list ^build) - (turn old-subs |=(^build +<(date date.build))) - :: link sub-builds provisionally, blocking on incomplete - :: - :: We don't know that :build will end up depending on :new-subs, - :: so they're not :verified. - :: - =/ split-new-subs - %+ skid new-subs - |= sub=^build - ^- ? - :: - ?~ maybe-build-status=(~(get by builds.state) sub) - %.n - :: - ?& ?=(%complete -.state.u.maybe-build-status) - ?=(%value -.build-record.state.u.maybe-build-status) - == - :: - =/ stored-new-subs=(list ^build) -.split-new-subs - =/ un-stored-new-subs=(list ^build) +.split-new-subs - :: - =. builds.state - (add-subs-to-client build stored-new-subs [verified=%.n blocked=%.n]) - =. builds.state - (add-subs-to-client build un-stored-new-subs [verified=%.n blocked=%.y]) - :: - =. state (add-anchors-to-build-subs build) - :: - ?^ un-stored-new-subs - :: enqueue incomplete sub-builds to be promoted or run - :: - :: When not all our sub builds have results, we can't add :build to - :: :next-builds.state. Instead, put all the remaining uncached new - :: subs into :candidate-builds. - :: - :: If all of our sub-builds finish immediately (i.e. promoted) when - :: they pass through +gather-internal, they will add :build back to - :: :candidate-builds and we will run again before +execute runs - :: +make. - :: - %_ ..execute - candidate-builds - (~(gas in candidate-builds) un-stored-new-subs) - == - :: - =^ promotable builds.state (are-subs-unchanged old-subs new-subs) - ?. promotable - (add-build-to-next build) - :: - ?> =(schematic.build schematic.u.old-build) - ?> (~(has by builds.state) build) - (promote-build u.old-build date.build new-subs) - :: +are-subs-unchanged: checks sub-build equivalence, updating access time - :: - ++ are-subs-unchanged - |= [old-subs=(list build) new-subs=(list build)] - ^- [? _builds.state] - :: - ?~ old-subs - [%.y builds.state] - ?> ?=(^ new-subs) - :: - =^ old-build-record builds.state (access-build-record i.old-subs) - ?. ?=([~ %value *] old-build-record) - [%.n builds.state] - :: - =^ new-build-record builds.state (access-build-record i.new-subs) - ?. ?=([~ %value *] new-build-record) - [%.n builds.state] - :: - ?. =(build-result.u.old-build-record build-result.u.new-build-record) - [%.n builds.state] - $(new-subs t.new-subs, old-subs t.old-subs) - :: +add-build-to-next: run this build during the +make phase - :: - ++ add-build-to-next - |= =build - ..execute(next-builds (~(put in next-builds) build)) - :: +promote-build: promote result of :build to newer :date - :: - :: Also performs relevant accounting, and possibly sends %made moves. - :: - ++ promote-build - |= [old-build=build new-date=@da new-subs=(list build)] - ^+ ..execute - :: grab the previous result, freshening the cache - :: - =^ old-build-record builds.state (access-build-record old-build) - :: we can only promote a cached result, not missing or a %tombstone - :: - ?> ?=([~ %value *] old-build-record) - =/ =build-result build-result.u.old-build-record - :: :new-build is :old-build at :date; promotion destination - :: - =/ new-build=build old-build(date new-date) - :: - =. builds.state - %+ ~(jab by builds.state) new-build - |= =build-status - ^+ build-status - :: - %_ build-status - :: verify linkages between :new-build and subs - :: - subs - :: - ^- (map build build-relation) - %- my - ^- (list (pair build build-relation)) - %+ turn new-subs - |= sub=build - :: - [sub [verified=& blocked=|]] - :: copy the old result to :new-build - :: - state - [%complete [%value last-accessed=now build-result=build-result]] - == - :: - (on-build-complete new-build) - -- - :: +run-builds: run the builds and produce +build-receipts - :: - :: Runs the builds and cleans up the build lists afterwards. - :: - :: When the vere interpreter has a parallel variant of +turn, use - :: that as each build might take a while and there are no data - :: dependencies between builds here. For now, though, run them serially. - :: - ++ run-builds - =< $ - ~% %run-builds + ~ - |. - ^- [(list build-receipt) _..execute] - :: - =/ build-receipts=(list build-receipt) - (turn ~(tap in next-builds) make) - :: - =. next-builds ~ - [build-receipts ..execute] - :: reduce: apply +build-receipts produce from the +make phase. - :: - :: +gather produces builds to run make on. +make produces - :: +build-receipts. It is in +reduce where we take these +build-receipts - :: and apply them to ..execute. - :: - ++ reduce !. - ~/ %reduce - |= build-receipts=(list build-receipt) - ^+ ..execute - :: sort :build-receipts so blocks are processed before completions - :: - :: It's possible for a build to block on a sub-build that was run - :: in the same batch. If that's the case, make sure we register - :: that the build blocked on the sub-build before registering the - :: completion of the sub-build. This way, when we do register the - :: completion of the sub-build, we will know which builds are blocked - :: on the sub-build, so we can enqueue those blocked clients to be - :: rerun. - :: - =. build-receipts - %+ sort build-receipts - |= [a=build-receipt b=build-receipt] - ^- ? - ?=(%blocks -.result.a) - :: - |^ ^+ ..execute - ?~ build-receipts ..execute - :: - =. ..execute (apply-build-receipt i.build-receipts) - $(build-receipts t.build-receipts) - :: +apply-build-receipt: applies a single state diff to ..execute - :: - ++ apply-build-receipt - |= made=build-receipt - ^+ ..execute - :: process :sub-builds.made - :: - =. state (track-sub-builds build.made sub-builds.made) - :: - ?- -.result.made - %build-result - (apply-build-result [build build-result.result cache-access]:made) - :: - %blocks - (apply-blocks [build builds.result]:made) - == - :: +track-sub-builds: - :: - :: For every sub-build discovered while running :build, we have to make - :: sure that we track that sub-build and that it is associated with the - :: right ducts. - :: - ++ track-sub-builds - |= [client=build sub-builds=(list build)] - ^+ state - :: mark :sub-builds as :subs in :build's +build-status - :: - =^ build-status builds.state - %+ update-build-status client - |= =build-status - %_ build-status - subs - %- ~(gas by subs.build-status) - %+ turn sub-builds - |= sub=build - :: - =/ blocked=? - ?~ sub-status=(~(get by builds.state) sub) - %.y - !?=([%complete %value *] state.u.sub-status) - :: - [sub [verified=& blocked]] - == - :: - =. state (add-anchors-to-build-subs client) - :: - |- ^+ state - ?~ sub-builds state - :: - =. builds.state - %+ ~(jab by builds.state) i.sub-builds - |= build-status=^build-status - %_ build-status - :: freshen :last-accessed date - :: - state - :: - ?. ?=([%complete %value *] state.build-status) - state.build-status - state.build-status(last-accessed.build-record now) - == - :: - $(sub-builds t.sub-builds) - :: +apply-build-result: apply a %build-result +build-receipt to ..execute - :: - :: Our build produced an actual result. - :: - ++ apply-build-result - |= [=build =build-result cache-access=(unit [=compiler-cache-key new=?])] - ^+ ..execute - :: - =? compiler-cache.state ?=(^ cache-access) - =+ by-clock=(by-clock compiler-cache-key ^build-result) - ?. new.u.cache-access - =^ ignored compiler-cache.state - (~(get by-clock compiler-cache.state) compiler-cache-key.u.cache-access) - compiler-cache.state - :: - %+ ~(put by-clock compiler-cache.state) - compiler-cache-key.u.cache-access - build-result - :: - =. builds.state - %+ ~(jab by builds.state) build - |= =build-status - build-status(state [%complete [%value last-accessed=now build-result]]) - :: - (on-build-complete build) - :: +apply-blocks: apply a %blocks +build-receipt to ..execute - :: - :: :build blocked. Record information about what builds it blocked on - :: and try those blocked builds as candidates in the next pass. - :: - ++ apply-blocks - |= [=build blocks=(list build)] - ^+ ..execute - :: if a %scry blocked, register it and maybe send an async request - :: - =? ..execute - ?=(~ blocks) - ?> ?=(%scry -.schematic.build) - =, resource.schematic.build - %- start-scry-request - [vane care [[ship.disc.rail desk.disc.rail [%da date.build]] spur.rail]] - :: we must run +apply-build-receipt on :build.made before :block - :: - ?< %+ lien blocks - |= block=^build - ?~ maybe-build-status=(~(get by builds.state) block) - %.n - ?=(%complete -.state.u.maybe-build-status) - :: transition :build's state machine to the %blocked state - :: - =. builds.state - %+ ~(jab by builds.state) build - |= =build-status - build-status(state [%blocked ~]) - :: enqueue :blocks to be run next - :: - =. candidate-builds (~(gas in candidate-builds) blocks) - :: - ..execute - -- - :: +make: attempt to perform :build, non-recursively - :: - :: Registers component linkages between :build and its sub-builds. - :: Attempts to perform +scry if necessary. Does not directly enqueue - :: any moves. - :: - ++ make - ~/ %make - |= =build - ^- build-receipt - :: out: receipt to return to caller - :: - =| out=build-receipt - :: ~& [%turbo-make (build-to-tape build)] - :: dispatch based on the kind of +schematic in :build - :: - |^ =, schematic.build - :: - =. build.out build - :: - ?- -.schematic.build - :: - ^ (make-autocons [head tail]) - :: - %$ (make-literal literal) - :: - %pin (make-pin date schematic) - %alts (make-alts choices ~) - %bake (make-bake renderer query-string path-to-render) - %bunt (make-bunt disc mark) - %call (make-call gate sample) - %cast (make-cast disc mark input) - %core (make-core source-path) - %diff (make-diff disc start end) - %dude (make-dude error attempt) - %hood (make-hood source-path) - %join (make-join disc mark first second) - %list (make-list schematics) - %mash (make-mash disc mark first second) - %mute (make-mute subject mutations) - %pact (make-pact disc start diff) - %path (make-path disc prefix raw-path) - %plan (make-plan path-to-render query-string scaffold) - %reef (make-reef disc) - %ride (make-ride formula subject) - %same (make-same schematic) - %scry (make-scry resource) - %slim (make-slim subject-type formula) - %slit (make-slit gate sample) - %vale (make-vale disc mark input) - %volt (make-volt disc mark input) - %walk (make-walk disc source target) - == - :: |schematic-handlers:make: implementation of the schematics - :: - :: All of these produce a value of the same type as +make itself. - :: - :: +| schematic-handlers - :: - ++ make-autocons - ~% %make-autocons ..^^$ ~ - |= [head=schematic tail=schematic] - ^- build-receipt - :: - =/ head-build=^build [date.build head] - =/ tail-build=^build [date.build tail] - =^ head-result out (depend-on head-build) - =^ tail-result out (depend-on tail-build) - :: - =| blocks=(list ^build) - =? blocks ?=(~ head-result) [head-build blocks] - =? blocks ?=(~ tail-result) [tail-build blocks] - :: if either build blocked, we're not done - :: - ?^ blocks - :: - (return-blocks blocks) - :: - ?< ?=(~ head-result) - ?< ?=(~ tail-result) - :: - (return-result %success u.head-result u.tail-result) - :: - ++ make-literal - ~% %make-literal ..^^$ ~ - |= =cage - ^- build-receipt - (return-result %success %$ cage) - :: - ++ make-pin - ~% %make-pin ..^^$ ~ - |= [date=@da =schematic] - ^- build-receipt - :: pinned-sub: sub-build with the %pin date as formal date - :: - =/ pinned-sub=^build [date schematic] - :: - =^ result out (depend-on pinned-sub) - :: - ?~ result - (return-blocks ~[pinned-sub]) - :: - (return-result u.result) - :: - ++ make-alts - ~% %make-alts ..^^$ ~ - |= [choices=(list schematic) errors=(list tank)] - ^- build-receipt - :: - ?~ choices - (return-error [[%leaf "%alts: all options failed"] errors]) - :: - =/ choice=^build [date.build i.choices] - :: - =^ result out (depend-on choice) - ?~ result - (return-blocks ~[choice]) - :: - ?: ?=([%error *] u.result) - :: - =/ braces [[' ' ' ' ~] ['{' ~] ['}' ~]] - =/ wrapped-error=tank - [%rose braces `(list tank)`message.u.result] - =. errors - (weld errors `(list tank)`[[%leaf "option"] wrapped-error ~]) - $(choices t.choices) - :: - (return-result %success %alts u.result) - :: - ++ make-bake - ~% %make-bake ..^^$ ~ - |= [renderer=term query-string=coin path-to-render=rail] - ^- build-receipt - :: path-build: find the file path for the renderer source - :: - =/ path-build=^build - [date.build [%path disc.path-to-render %ren renderer]] - :: - =^ path-result out (depend-on path-build) - ?~ path-result - (return-blocks [path-build]~) - :: - |^ ^- build-receipt - :: if there's a renderer called :renderer, use it on :path-to-render - :: - :: Otherwise, fall back to running the contents of :path-to-render - :: through a mark that has the same name as :renderer. - :: - ?: ?=([~ %success %path *] path-result) - (try-renderer-then-mark rail.u.path-result) - (try-mark ~) - :: +try-renderer-then-mark: try to render a path, then fall back to mark - :: - ++ try-renderer-then-mark - |= =rail - ^- build-receipt - :: build a +scaffold from the renderer source - :: - =/ hood-build=^build [date.build [%hood rail]] - :: - =^ hood-result out (depend-on hood-build) - ?~ hood-result - (return-blocks [hood-build]~) - :: if we can't find and parse the renderer, try the mark instead - :: - ?: ?=([~ %error *] hood-result) - (try-mark message.u.hood-result) - ?> ?=([~ %success %hood *] hood-result) - :: link the renderer, passing through :path-to-render and :query-string - :: - =/ plan-build=^build - :- date.build - [%plan path-to-render query-string scaffold.u.hood-result] - :: - =^ plan-result out (depend-on plan-build) - ?~ plan-result - (return-blocks [plan-build]~) - :: if compiling the renderer errors out, try the mark instead - :: - ?: ?=([~ %error *] plan-result) - (try-mark message.u.plan-result) - ?> ?=([~ %success %plan *] plan-result) - :: renderers return their name as the mark - :: - :: We should rethink whether we want this to be the case going - :: forward, but for now, Eyre depends on this detail to work. - :: - (return-result [%success %bake renderer vase.u.plan-result]) - :: +try-mark: try to cast a file's contents through a mark - :: - :: :errors contains any error messages from our previous attempt to - :: run a renderer, if we made one. This way if both the renderer and - :: mark fail, the requester will see the errors of both attempts. - :: - ++ try-mark - |= errors=(list tank) - ^- build-receipt - :: no renderer, try mark; retrieve directory listing of :path-to-render - :: - :: There might be multiple files of different marks stored at - :: :path-to-render. Retrieve the directory listing for - :: :path-to-render, then check which of the path segments in - :: that directory are files (not just folders), then for each - :: file try to %cast its mark to the desired mark (:renderer). - :: - :: Start by retrieving the directory listing, using :toplevel-build. - :: - =/ toplevel-build=^build - [date.build [%scry %c %y path-to-render]] - :: - =^ toplevel-result out (depend-on toplevel-build) - ?~ toplevel-result - (return-blocks [toplevel-build]~) - :: - ?: ?=([~ %error *] toplevel-result) - :: - =/ =path (rail-to-path path-to-render) - ?~ errors - %- return-error - :- [%leaf "ford: %bake {} on {} failed:"] - message.u.toplevel-result - :: - =/ braces [[' ' ' ' ~] ['{' ~] ['}' ~]] - %- return-error :~ - [%leaf "ford: %bake {} on {} failed:"] - [%leaf "as-renderer"] - [%rose braces errors] - [%leaf "as-mark"] - [%rose braces message.u.toplevel-result] - == - ?> ?=([~ %success %scry *] toplevel-result) - :: - =/ toplevel-arch=arch ;;(arch q.q.cage.u.toplevel-result) - :: find the :sub-path-segments that could be files - :: - :: Filter out path segments that aren't a +term, - :: since those aren't valid marks and therefore can't - :: be the last segment of a filepath in Clay. - :: - =/ sub-path-segments=(list @ta) - (skim (turn ~(tap by dir.toplevel-arch) head) (sane %tas)) - :: - =/ sub-schematics=(list [sub-path=@ta =schematic]) - %+ turn sub-path-segments - |= sub=@ta - :- sub - [%scry %c %y path-to-render(spur [sub spur.path-to-render])] - :: - =^ maybe-schematic-results out - %- perform-schematics :* - ;: weld - "ford: %bake " (trip renderer) " on " - (spud (rail-to-path path-to-render)) " contained failures:" - == - sub-schematics - %fail-on-errors - *@ta - == - ?~ maybe-schematic-results - out - :: marks: list of the marks of the files at :path-to-render - :: - =/ marks=(list @tas) - %+ murn u.maybe-schematic-results - |= [sub-path=@ta result=build-result] - ^- (unit @tas) - :: - ?> ?=([%success %scry *] result) - :: - =/ =arch ;;(arch q.q.cage.result) - :: if it's a directory, not a file, we can't load it - :: - ?~ fil.arch - ~ - [~ `@tas`sub-path] - :: sort marks in alphabetical order - :: - =. marks (sort marks lte) - :: try to convert files to the destination mark, in order - :: - =/ alts-build=^build - :: - :+ date.build %alts - ^= choices ^- (list schematic) - :: - %+ turn marks - |= mark=term - ^- schematic - :: - =/ file=rail path-to-render(spur [mark spur.path-to-render]) - :: - [%cast disc.file renderer [%scry %c %x file]] - :: - =^ alts-result out (depend-on alts-build) - ?~ alts-result - (return-blocks [alts-build]~) - :: - ?: ?=([~ %error *] alts-result) - =/ =path (rail-to-path path-to-render) - ?~ errors - %- return-error - :- [%leaf "ford: %bake {} on {} failed:"] - message.u.alts-result - :: - =/ braces [[' ' ' ' ~] ['{' ~] ['}' ~]] - %- return-error :~ - [%leaf "ford: %bake {} on {} failed:"] - [%leaf "as-renderer"] - [%rose braces errors] - [%leaf "as-mark"] - [%rose braces message.u.alts-result] - == - :: - ?> ?=([~ %success %alts *] alts-result) - :: - =/ =build-result - [%success %bake (result-to-cage u.alts-result)] - :: - (return-result build-result) - -- - :: - ++ make-bunt - ~% %make-bunt ..^^$ ~ - |= [=disc mark=term] - ^- build-receipt - :: resolve path of the mark definition file - :: - =/ path-build=^build [date.build [%path disc %mar mark]] - :: - =^ path-result out (depend-on path-build) - ?~ path-result - (return-blocks [path-build]~) - :: - ?: ?=([~ %error *] path-result) - %- return-error - :_ message.u.path-result - :- %leaf - "ford: %bunt resolving path for {} on {} failed:" - :: - ?> ?=([~ %success %path *] path-result) - :: build the mark core from source - :: - =/ core-build=^build [date.build [%core rail.u.path-result]] - :: - =^ core-result out (depend-on core-build) - ?~ core-result - (return-blocks [core-build]~) - :: - ?: ?=([~ %error *] core-result) - %- return-error - :_ message.u.core-result - :- %leaf - "ford: %bunt compiling mark {} on {} failed:" - :: - ?> ?=([~ %success %core *] core-result) - :: extract the sample from the mark core - :: - =/ mark-vase=vase vase.u.core-result - ~| %mark-vase - =+ [sample-type=p sample-value=q]:(slot 6 mark-vase) - :: if sample is wrapped in a face, unwrap it - :: - =? sample-type ?=(%face -.sample-type) q.sample-type - :: - =/ =cage [mark sample-type sample-value] - (return-result %success %bunt cage) - :: - ++ make-call - ~% %make-call ..^^$ ~ - |= [gate=schematic sample=schematic] - ^- build-receipt - :: - =/ gate-build=^build [date.build gate] - =^ gate-result out (depend-on gate-build) - :: - =/ sample-build=^build [date.build sample] - =^ sample-result out (depend-on sample-build) - :: - =| blocks=(list ^build) - =? blocks ?=(~ gate-result) [[date.build gate] blocks] - =? blocks ?=(~ sample-result) [[date.build sample] blocks] - ?^ blocks - (return-blocks blocks) - :: - ?< ?=(~ gate-result) - ?: ?=([~ %error *] gate-result) - %- return-error - :- [%leaf "ford: %call failed to build gate:"] - message.u.gate-result - :: - ?< ?=(~ sample-result) - ?: ?=([~ %error *] sample-result) - %- return-error - :- [%leaf "ford: %call failed to build sample:"] - message.u.sample-result - :: - =/ gate-vase=vase q:(result-to-cage u.gate-result) - =/ sample-vase=vase q:(result-to-cage u.sample-result) - :: run %slit to get the resulting type of calculating the gate - :: - =/ slit-schematic=schematic [%slit gate-vase sample-vase] - =/ slit-build=^build [date.build slit-schematic] - =^ slit-result out (depend-on slit-build) - ?~ slit-result - (return-blocks [date.build slit-schematic]~) - :: - ?: ?=([~ %error *] slit-result) - %- return-error - :- [%leaf "ford: %call failed type calculation"] - message.u.slit-result - :: - ?> ?=([~ %success %slit *] slit-result) - :: - =/ =compiler-cache-key [%call gate-vase sample-vase] - =^ cached-result out (access-cache compiler-cache-key) - ?^ cached-result - (return-result u.cached-result) - :: - ?> &(?=(^ q.gate-vase) ?=(^ +.q.gate-vase)) - =/ val - (mong [q.gate-vase q.sample-vase] intercepted-scry) - :: - ?- -.val - %0 - (return-result %success %call [type.u.slit-result p.val]) - :: - %1 - =/ blocked-paths=(list path) ;;((list path) p.val) - (blocked-paths-to-receipt %call blocked-paths) - :: - %2 - (return-error [[%leaf "ford: %call execution failed:"] p.val]) - == - :: - ++ make-cast - ~% %make-cast ..^^$ ~ - |= [=disc mark=term input=schematic] - ^- build-receipt - :: - =/ input-build=^build [date.build input] - :: - =^ input-result out (depend-on input-build) - ?~ input-result - (return-blocks [input-build]~) - :: - ?: ?=([~ %error *] input-result) - %- return-error - :_ message.u.input-result - :- %leaf - ;: weld - "ford: %cast " (trip mark) " on [" (trip (scot %p ship.disc)) - " " (trip desk.disc) "] failed on input:" - == - :: - ?> ?=([~ %success *] input-result) - :: - =/ result-cage=cage (result-to-cage u.input-result) - :: - =/ translation-path-build=^build - [date.build [%walk disc p.result-cage mark]] - =^ translation-path-result out - (depend-on translation-path-build) - :: - ?~ translation-path-result - (return-blocks [translation-path-build]~) - :: - ?: ?=([~ %error *] translation-path-result) - %- return-error - :_ message.u.translation-path-result - :- %leaf - ;: weld - "ford: %cast " (trip mark) " on [" (trip (scot %p ship.disc)) - " " (trip desk.disc) "] failed:" - == - :: - ?> ?=([~ %success %walk *] translation-path-result) - :: - =/ translation-path=(list mark-action) - results.u.translation-path-result - :: - |^ ^- build-receipt - ?~ translation-path - (return-result %success %cast result-cage) - :: - =^ action-result out - =, i.translation-path - ?- -.i.translation-path - %grow (run-grow source target result-cage) - %grab (run-grab source target result-cage) - == - :: - ?- -.action-result - %success - %_ $ - translation-path t.translation-path - result-cage cage.action-result - == - :: - %blocks - (return-blocks blocks.action-result) - :: - %error - (return-error [leaf+"ford: failed to %cast" tang.action-result]) - == - :: - += action-result - $% :: translation was successful and here's a cage for you - [%success =cage] - :: it was an error. sorry. - [%error =tang] - :: we block on a build - [%blocks blocks=(list ^build)] - == - :: - ++ run-grab - |= [source-mark=term target-mark=term input-cage=cage] - ^- [action-result _out] - :: - =/ mark-path-build=^build - [date.build [%path disc %mar target-mark]] - :: - =^ mark-path-result out - (depend-on mark-path-build) - ?~ mark-path-result - [[%blocks [mark-path-build]~] out] - :: - ?. ?=([~ %success %path *] mark-path-result) - %- cast-wrap-error :* - source-mark - target-mark - ;: weld - "ford: %cast failed to find path for mark " (trip source-mark) - " during +grab:" - == - mark-path-result - == - :: - =/ mark-core-build=^build [date.build [%core rail.u.mark-path-result]] - :: - =^ mark-core-result out (depend-on mark-core-build) - ?~ mark-core-result - [[%blocks ~[mark-core-build]] out] - :: find +grab within the destination mark core - :: - =/ grab-build=^build - :- date.build - [%ride [%limb %grab] [%$ (result-to-cage u.mark-core-result)]] - :: - =^ grab-result out (depend-on grab-build) - ?~ grab-result - [[%blocks [grab-build]~] out] - :: - ?. ?=([~ %success %ride *] grab-result) - =/ =path (rail-to-path rail.u.mark-path-result) - %- cast-wrap-error :* - source-mark - target-mark - :(weld "ford: %cast failed to ride " (spud path) " during +grab:") - grab-result - == - :: find an arm for the input's mark within the +grab core - :: - =/ grab-mark-build=^build - :- date.build - [%ride [%limb source-mark] [%$ %noun vase.u.grab-result]] - :: - =^ grab-mark-result out (depend-on grab-mark-build) - ?~ grab-mark-result - [[%blocks [grab-mark-build]~] out] - :: - ?. ?=([~ %success %ride *] grab-mark-result) - =/ =path (rail-to-path rail.u.mark-path-result) - %- cast-wrap-error :* - source-mark - target-mark - :(weld "ford: %cast failed to ride " (spud path) " during +grab:") - grab-mark-result - == - :: slam the +mark-name:grab gate on the result of running :input - :: - =/ call-build=^build - :- date.build - [%call gate=[%$ %noun vase.u.grab-mark-result] sample=[%$ input-cage]] - :: - =^ call-result out (depend-on call-build) - ?~ call-result - [[%blocks [call-build]~] out] - :: - ?. ?=([~ %success %call *] call-result) - =/ =path (rail-to-path rail.u.mark-path-result) - %- cast-wrap-error :* - source-mark - target-mark - :(weld "ford: %cast failed to call +grab arm in " (spud path) ":") - call-result - == - :: - [[%success [mark vase.u.call-result]] out] - :: +grow: grow from the input mark to the destination mark - :: - ++ run-grow - |= [source-mark=term target-mark=term input-cage=cage] - ^- [action-result _out] - :: - =/ starting-mark-path-build=^build - [date.build [%path disc %mar source-mark]] - :: - =^ starting-mark-path-result out - (depend-on starting-mark-path-build) - ?~ starting-mark-path-result - [[%blocks [starting-mark-path-build]~] out] - :: - ?. ?=([~ %success %path *] starting-mark-path-result) - %- cast-wrap-error :* - source-mark - target-mark - ;: weld - "ford: %cast failed to find path for mark " (trip source-mark) - " during +grow:" - == - starting-mark-path-result - == - :: grow the value from the initial mark to the final mark - :: - :: Replace the input mark's sample with the input's result, - :: then fire the mark-name:grow arm to produce a result. - :: - =/ grow-build=^build - :- date.build - :+ %ride - formula=`hoon`[%tsld [%wing ~[target-mark]] [%wing ~[%grow]]] - ^= subject - ^- schematic - :* %mute - ^- schematic - [%core rail.u.starting-mark-path-result] - ^= mutations - ^- (list [wing schematic]) - [[%& 6]~ [%$ input-cage]]~ - == - :: - =^ grow-result out (depend-on grow-build) - ?~ grow-result - [[%blocks [grow-build]~] out] - :: - ?. ?=([~ %success %ride *] grow-result) - =/ =path (rail-to-path rail.u.starting-mark-path-result) - %- cast-wrap-error :* - source-mark - target-mark - :(weld "ford: %cast failed to ride " (spud path) " during +grow:") - grow-result - == - :: make sure the product nests in the sample of the destination mark - :: - =/ bunt-build=^build [date.build [%bunt disc target-mark]] - :: - =^ bunt-result out (depend-on bunt-build) - ?~ bunt-result - [[%blocks [bunt-build]~] out] - :: - ?. ?=([~ %success %bunt *] bunt-result) - %- cast-wrap-error :* - source-mark - target-mark - :(weld "ford: %cast failed to bunt " (trip target-mark) ":") - bunt-result - == - :: - ?. (~(nest ut p.q.cage.u.bunt-result) | p.vase.u.grow-result) - =* src source-mark - =* dst target-mark - :_ out - :- %error - :_ ~ - :- %leaf - ;: weld - "ford: %cast from " (trip src) " to " (trip dst) - " failed: nest fail" - == - :: - [[%success mark vase.u.grow-result] out] - :: - ++ cast-wrap-error - |= $: source-mark=term - target-mark=term - description=tape - result=(unit build-result) - == - ^- [action-result _out] - :: - ?> ?=([~ %error *] result) - :: - :_ out - :- %error - :* :- %leaf - ;: weld - "ford: %cast failed while trying to cast from " - (trip source-mark) " to " (trip target-mark) ":" - == - [%leaf description] - message.u.result - == - -- - :: - ++ make-core - ~% %make-core ..^^$ ~ - |= source-path=rail - ^- build-receipt - :: convert file at :source-path to a +scaffold - :: - =/ hood-build=^build [date.build [%hood source-path]] - :: - =^ hood-result out (depend-on hood-build) - ?~ hood-result - (return-blocks [hood-build]~) - :: - ?: ?=(%error -.u.hood-result) - %- return-error - :- [%leaf "ford: %core on {<(rail-to-path source-path)>} failed:"] - message.u.hood-result - :: build the +scaffold into a program - :: - ?> ?=([%success %hood *] u.hood-result) - :: - =/ plan-build=^build - [date.build [%plan source-path `coin`[%many ~] scaffold.u.hood-result]] - :: - =^ plan-result out (depend-on plan-build) - ?~ plan-result - (return-blocks [plan-build]~) - :: - ?: ?=(%error -.u.plan-result) - %- return-error - :- [%leaf "ford: %core on {<(rail-to-path source-path)>} failed:"] - message.u.plan-result - :: - ?> ?=([%success %plan *] u.plan-result) - (return-result %success %core vase.u.plan-result) - :: - ++ make-diff - ~% %make-diff ..^^$ ~ - |= [=disc start=schematic end=schematic] - ^- build-receipt - :: run both input schematics as an autocons build - :: - =/ sub-build=^build [date.build [start end]] - :: - =^ sub-result out (depend-on sub-build) - ?~ sub-result - (return-blocks [sub-build]~) - :: - ?. ?=([~ %success ^ ^] sub-result) - (wrap-error sub-result) - ?. ?=([%success *] head.u.sub-result) - (wrap-error `head.u.sub-result) - ?. ?=([%success *] tail.u.sub-result) - (wrap-error `tail.u.sub-result) - :: - =/ start-cage=cage (result-to-cage head.u.sub-result) - =/ end-cage=cage (result-to-cage tail.u.sub-result) - :: if the marks aren't the same, we can't diff them - :: - ?. =(p.start-cage p.end-cage) - %- return-error :_ ~ :- %leaf - "ford: %diff failed: mark mismatch: %{} / %{}" - :: if the values are the same, the diff is null - :: - ?: =(q.q.start-cage q.q.end-cage) - =/ =build-result - [%success %diff [%null [%atom %n ~] ~]] - :: - (return-result build-result) - :: - =/ mark-path-build=^build [date.build [%path disc %mar p.start-cage]] - :: - =^ mark-path-result out (depend-on mark-path-build) - ?~ mark-path-result - (return-blocks [mark-path-build]~) - :: - ?: ?=([~ %error *] mark-path-result) - %- return-error - :- [%leaf "ford: %diff failed on {}:"] - message.u.mark-path-result - :: - ?> ?=([~ %success %path *] mark-path-result) - :: - =/ mark-build=^build [date.build [%core rail.u.mark-path-result]] - :: - =^ mark-result out (depend-on mark-build) - ?~ mark-result - (return-blocks [mark-build]~) - :: - ?: ?=([~ %error *] mark-result) - %- return-error - :- [%leaf "ford: %diff failed on {}:"] - message.u.mark-result - :: - ?> ?=([~ %success %core *] mark-result) - :: - ?. (slab %grad p.vase.u.mark-result) - %- return-error :_ ~ :- %leaf - "ford: %diff failed: %{} mark has no +grad arm" - :: - =/ grad-build=^build - [date.build [%ride [%limb %grad] [%$ %noun vase.u.mark-result]]] - :: - =^ grad-result out (depend-on grad-build) - ?~ grad-result - (return-blocks [grad-build]~) - :: - ?: ?=([~ %error *] grad-result) - %- return-error - :- [%leaf "ford: %diff failed on {}:"] - message.u.grad-result - :: - ?> ?=([~ %success %ride *] grad-result) - :: if +grad produced a @tas, convert to that mark and diff those - :: - ?@ q.vase.u.grad-result - =/ mark=(unit @tas) ((sand %tas) q.vase.u.grad-result) - ?~ mark - %- return-error :_ ~ :- %leaf - "ford: %diff failed: %{} mark has invalid +grad arm" - :: - =/ diff-build=^build - :- date.build - :^ %diff - disc - [%cast disc u.mark [%$ start-cage]] - [%cast disc u.mark [%$ end-cage]] - :: - =^ diff-result out (depend-on diff-build) - ?~ diff-result - (return-blocks [diff-build]~) - :: - ?. ?=([~ %success %diff *] diff-result) - (wrap-error diff-result) - :: - =/ =build-result - [%success %diff cage.u.diff-result] - :: - (return-result build-result) - :: +grad produced a cell, which should be a core with a +form arm - :: - ?. (slab %form p.vase.u.grad-result) - %- return-error :_ ~ :- %leaf - "ford: %diff failed: %{} mark has no +form:grab arm" - :: the +grab core should also contain a +diff arm - :: - ?. (slab %diff p.vase.u.grad-result) - %- return-error :_ ~ :- %leaf - "ford: %diff failed: %{} mark has no +diff:grab arm" - :: - =/ diff-build=^build - :- date.build - :+ %call - :: - ^= gate - :+ %ride - :: - formula=`hoon`[%tsld [%wing ~[%diff]] [%wing ~[%grad]]] - :: - ^= subject - :+ %mute - :: - subject=`schematic`[%$ %noun vase.u.mark-result] - :: - ^= mutations - ^- (list [wing schematic]) - [[%& 6]~ [%$ start-cage]]~ - :: - sample=`schematic`[%$ end-cage] - :: - =^ diff-result out (depend-on diff-build) - ?~ diff-result - (return-blocks [diff-build]~) - :: - ?. ?=([~ %success %call *] diff-result) - (wrap-error diff-result) - :: - =/ form-build=^build - [date.build [%ride [%limb %form] [%$ %noun vase.u.grad-result]]] - :: - =^ form-result out (depend-on form-build) - ?~ form-result - (return-blocks [form-build]~) - :: - ?. ?=([~ %success %ride *] form-result) - (wrap-error form-result) - :: - =/ mark=(unit @tas) ((soft @tas) q.vase.u.form-result) - ?~ mark - %- return-error :_ ~ :- %leaf - "ford: %diff failed: invalid +form result: {(text vase.u.form-result)}" - :: - =/ =build-result - [%success %diff [u.mark vase.u.diff-result]] - :: - (return-result build-result) - :: - ++ make-dude - ~% %make-dude ..^^$ ~ - |= [error=tank attempt=schematic] - ^- build-receipt - :: - =/ attempt-build=^build [date.build attempt] - =^ attempt-result out (depend-on attempt-build) - ?~ attempt-result - :: - (return-blocks ~[[date.build attempt]]) - :: - ?. ?=([%error *] u.attempt-result) - (return-result u.attempt-result) - :: - (return-error [error message.u.attempt-result]) - :: - ++ make-hood - ~% %make-hood ..^^$ ~ - |= source-rail=rail - ^- build-receipt - :: - =/ scry-build=^build [date.build [%scry [%c %x source-rail]]] - =^ scry-result out (depend-on scry-build) - ?~ scry-result - :: - (return-blocks ~[scry-build]) - :: - ?: ?=([~ %error *] scry-result) - =/ =path (rail-to-path source-rail) - %- return-error - :- [%leaf "ford: %hood failed for {}:"] - message.u.scry-result - =+ as-cage=(result-to-cage u.scry-result) - :: hoon files must be atoms to parse - :: - ?. ?=(@ q.q.as-cage) - =/ =path (rail-to-path source-rail) - %- return-error - :_ ~ - :- %leaf - "ford: %hood: path {} not an atom" - :: - =/ src-beam=beam [[ship.disc desk.disc [%ud 0]] spur]:source-rail - :: - =/ =compiler-cache-key [%hood src-beam q.q.as-cage] - =^ cached-result out (access-cache compiler-cache-key) - ?^ cached-result - (return-result u.cached-result) - :: - =/ parsed - ((full (parse-scaffold src-beam)) [1 1] (trip q.q.as-cage)) - :: - ?~ q.parsed - =/ =path (rail-to-path source-rail) - %- return-error - =/ lyn p.p.parsed - =/ col q.p.parsed - :~ leaf+(runt [(dec col) '-'] "^") - leaf+(trip (snag (dec lyn) (to-wain:format q.q.as-cage))) - leaf+"ford: %hood: syntax error at [{} {}] in {}" - == - :: - (return-result %success %hood p.u.q.parsed) - :: - ++ make-join - ~% %make-join ..^^$ ~ - |= [disc=disc mark=term first=schematic second=schematic] - ^- build-receipt - :: - =/ initial-build=^build - [date.build [first second] [%path disc %mar mark]] - :: - =^ initial-result out (depend-on initial-build) - ?~ initial-result - (return-blocks [initial-build]~) - :: - ?. ?=([~ %success [%success ^ ^] %success %path *] initial-result) - (wrap-error initial-result) - ?. ?=([%success *] head.head.u.initial-result) - (wrap-error `head.head.u.initial-result) - ?. ?=([%success *] tail.head.u.initial-result) - (wrap-error `tail.head.u.initial-result) - :: - =/ first-cage=cage (result-to-cage head.head.u.initial-result) - =/ second-cage=cage (result-to-cage tail.head.u.initial-result) - =/ mark-path=rail rail.tail.u.initial-result - :: TODO: duplicate logic with +make-pact and others - :: - =/ mark-build=^build [date.build [%core mark-path]] - :: - =^ mark-result out (depend-on mark-build) - ?~ mark-result - (return-blocks [mark-build]~) - :: - ?: ?=([~ %error *] mark-result) - %- return-error - :- [%leaf "ford: %join to {} on {} failed:"] - message.u.mark-result - :: - ?> ?=([~ %success %core *] mark-result) - :: - =/ mark-vase=vase vase.u.mark-result - :: - ?. (slab %grad p.mark-vase) - %- return-error :_ ~ :- %leaf - "ford: %join failed: %{} mark has no +grad arm" - :: - =/ grad-build=^build - [date.build [%ride [%limb %grad] [%$ %noun mark-vase]]] - :: - =^ grad-result out (depend-on grad-build) - ?~ grad-result - (return-blocks [grad-build]~) - :: - ?: ?=([~ %error *] grad-result) - %- return-error - :- [%leaf "ford: %join to {} on {} failed:"] - message.u.grad-result - :: - ?> ?=([~ %success %ride *] grad-result) - :: - =/ grad-vase=vase vase.u.grad-result - :: if +grad produced a mark, delegate %join behavior to that mark - :: - ?@ q.grad-vase - :: if +grad produced a term, make sure it's a valid mark - :: - =/ grad-mark=(unit term) ((sand %tas) q.grad-vase) - ?~ grad-mark - %- return-error :_ ~ :- %leaf - "ford: %join failed: %{} mark invalid +grad" - :: todo: doesn't catch full cycles of +grad arms, only simple cases - :: - ?: =(u.grad-mark mark) - %- return-error :_ ~ :- %leaf - "ford: %join failed: %{} mark +grad arm refers to self" - :: - =/ join-build=^build - [date.build [%join disc u.grad-mark [%$ first-cage] [%$ second-cage]]] - :: - =^ join-result out (depend-on join-build) - ?~ join-result - (return-blocks [join-build]~) - :: - ?: ?=([~ %error *] join-result) - %- return-error - :- [%leaf "ford: %join to {} on {} failed:"] - message.u.join-result - :: - ?> ?=([~ %success %join *] join-result) - :: - (return-result u.join-result) - :: make sure the +grad core has a +form arm - :: - ?. (slab %form p.grad-vase) - %- return-error :_ ~ :- %leaf - "ford: %join failed: no +form:grad in %{} mark" - :: make sure the +grad core has a +join arm - :: - ?. (slab %join p.grad-vase) - %- return-error :_ ~ :- %leaf - "ford: %join failed: no +join:grad in %{} mark" - :: fire the +form:grad arm, which should produce a mark - :: - =/ form-build=^build - [date.build [%ride [%limb %form] [%$ %noun grad-vase]]] - :: - =^ form-result out (depend-on form-build) - ?~ form-result - (return-blocks [form-build]~) - :: - ?. ?=([~ %success %ride *] form-result) - (wrap-error form-result) - :: - =/ form-mark=(unit term) ((soft @tas) q.vase.u.form-result) - ?~ form-mark - %- return-error :_ ~ :- %leaf - "ford: %join failed: %{} mark invalid +form:grad" - :: the mark produced by +form:grad should match both diffs - :: - ?. &(=(u.form-mark p.first-cage) =(u.form-mark p.second-cage)) - %- return-error :_ ~ :- %leaf - "ford: %join failed: mark mismatch" - :: if the diffs are identical, just produce the first - :: - ?: =(q.q.first-cage q.q.second-cage) - (return-result %success %join first-cage) - :: call the +join:grad gate on the two diffs - :: - =/ diff-build=^build - :- date.build - :+ %call - :+ %ride - [%limb %join] - [%$ %noun grad-vase] - [%$ %noun (slop q.first-cage q.second-cage)] - :: - =^ diff-result out (depend-on diff-build) - ?~ diff-result - (return-blocks [diff-build]~) - :: - ?: ?=([~ %error *] diff-result) - %- return-error - :- [%leaf "ford: %join to {} on {} failed:"] - message.u.diff-result - :: - ?> ?=([~ %success %call *] diff-result) - :: the result was a unit; if `~`, use %null mark; otherwise grab tail - :: - =/ =build-result - :+ %success %join - ?@ q.vase.u.diff-result - [%null vase.u.diff-result] - [u.form-mark (slot 3 vase.u.diff-result)] - :: - (return-result build-result) - :: - ++ make-list - ~% %make-list ..^^$ ~ - |= schematics=(list schematic) - ^- build-receipt - :: - =/ key-and-schematics - (turn schematics |=(=schematic [~ schematic])) - :: depend on builds of each schematic - :: - =^ maybe-schematic-results out - (perform-schematics "" key-and-schematics %ignore-errors *~) - ?~ maybe-schematic-results - out - :: return all builds - :: - =/ =build-result - :+ %success %list - :: the roll above implicitly flopped the results - :: - (flop (turn u.maybe-schematic-results tail)) - (return-result build-result) - :: - ++ make-mash - ~% %make-mash ..^^$ ~ - |= $: disc=disc - mark=term - first=[disc=disc mark=term =schematic] - second=[disc=disc mark=term =schematic] - == - ^- build-receipt - :: - =/ initial-build=^build - [date.build [schematic.first schematic.second] [%path disc %mar mark]] - :: - =^ initial-result out (depend-on initial-build) - ?~ initial-result - (return-blocks [initial-build]~) - :: TODO: duplicate logic with +make-join - :: - ?. ?=([~ %success [%success ^ ^] %success %path *] initial-result) - (wrap-error initial-result) - ?. ?=([%success *] head.head.u.initial-result) - (wrap-error `head.head.u.initial-result) - ?. ?=([%success *] tail.head.u.initial-result) - (wrap-error `tail.head.u.initial-result) - :: - =/ first-cage=cage (result-to-cage head.head.u.initial-result) - =/ second-cage=cage (result-to-cage tail.head.u.initial-result) - =/ mark-path=rail rail.tail.u.initial-result - :: TODO: duplicate logic with +make-pact and others - :: - =/ mark-build=^build [date.build [%core mark-path]] - :: - =^ mark-result out (depend-on mark-build) - ?~ mark-result - (return-blocks [mark-build]~) - :: - ?. ?=([~ %success %core *] mark-result) - (wrap-error mark-result) - :: - =/ mark-vase=vase vase.u.mark-result - :: - ?. (slab %grad p.mark-vase) - %- return-error :_ ~ :- %leaf - "ford: %mash failed: %{} mark has no +grad arm" - :: - =/ grad-build=^build - [date.build [%ride [%limb %grad] [%$ %noun mark-vase]]] - :: - =^ grad-result out (depend-on grad-build) - ?~ grad-result - (return-blocks [grad-build]~) - :: - ?. ?=([~ %success %ride *] grad-result) - (wrap-error grad-result) - :: - =/ grad-vase=vase vase.u.grad-result - :: if +grad produced a mark, delegate %mash behavior to that mark - :: - ?@ q.grad-vase - :: if +grad produced a term, make sure it's a valid mark - :: - =/ grad-mark=(unit term) ((sand %tas) q.grad-vase) - ?~ grad-mark - %- return-error :_ ~ :- %leaf - "ford: %mash failed: %{} mark invalid +grad" - :: - =/ mash-build=^build - :- date.build - :- %mash - :^ disc u.grad-mark - [disc.first mark.first [%$ first-cage]] - [disc.second mark.second [%$ second-cage]] - :: - =^ mash-result out (depend-on mash-build) - ?~ mash-result - (return-blocks [mash-build]~) - :: - ?. ?=([~ %success %mash *] mash-result) - (wrap-error mash-result) - :: - =/ =build-result - [%success %mash cage.u.mash-result] - :: - (return-result build-result) - :: - ?. (slab %form p.grad-vase) - %- return-error :_ ~ :- %leaf - "ford: %mash failed: %{} mark has no +form:grad" - :: - ?. (slab %mash p.grad-vase) - %- return-error :_ ~ :- %leaf - "ford: %mash failed: %{} mark has no +mash:grad" - :: - =/ form-build=^build - [date.build [%ride [%limb %form] [%$ %noun grad-vase]]] - :: - =^ form-result out (depend-on form-build) - ?~ form-result - (return-blocks [form-build]~) - :: - ?. ?=([~ %success %ride *] form-result) - (wrap-error form-result) - :: - =/ form-mark=(unit term) ((soft @tas) q.vase.u.form-result) - ?~ form-mark - %- return-error :_ ~ :- %leaf - "ford: %mash failed: %{} mark invalid +form:grad" - :: - ?. &(=(u.form-mark p.first-cage) =(u.form-mark p.second-cage)) - %- return-error :_ ~ :- %leaf - "ford: %mash failed: mark mismatch" - :: - ?: =(q.q.first-cage q.q.second-cage) - =/ =build-result - [%success %mash [%null [%atom %n ~] ~]] - :: - (return-result build-result) - :: call the +mash:grad gate on two [ship desk diff] triples - :: - =/ mash-build=^build - :- date.build - :+ %call - :+ %ride - [%limb %mash] - [%$ %noun grad-vase] - :+ %$ %noun - %+ slop - ;: slop - [[%atom %p ~] ship.disc.first] - [[%atom %tas ~] desk.disc.first] - q.first-cage - == - ;: slop - [[%atom %p ~] ship.disc.second] - [[%atom %tas ~] desk.disc.second] - q.second-cage - == - :: - =^ mash-result out (depend-on mash-build) - ?~ mash-result - (return-blocks [mash-build]~) - :: - ?. ?=([~ %success %call *] mash-result) - (wrap-error mash-result) - :: - =/ =build-result - [%success %mash [u.form-mark vase.u.mash-result]] - :: - (return-result build-result) - :: - ++ make-mute - ~% %make-mute ..^^$ ~ - |= [subject=schematic mutations=(list [=wing =schematic])] - ^- build-receipt - :: run the subject build to produce the noun to be mutated - :: - =/ subject-build=^build [date.build subject] - =^ subject-result out (depend-on subject-build) - ?~ subject-result - (return-blocks [subject-build]~) - :: - ?. ?=([~ %success *] subject-result) - (wrap-error subject-result) - :: - =/ subject-cage=cage (result-to-cage u.subject-result) - :: - =/ subject-vase=vase q.subject-cage - :: - =^ maybe-schematic-results out - %- perform-schematics :* - "ford: %mute contained failures:" - mutations - %fail-on-errors - *wing - == - ?~ maybe-schematic-results - out - :: all builds succeeded; retrieve vases from results - :: - =/ successes=(list [=wing =vase]) - %+ turn u.maybe-schematic-results - |= [=wing result=build-result] - ^- [^wing vase] - :: - ?> ?=([%success *] result) - :: - [wing q:(result-to-cage result)] - :: create and run a +build to apply all mutations in order - :: - =/ ride-build=^build - :- date.build - :+ %ride - :: formula: a `%_` +hoon that applies a list of mutations - :: - :: The hoon ends up looking like: - :: ``` - :: %_ +2 - :: wing-1 +6 - :: wing-2 +14 - :: ... - :: == - :: ``` - :: - ^= formula - ^- hoon - :+ %cncb [%& 2]~ - =/ axis 3 - :: - |- ^- (list [wing hoon]) - ?~ successes ~ - :: - :- [wing.i.successes [%$ (peg axis 2)]] - $(successes t.successes, axis (peg axis 3)) - :: subject: list of :subject-vase and mutations, as literal schematic - :: - :: The subject ends up as a vase of something like this: - :: ``` - :: :~ original-subject - :: mutant-1 - :: mutant-2 - :: ... - :: == - :: ``` - :: - ^= subject ^- schematic - :+ %$ %noun - ^- vase - %+ slop subject-vase - |- ^- vase - ?~ successes [[%atom %n ~] ~] - :: - (slop vase.i.successes $(successes t.successes)) - :: - =^ ride-result out (depend-on ride-build) - ?~ ride-result - (return-blocks [ride-build]~) - :: - ?. ?=([~ %success %ride *] ride-result) - (wrap-error ride-result) - :: - =/ =build-result - [%success %mute p.subject-cage vase.u.ride-result] - :: - (return-result build-result) - :: - ++ make-pact - ~% %make-pact ..^^$ ~ - |= [disc=disc start=schematic diff=schematic] - ^- build-receipt - :: first, build the inputs - :: - =/ initial-build=^build [date.build start diff] - :: - =^ initial-result out (depend-on initial-build) - ?~ initial-result - (return-blocks [initial-build]~) - :: - ?> ?=([~ %success ^ ^] initial-result) - =/ start-result=build-result head.u.initial-result - =/ diff-result=build-result tail.u.initial-result - :: - ?. ?=(%success -.start-result) - (wrap-error `start-result) - ?. ?=(%success -.diff-result) - (wrap-error `diff-result) - :: - =/ start-cage=cage (result-to-cage start-result) - =/ diff-cage=cage (result-to-cage diff-result) - :: - =/ start-mark=term p.start-cage - =/ diff-mark=term p.diff-cage - :: load the starting mark from the filesystem - :: - =/ mark-path-build=^build [date.build [%path disc %mar start-mark]] - :: - =^ mark-path-result out - (depend-on mark-path-build) - :: - ?~ mark-path-result - (return-blocks [mark-path-build]~) - :: - ?. ?=([~ %success %path *] mark-path-result) - (wrap-error mark-path-result) - :: - =/ mark-build=^build [date.build [%core rail.u.mark-path-result]] - :: - =^ mark-result out (depend-on mark-build) - ?~ mark-result - (return-blocks [mark-build]~) - :: - ?. ?=([~ %success %core *] mark-result) - (wrap-error mark-result) - :: - =/ mark-vase=vase vase.u.mark-result - :: fire the +grad arm of the mark core - :: - ?. (slab %grad p.mark-vase) - %- return-error :_ ~ :- %leaf - "ford: %pact failed: %{} mark has no +grad arm" - :: - =/ grad-build=^build - [date.build [%ride [%limb %grad] [%$ %noun mark-vase]]] - :: - =^ grad-result out (depend-on grad-build) - ?~ grad-result - (return-blocks [grad-build]~) - :: - ?. ?=([~ %success %ride *] grad-result) - (wrap-error grad-result) - :: - =/ grad-vase=vase vase.u.grad-result - :: +grad can produce a term or a core - :: - :: If a mark's +grad arm produces a mark (as a +term), - :: it means we should use that mark's machinery to run %pact. - :: In this way, a mark can delegate its patching machinery to - :: another mark. - :: - :: First we cast :start-cage to the +grad mark, then we run - :: a new %pact build on the result of that, which will use the - :: +grad mark's +grad arm. Finally we cast the %pact result back to - :: :start-mark, since we're trying to produce a patched version of - :: the initial marked value (:start-cage). - :: - ?@ q.grad-vase - :: if +grad produced a term, make sure it's a valid mark - :: - =/ grad-mark=(unit term) ((sand %tas) q.grad-vase) - ?~ grad-mark - %- return-error :_ ~ :- %leaf - "ford: %pact failed: %{} mark invalid +grad" - :: cast :start-cage to :grad-mark, %pact that, then cast back to start - :: - =/ cast-build=^build - :- date.build - :^ %cast disc start-mark - :^ %pact disc - :^ %cast disc u.grad-mark - [%$ start-cage] - [%$ diff-cage] - :: - =^ cast-result out (depend-on cast-build) - ?~ cast-result - (return-blocks [cast-build]~) - :: - ?. ?=([~ %success %cast *] cast-result) - (wrap-error cast-result) - :: - =/ =build-result - [%success %pact cage.u.cast-result] - :: - (return-result build-result) - :: +grad produced a core; make sure it has a +form arm - :: - :: +grad can produce a core containing +pact and +form - :: arms. +form:grad, which produces a mark (as a term), is used - :: to verify that the diff is of the correct mark. - :: - :: +pact:grad produces a gate that gets slammed with the diff - :: as its sample and produces a mutant version of :start-cage - :: by applying the diff. - :: - ?. (slab %form p.grad-vase) - %- return-error :_ ~ :- %leaf - "ford: %pact failed: no +form:grad in %{} mark" - :: we also need a +pact arm in the +grad core - :: - ?. (slab %pact p.grad-vase) - %- return-error :_ ~ :- %leaf - "ford: %pact failed: no +pact:grad in %{} mark" - :: fire the +form arm in the core produced by +grad - :: - =/ form-build=^build - [date.build [%ride [%limb %form] [%$ %noun grad-vase]]] - :: - =^ form-result out (depend-on form-build) - ?~ form-result - (return-blocks [form-build]~) - :: - ?. ?=([~ %success %ride *] form-result) - (wrap-error form-result) - :: +form:grad should produce a mark - :: - =/ form-mark=(unit @tas) ((soft @tas) q.vase.u.form-result) - ?~ form-mark - %- return-error :_ ~ :- %leaf - "ford: %pact failed: %{} mark invalid +form:grad" - :: mark produced by +form:grad needs to match the mark of the diff - :: - ?. =(u.form-mark diff-mark) - %- return-error :_ ~ :- %leaf - "ford: %pact failed: %{} mark invalid +form:grad" - :: call +pact:grad on the diff - :: - =/ pact-build=^build - :- date.build - :+ %call - ^- schematic - :+ %ride - [%tsld [%limb %pact] [%limb %grad]] - ^- schematic - :+ %mute - ^- schematic - [%$ %noun mark-vase] - ^- (list [wing schematic]) - [[%& 6]~ [%$ start-cage]]~ - ^- schematic - [%$ diff-cage] - :: - =^ pact-result out (depend-on pact-build) - ?~ pact-result - (return-blocks [pact-build]~) - :: - ?. ?=([~ %success %call *] pact-result) - (wrap-error pact-result) - :: - =/ =build-result - [%success %pact start-mark vase.u.pact-result] - :: - (return-result build-result) - :: - ++ make-path - ~% %make-path ..^^$ ~ - |= [disc=disc prefix=@tas raw-path=@tas] - ^- build-receipt - :: possible-spurs: flopped paths to which :raw-path could resolve - :: - =/ possible-spurs=(list spur) (turn (segments raw-path) flop) - :: rails-and-schematics: scrys to check each path in :possible-paths - :: - =/ rails-and-schematics=(list [=rail =schematic]) - %+ turn possible-spurs - |= possible-spur=spur - ^- [rail schematic] - :: full-spur: wrap :possible-spur with :prefix and /hoon suffix - :: - =/ full-spur=spur :(welp /hoon possible-spur /[prefix]) - :: - :- [disc full-spur] - [%scry %c %x `rail`[disc full-spur]] - :: depend on builds of each schematic - :: - =^ maybe-schematic-results out - %- perform-schematics :* - ;: weld - "ford: %path resolution of " (trip raw-path) "at prefix " - (trip prefix) " contained failures:" - == - rails-and-schematics - %filter-errors - *rail - == - ?~ maybe-schematic-results - out - :: matches: builds that completed with a successful result - :: - =/ matches u.maybe-schematic-results - :: if no matches, error out - :: - ?~ matches - =/ =beam - [[ship.disc desk.disc [%da date.build]] /hoon/[raw-path]/[prefix]] - :: - %- return-error - :_ ~ - :- %leaf - (weld "%path: no matches for " (spud (en-beam beam))) - :: if exactly one path matches, succeed with the matching path - :: - ?: ?=([* ~] matches) - (return-result %success %path key.i.matches) - :: multiple paths matched; error out - :: - %- return-error - :: - :- [%leaf "multiple matches for %path: "] - :: tmi; cast :matches back to +list - :: - %+ roll `_u.maybe-schematic-results`matches - |= [[key=rail result=build-result] message=tang] - ^- tang - :: beam: reconstruct request from :kid's schematic and date - :: - =/ =beam [[ship.disc desk.disc [%da date.build]] spur.key] - :: - [[%leaf (spud (en-beam beam))] message] - :: - ++ make-plan - ~% %make-plan ..^^$ ~ - |= [path-to-render=rail query-string=coin =scaffold] - ^- build-receipt - :: blocks: accumulator for blocked sub-builds - :: - =| blocks=(list ^build) - :: error-message: accumulator for failed sub-builds - :: - =| error-message=tang - :: - |^ :: imports: structure and library +cables, with %sur/%lib prefixes - :: - =/ imports=(list [prefix=?(%sur %lib) =cable]) - %+ welp - (turn structures.scaffold |=(cable [%sur +<])) - (turn libraries.scaffold |=(cable [%lib +<])) - :: path-builds: %path sub-builds to resolve import paths - :: - =/ path-builds (gather-path-builds imports) - :: - =^ path-results ..$ (resolve-builds path-builds) - ?^ blocks - (return-blocks blocks) - :: - ?^ error-message - (return-error error-message) - :: tmi; remove type specializations - :: - => .(blocks *(list ^build), error-message *tang) - :: core-builds: %core sub-builds to produce library vases - :: - =/ core-builds (gather-core-builds path-results) - :: - =^ core-results ..$ (resolve-builds core-builds) - ?^ blocks - (return-blocks blocks) - :: - ?^ error-message - (return-error error-message) - :: reef-build: %reef build to produce standard library - :: - =/ reef-build=^build [date.build [%reef disc.path-to-render]] - :: - =^ reef-result out (depend-on reef-build) - ?~ reef-result - (return-blocks [reef-build]~) - :: - ?. ?=([~ %success %reef *] reef-result) - (wrap-error reef-result) - :: subject: tuple of imports and standard library - :: - =/ subject=vase - (link-imports imports vase.u.reef-result core-results) - :: tmi; remove type specializations - :: - => .(blocks *(list ^build), error-message *tang) - :: iterate over each crane - :: - =^ crane-result ..$ - (compose-cranes [%noun subject] cranes.scaffold) - ?: ?=(%error -.crane-result) - (return-error message.crane-result) - ?: ?=(%block -.crane-result) - (return-blocks builds.crane-result) - :: combined-hoon: source hoons condensed into a single +hoon - :: - =/ combined-hoon=hoon [%tssg sources.scaffold] - :: compile :combined-hoon against :subject - :: - =/ compile=^build - [date.build [%ride combined-hoon [%$ subject.crane-result]]] - :: - =^ compiled out (depend-on compile) - :: compilation blocked; produce block on sub-build - :: - ?~ compiled - (return-blocks ~[compile]) - :: compilation failed; error out - :: - ?. ?=([~ %success %ride *] compiled) - (wrap-error compiled) - :: compilation succeeded: produce resulting +vase - :: - (return-result %success %plan vase.u.compiled) - :: +compose-result: the result of a single composition - :: - += compose-result - $% [%subject subject=cage] - [%block builds=(list ^build)] - [%error message=tang] - == - :: +compose-cranes: runs each crane and composes the results - :: - :: For each crane in :cranes, runs it and composes its result into a - :: new subject, which is returned if there are no errors or blocks. - :: - ++ compose-cranes - |= [subject=cage cranes=(list crane)] - ^- $: compose-result - _..compose-cranes - == - :: - ?~ cranes - [[%subject subject] ..compose-cranes] - :: - =^ result ..compose-cranes (run-crane subject i.cranes) - ?+ -.result [result ..compose-cranes] - :: - %subject - $(cranes t.cranes, subject [%noun (slop q.subject.result q.subject)]) - == - :: +run-crane: runs an individual :crane against :subject - :: - ++ run-crane - |= [subject=cage =crane] - ^- compose-cranes - :: - |^ ?- -.crane - %fssg (run-fssg +.crane) - %fsbc (run-fsbc +.crane) - %fsbr (run-fsbr +.crane) - %fsts (run-fsts +.crane) - %fscm (run-fscm +.crane) - %fspm (run-fspm +.crane) - %fscb (run-fscb +.crane) - %fsdt (run-fsdt +.crane) - %fssm (run-fssm +.crane) - %fscl (run-fscl +.crane) - %fskt (run-fskt +.crane) - %fstr (run-fstr +.crane) - %fszp (run-fszp +.crane) - %fszy (run-fszy +.crane) - == - :: +run-fssg: runs the `/~` rune - :: - ++ run-fssg - |= =hoon - ^- compose-cranes - :: - =/ ride-build=^build - [date.build [%ride hoon [%$ subject]]] - =^ ride-result out (depend-on ride-build) - ?~ ride-result - [[%block [ride-build]~] ..run-crane] - ?: ?=([~ %error *] ride-result) - [[%error [leaf+"/~ failed: " message.u.ride-result]] ..run-crane] - ?> ?=([~ %success %ride *] ride-result) - [[%subject %noun vase.u.ride-result] ..run-crane] - :: +run-fsbc: runs the `/$` rune - :: - ++ run-fsbc - |= =hoon - ^- compose-cranes - :: - =/ query-compile-build=^build - [date.build [%ride ((jock |) query-string) [%$ %noun !>(~)]]] - =^ query-compile-result out (depend-on query-compile-build) - ?~ query-compile-result - [[%block [query-compile-build]~] ..run-crane] - ?: ?=([~ %error *] query-compile-result) - :- [%error [leaf+"/; failed: " message.u.query-compile-result]] - ..run-crane - ?> ?=([~ %success %ride *] query-compile-result) - :: - =/ =beam - =, path-to-render - [[ship.disc desk.disc [%da date.build]] spur] - =+ arguments=(slop !>(beam) vase.u.query-compile-result) - :: - =/ call-build=^build - [date.build [%call [%ride hoon [%$ subject]] [%$ %noun arguments]]] - =^ call-result out (depend-on call-build) - ?~ call-result - [[%block [call-build]~] ..run-crane] - ?: ?=([~ %error *] call-result) - [[%error [leaf+"/; failed: " message.u.call-result]] ..run-crane] - ?> ?=([~ %success %call *] call-result) - :: - [[%subject %noun vase.u.call-result] ..run-crane] - :: +run-fsbr: runs the `/|` rune - :: - ++ run-fsbr - |= choices=(list ^crane) - ^- compose-cranes - :: - ?~ choices - [[%error [leaf+"/| failed: out of options"]~] ..run-crane] - :: - =^ child ..run-crane (run-crane subject i.choices) - ?. ?=([%error *] child) - [child ..run-crane] - $(choices t.choices) - :: +run-fsts: runs the `/=` rune - :: - ++ run-fsts - |= [face=term sub-crane=^crane] - ^- compose-cranes - :: - =^ child ..run-crane (run-crane subject sub-crane) - ?. ?=([%subject *] child) - [child ..run-crane] - :_ ..run-crane - :* %subject - p.subject.child - [[%face face p.q.subject.child] q.q.subject.child] - == - :: +run-fscm: runs the `/,` rune - :: - ++ run-fscm - |= cases=(list [=spur crane=^crane]) - ^- compose-cranes - :: - ?~ cases - [[%error [leaf+"/, failed: no match"]~] ..run-crane] - :: - ?. .= spur.i.cases - (scag (lent spur.i.cases) (flop spur.path-to-render)) - $(cases t.cases) - :: - (run-crane subject crane.i.cases) - :: +run-fspm: runs the `/&` rune - :: - ++ run-fspm - |= [marks=(list mark) sub-crane=^crane] - ^- compose-cranes - :: - =^ child ..run-crane (run-crane subject sub-crane) - ?. ?=([%subject *] child) - [child ..run-crane] - :: - =/ cast-build=^build - :- date.build - |- - ^- schematic - ?~ marks - :: TODO: If we were keeping track of the mark across runes, this - :: wouldn't have %noun here. This is a case where it might matter. - :: - [%$ subject.child] - [%cast disc.source-rail.scaffold i.marks $(marks t.marks)] - =^ cast-result out (depend-on cast-build) - ?~ cast-result - [[%block [cast-build]~] ..run-crane] - :: - ?: ?=([~ %error *] cast-result) - [[%error [leaf+"/& failed: " message.u.cast-result]] ..run-crane] - ?> ?=([~ %success %cast *] cast-result) - :: - [[%subject cage.u.cast-result] ..run-crane] - :: +run-fscb: runs the `/_` rune - :: - ++ run-fscb - |= sub-crane=^crane - ^- compose-cranes - :: perform a scry to get the contents of +path-to-render - :: - =/ toplevel-build=^build - [date.build [%scry [%c %y path-to-render]]] - :: - =^ toplevel-result out (depend-on toplevel-build) - ?~ toplevel-result - [[%block ~[toplevel-build]] ..run-crane] - :: - ?: ?=([~ %error *] toplevel-result) - :- [%error [leaf+"/_ failed: " message.u.toplevel-result]] - ..run-crane - ?> ?=([~ %success %scry *] toplevel-result) - :: - =/ toplevel-arch=arch ;;(arch q.q.cage.u.toplevel-result) - :: sub-path: each possible sub-directory to check - :: - =/ sub-paths=(list @ta) - (turn ~(tap by dir.toplevel-arch) head) - :: for each directory in :toplevel-arch, issue a sub-build - :: - =/ sub-builds=(list ^build) - %+ turn sub-paths - |= sub=@ta - ^- ^build - :- date.build - [%scry [%c %y path-to-render(spur [sub spur.path-to-render])]] - :: results: accumulator for results of sub-builds - :: - =| $= results - (list [kid=^build sub-path=@ta results=(unit build-result)]) - :: resolve all the :sub-builds - :: - =/ subs-results - |- ^+ [results out] - ?~ sub-builds [results out] - ?> ?=(^ sub-paths) - :: - =/ kid=^build i.sub-builds - =/ sub-path=@ta i.sub-paths - :: - =^ result out (depend-on kid) - =. results [[kid sub-path result] results] - :: - $(sub-builds t.sub-builds, sub-paths t.sub-paths) - :: apply mutations from depending on sub-builds - :: - =: results -.subs-results - out +.subs-results - == - :: split :results into completed :mades and incomplete :blocks - :: - =+ ^= split-results - (skid results |=([* * r=(unit build-result)] ?=(^ r))) - :: - =/ mades=_results -.split-results - =/ blocks=_results +.split-results - :: if any builds blocked, produce them all in %blocks - :: - ?^ blocks - [[%block (turn `_results`blocks head)] ..run-crane] - :: find the first error and return it if exists - :: - =/ errors=_results - %+ skim results - |= [* * r=(unit build-result)] - ?=([~ %error *] r) - ?^ errors - ?> ?=([~ %error *] results.i.errors) - [[%error message.u.results.i.errors] ..run-crane] - :: get a list of valid sub-paths - :: - :: :results is now a list of the :build-result of %cy on each path - :: in :toplevel-arch. What we want is to now filter this list so - :: that we filter files out. - :: - =/ sub-paths=(list [=rail sub-path=@ta]) - %+ murn results - |= [build=^build sub-path=@ta result=(unit build-result)] - ^- (unit [rail @ta]) - :: - ?> ?=([@da %scry %c %y *] build) - ?> ?=([~ %success %scry *] result) - =/ =arch ;;(arch q.q.cage.u.result) - :: - ?~ dir.arch - ~ - `[rail.resource.schematic.build sub-path] - :: keep track of the original value so we can reset it - :: - =/ old-path-to-render path-to-render - :: apply each of the filtered :sub-paths to the :sub-crane. - :: - =^ crane-results ..run-crane - %+ roll sub-paths - |= $: [=rail sub-path=@ta] - $= accumulator - [(list [sub-path=@ta =compose-result]) _..run-crane] - == - =. ..run-crane +.accumulator - =. path-to-render rail - =^ result ..run-crane (run-crane subject sub-crane) - [[[sub-path result] -.accumulator] ..run-crane] - :: set :path-to-render back - :: - =. path-to-render old-path-to-render - :: if any sub-cranes error, return the first error - :: - =/ error-list=(list [@ta =compose-result]) - %+ skim crane-results - |= [@ta =compose-result] - =(%error -.compose-result) - :: - ?^ error-list - [compose-result.i.error-list ..run-crane] - :: if any sub-cranes block, return all blocks - :: - =/ block-list=(list ^build) - =| block-list=(list ^build) - |- - ^+ block-list - ?~ crane-results - block-list - ?. ?=(%block -.compose-result.i.crane-results) - $(crane-results t.crane-results) - =. block-list - (weld builds.compose-result.i.crane-results block-list) - $(crane-results t.crane-results) - :: - ?^ block-list - [[%block block-list] ..run-crane] - :: put the data in map order - :: - =/ result-map=(map @ta vase) - %- my - %+ turn crane-results - |= [path=@ta =compose-result] - ^- (pair @ta vase) - :: - ?> ?=([%subject *] compose-result) - [path q.subject.compose-result] - :: convert the map into a flat format for return - :: - :: This step flattens the values out of the map for return. Let's - :: say we're doing a /_ over a directory of files that just have a - :: single @ud in them. We want the return value of /_ to have the - :: nest in (map @ta @ud) instead of returning a (map @ta vase). - :: - =/ as-vase=vase - |- - ^- vase - :: - ?~ result-map - [[%atom %n `0] 0] - :: - %+ slop - (slop [[%atom %ta ~] p.n.result-map] q.n.result-map) - (slop $(result-map l.result-map) $(result-map r.result-map)) - :: - [[%subject %noun as-vase] ..run-crane] - :: +run-fsdt: runs the `/.` rune - :: - ++ run-fsdt - |= sub-cranes=(list ^crane) - ^- compose-cranes - :: - =^ list-results ..run-crane - %+ roll sub-cranes - |= $: sub-crane=^crane - accumulator=[(list compose-result) _..run-crane] - == - =. ..run-crane +.accumulator - =^ result ..run-crane (run-crane subject sub-crane) - [[result -.accumulator] ..run-crane] - :: if any sub-cranes error, return the first error - :: - =/ error-list=(list compose-result) - %+ skim list-results - |= =compose-result - =(%error -.compose-result) - :: - ?^ error-list - [i.error-list ..run-crane] - :: if any sub-cranes block, return all blocks - :: - =/ block-list=(list ^build) - =| block-list=(list ^build) - |- - ^+ block-list - ?~ list-results - block-list - ?. ?=(%block -.i.list-results) - $(list-results t.list-results) - =. block-list (weld builds.i.list-results block-list) - $(list-results t.list-results) - :: - ?^ block-list - [[%block block-list] ..run-crane] - :: concatenate all the results together with null termination - :: - =. list-results (flop list-results) - :: - =/ final-result=vase - |- - ^- vase - ?~ list-results - [[%atom %n `~] 0] - ?> ?=(%subject -.i.list-results) - (slop q.subject.i.list-results $(list-results t.list-results)) - :: - [[%subject %noun final-result] ..run-crane] - :: +run-fssm: runs the `/;` rune - :: - ++ run-fssm - |= [=hoon sub-crane=^crane] - ^- compose-cranes - :: - =^ child ..run-crane (run-crane subject sub-crane) - ?. ?=([%subject *] child) - [child ..run-crane] - :: - =/ call-build=^build - [date.build [%call [%ride hoon [%$ subject]] [%$ subject.child]]] - =^ call-result out (depend-on call-build) - ?~ call-result - [[%block [call-build]~] ..run-crane] - ?: ?=([~ %error *] call-result) - [[%error [leaf+"/; failed: " message.u.call-result]] ..run-crane] - ?> ?=([~ %success %call *] call-result) - :: - [[%subject %noun vase.u.call-result] ..run-crane] - :: +run-fscl: runs the `/:` rune - :: - ++ run-fscl - |= [=truss sub-crane=^crane] - ^- compose-cranes - :: - =/ beam-to-render=beam - [[ship.disc desk.disc %ud 0] spur]:path-to-render - :: - =/ hoon-parser (vang & (en-beam beam-to-render)) - :: - =+ tuz=(posh:hoon-parser truss) - ?~ tuz - [[%error [leaf+"/: failed: bad tusk: {}"]~] ..run-crane] - =+ pax=(plex:hoon-parser %clsg u.tuz) - ?~ pax - [[%error [leaf+"/: failed: bad path: {}"]~] ..run-crane] - =+ bem=(de-beam u.pax) - ?~ bem - [[%error [leaf+"/: failed: bad beam: {}"]~] ..run-crane] - :: - =. path-to-render [[p q] s]:u.bem - (run-crane subject sub-crane) - :: +run-fskt: runs the `/^` rune - :: - ++ run-fskt - |= [=spec sub-crane=^crane] - ^- compose-cranes - :: - =^ child ..run-crane (run-crane subject sub-crane) - ?. ?=([%subject *] child) - [child ..run-crane] - :: - =/ bunt-build=^build - [date.build [%ride [%kttr spec] [%$ subject]]] - =^ bunt-result out (depend-on bunt-build) - ?~ bunt-result - [[%block [bunt-build]~] ..run-crane] - ?: ?=([~ %error *] bunt-result) - [[%error [leaf+"/^ failed: " message.u.bunt-result]] ..run-crane] - ?> ?=([~ %success %ride *] bunt-result) - :: - ?. (~(nest ut p.vase.u.bunt-result) | p.q.subject.child) - [[%error [leaf+"/^ failed: nest-fail"]~] ..run-crane] - :_ ..run-crane - [%subject %noun [p.vase.u.bunt-result q.q.subject.child]] - :: +run-fstr: runs the `/*` rune - :: - :: TODO: some duplicate code with +run-fscb - :: - ++ run-fstr - |= sub-crane=^crane - ^- compose-cranes - :: - =/ tree-build=^build - [date.build [%scry [%c %t path-to-render]]] - :: - =^ tree-result out (depend-on tree-build) - ?~ tree-result - [[%block ~[tree-build]] ..run-crane] - :: - ?: ?=([~ %error *] tree-result) - :- [%error [%leaf "/* failed: "] message.u.tree-result] - ..run-crane - ?> ?=([~ %success %scry *] tree-result) - :: - =/ file-list=(list path) ;;((list path) q.q.cage.u.tree-result) - :: trim file extensions off the file paths - :: - :: This is pretty ugly, but Ford expects :path-to-render not to - :: have a file extension, so we need to trim it off each path. - :: - =. file-list - :: deduplicate since multiple files could share a trimmed path - :: - =- ~(tap in (~(gas in *(set path)) `(list path)`-)) - %+ turn file-list - |= =path - ^+ path - (scag (sub (lent path) 1) path) - :: - =/ old-path-to-render path-to-render - :: apply each of the paths in :file-list to the :sub-crane - :: - =^ crane-results ..run-crane - %+ roll file-list - |= $: =path - $= accumulator - [(list [=path =compose-result]) _..run-crane] - == - =. ..run-crane +.accumulator - =. spur.path-to-render (flop path) - :: - =^ result ..run-crane (run-crane subject sub-crane) - [[[path result] -.accumulator] ..run-crane] - :: - =. path-to-render old-path-to-render - :: if any sub-cranes error, return the first error - :: - =/ error-list=(list [=path =compose-result]) - %+ skim crane-results - |= [=path =compose-result] - =(%error -.compose-result) - :: - ?^ error-list - [compose-result.i.error-list ..run-crane] - :: if any sub-cranes block, return all blocks - :: - =/ block-list=(list ^build) - =| block-list=(list ^build) - |- ^+ block-list - ?~ crane-results block-list - :: - ?. ?=(%block -.compose-result.i.crane-results) - $(crane-results t.crane-results) - =. block-list - (weld builds.compose-result.i.crane-results block-list) - :: - $(crane-results t.crane-results) - :: - ?^ block-list - [[%block block-list] ..run-crane] - :: - =/ result-map=(map path vase) - %- my - %+ turn crane-results - |= [=path =compose-result] - ^- (pair ^path vase) - :: - ?> ?=(%subject -.compose-result) - [path q.subject.compose-result] - :: - =/ as-vase - =/ path-type -:!>(*path) - |- ^- vase - ?~ result-map [[%atom %n `0] 0] - :: - %+ slop - (slop [path-type p.n.result-map] q.n.result-map) - (slop $(result-map l.result-map) $(result-map r.result-map)) - :: - [[%subject %noun as-vase] ..run-crane] - :: +run-fszp: runs the `/!mark/` "rune" - :: - ++ run-fszp - |= =mark - ^- compose-cranes - :: - =/ hoon-path=rail - =, path-to-render - [disc [%hoon spur]] - :: - =/ hood-build=^build [date.build [%hood hoon-path]] - =^ hood-result out (depend-on hood-build) - ?~ hood-result - [[%block [hood-build]~] ..run-crane] - ?: ?=([~ %error *] hood-result) - [[%error [leaf+"/! failed: " message.u.hood-result]] ..run-crane] - ?> ?=([~ %success %hood *] hood-result) - :: - =/ plan-build=^build - :- date.build - [%plan path-to-render query-string scaffold.u.hood-result] - =^ plan-result out (depend-on plan-build) - ?~ plan-result - [[%block [plan-build]~] ..run-crane] - ?: ?=([~ %error *] plan-result) - [[%error [leaf+"/! failed: " message.u.plan-result]] ..run-crane] - ?> ?=([~ %success %plan *] plan-result) - :: if :mark is %noun, don't perform mark translation; just return - :: - :: If we were to verify the product type with %noun, this would - :: cast to *, which would overwrite :vase.u.plan-result's actual - :: product type - :: - ?: =(%noun mark) - [[%subject %noun vase.u.plan-result] ..run-crane] - :: - =/ vale-build=^build - :- date.build - [%vale disc.source-rail.scaffold mark q.vase.u.plan-result] - =^ vale-result out (depend-on vale-build) - ?~ vale-result - [[%block [vale-build]~] ..run-crane] - ?: ?=([~ %error *] vale-result) - [[%error [leaf+"/! failed: " message.u.vale-result]] ..run-crane] - ?> ?=([~ %success %vale *] vale-result) - :: - [[%subject cage.u.vale-result] ..run-crane] - :: +run-fszy: runs the `/mark/` "rune" - :: - ++ run-fszy - |= =mark - ^- compose-cranes - :: - =/ bake-build=^build - :- date.build - [%bake mark query-string path-to-render] - =^ bake-result out (depend-on bake-build) - ?~ bake-result - [[%block [bake-build]~] ..run-crane] - ?: ?=([~ %error *] bake-result) - :_ ..run-crane - [%error [leaf+"/{(trip mark)}/ failed: " message.u.bake-result]] - ?> ?=([~ %success %bake *] bake-result) - :: - [[%subject cage.u.bake-result] ..run-crane] - -- - :: +gather-path-builds: produce %path builds to resolve import paths - :: - ++ gather-path-builds - |= imports=(list [prefix=?(%sur %lib) =cable]) - ^- (list ^build) - :: - %+ turn imports - |= [prefix=?(%sur %lib) =cable] - ^- ^build - [date.build [%path disc.source-rail.scaffold prefix file-path.cable]] - :: +resolve-builds: run a list of builds and collect results - :: - :: If a build blocks, put its +tang in :error-message and stop. - :: All builds that block get put in :blocks. Results of - :: successful builds are produced in :results. - :: - ++ resolve-builds - =| results=(list build-result) - |= builds=(list ^build) - ^+ [results ..^$] - :: - ?~ builds - [results ..^$] - :: - =^ result out (depend-on i.builds) - ?~ result - =. blocks [i.builds blocks] - $(builds t.builds) - :: - ?. ?=(%success -.u.result) - =. error-message [[%leaf "%plan failed: "] message.u.result] - [results ..^$] - :: - =. results [u.result results] - $(builds t.builds) - :: +gather-core-builds: produce %core builds from resolved paths - :: - ++ gather-core-builds - |= path-results=(list build-result) - ^- (list ^build) - %+ turn path-results - |= result=build-result - ^- ^build - :: - ?> ?=([%success %path *] result) - :: - [date.build [%core rail.result]] - :: +link-imports: link libraries and structures with standard library - :: - :: Prepends each library vase onto the standard library vase. - :: Wraps a face around each library to prevent namespace leakage - :: unless imported as *lib-name. - :: - ++ link-imports - |= $: imports=(list [?(%lib %sur) =cable]) - reef=vase - core-results=(list build-result) - == - ^- vase - :: - =/ subject=vase reef - :: - =/ core-vases=(list vase) - %+ turn core-results - |= result=build-result - ^- vase - ?> ?=([%success %core *] result) - vase.result - :: link structures and libraries into a subject for compilation - :: - |- ^+ subject - ?~ core-vases subject - ?< ?=(~ imports) - :: cons this vase onto the head of the subject - :: - =. subject - %- slop :_ subject - :: check if the programmer named the library - :: - ?~ face.cable.i.imports - :: no face assigned to this library, so use vase as-is - :: - i.core-vases - :: use the library name as a face to prevent namespace leakage - :: - ^- vase - [[%face u.face.cable.i.imports p.i.core-vases] q.i.core-vases] - :: - $(core-vases t.core-vases, imports t.imports) - -- - :: - ++ make-reef - ~% %make-reef ..^^$ ~ - |= =disc - ^- build-receipt - :: - =/ hoon-scry - [date.build [%scry %c %x [disc /hoon/hoon/sys]]] - :: - =^ hoon-scry-result out (depend-on hoon-scry) - :: - =/ arvo-scry - [date.build [%scry %c %x [disc /hoon/arvo/sys]]] - :: - =^ arvo-scry-result out (depend-on arvo-scry) - :: - =/ zuse-scry - [date.build [%scry %c %x [disc /hoon/zuse/sys]]] - :: - =^ zuse-scry-result out (depend-on zuse-scry) - :: - =| blocks=(list ^build) - =? blocks ?=(~ hoon-scry-result) [hoon-scry blocks] - =? blocks ?=(~ arvo-scry-result) [arvo-scry blocks] - =? blocks ?=(~ zuse-scry-result) [zuse-scry blocks] - :: - ?^ blocks - (return-blocks blocks) - :: - ?. ?=([~ %success %scry *] hoon-scry-result) - (wrap-error hoon-scry-result) - :: - ?. ?=([~ %success %scry *] arvo-scry-result) - (wrap-error arvo-scry-result) - :: - ?. ?=([~ %success %scry *] zuse-scry-result) - (wrap-error zuse-scry-result) - :: - :: short-circuit to .pit during boot - :: - :: This avoids needing to recompile the kernel if we're asked - :: to build %hoon one the home desk, at revision 1 or 2. - :: - ?: ?& =(our ship.disc) - ?=(?(%base %home) desk.disc) - :: - =/ =beam - [[ship.disc desk.disc [%da date.build]] /hoon/hoon/sys] - =/ cass - (scry [%141 %noun] [~ %cw beam]) - ?=([~ ~ %cass * ?(%1 %2) *] cass) - == - :: - (return-result %success %reef pit) - :: omit case from path to prevent cache misses - :: - =/ hoon-path=path - /(scot %p ship.disc)/(scot %tas desk.disc)/hoon/hoon/sys - =/ hoon-hoon=(each hoon tang) - %- mule |. - (rain hoon-path ;;(@t q.q.cage.u.hoon-scry-result)) - ?: ?=(%| -.hoon-hoon) - (return-error leaf+"ford: %reef failed to compile hoon" p.hoon-hoon) - :: - =/ arvo-path=path - /(scot %p ship.disc)/(scot %tas desk.disc)/hoon/arvo/sys - =/ arvo-hoon=(each hoon tang) - %- mule |. - (rain arvo-path ;;(@t q.q.cage.u.arvo-scry-result)) - ?: ?=(%| -.arvo-hoon) - (return-error leaf+"ford: %reef failed to compile arvo" p.arvo-hoon) - :: - =/ zuse-path=path - /(scot %p ship.disc)/(scot %tas desk.disc)/hoon/zuse/sys - =/ zuse-hoon=(each hoon tang) - %- mule |. - (rain zuse-path ;;(@t q.q.cage.u.zuse-scry-result)) - ?: ?=(%| -.zuse-hoon) - (return-error leaf+"ford: %reef failed to compile zuse" p.zuse-hoon) - :: - =/ zuse-build=^build - :* date.build - %ride p.zuse-hoon - :: hoon for `..is` to grab the :pit out of the arvo core - :: - %ride [%cnts ~[[%& 1] %is] ~] - %ride p.arvo-hoon - %ride [%$ 7] - %ride p.hoon-hoon - [%$ %noun !>(~)] - == - :: - =^ zuse-build-result out (depend-on zuse-build) - ?~ zuse-build-result - (return-blocks [zuse-build]~) - :: - ?. ?=([~ %success %ride *] zuse-build-result) - (wrap-error zuse-build-result) - :: - (return-result %success %reef vase.u.zuse-build-result) - :: - ++ make-ride - ~% %make-ride ..^^$ ~ - |= [formula=hoon =schematic] - ^- build-receipt - :: - =^ result out (depend-on [date.build schematic]) - ?~ result - (return-blocks [date.build schematic]~) - :: - =* subject-vase q:(result-to-cage u.result) - =/ slim-schematic=^schematic [%slim p.subject-vase formula] - =^ slim-result out (depend-on [date.build slim-schematic]) - ?~ slim-result - (return-blocks [date.build slim-schematic]~) - :: - ?: ?=([~ %error *] slim-result) - %- return-error - :* [%leaf "ford: %ride failed to compute type:"] - message.u.slim-result - == - :: - ?> ?=([~ %success %slim *] slim-result) - :: - =/ =compiler-cache-key [%ride formula subject-vase] - =^ cached-result out (access-cache compiler-cache-key) - ?^ cached-result - (return-result u.cached-result) - :: - =/ val - (mock [q.subject-vase nock.u.slim-result] intercepted-scry) - :: val is a toon, which might be a list of blocks. - :: - ?- -.val - :: - %0 - (return-result %success %ride [type.u.slim-result p.val]) - :: - %1 - =/ blocked-paths=(list path) ;;((list path) p.val) - (blocked-paths-to-receipt %ride blocked-paths) - :: - %2 - (return-error [[%leaf "ford: %ride failed to execute:"] p.val]) - == - :: - ++ make-same - ~% %make-same ..^^$ ~ - |= =schematic - ^- build-receipt - :: - =^ result out (depend-on [date.build schematic]) - :: - ?~ result - (return-blocks [date.build schematic]~) - (return-result u.result) - :: - ++ make-scry - ~% %make-scry ..^^$ ~ - |= =resource - ^- build-receipt - :: construct a full +beam to make the scry request - :: - =/ =beam (extract-beam resource `date.build) - =/ =scry-request [vane.resource care.resource beam] - :: perform scry operation if we don't already know the result - :: - :: Look up :scry-request in :scry-results.per-event to avoid - :: rerunning a previously blocked +scry. - :: - =/ scry-response - ?: (~(has by scry-results) scry-request) - (~(get by scry-results) scry-request) - (scry [%141 %noun] ~ `@tas`(cat 3 [vane care]:resource) beam) - :: scry blocked - :: - ?~ scry-response - (return-blocks ~) - :: scry failed - :: - ?~ u.scry-response - %- return-error - :~ leaf+"scry failed for" - leaf+:(weld "%c" (trip care.resource) " " (spud (en-beam beam))) - == - :: scry succeeded - :: - (return-result %success %scry u.u.scry-response) - :: - ++ make-slim - ~% %make-slim ..^^$ ~ - |= [subject-type=type formula=hoon] - ^- build-receipt - :: - =/ =compiler-cache-key [%slim subject-type formula] - =^ cached-result out (access-cache compiler-cache-key) - ?^ cached-result - (return-result u.cached-result) - :: - =/ compiled=(each (pair type nock) tang) - (mule |.((~(mint ut subject-type) [%noun formula]))) - :: - %_ out - result - ?- -.compiled - %| [%build-result %error [leaf+"ford: %slim failed: " p.compiled]] - %& [%build-result %success %slim p.compiled] - == - == - :: TODO: Take in +type instead of +vase? - :: - ++ make-slit - ~% %make-slit ..^^$ ~ - |= [gate=vase sample=vase] - ^- build-receipt - :: - =/ =compiler-cache-key [%slit p.gate p.sample] - =^ cached-result out (access-cache compiler-cache-key) - ?^ cached-result - (return-result u.cached-result) - :: - =/ product=(each type tang) - (mule |.((slit p.gate p.sample))) - :: - %_ out - result - ?- -.product - %| :* %build-result %error - :* (~(dunk ut p.sample) %have) - (~(dunk ut (~(peek ut p.gate) %free 6)) %want) - leaf+"ford: %slit failed:" - p.product - == - == - %& [%build-result %success %slit p.product] - == - == - :: - ++ make-volt - ~% %make-volt ..^^$ ~ - |= [=disc mark=term input=*] - ^- build-receipt - :: - =/ bunt-build=^build [date.build [%bunt disc mark]] - :: - =^ bunt-result out (depend-on bunt-build) - ?~ bunt-result - (return-blocks [bunt-build]~) - :: - ?: ?=([~ %error *] bunt-result) - %- return-error - :- [%leaf "ford: %volt {} on {} failed:"] - message.u.bunt-result - :: - ?> ?=([~ %success %bunt *] bunt-result) - :: - =/ =build-result - [%success %volt [mark p.q.cage.u.bunt-result input]] - :: - (return-result build-result) - :: - ++ make-vale - ~% %make-vale ..^^$ ~ - :: TODO: better docs - :: - |= [=disc mark=term input=*] - ^- build-receipt - :: don't validate for the %noun mark - :: - ?: =(%noun mark) - =/ =build-result [%success %vale [%noun %noun input]] - :: - (return-result build-result) - :: - =/ path-build [date.build [%path disc %mar mark]] - :: - =^ path-result out (depend-on path-build) - ?~ path-result - (return-blocks [path-build]~) - :: - ?: ?=([~ %error *] path-result) - %- return-error - :- leaf+"ford: %vale failed while searching for {}:" - message.u.path-result - :: - ?> ?=([~ %success %path *] path-result) - :: - =/ bunt-build=^build [date.build [%bunt disc mark]] - :: - =^ bunt-result out (depend-on bunt-build) - ?~ bunt-result - (return-blocks [bunt-build]~) - :: - ?. ?=([~ %success %bunt *] bunt-result) - (wrap-error bunt-result) - :: - =/ mark-sample=vase q.cage.u.bunt-result - :: - =/ call-build=^build - :^ date.build - %call - ^= gate - :* %ride - :: (ream 'noun:grab') - formula=`hoon`[%tsld [%wing ~[%noun]] [%wing ~[%grab]]] - subject=`schematic`[%core rail.u.path-result] - == - sample=[%$ %noun %noun input] - :: - =^ call-result out (depend-on call-build) - ?~ call-result - (return-blocks [call-build]~) - :: - ?: ?=([~ %error *] call-result) - :: - %- return-error - =/ =beam - [[ship.disc desk.disc %da date.build] spur.rail.u.path-result] - :* :- %leaf - "ford: %vale failed: invalid input for mark: {<(en-beam beam)>}" - message.u.call-result - == - :: - ?> ?=([~ %success %call *] call-result) - =/ product=vase vase.u.call-result - :: +grab might produce the wrong type - :: - ?. (~(nest ut p.mark-sample) | p.product) - %- return-error - :~ leaf+"ford: %vale failed" - leaf+"+grab has wrong type in mark {} on disc {}" - == - :: - =/ =build-result - [%success %vale [mark p.mark-sample q.product]] - :: - (return-result build-result) - :: - ++ make-walk - ~% %make-walk ..^^$ ~ - |= [=disc source=term target=term] - ^- build-receipt - :: define some types used in this gate - :: - => |% - :: +load-node: a queued arm to run from a mark core - :: - += load-node [type=?(%grab %grow) mark=term] - :: edge-jug: directed graph from :source mark to :target marks - :: - :: :source can be converted to :target either by running - :: its own +grow arm, or by running the target's +grab arm. - :: - += edge-jug (jug source=term [target=term arm=?(%grow %grab)]) - :: mark-path: a path through the mark graph - :: - :: +mark-path represents a series of mark translation - :: operations to be performed to 'walk' from one mark to another. - :: - :: +mark-action is defined in Zuse. It represents a conversion - :: from a source mark to a target mark, and it specifies - :: whether it will use +grow or +grab. - :: - += mark-path (list mark-action) - -- - :: - |^ ^- build-receipt - ?: =(source target) - (return-result %success %walk ~) - :: load all marks. - :: - =^ marks-result out - (load-marks-reachable-from [[%grow source] [%grab target] ~]) - ?~ -.marks-result - out - :: find a path through the graph - :: - :: Make a list of individual mark translation actions which will - :: take us from :source to :term. - :: - =/ path (find-path-through u.-.marks-result) - :: if there is no path between these marks, give an error message - :: - ?~ path - :: we failed; surface errors from +load-marks-reachable-from - :: - =/ braces [[' ' ' ' ~] ['{' ~] ['}' ~]] - =/ errors=(list tank) - %- zing - %+ turn ~(tap in +.marks-result) - |= [mark=term err=tang] - ^- tang - :~ [%leaf :(weld "while compiling " (trip mark) ":")] - [%rose braces err] - == - :: - %_ out - result - :* %build-result %error - :* :- %leaf - ;: weld - "ford: no mark path from " (trip source) " to " - (trip target) - == - errors - == == - == - :: - (return-result %success %walk path) - :: +load-marks-reachable-from: partial mark graph loading - :: - :: While we can just load all marks in the %/mar directory, this is - :: rather slow. What we do instead is traverse forwards and backwards - :: from the source and target marks: we start at the source mark, - :: check all the grow arms, and then check their grow arms. At the - :: same time, we start from the target mark, check all the grab arms, - :: and then check their grab arms. This gives us a much smaller - :: dependency set than loading the entire %/mar directory. - :: - ++ load-marks-reachable-from - |= queued-nodes=(list load-node) - :: list of nodes in the graph that we've already checked - :: - =| visited=(set load-node) - :: graph of the available edges - :: - =| =edge-jug - :: compile-failures: mark files which didn't compile - :: - =| compile-failures=(map term tang) - :: - |- - ^- [[(unit ^edge-jug) _compile-failures] _out] - :: no ?~ to prevent tmi - :: - ?: =(~ queued-nodes) - [[`edge-jug compile-failures] out] - :: - =/ nodes-and-schematics - %+ turn queued-nodes - |= =load-node - ^- [^load-node schematic] - :- load-node - [%path disc %mar mark.load-node] - :: get the path for each mark name - :: - :: For %path builds, any ambiguous path is just filtered out. - :: - =^ maybe-path-results out - %- perform-schematics :* - ;: weld - "ford: %walk from " (trip source) " to " (trip target) - " contained failures:" - == - nodes-and-schematics - %filter-errors - *load-node - == - ?~ maybe-path-results - [[~ ~] out] - :: - =/ nodes-and-cores - %+ turn u.maybe-path-results - |= [=load-node =build-result] - ^- [^load-node schematic] - :: - ?> ?=([%success %path *] build-result) - :: - :- load-node - [%core rail.build-result] - :: - =^ maybe-core-results out - %- perform-schematics :* - ;: weld - "ford: %walk from " (trip source) " to " (trip target) - " contained failures:" - == - nodes-and-cores - %ignore-errors - *load-node - == - ?~ maybe-core-results - [[~ ~] out] - :: clear the queue before we process the new results - :: - =. queued-nodes ~ - :: - =/ cores u.maybe-core-results - :: - |- - ?~ cores - ^$ - :: mark this node as visited - :: - =. visited (~(put in visited) key.i.cores) - :: add core errors to compile failures - :: - =? compile-failures ?=([%error *] result.i.cores) - %+ ~(put by compile-failures) mark.key.i.cores - message.result.i.cores - :: - =/ target-arms=(list load-node) - ?. ?=([%success %core *] result.i.cores) - ~ - ?: =(%grow type.key.i.cores) - (get-arms-of-type %grow vase.result.i.cores) - (get-arms-of-type %grab vase.result.i.cores) - :: filter places we know we've already been. - :: - =. target-arms - %+ skip target-arms ~(has in visited) - =. queued-nodes (weld target-arms queued-nodes) - :: - =. edge-jug - |- - ?~ target-arms - edge-jug - :: - =. edge-jug - ?- type.i.target-arms - :: - %grab - (~(put ju edge-jug) mark.i.target-arms [mark.key.i.cores %grab]) - :: - %grow - (~(put ju edge-jug) mark.key.i.cores [mark.i.target-arms %grow]) - == - $(target-arms t.target-arms) - :: - $(cores t.cores) - :: - ++ get-arms-of-type - |= [type=?(%grab %grow) =vase] - ^- (list load-node) - :: it is valid for this node to not have a +grow arm. - :: - ?. (slob type p.vase) - ~ - :: - %+ turn - (sloe p:(slap vase [%limb type])) - |= arm=term - [type arm] - :: +find-path-through: breadth first search over the mark graph - :: - ++ find-path-through - |= edges=edge-jug - ^- mark-path - :: the source node starts out visited - =/ visited-nodes=(set mark) [source ~ ~] - :: these paths are flopped so we're always inserting to the front. - =| path-queue=(qeu mark-path) - :: start the queue with all the edges which start at the source mark - :: - =. path-queue - =/ start-links (find-links-in-edges edges source) - :: - |- - ^+ path-queue - ?~ start-links - path-queue - :: - =. path-queue (~(put to path-queue) [i.start-links]~) - :: - $(start-links t.start-links) - :: - |- - ^- mark-path - :: - ?: =(~ path-queue) - :: no path found - ~ - =^ current path-queue [p q]:~(get to path-queue) - ?> ?=(^ current) - :: - ?: =(target target.i.current) - :: we have a completed path. paths in the queue are backwards - (flop current) - :: - =+ next-steps=(find-links-in-edges edges target.i.current) - :: filter out already visited nodes - :: - =. next-steps - %+ skip next-steps - |= link=mark-action - (~(has in visited-nodes) source.link) - :: then add the new ones to the set of already visited nodes - :: - =. visited-nodes - (~(gas in visited-nodes) (turn next-steps |=(mark-action source))) - :: now all next steps go in the queue - :: - =. path-queue - %- ~(gas to path-queue) - %+ turn next-steps - |= new-link=mark-action - [new-link current] - :: - $ - :: +find-links-in-edges: gets edges usable by +find-path-through - :: - :: This deals with disambiguating between %grab and %grow so we always - :: pick %grab over %grow. - :: - ++ find-links-in-edges - |= [edges=edge-jug source=term] - ^- (list mark-action) - :: - =+ links=~(tap in (~(get ju edges) source)) - :: - =| results=(set mark-action) - |- - ^- (list mark-action) - ?~ links - ~(tap in results) - :: - ?- arm.i.links - %grab - :: if :results has a %grow entry, remove it before adding our %grab - =/ grow-entry=mark-action [%grow source target.i.links] - =? results (~(has in results) grow-entry) - (~(del in results) grow-entry) - :: - =. results (~(put in results) [%grab source target.i.links]) - $(links t.links) - :: - %grow - :: if :results has a %grab entry, don't add a %grow entry - ?: (~(has in results) [%grab source target.i.links]) - $(links t.links) - :: - =. results (~(put in results) [%grow source target.i.links]) - $(links t.links) - == - -- - :: |utilities:make: helper arms - :: - ::+| utilities - :: - :: +perform-schematics: helper function that performs a list of builds - :: - :: We often need to run a list of builds. This helper method will - :: depend on all :builds, will return a +build-receipt of either the - :: blocks or the first error, or a list of all completed results. - :: - :: This is a wet gate so individual callers can associate their own - :: key types with schematics. - :: - ++ perform-schematics - |* $: failure=tape - builds=(list [key=* =schematic]) - on-error=?(%fail-on-errors %filter-errors %ignore-errors) - key-bunt=* - == - ^- $: (unit (list [key=_key-bunt result=build-result])) - _out - == - :: - |^ =^ results out - =| results=(list [_key-bunt ^build (unit build-result)]) - |- - ^+ [results out] - :: - ?~ builds - [results out] - :: - =/ sub-build=^build [date.build schematic.i.builds] - =^ result out (depend-on sub-build) - =. results [[key.i.builds sub-build result] results] - :: - $(builds t.builds) - ?: =(%fail-on-errors on-error) - (check-errors results) - ?: =(%filter-errors on-error) - (filter-errors results) - (handle-rest results) - :: - ++ check-errors - |= results=(list [_key-bunt ^build (unit build-result)]) - :: - =/ braces [[' ' ' ' ~] ['{' ~] ['}' ~]] - =/ errors=(list tank) - %+ murn results - |= [* * result=(unit build-result)] - ^- (unit tank) - ?. ?=([~ %error *] result) - ~ - `[%rose braces message.u.result] - :: - ?^ errors - :- ~ - %- return-error - :- [%leaf failure] - errors - :: - (handle-rest results) - :: - ++ filter-errors - |= results=(list [_key-bunt ^build (unit build-result)]) - =. results - %+ skip results - |= [* * r=(unit build-result)] - ?=([~ %error *] r) - (handle-rest results) - :: - ++ handle-rest - |= results=(list [_key-bunt ^build (unit build-result)]) - :: if any sub-builds blocked, produce all blocked sub-builds - :: - =/ blocks=(list ^build) - %+ murn `(list [* ^build (unit build-result)])`results - |= [* sub=^build result=(unit build-result)] - ^- (unit ^build) - ?^ result - ~ - `sub - :: - ?^ blocks - [~ (return-blocks blocks)] - :: - :_ out - :- ~ - %+ turn results - |* [key=_key-bunt ^build result=(unit build-result)] - ^- [_key-bunt build-result] - [key (need result)] - -- - :: +wrap-error: wrap an error message around a failed sub-build - :: - ++ wrap-error - |= result=(unit build-result) - ^- build-receipt - :: - ?> ?=([~ %error *] result) - =/ message=tang - [[%leaf "ford: {<-.schematic.build>} failed: "] message.u.result] - :: - (return-error message) - :: +return-blocks: exit +make as a blocked build - :: - ++ return-blocks - |= builds=(list ^build) - ^- build-receipt - out(result [%blocks builds]) - :: +return-error: exit +make with a specific failure message - :: - ++ return-error - |= =tang - ^- build-receipt - out(result [%build-result %error tang]) - :: +return-result: exit +make with a completed build - :: - ++ return-result - |= =build-result - ^- build-receipt - out(result [%build-result build-result]) - :: - ++ access-cache - |= =compiler-cache-key - ^- [(unit build-result) _out] - :: - ?~ entry=(~(get by lookup.compiler-cache.state) compiler-cache-key) - [~ out(cache-access `[compiler-cache-key new=%.y])] - :: - [`val.u.entry out(cache-access `[compiler-cache-key new=%.n])] - :: - ++ depend-on - |= kid=^build - ^- [(unit build-result) _out] - :: - ?: =(kid build) - ~| [%depend-on-self (build-to-tape kid)] - !! - :: - =. sub-builds.out [kid sub-builds.out] - :: +access-build-record will mutate :results.state - :: - :: It's okay to ignore this because the accessed-builds get gathered - :: and merged during the +reduce step. - :: - =/ maybe-build-record -:(access-build-record kid) - ?~ maybe-build-record - [~ out] - :: - =* build-record u.maybe-build-record - ?: ?=(%tombstone -.build-record) - [~ out] - :: - [`build-result.build-record out] - :: +blocked-paths-to-receipt: handle the %2 case for mock - :: - :: Multiple schematics handle +toon instances. This handles the %2 case - :: for a +toon and transforms it into a +build-receipt so we depend on - :: the blocked paths correctly. - :: - ++ blocked-paths-to-receipt - |= [name=term blocked-paths=(list path)] - ^- build-receipt - :: - =/ blocks-or-failures=(list (each ^build tank)) - %+ turn blocked-paths - |= =path - :: - =/ scry-request=(unit scry-request) (path-to-scry-request path) - ?~ scry-request - [%| [%leaf "ford: {}: invalid scry path: {}"]] - :: - =* case r.beam.u.scry-request - :: - ?. ?=(%da -.case) - [%| [%leaf "ford: {}: invalid case in scry path: {}"]] - :: - =/ date=@da p.case - :: - =/ resource=(unit resource) (path-to-resource path) - ?~ resource - :- %| - [%leaf "ford: {}: invalid resource in scry path: {}"] - :: - =/ sub-schematic=schematic [%pin date %scry u.resource] - :: - [%& `^build`[date sub-schematic]] - :: - =/ failed=tang - %+ murn blocks-or-failures - |= block=(each ^build tank) - ^- (unit tank) - ?- -.block - %& ~ - %| `p.block - == - :: - ?^ failed - :: some failed - :: - out(result [%build-result %error failed]) - :: no failures - :: - =/ blocks=(list ^build) - %+ turn blocks-or-failures - |= block=(each ^build tank) - ?> ?=(%& -.block) - :: - p.block - :: - =. out - %+ roll blocks - |= [block=^build accumulator=_out] - =. out accumulator - +:(depend-on [date.block schematic.block]) - :: - (return-blocks blocks) - -- - :: |utilities:per-event: helper arms - :: - ::+| utilities - :: - :: +got-build: lookup :build in state, asserting presence - :: - ++ got-build - |= =build - ^- build-status - ~| [%ford-missing-build build=(build-to-tape build) duct=duct] - (~(got by builds.state) build) - :: +add-build: store a fresh, unstarted build in the state - :: - ++ add-build - ~/ %add-build - |= =build - ^+ state - :: don't overwrite an existing entry - :: - ?: (~(has by builds.state) build) - state - :: - %_ state - builds-by-schematic - (~(put by-schematic builds-by-schematic.state) build) - :: - builds - %+ ~(put by builds.state) build - =| =build-status - build-status(state [%untried ~]) - == - :: +remove-builds: remove builds and their sub-builds - :: - ++ remove-builds - ~/ %remove-builds - |= builds=(list build) - :: - |^ ^+ state - :: - ?~ builds - state - :: - ?~ maybe-build-status=(~(get by builds.state) i.builds) - $(builds t.builds) - =/ subs ~(tap in ~(key by subs.u.maybe-build-status)) - :: - =^ removed state (remove-single-build i.builds u.maybe-build-status) - ?. removed - $(builds t.builds) - :: - $(builds (welp t.builds subs)) - :: +remove-build: stop storing :build in the state - :: - :: Removes all linkages to and from sub-builds - :: - ++ remove-single-build - |= [=build =build-status] - ^+ [removed=| state] - :: never delete a build that something depends on - :: - ?^ clients.build-status - [removed=| state] - ?^ requesters.build-status - [removed=| state] - :: nothing depends on :build, so we'll remove it - :: - :- removed=& - :: - %_ state - builds-by-schematic - (~(del by-schematic builds-by-schematic.state) build) - :: - builds - (~(del by builds.state) build) - == - -- - :: +update-build-status: replace :build's +build-status by running a function - :: - ++ update-build-status - ~/ %update-build-status - |= [=build update-func=$-(build-status build-status)] - ^- [build-status builds=_builds.state] - :: - =/ original=build-status (got-build build) - =/ mutant=build-status (update-func original) - :: - [mutant (~(put by builds.state) build mutant)] - :: +intercepted-scry: augment real scry with local %scry build results - :: - :: Try to deduplicate requests for possibly remote resources by looking up - :: the result in local state if the real scry has no synchronous - :: answer (it produced `~`). - :: - ++ intercepted-scry - %- sloy ^- slyd - ~/ %intercepted-scry - |= [ref=* (unit (set monk)) =term =beam] - ^- (unit (unit (cask meta))) - :: if the actual scry produces a value, use that value; otherwise use local - :: - =/ scry-response (scry +<.$) - :: - ?^ scry-response - scry-response - :: - =/ vane=(unit %c) ((soft ,%c) (end 3 1 term)) - ?~ vane - ~ - =/ care=(unit care:clay) ((soft care:clay) (rsh 3 1 term)) - ?~ care - ~ - ?. ?=(%da -.r.beam) - ~ - =/ =resource [u.vane u.care rail=[[p.beam q.beam] s.beam]] - =/ =build [date=p.r.beam %scry resource] - :: look up the scry result from our permanent state - :: - :: Note: we can't freshen :build's :last-accessed date because - :: we can't mutate :state from this gate. %scry results might get - :: deleted during %wipe more quickly than they should because of this. - :: - =/ local-result -:(access-build-record build) - ?~ local-result - ~ - ?: ?=(%tombstone -.u.local-result) - ~ - :: - =/ local-cage=cage (result-to-cage build-result.u.local-result) - :: if :local-result does not nest in :type, produce an error - :: - ?. -:(nets:wa +.ref `type`p.q.local-cage) - [~ ~] - :: - [~ ~ local-cage] - :: +unblock-clients-on-duct: unblock and produce clients blocked on :build - :: - ++ unblock-clients-on-duct - =| unblocked=(list build) - ~% %unblock-clients-on-duct +>+ ~ - |= =build - ^+ [unblocked builds.state] - :: - =/ =build-status (got-build build) - :: - =/ clients=(list ^build) ~(tap in (~(get ju clients.build-status) [%duct duct])) - :: - |- - ^+ [unblocked builds.state] - ?~ clients - [unblocked builds.state] - :: - =^ client-status builds.state - %+ update-build-status i.clients - |= client-status=^build-status - :: - =. subs.client-status - %+ ~(jab by subs.client-status) build - |= original=build-relation - original(blocked |) - :: - =? state.client-status - ?& ?=(%blocked -.state.client-status) - :: - ?! - %- ~(any by subs.client-status) - |=(build-relation &(blocked verified)) - == - :: - [%unblocked ~] - client-status - :: - =? unblocked !?=(%blocked -.state.client-status) - [i.clients unblocked] - :: - $(clients t.clients) - :: +on-build-complete: handles completion of any build - :: - ++ on-build-complete - ~/ %on-build-complete - |= =build - ^+ ..execute - :: - =. ..execute (cleanup-orphaned-provisional-builds build) - :: - =/ duct-status (~(got by ducts.state) duct) - :: - =/ =build-status (got-build build) - ?: (~(has in requesters.build-status) [%duct duct]) - (on-root-build-complete build) - :: - =^ unblocked-clients builds.state (unblock-clients-on-duct build) - =. candidate-builds (~(gas in candidate-builds) unblocked-clients) - :: - ..execute - :: +on-root-build-complete: handle completion or promotion of a root build - :: - :: When a build completes for a duct, we might have to send a %made move - :: on the requesting duct and also do duct and build book-keeping. - :: - ++ on-root-build-complete - ~/ %on-root-build-complete - |= =build - ^+ ..execute - :: - =; res=_..execute - =/ duct-status=(unit duct-status) - (~(get by ducts.state.res) duct) - ?~ duct-status res - :: debugging assertions to try to track down failure in - :: +copy-build-tree-as-provisional - :: - ~| [%failed-to-preserve-live-build (build-to-tape build)] - ?> ?=(%live -.live.u.duct-status) - ~| %failed-2 - ?> ?=(^ last-sent.live.u.duct-status) - ~| %failed-3 - ?> .= build - [date.u.last-sent.live.u.duct-status root-schematic.u.duct-status] - ~| %failed-4 - ?> (~(has by builds.state.res) build) - :: - res - :: - =/ =build-status (got-build build) - =/ =duct-status (~(got by ducts.state) duct) - :: make sure we have something to send - :: - ?> ?=([%complete %value *] state.build-status) - :: send a %made move unless it's an unchanged live build - :: - =? moves - ?! - ?& ?=(%live -.live.duct-status) - ?=(^ last-sent.live.duct-status) - :: - =/ last-build-status - %- ~(got by builds.state) - [date.u.last-sent.live.duct-status schematic.build] - :: - ?> ?=(%complete -.state.last-build-status) - ?& ?=(%value -.build-record.state.last-build-status) - :: - .= build-result.build-record.state.last-build-status - build-result.build-record.state.build-status - == == - :_ moves - ^- move - :: - :* duct %give %made date.build %complete - build-result.build-record.state.build-status - == - :: - ?- -.live.duct-status - %once - =. ducts.state (~(del by ducts.state) duct) - =. state (move-root-to-cache build) - :: - ..execute - :: - %live - :: clean up previous build - :: - =? state ?=(^ last-sent.live.duct-status) - =/ old-build=^build build(date date.u.last-sent.live.duct-status) - ~? =(date.build date.old-build) - :+ "old and new builds have same date, will probably crash!" - (build-to-tape build) - (build-to-tape old-build) - :: - (remove-anchor-from-root old-build [%duct duct]) - :: - =/ resource-list=(list [=disc resources=(set resource)]) - ~(tap by (collect-live-resources build)) - :: we can only handle a single subscription - :: - :: In the long term, we need Clay's interface to change so we can - :: subscribe to multiple desks at the same time. - :: - ?: (lth 1 (lent resource-list)) - =. ..execute - %+ send-incomplete build :~ - [%leaf "root build {(build-to-tape build)}"] - [%leaf "on duct:"] - [%leaf "{}"] - [%leaf "tried to subscribe to multiple discs:"] - [%leaf "{}"] - == - :: delete this instead of caching it, since it wasn't right - :: - =. ducts.state (~(del by ducts.state) duct) - =. state (remove-anchor-from-root build [%duct duct]) - ..execute - :: - =/ subscription=(unit subscription) - ?~ resource-list - ~ - `[date.build disc.i.resource-list resources.i.resource-list] - :: - =? ..execute ?=(^ subscription) - (start-clay-subscription u.subscription) - :: - =. ducts.state - %+ ~(put by ducts.state) duct - %_ duct-status - live - [%live in-progress=~ last-sent=`[date.build subscription]] - == - :: - ..execute - == - :: +send-incomplete: emit a move indicating we can't complete :build - :: - ++ send-incomplete - |= [=build message=tang] - ^+ ..execute - :: - =. moves - :_ moves - `move`[duct %give %made date.build %incomplete message] - :: - ..execute - :: +cleanup-orphaned-provisional-builds: delete extraneous sub-builds - :: - :: Remove unverified linkages to sub builds. If a sub-build has no other - :: clients on this duct, then it is orphaned and we remove the duct from - :: its subs and call +cleanup on it. - :: - ++ cleanup-orphaned-provisional-builds - ~/ %cleanup-orphaned-provisional-builds - |= =build - ^+ ..execute - :: - =/ =build-status (got-build build) - :: - =/ orphans=(list ^build) - %+ murn ~(tap by subs.build-status) - |= [sub=^build =build-relation] - ^- (unit ^build) - :: - ?: verified.build-relation - ~ - `sub - :: dequeue orphans in case we were about to run them - :: - =/ orphan-set (~(gas in *(set ^build)) orphans) - =. next-builds (~(dif in next-builds) orphan-set) - =. candidate-builds (~(dif in candidate-builds) orphan-set) - :: remove links to orphans in :build's +build-status - :: - =^ build-status builds.state - %+ update-build-status build - |= build-status=^build-status - %_ build-status - subs - :: - |- ^+ subs.build-status - ?~ orphans subs.build-status - :: - =. subs.build-status (~(del by subs.build-status) i.orphans) - :: - $(orphans t.orphans) - == - :: - =/ =anchor [%duct duct] - :: - |- ^+ ..execute - ?~ orphans ..execute - :: remove link to :build in :i.orphan's +build-status - :: - =^ orphan-status builds.state - %+ update-build-status i.orphans - |= orphan-status=_build-status - %_ orphan-status - clients (~(del ju clients.orphan-status) anchor build) - == - :: - ?: (~(has by clients.orphan-status) anchor) - $(orphans t.orphans) - :: :build was the last client on this duct so remove it - :: - =. builds.state (remove-anchor-from-subs i.orphans anchor) - =. state (cleanup i.orphans) - $(orphans t.orphans) - :: +access-build-record: access a +build-record, updating :last-accessed - :: - :: Usage: - :: ``` - :: =^ maybe-build-record builds.state (access-build-record build) - :: ``` - :: - ++ access-build-record - ~/ %access-build-record - |= =build - ^- [(unit build-record) _builds.state] - :: - ?~ maybe-build-status=(~(get by builds.state) build) - [~ builds.state] - :: - =/ =build-status u.maybe-build-status - :: - ?. ?=(%complete -.state.build-status) - [~ builds.state] - :: - ?: ?=(%tombstone -.build-record.state.build-status) - [`build-record.state.build-status builds.state] - :: - =. last-accessed.build-record.state.build-status now - :: - :- `build-record.state.build-status - (~(put by builds.state) build build-status) - :: +cleanup: try to clean up a build and its sub-builds - :: - ++ cleanup - ~/ %cleanup - |= =build - ^+ state - :: does this build even exist?! - :: - ?~ maybe-build-status=(~(get by builds.state) build) - state - :: - =/ =build-status u.maybe-build-status - :: never delete a build that something depends on - :: - ?^ clients.build-status - state - ?^ requesters.build-status - state - :: - (remove-builds ~[build]) - :: +collect-live-resources: produces all live resources from sub-scrys - :: - ++ collect-live-resources - ~/ %collect-live-resources - |= =build - ^- (jug disc resource) - :: - ?: ?=(%scry -.schematic.build) - =* resource resource.schematic.build - (my [(extract-disc resource) (sy [resource]~)]~) - :: - ?: ?=(%pin -.schematic.build) - ~ - :: - =/ subs ~(tap in ~(key by subs:(got-build build))) - =| resources=(jug disc resource) - |- - ?~ subs - resources - :: - =/ sub-resources=(jug disc resource) ^$(build i.subs) - =. resources (unify-jugs resources sub-resources) - $(subs t.subs) - :: +collect-blocked-resources: produces all blocked resources from sub-scrys - :: - ++ collect-blocked-sub-scrys - ~/ %collect-blocked-sub-scrys - |= =build - ^- (set scry-request) - :: - ?: ?=(%scry -.schematic.build) - =, resource.schematic.build - =/ =scry-request - :+ vane care - ^- beam - [[ship.disc.rail desk.disc.rail [%da date.build]] spur.rail] - (sy [scry-request ~]) - :: only recurse on blocked sub-builds - :: - =/ subs=(list ^build) - %+ murn ~(tap by subs:(got-build build)) - |= [sub=^build =build-relation] - ^- (unit ^build) - :: - ?. blocked.build-relation - ~ - `sub - :: - =| scrys=(set scry-request) - |- - ^+ scrys - ?~ subs - scrys - :: - =. scrys (~(uni in scrys) ^$(build i.subs)) - $(subs t.subs) - :: +start-clay-subscription: listen for changes in the filesystem - :: - ++ start-clay-subscription - ~/ %start-clay-subscription - |= =subscription - ^+ ..execute - :: - =/ already-subscribed=? - (~(has by pending-subscriptions.state) subscription) - :: - =. pending-subscriptions.state - (put-request pending-subscriptions.state subscription duct) - :: don't send a duplicate move if we're already subscribed - :: - ?: already-subscribed - ..execute - :: - =/ =wire (clay-subscription-wire [date disc]:subscription) - :: - =/ =note - :: request-contents: the set of [care path]s to subscribe to in clay - :: - =/ request-contents=(set [care:clay path]) - %- sy ^- (list [care:clay path]) - %+ murn ~(tap in `(set resource)`resources.subscription) - |= =resource ^- (unit [care:clay path]) - :: - `[care.resource (flop spur.rail.resource)] - :: if :request-contents is `~`, this code is incorrect - :: - ?< ?=(~ request-contents) - :: their: requestee +ship - :: - =+ [their desk]=disc.subscription - :: - :^ %c %warp ship=their - ^- riff:clay - [desk `[%mult `case`[%da date.subscription] request-contents]] - :: - =. moves [`move`[duct [%pass wire note]] moves] - :: - ..execute - :: +cancel-clay-subscription: remove a subscription on :duct - :: - ++ cancel-clay-subscription - ~/ %cancel-clay-subscription - |= =subscription - ^+ ..execute - :: - =^ originator pending-subscriptions.state - (del-request pending-subscriptions.state subscription duct) - :: if there are still other ducts on this subscription, don't send a move - :: - ?~ originator - ..execute - :: - =/ =wire (clay-subscription-wire [date disc]:subscription) - :: - =/ =note - =+ [their desk]=disc.subscription - [%c %warp ship=their `riff:clay`[desk ~]] - :: - =. moves [`move`[u.originator [%pass wire note]] moves] - :: - ..execute - :: +clay-sub-wire: the wire to use for a clay subscription - :: - :: While it is possible for two different root builds to make - :: subscriptions with the same wire, those wires will always be associated - :: with different ducts, so there's no risk of duplicates. - :: - ++ clay-subscription-wire - |= [date=@da =disc] - ^- wire - :: - =+ [their desk]=disc - :: - /clay-sub/(scot %p their)/[desk]/(scot %da date) - :: +start-scry-request: kick off an asynchronous request for a resource - :: - ++ start-scry-request - |= =scry-request - ^+ ..execute - :: if we are the first block depending on this scry, send a move - :: - =/ already-started=? (~(has by pending-scrys.state) scry-request) - :: - =. pending-scrys.state - (put-request pending-scrys.state scry-request duct) - :: don't send a duplicate move if we've already sent one - :: - ?: already-started - ..execute - :: - =/ =wire (scry-request-wire scry-request) - :: - =/ =note - =, scry-request - =/ =disc [p q]:beam - :* %c %warp their=ship.disc desk.disc - `[%sing care case=r.beam (flop s.beam)] - == - :: - =. moves [`move`[duct [%pass wire note]] moves] - :: - ..execute - :: +cancel-scry-request: cancel a pending asynchronous scry request - :: - ++ cancel-scry-request - |= =scry-request - ^+ ..execute - :: - =^ originator pending-scrys.state - (del-request pending-scrys.state scry-request duct) - :: if there are still other ducts on this subscription, don't send a move - :: - ?~ originator - ..execute - :: - =/ =wire (scry-request-wire scry-request) - :: - =/ =note - =+ [their desk]=[p q]:beam.scry-request - [%c %warp ship=their `riff:clay`[desk ~]] - :: - =. moves [`move`[u.originator [%pass wire note]] moves] - :: - ..execute - :: +scry-request-wire - :: - ++ scry-request-wire - |= =scry-request - ^- wire - (welp /scry-request (scry-request-to-path scry-request)) - -- --- -:: -:: end the =~ -:: -. == -:: -:::: vane interface - :: -:: begin with a default +axle as a blank slate -:: -=| ax=axle -:: a vane is activated with identity, the current date, entropy, -:: and a namespace function -:: -|= [our=ship now=@da eny=@uvJ scry-gate=sley] -=* ford-gate . -:: allow jets to be registered within this core -:: -~% %ford ..is ~ -|% -:: +call: handle a +task:able from arvo -:: -:: Ford can be tasked with: -:: -:: %build: perform a build -:: %keep: resize caches -:: %kill: cancel a build -:: %wipe: clear memory -:: -:: Most requests get converted into operations to be performed inside -:: the +per-event core, which is Ford's main build engine. -:: -++ call - |= [=duct dud=(unit goof) type=* wrapped-task=(hobo task:able)] - ^- [(list move) _ford-gate] - ?^ dud - ~|(%ford-call-dud (mean tang.u.dud)) - :: - =/ task=task:able ((harden task:able) wrapped-task) - :: we wrap +per-event with a call that binds our event args - :: - =* this-event (per-event [our duct now scry-gate] state.ax) - :: - ?- -.task - :: %build: request to perform a build - :: - %build - :: perform the build indicated by :task - :: - :: We call :start-build on :this-event, which is the |per-event core - :: with the our event-args already bound. :start-build performs the - :: build and produces a pair of :moves and a mutant :state. - :: We update our :state and produce it along with :moves. - :: - =/ =build [now schematic.task] - =^ moves state.ax (start-build:this-event build live.task) - :: - [moves ford-gate] - :: - :: %keep: keep :count cache entries - :: - %keep - :: - =. state.ax (keep:this-event [compiler-cache build-cache]:task) - :: - [~ ford-gate] - :: - :: %kill: cancel a %build - :: - %kill - :: - =^ moves state.ax cancel:this-event - :: - [moves ford-gate] - :: - :: %trim: in response to memory pressure - :: - %trim - :: - ?. =(0 p.task) - :: low-priority: remove 50% of cache/stored-builds - :: - ~> %slog.[0 leaf+"ford: trim: pruning caches"] - =. state.ax (wipe:this-event 50) - [~ ford-gate] - :: - :: high-priority: remove 100% of cache/stored-builds - :: - :: We use %keep to ensure that cache-keys are also purged, - :: then restore original limits to allow future caching. - :: - :: XX cancel in-progress builds? - :: - ~> %slog.[0 leaf+"ford: trim: clearing caches"] - =/ b-max max-size.queue.build-cache.state.ax - =/ c-max max-size.compiler-cache.state.ax - =. state.ax (keep:this-event 0 0) - =. state.ax (keep:this-event c-max b-max) - [~ ford-gate] - :: - :: %vega: learn of kernel upgrade - :: - :: XX clear cache, rebuild live builds - :: - %vega - :: - [~ ford-gate] - :: - :: %wipe: wipe stored builds, clearing :percent-to-remove of the entries - :: - %wipe - :: - =. state.ax (wipe:this-event percent-to-remove.task) - :: - [~ ford-gate] - :: - %wegh - :_ ford-gate - :_ ~ - :^ duct %give %mass - ^- mass - :+ %ford %| - :~ builds+&+builds.state.ax - compiler-cache+&+compiler-cache.state.ax - dot+&+ax - == - == -:: +take: receive a response from another vane -:: -:: A +take is a response to a request that Ford made of another vane. -:: -:: Ford decodes the type of response based on the +wire in the +take. -:: The possibilities are: -:: -:: %clay-sub: Clay notification of an update to a subscription -:: -:: If Ford receives this, it will rebuild one or more live builds, -:: taking into account the new date and changed resources. -:: -:: %scry-request: Clay response to a request for a resource -:: -:: If Ford receives this, it will continue building one or more builds -:: that were blocked on this resource. -:: -:: The +sign gets converted into operations to be performed inside -:: the +per-event core, which is Ford's main build engine. -:: -++ take - |= [=wire =duct dud=(unit goof) wrapped-sign=(hypo sign)] - ^- [(list move) _ford-gate] - ?^ dud - ~|(%ford-take-dud (mean tang.u.dud)) - :: unwrap :sign, ignoring unneeded +type in :p.wrapped-sign - :: - =/ =sign q.wrapped-sign - :: :wire must at least contain a tag for dispatching - :: - ?> ?=([@ *] wire) - :: - |^ ^- [(list move) _ford-gate] - :: - =^ moves state.ax - ?+ i.wire ~|([%bad-take-wire wire] !!) - %clay-sub take-rebuilds - %scry-request take-unblocks - == - :: - [moves ford-gate] - :: +take-rebuilds: rebuild all live builds affected by the Clay changes - :: - ++ take-rebuilds - ^- [(list move) ford-state] - :: - ~| [%ford-take-rebuilds wire=wire duct=duct] - ?> ?=([@tas %wris *] sign) - =* case-sign p.sign - =* care-paths-sign q.sign - =+ [ship desk date]=(raid:wired t.wire ~[%p %tas %da]) - =/ disc [ship desk] - :: ignore spurious clay updates - :: - :: Due to asynchronicity of Clay notifications, we might get a - :: subscription update on an already-canceled duct. This is - :: normal; no-op. - :: - ?~ duct-status=(~(get by ducts.state.ax) duct) - [~ state.ax] - :: - =/ =subscription - ?> ?=(%live -.live.u.duct-status) - (need subscription:(need last-sent.live.u.duct-status)) - :: - =/ ducts=(list ^duct) - :: sanity check; there must be at least one duct per subscription - :: - =- ?<(=(~ -) -) - (get-request-ducts pending-subscriptions.state.ax subscription) - :: - =| moves=(list move) - |- ^+ [moves state.ax] - ?~ ducts [moves state.ax] - :: - =* event-args [[our i.ducts now scry-gate] state.ax] - =* rebuild rebuild:(per-event event-args) - =^ duct-moves state.ax - (rebuild subscription p.case-sign disc care-paths-sign) - :: - $(ducts t.ducts, moves (weld moves duct-moves)) - :: +take-unblocks: unblock all builds waiting on this scry request - :: - ++ take-unblocks - ^- [(list move) ford-state] - :: - ~| [%ford-take-unblocks wire=wire duct=duct] - ?> ?=([@tas %writ *] sign) - =* riot-sign p.sign - :: scry-request: the +scry-request we had previously blocked on - :: - =/ =scry-request (need (path-to-scry-request t.wire)) - :: scry-result: parse a (unit cage) from :sign - :: - :: If the result is `~`, the requested resource was not available. - :: - =/ scry-result=(unit cage) - ?~ riot-sign - ~ - `r.u.riot-sign - :: if spurious Clay response, :ducts will be empty, causing no-op - :: - =/ ducts=(list ^duct) - (get-request-ducts pending-scrys.state.ax scry-request) - :: - =| moves=(list move) - |- ^+ [moves state.ax] - ?~ ducts [moves state.ax] - :: - =* event-args [[our i.ducts now scry-gate] state.ax] - :: unblock the builds that had blocked on :resource - :: - =* unblock unblock:(per-event event-args) - =^ duct-moves state.ax (unblock scry-request scry-result) - :: - $(ducts t.ducts, moves (weld moves duct-moves)) - -- -:: +load: either flush or migrate old state (called on vane reload) -:: -:: If it has the old state version, flush the ford state. Otherwise trim -:: build results in case a change to our code invalidated an old build -:: result. -:: -:: Flushing state of the old version is a temporary measure for the OS1 -:: %publish update. We can flush all build state like this because only gall -:: and %publish use ford live builds currently. :goad will handle remaking -:: builds for gall, and the new %publish does not use ford. -:: -++ load - |= old=axle - ^+ ford-gate - ?: =(%~2018.12.13 -.old) - =. -.ax %~2020.2.21 - ford-gate - =. ax [%~2020.2.21 state.old] - =. ford-gate +:(call ~[/ford-load-self] ~ *type %trim 0) - ford-gate -:: +stay: produce current state -:: -++ stay `axle`ax -:: +scry: request a path in the urbit namespace -:: -++ scry - |= * - [~ ~] +++ call |=(* ((slog leaf+"ford: gone (+call)" ~) `..^$)) +++ take |=(* ((slog leaf+"ford: gone (+take)" ~) `..^$)) +++ scry |=(* ``mass+!>(*(list mass))) +++ stay ~ +++ load |=(* ..^$) -- diff --git a/pkg/arvo/sys/vane/gall.hoon b/pkg/arvo/sys/vane/gall.hoon index 65d8921f11..451d2e5eed 100644 --- a/pkg/arvo/sys/vane/gall.hoon +++ b/pkg/arvo/sys/vane/gall.hoon @@ -1,169 +1,326 @@ -!: :: %gall, agent execution +:: :: %gall, agent execution !? 163 -!: +:: :::: |= pit=vase =, gall -=> =~ +=> |% -:: +ames-response: network response message (%boon) ++| %main +:: +:: $move: Arvo-level move +:: ++$ move [=duct move=(wind note-arvo gift-arvo)] +:: $state-6: overall gall state, versioned +:: ++$ state-6 [%6 state] +:: $state: overall gall state +:: +:: system-duct: TODO document +:: outstanding: outstanding request queue +:: contacts: other ships we're in communication with +:: yokes: running agents +:: blocked: moves to agents that haven't been started yet +:: ++$ state + $: system-duct=duct + outstanding=(map [wire duct] (qeu remote-request)) + contacts=(set ship) + yokes=(map term yoke) + blocked=(map term (qeu blocked-move)) + == +:: $watches: subscribers and publications +:: +:: TODO: rename this, to $ties? +:: TODO: rename $boat and $bitt and document +:: ++$ watches [inbound=bitt outbound=boat] +:: $routes: new cuff; TODO: document +:: ++$ routes + $: disclosing=(unit (set ship)) + attributing=ship + == +:: $yoke: agent runner state +:: +:: control-duct: TODO document +:: live: is this agent running? TODO document better +:: stats: TODO document +:: watches: incoming and outgoing subscription state +:: agent: agent core +:: beak: compilation source +:: marks: mark conversion requests +:: ++$ yoke + $: control-duct=duct + live=? + =stats + =watches + =agent + =beak + marks=(map duct mark) + == +:: $blocked-move: enqueued move to an agent +:: ++$ blocked-move [=duct =routes =deal] +:: $stats: statistics +:: +:: change: how many moves this agent has processed +:: eny: entropy +:: time: date of current event processing +:: ++$ stats [change=@ud eny=@uvJ time=@da] +:: $ames-response: network response message (%boon) :: :: %d: fact :: %x: quit :: -++ ames-response ++$ ames-response $% [%d =mark noun=*] [%x ~] == -:: +ames-request: network request (%plea) +:: $ames-request: network request (%plea) :: :: %m: poke :: %l: watch-as :: %s: watch :: %u: leave :: -++ ames-request ++$ ames-request $% [%m =mark noun=*] [%l =mark =path] [%s =path] [%u ~] == -:: +remote-request: kinds of agent actions that can cross the network +:: $remote-request: kinds of agent actions that can cross the network :: :: Used in wires to identify the kind of remote request we made. :: Bijective with the tags of $ames-request. :: -++ remote-request ++$ remote-request $? %watch %watch-as %poke %leave %missing == --- -|% -:: +move: Arvo-level move +:: |migrate: data structures for upgrades :: -++ move - $: =duct - move=(wind note-arvo gift-arvo) - == --- -|% -:: +state: all state ++| %migrate :: -++ state - $: :: state version - :: - %5 - :: agents by ship - :: - =agents - == -:: +subscribers: subscriber data +:: $spore: structures for update, produced by +stay :: -++ subscribers - $: :: incoming subscribers - :: - incoming=bitt - :: outgoing subscribers - :: - outgoing=boat - == -:: +agents: ship state -:: -++ agents - $: :: system duct - :: ++$ spore + $: %6 system-duct=duct - :: outstanding request queue - :: outstanding=(map [wire duct] (qeu remote-request)) - :: foreign contacts - :: contacts=(set ship) - :: running agents - :: - running=(map term running-agent) - :: waiting queue - :: - blocked=(map term blocked) + eggs=(map term egg) + blocked=(map term (qeu blocked-move)) == -:: +routes: new cuff +:: $egg: migratory agent state; $yoke with .old-state instead of .agent :: -++ routes - $: :: disclosing to - :: - disclosing=(unit (set ship)) - :: attributed to - :: - attributing=ship - == -:: +running-agent: agent state -:: -++ running-agent - $: :: cache - :: - cache=worm - :: control duct - :: - control-duct=duct - :: unstopped - :: ++$ egg + $: control-duct=duct live=? - :: statistics - :: =stats - :: subscribers - :: - =subscribers - :: agent core - :: - =agent - :: update control - :: + =watches + old-state=vase =beak - :: req'd translations - :: marks=(map duct mark) == -:: +blocked: blocked tasks -:: -++ blocked (qeu (trel duct routes deal)) -:: +stats: statistics -:: -++ stats - $: :: change number - :: - change=@ud - :: entropy - :: - eny=@uvJ - :: time - :: - time=@da - == -- -. == -=| =state -|= $: :: identity +:: pupal gall core, on upgrade +:: +=< =* adult-gate . + =| =spore + |= [our=ship now=@da eny=@uvJ ski=sley] + =* pupal-gate . + =* adult-core (adult-gate +<) + =< |% + ++ call ^call + ++ load ^load + ++ scry ^scry + ++ stay ^stay + ++ take ^take + -- + |% + ++ molt + |= [=duct fec=(unit move)] + ^- [(list move) _adult-gate] + ~> %slog.[0 leaf+"gall: molting"] + ~< %slog.[0 leaf+"gall: molted"] + :: +molt should never notify its client about agent changes + :: + =- [(skip -< |=(move ?=([* %give %onto *] +<))) ->] + =/ adult adult-core + =. state.adult + [%6 system-duct outstanding contacts yokes=~ blocked]:spore + =/ mo-core (mo-abed:mo:adult duct) + =. mo-core + =/ apps=(list [dap=term =egg]) ~(tap by eggs.spore) + |- ^+ mo-core + ?~ apps mo-core + ~> %slog.[0 leaf+"gall: upgrading {}"] + =/ ap-core (ap-abut:ap:mo-core i.apps) + =^ tan ap-core (ap-install:ap-core `old-state.egg.i.apps) + ?^ tan + (mean u.tan) + $(apps t.apps, mo-core ap-abet:ap-core) + =. mo-core (mo-subscribe-to-agent-builds:mo-core now) + =^ moves adult-gate mo-abet:mo-core + =? moves ?=(^ fec) (weld moves [u.fec]~) + [moves adult-gate] + :: + ++ call + |= [=duct dud=(unit goof) typ=type wrapped-task=(hobo task:able)] + =* call-args +< + ?: =(~ eggs.spore) + ~> %slog.[0 leaf+"gall: direct morphogenesis"] + =. state.adult-gate spore(eggs *(map term yoke)) + (call:adult-core call-args) + ?^ dud + ~> %slog.[0 leaf+"gall: pupa call dud"] + (mean >mote.u.dud< tang.u.dud) + =/ task ((harden task:able:gall) wrapped-task) + (molt duct `[duct %slip %g task]) + :: + ++ scry scry:adult-core + ++ stay ~|(%gall-subinvolution !!) + ++ take + |= [=wire =duct dud=(unit goof) typ=type sign=sign-arvo] + =* take-args +< + ?: =(~ eggs.spore) + ~> %slog.[0 leaf+"gall: direct morphogenesis"] + =. state.adult-gate spore(eggs *(map term yoke)) + (take:adult-core take-args) + ?^ dud + ~> %slog.[0 leaf+"gall: pupa take dud"] + (mean >mote.u.dud< tang.u.dud) + ?: =(/sys/lyv wire) + (molt duct ~) + :: TODO: test this or remove and assert /sys/lyv + :: + (molt duct `[duct %pass wire %b %huck !>(sign)]) + :: + ++ load + |^ + |= old=all-state + =. spore (upgrade old) + ?. =(~ eggs.spore) + pupal-gate + ~> %slog.[0 leaf+"gall: direct morphogenesis"] + adult-gate(state spore(eggs *(map term yoke))) + :: + ++ upgrade + |= =all-state + ^- ^spore :: - our=ship - :: urban time + =? all-state ?=(%0 -.all-state) + (state-0-to-1 all-state) :: - now=@da - :: entropy + =? all-state ?=(%1 -.all-state) + (state-1-to-2 all-state) :: - eny=@uvJ - :: activate + =? all-state ?=(%2 -.all-state) + (state-2-to-3 all-state) :: - ski=sley - == + =? all-state ?=(%3 -.all-state) + (state-3-to-4 all-state) + :: + =? all-state ?=(%4 -.all-state) + (state-4-to-5 all-state) + :: + =? all-state ?=(%5 -.all-state) + (state-5-to-spore-6 all-state) + :: + ?> ?=(%6 -.all-state) + all-state + :: +all-state: upgrade path + :: + +$ all-state $%(state-0 state-1 state-2 state-3 state-4 state-5 ^spore) + :: + ++ state-5-to-spore-6 + |= s=state-5 + ^- ^spore + %= s + - %6 + outstanding ~ :: TODO: do we need to process these somehow? + running + (~(run by running.s) |=(y=yoke-0 +:y(agent on-save:agent.y))) + == + :: + ++ state-4-to-5 |=(s=state-4 `state-5`s(- %5, outstanding ~)) + ++ state-3-to-4 |=(s=state-3 `state-4`s(- %4, outstanding ~)) + ++ state-2-to-3 |=(s=state-2 `state-3`s(- %3)) + ++ state-1-to-2 |=(s=state-1 `state-2`s(- %2, +< +<.s, +> `+>.s)) + ++ state-0-to-1 |=(s=state-0 `state-1`s(- %1)) + :: + +$ state-5 [%5 agents-2] + +$ state-4 [%4 agents-2] + +$ state-3 [%3 agents-2] + +$ state-2 [%2 agents-2] + +$ state-1 [%1 agents-0] + +$ state-0 [%0 agents-0] + :: + +$ agents-2 + $: system-duct=duct + outstanding=(map [wire duct] (qeu remote-request)) + contacts=(set ship) + running=(map term yoke-0) + blocked=(map term (qeu blocked-move)) + == + :: + +$ agents-0 + $: system-duct=duct + contacts=(set ship) + running=(map term yoke-0) + blocked=(map term (qeu blocked-move)) + == + :: + +$ yoke-0 + $: cache=worm + control-duct=duct + live=? + =stats + =watches + agent=any-agent + =beak + marks=(map duct mark) + == + :: + ++ any-agent + $_ + ^| + |_ bowl + ++ on-init ** + ++ on-save *vase + ++ on-load ** + ++ on-poke ** + ++ on-watch ** + ++ on-leave ** + ++ on-peek ** + ++ on-agent ** + ++ on-arvo ** + ++ on-fail ** + -- + -- + -- +:: adult gall vane interface, for type compatibility with pupa +:: +=| state=state-6 +|= [our=ship now=@da eny=@uvJ ski=sley] +=* gall-payload . +=< ~% %gall-wrap ..mo ~ + |% + ++ call ^call + ++ load ^load + ++ scry ^scry + ++ stay ^stay + ++ take ^take + -- ~% %gall-top ..is ~ |% -:: +gall-payload: gall payload -:: -++ gall-payload + :: +mo: Arvo-level move handling :: :: An outer core responsible for routing moves to and from Arvo; it calls @@ -171,101 +328,45 @@ :: ++ mo ~% %gall-mo +> ~ - |_ - $: hen=duct - moves=(list move) - == + |_ [hen=duct moves=(list move)] + :: +mo-abed: initialise state with the provided duct + :: +mo-abet: finalize, reversing moves + :: +mo-pass: prepend a standard %pass to the current list of moves + :: +mo-give: prepend a standard %give to the current list of moves + :: ++ mo-core . - :: +mo-abed: initialise state with the provided duct. - :: - ++ mo-abed - |= =duct - ^+ mo-core - :: - mo-core(hen duct) - :: +mo-abet: resolve moves. - :: - ++ mo-abet - ^- [(list move) _gall-payload] - :: - =/ resolved (flop moves) - [resolved gall-payload] - :: + ++ mo-abed |=(hun=duct mo-core(hen hun)) + ++ mo-abet [(flop moves) gall-payload] + ++ mo-pass |=(p=[wire note-arvo] mo-core(moves [[hen pass+p] moves])) + ++ mo-give |=(g=gift:able mo-core(moves [[hen give+g] moves])) :: +mo-boot: ask %ford to build us a core for the specified agent. :: ++ mo-boot - |= [=term =ship =desk] + |= [dap=term =ship =desk] ^+ mo-core - :: =/ =case [%da now] - =/ =wire - =/ ship (scot %p ship) - =/ case (scot case) - /sys/cor/[term]/[ship]/[desk]/[case] - :: - =/ =note-arvo - =/ =schematic:ford [%core [ship desk] /hoon/[term]/app] - [%f %build live=%.y schematic] - :: - (mo-pass wire note-arvo) - :: + =/ =wire /sys/cor/[dap]/(scot %p ship)/[desk]/(scot case) + (mo-pass wire %c %warp ship desk ~ %sing %a case /app/[dap]/hoon) :: +mo-reboot: ask %ford to rebuild the specified agent :: ++ mo-reboot - |= [force=? =term =ship] + |= [dap=term =ship] ^+ mo-core - =/ gent (~(got by running.agents.state) term) - =. hen control-duct.gent + =/ gent (~(got by yokes.state) dap) =* desk q.beak.gent - :: if we're forcing a reboot, we don't try to %kill the old build - :: - ?: force - (mo-boot term ship desk) - :: - =/ =wire - =/ ship (scot %p ship) - =/ case (scot r.beak.gent) - /sys/cor/[term]/[ship]/[desk]/[case] - %. [term ship desk] - =< mo-boot - =/ =note-arvo [%f %kill ~] - (mo-pass wire note-arvo) - :: + (mo-boot:(mo-abed control-duct.gent) dap ship desk) :: +mo-goad: rebuild agent(s) :: ++ mo-goad - |= [force=? agent=(unit dude)] + |= agent=(unit dude) ^+ mo-core ?^ agent ~| goad-gone+u.agent - (mo-reboot force u.agent our) - :: - =/ agents=(list term) - ~(tap in ~(key by running.agents.state)) + (mo-reboot u.agent our) + =/ agents=(list term) ~(tap in ~(key by yokes.state)) |- ^+ mo-core - ?~ agents - mo-core - %= $ - agents t.agents - ..mo-core (mo-reboot force i.agents our) - == - :: - :: +mo-pass: prepend a standard %pass to the current list of moves. - :: - ++ mo-pass - |= pass=(pair wire note-arvo) - ^+ mo-core - :: - =/ =move [hen [%pass pass]] - mo-core(moves [move moves]) - :: +mo-give: prepend a standard %give to the current list of moves. - :: - ++ mo-give - |= =gift:able - ^+ mo-core - :: - =/ =move [hen [%give gift]] - mo-core(moves [move moves]) + ?~ agents mo-core + $(agents t.agents, mo-core (mo-reboot i.agents our)) :: +mo-receive-core: receives an app core built by %ford. :: :: Presuming we receive a good core, we first check to see if the agent @@ -280,72 +381,83 @@ :: ++ mo-receive-core ~/ %mo-receive-core - |= [=term =beak =made-result:ford] + |= [dap=term bek=beak =agent] ^+ mo-core :: - ?: ?=([%incomplete *] made-result) - (mo-give %onto %.n tang.made-result) + =/ existing (~(get by yokes.state) dap) + =/ re ?~(existing "" "re") + ~> %slog.[0 leaf+"gall: {re}loading {}"] :: - =/ build-result build-result.made-result - :: - ?: ?=([%error *] build-result) - (mo-give %onto %.n message.build-result) - :: - =/ =cage (result-to-cage:ford build-result) - =/ result-vase q.cage - =/ maybe-agent=(unit running-agent) - (~(get by running.agents.state) term) - :: - ?^ maybe-agent - =/ agent u.maybe-agent(beak beak) - =. running.agents.state - (~(put by running.agents.state) term agent) + ?^ existing + =. yokes.state + (~(put by yokes.state) dap u.existing(beak bek)) =/ =routes [disclosing=~ attributing=our] - =/ app (ap-abed:ap term routes) - =. app (ap-reinstall:app result-vase) - ap-abet:app + =/ ap-core (ap-abed:ap dap routes) + =. ap-core (ap-reinstall:ap-core agent) + ap-abet:ap-core + :: + =. yokes.state + %+ ~(put by yokes.state) dap + =/ default-yoke *yoke + default-yoke(control-duct hen, beak bek, agent agent) :: - =/ maybe-new-agent (mule |.(!<(agent result-vase))) - ?: ?=(%| -.maybe-new-agent) - =/ err [[%leaf "{}: not valid agent"] p.maybe-new-agent] - (mo-give %onto %.n err) - =. mo-core (mo-new-agent term beak p.maybe-new-agent) =/ old mo-core =/ wag =/ =routes [disclosing=~ attributing=our] - =/ app (ap-abed:ap term routes) - (ap-upgrade-state:app ~) + =/ ap-core (ap-abed:ap dap routes) + (ap-upgrade-state:ap-core ~) :: =/ maybe-tang -.wag - =/ app +.wag + =/ ap-core +.wag ?^ maybe-tang =. mo-core old (mo-give %onto %.n u.maybe-tang) :: - =. mo-core ap-abet:app - =. mo-core (mo-clear-queue term) - =/ =suss [term %boot now] + =. mo-core ap-abet:ap-core + =. mo-core (mo-clear-queue dap) + =/ =suss [dap %boot now] (mo-give %onto [%.y suss]) - :: +mo-new-agent: create a new agent and add it to %gall's state. + :: +mo-subscribe-to-agent-builds: request agent update notices :: - :: %gall maintains a collection of running agents. This arm creates a - :: new one with the provided name, beak, and state (held in a vase). + :: Also subscribe to our own source path, in case we get reloaded + :: but none of the agents do. This way, Clay will still notify us, + :: and we'll be able to exit the chrysalis. :: - ++ mo-new-agent - |= [=term =beak =agent] + ++ mo-subscribe-to-agent-builds + |= date=@da ^+ mo-core - :: - =/ running-agent - =/ default-agent *running-agent - %_ default-agent - control-duct hen - beak beak - agent agent + =. mo-core (mo-abed system-duct.state) + =/ =wire /sys/lyv + =. mo-core (mo-pass /sys/lyv %c %warp our %home ~) + =/ =mool:clay + :- da+date + %- ~(gas in *(set [care:clay path])) + :* [%z /sys/hoon/hoon] + [%z /sys/arvo/hoon] + [%z /sys/zuse/hoon] + [%z /sys/vane/gall/hoon] + %+ turn ~(tap in ~(key by yokes.state)) + |= dap=term + ^- [care:clay path] + [%a /app/[dap]/hoon] == - :: - %_ mo-core - running.agents.state (~(put by running.agents.state) term running-agent) - == + (mo-pass wire %c %warp our %home ~ %mult mool) + :: +mo-scry-agent-cage: read $agent core from clay + :: + ++ mo-scry-agent-cage + |= [dap=term =case:clay] + ^- (each agent tang) + =/ bek=beak [our %home case] + =/ sky (ski [%141 %noun] ~ %ca bek /hoon/[dap]/app) + ?~ sky |+[leaf+"gall: {} scry blocked"]~ + ?~ u.sky |+[leaf+"gall: {} scry failed"]~ + =/ =cage u.u.sky + ?. =(%vase p.cage) + |+[leaf+"gall: bad mark {} for agent {}"]~ + =/ res (mule |.(!<(agent !<(vase q.cage)))) + ?: ?=(%& -.res) + &+p.res + |+[[leaf+"gall: {} not valid agent"] p.res] :: +mo-send-foreign-request: handle local request to .ship :: ++ mo-send-foreign-request @@ -359,7 +471,7 @@ ?- -.deal %poke [%m p.cage.deal q.q.cage.deal] %leave [%u ~] - %watch-as [%l deal] + %watch-as [%l [mark path]:deal] %watch [%s path.deal] == :: @@ -370,10 +482,10 @@ =/ =path /ge/[foreign-agent] [%a %plea ship %g path ames-request] :: - =. outstanding.agents.state + =. outstanding.state =/ stand - (~(gut by outstanding.agents.state) [wire hen] *(qeu remote-request)) - (~(put by outstanding.agents.state) [wire hen] (~(put to stand) -.deal)) + (~(gut by outstanding.state) [wire hen] *(qeu remote-request)) + (~(put by outstanding.state) [wire hen] (~(put to stand) -.deal)) (mo-pass wire note-arvo) :: +mo-track-ship: subscribe to ames and jael for notices about .ship :: @@ -382,19 +494,19 @@ ^+ mo-core :: if already contacted, no-op :: - ?: (~(has in contacts.agents.state) ship) + ?: (~(has in contacts.state) ship) mo-core :: first contact; update state and subscribe to notifications :: - =. contacts.agents.state (~(put in contacts.agents.state) ship) + =. contacts.state (~(put in contacts.state) ship) :: ask ames to track .ship's connectivity :: - =. moves [[system-duct.agents.state %pass /sys/lag %a %heed ship] moves] + =. moves [[system-duct.state %pass /sys/lag %a %heed ship] moves] :: ask jael to track .ship's breaches :: =/ =note-arvo [%j %public-keys (silt ship ~)] =. moves - [[system-duct.agents.state %pass /sys/era note-arvo] moves] + [[system-duct.state %pass /sys/era note-arvo] moves] mo-core :: +mo-untrack-ship: cancel subscriptions to ames and jael for .ship :: @@ -403,17 +515,17 @@ ^+ mo-core :: if already canceled, no-op :: - ?. (~(has in contacts.agents.state) ship) + ?. (~(has in contacts.state) ship) mo-core :: delete .ship from state and kill subscriptions :: - =. contacts.agents.state (~(del in contacts.agents.state) ship) + =. contacts.state (~(del in contacts.state) ship) :: - =. moves [[system-duct.agents.state %pass /sys/lag %a %jilt ship] moves] + =. moves [[system-duct.state %pass /sys/lag %a %jilt ship] moves] :: =/ =note-arvo [%j %nuke (silt ship ~)] =. moves - [[system-duct.agents.state %pass /sys/era note-arvo] moves] + [[system-duct.state %pass /sys/era note-arvo] moves] mo-core :: +mo-breach: ship breached, so forget about them :: @@ -422,10 +534,10 @@ ^+ mo-core =. mo-core (mo-untrack-ship ship) =. mo-core (mo-filter-queue ship) - =/ agents=(list [name=term =running-agent]) ~(tap by running.agents.state) - =. outstanding.agents.state + =/ agents=(list [name=term =yoke]) ~(tap by yokes.state) + =. outstanding.state %- malt - %+ skip ~(tap by outstanding.agents.state) + %+ skip ~(tap by outstanding.state) |= [[=wire duct] (qeu remote-request)] =(/sys/way/(scot %p ship) (scag 3 wire)) :: @@ -447,13 +559,11 @@ ^+ mo-core :: ?+ -.path !! + %lyv (mo-handle-sys-lyv path sign-arvo) %era (mo-handle-sys-era path sign-arvo) %cor (mo-handle-sys-cor path sign-arvo) %lag (mo-handle-sys-lag path sign-arvo) - %pel (mo-handle-sys-pel path sign-arvo) - %rep (mo-handle-sys-rep path sign-arvo) %req (mo-handle-sys-req path sign-arvo) - %val (mo-handle-sys-val path sign-arvo) %way (mo-handle-sys-way path sign-arvo) == :: +mo-handle-sys-era: receive update about contact @@ -466,21 +576,58 @@ ?. ?=(%breach -.public-keys-result.sign-arvo) mo-core (mo-breach who.public-keys-result.sign-arvo) - :: +mo-handle-sys-cor: receive a cor from %ford. + :: +mo-handle-sys-cor: receive a built agent from %clay :: ++ mo-handle-sys-cor |= [=path =sign-arvo] ^+ mo-core :: ?> ?=([%cor @ @ @ @ ~] path) - ?> ?=([%f %made *] sign-arvo) - =/ beak-path t.t.path - =/ =beak - =/ =ship (slav %p i.beak-path) - =/ =desk i.t.beak-path - =/ =case [%da (slav %da i.t.t.beak-path)] - [ship desk case] - (mo-receive-core i.t.path beak result.sign-arvo) + =/ [dap=term her=@ta desk=@ta dat=@ta ~] t.path + =/ tim (slav da+dat) + =/ =beak [(slav %p her) desk da+tim] + ?> ?=([?(%b %c) %writ *] sign-arvo) + |^ ^+ mo-core + ?~ p.sign-arvo + (fail leaf+"gall: failed to build agent {}" ~) + =/ cag=cage r.u.p.sign-arvo + ?. =(%vase p.cag) + (fail leaf+"gall: bad %writ {} for {}" ~) + =/ res (mule |.(!<(agent !<(vase q.cag)))) + ?: ?=(%| -.res) + (fail leaf+["gall: bad agent {}"] p.res) + =. mo-core (mo-receive-core dap beak p.res) + (mo-subscribe-to-agent-builds tim) + :: + ++ fail + |= =tang + ^+ mo-core + =. mo-core (mo-give %onto |+tang) + =/ =case [%da tim] + =/ =wire /sys/cor/[dap]/[her]/[desk]/(scot case) + (mo-pass wire %c %warp p.beak desk ~ %next %a case /app/[dap]/hoon) + -- + :: +mo-handle-sys-lyv: handle notice that agents have been rebuilt + :: + ++ mo-handle-sys-lyv + |= [=path =sign-arvo] + ^+ mo-core + ?> ?=([%lyv ~] path) + ?> ?=([?(%b %c) %wris *] sign-arvo) + =/ bek=beak [our %home p.sign-arvo] + =/ nex=(list [=care:clay =^path]) ~(tap in q.sign-arvo) + ~> %slog.[0 leaf+"gall: reloading agents"] + ~< %slog.[0 leaf+"gall: reloaded agents"] + =; cor (mo-subscribe-to-agent-builds:cor p.p.sign-arvo) + %+ roll nex + |= [[=care:clay =^path] cor=_mo-core] + ^+ cor + ?> =(%a care) + =/ dap dap:;;([%app dap=@tas %hoon ~] path) + =/ rag (mo-scry-agent-cage dap p.sign-arvo) + ?: ?=(%| -.rag) + (mean p.rag) + (mo-receive-core:cor dap bek p.rag) :: +mo-handle-sys-lag: handle an ames %clog notification :: ++ mo-handle-sys-lag @@ -490,7 +637,7 @@ ?> ?=([%lag ~] path) ?> ?=([%a %clog *] sign-arvo) :: - =/ agents=(list term) ~(tap in ~(key by running.agents.state)) + =/ agents=(list term) ~(tap in ~(key by yokes.state)) |- ^+ mo-core ?~ agents mo-core :: @@ -500,51 +647,6 @@ ap-abet:(ap-clog:app ship.sign-arvo) :: $(agents t.agents) - :: +mo-handle-sys-pel: translated peer. - :: - :: Validates a received %ford result and %gives an internal - :: %fact. - :: - ++ mo-handle-sys-pel - |= [=path =sign-arvo] - ^+ mo-core - :: - ?> ?=([%pel @ ~] path) - ?> ?=([%f %made *] sign-arvo) - :: - ?- result.sign-arvo - [%incomplete *] - (mo-give %unto %poke-ack `tang.result.sign-arvo) - :: - [%complete %error *] - (mo-give %unto %poke-ack `message.build-result.result.sign-arvo) - :: - [%complete %success *] - (mo-give %unto %fact (result-to-cage:ford build-result.result.sign-arvo)) - == - :: +mo-handle-sys-rep: reverse request. - :: - :: On receipt of a valid +sign from %ford, sets state to the - :: appropriate duct and gives an internal %fact - :: containing the +sign payload. - :: - ++ mo-handle-sys-rep - |= [=path =sign-arvo] - ^+ mo-core - :: - ?> ?=([%rep ~] path) - ?> ?=([%f %made *] sign-arvo) - :: - ?- result.sign-arvo - [%incomplete *] - (mo-give %done `[%gall-fail tang.result.sign-arvo]) - :: - [%complete %error *] - (mo-give %done `[%gall-fail message.build-result.result.sign-arvo]) - :: - [%complete %success *] - (mo-give %unto %fact (result-to-cage:ford build-result.result.sign-arvo)) - == :: +mo-handle-sys-req: TODO description :: :: TODO: what should we do if the remote nacks our %pull? @@ -579,32 +681,6 @@ `[%watch-ack u.p.sign] (mo-give %done err) == - :: +mo-handle-sys-val: inbound validate. - :: - :: Validates an incoming +sign from %ford and applies it to the - :: specified agent. - :: - ++ mo-handle-sys-val - |= [=path =sign-arvo] - ^+ mo-core - :: - ?> ?=([%val @ @ ~] path) - ?> ?=([%f %made *] sign-arvo) - =/ =ship (slav %p i.t.path) - =/ =term i.t.t.path - ?: ?=([%incomplete *] result.sign-arvo) - =/ err (some tang.result.sign-arvo) - (mo-give %unto %poke-ack err) - :: - =/ build-result build-result.result.sign-arvo - ?: ?=([%error *] build-result) - =/ err (some message.build-result) - (mo-give %unto %poke-ack err) - :: - =/ =routes [disclosing=~ attributing=ship] - =/ =cage (result-to-cage:ford build-result) - =/ =deal [%poke cage] - (mo-apply term routes deal) :: +mo-handle-sys-way: handle response to outgoing remote request :: ++ mo-handle-sys-way @@ -616,11 +692,11 @@ :: ?+ sign-arvo !! [%a %done *] - =^ remote-request outstanding.agents.state + =^ remote-request outstanding.state ?~ t.t.t.wire =/ full-wire sys+wire =/ stand - (~(gut by outstanding.agents.state) [full-wire hen] ~) + (~(gut by outstanding.state) [full-wire hen] ~) :: :: default is to send both ack types; should only hit if :: cleared queue in +load 3-to-4 or +load-4-to-5 @@ -629,11 +705,11 @@ (~(put to *(qeu remote-request)) %missing) ~| [full-wire=full-wire hen=hen stand=stand] =^ rr stand ~(get to stand) - [rr (~(put by outstanding.agents.state) [full-wire hen] stand)] + [rr (~(put by outstanding.state) [full-wire hen] stand)] :: non-null case of wire is old, remove on next breach after :: 2019/12 :: - [;;(remote-request i.t.t.t.wire) outstanding.agents.state] + [;;(remote-request i.t.t.t.wire) outstanding.state] :: =/ err=(unit tang) ?~ error=error.sign-arvo @@ -706,43 +782,34 @@ :: +mo-clear-queue: clear blocked tasks from the specified running agent. :: ++ mo-clear-queue - |= =term + |= dap=term ^+ mo-core - :: - ?. (~(has by running.agents.state) term) + ?. (~(has by yokes.state) dap) mo-core - =/ maybe-blocked (~(get by blocked.agents.state) term) - ?~ maybe-blocked + ?~ maybe-blocked=(~(get by blocked.state) dap) mo-core - :: - =/ =blocked u.maybe-blocked - :: + =/ blocked=(qeu blocked-move) u.maybe-blocked |- ^+ mo-core ?: =(~ blocked) - =/ blocked (~(del by blocked.agents.state) term) - %_ mo-core - blocked.agents.state blocked - == - =^ task blocked [p q]:~(get to blocked) - =/ =duct p.task - =/ =routes q.task - =/ =deal r.task - :: + =. blocked.state (~(del by blocked.state) dap) + mo-core + =^ [=duct =routes =deal] blocked ~(get to blocked) =/ move =/ =sock [attributing.routes our] - =/ card [%slip %g %deal sock term deal] + =/ card [%slip %g %deal sock dap deal] [duct card] $(moves [move moves]) :: +mo-filter-queue: remove all blocked tasks from ship. :: ++ mo-filter-queue |= =ship - =/ agents=(list [name=term =blocked]) ~(tap by blocked.agents.state) - =| new-agents=(map term blocked) + =/ agents=(list [name=term blocked=(qeu blocked-move)]) + ~(tap by blocked.state) + =| new-agents=(map term (qeu blocked-move)) |- ^+ mo-core ?~ agents - mo-core(blocked.agents.state new-agents) - =| new-blocked=blocked + mo-core(blocked.state new-agents) + =| new-blocked=(qeu blocked-move) |- ^+ mo-core ?: =(~ blocked.i.agents) ?~ new-blocked @@ -751,124 +818,85 @@ agents t.agents new-agents (~(put by new-agents) name.i.agents new-blocked) == - =^ mov blocked.i.agents ~(get to blocked.i.agents) - =? new-blocked !=(ship attributing.q.p.mov) + =^ mov=blocked-move blocked.i.agents ~(get to blocked.i.agents) + =? new-blocked !=(ship attributing.routes.mov) (~(put to new-blocked) mov) $ :: +mo-beak: assemble a beak for the specified agent. :: ++ mo-beak - |= =term + |= dap=term ^- beak + ?^ yoke=(~(get by yokes.state) dap) + beak.u.yoke + :: XX this fallback is necessary, as .term could be either the source + :: or the destination app. ie, it might not exist locally ... :: - ?~ running=(~(get by running.agents.state) term) - :: XX this fallback is necessary, as .term could be either the source - :: or the destination app. ie, it might not exist locally ... - :: - [our %home %da now] - beak.u.running + [our %home %da now] :: +mo-peek: call to +ap-peek (which is not accessible outside of +mo). :: ++ mo-peek ~/ %mo-peek - |= [agent=term =routes =term =path] + |= [dap=term =routes care=term =path] ^- (unit (unit cage)) :: - =/ app (ap-abed:ap agent routes) - (ap-peek:app term path) - :: +mo-apply: apply the supplied action to the specified agent. + =/ app (ap-abed:ap dap routes) + (ap-peek:app care path) :: ++ mo-apply - |= [agent=term =routes =deal] + |= [dap=term =routes =deal] ^+ mo-core - :: TODO: Remove this horrific hack when ford pinto comes! - => |% - +$ serial @uvH - :: - +$ letter - $% [%text text=cord] - [%url url=cord] - [%code expression=cord output=(list tank)] - [%me narrative=cord] - == - :: - +$ envelope - $: uid=serial - number=@ - author=ship - when=time - =letter - == - :: - +$ config - $: length=@ - read=@ - == - :: - +$ mailbox - $: =config - envelopes=(list envelope) - == - :: - +$ inbox (map path mailbox) - :: - +$ chat-configs (map path config) - :: - +$ chat-base - $% [%create =path] - [%delete =path] - [%message =path =envelope] - [%read =path] - == - :: - +$ chat-action - $% :: %messages: append a list of messages to mailbox - :: - [%messages =path envelopes=(list envelope)] - chat-base - == - :: - +$ chat-update - $% [%keys keys=(set path)] - [%config =path =config] - [%messages =path start=@ud end=@ud envelopes=(list envelope)] - chat-base - == - -- + ?- -.deal + ?(%watch %watch-as %leave %poke) + (mo-apply-sure dap routes deal) :: - =/ =path - =/ ship (scot %p attributing.routes) - /sys/val/[ship]/[agent] - :: - =/ ship-desk - =/ =beak (mo-beak agent) - [p q]:beak - :: - ?: ?=(%raw-poke -.deal) - :: TODO: Remove this horrific hack when ford pinto comes! - ?+ mark.deal - =/ =schematic:ford [%vale ship-desk +.deal] - =/ =note-arvo [%f %build live=%.n schematic] - (mo-pass path note-arvo) + %raw-poke + =/ =case:clay da+now + =/ sky (ski [%141 %noun] ~ %cb [our %home case] /[mark.deal]) + ?- sky + ?(~ [~ ~]) + =/ ror "gall: raw-poke fail :{(trip dap)} {}" + (mo-give %unto %poke-ack `[leaf+ror]~) :: - %chat-action - =/ chat-act=(unit chat-action) ((soft chat-action) noun.deal) - ?~ chat-act - ~& gall-raw-chat-poke-failed+[agent attributing.routes] - mo-core - =/ =cage [%chat-action !>(u.chat-act)] - =/ new-deal=^deal [%poke cage] - =/ app (ap-abed:ap agent routes) - =. app (ap-apply:app new-deal) - ap-abet:app + [~ ~ *] + =+ !<(=dais:clay q.u.u.sky) + =/ res (mule |.((vale:dais noun.deal))) + ?: ?=(%| -.res) + =/ ror "gall: raw-poke vale fail :{(trip dap)} {}" + (mo-give %unto %poke-ack `[leaf+ror p.res]) + =. mo-core + %+ mo-pass /nowhere + [%c %warp our %home ~ %sing %b case /[mark.deal]] + (mo-apply-sure dap routes [%poke mark.deal p.res]) == :: - ?: ?=(%poke-as -.deal) - =/ =schematic:ford [%cast ship-desk mark.deal [%$ cage.deal]] - =/ =note-arvo [%f %build live=%.n schematic] - (mo-pass path note-arvo) - :: - =/ app (ap-abed:ap agent routes) + %poke-as + =/ =case:clay da+now + =/ =mars:clay [p.cage mark]:deal + =/ mars-path /[a.mars]/[b.mars] + =/ sky (ski [%141 %noun] ~ %cc [our %home case] (flop mars-path)) + ?- sky + ?(~ [~ ~]) + =/ ror "gall: poke cast fail :{(trip dap)} {}" + (mo-give %unto %poke-ack `[leaf+ror]~) + :: + [~ ~ *] + =+ !<(=tube:clay q.u.u.sky) + =/ res (mule |.((tube q.cage.deal))) + ?: ?=(%| -.res) + =/ ror "gall: poke-as cast fail :{(trip dap)} {}" + (mo-give %unto %poke-ack `[leaf+ror p.res]) + =. mo-core + %+ mo-pass /nowhere + [%c %warp our %home ~ %sing %c case /[a.mars]/[b.mars]] + (mo-apply-sure dap routes [%poke mark.deal p.res]) + == + == + :: + ++ mo-apply-sure + |= [dap=term =routes =deal] + ^+ mo-core + =/ app (ap-abed:ap dap routes) =. app (ap-apply:app deal) ap-abet:app :: +mo-handle-local: handle locally. @@ -881,19 +909,19 @@ ^+ mo-core :: =/ =routes [disclosing=~ attributing=ship] - =/ is-running (~(has by running.agents.state) agent) - =/ is-blocked (~(has by blocked.agents.state) agent) + =/ is-running (~(has by yokes.state) agent) + =/ is-blocked (~(has by blocked.state) agent) :: ?: |(!is-running is-blocked) - =/ =blocked - =/ waiting (~(get by blocked.agents.state) agent) - =/ deals (fall waiting *blocked) + =/ blocked=(qeu blocked-move) + =/ waiting (~(get by blocked.state) agent) + =/ deals (fall waiting *(qeu blocked-move)) =/ deal [hen routes deal] (~(put to deals) deal) :: %- (slog leaf+"gall: not running {} yet, got {<-.deal>}" ~) %_ mo-core - blocked.agents.state (~(put by blocked.agents.state) agent blocked) + blocked.state (~(put by blocked.state) agent blocked) == (mo-apply agent routes deal) :: +mo-handle-ames-request: handle %ames request message. @@ -922,16 +950,27 @@ |= =ames-response ^+ mo-core ?- -.ames-response - :: %d: diff; ask ford to validate .noun as .mark + :: %d: diff; ask clay to validate .noun as .mark :: %d - =/ =wire /sys/rep - :: agents load their code from the %home desk, including marks + =/ =case:clay da+now + =/ sky (ski [%141 %noun] ~ %cb [our %home case] /[mark.ames-response]) + ?- sky + ?(~ [~ ~]) + =/ ror "gall: ames mark fail {}" + (mo-give %done `vale+[leaf+ror]~) :: - =/ =note-arvo - =/ =disc:ford [our %home] - [%f %build live=%.n %vale disc [mark noun]:ames-response] - (mo-pass wire note-arvo) + [~ ~ *] + =+ !<(=dais:clay q.u.u.sky) + =/ res (mule |.((vale:dais noun.ames-response))) + ?: ?=(%| -.res) + =/ ror "gall: ames vale fail {}" + (mo-give %done `vale+[leaf+ror p.res]) + =. mo-core + %+ mo-pass /nowhere + [%c %warp our %home ~ %sing %b case /[mark.ames-response]] + (mo-give %unto %fact mark.ames-response p.res) + == :: :: %x: kick; tell agent the publisher canceled the subscription :: @@ -950,7 +989,7 @@ agent-duct=duct agent-moves=(list move) agent-config=(list (each suss tang)) - current-agent=running-agent + current-agent=yoke == ++ ap-core . :: +ap-abed: initialise state for an agent, with the supplied routes. @@ -960,20 +999,32 @@ :: ++ ap-abed ~/ %ap-abed - |= [=term =routes] + |= [dap=term =routes] ^+ ap-core - :: - =/ =running-agent - =/ running (~(got by running.agents.state) term) - =/ =stats - :+ +(change.stats.running) - (shaz (mix (add term change.stats.running) eny)) - now - running(stats stats) - :: - =. agent-name term + (ap-yoke dap routes (~(got by yokes.state) dap)) + :: +ap-hatch: initialize agent state from $egg, after upgrade + :: + ++ ap-abut + |= [dap=term =egg] + ^+ ap-core + =/ res (mo-scry-agent-cage dap da+now) + ?: ?=(%| -.res) + (mean p.res) + =/ =yoke egg(old-state `agent`p.res) + =/ =routes [disclosing=~ attributing=our] + (ap-yoke dap routes yoke) + :: +ap-yoke: initialize agent state, starting from a $yoke + :: + ++ ap-yoke + |= [dap=term =routes =yoke] + ^+ ap-core + =. stats.yoke + :+ +(change.stats.yoke) + (shaz (mix (add dap change.stats.yoke) eny)) + now + =. agent-name dap =. agent-routes routes - =. current-agent running-agent + =. current-agent yoke =. agent-duct hen ap-core :: +ap-abet: resolve moves. @@ -981,15 +1032,15 @@ ++ ap-abet ^+ mo-core :: - =/ running (~(put by running.agents.state) agent-name current-agent) + =/ running (~(put by yokes.state) agent-name current-agent) =/ moves =/ giver |=(report=(each suss tang) [hen %give %onto report]) =/ from-suss (turn agent-config giver) :(weld agent-moves from-suss moves) :: %_ mo-core - running.agents.state running - moves moves + yokes.state running + moves moves == :: +ap-from-internal: internal move to move. :: @@ -1010,7 +1061,7 @@ =/ ducts=(list duct) (ap-ducts-from-paths paths.gift ship.gift) %+ turn ducts |= =duct - ~? &(=(duct system-duct.agents.state) !=(agent-name %hood)) + ~? &(=(duct system-duct.state) !=(agent-name %hood)) [%agent-giving-on-system-duct agent-name -.gift] [duct %give %unto %kick ~] :: @@ -1019,29 +1070,42 @@ :: =/ ducts=(list duct) (ap-ducts-from-paths paths.gift ~) =/ =cage cage.gift + %- zing %+ turn ducts |= =duct - ~? &(=(duct system-duct.agents.state) !=(agent-name %hood)) + ~? &(=(duct system-duct.state) !=(agent-name %hood)) [%agent-giving-on-system-duct agent-name -.gift] - ^- move + ^- (list move) =/ =mark (~(gut by marks.current-agent) duct p.cage) :: ?: =(mark p.cage) - [duct %give %unto %fact cage.gift] - =/ =path /sys/pel/[agent-name] - =/ =note-arvo - =/ =schematic:ford - =/ =beak (mo-beak agent-name) - [%cast [p q]:beak mark [%$ cage]] - [%f %build live=%.n schematic] + [duct %give %unto %fact cage.gift]~ + =/ =mars:clay [p.cage mark] + =/ =case:clay da+now + =/ bek=beak [our %home case] + =/ mars-path /[a.mars]/[b.mars] + =/ sky (ski [%141 %noun] ~ %cc bek (flop mars-path)) + ?- sky + ?(~ [~ ~]) + %- (slog leaf+"watch-as fact conversion find-fail" >sky< ~) + (ap-kill-up-slip duct) :: - [duct %pass path note-arvo] + [~ ~ *] + =+ !<(=tube:clay q.u.u.sky) + =/ res (mule |.((tube q.cage))) + ?: ?=(%| -.res) + %- (slog leaf+"watch-as fact conversion failure" p.res) + (ap-kill-up-slip duct) + :~ [duct %pass /nowhere %c %warp our %home ~ %sing %c case mars-path] + [duct %give %unto %fact b.mars p.res] + == + == :: %pass - =/ =duct system-duct.agents.state + =/ =duct system-duct.state =/ =wire p.card - =/ =neat:agent q.card + =/ =neat q.card =. wire ?: ?=(%agent -.neat) :: remove `our` in next breach after 2019/12 and reflect in @@ -1050,16 +1114,11 @@ :- (scot %p our) [%out (scot %p ship.neat) name.neat wire] [(scot %p attributing.agent-routes) wire] - =. wire - [%use agent-name wire] + =. wire [%use agent-name wire] =/ =note-arvo - ?- -.neat - %arvo note-arvo.neat - %agent - =/ =task:able - =/ =sock [our ship.neat] - [%deal sock [name deal]:neat] - [%g task] + ?- -.neat + %arvo note-arvo.neat + %agent [%g %deal [our ship.neat] [name deal]:neat] == [duct %pass wire note-arvo]~ == @@ -1069,7 +1128,7 @@ |= =ship ^+ ap-core =/ in=(list [=duct =^ship =path]) - ~(tap by incoming.subscribers.current-agent) + ~(tap by inbound.watches.current-agent) |- ^+ ap-core ?^ in =? ap-core =(ship ship.i.in) @@ -1078,13 +1137,13 @@ $(in t.in) :: =/ out=(list [[=wire =^ship =term] ? =path]) - ~(tap by outgoing.subscribers.current-agent) + ~(tap by outbound.watches.current-agent) |- ^+ ap-core ?~ out ap-core =? ap-core =(ship ship.i.out) =/ core - =. agent-duct system-duct.agents.state + =. agent-duct system-duct.state =/ way [%out (scot %p ship) term.i.out wire.i.out] (ap-specific-take way %kick ~) core(agent-duct agent-duct) @@ -1101,7 +1160,7 @@ ^+ ap-core :: =/ in=(list [=duct =^ship =path]) - ~(tap by incoming.subscribers.current-agent) + ~(tap by inbound.watches.current-agent) |- ^+ ap-core ?~ in ap-core :: @@ -1121,7 +1180,7 @@ ?~ target-paths ?~ target-ship ~[agent-duct] - %+ murn ~(tap by incoming.subscribers.current-agent) + %+ murn ~(tap by inbound.watches.current-agent) |= [=duct =ship =path] ^- (unit ^duct) ?: =(target-ship `ship) @@ -1136,7 +1195,7 @@ ++ ap-ducts-from-path |= [target-path=path target-ship=(unit ship)] ^- (list duct) - %+ murn ~(tap by incoming.subscribers.current-agent) + %+ murn ~(tap by inbound.watches.current-agent) |= [=duct =ship =path] ^- (unit ^duct) ?: ?& =(target-path path) @@ -1149,7 +1208,6 @@ ++ ap-apply |= =deal ^+ ap-core - :: ?- -.deal %watch-as (ap-subscribe-as +.deal) %poke (ap-poke +.deal) @@ -1162,34 +1220,50 @@ :: ++ ap-peek ~/ %ap-peek - |= [=term tyl=path] + |= [care=term tyl=path] ^- (unit (unit cage)) + :: take trailing mark off path for %x scrys :: - =/ marked - ?. ?=(%x term) - [mark=%$ tyl=tyl] - :: - =/ =path (flop tyl) - ?> ?=(^ path) - [mark=i.path tyl=(flop t.path)] - :: - =/ =mark mark.marked - =/ tyl tyl.marked + =^ want=mark tyl + ?. ?=(%x care) [%$ tyl] + =. tyl (flop tyl) + [(head tyl) (flop (tail tyl))] + :: call the app's +on-peek, producing [~ ~] if it crashes :: =/ peek-result=(each (unit (unit cage)) tang) - (ap-mule-peek |.((on-peek:ap-agent-core [term tyl]))) + (ap-mule-peek |.((on-peek:ap-agent-core [care tyl]))) + ?: ?=(%| -.peek-result) + ((slog leaf+"peek bad result" p.peek-result) [~ ~]) + :: for non-%x scries, or failed %x scries, or %x results that already + :: have the requested mark, produce the result as-is :: - ?- -.peek-result - %& p.peek-result - %| ((slog leaf+"peek bad result" p.peek-result) [~ ~]) - == + ?. ?& ?=(%x care) + ?=([~ ~ *] p.peek-result) + !=(mark p.u.u.p.peek-result) + == + p.peek-result + :: for %x scries, attempt to convert to the requested mark if needed + :: + =* have p.u.u.p.peek-result + =* vase q.u.u.p.peek-result + =/ tub=(unit tube:clay) + ?: =(have want) `(bake same ^vase) + =/ tuc=(unit (unit cage)) + (ski [%141 %noun] ~ %cc [our %home da+now] (flop /[have]/[want])) + ?. ?=([~ ~ *] tuc) ~ + `!<(tube:clay q.u.u.tuc) + ?~ tub + ((slog leaf+"peek no tube from {(trip have)} to {(trip want)}" ~) ~) + =/ res (mule |.((u.tub vase))) + ?: ?=(%& -.res) + ``want^p.res + ((slog leaf+"peek failed tube from {(trip have)} to {(trip want)}" ~) ~) :: +ap-update-subscription: update subscription. :: ++ ap-update-subscription ~/ %ap-update-subscription |= [is-ok=? =other=ship other-agent=term =wire] ^+ ap-core - :: ?: is-ok ap-core (ap-kill-down wire [other-ship other-agent]) @@ -1198,7 +1272,6 @@ ++ ap-give |= =gift:agent ^+ ap-core - :: =/ internal-moves (weld (ap-from-internal %give gift) agent-moves) ap-core(agent-moves internal-moves) @@ -1210,8 +1283,8 @@ attributing.agent-routes :: guest agent-name :: agent == :: - :* wex=outgoing.subscribers.current-agent :: outgoing - sup=incoming.subscribers.current-agent :: incoming + :* wex=outbound.watches.current-agent :: outgoing + sup=inbound.watches.current-agent :: incoming == :: :* act=change.stats.current-agent :: tick eny=eny.stats.current-agent :: nonce @@ -1223,7 +1296,6 @@ ++ ap-pass |= [=path =neat] ^+ ap-core - :: =/ internal-moves (ap-from-internal %pass path neat) ap-core(agent-moves (weld internal-moves agent-moves)) @@ -1231,31 +1303,19 @@ :: ++ ap-reinstall ~/ %ap-reinstall - |= =vase + |= =agent ^+ ap-core - :: - =/ maybe-agent (mule |.(!<(agent vase))) - ?: ?=(%| -.maybe-agent) - (ap-error %new-core-not-agent p.maybe-agent) - :: - =/ prep - =/ =agent p.maybe-agent - =/ running - %- some - ~(on-save agent.current-agent ap-construct-bowl) - =/ installed ap-install(agent.current-agent agent) - (installed running) - :: - =^ maybe-tang ap-core prep - ?~ maybe-tang + =/ old-state=vase ~(on-save agent.current-agent ap-construct-bowl) + =^ error ap-core + (ap-install(agent.current-agent agent) `old-state) + ?~ error ap-core - (ap-error %load-failed u.maybe-tang) + (mean >%load-failed< u.error) :: +ap-subscribe-as: apply %watch-as. :: ++ ap-subscribe-as |= [=mark =path] ^+ ap-core - :: =. marks.current-agent (~(put by marks.current-agent) agent-duct mark) (ap-subscribe path) :: +ap-subscribe: apply %watch. @@ -1264,11 +1324,9 @@ ~/ %ap-subscribe |= pax=path ^+ ap-core - :: =/ incoming [attributing.agent-routes pax] - =. incoming.subscribers.current-agent - (~(put by incoming.subscribers.current-agent) agent-duct incoming) - :: + =. inbound.watches.current-agent + (~(put by inbound.watches.current-agent) agent-duct incoming) =^ maybe-tang ap-core %+ ap-ingest %watch-ack |. (on-watch:ap-agent-core pax) @@ -1281,7 +1339,6 @@ ~/ %ap-poke |= =cage ^+ ap-core - :: =^ maybe-tang ap-core %+ ap-ingest %poke-ack |. (on-poke:ap-agent-core cage) @@ -1291,7 +1348,6 @@ ++ ap-error |= [=term =tang] ^+ ap-core - :: =/ form |=(=tank [%rose [~ "! " ~] tank ~]) =^ maybe-tang ap-core %+ ap-ingest ~ |. @@ -1303,7 +1359,6 @@ ~/ %ap-generic-take |= [=wire =sign-arvo] ^+ ap-core - :: =^ maybe-tang ap-core %+ ap-ingest ~ |. (on-arvo:ap-agent-core wire sign-arvo) @@ -1315,7 +1370,6 @@ ++ ap-specific-take |= [=wire =sign:agent] ^+ ap-core - :: ~| wire=wire ?> ?=([%out @ @ *] wire) =/ other-ship (slav %p i.t.wire) @@ -1324,26 +1378,25 @@ =/ agent-wire t.t.t.wire :: if subscription ack or close, handle before calling user code :: - =? outgoing.subscribers.current-agent ?=(%kick -.sign) - %- ~(del by outgoing.subscribers.current-agent) + =? outbound.watches.current-agent ?=(%kick -.sign) + %- ~(del by outbound.watches.current-agent) [agent-wire dock] ?: ?& ?=(%watch-ack -.sign) - !(~(has by outgoing.subscribers.current-agent) [agent-wire dock]) + !(~(has by outbound.watches.current-agent) [agent-wire dock]) == %- %: slog leaf+"{}: got ack for nonexistent subscription" leaf+"{}: {}" >wire=wire< - >out=outgoing.subscribers.current-agent< ~ == ap-core :: - =? outgoing.subscribers.current-agent ?=(%watch-ack -.sign) + =? outbound.watches.current-agent ?=(%watch-ack -.sign) ?^ p.sign - %- ~(del by outgoing.subscribers.current-agent) + %- ~(del by outbound.watches.current-agent) [agent-wire dock] - %+ ~(jab by outgoing.subscribers.current-agent) [agent-wire dock] + %+ ~(jab by outbound.watches.current-agent) [agent-wire dock] |= [acked=? =path] =. . ?. acked @@ -1367,13 +1420,13 @@ :: +ap-install: install wrapper. :: ++ ap-install - |= maybe-vase=(unit vase) + |= old-agent-state=(unit vase) ^- [(unit tang) _ap-core] :: - =^ maybe-tang ap-core (ap-upgrade-state maybe-vase) + =^ maybe-tang ap-core (ap-upgrade-state old-agent-state) :: - =/ new-agent-config - =/ =term ?~(maybe-vase %boot %bump) + =. agent-config + =/ =term ?~(old-agent-state %boot %bump) =/ possibly-suss ?~ maybe-tang =/ =suss [agent-name term now] @@ -1381,10 +1434,7 @@ [%.n u.maybe-tang] [possibly-suss agent-config] :: - =/ next - ap-core(agent-config new-agent-config) - :: - [maybe-tang next] + [maybe-tang ap-core] :: +ap-upgrade-state: low-level install. :: ++ ap-upgrade-state @@ -1404,8 +1454,8 @@ ^+ ap-core :: %= ap-core - incoming.subscribers.current-agent - (~(del by incoming.subscribers.current-agent) agent-duct) + inbound.watches.current-agent + (~(del by inbound.watches.current-agent) agent-duct) == :: +ap-load-delete: load delete. :: @@ -1413,13 +1463,13 @@ ^+ ap-core :: =/ maybe-incoming - (~(get by incoming.subscribers.current-agent) agent-duct) + (~(get by inbound.watches.current-agent) agent-duct) ?~ maybe-incoming ap-core :: =/ incoming u.maybe-incoming - =. incoming.subscribers.current-agent - (~(del by incoming.subscribers.current-agent) agent-duct) + =. inbound.watches.current-agent + (~(del by inbound.watches.current-agent) agent-duct) :: =^ maybe-tang ap-core %+ ap-ingest ~ |. @@ -1434,6 +1484,20 @@ :: => ap-load-delete (ap-give %kick ~ ~) + :: +ap-kill-up-slip: 2-sided kill from publisher side by slip + :: + :: +ap-kill-up is reentrant if you call it in the + :: middle of processing another deal + :: + :: Should probably call +ap-error with error message + :: + ++ ap-kill-up-slip + |= =duct + ^- (list move) + :: + :~ [duct %slip %g %deal [our our] agent-name %leave ~] + [duct %give %unto %kick ~] + == :: +ap-kill-down: 2-sided kill from subscriber side :: :: Must process leave first in case kick handler rewatches. @@ -1512,10 +1576,10 @@ :: =. agent.current-agent +.p.result =/ moves (zing (turn -.p.result ap-from-internal)) - =. incoming.subscribers.current-agent + =. inbound.watches.current-agent (ap-handle-kicks moves) (ap-handle-peers moves) - :: +ap-handle-kicks: handle cancels of incoming subscriptions + :: +ap-handle-kicks: handle cancels of inbound.watches :: ++ ap-handle-kicks ~/ %ap-handle-kicks @@ -1531,8 +1595,8 @@ :: =/ quit-map=bitt (malt (turn quits |=(=duct [duct *[ship path]]))) - (~(dif by incoming.subscribers.current-agent) quit-map) - :: +ap-handle-peers: handle new outgoing subscriptions + (~(dif by inbound.watches.current-agent) quit-map) + :: +ap-handle-peers: handle new outbound.watches :: ++ ap-handle-peers ~/ %ap-handle-peers @@ -1548,27 +1612,31 @@ ?> ?=([%use @ @ %out @ @ *] wire) =/ short-wire t.t.t.t.t.t.wire =/ =dock [q.p q]:q.move.move - =. outgoing.subscribers.current-agent - (~(del by outgoing.subscribers.current-agent) [short-wire dock]) + =. outbound.watches.current-agent + (~(del by outbound.watches.current-agent) [short-wire dock]) $(moves t.moves, new-moves [move new-moves]) - ?. ?=([* %pass * %g %deal * * %watch *] move) + ?. ?=([* %pass * %g %deal * * ?(%watch %watch-as) *] move) $(moves t.moves, new-moves [move new-moves]) =/ =wire p.move.move ?> ?=([%use @ @ %out @ @ *] wire) =/ short-wire t.t.t.t.t.t.wire =/ =dock [q.p q]:q.move.move - =/ =path path.r.q.move.move - ?: (~(has by outgoing.subscribers.current-agent) short-wire dock) + =/ =path + ?- -.r.q.move.move + %watch path.r.q.move.move + %watch-as path.r.q.move.move + == + ?: (~(has by outbound.watches.current-agent) short-wire dock) =. ap-core =/ =tang ~[leaf+"subscribe wire not unique" >agent-name< >short-wire< >dock<] =/ have - (~(got by outgoing.subscribers.current-agent) short-wire dock) + (~(got by outbound.watches.current-agent) short-wire dock) %- (slog >out=have< tang) - (ap-error %watch-not-unique tang) + (ap-error %watch-not-unique tang) :: reentrant, maybe bad? $(moves t.moves) - =. outgoing.subscribers.current-agent - (~(put by outgoing.subscribers.current-agent) [short-wire dock] [| path]) + =. outbound.watches.current-agent + (~(put by outbound.watches.current-agent) [short-wire dock] [| path]) $(moves t.moves, new-moves [move new-moves]) -- -- @@ -1584,52 +1652,18 @@ ~| [%gall-call-failed duct q.hic] =/ =task:able ((harden task:able) q.hic) :: - =/ initialised (mo-abed:mo duct) + =/ mo-core (mo-abed:mo duct) ?- -.task - %conf - =/ =dock p.task - =/ =ship p.dock - ?. =(our ship) - ~& [%gall-not-ours ship] - [~ gall-payload] - :: - => (mo-boot:initialised q.dock q.task) - mo-abet - :: + %conf mo-abet:(mo-boot:mo-core dap.task our %home) %deal - =/ =sock p.task - =/ =term q.task - =/ =deal r.task + =/ [=sock =term =deal] [p q r]:task ?. =(q.sock our) ?> =(p.sock our) - => (mo-send-foreign-request:initialised q.sock term deal) - mo-abet - :: - => (mo-handle-local:initialised p.sock term deal) - mo-abet - :: - %goad - mo-abet:(mo-goad:initialised force.task agent.task) - :: - %sear - mo-abet:(mo-filter-queue:initialised ship.task) - :: - %init - =/ payload gall-payload(system-duct.agents.state duct) - [~ payload] - :: - %trim - :: reuse %wash task to clear caches on memory-pressure - :: - :: XX cancel subscriptions if =(0 trim-priority) ? - :: - ~> %slog.[0 leaf+"gall: trim: clearing caches"] - =/ =move [duct %pass / %g [%wash ~]] - [[move ~] gall-payload] - :: - %vega - [~ gall-payload] + mo-abet:(mo-send-foreign-request:mo-core q.sock term deal) + mo-abet:(mo-handle-local:mo-core p.sock term deal) :: + %goad mo-abet:(mo-goad:mo-core agent.task) + %init [~ gall-payload(system-duct.state duct)] %plea =/ =ship ship.task =/ =path path.plea.task @@ -1640,466 +1674,65 @@ =/ agent-name i.t.path :: =/ =ames-request ;;(ames-request noun) - => (mo-handle-ames-request:initialised ship agent-name ames-request) + => (mo-handle-ames-request:mo-core ship agent-name ames-request) mo-abet :: - %wash - =. running.agents.state - %- ~(run by running.agents.state) - |= =running-agent - running-agent(cache *worm) - [~ gall-payload] - :: - %wegh - =/ blocked - =/ queued (~(run by blocked.agents.state) |=(blocked [%.y +<])) - (sort ~(tap by queued) aor) - :: - =/ running - =/ active (~(run by running.agents.state) |=(running-agent [%.y +<])) - (sort ~(tap by active) aor) - :: - =/ =mass - :+ %gall %.n - :~ [%foreign %.y contacts.agents.state] - [%blocked %.n blocked] - [%active %.n running] - [%dot %.y state] - == - :: - [[duct %give %mass mass]~ gall-payload] + %sear mo-abet:(mo-filter-queue:mo-core ship.task) + %trim [~ gall-payload] + %vega [~ gall-payload] == -:: +load: recreate vane +:: +load: recreate vane; note, only valid if called from pupa :: -++ load - |^ - |= =all-state - ^+ gall-payload - :: - =? all-state ?=(%0 -.all-state) - (state-0-to-1 all-state) - :: - =? all-state ?=(%1 -.all-state) - (state-1-to-2 all-state) - :: - =? all-state ?=(%2 -.all-state) - (state-2-to-3 all-state) - :: - =? all-state ?=(%3 -.all-state) - (state-3-to-4 all-state) - :: - =? all-state ?=(%4 -.all-state) - (state-4-to-5 all-state) - :: - ?> ?=(%5 -.all-state) - gall-payload(state all-state) - :: - :: +all-state: upgrade path - :: - ++ all-state $%(state-0 state-1 state-2 state-3 state-4 ^state) - :: - ++ state-4-to-5 - |= =state-4 - ^- ^state - %= state-4 - - %5 - outstanding.agents ~ - == - :: - ++ state-4 - $: %4 - =agents - == - :: - ++ state-3-to-4 - |= =state-3 - ^- state-4 - %= state-3 - - %4 - outstanding.agents ~ - == - :: - ++ state-3 - $: %3 - =agents - == - :: - ++ state-2-to-3 - |= =state-2 - ^- state-3 - %= state-2 - - %3 - running.agents-2 - %- ~(run by running.agents-2.state-2) - |= =running-agent-2 - ^- running-agent - %= running-agent-2 - agent-2 (agent-2-to-3 agent-2.running-agent-2) - == - == - :: - ++ agent-2-to-3 - |= =agent-2 - ^- agent - => |% - ++ cards-2-to-3 - |= cards=(list card:^agent-2) - ^- (list card:agent) - %+ turn cards - |= =card:^agent-2 - ^- card:agent - ?. ?=([%give ?(%fact %kick) *] card) card - %=(card path.p (drop path.p.card)) - -- - |_ =bowl:gall - +* this . - pass ~(. agent-2 bowl) - ++ on-init - =^ cards agent-2 on-init:pass - [(cards-2-to-3 cards) this] - :: - ++ on-save - on-save:pass - :: - ++ on-load - |= old-state=vase - =^ cards agent-2 (on-load:pass old-state) - [(cards-2-to-3 cards) this] - :: - ++ on-poke - |= [=mark =vase] - =^ cards agent-2 (on-poke:pass mark vase) - [(cards-2-to-3 cards) this] - :: - ++ on-watch - |= =path - =^ cards agent-2 (on-watch:pass path) - [(cards-2-to-3 cards) this] - :: - ++ on-leave - |= =path - =^ cards agent-2 (on-leave:pass path) - [(cards-2-to-3 cards) this] - :: - ++ on-peek - |= =path - (on-peek:pass path) - :: - ++ on-agent - |= [=wire =sign:agent:gall] - =^ cards agent-2 (on-agent:pass wire sign) - [(cards-2-to-3 cards) this] - :: - ++ on-arvo - |= [=wire =sign-arvo] - =^ cards agent-2 (on-arvo:pass wire sign-arvo) - [(cards-2-to-3 cards) this] - :: - ++ on-fail - |= [=term =tang] - =^ cards agent-2 (on-fail:pass term tang) - [(cards-2-to-3 cards) this] - -- - :: - ++ state-2 - $: %2 - =agents-2 - == - :: - ++ agents-2 - $: system-duct=duct - outstanding=(map [wire duct] (qeu remote-request)) - contacts=(set ship) - running=(map term running-agent-2) - blocked=(map term blocked) - == - :: - ++ running-agent-2 - $: cache=worm - control-duct=duct - live=? - =stats - =subscribers - =agent-2 - =beak - marks=(map duct mark) - == - :: - ++ agent-2 - =< form - |% - +$ step (quip card form) - +$ card (wind note gift) - +$ note note:agent - +$ task task:agent - +$ sign sign:agent - +$ gift - $% [%fact path=(unit path) =cage] - [%kick path=(unit path) ship=(unit ship)] - [%watch-ack p=(unit tang)] - [%poke-ack p=(unit tang)] - == - ++ form - $_ ^| - |_ bowl - ++ on-init - *(quip card _^|(..on-init)) - :: - ++ on-save - *vase - :: - ++ on-load - |~ old-state=vase - *(quip card _^|(..on-init)) - :: - ++ on-poke - |~ [mark vase] - *(quip card _^|(..on-init)) - :: - ++ on-watch - |~ path - *(quip card _^|(..on-init)) - :: - ++ on-leave - |~ path - *(quip card _^|(..on-init)) - :: - ++ on-peek - |~ path - *(unit (unit cage)) - :: - ++ on-agent - |~ [wire sign] - *(quip card _^|(..on-init)) - :: - ++ on-arvo - |~ [wire sign-arvo] - *(quip card _^|(..on-init)) - :: - ++ on-fail - |~ [term tang] - *(quip card _^|(..on-init)) - -- - -- - :: - ++ state-1-to-2 - |= =state-1 - ^- state-2 - %= state-1 - - %2 - +.agents-1 [~ +.agents-1.state-1] - == - :: - ++ state-1 - $: %1 - =agents-1 - == - :: - ++ agents-1 - $: system-duct=duct - contacts=(set ship) - running=(map term running-agent-2) - blocked=(map term blocked) - == - :: - ++ state-0-to-1 - |= =state-0 - ^- state-1 - %= state-0 - - %1 - running.agents-0 - %- ~(run by running.agents-0.state-0) - |= =running-agent-0 - ^- running-agent-2 - %= running-agent-0 - agent-0 (agent-0-to-1 agent-0.running-agent-0) - == - == - :: - ++ agent-0-to-1 - |= =agent-0 - ^- agent-2 - |_ =bowl:gall - +* this . - pass ~(. agent-0 bowl) - ++ on-init - =^ cards agent-0 on-init:pass - [cards this] - :: - ++ on-save - on-save:pass - :: - ++ on-load - |= old-state=vase - =^ cards agent-0 (on-load:pass old-state) - [cards this] - :: - ++ on-poke - |= [=mark =vase] - =^ cards agent-0 (on-poke:pass mark vase) - [cards this] - :: - ++ on-watch - |= =path - =^ cards agent-0 (on-watch:pass path) - [cards this] - :: - ++ on-leave - |= =path - =^ cards agent-0 (on-leave:pass path) - [cards this] - :: - ++ on-peek - |= =path - (on-peek:pass path) - :: - ++ on-agent - |= [=wire =sign:agent:gall] - =^ cards agent-0 (on-agent:pass wire sign) - [cards this] - :: - ++ on-arvo - |= [=wire =sign-arvo] - ?< ?=([%d %pack *] sign-arvo) - =^ cards agent-0 (on-arvo:pass wire `sign-arvo-0`sign-arvo) - [cards this] - :: - ++ on-fail - |= [=term =tang] - =^ cards agent-0 (on-fail:pass term tang) - [cards this] - -- - :: - ++ state-0 - $: %0 - =agents-0 - == - :: - ++ agents-0 - $: system-duct=duct - contacts=(set ship) - running=(map term running-agent-0) - blocked=(map term blocked) - == - :: - ++ running-agent-0 - $: cache=worm - control-duct=duct - live=? - =stats - =subscribers - =agent-0 - =beak - marks=(map duct mark) - == - :: - ++ agent-0 - =< form - |% - +$ step (quip card form) - +$ card (wind note gift) - +$ note note:agent - +$ task task:agent - +$ gift gift:agent-2 - +$ sign sign:agent - ++ form - $_ ^| - |_ bowl - ++ on-init - *(quip card _^|(..on-init)) - :: - ++ on-save - *vase - :: - ++ on-load - |~ old-state=vase - *(quip card _^|(..on-init)) - :: - ++ on-poke - |~ [mark vase] - *(quip card _^|(..on-init)) - :: - ++ on-watch - |~ path - *(quip card _^|(..on-init)) - :: - ++ on-leave - |~ path - *(quip card _^|(..on-init)) - :: - ++ on-peek - |~ path - *(unit (unit cage)) - :: - ++ on-agent - |~ [wire sign] - *(quip card _^|(..on-init)) - :: - ++ on-arvo - |~ [wire sign-arvo-0] - *(quip card _^|(..on-init)) - :: - ++ on-fail - |~ [term tang] - *(quip card _^|(..on-init)) - -- - -- - :: - ++ sign-arvo-0 - $% {$a gift:able:ames} - $: $b - $% gift:able:behn - [%writ riot:clay] - $>(%mere gift:able:clay) - $>(%unto gift:able:gall) - == - == - {$c gift:able:clay} - {$d $<(%pack gift:able:dill)} - {$f gift:able:ford} - [%e gift:able:eyre] - {$g gift:able:gall} - [%i gift:able:iris] - {$j gift:able:jael} - == - -- +++ load !! :: +scry: standard scry :: ++ scry ~/ %gall-scry - |= [fur=(unit (set monk)) =term =shop =desk =coin =path] + |= [fur=(unit (set monk)) care=term =shop dap=desk =coin =path] ^- (unit (unit cage)) ?. ?=(%.y -.shop) ~ - :: =/ =ship p.shop - ?: ?& =(%u term) + ?: &(=(care %$) =(path /whey)) + =/ blocked + =/ queued (~(run by blocked.state) |=((qeu blocked-move) [%.y +<])) + (sort ~(tap by queued) aor) + :: + =/ running + =/ active (~(run by yokes.state) |=(yoke [%.y +<])) + (sort ~(tap by active) aor) + :: + =/ maz=(list mass) + :~ [%foreign %.y contacts.state] + [%blocked %.n blocked] + [%active %.n running] + == + ``mass+!>(maz) + :: + ?: ?& =(%u care) =(~ path) =([%$ %da now] coin) =(our ship) == - =/ =vase !>((~(has by running.agents.state) desk)) - =/ =cage [%noun vase] - (some (some cage)) + [~ ~ noun+!>((~(has by yokes.state) dap))] :: ?. =(our ship) ~ - :: ?. =([%$ %da now] coin) ~ - :: - ?. (~(has by running.agents.state) desk) - (some ~) - :: + ?. (~(has by yokes.state) dap) + [~ ~] ?. ?=(^ path) ~ - :: - =/ initialised mo-abed:mo =/ =routes [~ ship] - (mo-peek:initialised desk routes term path) + (mo-peek:mo dap routes care path) :: +stay: save without cache :: -++ stay state +++ stay + ^- spore + =; eggs=(map term egg) state(yokes eggs) + %- ~(run by yokes.state) + |=(=yoke `egg`yoke(agent on-save:agent.yoke)) :: +take: response :: ++ take @@ -2107,16 +1740,18 @@ |= [=wire =duct dud=(unit goof) hin=(hypo sign-arvo)] ^- [(list move) _gall-payload] ?^ dud - ~|(%gall-take-dud (mean tang.u.dud)) + ~&(%gall-take-dud ((slog tang.u.dud) [~ gall-payload])) + ?: =(/nowhere wire) + [~ gall-payload] :: ~| [%gall-take-failed wire] :: ?> ?=([?(%sys %use) *] wire) - =/ initialised (mo-abed:mo duct) + =/ mo-core (mo-abed:mo duct) =/ =sign-arvo q.hin => ?- i.wire - %sys (mo-handle-sys:initialised t.wire sign-arvo) - %use (mo-handle-use:initialised t.wire hin) + %sys (mo-handle-sys:mo-core t.wire sign-arvo) + %use (mo-handle-use:mo-core t.wire hin) == mo-abet -- diff --git a/pkg/arvo/sys/vane/iris.hoon b/pkg/arvo/sys/vane/iris.hoon index 15890e55f7..0cc5de7bd3 100644 --- a/pkg/arvo/sys/vane/iris.hoon +++ b/pkg/arvo/sys/vane/iris.hoon @@ -366,20 +366,6 @@ %receive =^ moves state.ax (receive:client +.task) [moves light-gate] - :: - %wegh - :_ light-gate - :~ :* duct - %give - %mass - ^- mass - :+ %iris %| - :~ nex+&+next-id.state.ax - outbound+&+outbound-duct.state.ax - by-id+&+connection-by-id.state.ax - by-duct+&+connection-by-duct.state.ax - axle+&+ax - == == == == :: http-client issues no requests to other vanes :: @@ -404,6 +390,18 @@ :: +scry: request a path in the urbit namespace :: ++ scry - |= * + |= {fur/(unit (set monk)) ren/@tas why/shop syd/desk lot/coin tyl/path} + ^- (unit (unit cage)) + ?. ?=(%& -.why) ~ + =* his p.why + ?: &(=(ren %$) =(tyl /whey)) + =/ maz=(list mass) + :~ nex+&+next-id.state.ax + outbound+&+outbound-duct.state.ax + by-id+&+connection-by-id.state.ax + by-duct+&+connection-by-duct.state.ax + axle+&+ax + == + ``mass+!>(maz) [~ ~] -- diff --git a/pkg/arvo/sys/vane/jael.hoon b/pkg/arvo/sys/vane/jael.hoon index fd024cdc23..4fcc5f3b97 100644 --- a/pkg/arvo/sys/vane/jael.hoon +++ b/pkg/arvo/sys/vane/jael.hoon @@ -488,20 +488,6 @@ :: %private-keys (curd abet:~(private-keys ~(feed su hen our now pki etn) hen)) - :: - %wegh - %_ +> - moz - :_ moz - ^- move - :^ hen %give %mass - ^- mass - :+ %jael %| - :~ pki+&+pki - etn+&+etn - dot+&+lex - == - == :: :: authenticated remote request :: {$west p/ship q/path r/*} @@ -1023,6 +1009,12 @@ :: ?. =(lot [%$ %da now]) ~ ?. =(%$ ren) [~ ~] + ?: =(tyl /whey) + =/ maz=(list mass) + :~ pki+&+pki.lex + etn+&+etn.lex + == + ``mass+!>(maz) ?+ syd ~ :: diff --git a/pkg/arvo/sys/zuse.hoon b/pkg/arvo/sys/zuse.hoon index 11c5191940..57091eb50a 100644 --- a/pkg/arvo/sys/zuse.hoon +++ b/pkg/arvo/sys/zuse.hoon @@ -1,20 +1,19 @@ -:: :: /van/zuse -:: :: %reference/1 -:: %zuse: arvo library. +:: /sys/zuse +:: %reference/1 +:: %zuse: arvo library :: :: %zuse is two nested cores: the first for models :: (data structures), the second for engines (functions :: or classes). :: :: each of these stages is split into cores for each of -:: arvo's nine major vanes (kernel modules). these are: +:: arvo's eight major vanes (kernel modules). these are: :: :: - %ames: networking (rhymes with "games") :: - %behn: scheduling ("bane") :: - %clay: revision control ("play") :: - %dill: console ("pill") :: - %eyre: http server ("fair") -:: - %ford: build ("lord") :: - %gall: application ("ball") :: - %iris: http client ("virus") :: - %jael: security ("jail") @@ -70,6 +69,9 @@ == :: ++ coop (unit ares) :: possible error +:: +disc: a desk on a ship; can be used as a beak that varies with time +:: ++$ disc [=ship =desk] ++ life @ud :: ship key revision ++ rift @ud :: ship continuity ++ mime {p/mite q/octs} :: mimetyped data @@ -211,9 +213,6 @@ :: kernel upgraded :: [%vega ~] - :: produce labeled state (for memory measurement) - :: - [%wegh ~] :: receive message via %ames :: :: TODO: move .vane from $plea to here @@ -434,8 +433,8 @@ :: %init: vane boot :: %sift: limit verbosity to .ships :: %spew: set verbosity toggles + :: %trim: release memory :: %vega: kernel reload notification - :: %wegh: request for memory usage report :: +$ task $% [%hear =lane =blob] @@ -452,7 +451,6 @@ [%stir arg=@t] $>(%trim vane-task) $>(%vega vane-task) - $>(%wegh vane-task) == :: $gift: effect from ames :: @@ -466,7 +464,6 @@ :: :: System and Lifecycle Gifts :: - :: %mass: memory usage report :: %turf: domain report, relayed from jael :: +$ gift @@ -476,7 +473,6 @@ [%lost ~] [%send =lane =blob] :: - [%mass p=mass] [%turf turfs=(list turf)] == -- ::able @@ -797,7 +793,6 @@ |% ++ gift :: out result <-$ $% [%doze p=(unit @da)] :: next alarm - [%mass p=mass] :: memory usage [%wake error=(unit tang)] :: wakeup or failed [%meta p=vase] == @@ -812,7 +807,6 @@ $>(%vega vane-task) :: report upgrade [%wait p=@da] :: set alarm [%wake ~] :: timer activate - $>(%wegh vane-task) :: report memory == -- ::able -- ::behn @@ -834,7 +828,6 @@ {$ergo p/@tas q/mode} :: version update {$hill p/(list @tas)} :: mount points [%done error=(unit error:ames)] :: ames message (n)ack - {$mass p/mass} :: memory usage {$mere p/(each (set path) (pair term tang))} :: merge result {$note p/@tD q/tank} :: debug message {$ogre p/@tas} :: delete mount point @@ -858,15 +851,16 @@ her/@p dem/desk cas/case :: source how/germ :: method == :: - {$mont des/desk bem/beam} :: mount to unix + {$mont pot/term bem/beam} :: mount to unix {$dirk des/desk} :: mark mount dirty {$ogre pot/$@(desk beam)} :: delete mount point + {$park des/desk yok/yoki ran/rang} :: synchronous commit {$perm des/desk pax/path rit/rite} :: change permissions + {$pork ~} :: resume commit $>(%trim vane-task) :: trim state $>(%vega vane-task) :: report upgrade {$warp wer/ship rif/riff} :: internal file req {$werp who/ship wer/ship rif/riff} :: external file req - $>(%wegh vane-task) :: report memory $>(%plea vane-task) :: ames request == :: -- ::able @@ -885,7 +879,14 @@ $% {$delta p/lobe q/{p/mark q/lobe} r/page} :: delta on q {$direct p/lobe q/page} :: immediate == :: - ++ care ?($d $p $t $u $v $w $x $y $z) :: clay submode + :: +cable: a reference to something on the filesystem + :: face: the face to wrap around the imported file + :: file-path: location in clay + +$ cable + $: face=(unit term) + file-path=term + == + ++ care ?($a $b $c $d $p $r $s $t $u $v $w $x $y $z) :: clay submode ++ case :: ship desk case spur $% {$da p/@da} :: date {$tas p/@tas} :: label @@ -942,6 +943,7 @@ $% {%& p/suba} :: delta {%| p/@tas} :: label == :: + ++ open $-(path vase) :: get prelude ++ page (cask *) :: untyped cage ++ plop blob :: unvalidated blob ++ rang :: repository @@ -985,12 +987,108 @@ == :: ++ urge |*(a/mold (list (unce a))) :: list change ++ whom (each ship @ta) :: ship or named crew + ++ yoki (each yuki yaki) :: commit + ++ yuki :: proto-commit + $: p/(list tako) :: parents + q/(map path (each page lobe)) :: namespace + == :: ++ yaki :: commit $: p/(list tako) :: parents q/(map path lobe) :: namespace r/tako :: self-reference t/@da :: date == :: + :: + :: +page-to-lobe: hash a page to get a lobe. + :: + ++ page-to-lobe |=(page (shax (jam +<))) + :: + :: +make-yaki: make commit out of a list of parents, content, and date. + :: + ++ make-yaki + |= {p/(list tako) q/(map path lobe) t/@da} + ^- yaki + =+ ^= has + %^ cat 7 (sham [%yaki (roll p add) q t]) + (sham [%tako (roll p add) q t]) + [p q has t] + :: $pile: preprocessed hoon source file + :: + :: /- sur-file :: surface imports from /sur + :: /+ lib-file :: library imports from /lib + :: /= face /path :: imports built hoon file at path + :: /* face %mark /path :: unbuilt file imports, as mark + :: + +$ pile + $: sur=(list taut) + lib=(list taut) + raw=(list [face=term =path]) + bar=(list [face=term =mark =path]) + =hoon + == + :: $taut: file import from /lib or /sur + :: + +$ taut [face=(unit term) pax=term] + :: $mars: mark conversion request + :: $tube: mark conversion gate + :: + +$ mars [a=mark b=mark] + +$ tube $-(vase vase) + :: $dais: processed mark core + :: + +$ dais + $_ ^| + |_ sam=vase + ++ bunt sam + ++ diff |~(new=_sam *vase) + ++ form *mark + ++ join |~([a=vase b=vase] *(unit (unit vase))) + ++ mash + |~ [a=[ship desk diff=vase] b=[ship desk diff=vase]] + *(unit vase) + ++ pact |~(diff=vase sam) + ++ vale |~(noun sam) + ++ volt |~(noun sam) + -- + :: + ++ get-fit + |= [bek=beak pre=@tas pax=@tas] + ^- (unit path) + =/ paz (segments pax) + |- ^- (unit path) + ?~ paz + ~ + =/ puz=path (snoc `path`[pre i.paz] %hoon) + =+ .^(=arch cy+[(scot %p p.bek) q.bek (scot r.bek) puz]) + ?^ fil.arch + `puz + $(paz t.paz) + :: +segments: compute all paths from :path-part, replacing some `/`s with `-`s + :: + :: For example, when passed a :path-part of 'foo-bar-baz', + :: the product will contain: + :: ``` + :: dojo> (segments 'foo-bar-baz') + :: ~[/foo-bar-baz /foo-bar/baz /foo/bar-baz /foo/bar/baz] + :: ``` + :: + ++ segments + |= suffix=@tas + ^- (list path) + =/ parser + (most hep (cook crip ;~(plug low (star ;~(pose low nud))))) + =/ torn=(list @tas) (fall (rush suffix parser) ~[suffix]) + %- flop + |- ^- (list (list @tas)) + ?< ?=(~ torn) + ?: ?=([@ ~] torn) + ~[torn] + %- zing + %+ turn $(torn t.torn) + |= s=(list @tas) + ^- (list (list @tas)) + ?> ?=(^ s) + ~[[i.torn s] [(crip "{(trip i.torn)}-{(trip i.s)}") t.s]] -- ::clay :: :::: :::: ++dill :: (1d) console @@ -1008,11 +1106,11 @@ {$burl p/@t} :: activate url {$init p/@p} :: set owner {$logo ~} :: logout - {$lyra p/@t q/@t} :: upgrade kernel - {$mass p/mass} :: memory usage + [%lyra hoon=(unit @t) arvo=@t] :: upgrade kernel {$pack ~} :: compact memory {$veer p/@ta q/path r/@t} :: install vane {$verb ~} :: verbose mode + [%whey ~] :: memory report == :: ++ task :: in request ->$ $~ [%vega ~] :: @@ -1027,7 +1125,7 @@ {$hook ~} :: this term hung up {$harm ~} :: all terms hung up $>(%init vane-task) :: after gall ready - {$lyra p/@t q/@t} :: upgrade kernel + [%lyra hoon=(unit @t) arvo=@t] :: upgrade kernel {$noop ~} :: no operation {$pack ~} :: compact memory {$talk p/tank} :: @@ -1093,7 +1191,7 @@ ++ flog :: sent to %dill $% {$crud p/@tas q/(list tank)} :: {$heft ~} :: - {$lyra p/@t q/@t} :: upgrade kernel + [%lyra hoon=(unit @t) arvo=@t] :: upgrade kernel {$pack ~} :: compact memory {$text p/tape} :: {$veer p/@ta q/path r/@t} :: install vane @@ -1123,9 +1221,6 @@ :: not allowed. :: [%bound accepted=? =binding] - :: memory usage report - :: - [%mass p=mass] == :: ++ task @@ -1172,16 +1267,13 @@ :: the first place. :: [%disconnect =binding] - :: memory usage request - :: - $>(%wegh vane-task) == :: -- :: +outstanding-connection: open http connections not fully complete: :: :: This refers to outstanding connections where the connection to - :: outside is opened and we are currently waiting on ford or an app to + :: outside is opened and we are currently waiting on an app to :: produce the results. :: +$ outstanding-connection @@ -1324,6 +1416,9 @@ :: gall channel system :: [%channel ~] + :: gall scry endpoint + :: + [%scry ~] :: respond with the default file not found page :: [%four-oh-four ~] @@ -1567,715 +1662,6 @@ ++ user knot :: username -- ::eyre :: :::: -:::: ++ford :: (1f) build - :: :::: -:: |ford: build system vane interface -:: -++ ford ^? - |% - :: |able:ford: ford's public +move interface - :: - ++ able ^? - |% - :: +task:able:ford: requests to ford - :: - += task - $~ [%vega ~] - $% :: %build: perform a build, either live or once - :: - $: %build - :: live: whether we run this build live - :: - :: A live build will subscribe to further updates and keep the - :: build around. - :: - live=? - :: plan: the schematic to build - :: - =schematic - == - :: %keep: reset cache sizes - :: - [%keep compiler-cache=@ud build-cache=@ud] - :: %kill: stop a build; send on same duct as original %build request - :: - [%kill ~] - :: trim state (in response to memory pressure) - :: - $>(%trim vane-task) - :: %vega: report kernel upgrade - :: - $>(%vega vane-task) - :: %wegh: produce memory usage information - :: - $>(%wegh vane-task) - :: %wipe: wipes stored builds - :: - [%wipe percent-to-remove=@ud] - == - :: +gift:able:ford: responses from ford - :: - += gift - $% :: %mass: memory usage; response to %wegh +task - :: - [%mass p=mass] - :: %made: build result; response to %build +task - :: - $: %made - :: date: formal date of the build - :: - date=@da - :: result: result of the build; either complete build, or error - :: - result=made-result - == == - -- - :: +made-result: the main payload for a %made +gift - :: - += made-result - $% :: %complete: contains the result of the completed build - :: - [%complete =build-result] - :: %incomplete: couldn't finish build; contains error message - :: - [%incomplete =tang] - == - :: +disc: a desk on a ship; can be used as a beak that varies with time - :: - += disc [=ship =desk] - :: +rail: a time-varying full path - :: - :: This can be thought of as a +beam without a +case, which is what - :: would specify the time. :spur is flopped just like the +spur in a +beam. - :: - += rail [=disc =spur] - :: +resource: time-varying dependency on a value from the urbit namespace - :: - += resource - $: :: vane which we are querying - :: - vane=%c - :: type of request - :: - :: TODO: care:clay should be cleaned up in zuse as it is a general - :: type, not a clay specific one. - :: - care=care:clay - :: path on which to depend, missing time, which will be filled in - :: - =rail - == - :: +build-result: the referentially transparent result of a +build - :: - :: A +build produces either an error or a result. A result is a tagged - :: union of the various kinds of datatypes a build can produce. The tag - :: represents the sub-type of +schematic that produced the result. - :: - += build-result - $% :: %error: the build produced an error whose description is :message - :: - [%error message=tang] - :: %success: result of successful +build, tagged by +schematic sub-type - :: - $: %success - $^ [head=build-result tail=build-result] - $% [%$ =cage] - [%alts =build-result] - [%bake =cage] - [%bunt =cage] - [%call =vase] - [%cast =cage] - [%core =vase] - [%diff =cage] - [%hood =scaffold] - [%join =cage] - [%list results=(list build-result)] - [%mash =cage] - [%mute =cage] - [%pact =cage] - [%path =rail] - [%plan =vase] - [%reef =vase] - [%ride =vase] - [%scry =cage] - [%slim [=type =nock]] - [%slit =type] - [%vale =cage] - [%volt =cage] - [%walk results=(list mark-action)] - == == == - :: +mark-action: represents a single mark conversion step - :: - :: In mark conversion, we want to convert from :source to :target. We also - :: need to keep track of what type of conversion this is. If %grab, we - :: want to use the definitions in the :target mark. If %grow, we want to - :: use the :source mark. - :: - += mark-action [type=?(%grow %grab) source=term target=term] - :: - :: +schematic: plan for building - :: - ++ schematic - :: If the head of the +schematic is a pair, it's an auto-cons - :: schematic. Its result will be the pair of results of its - :: sub-schematics. - :: - $^ [head=schematic tail=schematic] - :: - $% :: %$: literal value. Produces its input unchanged. - :: - $: %$ - :: literal: the value to be produced by the build - :: - literal=cage - == - :: %pin: pins a sub-schematic to a date - :: - :: There is a difference between live builds and once builds. In - :: live builds, we produce results over and over again and aren't - :: pinned to a specifc time. In once builds, we want to specify a - :: specific date, which we apply recursively to any sub-schematics - :: contained within :schematic. - :: - :: If a build has a %pin at the top level, we consider it to be a - :: once build. Otherwise, we consider it to be a live build. We do - :: this so schematics which depend on the result of a once build can - :: be cached, giving the client explicit control over the caching - :: behaviour. - :: - $: %pin - :: date: time at which to perform the build - :: - date=@da - :: schematic: wrapped schematic of pinned time - :: - =schematic - == - :: %alts: alternative build choices - :: - :: Try each choice in :choices, in order; accept the first one that - :: succeeds. Note that the result inherits the dependencies of all - :: failed schematics, as well as the successful one. - :: - $: %alts - :: choices: list of build options to try - :: - choices=(list schematic) - == - :: %bake: run a file through a renderer - :: - $: %bake - :: renderer: name of renderer; also its file path in ren/ - :: - renderer=term - :: query-string: the query string of the renderer's http path - :: - query-string=coin - :: path-to-render: full path of file to render - :: - path-to-render=rail - == - :: %bunt: produce the default value for a mark - :: - $: %bunt - :: disc where in clay to load the mark from - :: - =disc - :: mark: name of mark; also its file path in mar/ - :: - mark=term - == - :: %call: call a gate on a sample - :: - $: %call - :: gate: schematic whose result is a gate - :: - gate=schematic - :: sample: schematic whose result will be the gate's sample - :: - sample=schematic - == - :: %cast: cast the result of a schematic through a mark - :: - $: %cast - :: disc where in clay to load the mark from - :: - =disc - :: mark: name of mark; also its file path in ren/ - :: - mark=term - :: input: schematic whose result will be run through the mark - :: - input=schematic - == - :: %core: build a hoon program from a source file - :: - $: %core - :: source-path: clay path from which to load hoon source - :: - source-path=rail - == - :: %diff: produce marked diff from :first to :second - :: - $: %diff - :: disc where in clay to load the mark from - :: - =disc - :: old: schematic producing data to be used as diff starting point - :: - start=schematic - :: new: schematic producing data to be used as diff ending point - :: - end=schematic - == - :: %dude: wrap a failure's error message with an extra message - :: - $: %dude - :: error: a trap producing an error message to wrap the original - :: - error=tank - :: attempt: the schematic to try, whose error we wrap, if any - :: - attempt=schematic - == - :: %hood: create a +hood from a hoon source file - :: - $: %hood - :: source-path: clay path from which to load hoon source - :: - source-path=rail - == - :: %join: merge two diffs into one diff; produces `~` if conflicts - :: - $: %join - :: disc where in clay to load the mark from - :: - =disc - :: mark: name of the mark to use for diffs; also file path in mar/ - :: - mark=term - :: first: schematic producing first diff - :: - first=schematic - :: second: schematic producing second diff - :: - second=schematic - == - :: %list: performs a list of schematics, returns a list of +builds-results - :: - $: %list - :: schematics: list of builds to perform - :: - schematics=(list schematic) - == - :: %mash: force a merge, annotating any conflicts - :: - $: %mash - :: disc where in clay to load the mark from - :: - =disc - :: mark: name of mark used in diffs; also file path in mar/ - :: - mark=term - :: first: marked schematic producing first diff - :: - first=[=disc mark=term =schematic] - :: second: marked schematic producing second diff - :: - second=[=disc mark=term =schematic] - == - :: %mute: mutate a noun by replacing its wings with new values - :: - $: %mute - :: subject: schematic producing the noun to mutate - :: - subject=schematic - :: mutations: axes and schematics to produce their new contents - :: - mutations=(list (pair wing schematic)) - == - :: %pact: patch a marked noun by applying a diff - :: - $: %pact - :: disc where in clay to load marks from - :: - =disc - :: start: schematic producing a noun to be patched - :: - start=schematic - :: diff: schematic producing the diff to apply to :start - :: - diff=schematic - == - :: %path: resolve a path with `-`s to a path with `/`s - :: - :: Resolve +raw-path to a path containing a file, replacing - :: any `-`s in the path with `/`s if no file exists at the - :: original path. Produces an error if multiple files match, - :: e.g. a/b/c and a/b-c, or a/b/c and a-b/c. - :: - $: %path - :: disc: the +disc forming the base of the path to be resolved - :: - =disc - :: prefix: path prefix under which to resolve :raw-path, e.g. lib - :: - prefix=@tas - :: raw-path: the file path to be resolved - :: - raw-path=@tas - == - :: %plan: build a hoon program from a preprocessed source file - :: - $: %plan - :: path-to-render: the clay path of a file being rendered - :: - :: TODO: Once we've really implemented this, write the - :: documentation. (This is the path that starts out as the path - :: of the hoon source which generated the scaffold, but can be - :: changed with `/:`.) - :: - path-to-render=rail - :: query-string: the query string of the http request - :: - query-string=coin - :: scaffold: preprocessed hoon source and imports - :: - =scaffold - == - :: %reef: produce a hoon+zuse kernel. used internally for caching - :: - $: %reef - :: disc: location of sys/hoon/hoon and sys/zuse/hoon - :: - =disc - == - :: %ride: eval hoon as formula with result of a schematic as subject - :: - $: %ride - :: formula: a hoon to be evaluated against a subject - :: - formula=hoon - :: subject: a schematic whose result will be used as subject - :: - subject=schematic - == - :: %same: the identity function - :: - :: Functionally used to "unpin" a build for caching reasons. If you - :: run a %pin build, it is treated as a once build and is therefore - :: not cached. Wrapping the %pin schematic in a %same schematic - :: converts it to a live build, which will be cached due to live - :: build subscription semantics. - :: - $: %same - :: schematic that we evaluate to - :: - =schematic - == - :: %scry: lookup a value from the urbit namespace - :: - $: %scry - :: resource: a namespace request, with unspecified time - :: - :: Schematics can only be resolved when specifying a time, - :: which will convert this +resource into a +scry-request. - :: - =resource - == - :: %slim: compile a hoon against a subject type - :: - $: %slim - :: compile-time subject type for the :formula - :: - subject-type=type - :: formula: a +hoon to be compiled to (pair type nock) - :: - formula=hoon - == - :: %slit: get type of gate product - :: - $: %slit - :: gate: a vase containing a gate - :: - gate=vase - :: sample: a vase containing the :gate's sample - :: - sample=vase - == - :: %vale: coerce a noun to a mark, validated - :: - $: %vale - :: disc where in clay to load the mark from - :: - =disc - :: mark: name of mark to use; also file path in mar/ - :: - mark=term - :: input: the noun to be converted using the mark - :: - input=* - == - :: %volt: coerce a noun to a mark, unsafe - :: - $: %volt - :: disc where in clay to load the mark from - :: - =disc - :: mark: name of mark to use; also file path in mar/ - :: - mark=term - :: input: the noun to be converted using the mark - :: - input=* - == - :: %walk: finds a mark conversion path between two marks - :: - $: %walk - :: disc in clay to load the marks from - :: - =disc - :: source: the original mark type - :: - source=term - :: target: the destination mark type - :: - target=term - == - == - :: - :: +scaffold: program construction in progress - :: - :: A source file with all its imports and requirements, which will be - :: built and combined into one final product. - :: - += scaffold - $: :: source-rail: the file this scaffold was parsed from - :: - source-rail=rail - :: zuse-version: the kelvin version of the standard library - :: - zuse-version=@ud - :: structures: files from %/sur which are included - :: - structures=(list cable) - :: libraries: files from %/lib which are included - :: - libraries=(list cable) - :: cranes: a list of resources to transform and include - :: - cranes=(list crane) - :: sources: hoon sources, either parsed or on the filesystem - :: - sources=(list hoon) - == - :: +cable: a reference to something on the filesystem - :: - += cable - $: :: face: the face to wrap around the imported file - :: - face=(unit term) - :: file-path: location in clay - :: - file-path=term - == - :: +truss: late-bound path - :: - :: TODO: the +tyke data structure should be rethought, possibly as part - :: of this effort since it is actually a `(list (unit hoon))`, when it - :: only represents @tas. It should be a structure which explicitly - :: represents a path with holes that need to be filled in. - :: - += truss - $: pre=(unit tyke) - pof=(unit [p=@ud q=tyke]) - == - :: +crane: parsed rune used to include and transform resources - :: - :: Cranes lifting cranes lifting cranes! - :: - :: A recursive tree of Ford directives that specifies instructions for - :: including and transforming resources from the Urbit namespace. - :: - += crane - $% $: :: %fssg: `/~` hoon literal - :: - :: `/~ ` produces a crane that evaluates arbitrary hoon. - :: - %fssg - =hoon - == - $: :: %fsbc: `/$` process query string - :: - :: `/$` will call a gate with the query string supplied to this - :: build. If no query string, this errors. - :: - %fsbc - =hoon - == - $: :: %fsbr: `/|` first of many options that succeeds - :: - :: `/|` takes a series of cranes and produces the first one - :: (left-to-right) that succeeds. If none succeed, it produces - :: stack traces from all of its arguments. - :: - %fsbr - :: choices: cranes to try - :: - choices=(list crane) - == - $: :: %fsts: `/=` wrap a face around a crane - :: - :: /= runs a crane (usually produced by another ford rune), takes - :: the result of that crane, and wraps a face around it. - :: - %fsts - :: face: face to apply - :: - face=term - :: crane: internal build step - :: - =crane - == - $: :: %fsdt: `/.` null-terminated list - :: - :: Produce a null-terminated list from a sequence of cranes, - :: terminated by a `==`. - :: - %fsdt - :: items: cranes to evaluate - :: - items=(list crane) - == - $: :: %fscm: `/,` switch by path - :: - :: `/,` is a switch statement, which picks a branch to evaluate - :: based on whether the current path matches the path in the - :: switch statement. Takes a sequence of pairs of (path, crane) - :: terminated by a `==`. - :: - %fscm - :: cases: produces evaluated crane of first +spur match - :: - cases=(list (pair spur crane)) - == - $: :: %fspm: `/&` pass through a series of marks - :: - :: `/&` passes a crane through multiple marks, right-to-left. - :: - %fspm - :: marks: marks to apply to :crane, in reverse order - :: - marks=(list mark) - =crane - == - $: :: %fscb: `/_` run a crane on each file in the current directory - :: - :: `/_` takes a crane as an argument. It produces a new crane - :: representing the result of mapping the supplied crane over the - :: list of files in the current directory. The keys in the - :: resulting map are the basenames of the files in the directory, - :: and each value is the result of running that crane on the - :: contents of the file. - :: - %fscb - =crane - == - $: :: %fssm: `/;` operate on - :: - :: `/;` takes a hoon and a crane. The hoon should evaluate to a - :: gate, which is then called with the result of the crane as its - :: sample. - :: - %fssm - =hoon - =crane - == - $: :: %fscl: `/:` evaluate at path - :: - :: `/:` takes a path and a +crane, and evaluates the crane with - :: the current path set to the supplied path. - :: - %fscl - :: path: late bound path to be resolved relative to current beak - :: - :: This becomes current path of :crane - :: - path=truss - =crane - == - $: :: %fskt: `/^` cast - :: - :: `/^` takes a +mold and a +crane, and casts the result of the - :: crane to the mold. - :: - %fskt - :: mold: evaluates to a mold to be applied to :crane - :: - =spec - =crane - == - $: :: %fstr: `/*` run :crane on all files with current path as prefix - :: - %fstr - =crane - == - $: :: %fszp: `/!mark/` evaluate as hoon, then pass through mark - :: - %fszp - =mark - == - $: :: %fszy: `/mark/` passes current path through :mark - :: - %fszy - =mark - == == - :: +result-to-cage: extract a +cage from a +build-result - :: - ++ result-to-cage - |= result=build-result - ^- cage - ?: ?=(%error -.result) - [%tang !>(message.result)] - ?- -.+.result - ^ [%noun (slop q:$(result head.result) q:$(result tail.result))] - %$ cage.result - %alts $(result build-result.result) - %bake cage.result - %bunt cage.result - %call [%noun vase.result] - %cast cage.result - %core [%noun vase.result] - %diff cage.result - %hood [%noun !>(scaffold.result)] - %join cage.result - %list [%noun -:!>(*(list cage)) (turn results.result result-to-cage)] - %mash cage.result - %mute cage.result - %pact cage.result - %path [%noun !>(rail.result)] - %plan [%noun vase.result] - %reef [%noun vase.result] - %ride [%noun vase.result] - %scry cage.result - %slim [%noun !>([type nock]:result)] - %slit [%noun !>(type.result)] - %vale cage.result - %volt cage.result - %walk [%noun !>(results.result)] - == - :: +result-as-error: extracts a tang out of a made-result - :: - ++ made-result-as-error - |= result=made-result - ^- tang - ?: ?=([%incomplete *] result) - tang.result - ?: ?=([%complete %error *] result) - message.build-result.result - ~ - -- -:: :::: :::: ++gall :: (1g) extensions :: :::: ++ gall ^? @@ -2288,13 +1674,12 @@ ++ gift :: outgoing result $% [%boon payload=*] :: ames response [%done error=(unit error:ames)] :: ames message (n)ack - [%mass p=mass] :: memory usage [%onto p=(each suss tang)] :: about agent [%unto p=sign:agent] :: == :: ++ task :: incoming request $~ [%vega ~] :: - $% [$conf p=dock q=dock] :: configure app + $% [%conf dap=term] :: start agent [$deal p=sock q=term r=deal] :: full transmission [%goad force=? agent=(unit dude)] :: rebuild agent(s) [%sear =ship] :: clear pending queues @@ -2302,8 +1687,6 @@ $>(%trim vane-task) :: trim state $>(%vega vane-task) :: report upgrade $>(%plea vane-task) :: network request - [%wash ~] :: clear caches - $>(%wegh vane-task) :: report memory == :: -- ::able ++ bitt (map duct (pair ship path)) :: incoming subs @@ -2435,9 +1818,6 @@ :: %response: response to the caller :: [%http-response =client-response] - :: memory usage report - :: - [%mass p=mass] == :: ++ task @@ -2463,9 +1843,6 @@ :: receives http data from outside :: [%receive id=@ud =http-event:http] - :: memory usage request - :: - $>(%wegh vane-task) == -- :: +client-response: one or more client responses given to the caller @@ -2549,7 +1926,6 @@ :: :: ++ gift :: out result <-$ $% [%init p=ship] :: report install unix - [%mass p=mass] :: memory usage report [%done error=(unit error:ames)] :: ames message (n)ack [%boon payload=*] :: ames response [%private-keys =life vein=(map life ring)] :: private keys @@ -2575,7 +1951,6 @@ $>(%trim vane-task) :: trim state [%turf ~] :: view domains $>(%vega vane-task) :: report upgrade - $>(%wegh vane-task) :: memory usage request $>(%plea vane-task) :: ames request == :: :: @@ -2765,7 +2140,6 @@ gift:able:clay gift:able:dill gift:able:eyre - gift:able:ford gift:able:gall gift:able:iris gift:able:jael @@ -2776,7 +2150,6 @@ task:able:behn task:able:dill task:able:eyre - task:able:ford task:able:gall task:able:iris task:able:jael @@ -2788,7 +2161,6 @@ {$c task:able:clay} {$d task:able:dill} [%e task:able:eyre] - {$f task:able:ford} {$g task:able:gall} [%i task:able:iris] {$j task:able:jael} @@ -2798,14 +2170,14 @@ $% {$a gift:able:ames} $: $b $% gift:able:behn - [%writ riot:clay] + $>(%wris gift:able:clay) + $>(%writ gift:able:clay) $>(%mere gift:able:clay) $>(%unto gift:able:gall) == == {$c gift:able:clay} {$d gift:able:dill} - {$f gift:able:ford} [%e gift:able:eyre] {$g gift:able:gall} [%i gift:able:iris] diff --git a/pkg/arvo/ted/build-cast.hoon b/pkg/arvo/ted/build-cast.hoon new file mode 100644 index 0000000000..808859fd0e --- /dev/null +++ b/pkg/arvo/ted/build-cast.hoon @@ -0,0 +1,12 @@ +/- spider +/+ strandio +=, strand=strand:spider +^- thread:spider +|= arg=vase +=/ m (strand ,vase) +^- form:m +=+ !<([a=mark b=mark ~] arg) +;< =bowl:spider bind:m get-bowl:strandio +=/ bek=beak [our q.byk da+now]:bowl +;< =tube:clay bind:m (build-cast:strandio bek a b) +(pure:m !>(tube)) diff --git a/pkg/arvo/ted/build-file.hoon b/pkg/arvo/ted/build-file.hoon new file mode 100644 index 0000000000..a1a6d3ff7c --- /dev/null +++ b/pkg/arvo/ted/build-file.hoon @@ -0,0 +1,11 @@ +/- spider +/+ strandio +=, strand=strand:spider +^- thread:spider +|= arg=vase +=/ m (strand ,vase) +^- form:m +=+ !<([pax=path ~] arg) +;< =bowl:spider bind:m get-bowl:strandio +=/ bek=beak [our q.byk da+now]:bowl +(build-file:strandio bek (flop pax)) diff --git a/pkg/arvo/ted/build-mark.hoon b/pkg/arvo/ted/build-mark.hoon new file mode 100644 index 0000000000..d65fc9d257 --- /dev/null +++ b/pkg/arvo/ted/build-mark.hoon @@ -0,0 +1,12 @@ +/- spider +/+ strandio +=, strand=strand:spider +^- thread:spider +|= arg=vase +=/ m (strand ,vase) +^- form:m +=+ !<([mak=mark ~] arg) +;< =bowl:spider bind:m get-bowl:strandio +=/ bek=beak [our q.byk da+now]:bowl +;< =dais:clay bind:m (build-mark:strandio bek mak) +(pure:m !>(dais)) diff --git a/pkg/arvo/ted/ph/breach-sync.hoon b/pkg/arvo/ted/ph/breach-sync.hoon index d8a4ac09fb..833ececd19 100644 --- a/pkg/arvo/ted/ph/breach-sync.hoon +++ b/pkg/arvo/ted/ph/breach-sync.hoon @@ -11,13 +11,13 @@ ;< ~ bind:m (spawn az ~marbud) ;< ~ bind:m (real-ship az ~bud) ;< ~ bind:m (real-ship az ~marbud) -;< file=@t bind:m (touch-file ~bud %base %foo) +;< file=@t bind:m (touch-file ~bud %kids %foo) ;< ~ bind:m (check-file-touched ~marbud %home file) ;< ~ bind:m (breach-and-hear az ~bud ~marbud) ;< ~ bind:m (real-ship az ~bud) -;< ~ bind:m (dojo ~bud "|merge %base ~marbud %kids, =gem %this") -;< file=@t bind:m (touch-file ~bud %base %bar) -;< file=@t bind:m (touch-file ~bud %base %baz) +;< ~ bind:m (dojo ~bud "|merge %kids ~marbud %kids, =gem %this") +;< file=@t bind:m (touch-file ~bud %kids %bar) +;< file=@t bind:m (touch-file ~bud %kids %baz) ;< ~ bind:m (check-file-touched ~marbud %home file) ;< ~ bind:m end-azimuth (pure:m *vase) diff --git a/pkg/arvo/ted/ph/child-update.hoon b/pkg/arvo/ted/ph/child-update.hoon new file mode 100644 index 0000000000..fc0878ad2c --- /dev/null +++ b/pkg/arvo/ted/ph/child-update.hoon @@ -0,0 +1,54 @@ +/- spider +/+ *ph-io +=, strand=strand:spider +^- thread:spider +|= vase +|^ +=/ m (strand ,vase) +;< ~ bind:m start-simple +;< ~ bind:m (raw-ship ~bud ~) +;< ~ bind:m (raw-ship ~marbud ~) +;< [path @t] bind:m (modify ~bud %home) +;< [=path file=@t] bind:m (modify ~bud %kids) +;< ~ bind:m (check-touched ~marbud %kids path file) +;< ~ bind:m end-simple +(pure:m *vase) +:: +++ modify + |= [her=@p =desk] + =/ m (strand ,[path @t]) + ^- form:m + ;< ~ bind:m (mount her desk) + ;< our=@p bind:m get-our + ;< now=@da bind:m get-time + |^ + =/ zuse-contents + %^ cat 3 '=/ new-val 57 ' + (get-val /sys/zuse/hoon) + =/ mar-contents + %^ cat 3 (get-val /mar/js/hoon) + ' ~& > new-val=new-val .' + =/ js-contents + %^ cat 3 (get-val /app/publish/js/index/js) + 'extra' + =/ files + :~ [/sys/zuse/hoon zuse-contents] + [/mar/js/hoon mar-contents] + [/app/publish/js/index/js js-contents] + == + ;< ~ bind:m (send-events (insert-files:util her desk files)) + (pure:m /app/publish/js/index/js js-contents) + :: + ++ aqua-path + |= =path + ;: weld + /i/(scot %p her)/cx/(scot %p her)/[desk]/(scot %da now) + path + /noun + == + :: + ++ get-val + |= =path + (need (scry-aqua:util (unit @) our now (aqua-path path))) + -- +-- diff --git a/pkg/arvo/ted/read.hoon b/pkg/arvo/ted/read.hoon new file mode 100644 index 0000000000..12816e9850 --- /dev/null +++ b/pkg/arvo/ted/read.hoon @@ -0,0 +1,18 @@ +/- spider +/+ strandio +=, strand=strand:spider +^- thread:spider +|= arg=vase +=/ m (strand ,vase) +^- form:m +:: Parse arguments as ship, desk, and path +:: +=+ !<([=care:clay =ship =desk =case =target=path ~] arg) +:: Read the file, possibly asyncrhonously +:: +;< =bowl:spider bind:m get-bowl:strandio +;< =riot:clay bind:m + (warp:strandio ship desk ~ %sing care case target-path) +?~ riot + (pure:m !>("nothing")) +(pure:m q.r.u.riot) diff --git a/pkg/arvo/ted/test.hoon b/pkg/arvo/ted/test.hoon new file mode 100644 index 0000000000..d9f428ea7f --- /dev/null +++ b/pkg/arvo/ted/test.hoon @@ -0,0 +1,127 @@ +/- spider +/+ strandio +=, strand=strand:spider +=> +|% +:: $test: a test with a fully resolved path +:: $test-arm: test with name (derived from its arm name in a test core) +:: $test-func: single test, as gate; sample is entropy, produces failures +:: ++$ test [=path func=test-func] ++$ test-arm [name=term func=test-func] ++$ test-func (trap tang) +-- +=> +|% +:: +run-test: execute an individual test +:: +++ run-test + |= [pax=path test=test-func] + ^- [ok=? =tang] + =+ name=(spud pax) + =+ run=(mule test) + ?- -.run + %| |+(welp p.run leaf+"CRASHED {name}" ~) + %& ?: =(~ p.run) + &+[leaf+"OK {name}"]~ + |+(flop `tang`[leaf+"FAILED {name}" p.run]) + == +:: +filter-tests-by-prefix: TODO document +:: +++ filter-tests-by-prefix + |= [prefix=path tests=(list test)] + ^+ tests + =/ prefix-length=@ud (lent prefix) + (skim tests |=([p=path *] =(prefix (scag prefix-length p)))) +:: +resolve-test-paths: add test names to file paths to form full identifiers +:: +++ resolve-test-paths + |= paths-to-tests=(map path (list test-arm)) + ^- (list test) + %- sort :_ |=([a=test b=test] !(aor path.a path.b)) + ^- (list test) + %- zing + %+ turn ~(tap by paths-to-tests) + |= [=path test-arms=(list test-arm)] + ^- (list test) + :: strip off leading 'tests' from :path + :: + =. path ?>(?=([%tests *] path) t.path) + :: for each test, add the test's name to :path + :: + %+ turn test-arms + |= =test-arm + ^- test + [(weld path /[name.test-arm]) func.test-arm] +:: +get-test-arms: convert test arms to functions and produce them +:: +++ get-test-arms + |= [typ=type cor=*] + ^- (list test-arm) + =/ arms=(list @tas) (sloe typ) + %+ turn (skim arms has-test-prefix) + |= name=term + ^- test-arm + =/ fire-arm=nock + ~| [%failed-to-compile-test-arm name] + q:(~(mint ut typ) p:!>(*tang) [%limb name]) + [name |.(;;(tang .*(cor fire-arm)))] +:: +has-test-prefix: does the arm define a test we should run? +:: +++ has-test-prefix + |= a=term ^- ? + =((end 3 5 a) 'test-') +:: +++ find-test-files + =| fiz=(set [=beam test=(unit term)]) + =/ m (strand ,_fiz) + |= bez=(list beam) + ^- form:m + =* loop $ + ?~ bez + (pure:m fiz) + ;< hav=? bind:m (check-for-file:strandio -.i.bez hoon+s.i.bez) + ?: hav + loop(bez t.bez, fiz (~(put in fiz) [i.bez(s hoon+s.i.bez) ~])) + ;< fez=(list path) bind:m (list-tree:strandio i.bez) + ?. =(~ fez) + =/ foz (turn fez |=(path [[-.i.bez (flop +<)] ~])) + loop(bez t.bez, fiz (~(gas in fiz) foz)) + ~| bad-test-beam+i.bez + =/ tex=term =-(?>(((sane %tas) -) -) (head s.i.bez)) + =/ xup=path (tail s.i.bez) + ;< hov=? bind:m (check-for-file:strandio i.bez(s hoon+xup)) + ?. hov + ~|(no-tests-at-path+i.bez !!) + loop(bez t.bez, fiz (~(put in fiz) [[-.i.bez hoon+xup] `tex])) +-- +^- thread:spider +|= arg=vase +=/ m (strand ,vase) +^- form:m +=/ bez=(list beam) + (turn !<((list path) arg) |=(p=path (need (de-beam:format p)))) +;< fiz=(set [=beam test=(unit term)]) bind:m (find-test-files bez) +=> .(fiz (sort ~(tap in fiz) aor)) +=| test-arms=(map path (list test-arm)) +|- ^- form:m +=* gather-tests $ +?^ fiz + ~> %slog.0^leaf+"test: building {(spud (flop s.beam.i.fiz))}" + ;< cor=vase bind:m (build-file:strandio beam.i.fiz) + =/ arms=(list test-arm) (get-test-arms cor) + =? arms ?=(^ test.i.fiz) + |- ^+ arms + ?~ arms ~|(no-test-arm+i.fiz !!) + ?: =(name.i.arms u.test.i.fiz) + [i.arms]~ + $(arms t.arms) + =. test-arms (~(put by test-arms) (flop (tail s.beam.i.fiz)) arms) + gather-tests(fiz t.fiz) +%- pure:m !> ^= ok +%+ roll (resolve-test-paths test-arms) +|= [[=path =test-func] ok=_`?`%&] +^+ ok +=/ res (run-test path test-func) +%- (slog (flop tang.res)) +&(ok ok.res) diff --git a/pkg/arvo/ted/tree.hoon b/pkg/arvo/ted/tree.hoon new file mode 100644 index 0000000000..63dec6e08b --- /dev/null +++ b/pkg/arvo/ted/tree.hoon @@ -0,0 +1,11 @@ +/- spider +/+ strandio +=, strand=strand:spider +^- thread:spider +|= arg=vase +=/ m (strand ,vase) +^- form:m +=+ !<([pax=path ~] arg) +;< bek=beak bind:m get-beak:strandio +;< paz=(list path) bind:m (list-tree:strandio bek (flop pax)) +(pure:m !>(paz)) diff --git a/pkg/arvo/ted/work.hoon b/pkg/arvo/ted/work.hoon new file mode 100644 index 0000000000..adbb4fa451 --- /dev/null +++ b/pkg/arvo/ted/work.hoon @@ -0,0 +1,36 @@ +:: -work: create and mount development desk(s) +:: +:: With no arguments, creates and mounts a %work desk. +:: If there are arguments, each one is created and mounted. +:: All desks are begun by merging from our %home desk. +:: +/- spider +/+ strandio +=, strand=strand:spider +^- thread:spider +|= arg=vase +=/ m (strand ,vase) +^- form:m +=+ !<(desks=(list desk) arg) +=? desks =(~ desks) [%work]~ +|- ^- form:m +=* loop $ +?~ desks (pure:m !>(ok=&)) +:: |merge %work our %home +:: +;< [=ship =desk =case:clay] bind:m get-beak:strandio +=/ kiln-merge [i.desks ship %home case %auto] +;< ~ bind:m (poke-our:strandio %hood %kiln-merge !>(kiln-merge)) +;< ~ bind:m (trace:strandio leaf+"work: merged {}" ~) +:: sleep 10ms to defer to new event +:: +:: TODO: This crashes if it's in the same event for some reason. +:: +;< ~ bind:m (sleep:strandio `@dr`(div ~s1 100)) +:: |mount %work +:: +=/ pax=path (en-beam:format [ship i.desks case] /) +;< ~ bind:m (poke-our:strandio %hood %kiln-mount !>([pax i.desks])) +;< ~ bind:m (trace:strandio leaf+"work: mounted {}" ~) +:: +loop(desks t.desks) diff --git a/pkg/arvo/tests/sys/vane/ames.hoon b/pkg/arvo/tests/sys/vane/ames.hoon index ae1ceb3524..83bc5a4b52 100644 --- a/pkg/arvo/tests/sys/vane/ames.hoon +++ b/pkg/arvo/tests/sys/vane/ames.hoon @@ -1,6 +1,5 @@ /+ *test -/= ames /: /===/sys/vane/ames - /!noun/ +/= ames /sys/vane/ames :: construct some test fixtures :: =/ vane (ames !>(..zuse)) diff --git a/pkg/arvo/tests/sys/vane/clay.hoon b/pkg/arvo/tests/sys/vane/clay.hoon index 1ffe326538..76b0f43dea 100644 --- a/pkg/arvo/tests/sys/vane/clay.hoon +++ b/pkg/arvo/tests/sys/vane/clay.hoon @@ -1,460 +1,169 @@ -/+ *test, test-ford-external -:: -/= clay-raw /: /===/sys/vane/clay /!noun/ +/+ *test +/= clay-raw /sys/vane/clay +/* hello-gen %hoon /gen/hello/hoon +/* strandio-lib %hoon /lib/strandio/hoon +/* strand-lib %hoon /lib/strand/hoon +/* spider-sur %hoon /sur/spider/hoon :: !: =, format :: -=/ test-pit=vase !>(..zuse) -=/ clay-gate (clay-raw test-pit) +=/ bud=vase !>(..zuse) +=/ clay-gate (clay-raw bud) +=/ fusion fusion:clay-gate :: |% -++ test-info ^- tang - =^ results0 clay-gate - %- clay-call :* - clay-gate - now=~1111.1.1 - scry=*sley - call-args=[duct=~[/init] -:!>(*task:able:clay) [%init ~nul]] - expected-moves=~ +++ test-parse-pile ^- tang + %+ expect-eq + !> ^- pile:fusion + :* ~ ~ ~ ~ + tssg+[%dbug [/sur/foo/hoon [[1 1] [1 2]]] [%cnts ~[[%.y 1]] ~]]~ + == + !> (parse-pile:(ford):fusion /sur/foo/hoon ".") +:: +++ test-parse-multiline-faslus ^- tang + =/ src + """ + :: :: :: + :::: /hoon/hood/app :: :: + :: :: :: + /? 310 :: zuse version + /- *sole + /+ sole :: libraries + :: XX these should really be separate apps, as + :: none of them interact with each other in + :: any fashion; however, to reduce boot-time + :: complexity and work around the current + :: non-functionality of end-to-end acknowledgments, + :: they have been bundled into :hood + :: + :: |command handlers + /+ hood-helm, hood-kiln, hood-drum, hood-write + :: :: :: + . + """ + %+ expect-eq + !> ^- pile:fusion + :* sur=`(list taut:fusion)`[~ %sole]~ + ^= lib ^- (list taut:fusion) + :~ [`%sole %sole] + [`%hood-helm %hood-helm] + [`%hood-kiln %hood-kiln] + [`%hood-drum %hood-drum] + [`%hood-write %hood-write] + == + raw=~ bar=~ + hoon=tssg+[p:(need q:(tall:(vang & /app/hood/hoon) [17 1] "."))]~ + == + !> (parse-pile:(ford):fusion /app/hood/hoon src) +:: +++ test-cycle ^- tang + =/ source=@t + ''' + /+ self + . + ''' + =/ =ankh:clay + :- fil=~ + %- ~(gas by *(map @tas ankh:clay)) + :~ :+ %lib fil=~ + %- ~(gas by *(map @tas ankh:clay)) + :~ :+ %self fil=~ + %- ~(gas by *(map @tas ankh:clay)) + :~ :+ %hoon fil=`[*lobe:clay hoon+!>(source)] dir=~ + == == == + %- expect-fail + |. + =/ ford + %: ford:fusion + bud + ankh + deletes=~ + changes=~ + file-store=~ + *ford-cache:fusion == - :: - =^ results1 clay-gate - %- clay-call-with-comparator :* - clay-gate - now=~1111.1.1 - scry=*sley - ^= call-args - :+ duct=~[/info] type=-:!>(*task:able:clay) - ^- task:able:clay - :+ %info %home - ^- nori:clay - :- %& - ^- soba:clay - :~ [/file1/noun `miso:clay`[%ins [%noun %noun 'file1']]] - [/file2/noun `miso:clay`[%ins [%noun %noun 'file2']]] - == - ^= move-comparator - |= moves=(list move:clay-gate) - ^- tang - :: - ?. ?=([* ~] moves) - [%leaf "wrong number of moves: {<(lent moves)>}"]~ - :: - ^- tang - ;: weld - :: - ^- tang - :: - =/ move=move:clay-gate i.moves - =/ =duct p.move - =/ card=(wind note:clay-gate gift:able:clay) q.move - :: - %+ weld - (expect-eq !>(~[/info]) !>(duct)) - :: - ?. ?=(%pass -.card) - [%leaf "bad move, not a %pass: {}"]~ - :: - =/ =wire p.card - :: - %+ weld - (expect-eq !>(/commit/home/inserts) !>(wire)) - :: - =/ note=note:clay-gate q.card - :: - ?. ?=([%f %build *] note) - [%leaf "bad move, not a %build: {}"]~ - :: - %+ weld - (expect-eq !>(%.n) !>(live.note)) - :: - %- expect-schematic:test-ford-external - :_ schematic.note - ^- schematic:ford - :+ %pin ~1111.1.1 - :- %list - :~ :- [%$ %path -:!>(*path) /file1/noun] - :^ %cast [~nul %home] %noun - [%$ %noun %noun 'file1'] - :: - :- [%$ %path -:!>(*path) /file2/noun] - :^ %cast [~nul %home] %noun - [%$ %noun %noun 'file2'] - == - == == - :: - :: inserting - :: - =^ results2 clay-gate - %- clay-take-with-comparator :* - clay-gate - now=~1111.1.1 - scry=*sley - ^= take-args - :* wire=/commit/home/inserts - duct=~[/info] - -:!>(*sign:clay-gate) - ^- sign:clay-gate - :* %f %made ~1111.1.1 %complete %success %list - ^- (list build-result:ford) - :~ :+ %success - [%success %$ %path -:!>(*path) /file1/noun] - [%success %cast %noun %noun 'file1'] - :: - :+ %success - [%success %$ %path -:!>(*path) /file2/noun] - [%success %cast %noun %noun 'file2'] - == == == - ^= comparator - |= moves=(list move:clay-gate) - ^- tang - :: - ?. ?=([* ~] moves) - [%leaf "wrong number of moves: {<(lent moves)>}"]~ - :: - %+ expect-eq - !> ^- move:clay-gate - :- duct=~[/info] - ^- (wind note:clay-gate gift:able:clay) - :+ %pass /commit/home/diffs - ^- note:clay-gate - :- %f - [%build live=%.n [%pin ~1111.1.1 [%list ~]]] - !> i.moves - == :: == - :: - :: diffing - :: - =^ results3 clay-gate - %- clay-take-with-comparator :* - clay-gate - now=~1111.1.1 - scry=*sley - ^= take-args - :* wire=/commit/home/diffs - duct=~[/info] - -:!>(*sign:clay-gate) - ^- sign:clay-gate - [%f %made ~1111.1.1 %complete %success %list ~] - == - ^= move-comparator - |= moves=(list move:clay-gate) - ^- tang - :: - ?. ?=([* ~] moves) - [%leaf "wrong number of moves: {<(lent moves)>}"]~ - :: - %+ expect-eq - !> ^- move:clay-gate - :- duct=~[/info] - ^- (wind note:clay-gate gift:able:clay) - :+ %pass /commit/home/casts - ^- note:clay-gate - :- %f - [%build live=%.n [%pin ~1111.1.1 [%list ~]]] - !> i.moves + (build-file:ford /lib/self/hoon) +:: +++ test-parse-fail ^- tang + %- expect-fail + |. (parse-pile:(ford):fusion /sur/foo/hoon "[") +:: +++ test-hello-gen ^- tang + =/ =ankh:clay + :- fil=~ + %- ~(gas by *(map @tas ankh:clay)) + :~ :+ %gen fil=~ + %- ~(gas by *(map @tas ankh:clay)) + :~ :+ %hello fil=~ + %- ~(gas by *(map @tas ankh:clay)) + :~ :+ %hoon fil=`[*lobe:clay hoon+!>(hello-gen)] dir=~ + == == == + =/ ford + %: ford:fusion + bud + ankh + deletes=~ + changes=(my [/gen/hello/hoon &+hoon+hello-gen]~) + file-store=~ + *ford-cache:fusion == + =/ [res=vase nub=state:ford:fusion] (build-file:ford /gen/hello/hoon) + ;: weld + %+ expect-eq + !> noun+'hello, bob' + (slap res (ream '(+ [*^ [%bob ~] ~])')) :: - :: castifying - :: - =^ results4 clay-gate - %- clay-take-with-comparator :* - clay-gate - now=~1111.1.1 - scry=*sley - ^= take-args - :* wire=/commit/home/casts - duct=~[/info] - -:!>(*sign:clay-gate) - ^- sign:clay-gate - [%f %made ~1111.1.1 %complete %success %list ~] - == - ^= comparator - |= moves=(list move:clay-gate) - ^- tang - :: - ?. ?=([* ~] moves) - [%leaf "wrong number of moves: {<(lent moves)>}"]~ - :: - =/ move=move:clay-gate i.moves - =/ =duct p.move - =/ card=(wind note:clay-gate gift:able:clay) q.move - :: - %+ weld - (expect-eq !>(~[/info]) !>(duct)) - :: - ?. ?=(%pass -.card) - [%leaf "bad move, not a %pass: {}"]~ - :: - =/ =wire p.card - :: - %+ weld - (expect-eq !>(/commit/home/mutates) !>(wire)) - :: - =/ note=note:clay-gate q.card - :: - ?. ?=([%f %build *] note) - [%leaf "bad move, not a %build: {}"]~ - :: - %+ weld - (expect-eq !>(%.n) !>(live.note)) - :: - %- expect-schematic:test-ford-external - :_ schematic.note - ^- schematic:ford - [%pin ~1111.1.1 %list ~] - == - :: - :: mutating - :: - =^ results5 clay-gate - %- clay-take-with-comparator :* - clay-gate - now=~1111.1.1 - scry=*sley - ^= take-args - :* wire=/commit/home/mutates - duct=~[/info] - -:!>(*sign:clay-gate) - ^- sign:clay-gate - [%f %made ~1111.1.1 %complete %success %list ~] - == - ^= comparator - |= moves=(list move:clay-gate) - ^- tang - :: - ?. ?=([* ~] moves) - [%leaf "wrong number of moves: {<(lent moves)>}"]~ - :: - =/ move=move:clay-gate i.moves - =/ =duct p.move - =/ card=(wind note:clay-gate gift:able:clay) q.move - :: - %+ weld - (expect-eq !>(~[/info]) !>(duct)) - :: - ?. ?=(%pass -.card) - [%leaf "bad move, not a %pass: {}"]~ - :: - =/ =wire p.card - :: - %+ weld - (expect-eq !>(/commit/home/checkout) !>(wire)) - :: - =/ note=note:clay-gate q.card - :: - ?. ?=([%f %build *] note) - [%leaf "bad move, not a %build: {}"]~ - :: - %+ weld - (expect-eq !>(%.n) !>(live.note)) - :: - %- expect-schematic:test-ford-external - :_ schematic.note - ^- schematic:ford - :- %list - ^- (list schematic:ford) - :~ :- :^ %$ %path-hash -:!>([*path *@uvI]) - :- /file1/noun - 0v1u.egg7f.h1o7a.22g2g.torgm.2kcfj.k8b3s.n5hlf.57i21.5m1nn.bhob7 - :: - [%volt [~nul %home] %noun 'file1'] - :: - :- :^ %$ %path-hash -:!>([*path *@uvI]) - :- /file2/noun - 0vj.5f6kr.5o1of.dubnd.6k5a7.jprgp.8ifgp.0ljbi.dqau7.7c0q0.fj144 - :: - [%volt [~nul %home] %noun 'file2'] - == == - :: - :: patching - :: - =^ results6 clay-gate - %- clay-take :* - clay-gate - now=~1111.1.1 - scry=*sley - ^= take-args - :* wire=/commit/home/checkout - duct=~[/info] - -:!>(*sign:clay-gate) - ^- sign:clay-gate - :* %f %made ~1111.1.1 %complete %success %list - ^- (list build-result:ford) - :~ :+ %success - :* %success %$ %path-hash -:!>([*path *@uvI]) - /file1/noun - 0v1u.egg7f.h1o7a.22g2g.torgm.2kcfj. - k8b3s.n5hlf.57i21.5m1nn.bhob7 - == - [%success %volt %noun %noun 'file1'] - :: - :+ %success - :* %success %$ %path-hash -:!>([*path *@uvI]) - /file2/noun - 0vj.5f6kr.5o1of.dubnd.6k5a7.jprgp. - 8ifgp.0ljbi.dqau7.7c0q0.fj144 - == - [%success %volt %noun %noun 'file2'] - == == == - ^= expected-moves - :~ :* duct=~[/init] %give %note '+' %rose ["/" "/" ~] - :~ [%leaf "~nul"] - [%leaf "home"] - [%leaf "1"] - [%leaf "file1"] - [%leaf "noun"] - == == - :: - :* duct=~[/init] %give %note '+' %rose ["/" "/" ~] - :~ [%leaf "~nul"] - [%leaf "home"] - [%leaf "1"] - [%leaf "file2"] - [%leaf "noun"] - == == == == - :: make a second write request during the same arvo event - :: - :: This should produce a Behn timer at `now` to run the write - :: request. - :: - =^ results7 clay-gate - %- clay-call-with-comparator :* - clay-gate - now=~1111.1.1 - scry=*sley - ^= call-args - :+ duct=~[/info2] type=-:!>(*task:able:clay) - ^- task:able:clay - :+ %info %home - ^- nori:clay - :- %& - ^- soba:clay - :~ [/file3/noun `miso:clay`[%ins [%noun %noun 'file3']]] - [/file4/noun `miso:clay`[%ins [%noun %noun 'file4']]] - == - ^= comparator - |= moves=(list move:clay-gate) - ^- tang - :: - ?. ?=([* ~] moves) - [%leaf "wrong number of moves: {}"]~ - :: - =/ move=move:clay-gate i.moves - =/ =duct p.move - =/ card=(wind note:clay-gate gift:able:clay) q.move - :: - %+ weld - (expect-eq !>(~[/info2]) !>(duct)) - :: - ?. ?=(%pass -.card) - [%leaf "bad move, not a %pass: {}"]~ - :: - =/ =wire p.card - :: - %+ weld - (expect-eq !>(/queued-request) !>(wire)) - :: - =/ note=note:clay-gate q.card - :: - ?. ?=([%b %wait *] note) - [%leaf "bad move, not a %wait: {}"]~ - :: - (expect-eq !>(~1111.1.1) !>(p.note)) - == - :: - =^ results8 clay-gate - %- clay-take-with-comparator :* - clay-gate - now=~2222.2.2 - scry=*sley - ^= take-args - :* wire=/queued-request - duct=~[/info2] - -:!>(*sign:clay-gate) - ^- sign:clay-gate - [%b %wake ~] - == - ^= comparator - |= moves=(list move:clay-gate) - ^- tang - :: - ?. ?=([* * * ~] moves) - [%leaf "wrong number of moves: {<(lent moves)>}"]~ - :: - ^- tang - ;: weld - %+ expect-eq - !> ^- move:clay-gate - :- duct=~[/info2] - ^- (wind note:clay-gate gift:able:clay) - :+ %pass /castifying/~nul/home/~2222.2.2 - ^- note:clay-gate - :- %f - [%build live=%.n [%pin ~2222.2.2 [%list ~]]] - !> i.moves - :: - %+ expect-eq - !> ^- move:clay-gate - :- duct=~[/info2] - ^- (wind note:clay-gate gift:able:clay) - :+ %pass /diffing/~nul/home/~2222.2.2 - ^- note:clay-gate - :- %f - [%build live=%.n [%pin ~2222.2.2 [%list ~]]] - !> i.t.moves - :: - ^- tang - :: - =/ move=move:clay-gate i.t.t.moves - =/ =duct p.move - =/ card=(wind note:clay-gate gift:able:clay) q.move - :: - %+ weld - (expect-eq !>(~[/info2]) !>(duct)) - :: - ?. ?=(%pass -.card) - [%leaf "bad move, not a %pass: {}"]~ - :: - =/ =wire p.card - :: - %+ weld - (expect-eq !>(/inserting/~nul/home/~2222.2.2) !>(wire)) - :: - =/ note=note:clay-gate q.card - :: - ?. ?=([%f %build *] note) - [%leaf "bad move, not a %build: {}"]~ - :: - %+ weld - (expect-eq !>(%.n) !>(live.note)) - :: - %- expect-schematic:test-ford-external - :_ schematic.note - ^- schematic:ford - :+ %pin ~2222.2.2 - :- %list - :~ :- [%$ %path -:!>(*path) /file3/noun] - :^ %cast [~nul %home] %noun - [%$ %noun %noun 'file3'] - :: - :- [%$ %path -:!>(*path) /file4/noun] - :^ %cast [~nul %home] %noun - [%$ %noun %noun 'file4'] - == - == == - :: - ;: welp - results0 - results1 - results2 - results3 - results4 - results5 - results6 - results7 + %+ expect-eq + !> (~(gas in *(set path)) /gen/hello/hoon ~) + !> dez:(~(got by vases.cache.nub) /gen/hello/hoon) == +:: +++ test-strandio-lib ^- tang + =/ =ankh:clay + :- fil=~ + %- ~(gas by *(map @tas ankh:clay)) + :~ :+ %lib fil=~ + %- ~(gas by *(map @tas ankh:clay)) + :~ :+ %strandio fil=~ + %- ~(gas by *(map @tas ankh:clay)) + :~ :+ %hoon fil=`[*lobe:clay hoon+!>(strandio-lib)] dir=~ + == + :: + :+ %strand fil=~ + %- ~(gas by *(map @tas ankh:clay)) + :~ :+ %hoon fil=`[*lobe:clay hoon+!>(strand-lib)] dir=~ + == == + :: + :+ %sur fil=~ + %- ~(gas by *(map @tas ankh:clay)) + :~ :+ %spider fil=~ + %- ~(gas by *(map @tas ankh:clay)) + :~ :+ %hoon fil=`[*lobe:clay hoon+!>(spider-sur)] dir=~ + == == == + =/ ford + %: ford:fusion + bud + ankh + deletes=~ + changes=~ + file-store=~ + *ford-cache:fusion + == + =/ [res=vase nub=state:ford:fusion] (build-file:ford /lib/strandio/hoon) + ;: weld + %- expect + !>((slab %read %get-our -.res)) + :: + %+ expect-eq + !> %- ~(gas in *(set path)) + :~ /lib/strandio/hoon + /lib/strand/hoon + /sur/spider/hoon + == + !> dez:(~(got by vases.cache.nub) /lib/strandio/hoon) + == +:: :: |utilities: helper functions for testing :: :: TODO: make these utilities generic for any vane diff --git a/pkg/arvo/tests/sys/vane/eyre.hoon b/pkg/arvo/tests/sys/vane/eyre.hoon index fa875d08ff..bd06b75fe0 100644 --- a/pkg/arvo/tests/sys/vane/eyre.hoon +++ b/pkg/arvo/tests/sys/vane/eyre.hoon @@ -1,18 +1,17 @@ -/+ *test, *test-ford-external -:: -/= http-server-raw /: /===/sys/vane/eyre /!noun/ +/+ *test +/= eyre-raw /sys/vane/eyre :: !: :: =/ test-pit=vase !>(..zuse) -=/ http-server-gate (http-server-raw test-pit) +=/ eyre-gate (eyre-raw test-pit) =/ eyre-id '~.eyre_0v4.elsnk.20412.0h04v.50lom.5lq0o' :: |% ++ test-init - =^ results1 http-server-gate - %- http-server-call :* - http-server-gate + =^ results1 eyre-gate + %- eyre-call :* + eyre-gate now=~1111.1.1 scry=scry-provides-code call-args=[duct=~[/init] ~ [%init ~nul]] @@ -23,9 +22,9 @@ :: ++ test-duplicate-bindings :: - =^ results1 http-server-gate - %- http-server-call :* - http-server-gate + =^ results1 eyre-gate + %- eyre-call :* + eyre-gate now=~1111.1.1 scry=scry-provides-code call-args=[duct=~[/init] ~ [%init ~nul]] @@ -33,9 +32,9 @@ == :: app1 binds successfully :: - =^ results2 http-server-gate - %- http-server-call :* - http-server-gate + =^ results2 eyre-gate + %- eyre-call :* + eyre-gate now=~1111.1.2 scry=scry-provides-code call-args=[duct=~[/app1] ~ [%connect [~ /] %app1]] @@ -43,9 +42,9 @@ == :: app2 tries to bind to the same path and fails :: - =^ results3 http-server-gate - %- http-server-call :* - http-server-gate + =^ results3 eyre-gate + %- eyre-call :* + eyre-gate now=~1111.1.3 scry=scry-provides-code call-args=[duct=~[/app2] ~ [%connect [~ /] %app2]] @@ -60,9 +59,9 @@ :: ++ test-remove-binding :: - =^ results1 http-server-gate - %- http-server-call :* - http-server-gate + =^ results1 eyre-gate + %- eyre-call :* + eyre-gate now=~1111.1.1 scry=scry-provides-code call-args=[duct=~[/init] ~ [%init ~nul]] @@ -70,9 +69,9 @@ == :: app1 binds successfully :: - =^ results2 http-server-gate - %- http-server-call :* - http-server-gate + =^ results2 eyre-gate + %- eyre-call :* + eyre-gate now=~1111.1.2 scry=scry-provides-code call-args=[duct=~[/app1] ~ [%connect [~ /] %app1]] @@ -80,9 +79,9 @@ == :: app1 unbinds :: - =^ results3 http-server-gate - %- http-server-call :* - http-server-gate + =^ results3 eyre-gate + %- eyre-call :* + eyre-gate now=~1111.1.3 scry=scry-provides-code call-args=[duct=~[/app1] ~ [%disconnect [~ /]]] @@ -90,9 +89,9 @@ == :: app2 binds successfully :: - =^ results4 http-server-gate - %- http-server-call :* - http-server-gate + =^ results4 eyre-gate + %- eyre-call :* + eyre-gate now=~1111.1.4 scry=scry-provides-code call-args=[duct=~[/app2] ~ [%connect [~ /] %app2]] @@ -111,30 +110,30 @@ :: %+ expect-eq !>(%.y) - !>((host-matches:http-server-gate ~ `'example.com')) + !>((host-matches:eyre-gate ~ `'example.com')) :: %+ expect-eq !>(%.y) - !>((host-matches:http-server-gate ~ ~)) + !>((host-matches:eyre-gate ~ ~)) :: %+ expect-eq !>(%.n) - !>((host-matches:http-server-gate `'example.com' ~)) + !>((host-matches:eyre-gate `'example.com' ~)) :: %+ expect-eq !>(%.y) - !>((host-matches:http-server-gate `'example.com' `'example.com')) + !>((host-matches:eyre-gate `'example.com' `'example.com')) :: %+ expect-eq !>(%.n) - !>((host-matches:http-server-gate `'example.com' `'blah.com')) + !>((host-matches:eyre-gate `'example.com' `'blah.com')) == :: ++ test-cant-remove-other-ducts-binding :: - =^ results1 http-server-gate - %- http-server-call :* - http-server-gate + =^ results1 eyre-gate + %- eyre-call :* + eyre-gate now=~1111.1.1 scry=scry-provides-code call-args=[duct=~[/init] ~ [%init ~nul]] @@ -142,9 +141,9 @@ == :: app1 binds successfully :: - =^ results2 http-server-gate - %- http-server-call :* - http-server-gate + =^ results2 eyre-gate + %- eyre-call :* + eyre-gate now=~1111.1.2 scry=scry-provides-code call-args=[duct=~[/app1] ~ [%connect [~ /] %app1]] @@ -152,9 +151,9 @@ == :: app2 tries to steal the binding by disconnecting the path :: - =^ results3 http-server-gate - %- http-server-call :* - http-server-gate + =^ results3 eyre-gate + %- eyre-call :* + eyre-gate now=~1111.1.3 scry=scry-provides-code call-args=[duct=~[/app2] ~ [%disconnect [~ /]]] @@ -162,9 +161,9 @@ == :: app2 doesn't bind successfully because it couldn't remove app1's binding :: - =^ results4 http-server-gate - %- http-server-call :* - http-server-gate + =^ results4 eyre-gate + %- eyre-call :* + eyre-gate now=~1111.1.4 scry=scry-provides-code call-args=[duct=~[/app2] ~ [%connect [~ /] %app2]] @@ -181,9 +180,9 @@ :: ++ test-builtin-four-oh-four :: - =^ results1 http-server-gate - %- http-server-call :* - http-server-gate + =^ results1 eyre-gate + %- eyre-call :* + eyre-gate now=~1111.1.1 scry=scry-provides-code call-args=[duct=~[/init] ~ [%init ~nul]] @@ -191,9 +190,9 @@ == :: when there's no configuration and nothing matches, expect 404 :: - =^ results2 http-server-gate - %- http-server-call :* - http-server-gate + =^ results2 eyre-gate + %- eyre-call :* + eyre-gate now=~1111.1.1 scry=scry-provides-code ^= call-args @@ -204,7 +203,7 @@ [%'GET' '/' ~ ~] == ^= expectec-moves - ^- (list move:http-server-gate) + ^- (list move:eyre-gate) :~ :* duct=~[/http-blah] %give %response @@ -213,7 +212,7 @@ %+ complete-http-start-event :- 404 ['content-type' 'text/html']~ - [~ (error-page:http-server-gate 404 %.n '/' ~)] + [~ (error-page:eyre-gate 404 %.n '/' ~)] == == == :: @@ -224,9 +223,9 @@ :: ++ test-basic-app-request :: - =^ results1 http-server-gate - %- http-server-call :* - http-server-gate + =^ results1 eyre-gate + %- eyre-call :* + eyre-gate now=~1111.1.1 scry=scry-provides-code call-args=[duct=~[/init] ~ [%init ~nul]] @@ -234,9 +233,9 @@ == :: app1 binds successfully :: - =^ results2 http-server-gate - %- http-server-call :* - http-server-gate + =^ results2 eyre-gate + %- eyre-call :* + eyre-gate now=~1111.1.2 scry=scry-provides-code call-args=[duct=~[/app1] ~ [%connect [~ /] %app1]] @@ -244,9 +243,9 @@ == :: outside requests a path that app1 has bound to :: - =^ results3 http-server-gate - %- http-server-call-with-comparator :* - http-server-gate + =^ results3 eyre-gate + %- eyre-call-with-comparator :* + eyre-gate now=~1111.1.3 scry=scry-provides-code ^= call-args @@ -257,15 +256,15 @@ [%'GET' '/' ~ ~] == ^= comparator - |= moves=(list move:http-server-gate) + |= moves=(list move:eyre-gate) ^- tang :: ?. ?=([* * ~] moves) [%leaf "wrong number of moves: {<(lent moves)>}"]~ :: :: - =/ move-1=move:http-server-gate i.moves - =/ move-2=move:http-server-gate i.t.moves + =/ move-1=move:eyre-gate i.moves + =/ move-2=move:eyre-gate i.t.moves :: %+ weld (expect-eq !>(~[/http-blah]) !>(duct.move-1)) @@ -290,14 +289,14 @@ == :: theoretical outside response :: - =^ results4 http-server-gate - %- http-server-take :* - http-server-gate + =^ results4 eyre-gate + %- eyre-take :* + eyre-gate now=~1111.1.4 scry=scry-provides-code ^= take-args :* wire=/watch-response/[eyre-id] duct=~[/http-blah] - ^- (hypo sign:http-server-gate) + ^- (hypo sign:eyre-gate) :- *type :* %g %unto %fact %http-response-header @@ -318,9 +317,9 @@ :: ++ test-app-error :: - =^ results1 http-server-gate - %- http-server-call :* - http-server-gate + =^ results1 eyre-gate + %- eyre-call :* + eyre-gate now=~1111.1.1 scry=scry-provides-code call-args=[duct=~[/init] ~ [%init ~nul]] @@ -328,9 +327,9 @@ == :: app1 binds successfully :: - =^ results2 http-server-gate - %- http-server-call :* - http-server-gate + =^ results2 eyre-gate + %- eyre-call :* + eyre-gate now=~1111.1.2 scry=scry-provides-code call-args=[duct=~[/app1] ~ [%connect [~ /] %app1]] @@ -338,9 +337,9 @@ == :: outside requests a path that app1 has bound to :: - =^ results3 http-server-gate - %- http-server-call-with-comparator :* - http-server-gate + =^ results3 eyre-gate + %- eyre-call-with-comparator :* + eyre-gate now=~1111.1.3 scry=scry-provides-code ^= call-args @@ -351,15 +350,15 @@ [%'GET' '/' ~ ~] == ^= comparator - |= moves=(list move:http-server-gate) + |= moves=(list move:eyre-gate) ^- tang :: ?. ?=([* * ~] moves) [[%leaf "wrong number of moves: {<(lent moves)>}"] >moves< ~] :: :: - =/ move-1=move:http-server-gate i.moves - =/ move-2=move:http-server-gate i.t.moves + =/ move-1=move:eyre-gate i.moves + =/ move-2=move:eyre-gate i.t.moves :: %+ weld (expect-eq !>(~[/http-blah]) !>(duct.move-1)) @@ -385,14 +384,14 @@ == :: the poke fails. we should relay this to the client :: - =^ results4 http-server-gate - %- http-server-take :* - http-server-gate + =^ results4 eyre-gate + %- eyre-take :* + eyre-gate now=~1111.1.4 scry=scry-provides-code ^= take-args :* wire=/run-app-request/app1 duct=~[/http-blah] - ^- (hypo sign:http-server-gate) + ^- (hypo sign:eyre-gate) :- *type :* %g %unto %poke-ack ~ :~ [%leaf "/~zod/...../app1:<[1 1].[1 20]>"] @@ -410,7 +409,7 @@ %+ complete-http-start-event :- 500 ['content-type' 'text/html']~ - [~ (internal-server-error:http-server-gate %.n '/' ~)] + [~ (internal-server-error:eyre-gate %.n '/' ~)] == == == :: ;: weld @@ -422,9 +421,9 @@ :: ++ test-multipart-app-request :: - =^ results1 http-server-gate - %- http-server-call :* - http-server-gate + =^ results1 eyre-gate + %- eyre-call :* + eyre-gate now=~1111.1.1 scry=scry-provides-code call-args=[duct=~[/init] ~ [%init ~nul]] @@ -432,9 +431,9 @@ == :: app1 binds successfully :: - =^ results2 http-server-gate - %- http-server-call :* - http-server-gate + =^ results2 eyre-gate + %- eyre-call :* + eyre-gate now=~1111.1.2 scry=scry-provides-code call-args=[duct=~[/app1] ~ [%connect [~ /] %app1]] @@ -442,9 +441,9 @@ == :: outside requests a path that app1 has bound to :: - =^ results3 http-server-gate - %- http-server-call-with-comparator :* - http-server-gate + =^ results3 eyre-gate + %- eyre-call-with-comparator :* + eyre-gate now=~1111.1.3 scry=scry-provides-code ^= call-args @@ -455,15 +454,15 @@ [%'GET' '/' ~ ~] == ^= comparator - |= moves=(list move:http-server-gate) + |= moves=(list move:eyre-gate) ^- tang :: ?. ?=([* * ~] moves) [%leaf "wrong number of moves: {<(lent moves)>}"]~ :: :: - =/ move-1=move:http-server-gate i.moves - =/ move-2=move:http-server-gate i.t.moves + =/ move-1=move:eyre-gate i.moves + =/ move-2=move:eyre-gate i.t.moves :: %+ weld (expect-eq !>(~[/http-blah]) !>(duct.move-1)) @@ -488,14 +487,14 @@ == :: theoretical outside response :: - =^ results4 http-server-gate - %- http-server-take :* - http-server-gate + =^ results4 eyre-gate + %- eyre-take :* + eyre-gate now=~1111.1.4 scry=scry-provides-code ^= take-args :* wire=/watch-response/[eyre-id] duct=~[/http-blah] - ^- (hypo sign:http-server-gate) :- *type + ^- (hypo sign:eyre-gate) :- *type :* %g %unto %fact %http-response-header !>([200 ['content-type' 'text/html']~]) @@ -507,14 +506,14 @@ == == == :: theoretical outside response :: - =^ results5 http-server-gate - %- http-server-take :* - http-server-gate + =^ results5 eyre-gate + %- eyre-take :* + eyre-gate now=~1111.1.4 scry=scry-provides-code ^= take-args :* wire=/watch-response/[eyre-id] duct=~[/http-blah] - ^- (hypo sign:http-server-gate) :- *type + ^- (hypo sign:eyre-gate) :- *type :* %g %unto %fact %http-response-data !>(`(as-octs:mimes:html 'ya!')) @@ -537,9 +536,9 @@ :: ++ test-login-handler-full-path :: - =^ results1 http-server-gate - %- http-server-call :* - http-server-gate + =^ results1 eyre-gate + %- eyre-call :* + eyre-gate now=~1111.1.1 scry=scry-provides-code call-args=[duct=~[/init] ~ [%init ~nul]] @@ -547,9 +546,9 @@ == :: app1 binds successfully :: - =^ results2 http-server-gate - %- http-server-call :* - http-server-gate + =^ results2 eyre-gate + %- eyre-call :* + eyre-gate now=~1111.1.2 scry=scry-provides-code call-args=[duct=~[/app1] ~ [%connect [~ /'~landscape'] %app1]] @@ -557,9 +556,9 @@ == :: outside requests a path that app1 has bound to :: - =^ results3 http-server-gate - %- http-server-call-with-comparator :* - http-server-gate + =^ results3 eyre-gate + %- eyre-call-with-comparator :* + eyre-gate now=~1111.1.3 scry=scry-provides-code ^= call-args @@ -570,15 +569,15 @@ [%'GET' '/~landscape/inner-path' ~ ~] == ^= comparator - |= moves=(list move:http-server-gate) + |= moves=(list move:eyre-gate) ^- tang :: ?. ?=([* * ~] moves) [%leaf "wrong number of moves: {<(lent moves)>}"]~ :: :: - =/ move-1=move:http-server-gate i.moves - =/ move-2=move:http-server-gate i.t.moves + =/ move-1=move:eyre-gate i.moves + =/ move-2=move:eyre-gate i.t.moves :: %+ weld (expect-eq !>(~[/http-blah]) !>(duct.move-1)) @@ -603,14 +602,14 @@ == :: app then gives a redirect to Eyre :: - =^ results4 http-server-gate - %- http-server-take :* - http-server-gate + =^ results4 eyre-gate + %- eyre-take :* + eyre-gate now=~1111.1.4 scry=scry-provides-code ^= take-args :* wire=/watch-response/[eyre-id] duct=~[/http-blah] - ^- (hypo sign:http-server-gate) :- *type + ^- (hypo sign:eyre-gate) :- *type :* %g %unto %fact %http-response-header !>([303 ['location' '/~/login?redirect=/~landscape/inner-path']~]) @@ -622,21 +621,21 @@ == == == :: the browser then fetches the login page :: - =^ results5 http-server-gate + =^ results5 eyre-gate %- perform-authentication :* - http-server-gate + eyre-gate now=~1111.1.5 scry=scry-provides-code == :: going back to the original url will acknowledge the authentication cookie :: - =^ results6 http-server-gate - %- http-server-call-with-comparator :* - http-server-gate + =^ results6 eyre-gate + %- eyre-call-with-comparator :* + eyre-gate now=~1111.1.5..1.0.0 scry=scry-provides-code ^= call-args - ^- [=duct type=* wrapped-task=(hobo task:able:http-server-gate)] + ^- [=duct type=* wrapped-task=(hobo task:able:eyre-gate)] :* duct=~[/http-blah] ~ %request %.n @@ -647,15 +646,15 @@ ~ == ^= comparator - |= moves=(list move:http-server-gate) + |= moves=(list move:eyre-gate) ^- tang :: ?. ?=([* * ~] moves) [%leaf "wrong number of moves: {<(lent moves)>}"]~ :: :: - =/ move-1=move:http-server-gate i.moves - =/ move-2=move:http-server-gate i.t.moves + =/ move-1=move:eyre-gate i.moves + =/ move-2=move:eyre-gate i.t.moves :: %+ weld (expect-eq !>(~[/http-blah]) !>(duct.move-1)) @@ -701,9 +700,9 @@ :: ++ test-generator :: - =^ results1 http-server-gate - %- http-server-call :* - http-server-gate + =^ results1 eyre-gate + %- eyre-call :* + eyre-gate now=~1111.1.1 scry=scry-provides-code call-args=[duct=~[/init] ~ [%init ~nul]] @@ -711,9 +710,9 @@ == :: gen1 binds successfully :: - =^ results2 http-server-gate - %- http-server-call :* - http-server-gate + =^ results2 eyre-gate + %- eyre-call :* + eyre-gate now=~1111.1.2 scry=scry-provides-code call-args=[duct=~[/gen1] ~ [%serve [~ /] [%home /gen/handler/hoon ~]]] @@ -721,9 +720,9 @@ == :: outside requests a path that app1 has bound to :: - =^ results3 http-server-gate - %- http-server-call-with-comparator :* - http-server-gate + =^ results3 eyre-gate + %- eyre-call :* + eyre-gate now=~1111.1.3 scry=scry-provides-code ^= call-args @@ -733,95 +732,39 @@ [%ipv4 .192.168.1.1] [%'GET' '/' ~ ~] == - ^= comparator - |= moves=(list move:http-server-gate) - ^- tang - :: - ?. ?=([* ~] moves) - [%leaf "wrong number of moves: {<(lent moves)>}"]~ - :: - :: - =/ move=move:http-server-gate i.moves - =/ =duct duct.move - =/ card=(wind note:http-server-gate gift:able:http-server-gate) card.move - :: - ?. ?=(%pass -.card) - [%leaf "not a %pass"]~ - ?. ?=([%f %build *] q.card) - [%leaf "not a ford build"]~ - :: - %+ weld - %+ expect-eq - !> /run-build - !> p.card - :: - %+ expect-schematic - :+ %call - :+ %call - [%core [[~nul %home] /hoon/handler/gen]] - [%$ %noun !>([[~1111.1.3 0xdead.beef [~nul %home [%da ~1111.1.3]]] ~ ~])] - [%$ %noun !>([%.n [%'GET' '/' ~ ~]])] - :: - schematic.q.card + ^= expected-moves + :~ :+ ~[/http-blah] %give + [%response %start [404 headers=~] data=~ complete=%.y] + == == - :: ford response (time assumes nothing blocked) - :: - =^ results4 http-server-gate - %- http-server-take :* - http-server-gate - now=~1111.1.3 - scry=scry-provides-code - ^= take-args - :* wire=/run-build duct=~[/http-blah] - ^- (hypo sign:http-server-gate) - :- *type - :^ %f %made ~1111.1.3 - ^- made-result:ford - :- %complete - ^- build-result:ford - :^ %success %cast %mime - !> - :- [200 ['content-type' 'text/plain']~] - `(as-octs:mimes:html 'one two three') - == - ^= expected-move - :~ :* duct=~[/http-blah] %give %response - %start - :: - %+ complete-http-start-event - :- 200 - ['content-type' 'text/plain']~ - `[13 'one two three'] - == == == :: ;: weld results1 results2 results3 - results4 == :: ++ test-simplified-url-parser ;: weld %+ expect-eq !> `[[%site 'localhost'] [~ 8.000]] - !> (rush 'localhost:8000' simplified-url-parser:http-server-gate) + !> (rush 'localhost:8000' simplified-url-parser:eyre-gate) :: %+ expect-eq !> `[[%ip .192.168.1.1] ~] - !> (rush '192.168.1.1' simplified-url-parser:http-server-gate) + !> (rush '192.168.1.1' simplified-url-parser:eyre-gate) == :: ++ test-parse-channel-request ;: weld %+ expect-eq !> `[%ack 5]~ - !> %- parse-channel-request:http-server-gate + !> %- parse-channel-request:eyre-gate (need (de-json:html '[{"action": "ack", "event-id": 5}]')) :: %+ expect-eq !> `[%poke 0 ~nec %app1 %app-type [%n '5']]~ - !> %- parse-channel-request:http-server-gate + !> %- parse-channel-request:eyre-gate %- need %- de-json:html ''' [{"action": "poke", @@ -834,7 +777,7 @@ :: %+ expect-eq !> `[%subscribe 1 ~sampyl-sipnym %hall /this/path]~ - !> %- parse-channel-request:http-server-gate + !> %- parse-channel-request:eyre-gate %- need %- de-json:html ''' [{"action": "subscribe", @@ -846,7 +789,7 @@ :: %+ expect-eq !> `[%unsubscribe 2 1]~ - !> %- parse-channel-request:http-server-gate + !> %- parse-channel-request:eyre-gate %- need %- de-json:html ''' [{"action": "unsubscribe", @@ -856,19 +799,19 @@ :: %+ expect-eq !> ~ - !> %- parse-channel-request:http-server-gate + !> %- parse-channel-request:eyre-gate %- need %- de-json:html '[{"noaction": "noaction"}]' :: %+ expect-eq !> ~ - !> %- parse-channel-request:http-server-gate + !> %- parse-channel-request:eyre-gate %- need %- de-json:html '[{"action": "bad-action"}]' :: %+ expect-eq !> ~ - !> %- parse-channel-request:http-server-gate + !> %- parse-channel-request:eyre-gate %- need %- de-json:html '[{"action": "ack", "event-id": 5}, {"action": "bad-action"}]' :: @@ -877,7 +820,7 @@ :~ [%ack 9] [%poke 3 ~bud %wut %wut-type [%a [%n '2'] [%n '1'] ~]] == - !> %- parse-channel-request:http-server-gate + !> %- parse-channel-request:eyre-gate %- need %- de-json:html ''' [{"action": "ack", "event-id": 9}, @@ -892,18 +835,18 @@ :: ++ test-channel-reject-unauthenticated :: - =^ results1 http-server-gate - %- http-server-call :* - http-server-gate + =^ results1 eyre-gate + %- eyre-call :* + eyre-gate now=~1111.1.1 scry=scry-provides-code call-args=[duct=~[/init] ~ [%init ~nul]] expected-moves=~ == :: - =^ results2 http-server-gate - %- http-server-call :* - http-server-gate + =^ results2 eyre-gate + %- eyre-call :* + eyre-gate now=~1111.1.2 scry=scry-provides-code ^= call-args @@ -914,7 +857,7 @@ [%'PUT' '/~/channel/1234567890abcdef' ~ ~] == ^= expected-moves - ^- (list move:http-server-gate) + ^- (list move:eyre-gate) :~ :* duct=~[/http-blah] %give %response @@ -924,7 +867,7 @@ :- 403 ['content-type' 'text/html']~ :- ~ - %- error-page:http-server-gate :* + %- error-page:eyre-gate :* 403 %.n '/~/channel/1234567890abcdef' @@ -939,22 +882,22 @@ == :: ++ test-channel-open-never-used-expire - =^ results1 http-server-gate (perform-init-start-channel http-server-gate *sley) + =^ results1 eyre-gate (perform-init-start-channel eyre-gate *sley) :: the behn timer wakes us up; we cancel our subscription :: - =^ results2 http-server-gate - %- http-server-take-with-comparator :* - http-server-gate + =^ results2 eyre-gate + %- eyre-take-with-comparator :* + eyre-gate now=(add ~1111.1.2 ~h12) scry=scry-provides-code ^= take-args :* wire=/channel/timeout/'0123456789abcdef' duct=~[/http-blah] - ^- (hypo sign:http-server-gate) + ^- (hypo sign:eyre-gate) :- *type [%b %wake ~] == ^= comparator - |= moves=(list move:http-server-gate) + |= moves=(list move:eyre-gate) ^- tang :: ?. ?=([^ ~] moves) @@ -975,17 +918,17 @@ ++ test-channel-results-before-open :: common initialization :: - =^ results1 http-server-gate (perform-init-start-channel http-server-gate *sley) + =^ results1 eyre-gate (perform-init-start-channel eyre-gate *sley) :: poke gets a success message :: - =^ results2 http-server-gate - %- http-server-take :* - http-server-gate + =^ results2 eyre-gate + %- eyre-take :* + eyre-gate now=(add ~1111.1.2 ~m1) scry=scry-provides-code ^= take-args :* wire=/channel/poke/'0123456789abcdef'/'0' duct=~[/http-put-request] - ^- (hypo sign:http-server-gate) + ^- (hypo sign:eyre-gate) :- *type [%g %unto %poke-ack ~] == @@ -993,14 +936,14 @@ == :: subscription gets a success message :: - =^ results3 http-server-gate - %- http-server-take :* - http-server-gate + =^ results3 eyre-gate + %- eyre-take :* + eyre-gate now=(add ~1111.1.2 ~m1) scry=scry-provides-code ^= take-args :* wire=/channel/subscription/'0123456789abcdef'/'1' duct=~[/http-put-request] - ^- (hypo sign:http-server-gate) + ^- (hypo sign:eyre-gate) :- *type [%g %unto %watch-ack ~] == @@ -1008,14 +951,14 @@ == :: subscription gets a result :: - =^ results4 http-server-gate - %- http-server-take :* - http-server-gate + =^ results4 eyre-gate + %- eyre-take :* + eyre-gate now=(add ~1111.1.2 ~m2) scry=scry-provides-code ^= take-args :* wire=/channel/subscription/'0123456789abcdef'/'1' duct=~[/http-put-request] - ^- (hypo sign:http-server-gate) + ^- (hypo sign:eyre-gate) :- *type [%g %unto %fact %json !>(`json`[%a [%n '1'] [%n '2'] ~])] == @@ -1025,9 +968,9 @@ :: :: send the channel a poke and a subscription request :: - =^ results5 http-server-gate - %- http-server-call :* - http-server-gate + =^ results5 eyre-gate + %- eyre-call :* + eyre-gate now=(add ~1111.1.2 ~m3) scry=scry-provides-code ^= call-args @@ -1041,7 +984,7 @@ ~ == ^= expected-moves - ^- (list move:http-server-gate) + ^- (list move:eyre-gate) :~ :* duct=~[/http-get-open] %pass /channel/heartbeat/'0123456789abcdef' @@ -1083,14 +1026,14 @@ == == == :: we get a cancel when we notice the client has disconnected :: - =^ results6 http-server-gate - %- http-server-call :* - http-server-gate + =^ results6 eyre-gate + %- eyre-call :* + eyre-gate now=(add ~1111.1.2 ~m4) scry=scry-provides-code call-args=[duct=~[/http-get-open] ~ %cancel-request ~] ^= expected-moves - ^- (list move:http-server-gate) + ^- (list move:eyre-gate) :: closing the channel cancels the sse heartbeat :: (initialized in results5 above) and restarts the timeout timer :: @@ -1117,16 +1060,16 @@ ++ test-channel-second-get-updates-timer :: common initialization :: - =^ results1 http-server-gate (perform-init-start-channel http-server-gate *sley) + =^ results1 eyre-gate (perform-init-start-channel eyre-gate *sley) :: perform another poke to a different app :: :: Since we haven't connected with a GET, the old timer should be canceled :: and a new one should be set. :: send the channel a poke and a subscription request :: - =^ results2 http-server-gate - %- http-server-call-with-comparator :* - http-server-gate + =^ results2 eyre-gate + %- eyre-call-with-comparator :* + eyre-gate now=(add ~1111.1.2 ~m1) scry=scry-provides-code ^= call-args @@ -1150,7 +1093,7 @@ ''' == ^= comparator - |= moves=(list move:http-server-gate) + |= moves=(list move:eyre-gate) ^- tang :: ?. ?=([^ ^ ^ ^ ~] moves) @@ -1191,17 +1134,17 @@ ++ test-channel-unsubscribe-stops-events :: common initialization :: - =^ results1 http-server-gate (perform-init-start-channel http-server-gate *sley) + =^ results1 eyre-gate (perform-init-start-channel eyre-gate *sley) :: poke gets a success message :: - =^ results2 http-server-gate - %- http-server-take :* - http-server-gate + =^ results2 eyre-gate + %- eyre-take :* + eyre-gate now=(add ~1111.1.2 ~m1) scry=scry-provides-code ^= take-args :* wire=/channel/poke/'0123456789abcdef'/'0' duct=~[/http-put-request] - ^- (hypo sign:http-server-gate) + ^- (hypo sign:eyre-gate) :- *type [%g %unto %poke-ack ~] == @@ -1209,14 +1152,14 @@ == :: subscription gets a success message :: - =^ results3 http-server-gate - %- http-server-take :* - http-server-gate + =^ results3 eyre-gate + %- eyre-take :* + eyre-gate now=(add ~1111.1.2 ~m2) scry=scry-provides-code ^= take-args :* wire=/channel/subscription/'0123456789abcdef'/'1' duct=~[/http-put-request] - ^- (hypo sign:http-server-gate) + ^- (hypo sign:eyre-gate) :- *type [%g %unto %watch-ack ~] == @@ -1224,9 +1167,9 @@ == :: sending an unsubscribe sends an unsubscribe to gall :: - =^ results4 http-server-gate - %- http-server-call-with-comparator :* - http-server-gate + =^ results4 eyre-gate + %- eyre-call-with-comparator :* + eyre-gate now=(add ~1111.1.2 ~m3) scry=scry-provides-code ^= call-args @@ -1248,7 +1191,7 @@ ''' == ^= comparator - |= moves=(list move:http-server-gate) + |= moves=(list move:eyre-gate) ^- tang :: ?. ?=([^ ^ ^ ^ ~] moves) @@ -1292,17 +1235,17 @@ ++ test-channel-double-subscription-works :: common initialization :: - =^ results1 http-server-gate (perform-init-start-channel http-server-gate *sley) + =^ results1 eyre-gate (perform-init-start-channel eyre-gate *sley) :: poke gets a success message :: - =^ results2 http-server-gate - %- http-server-take :* - http-server-gate + =^ results2 eyre-gate + %- eyre-take :* + eyre-gate now=(add ~1111.1.2 ~m1) scry=scry-provides-code ^= take-args :* wire=/channel/poke/'0123456789abcdef'/'0' duct=~[/http-put-request] - ^- (hypo sign:http-server-gate) + ^- (hypo sign:eyre-gate) :- *type [%g %unto %poke-ack ~] == @@ -1310,14 +1253,14 @@ == :: subscription gets a success message :: - =^ results3 http-server-gate - %- http-server-take :* - http-server-gate + =^ results3 eyre-gate + %- eyre-take :* + eyre-gate now=(add ~1111.1.2 ~m2) scry=scry-provides-code ^= take-args :* wire=/channel/subscription/'0123456789abcdef'/'1' duct=~[/http-put-request] - ^- (hypo sign:http-server-gate) + ^- (hypo sign:eyre-gate) :- *type [%g %unto %watch-ack ~] == @@ -1325,9 +1268,9 @@ == :: now make a second subscription from the client on the same path :: - =^ results3 http-server-gate - %- http-server-call-with-comparator :* - http-server-gate + =^ results3 eyre-gate + %- eyre-call-with-comparator :* + eyre-gate now=(add ~1111.1.2 ~m3) scry=scry-provides-code ^= call-args @@ -1351,7 +1294,7 @@ ''' == ^= comparator - |= moves=(list move:http-server-gate) + |= moves=(list move:eyre-gate) ^- tang :: ?. ?=([^ ^ ^ ^ ~] moves) @@ -1385,14 +1328,14 @@ == == :: subscription gets a result (on the id 1) :: - =^ results4 http-server-gate - %- http-server-take :* - http-server-gate + =^ results4 eyre-gate + %- eyre-take :* + eyre-gate now=(add ~1111.1.2 ~m2) scry=scry-provides-code ^= take-args :* wire=/channel/subscription/'0123456789abcdef'/'1' duct=~[/http-put-request] - ^- (hypo sign:http-server-gate) + ^- (hypo sign:eyre-gate) :- *type [%g %unto %fact %json !>(`json`[%a [%n '1'] [%n '2'] ~])] == @@ -1400,14 +1343,14 @@ == :: subscription gets a result (on the id 2) :: - =^ results5 http-server-gate - %- http-server-take :* - http-server-gate + =^ results5 eyre-gate + %- eyre-take :* + eyre-gate now=(add ~1111.1.2 ~m2) scry=scry-provides-code ^= take-args :* wire=/channel/subscription/'0123456789abcdef'/'2' duct=~[/http-put-request] - ^- (hypo sign:http-server-gate) + ^- (hypo sign:eyre-gate) :- *type [%g %unto %fact %json !>(`json`[%a [%n '1'] [%n '2'] ~])] == @@ -1415,9 +1358,9 @@ == :: open up the channel :: - =^ results6 http-server-gate - %- http-server-call :* - http-server-gate + =^ results6 eyre-gate + %- eyre-call :* + eyre-gate now=(add ~1111.1.2 ~m3) scry=scry-provides-code ^= call-args @@ -1431,7 +1374,7 @@ ~ == ^= expected-moves - ^- (list move:http-server-gate) + ^- (list move:eyre-gate) :~ :* duct=~[/http-get-open] %pass /channel/heartbeat/'0123456789abcdef' @@ -1476,9 +1419,9 @@ == == == :: we can close the first channel without closing the second :: - =^ results7 http-server-gate - %- http-server-call-with-comparator :* - http-server-gate + =^ results7 eyre-gate + %- eyre-call-with-comparator :* + eyre-gate now=(add ~1111.1.2 ~m3) scry=scry-provides-code ^= call-args @@ -1500,7 +1443,7 @@ ''' == ^= comparator - |= moves=(list move:http-server-gate) + |= moves=(list move:eyre-gate) ^- tang :: ?. ?=([^ ^ ~] moves) @@ -1522,19 +1465,19 @@ :: This just tests that closing one of the two subscriptions doesn't :: unsubscribe to the other. :: - =^ results8 http-server-gate - %- http-server-take-with-comparator :* - http-server-gate + =^ results8 eyre-gate + %- eyre-take-with-comparator :* + eyre-gate now=(add ~1111.1.2 ~m2) scry=scry-provides-code ^= take-args :* wire=/channel/subscription/'0123456789abcdef'/'2' duct=~[/http-put-request] - ^- (hypo sign:http-server-gate) + ^- (hypo sign:eyre-gate) :- *type [%g %unto %fact %json !>(`json`[%a [%n '1'] [%n '2'] ~])] == ^= comparator - |= moves=(list move:http-server-gate) + |= moves=(list move:eyre-gate) ^- tang :: ?. ?=([^ ~] moves) @@ -1573,24 +1516,24 @@ =. q (~(put to q) [3 ~]) =. q (~(put to q) [4 ~]) :: - =. q (prune-events:http-server-gate q 3) + =. q (prune-events:eyre-gate q 3) :: (expect-eq !>([~ [4 ~]]) !>(~(top to q))) :: ++ test-channel-sends-unacknowledged-events-on-reconnection :: common initialization :: - =^ results1 http-server-gate (perform-init-start-channel http-server-gate *sley) + =^ results1 eyre-gate (perform-init-start-channel eyre-gate *sley) :: poke gets a success message :: - =^ results2 http-server-gate - %- http-server-take :* - http-server-gate + =^ results2 eyre-gate + %- eyre-take :* + eyre-gate now=(add ~1111.1.2 ~m1) scry=scry-provides-code ^= take-args :* wire=/channel/poke/'0123456789abcdef'/'0' duct=~[/http-put-request] - ^- (hypo sign:http-server-gate) + ^- (hypo sign:eyre-gate) :- *type [%g %unto %poke-ack ~] == @@ -1598,14 +1541,14 @@ == :: subscription gets a success message :: - =^ results3 http-server-gate - %- http-server-take :* - http-server-gate + =^ results3 eyre-gate + %- eyre-take :* + eyre-gate now=(add ~1111.1.2 ~m2) scry=scry-provides-code ^= take-args :* wire=/channel/subscription/'0123456789abcdef'/'1' duct=~[/http-put-request] - ^- (hypo sign:http-server-gate) + ^- (hypo sign:eyre-gate) :- *type [%g %unto %watch-ack ~] == @@ -1613,13 +1556,13 @@ == :: opens the http channel :: - =^ results4 http-server-gate - %- http-server-call :* - http-server-gate + =^ results4 eyre-gate + %- eyre-call :* + eyre-gate now=(add ~1111.1.2 ~m3) scry=scry-provides-code ^= call-args - ^- [duct * (hobo task:able:http-server-gate)] + ^- [duct * (hobo task:able:eyre-gate)] :* duct=~[/http-get-open] ~ %request %.n @@ -1630,7 +1573,7 @@ ~ == ^= expected-moves - ^- (list move:http-server-gate) + ^- (list move:eyre-gate) :~ :* duct=~[/http-get-open] %pass /channel/heartbeat/'0123456789abcdef' @@ -1669,19 +1612,19 @@ == == == :: first subscription result gets sent to the user :: - =^ results5 http-server-gate - %- http-server-take :* - http-server-gate + =^ results5 eyre-gate + %- eyre-take :* + eyre-gate now=(add ~1111.1.2 ~m4) scry=scry-provides-code ^= take-args :* wire=/channel/subscription/'0123456789abcdef'/'1' duct=~[/http-put-request] - ^- (hypo sign:http-server-gate) + ^- (hypo sign:eyre-gate) :- *type [%g %unto %fact %json !>(`json`[%a [%n '1'] ~])] == ^= moves - ^- (list move:http-server-gate) + ^- (list move:eyre-gate) :~ :* duct=~[/http-get-open] %give %response @@ -1700,9 +1643,9 @@ :: :: send the channel a poke and a subscription request :: - =^ results6 http-server-gate - %- http-server-call-with-comparator :* - http-server-gate + =^ results6 eyre-gate + %- eyre-call-with-comparator :* + eyre-gate now=(add ~1111.1.2 ~m5) scry=scry-provides-code ^= call-args @@ -1723,7 +1666,7 @@ ''' == ^= comparator - |= moves=(list move:http-server-gate) + |= moves=(list move:eyre-gate) ^- tang :: ?. ?=([^ ~] moves) @@ -1735,14 +1678,14 @@ == :: the client connection is detected to be broken :: - =^ results7 http-server-gate - %- http-server-call :* - http-server-gate + =^ results7 eyre-gate + %- eyre-call :* + eyre-gate now=(add ~1111.1.2 ~m6) scry=scry-provides-code call-args=[duct=~[/http-get-open] ~ %cancel-request ~] ^= expected-moves - ^- (list move:http-server-gate) + ^- (list move:eyre-gate) :: closing the channel cancels the sse heartbeat :: (initialized in results4 above) and restarts the timeout timer :: @@ -1757,14 +1700,14 @@ == :: another subscription result while the user is disconnected :: - =^ results8 http-server-gate - %- http-server-take :* - http-server-gate + =^ results8 eyre-gate + %- eyre-take :* + eyre-gate now=(add ~1111.1.2 ~m7) scry=scry-provides-code ^= take-args :* wire=/channel/subscription/'0123456789abcdef'/'1' duct=~[/http-put-request] - ^- (hypo sign:http-server-gate) + ^- (hypo sign:eyre-gate) :- *type [%g %unto %fact %json !>(`json`[%a [%n '2'] ~])] == @@ -1775,9 +1718,9 @@ :: Because the client has acknowledged up to event 1, we should start the connection by :: resending events 2 and 3. :: - =^ results9 http-server-gate - %- http-server-call :* - http-server-gate + =^ results9 eyre-gate + %- eyre-call :* + eyre-gate now=(add ~1111.1.2 ~m8) scry=scry-provides-code ^= call-args @@ -1791,7 +1734,7 @@ ~ == ^= expected-moves - ^- (list move:http-server-gate) + ^- (list move:eyre-gate) :~ :* duct=~[/http-get-open] %pass /channel/heartbeat/'0123456789abcdef' @@ -1845,9 +1788,9 @@ :: ++ test-born-sends-pending-cancels :: - =^ results1 http-server-gate - %- http-server-call :* - http-server-gate + =^ results1 eyre-gate + %- eyre-call :* + eyre-gate now=~1111.1.1 scry=scry-provides-code call-args=[duct=~[/init] ~ [%init ~nul]] @@ -1855,9 +1798,9 @@ == :: app1 binds successfully :: - =^ results2 http-server-gate - %- http-server-call :* - http-server-gate + =^ results2 eyre-gate + %- eyre-call :* + eyre-gate now=~1111.1.2 scry=scry-provides-code call-args=[duct=~[/app1] ~ [%connect [~ /] %app1]] @@ -1867,9 +1810,9 @@ :: :: outside requests a path that app1 has bound to :: - =^ results3 http-server-gate - %- http-server-call-with-comparator :* - http-server-gate + =^ results3 eyre-gate + %- eyre-call-with-comparator :* + eyre-gate now=~1111.1.3 scry=scry-provides-code ^= call-args @@ -1880,14 +1823,14 @@ [%'GET' '/' ~ ~] == ^= comparator - |= moves=(list move:http-server-gate) + |= moves=(list move:eyre-gate) ^- tang :: ?. ?=([* * ~] moves) [%leaf "wrong number of moves: {<(lent moves)>}"]~ :: - =/ move-1=move:http-server-gate i.moves - =/ move-2=move:http-server-gate i.t.moves + =/ move-1=move:eyre-gate i.moves + =/ move-2=move:eyre-gate i.t.moves :: %+ weld (expect-eq !>(~[/http-blah]) !>(duct.move-1)) @@ -1913,14 +1856,14 @@ :: but app1 doesn't respond before our urbit gets shut down. ensure we send :: cancels on open connections. :: - =^ results4 http-server-gate - %- http-server-call-with-comparator :* - http-server-gate + =^ results4 eyre-gate + %- eyre-call-with-comparator :* + eyre-gate now=~1111.1.4 scry=scry-provides-code call-args=[duct=~[/born] ~ [%born ~]] ^= expected-moves - |= moves=(list move:http-server-gate) + |= moves=(list move:eyre-gate) ^- tang :: ?. ?=([^ ^ ~] moves) @@ -1929,9 +1872,9 @@ :: we don't care about the first one, which is just a static :: configuration move. :: - =/ move=move:http-server-gate i.t.moves + =/ move=move:eyre-gate i.t.moves =/ =duct duct.move - =/ card=(wind note:http-server-gate gift:able:http-server-gate) card.move + =/ card=(wind note:eyre-gate gift:able:eyre-gate) card.move :: %+ weld (expect-eq !>(~[/http-blah]) !>(duct)) @@ -1949,83 +1892,85 @@ results4 == :: -++ http-server-call - |= $: http-server-gate=_http-server-gate +++ eyre-call + |= $: eyre-gate=_eyre-gate now=@da scry=sley - call-args=[=duct type=* wrapped-task=(hobo task:able:http-server-gate)] - expected-moves=(list move:http-server-gate) + call-args=[=duct type=* wrapped-task=(hobo task:able:eyre-gate)] + expected-moves=(list move:eyre-gate) == - ^- [tang _http-server-gate] + ^- [tang _eyre-gate] :: - =/ http-server-core (http-server-gate our=~nul now=now eny=`@uvJ`0xdead.beef scry=scry) + =/ eyre-core + (eyre-gate our=~nul now=now eny=`@uvJ`0xdead.beef scry=scry) :: - =^ moves http-server-gate (call:http-server-core [duct ~ type wrapped-task]:call-args) + =^ moves eyre-gate + (call:eyre-core [duct ~ type wrapped-task]:call-args) :: =/ output=tang %+ expect-eq !> expected-moves !> moves :: - [output http-server-gate] + [output eyre-gate] :: -++ http-server-call-with-comparator - |= $: http-server-gate=_http-server-gate +++ eyre-call-with-comparator + |= $: eyre-gate=_eyre-gate now=@da scry=sley - call-args=[=duct type=* wrapped-task=(hobo task:able:http-server-gate)] - move-comparator=$-((list move:http-server-gate) tang) + call-args=[=duct type=* wrapped-task=(hobo task:able:eyre-gate)] + move-comparator=$-((list move:eyre-gate) tang) == - ^- [tang _http-server-gate] + ^- [tang _eyre-gate] :: - =/ http-server-core (http-server-gate our=~nul now=now eny=`@uvJ`0xdead.beef scry=scry) + =/ eyre-core (eyre-gate our=~nul now=now eny=`@uvJ`0xdead.beef scry=scry) :: - =^ moves http-server-gate (call:http-server-core [duct ~ type wrapped-task]:call-args) + =^ moves eyre-gate (call:eyre-core [duct ~ type wrapped-task]:call-args) :: =/ output=tang (move-comparator moves) :: - [output http-server-gate] + [output eyre-gate] :: -++ http-server-take - |= $: http-server-gate=_http-server-gate +++ eyre-take + |= $: eyre-gate=_eyre-gate now=@da scry=sley - take-args=[=wire =duct wrapped-sign=(hypo sign:http-server-gate)] - expected-moves=(list move:http-server-gate) + take-args=[=wire =duct wrapped-sign=(hypo sign:eyre-gate)] + expected-moves=(list move:eyre-gate) == - ^- [tang _http-server-gate] + ^- [tang _eyre-gate] :: - =/ http-server-core (http-server-gate our=~nul now=now eny=`@uvJ`0xdead.beef scry=scry) + =/ eyre-core (eyre-gate our=~nul now=now eny=`@uvJ`0xdead.beef scry=scry) :: - =^ moves http-server-gate (take:http-server-core [wire duct ~ wrapped-sign]:take-args) + =^ moves eyre-gate (take:eyre-core [wire duct ~ wrapped-sign]:take-args) :: =/ output=tang %+ expect-eq !> expected-moves !> moves :: - [output http-server-gate] + [output eyre-gate] :: -++ http-server-take-with-comparator - |= $: http-server-gate=_http-server-gate +++ eyre-take-with-comparator + |= $: eyre-gate=_eyre-gate now=@da scry=sley - take-args=[=wire =duct wrapped-sign=(hypo sign:http-server-gate)] - move-comparator=$-((list move:http-server-gate) tang) + take-args=[=wire =duct wrapped-sign=(hypo sign:eyre-gate)] + move-comparator=$-((list move:eyre-gate) tang) == - ^- [tang _http-server-gate] + ^- [tang _eyre-gate] :: - =/ http-server-core (http-server-gate our=~nul now=now eny=`@uvJ`0xdead.beef scry=scry) + =/ eyre-core (eyre-gate our=~nul now=now eny=`@uvJ`0xdead.beef scry=scry) :: - =^ moves http-server-gate (take:http-server-core [wire duct ~ wrapped-sign]:take-args) + =^ moves eyre-gate (take:eyre-core [wire duct ~ wrapped-sign]:take-args) :: =/ output=tang (move-comparator moves) :: - [output http-server-gate] + [output eyre-gate] :: ++ expect-gall-deal |= $: expected=[wire=path id=sock app=term =deal:gall] - actual=(wind note:http-server-gate gift:able:http-server-gate) + actual=(wind note:eyre-gate gift:able:eyre-gate) == ^- tang :: @@ -2035,7 +1980,7 @@ %+ weld (expect-eq !>(wire.expected) !>(p.actual)) :: - =/ note=note:http-server-gate q.actual + =/ note=note:eyre-gate q.actual ?. ?=([%g %deal *] note) [%leaf "bad move, not a %deal: {}"]~ :: @@ -2099,16 +2044,16 @@ :: +perform-authentication: goes through the authentication flow :: ++ perform-authentication - |= $: http-server-gate=_http-server-gate + |= $: eyre-gate=_eyre-gate start-now=@da scry=sley == - ^- [tang _http-server-gate] + ^- [tang _eyre-gate] :: the browser then fetches the login page :: - =^ results1 http-server-gate - %- http-server-call :* - http-server-gate + =^ results1 eyre-gate + %- eyre-call :* + eyre-gate now=start-now scry=scry-provides-code ^= call-args @@ -2119,7 +2064,7 @@ [%'GET' '/~/login?redirect=/~landscape/inner-path' ~ ~] == ^= expected-moves - ^- (list move:http-server-gate) + ^- (list move:eyre-gate) :~ :* duct=~[/http-blah] %give %response @@ -2128,14 +2073,14 @@ %+ complete-http-start-event :- 200 ['content-type' 'text/html']~ - [~ (login-page:http-server-gate `'/~landscape/inner-path' ~nul)] + [~ (login-page:eyre-gate `'/~landscape/inner-path' ~nul)] == == == :: a response post redirects back to the application, setting cookie :: - =^ results2 http-server-gate - %- http-server-call :* - http-server-gate + =^ results2 eyre-gate + %- eyre-call :* + eyre-gate now=(add start-now ~m1) scry=scry-provides-code ^= call-args @@ -2151,7 +2096,7 @@ 'password=lidlut-tabwed-pillex-ridrup&redirect=/~landscape' == ^= expected-moves - ^- (list move:http-server-gate) + ^- (list move:eyre-gate) :~ ::NOTE this ~d7 is tied to the eyre-internal +session-timeout... :- duct=~[/http-blah] [%pass p=/sessions/expire q=[%b [%wait p=(add start-now ~d7.m1)]]] @@ -2169,19 +2114,19 @@ == == == :: - :_ http-server-gate + :_ eyre-gate (weld results1 results2) :: performs all initialization and an initial PUT. :: ++ perform-init-start-channel - |= $: http-server-gate=_http-server-gate + |= $: eyre-gate=_eyre-gate scry=sley == - ^- [tang _http-server-gate] + ^- [tang _eyre-gate] :: - =^ results1 http-server-gate - %- http-server-call :* - http-server-gate + =^ results1 eyre-gate + %- eyre-call :* + eyre-gate now=~1111.1.1 scry=scry-provides-code call-args=[duct=~[/init] ~ [%init ~nul]] @@ -2189,17 +2134,17 @@ == :: ensure there's an authenticated session :: - =^ results2 http-server-gate + =^ results2 eyre-gate %- perform-authentication :* - http-server-gate + eyre-gate now=~1111.1.2 scry=scry-provides-code == :: send the channel a poke and a subscription request :: - =^ results3 http-server-gate - %- http-server-call-with-comparator :* - http-server-gate + =^ results3 eyre-gate + %- eyre-call-with-comparator :* + eyre-gate now=~1111.1.2 scry=scry-provides-code ^= call-args @@ -2229,7 +2174,7 @@ ''' == ^= comparator - |= moves=(list move:http-server-gate) + |= moves=(list move:eyre-gate) ^- tang :: ?. ?=([^ ^ ^ ^ ~] moves) @@ -2262,12 +2207,15 @@ !> i.t.t.t.moves == == :: - :_ http-server-gate + :_ eyre-gate :(weld results1 results2 results3) :: ++ scry-provides-code ^- sley |= [* (unit (set monk)) =term =beam] ^- (unit (unit cage)) + ?: &(=(%ca term) =(/hoon/handler/gen s.beam)) + :+ ~ ~ + vase+!>(!>(|=(* |=(* [[%404 ~] ~])))) :: ?> =(%j term) ?> =(~nul p.beam) diff --git a/pkg/arvo/tests/sys/vane/ford.hoon b/pkg/arvo/tests/sys/vane/ford.hoon deleted file mode 100644 index 51b83dbfea..0000000000 --- a/pkg/arvo/tests/sys/vane/ford.hoon +++ /dev/null @@ -1,7066 +0,0 @@ -/+ *test, *test-ford -:: -|% -++ test-tear ^- tang - :: - ;: welp - %+ expect-eq - !> ~['a' 'bc' 'de'] - !> (tear:ford-gate 'a-bc-de') - :: - %+ expect-eq - !> ~['abc'] - !> (tear:ford-gate 'abc') - :: - %+ expect-eq - !> ~['ab/c'] - !> (tear:ford-gate 'ab/c') - == -:: -++ test-unify-jugs ^- tang - :: - %+ expect-eq - !> ^- (jug @tas @ud) - (my ~[[%a (sy 1 2 ~)] [%b (sy 3 4 5 6 ~)] [%c (sy 7 8 ~)]]) - !> %+ unify-jugs:ford-gate - `(jug @tas @ud)`(my ~[[%a (sy 1 2 ~)] [%b (sy 3 4 ~)]]) - `(jug @tas @ud)`(my ~[[%b (sy 5 6 ~)] [%c (sy 7 8 ~)]]) -:: -++ test-resource-wire-encoding ^- tang - :: - ;: welp - %+ expect-eq - !> /cx/~nul/desk/~1234.5.6/bar/foo - !> ^- path - %- scry-request-to-path:ford-gate - [%c care=%x [[~nul %desk [%da ~1234.5.6]] /foo/bar]] - :: - %+ expect-eq - !> [%c care=%x [[~nul %desk [%da ~1234.5.6]] /foo/bar]] - !> %- need - (path-to-scry-request:ford-gate /cx/~nul/desk/~1234.5.6/bar/foo) - == -:: -++ test-parse-scaffold ^- tang - :: - =/ parsed - %+ (full (parse-scaffold:ford-gate [[~nul %desk %da ~1234.5.6] /bar/foo])) - [1 1] - "!. |=(a=@ud +(a))" - ?~ q.parsed - [%leaf "failed to parse at {}"]~ - :: - %+ expect-eq - !> :- [1 19] - :- ~ - :_ [[1 19] ""] - ^- scaffold:ford-gate - :* source-rail=[[~nul %desk] /bar/foo] - zuse-version=%309 - structures=~ - libraries=~ - cranes=~ - ^= sources - :~ :* %dbug [/~nul/desk/~1234.5.6/foo/bar [[1 1] [1 19]]] - (ream '!. |=(a=@ud +(a))') - == == == - !> parsed -:: -++ test-parse-scaffold-sur-libk ^- tang - :: - =/ parsed - %+ (full (parse-scaffold:ford-gate [[~nul %desk %da ~1234.5.6] /bar/foo])) - [1 1] - """ - /- struct, face=other - /+ library, *thing - !. - |=(a a) - """ - ?~ q.parsed - [%leaf "failed to parse at {}"]~ - %+ expect-eq - !> :* source-rail=[[~nul %desk] /bar/foo] - zuse-version=309 - structures=~[[`%struct %struct] [`%face %other]] - libraries=~[[`%library %library] [~ %thing]] - cranes=~ - ^= sources - :~ :* %dbug - [/~nul/desk/~1234.5.6/foo/bar [3 1] [4 8]] - (ream '|=(a a)') - == == == - !> p.u.q.parsed -:: -++ test-parse-scaffold-zuse-version ^- tang - :: - =/ parsed - %+ (full (parse-scaffold:ford-gate [[~nul %desk %da ~1234.5.6] /bar/foo])) - [1 1] - """ - /? 400 - !. - |=(a a) - """ - ?~ q.parsed - [%leaf "failed to parse at {}"]~ - %+ expect-eq - !> :* source-rail=[[~nul %desk] /bar/foo] - zuse-version=400 - structures=~ - libraries=~ - cranes=~ - ^= sources - :~ :* %dbug - [/~nul/desk/~1234.5.6/foo/bar [2 1] [3 8]] - (ream '|=(a a)') - == == == - !> p.u.q.parsed -:: -++ test-parse-scaffold-crane-fssg ^- tang - :: - =/ parsed - %+ (full (parse-scaffold:ford-gate [[~nul %desk %da ~1234.5.6] /bar/foo])) - [1 1] - """ - /~ !. [a=1 b=3] - !. - |=(a b) - """ - ?~ q.parsed - [%leaf "failed to parse at {}"]~ - %+ expect-eq - !> :* source-rail=[[~nul %desk] /bar/foo] - zuse-version=309 - structures=~ - libraries=~ - ^= crane - :~ :* %fssg - %dbug - [/~nul/desk/~1234.5.6/foo/bar [1 5] [1 18]] - (ream '[a=1 b=3]') - == == - ^= sources - :~ :* %dbug - [/~nul/desk/~1234.5.6/foo/bar [2 1] [3 8]] - (ream '|=(a b)') - == == == - !> p.u.q.parsed -:: -++ test-parse-scaffold-crane-fsbc ^- tang - :: - =/ parsed - %+ (full (parse-scaffold:ford-gate [[~nul %desk %da ~1234.5.6] /bar/foo])) - [1 1] - """ - /$ !. |=(a a) - !. - |=(a b) - """ - ?~ q.parsed - [%leaf "failed to parse at {}"]~ - %+ expect-eq - !> :* source-rail=[[~nul %desk] /bar/foo] - zuse-version=309 - structures=~ - libraries=~ - ^= crane - :~ :* %fsbc - %dbug - [/~nul/desk/~1234.5.6/foo/bar [1 5] [1 16]] - (ream '|=(a a)') - == == - ^= sources - :~ :* %dbug - [/~nul/desk/~1234.5.6/foo/bar [2 1] [3 8]] - (ream '|=(a b)') - == == == - !> p.u.q.parsed -:: -++ test-parse-scaffold-crane-fsbr ^- tang - :: - =/ parsed - %+ (full (parse-scaffold:ford-gate [[~nul %desk %da ~1234.5.6] /bar/foo])) - [1 1] - """ - /| /~ ~ - /~ ~ - == - 5 - """ - ?~ q.parsed - [%leaf "failed to parse at {}"]~ - %+ expect-eq - !> :* source-rail=[[~nul %desk] /bar/foo] - zuse-version=309 - structures=~ - libraries=~ - ^= crane - :~ :* %fsbr - :~ :* %fssg %dbug - [/~nul/desk/~1234.5.6/foo/bar [1 9] [1 10]] - [%bust %null] - == - :* %fssg %dbug - [/~nul/desk/~1234.5.6/foo/bar [2 9] [2 10]] - [%bust %null] - == == == == - ^= sources - :~ [%dbug [/~nul/desk/~1234.5.6/foo/bar [4 1] [4 2]] [%sand %ud 5]] - == == - !> p.u.q.parsed -:: -++ test-parse-scaffold-crane-fsts ^- tang - :: - =/ parsed - %+ (full (parse-scaffold:ford-gate [[~nul %desk %da ~1234.5.6] /bar/foo])) - [1 1] - """ - /= a /~ ~ - 5 - """ - ?~ q.parsed - [%leaf "failed to parse at {}"]~ - %+ expect-eq - !> :* source-rail=[[~nul %desk] /bar/foo] - zuse-version=309 - structures=~ - libraries=~ - ^= crane - :~ :* %fsts %a - %fssg %dbug [/~nul/desk/~1234.5.6/foo/bar [1 12] [1 13]] - [%bust %null] - == == - ^= sources - :~ :* %dbug - [/~nul/desk/~1234.5.6/foo/bar [2 1] [2 2]] [%sand %ud 5] - == == == - !> p.u.q.parsed -:: -++ test-parse-scaffold-crane-fsdt ^- tang - :: - =/ parsed - %+ (full (parse-scaffold:ford-gate [[~nul %desk %da ~1234.5.6] /bar/foo])) - [1 1] - """ - /. /~ !. a=5 - /~ !. b=6 - == - 5 - """ - ?~ q.parsed - [%leaf "failed to parse at {}"]~ - %+ expect-eq - !> :* source-rail=[[~nul %desk] /bar/foo] - zuse-version=309 - structures=~ - libraries=~ - ^= crane - :~ :* %fsdt - :~ :* %fssg %dbug - [/~nul/desk/~1234.5.6/foo/bar [1 9] [1 16]] - (ream 'a=5') - == - :* %fssg %dbug - [/~nul/desk/~1234.5.6/foo/bar [2 9] [2 16]] - (ream 'b=6') - == == == == - ^= sources - :~ :* %dbug - [/~nul/desk/~1234.5.6/foo/bar [4 1] [4 2]] [%sand %ud 5] - == == == - !> p.u.q.parsed -:: -++ test-parse-scaffold-crane-fscm ^- tang - :: - =/ parsed - %+ (full (parse-scaffold:ford-gate [[~nul %desk %da ~1234.5.6] /bar/foo])) - [1 1] - """ - /, - /path/to/a - /~ !. a=5 - :: - /path/to/b - /~ !. b=6 - == - 1 - """ - ?~ q.parsed - [%leaf "failed to parse at {}"]~ - %+ expect-eq - !> :* source-rail=[[~nul %desk] /bar/foo] - zuse-version=309 - structures=~ - libraries=~ - ^= crane - :~ :* %fscm - :~ :- /path/to/a - :* %fssg %dbug - [/~nul/desk/~1234.5.6/foo/bar [3 7] [3 14]] - (ream 'a=5') - == - :- /path/to/b - :* %fssg %dbug - [/~nul/desk/~1234.5.6/foo/bar [6 7] [6 14]] - (ream 'b=6') - == == == == - ^= sources - :~ :* %dbug - [/~nul/desk/~1234.5.6/foo/bar [8 1] [8 2]] [%sand %ud 1] - == == == - !> p.u.q.parsed -:: -++ test-parse-scaffold-crane-fspm ^- tang - :: - =/ parsed - %+ (full (parse-scaffold:ford-gate [[~nul %desk %da ~1234.5.6] /bar/foo])) - [1 1] - """ - /= data /& mark /~ !. a=1 - 1 - """ - ?~ q.parsed - [%leaf "failed to parse at {}"]~ - %+ expect-eq - !> :* source-rail=[[~nul %desk] /bar/foo] - zuse-version=309 - structures=~ - libraries=~ - ^= crane - :~ :* %fsts %data - %fspm [%mark ~] - %fssg %dbug - [/~nul/desk/~1234.5.6/foo/bar [1 25] [1 32]] - (ream 'a=1') - == == - ^= sources - :~ :* %dbug - [/~nul/desk/~1234.5.6/foo/bar [2 1] [2 2]] [%sand %ud 1] - == == == - !> p.u.q.parsed -:: -++ test-parse-scaffold-crane-fscb ^- tang - :: - =/ parsed - %+ (full (parse-scaffold:ford-gate [[~nul %desk %da ~1234.5.6] /bar/foo])) - [1 1] - """ - /_ /mark/ - 8 - """ - ?~ q.parsed - [%leaf "failed to parse at {}"]~ - %+ expect-eq - !> :* source-rail=[[~nul %desk] /bar/foo] - zuse-version=309 - structures=~ - libraries=~ - ^= crane - :~ :* %fscb %fszy %mark - == == - ^= sources - :~ :* %dbug - [/~nul/desk/~1234.5.6/foo/bar [2 1] [2 2]] [%sand %ud 8] - == == == - !> p.u.q.parsed -:: -++ test-parse-scaffold-crane-fssm ^- tang - :: - =/ parsed - %+ (full (parse-scaffold:ford-gate [[~nul %desk %da ~1234.5.6] /bar/foo])) - [1 1] - """ - /= data - /; !. |=(a=@u +(a)) - /~ !. 5 - 7 - """ - ?~ q.parsed - [%leaf "failed to parse at {}"]~ - %+ expect-eq - !> :* source-rail=[[~nul %desk] /bar/foo] - zuse-version=309 - structures=~ - libraries=~ - ^= crane - :~ :* %fsts %data - %fssm - :* %dbug - [/~nul/desk/~1234.5.6/foo/bar [2 7] [2 24]] - (ream '|=(a=@u +(a))') - == - %fssg - :* %dbug - [/~nul/desk/~1234.5.6/foo/bar [3 7] [3 12]] - (ream '5') - == == == - ^= sources - :~ :* %dbug - [/~nul/desk/~1234.5.6/foo/bar [4 1] [4 2]] [%sand %ud 7] - == == == - !> p.u.q.parsed -:: -++ test-parse-scaffold-crane-fscl ^- tang - :: - =/ parsed - %+ (full (parse-scaffold:ford-gate [[~nul %desk %da ~1234.5.6] /bar/foo])) - [1 1] - """ - /= tests - /: /===/tests - /_ /mark/ - 3 - """ - ?~ q.parsed - [%leaf "failed to parse at {}"]~ - %+ expect-eq - !> :* source-rail=[[~nul %desk] /bar/foo] - zuse-version=309 - structures=~ - libraries=~ - ^= crane - :~ :* %fsts %tests - %fscl [[~ ~[~ ~ ~ [~ [%sand %tas 495.874.958.708]]]] ~] - %fscb %fszy %mark - == == - ^= sources - :~ :* %dbug - [/~nul/desk/~1234.5.6/foo/bar [4 1] [4 2]] [%sand %ud 3] - == == == - !> p.u.q.parsed -:: -++ test-parse-scaffold-crane-fskt ^- tang - :: - =/ parsed - %+ (full (parse-scaffold:ford-gate [[~nul %desk %da ~1234.5.6] /bar/foo])) - [1 1] - """ - /= data - /^ (list @ud) - /. /~ 1 - /~ 2 - == - 6 - """ - ?~ q.parsed - [%leaf "failed to parse at {}"]~ - %+ expect-eq - !> :* source-rail=[[~nul %desk] /bar/foo] - zuse-version=309 - structures=~ - libraries=~ - ^= crane - :~ :* %fsts %data - %fskt - :* %dbug - [/~nul/desk/~1234.5.6/foo/bar [2 7] [2 17]] - %make - :+ %dbug - [/~nul/desk/~1234.5.6/foo/bar [2 8] [2 12]] - [%wing ~[%list]] - :~ :+ %dbug - [/~nul/desk/~1234.5.6/foo/bar [2 13] [2 16]] - [%base [%atom %ud]] - == - == - %fsdt - :~ :- %fssg - :+ %dbug - [/~nul/desk/~1234.5.6/foo/bar [3 11] [3 12]] - [%sand %ud 1] - :: - :- %fssg - :+ %dbug - [/~nul/desk/~1234.5.6/foo/bar [4 11] [4 12]] - [%sand %ud 2] - == == == - ^= sources - :~ :* %dbug - [/~nul/desk/~1234.5.6/foo/bar [6 1] [6 2]] [%sand %ud 6] - == == == - !> p.u.q.parsed -:: -++ test-parse-scaffold-crane-fszp ^- tang - :: - =/ parsed - %+ (full (parse-scaffold:ford-gate [[~nul %desk %da ~1234.5.6] /bar/foo])) - [1 1] - """ - /= data /!mark/ - 2 - """ - ?~ q.parsed - [%leaf "failed to parse at {}"]~ - %+ expect-eq - !> :* source-rail=[[~nul %desk] /bar/foo] - zuse-version=309 - structures=~ - libraries=~ - ^= crane - :~ :* %fsts %data - %fszp %mark - == == - ^= sources - :~ :* %dbug - [/~nul/desk/~1234.5.6/foo/bar [2 1] [2 2]] [%sand %ud 2] - == == == - !> p.u.q.parsed -:: -++ test-parse-scaffold-crane-fszy ^- tang - :: - =/ parsed - %+ (full (parse-scaffold:ford-gate [[~nul %desk %da ~1234.5.6] /bar/foo])) - [1 1] - """ - /= data /mark/ - 9 - """ - ?~ q.parsed - [%leaf "failed to parse at {}"]~ - %+ expect-eq - !> :* source-rail=[[~nul %desk] /bar/foo] - zuse-version=309 - structures=~ - libraries=~ - ^= crane - :~ :* %fsts %data - %fszy %mark - == == - ^= sources - :~ :* %dbug - [/~nul/desk/~1234.5.6/foo/bar [2 1] [2 2]] [%sand %ud 9] - == == == - !> p.u.q.parsed -:: -++ test-literal ^- tang - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=scry-is-forbidden - :: send a pinned literal, expects a %made response with pinned literal - :: - ^= call-args - [duct=~ type=~ %build live=%.n [%$ %noun !>(**)]] - :: - ^= moves - :~ :* duct=~ %give %made ~1234.5.6 - %complete %success %$ %noun !>(**) - == == - == - :: - %+ welp - results1 - (expect-ford-empty ford-gate ~nul) -:: -++ test-autocons-same ^- tang - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=scry-is-forbidden - :: if we autocons the same schematic, we should get two of it as a result - :: - ^= call-args - :* duct=~ type=~ %build live=%.n - [[%$ %noun !>(**)] [%$ %noun !>(**)]] - == - :: - ^= moves - :~ :* duct=~ %give %made ~1234.5.6 %complete - %success - [%success %$ %noun !>(**)] - [%success %$ %noun !>(**)] - == == == - :: - %+ welp - results1 - (expect-ford-empty ford-gate ~nul) -:: -++ test-autocons-different ^- tang - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=scry-is-forbidden - :: if we autocons different schematics, we get different values - :: - ^= call-args - :* duct=~ type=~ %build live=%.n - [[%$ %noun !>(42)] [%$ %noun !>(43)]] - == - :: - ^= moves - :~ :* duct=~ %give %made ~1234.5.6 %complete - %success - [%success %$ %noun !>(42)] - [%success %$ %noun !>(43)] - == == == - :: - %+ welp - results1 - (expect-ford-empty ford-gate ~nul) -:: -++ test-scry-clay-succeed ^- tang - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=(scry-succeed ~1234.5.6 [%noun !>(42)]) - :: test a pinned scry which succeeds - :: - ^= call-args - :* duct=~ type=~ %build live=%.n - [%scry %c ren=%x rail=[[~nul %desk] /bar/foo]] - == - :: - ^= moves - :~ :* duct=~ %give %made ~1234.5.6 %complete %success - [%scry %noun !>(42)] - == == == - :: - %+ welp - results1 - (expect-ford-empty ford-gate ~nul) -:: -++ test-scry-clay-fail ^- tang - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=(scry-fail ~1234.5.6) - :: attempting to scry a path which fails should produce an error - :: - ^= call-args - :* duct=~ type=~ %build live=%.n - [%scry %c ren=%x rail=[[~nul %desk] /bar/foo]] - == - :: - ^= moves - :~ :* duct=~ %give %made ~1234.5.6 %complete - %error - :~ leaf+"scry failed for" - leaf+"%cx /~nul/desk/~1234.5.6/foo/bar" - == == == == - :: - %+ weld - results1 - (expect-ford-empty ford-gate ~nul) -:: -++ test-scry-clay-block ^- tang - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=(scry-block ~1234.5.6) - :: when we scry on a blocked path, expect a subscription move - :: - ^= call-args - :* duct=~ type=~ %build live=%.n - [%scry %c ren=%x rail=[[~nul %desk] /bar/foo]] - == - :: - ^= moves - :~ :* duct=~ %pass - wire=/scry-request/cx/~nul/desk/~1234.5.6/foo/bar - %c %warp ~nul %desk - ~ %sing %x [%da ~1234.5.6] /foo/bar - == == == - :: - =^ results2 ford-gate - %- ford-take :* - ford-gate - now=~1234.5.7 - scry=scry-is-forbidden - :: when clay responds, send a %made - :: - ^= take-args - :* wire=/scry-request/cx/~nul/desk/~1234.5.6/foo/bar duct=~ - ^= wrapped-sign ^- (hypo sign:ford-gate) :- *type - [%c %writ ~ [%x [%da ~1234.5.6] %desk] /bar/foo %noun !>(42)] - == - :: - ^= moves - :~ :* duct=~ %give %made ~1234.5.6 %complete %success - [%scry %noun !>(42)] - == == == - :: - ;: welp - results1 - results2 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-scry-clay-multiblock ^- tang - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=(scry-block ~1234.5.6) - :: when we scry on a blocked path, expect a subscription move - :: - ^= call-args - :* duct=~[/one] type=~ %build live=%.n - [%scry %c ren=%x rail=[[~nul %desk] /bar/foo]] - == - :: - ^= moves - :~ :* duct=~[/one] %pass - wire=/scry-request/cx/~nul/desk/~1234.5.6/foo/bar - %c %warp ~nul %desk - ~ %sing %x [%da ~1234.5.6] /foo/bar - == == == - :: - =^ results2 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.7 - scry=(scry-block ~1234.5.6) - :: when we scry on a blocked path, expect a subscription move - :: - ^= call-args - :* duct=~[/two] type=~ %build live=%.n - [%pin ~1234.5.6 [%scry %c ren=%x rail=[[~nul %desk] /bar/foo]]] - == - :: - ^= moves ~ - == - :: - =^ results3 ford-gate - %- ford-take :* - ford-gate - now=~1234.5.8 - scry=scry-is-forbidden - :: when clay responds, send a %made - :: - ^= take-args - :* wire=/scry-request/cx/~nul/desk/~1234.5.6/foo/bar duct=~ - ^= wrapped-sign ^- (hypo sign:ford-gate) :- *type - [%c %writ ~ [%x [%da ~1234.5.6] %desk] /bar/foo %noun !>(42)] - == - :: - ^= moves - :~ :* duct=~[/two] %give %made ~1234.5.7 %complete %success - [%scry %noun !>(42)] - == - :* duct=~[/one] %give %made ~1234.5.6 %complete %success - [%scry %noun !>(42)] - == == == - :: - ;: welp - results1 - results2 - results3 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-scry-clay-cancel ^- tang - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=(scry-block ~1234.5.6) - :: when we scry on a blocked path, expect a subscription move - :: - ^= call-args - :* duct=~[/one] type=~ %build live=%.n - [%scry %c ren=%x rail=[[~nul %desk] /bar/foo]] - == - :: - ^= moves - :~ :* duct=~[/one] %pass - wire=/scry-request/cx/~nul/desk/~1234.5.6/foo/bar - %c %warp ~nul %desk - ~ %sing %x [%da ~1234.5.6] /foo/bar - == == == - :: - =^ results2 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.8 - scry=scry-is-forbidden - :: - call-args=[duct=~[/one] type=~ %kill ~] - :: - ^= moves - :~ :* duct=~[/one] %pass - wire=/scry-request/cx/~nul/desk/~1234.5.6/foo/bar - %c %warp ~nul %desk ~ - == == == - :: - ;: weld - results1 - results2 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-scry-clay-live ^- tang - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=(scry-succeed ~1234.5.6 [%noun !>(42)]) - :: - ^= call-args - :* duct=~[/first] type=~ %build live=%.y - [%scry %c care=%x rail=[[~nul %desk] /bar/foo]] - == - :: - ^= moves - :~ :* duct=~[/first] %give %made ~1234.5.6 %complete %success - [%scry %noun !>(42)] - == - :* duct=~[/first] %pass wire=/clay-sub/~nul/desk/~1234.5.6 - %c %warp ~nul %desk - `[%mult [%da ~1234.5.6] (sy [%x /foo/bar]~)] - == == == - :: - =^ results2 ford-gate - %- ford-take :* - ford-gate - now=~1234.5.7 - scry=(scry-succeed ~1234.5.7 [%noun !>(43)]) - :: - ^= take-args - :* wire=/clay-sub/~nul/desk/~1234.5.6 duct=~[/first] - ^= wrapped-sign ^- (hypo sign:ford-gate) :- *type - [%c %wris [%da ~1234.5.7] (sy [%x /foo/bar]~)] - == - :: - ^= moves - :~ :* duct=~[/first] %give %made ~1234.5.7 %complete %success - [%scry %noun !>(43)] - == - :* duct=~[/first] %pass wire=/clay-sub/~nul/desk/~1234.5.7 - %c %warp ~nul %desk - `[%mult [%da ~1234.5.7] (sy [%x /foo/bar]~)] - == == == - :: - =^ results3 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.8 - scry=scry-is-forbidden - :: - call-args=[duct=~[/first] type=~ %kill ~] - :: - ^= moves - :~ :* duct=~[/first] %pass wire=/clay-sub/~nul/desk/~1234.5.7 - %c %warp ~nul %desk ~ - == == == - :: - ;: weld - results1 - results2 - results3 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-scry-clay-live-again ^- tang - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=(scry-succeed ~1234.5.6 [%noun !>(42)]) - :: perform a live scry, we should get a %made and a clay subscription - :: - ^= call-args - :* duct=~[/first] type=~ %build live=%.y - [%scry %c care=%x rail=[[~nul %desk] /bar/foo]] - == - :: - ^= moves - :~ :* duct=~[/first] %give %made ~1234.5.6 %complete %success - [%scry %noun !>(42)] - == - :* duct=~[/first] %pass wire=/clay-sub/~nul/desk/~1234.5.6 - %c %warp ~nul %desk - `[%mult [%da ~1234.5.6] (sy [%x /foo/bar]~)] - == == == - :: - =^ results2 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.7 - scry=(scry-succeed ~1234.5.7 [%noun !>(42)]) - :: - ^= call-args - :* duct=~[/second] type=~ %build live=%.y - [%scry %c care=%x rail=[[~nul %desk] /bar/foo]] - == - :: - ^= moves - :~ :* duct=~[/second] %give %made ~1234.5.7 %complete %success - [%scry %noun !>(42)] - == - :* duct=~[/second] %pass wire=/clay-sub/~nul/desk/~1234.5.7 - %c %warp ~nul %desk - `[%mult [%da ~1234.5.7] (sy [%x /foo/bar]~)] - == == == - :: - =^ results3 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.8 - scry=scry-is-forbidden - :: - call-args=[duct=~[/first] type=~ %kill ~] - ^= moves - :~ :* duct=~[/first] %pass wire=/clay-sub/~nul/desk/~1234.5.6 - %c %warp ~nul %desk ~ - == == == - :: - =^ results4 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.9 - scry=scry-is-forbidden - :: - call-args=[duct=~[/second] type=~ %kill ~] - :: - ^= moves - :~ :* duct=~[/second] %pass wire=/clay-sub/~nul/desk/~1234.5.7 - %c %warp ~nul %desk ~ - == == == - :: - ;: weld - results1 - results2 - results3 - results4 - (expect-ford-empty ford-gate ~nul) - == -:: tests multiple subscriptions on the same resource at different times -:: -:: We can depend on the same paths but at different times. Make sure we can -:: block on /~nul/desk/~1234.5.7/... and /~nul/desk/~1234.5.8/... at the -:: same time. -:: -++ test-scry-clay-same-path ^- tang - :: - =/ scry-type=type [%atom %tas ~] - :: - =/ blocks=(set @da) (sy ~1234.5.7 ~1234.5.8 ~) - :: - =/ scry-schematic=schematic:ford-gate - [%scry %c care=%x rail=[[~nul %desk] /bar/foo]] - =/ autocons=schematic:ford-gate - [[%pin ~1234.5.7 scry-schematic] [%pin ~1234.5.8 scry-schematic]] - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-blocks blocks) - :: - call-args=[duct=~[/first] type=~ %build live=%.y autocons] - :: - ^= comparator - |= moves=(list move:ford-gate) - ^- tang - :: - %+ expect-eq - !> %- sy - :~ :* duct=~[/first] %pass - wire=/scry-request/cx/~nul/desk/~1234.5.7/foo/bar - %c %warp ~nul %desk - `[%sing %x [%da ~1234.5.7] /foo/bar] - == - :* duct=~[/first] %pass - wire=/scry-request/cx/~nul/desk/~1234.5.8/foo/bar - %c %warp ~nul %desk - `[%sing %x [%da ~1234.5.8] /foo/bar] - == == - !> (sy moves) - == - :: - =^ results2 ford-gate - %- ford-take :* - ford-gate - now=~1234.5.7 - scry=(scry-blocks blocks) - :: - ^= take-args - :* wire=/scry-request/cx/~nul/desk/~1234.5.7/foo/bar duct=~[/first] - ^= wrapped-sign ^- (hypo sign:ford-gate) :- *type - :* %c %writ ~ [%x [%da ~1234.5.7] %desk] - /bar/foo %noun scry-type %seven - == - == - :: - expected-moves=~ - == - :: - =^ results3 ford-gate - %- ford-take :* - ford-gate - now=~1234.5.8 - scry=(scry-blocks blocks) - :: - ^= take-args - :* wire=/scry-request/cx/~nul/desk/~1234.5.8/foo/bar duct=~[/first] - ^= wrapped-sign ^- (hypo sign:ford-gate) :- *type - :* %c %writ ~ [%x [%da ~1234.5.8] %desk] - /bar/foo %noun scry-type %eight - == - == - :: - ^= expected-moves - ^- (list move:ford-gate) - :~ :* duct=~[/first] %give %made ~1234.5.6 %complete %success - [%success %scry %noun scry-type %seven] - [%success %scry %noun scry-type %eight] - == == == - :: - =^ results4 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.9 - scry=scry-is-forbidden - :: - call-args=[duct=~[/first] type=~ %kill ~] - :: - moves=~ - == - :: - ;: weld - results1 - results2 - results3 - results4 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-pinned-in-past ^- tang - :: - =/ schematic [%pin ~1234.5.5 [%$ %noun !>(42)]] - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=scry-is-forbidden - :: - call-args=[duct=~[/pin] type=~ %build live=%.n schematic] - :: - ^= expected-moves - :~ :* duct=~[/pin] %give %made ~1234.5.6 %complete - %success %$ %noun !>(42) - == == == - results1 -:: -++ test-pinned-in-future ^- tang - :: - =/ schematic [%pin ~1234.5.7 [%$ %noun !>(42)]] - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=scry-is-forbidden - :: - call-args=[duct=~[/pin] type=~ %build live=%.n schematic] - :: - ^= expected-moves - :~ :* duct=~[/pin] %give %made ~1234.5.6 %complete - %success %$ %noun !>(42) - == == == - results1 -:: -++ test-pinned-in-pin ^- tang - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.8 - scry=(scry-succeed ~1234.5.6 [%noun !>(42)]) - :: - ^= call-args - :* duct=~[/pinned-in-pin] type=~ %build live=%.n - %pin ~1234.5.7 - %pin ~1234.5.6 - [%scry %c care=%x rail=[[~nul %desk] /bar/foo]] - == - :: - ^= moves - :~ :* duct=~[/pinned-in-pin] - %give %made ~1234.5.8 %complete - [%success %scry %noun !>(42)] - == == == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-pinned-in-live ^- tang - :: - =/ scry-42 (scry-succeed ~1234.5.6 [%noun !>(42)]) - =/ scry-43 (scry-succeed ~1234.5.7 [%noun !>(43)]) - :: - =/ schematic=schematic:ford-gate - :* %same %pin ~1234.5.6 - [%scry %c care=%x rail=[[~nul %desk] /bar/foo]] - == - :: - =/ build=build:ford-gate [~1234.5.6 schematic] - =/ result=build-result:ford-gate - [%success [%scry %noun !>(42)]] - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=scry-42 - :: - call-args=[duct=~[/live] type=~ %build live=%.y schematic] - moves=[duct=~[/live] %give %made ~1234.5.6 %complete result]~ - == - :: - =^ results2 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.8 - scry=scry-is-forbidden - :: - call-args=[duct=~[/live] type=~ %kill ~] - moves=~ - == - :: - ;: weld - results1 - results2 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-live-build-that-blocks ^- tang - :: - =/ scry-blocked (scry-block ~1234.5.6) - =/ scry-42 (scry-succeed ~1234.5.6 [%noun !>(42)]) - =/ scry-43 (scry-succeed ~1234.5.8 [%noun !>(43)]) - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=scry-blocked - :: - ^= call-args - :* duct=~[/live] type=~ %build live=%.y - [%scry %c care=%x rail=[[~nul %desk] /bar/foo]] - == - :: - ^= moves - :~ :* duct=~[/live] %pass - wire=/scry-request/cx/~nul/desk/~1234.5.6/foo/bar - %c %warp ~nul %desk - ~ %sing %x [%da ~1234.5.6] /foo/bar - == == == - :: - =^ results2 ford-gate - %- ford-take :* - ford-gate - now=~1234.5.7 - scry=scry-42 - :: - ^= take-args - :* wire=/scry-request/cx/~nul/desk/~1234.5.6/foo/bar duct=~[/live] - ^= wrapped-sign ^- (hypo sign:ford-gate) :- *type - [%c %writ ~ [%x [%da ~1234.5.6] %desk] /bar/foo %noun !>(42)] - == - :: - ^= moves - :~ :* duct=~[/live] %give %made ~1234.5.6 %complete %success - [%scry %noun !>(42)] - == - :* duct=~[/live] %pass wire=/clay-sub/~nul/desk/~1234.5.6 - %c %warp ~nul %desk - `[%mult [%da ~1234.5.6] (sy [%x /foo/bar]~)] - == == == - :: - =^ results3 ford-gate - %- ford-take :* - ford-gate - now=~1234.5.8 - scry=scry-43 - :: - ^= take-args - :* wire=/clay-sub/~nul/desk/~1234.5.6 duct=~[/live] - ^= wrapped-sign ^- (hypo sign:ford-gate) :- *type - [%c %wris [%da ~1234.5.8] (sy [%x /foo/bar]~)] - == - :: - ^= moves - :~ :* duct=~[/live] %give %made ~1234.5.8 %complete %success - [%scry %noun !>(43)] - == - :* duct=~[/live] %pass wire=/clay-sub/~nul/desk/~1234.5.8 - %c %warp ~nul %desk - `[%mult [%da ~1234.5.8] (sy [%x /foo/bar]~)] - == == == - :: - =^ results4 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.9 - scry=scry-is-forbidden - :: - call-args=[duct=~[/live] type=~ %kill ~] - :: - ^= moves - :~ :* duct=~[/live] %pass wire=/clay-sub/~nul/desk/~1234.5.8 - %c %warp ~nul %desk ~ - == == == - :: - ;: weld - results1 - results2 - results3 - results4 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-live-and-once ^- tang - :: - =/ scry-blocked (scry-block ~1234.5.6) - =/ scry-42 (scry-succeed ~1234.5.6 [%noun !>(42)]) - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=scry-blocked - :: - ^= call-args - :* duct=~[/live] type=~ %build live=%.y - [%scry %c care=%x rail=[[~nul %desk] /bar/foo]] - == - :: - ^= moves - :~ :* duct=~[/live] %pass - wire=/scry-request/cx/~nul/desk/~1234.5.6/foo/bar - %c %warp ~nul %desk - ~ %sing %x [%da ~1234.5.6] /foo/bar - == == == - :: - =^ results2 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.7 - scry=scry-blocked - :: - ^= call-args - :* duct=~[/once] type=~ %build live=%.n - [%pin ~1234.5.6 [%scry %c ren=%x rail=[[~nul %desk] /bar/foo]]] - == - :: - moves=~ - == - :: - =^ results3 ford-gate - %- ford-take :* - ford-gate - now=~1234.5.8 - scry=scry-is-forbidden - :: - ^= take-args - :* wire=/scry-request/cx/~nul/desk/~1234.5.6/foo/bar duct=~[/live] - ^= wrapped-sign ^- (hypo sign:ford-gate) :- *type - [%c %writ ~ [%x [%da ~1234.5.6] %desk] /bar/foo %noun !>(42)] - == - :: - ^= moves - :~ :* duct=~[/live] %give %made ~1234.5.6 %complete - [%success [%scry %noun !>(42)]] - == - :* duct=~[/live] %pass wire=/clay-sub/~nul/desk/~1234.5.6 - %c %warp ~nul %desk - `[%mult [%da ~1234.5.6] (sy [%x /foo/bar]~)] - == - :* duct=~[/once] %give %made ~1234.5.7 %complete - [%success [%scry %noun !>(42)]] - == == == - :: - =^ results4 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.9 - scry=scry-is-forbidden - :: - call-args=[duct=~[/live] type=~ %kill ~] - :: - ^= moves - :~ :* duct=~[/live] %pass wire=/clay-sub/~nul/desk/~1234.5.6 - %c %warp ~nul %desk ~ - == == == - :: - ;: weld - results1 - results2 - results3 - results4 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-live-two-deep ^- tang - :: - =/ scry-42 (scry-succeed ~1234.5.6 [%noun !>(42)]) - =/ scry-43 (scry-succeed ~1234.5.7 [%noun !>(43)]) - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=scry-42 - :: - ^= call-args - :* duct=~[/two-deep-4u] type=~ %build live=%.y - [%same [%scry %c care=%x rail=[[~nul %desk] /bar/foo]]] - == - :: - ^= moves - :~ :* duct=~[/two-deep-4u] %give %made ~1234.5.6 %complete - %success [%scry %noun !>(42)] - == - :* duct=~[/two-deep-4u] %pass - wire=/clay-sub/~nul/desk/~1234.5.6 - %c %warp ~nul %desk - `[%mult [%da ~1234.5.6] (sy [%x /foo/bar]~)] - == == == - :: - =^ results2 ford-gate - %- ford-take :* - ford-gate - now=~1234.5.7 - scry=scry-43 - :: - ^= take-args - :* wire=/clay-sub/~nul/desk/~1234.5.6 duct=~[/two-deep-4u] - ^= wrapped-sign ^- (hypo sign:ford-gate) :- *type - [%c %wris [%da ~1234.5.7] (sy [%x /foo/bar]~)] - == - :: - ^= moves - :~ :* duct=~[/two-deep-4u] %give %made ~1234.5.7 %complete - %success [%scry %noun !>(43)] - == - :* duct=~[/two-deep-4u] %pass - wire=/clay-sub/~nul/desk/~1234.5.7 - %c %warp ~nul %desk - `[%mult [%da ~1234.5.7] (sy [%x /foo/bar]~)] - == == == - :: - =^ results3 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.8 - scry=scry-is-forbidden - :: - call-args=[duct=~[/two-deep-4u] type=~ %kill ~] - :: - ^= moves - :~ :* duct=~[/two-deep-4u] %pass - wire=/clay-sub/~nul/desk/~1234.5.7 - %c %warp ~nul %desk ~ - == == == - :: - ;: weld - results1 - results2 - results3 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-live-three-deep ^- tang - :: - =/ scry-type=type [%atom %tas ~] - :: - =/ scry-results=(map [term beam] cage) - %- my :~ - :- [%cx [[~nul %desk %da ~1234.5.6] /bar/foo]] - [%noun scry-type %it-doesnt-matter] - :: - :- [%cx [[~nul %desk %da ~1234.5.7] /bar/foo]] - [%noun scry-type %changed] - == - :: - =/ scry (scry-with-results scry-results) - :: - =/ formula=hoon (ream '`@tas`%constant') - =/ subject-schematic=schematic:ford-gate - [%scry %c %x [~nul %desk] /bar/foo] - :: - =/ ride=schematic:ford-gate [%ride formula subject-schematic] - =/ same=schematic:ford-gate [%same ride] - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=scry - :: - call-args=[duct=~[/ride] type=~ %build live=%.y same] - :: - ^= moves - :~ :* duct=~[/ride] %give %made ~1234.5.6 %complete - [%success [%ride scry-type %constant]] - == - :* duct=~[/ride] %pass wire=/clay-sub/~nul/desk/~1234.5.6 - %c %warp ~nul %desk - `[%mult [%da ~1234.5.6] (sy [%x /foo/bar] ~)] - == == == - :: - =^ results2 ford-gate - %- ford-take :* - ford-gate - now=~1234.5.7 - scry=scry - :: - ^= take-args - :* wire=/clay-sub/~nul/desk/~1234.5.6 duct=~[/ride] - ^= wrapped-sign ^- (hypo sign:ford-gate) :- *type - [%c %wris [%da ~1234.5.7] (sy [%x /foo/bar]~)] - == - :: - ^= moves - :~ :* duct=~[/ride] %pass wire=/clay-sub/~nul/desk/~1234.5.7 - %c %warp ~nul %desk - `[%mult [%da ~1234.5.7] (sy [%x /foo/bar] ~)] - == == == - :: - =^ results3 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.8 - scry=scry-is-forbidden - :: - call-args=[duct=~[/ride] type=~ %kill ~] - :: - ^= moves - :~ :* duct=~[/ride] %pass wire=/clay-sub/~nul/desk/~1234.5.7 - %c %warp ~nul %desk ~ - == == == - :: - ;: weld - results1 - results2 - results3 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-live-triangle ^- tang - :: - =/ scry-results=(map [term beam] cage) - %- my :~ - :- [%cx [[~nul %desk %da ~1234.5.6] /bar/foo]] - [%noun !>(%it-does-in-fact-matter)] - :: - :- [%cx [[~nul %desk %da ~1234.5.7] /bar/foo]] - [%noun !>(%changed)] - == - :: - =/ scry (scry-with-results scry-results) - :: - =/ formula=hoon (ream '`@tas`%constant') - =/ subject-schematic=schematic:ford-gate - [%scry %c %x [~nul %desk] /bar/foo] - :: - =/ ride-type=type [%atom %tas ~] - =/ ride=schematic:ford-gate [%ride formula subject-schematic] - =/ autocons=schematic:ford-gate [ride subject-schematic] - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=scry - :: - call-args=[duct=~[/ride] type=~ %build live=%.y autocons] - :: - ^= moves - :~ :* duct=~[/ride] %give %made ~1234.5.6 %complete %success - [%success [%ride ride-type %constant]] - [%success [%scry %noun !>(%it-does-in-fact-matter)]] - == - :* duct=~[/ride] %pass wire=/clay-sub/~nul/desk/~1234.5.6 - %c %warp ~nul %desk - `[%mult [%da ~1234.5.6] (sy [%x /foo/bar] ~)] - == == == - :: - =^ results2 ford-gate - %- ford-take :* - ford-gate - now=~1234.5.7 - scry=scry - :: - ^= take-args - :* wire=/clay-sub/~nul/desk/~1234.5.6 duct=~[/ride] - ^= wrapped-sign ^- (hypo sign:ford-gate) :- *type - [%c %wris [%da ~1234.5.7] (sy [%x /foo/bar]~)] - == - :: - ^= moves - :~ :* duct=~[/ride] %give %made ~1234.5.7 %complete %success - [%success [%ride ride-type %constant]] - [%success [%scry %noun !>(%changed)]] - == - :* duct=~[/ride] %pass wire=/clay-sub/~nul/desk/~1234.5.7 - %c %warp ~nul %desk - `[%mult [%da ~1234.5.7] (sy [%x /foo/bar] ~)] - == == == - :: - =^ results3 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.8 - scry=scry-is-forbidden - :: - call-args=[duct=~[/ride] type=~ %kill ~] - :: - ^= moves - :~ :* duct=~[/ride] %pass wire=/clay-sub/~nul/desk/~1234.5.7 - %c %warp ~nul %desk ~ - == == == - :: - ;: weld - results1 - results2 - results3 - (expect-ford-empty ford-gate ~nul) - == -:: like +test-live-triangle, but with another pinned build -:: -:: Ensures that we deal with various issues with live builds which -:: were partially pinned and their interaction with other live builds. -:: -++ test-live-and-pinned-triangle ^- tang - :: - =/ scry-type=type [%atom %tas ~] - :: - =/ scry-results=(map [term beam] cage) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /bar/foo]] - [%noun scry-type %it-does-in-fact-matter] - :: - :- [%cx [[~nul %home %da ~1234.5.7] /bar/foo]] - [%noun scry-type %it-does-in-fact-matter] - == - :: - =/ scry (scry-with-results scry-results) - :: - =/ formula=hoon (ream '`@tas`%constant') - =/ subject-schematic=schematic:ford-gate [%scry %c %x [~nul %home] /bar/foo] - :: - =/ ride-type=type [%atom %tas ~] - =/ ride=schematic:ford-gate [%ride formula subject-schematic] - =/ autocons=schematic:ford-gate [ride subject-schematic] - :: - =/ static=schematic:ford-gate [%same [%pin ~1234.5.6 autocons]] - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=scry - :: - call-args=[duct=~[/static] type=~ %build live=%.y static] - :: - ^= moves - :~ :* duct=~[/static] %give %made ~1234.5.6 %complete %success - [%success [%ride ride-type %constant]] - [%success [%scry %noun scry-type %it-does-in-fact-matter]] - == == == - :: - =^ results2 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.7 - scry=scry - :: - call-args=[duct=~[/autocons] type=~ %build live=%.y autocons] - :: - ^= moves - :~ :* duct=~[/autocons] %give %made ~1234.5.7 %complete %success - [%success [%ride ride-type %constant]] - [%success [%scry %noun scry-type %it-does-in-fact-matter]] - == - :* duct=~[/autocons] %pass wire=/clay-sub/~nul/home/~1234.5.7 - %c %warp ~nul %home - `[%mult [%da ~1234.5.7] (sy [%x /foo/bar] ~)] - == == == - :: - =^ results3 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.8 - scry=scry-is-forbidden - :: - call-args=[duct=~[/static] type=~ %kill ~] - :: - moves=~ - == - :: - =^ results4 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.9 - scry=scry-is-forbidden - :: - call-args=[duct=~[/autocons] type=~ %kill ~] - :: - ^= moves - :~ :* duct=~[/autocons] %pass wire=/clay-sub/~nul/home/~1234.5.7 - %c %warp ~nul %home ~ - == == == - :: - ;: weld - results1 - results2 - results3 - results4 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-call ^- tang - :: - =/ sample-schematic=schematic:ford-gate [%$ %noun !>(5)] - =/ gate-schematic=schematic:ford-gate [%$ %noun !>(|=(a=@ud +(a)))] - =/ call-schematic=schematic:ford-gate - [%call gate-schematic sample-schematic] - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=scry-is-forbidden - :: - call-args=[duct=~[/call] type=~ %build live=%.y call-schematic] - :: - ^= comparator - |= moves=(list move:ford-gate) - ^- tang - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete %success %call *] i.moves) - :: - =/ result=vase |7:i.moves - :: - (expect-eq !>(6) result) - == - :: - =^ results2 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.7 - scry=scry-is-forbidden - :: - call-args=[duct=~[/call] type=~ %kill ~] - :: - moves=~ - == - :: - ;: weld - results1 - results2 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-call-scry-succeed ^- tang - :: - =/ scry-42 (scry-succeed ~1234.5.6 [%noun !>(42)]) - :: - =/ sample-schematic=schematic:ford-gate [%$ %noun !>(24)] - =/ gate-schematic=schematic:ford-gate - [%$ %noun !>(|=(a=@ud .^(@ud %cx /~nul/desk/~1234.5.6/foo/bar)))] - =/ call-schematic=schematic:ford-gate - [%call gate-schematic sample-schematic] - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=scry-42 - :: - call-args=[duct=~[/call] type=~ %build live=%.y call-schematic] - :: - ^= comparator - |= moves=(list move:ford-gate) - ^- tang - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - :: - ?> ?=([* %give %made @da %complete %success %call *] i.moves) - :: - =/ result=vase |7:i.moves - :: - (expect-eq !>(42) result) - == - :: - =^ results2 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.7 - scry=scry-is-forbidden - :: - call-args=[duct=~[/call] type=~ %kill ~] - :: - moves=~ - == - :: - ;: weld - results1 - results2 - (expect-ford-empty ford-gate ~nul) - == -++ test-call-scry-fail ^- tang - :: - =/ scry-failed (scry-fail ~1234.5.6) - :: - =/ sample-schematic=schematic:ford-gate [%$ %noun !>(24)] - =/ gate-schematic=schematic:ford-gate - [%$ %noun !>(|=(a=@ud .^(@ud %cx /~nul/desk/~1234.5.6/foo/bar)))] - =/ call-schematic=schematic:ford-gate - [%call gate-schematic sample-schematic] - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=scry-failed - :: - call-args=[duct=~[/dead] type=~ %build live=%.y call-schematic] - :: - ^= comparator - |= moves=(list move:ford-gate) - ^- tang - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete %error *] i.moves) - :: compare the move to the expected move, omitting check on stack trace - :: - %+ expect-eq - !> :* duct=~[/dead] %give %made ~1234.5.6 %complete - [%error [leaf+"ford: %call execution failed:" ~]] - == - !> i.moves(|7 ~) - == - :: - =^ results2 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.7 - scry=scry-is-forbidden - :: - call-args=[duct=~[/dead] type=~ %kill ~] - :: - moves=~ - == - :: - ;: weld - results1 - results2 - (expect-ford-empty ford-gate ~nul) - == -:: -:: -++ test-call-scry-block ^- tang - :: - =/ scry-blocked (scry-block ~1234.5.6) - :: - =/ sample-schematic=schematic:ford-gate [%$ %noun !>(24)] - =/ gate-schematic=schematic:ford-gate - [%$ %noun !>(|=(a=@ud .^(@ud %cx /~nul/desk/~1234.5.6/foo/bar)))] - =/ call-schematic=schematic:ford-gate - [%call gate-schematic sample-schematic] - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=scry-blocked - :: - call-args=[duct=~[/live] type=~ %build live=%.y call-schematic] - :: - ^= moves - :~ :* duct=~[/live] %pass - wire=/scry-request/cx/~nul/desk/~1234.5.6/foo/bar - %c %warp ~nul %desk - ~ %sing %x [%da ~1234.5.6] /foo/bar - == == == - :: - =^ results2 ford-gate - %- ford-take-with-comparator :* - ford-gate - now=~1234.5.7 - scry=scry-blocked - :: - ^= call-args - :* wire=/scry-request/cx/~nul/desk/~1234.5.6/foo/bar duct=~ - ^= wrapped-sign ^- (hypo sign:ford-gate) :- *type - [%c %writ ~ [%x [%da ~1234.5.6] %desk] /bar/foo %noun !>(42)] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - ^- tang - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete %success %call *] i.moves) - :: - =/ result |7:i.moves - :: - (expect-eq !>(42) result) - == - :: - =^ results3 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.8 - scry=scry-is-forbidden - :: - call-args=[duct=~[/live] type=~ %kill ~] - moves=~ - == - :: - ;: weld - results1 - results2 - results3 - (expect-ford-empty ford-gate ~nul) - == -:: +test-call-scry-varies: call with an argument which varies -:: -:: This test reads the sample for a %call schematic from clay. This sample -:: is a date. Inside of the gate called, we scry on a path based on the -:: passed in sample date. -:: -++ test-call-scry-varies ^- tang - :: - =/ date-type=type [%atom %da ~] - =/ term-type=type [%atom %tas ~] - :: - =/ scry-results=(map [term beam] cage) - %- my :~ - :- [%cx [[~nul %desk %da ~1234.5.6] /timer]] - [%noun date-type ~1234.5.6] - :: - :- [%cx [[~nul %desk %da ~1234.5.6] /result]] - [%noun term-type %first] - :: - :- [%cx [[~nul %desk %da ~1234.5.7] /timer]] - [%noun date-type ~1234.5.7] - :: - :- [%cx [[~nul %desk %da ~1234.5.7] /result]] - [%noun term-type %second] - == - :: - =/ scry (scry-with-results scry-results) - :: - =/ sample-schematic=schematic:ford-gate - [%scry [%c care=%x bel=[[~nul %desk] /timer]]] - =/ gate-schematic=schematic:ford-gate - [%$ %noun !>(|=(a=@da .^(@tas %cx /~nul/desk/(scot %da a)/result)))] - =/ call-schematic=schematic:ford-gate - [%call gate-schematic sample-schematic] - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=scry - :: - ^= call-args - [duct=~[/call] type=~ %build live=%.y call-schematic] - :: - ^= comparator - |= moves=(list move:ford-gate) - ^- tang - :: - ?> =(2 (lent moves)) - ?> ?=([^ ^ ~] moves) - ?> ?=([* %give %made @da %complete %success %call *] i.moves) - :: - %+ weld - =/ result |7:i.moves - (expect-eq !>(%first) result) - :: make sure the other move is a subscription - :: - %+ expect-eq - !> :* duct=~[/call] %pass wire=/clay-sub/~nul/desk/~1234.5.6 - %c %warp ~nul %desk - `[%mult [%da ~1234.5.6] (sy [%x /timer] ~)] - == - !> i.t.moves - == - :: - =^ results2 ford-gate - %- ford-take-with-comparator :* - ford-gate - now=~1234.5.7 - scry=scry - :: - ^= call-args - :* wire=/clay-sub/~nul/desk/~1234.5.6 duct=~[/call] - ^= wrapped-sign ^- (hypo sign:ford-gate) :- *type - [%c %wris [%da ~1234.5.7] (sy [%x /timer]~)] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - ^- tang - :: - ?> =(2 (lent moves)) - ?> ?=([^ ^ ~] moves) - ?> ?=([* %give %made @da %complete %success %call *] i.moves) - :: - %+ weld - =/ result |7:i.moves - (expect-eq !>(%second) result) - :: make sure the other move is a subscription - :: - %+ expect-eq - !> :* duct=~[/call] %pass wire=/clay-sub/~nul/desk/~1234.5.7 - %c %warp ~nul %desk - `[%mult [%da ~1234.5.7] (sy [%x /timer] ~)] - == - !> i.t.moves - == - :: - =^ results3 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.8 - scry=scry-is-forbidden - :: - call-args=[duct=~[/call] type=~ %kill ~] - :: - ^= moves - :~ :* duct=~[/call] %pass wire=/clay-sub/~nul/desk/~1234.5.7 - %c %warp ~nul %desk ~ - == == == - :: - ;: weld - results1 - results2 - results3 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-dude ^- tang - :: - =/ schematic=schematic:ford-gate - :* %dude >%test-no-error< - [%scry [%c care=%x bel=[[~nul %desk] /bar/foo]]] - == - :: - =/ scry-42 (scry-succeed ~1234.5.6 [%noun !>(42)]) - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=scry-42 - :: - call-args=[duct=~[/once] type=~ %build live=%.n schematic] - :: - ^= moves - :~ :* duct=~[/once] %give %made ~1234.5.6 %complete %success - [%scry %noun !>(42)] - == == == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-dude-error ^- tang - :: - =/ schematic=schematic:ford-gate - :* %dude >%in-the-error-message< - [%scry [%c care=%x bel=[[~nul %desk] /bar/foo]]] - == - :: - =/ scry-42 (scry-fail ~1234.5.6) - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=scry-42 - :: - call-args=[duct=~[/once] type=~ %build live=%.n schematic] - :: - ^= moves - :~ :* duct=~[/once] %give %made ~1234.5.6 %complete - %error - :~ leaf+"%in-the-error-message" - leaf+"scry failed for" - leaf+"%cx /~nul/desk/~1234.5.6/foo/bar" - == == == == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-hood ^- tang - :: - =/ scry-type=type [%atom %tas ~] - =/ scry - %- scry-with-results - ^- (map [term beam] cage) - %- my :~ - :- [%cx [[~nul %desk %da ~1234.5.6] /hoon/bar/foo]] - :* %noun scry-type - '!. |=(a=@ud +(a))' - == - == - :: - =/ schematic=schematic:ford-gate [%hood [[~nul %desk] /hoon/bar/foo]] - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=scry - :: - call-args=[duct=~[/hood] type=~ %build live=%.y schematic] - :: - ^= moves - :~ :* duct=~[/hood] %give %made ~1234.5.6 - %complete %success %hood - :* source-rail=[[~nul %desk] /hoon/bar/foo] - zuse-version=309 - structures=~ - libraries=~ - cranes=~ - ^= sources - :~ :* %dbug - [/~nul/desk/0/foo/bar/hoon [1 1] [1 19]] - (ream '|=(a=@ud +(a))') - == == == == - :* duct=~[/hood] %pass /clay-sub/~nul/desk/~1234.5.6 - %c %warp ~nul %desk - `[%mult [%da ~1234.5.6] (sy [%x /foo/bar/hoon] ~)] - == == == - :: - =^ results2 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.8 - scry=scry-is-forbidden - :: - call-args=[duct=~[/hood] type=~ %kill ~] - :: - ^= moves - :~ :* duct=~[/hood] %pass wire=/clay-sub/~nul/desk/~1234.5.6 - %c %warp ~nul %desk ~ - == == == - :: - ;: weld - results1 - results2 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-slim ^- tang - :: - =/ formula=hoon (ream '(add 2 2)') - =/ subject-type=type -:!>(.) - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=scry-is-forbidden - :: - ^= call-args - [duct=~[/dead] type=~ %build live=%.y [%slim subject-type formula]] - :: - ^= moves - :~ :* duct=~[/dead] %give %made ~1234.5.6 %complete - [%success [%slim (~(mint ut subject-type) [%noun formula])]] - == == == - :: - =^ results2 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.7 - scry=scry-is-forbidden - :: - call-args=[duct=~[/dead] type=~ %kill ~] - :: - moves=~ - == - :: - ;: weld - results1 - results2 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-slit ^- tang - :: - =/ gate=vase (ride %noun '|=(a=@ud ["one" a])') - =/ sample=vase !>(42) - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=scry-is-forbidden - :: - call-args=[duct=~[/slit] type=~ %build live=%.y [%slit gate sample]] - :: - ^= comparator - |= moves=(list move:ford-gate) - ^- tang - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete %success %slit *] i.moves) - :: we are expecting a type, and all we can do is ensure it nests in - :: the right type - :: - =/ expected-type=type -:!>([*tape *@ud]) - =/ actual-type=type |7:i.moves - %+ expect-eq - !> & - !> (~(nest ut actual-type) | expected-type) - == - :: - =^ results2 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.7 - scry=scry-is-forbidden - :: - call-args=[duct=~[/slit] type=~ %kill ~] - :: - moves=~ - == - :: - ;: weld - results1 - results2 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-slit-error ^- tang - :: - =/ gate=vase (ride %noun '|=(a=@ud ["one" a])') - =/ sample=vase !>("a tape instead of @ud") - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=scry-is-forbidden - :: - call-args=[duct=~[/slit] type=~ %build live=%.y [%slit gate sample]] - :: - ^= comparator - |= moves=(list move:ford-gate) - ^- tang - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete %error *] i.moves) - :: ignore last message; contains source positions in the stack trace - :: - =/ messages=tang (scag 4 `tang`|6:i.moves) - :: - %+ expect-eq - !> :~ [%palm ["." "-" "" ""] [%leaf "have"] [%leaf "\"\""] ~] - :~ %palm ["." "-" "" ""] - [%leaf "want"] - [%palm ["/" "" "" ""] [%leaf "a"] [%leaf "@ud"] ~] - == - [%leaf "ford: %slit failed:"] - [%leaf "nest-fail"] - == - !> messages - == - :: - =^ results2 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.7 - scry=scry-is-forbidden - :: - call-args=[duct=~[/slit] type=~ %kill ~] - :: - moves=~ - == - :: - ;: weld - results1 - results2 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-ride ^- tang - :: - =/ fun |=(a=@ (add 2 a)) - =/ formula=hoon (ream '!: (fun 3)') - =/ subject-schematic=schematic:ford-gate [%$ %noun !>(.)] - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=scry-is-forbidden - :: - ^= call-args - :* duct=~[/dead] type=~ %build live=%.y - [%ride formula subject-schematic] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - ^- tang - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete %success %ride *] i.moves) - :: - =/ result |7:i.moves - (expect-eq !>(5) result) - == - :: - =^ results2 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.7 - scry=scry-is-forbidden - :: - call-args=[duct=~[/dead] type=~ %kill ~] - moves=~ - == - :: - ;: weld - results1 - results2 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-ride-scry-succeed ^- tang - :: - =/ scry-42 (scry-succeed ~1234.5.6 [%noun !>(42)]) - :: - =/ formula=hoon (ream '!: .^(* %cx /~nul/desk/~1234.5.6/foo/bar)') - =/ subject-schematic=schematic:ford-gate [%$ %noun !>(.)] - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=scry-42 - :: - ^= call-args - :* duct=~[/dead] type=~ %build live=%.y - [%ride formula subject-schematic] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - ^- tang - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete %success %ride *] i.moves) - :: - =/ result |7:i.moves - (expect-eq !>(42) result) - == - :: - =^ results2 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.7 - scry=scry-is-forbidden - :: - call-args=[duct=~[/dead] type=~ %kill ~] - moves=~ - == - :: - ;: weld - results1 - results2 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-ride-scry-fail ^- tang - :: - =/ scry-failed (scry-fail ~1234.5.6) - :: - =/ formula=hoon (ream '!: .^(* %cx /~nul/desk/~1234.5.6/foo/bar)') - =/ subject-schematic=schematic:ford-gate [%$ %noun !>(.)] - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=scry-failed - :: - ^= call-args - :* duct=~[/dead] type=~ %build live=%.y - [%ride formula subject-schematic] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - ^- tang - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete %error *] i.moves) - :: compare the move to the expected move, omitting check on stack trace - :: - %+ expect-eq - !> :* duct=~[/dead] %give %made ~1234.5.6 %complete - [%error [leaf+"ford: %ride failed to execute:" ~]] - == - !> i.moves(|7 ~) - == - :: - =^ results2 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.7 - scry=scry-is-forbidden - :: - call-args=[duct=~[/dead] type=~ %kill ~] - moves=~ - == - :: - ;: weld - results1 - results2 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-ride-scry-block ^- tang - :: - =/ scry-blocked (scry-block ~1234.5.6) - :: - =/ formula=hoon (ream '!: .^(* %cx /~nul/desk/~1234.5.6/foo/bar)') - =/ subject-schematic=schematic:ford-gate [%$ %noun !>(.)] - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=scry-blocked - :: - ^= call-args - :* duct=~[/live] type=~ %build live=%.y - [%ride formula subject-schematic] - == - :: - ^= moves - :~ :* duct=~[/live] %pass - wire=/scry-request/cx/~nul/desk/~1234.5.6/foo/bar - %c %warp ~nul %desk - ~ %sing %x [%da ~1234.5.6] /foo/bar - == == == - :: - =^ results2 ford-gate - %- ford-take-with-comparator :* - ford-gate - now=~1234.5.7 - :: TODO: using +scry-is-forbidden causes a bail: 4 - :: - scry=scry-blocked - :: - ^= take-args - :* wire=/scry-request/cx/~nul/desk/~1234.5.6/foo/bar duct=~[/live] - ^= wrapped-sign ^- (hypo sign:ford-gate) :- *type - [%c %writ ~ [%x [%da ~1234.5.6] %desk] /bar/foo %noun !>(42)] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - ^- tang - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete %success %ride *] i.moves) - :: - =/ result |7:i.moves - (expect-eq !>(42) result) - == - :: - =^ results3 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.8 - scry=scry-is-forbidden - :: - call-args=[duct=~[/live] type=~ %kill ~] - moves=~ - == - :: - ;: weld - results1 - results2 - results3 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-ride-scry-promote ^- tang - :: - =/ scry-type=type [%atom %tas ~] - :: - =/ scry-results=(map [term beam] cage) - %- my :~ - :- [%cx [[~nul %desk %da ~1234.5.6] /bar/foo]] - [%noun scry-type %it-doesnt-matter] - :: - :- [%cx [[~nul %desk %da ~1234.5.7] /bar/foo]] - [%noun scry-type %changed] - == - :: - =/ scry (scry-with-results scry-results) - :: - =/ formula=hoon (ream '`@tas`%constant') - =/ subject-schematic=schematic:ford-gate [%scry %c %x [~nul %desk] /bar/foo] - :: - =/ ride=schematic:ford-gate [%ride formula subject-schematic] - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=scry - :: - call-args=[duct=~[/ride] type=~ %build live=%.y ride] - :: - ^= moves - :~ :* duct=~[/ride] %give %made ~1234.5.6 %complete - [%success [%ride scry-type %constant]] - == - :* duct=~[/ride] %pass wire=/clay-sub/~nul/desk/~1234.5.6 - %c %warp ~nul %desk - `[%mult [%da ~1234.5.6] (sy [%x /foo/bar] ~)] - == == == - :: - =^ results2 ford-gate - %- ford-take :* - ford-gate - now=~1234.5.7 - scry=scry - :: - ^= take-args - :* wire=/clay-sub/~nul/desk/~1234.5.6 duct=~[/ride] - ^= wrapped-sign ^- (hypo sign:ford-gate) :- *type - [%c %wris [%da ~1234.5.7] (sy [%x /foo/bar]~)] - == - :: - ^= moves - :~ :* duct=~[/ride] %pass wire=/clay-sub/~nul/desk/~1234.5.7 - %c %warp ~nul %desk - `[%mult [%da ~1234.5.7] (sy [%x /foo/bar] ~)] - == == == - :: - =^ results3 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.8 - scry=scry-is-forbidden - :: - call-args=[duct=~[/ride] type=~ %kill ~] - :: - ^= moves - :~ :* duct=~[/ride] %pass wire=/clay-sub/~nul/desk/~1234.5.7 - %c %warp ~nul %desk ~ - == == == - :: - ;: weld - results1 - results2 - results3 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-five-oh-fora ^- tang - :: - =/ scry-type=type - [%cell [%face %title [%atom %t ~]] [%face %contents -:!>("")]] - :: - =/ scry-results=(map [term beam] cage) - %- my :~ - :- [%cx [[~nul %desk %da ~1234.5.6] /a/posts]] - [%noun scry-type [title='post-a' contents="post-a-contents"]] - :: - :- [%cx [[~nul %desk %da ~1234.5.6] /b/posts]] - [%noun scry-type [title='post-b' contents="post-b-contents"]] - :: - :- [%cx [[~nul %desk %da ~1234.5.7] /a/posts]] - [%noun scry-type [title='post-a' contents="post-a-contents"]] - :: - :- [%cx [[~nul %desk %da ~1234.5.7] /b/posts]] - [%noun scry-type [title='post-b' contents="post-b-contents"]] - :: - :- [%cx [[~nul %desk %da ~1234.5.8] /a/posts]] - [%noun scry-type [title='post-a' contents="post-a-contents-changed"]] - == - :: - =/ scry (scry-with-results scry-results) - :: - =/ post-a=schematic:ford-gate [%scry [%c %x [~nul %desk] /a/posts]] - =/ title-a=schematic:ford-gate [%ride (ream '!: title') post-a] - :: - =/ post-b=schematic:ford-gate [%scry [%c %x [~nul %desk] /b/posts]] - =/ title-b=schematic:ford-gate [%ride (ream '!: title') post-b] - :: - =/ sidebar=schematic:ford-gate [title-a title-b] - :: - =/ rendered-a=schematic:ford-gate [post-a sidebar] - =/ rendered-b=schematic:ford-gate [post-b sidebar] - :: first, ask ford to build rendered-a - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=scry - :: - call-args=[duct=~[/post-a] type=~ %build live=%.y rendered-a] - :: - ^= comparator - |= moves=(list move:ford-gate) - ^- tang - :: - ?> ?=([^ ^ ~] moves) - %+ welp - %- verify-post-made :* - move=i.moves - duct=~[/post-a] - type=scry-type - date=~1234.5.6 - title='post-a' - contents="post-a-contents" - == - %+ expect-eq - !> :* duct=~[/post-a] %pass - wire=/clay-sub/~nul/desk/~1234.5.6 %c %warp - ~nul %desk - `[%mult [%da ~1234.5.6] (sy [%x /posts/a] [%x /posts/b] ~)] - == - !> i.t.moves - == - :: - =^ results2 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.7 - scry=scry - :: - call-args=[duct=~[/post-b] type=~ %build live=%.y rendered-b] - :: - ^= comparator - |= moves=(list move:ford-gate) - ^- tang - :: - ?> ?=([^ ^ ~] moves) - %+ welp - %- verify-post-made :* - move=i.moves - duct=~[/post-b] - type=scry-type - date=~1234.5.7 - title='post-b' - contents="post-b-contents" - == - %+ expect-eq - !> :* duct=~[/post-b] %pass - wire=/clay-sub/~nul/desk/~1234.5.7 %c %warp - ~nul %desk - `[%mult [%da ~1234.5.7] (sy [%x /posts/a] [%x /posts/b] ~)] - == - !> i.t.moves - == - :: - =^ results3 ford-gate - %- ford-take-with-comparator :* - ford-gate - now=~1234.5.8 - scry=scry - :: - ^= take-args - :* wire=/clay-sub/~nul/desk/~1234.5.6 duct=~[/post-a] - ^= wrapped-sign ^- (hypo sign:ford-gate) :- *type - [%c %wris [%da ~1234.5.8] (sy [%x /posts/a]~)] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - ^- tang - :: - ?> ?=([^ ^ ~] moves) - %+ welp - %- verify-post-made :* - move=i.moves - duct=~[/post-a] - type=scry-type - date=~1234.5.8 - title='post-a' - contents="post-a-contents-changed" - == - %+ expect-eq - !> :* duct=~[/post-a] %pass - wire=/clay-sub/~nul/desk/~1234.5.8 - %c %warp ~nul %desk - `[%mult [%da ~1234.5.8] (sy [%x /posts/a] [%x /posts/b] ~)] - == - !> i.t.moves - == - :: - =^ results4 ford-gate - %- ford-take :* - ford-gate - now=~1234.5.9 - scry=scry - :: - ^= take-args - :* wire=/clay-sub/~nul/desk/~1234.5.7 duct=~[/post-b] - ^= wrapped-sign ^- (hypo sign:ford-gate) :- *type - [%c %wris [%da ~1234.5.8] (sy [%x /posts/a]~)] - == - :: - moves=~ - == - :: - =^ results5 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.10 - scry=scry-is-forbidden - :: - call-args=[duct=~[/post-a] type=~ %kill ~] - :: - moves=~ - == - :: - =^ results6 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.11 - scry=scry-is-forbidden - :: - call-args=[duct=~[/post-b] type=~ %kill ~] - :: - ^= moves - :~ :* duct=~[/post-a] %pass wire=/clay-sub/~nul/desk/~1234.5.8 - %c %warp ~nul %desk ~ - == == == - :: - ;: weld - results1 - results2 - results3 - results4 - results5 - results6 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-alts ^- tang - :: - =/ scry-type=type [%atom %tas ~] - :: - =/ scry-results=(map [term beam] (unit cage)) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /one/scry]] - ~ - :: - :- [%cx [[~nul %home %da ~1234.5.6] /two/scry]] - ~ - :: - :- [%cx [[~nul %home %da ~1234.5.7] /one/scry]] - ~ - :: - :- [%cx [[~nul %home %da ~1234.5.7] /two/scry]] - `[%noun scry-type 'scry-two'] - :: - :- [%cx [[~nul %home %da ~1234.5.8] /one/scry]] - `[%noun scry-type 'scry-one'] - == - :: - =/ scry (scry-with-results-and-failures scry-results) - :: - =/ scry1=schematic:ford-gate [%scry [%c %x [~nul %home] /one/scry]] - =/ scry2=schematic:ford-gate [%scry [%c %x [~nul %home] /two/scry]] - =/ alts=schematic:ford-gate [%alts [scry1 scry2 ~]] - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=scry - :: - call-args=[duct=~[/alts] type=~ %build live=%.y alts] - :: - ^= moves - :~ :* duct=~[/alts] %give %made ~1234.5.6 %complete %error - :~ [%leaf "%alts: all options failed"] - [%leaf "option"] - :+ %rose [" " "\{" "}"] :~ - [%leaf "scry failed for"] - [%leaf "%cx /~nul/home/~1234.5.6/scry/one"] - == - [%leaf "option"] - :+ %rose [" " "\{" "}"] :~ - [%leaf "scry failed for"] - [%leaf "%cx /~nul/home/~1234.5.6/scry/two"] - == - == == - :* duct=~[/alts] %pass wire=/clay-sub/~nul/home/~1234.5.6 - %c %warp ~nul %home - `[%mult [%da ~1234.5.6] (sy [%x /scry/two] [%x /scry/one] ~)] - == == == - :: - =^ results2 ford-gate - %- ford-take :* - ford-gate - now=~1234.5.7 - scry=scry - :: - ^= take-args - :* wire=/clay-sub/~nul/home/~1234.5.6 duct=~[/alts] - ^= wrapped-sign ^- (hypo sign:ford-gate) :- *type - [%c %wris [%da ~1234.5.7] (sy [%x /scry/two]~)] - == - :: - ^= moves - :~ :* duct=~[/alts] %give %made ~1234.5.7 %complete - %success %alts %success %scry %noun scry-type 'scry-two' - == - :* duct=~[/alts] %pass wire=/clay-sub/~nul/home/~1234.5.7 - %c %warp ~nul %home - `[%mult [%da ~1234.5.7] (sy [%x /scry/two] [%x /scry/one] ~)] - == == == - :: - =^ results3 ford-gate - %- ford-take :* - ford-gate - now=~1234.5.8 - scry=scry - :: - ^= take-args - :* wire=/clay-sub/~nul/home/~1234.5.6 duct=~[/alts] - ^= wrapped-sign ^- (hypo sign:ford-gate) :- *type - [%c %wris [%da ~1234.5.8] (sy [%x /scry/one]~)] - == - :: - ^= moves - :~ :* duct=~[/alts] %give %made ~1234.5.8 %complete - %success %alts %success %scry %noun scry-type 'scry-one' - == - :* duct=~[/alts] %pass wire=/clay-sub/~nul/home/~1234.5.8 - %c %warp ~nul %home - `[%mult [%da ~1234.5.8] (sy [%x /scry/one] ~)] - == == == - :: - =^ results4 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.9 - scry=scry-is-forbidden - :: - call-args=[duct=~[/alts] type=~ %kill ~] - :: - ^= moves - :~ :* duct=~[/alts] %pass wire=/clay-sub/~nul/home/~1234.5.8 - %c %warp ~nul %home ~ - == == == - :: - ;: weld - results1 - results2 - results3 - results4 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-alts-and-live ^- tang - :: - =/ scry-type=type [%atom %tas ~] - :: - =/ scry-results=(map [term beam] (unit cage)) - %- my :~ - :- [%cx [[~nul %desk %da ~1234.5.6] /one/scry]] - ~ - :: - :- [%cx [[~nul %desk %da ~1234.5.6] /two/scry]] - `[%noun scry-type 'scry-two'] - :: - :- [%cx [[~nul %desk %da ~1234.5.7] /one/scry]] - ~ - :: - :- [%cx [[~nul %desk %da ~1234.5.7] /two/scry]] - `[%noun scry-type 'scry-two'] - :: - :- [%cx [[~nul %desk %da ~1234.5.8] /one/scry]] - `[%noun scry-type 'scry-one'] - == - :: - =/ scry (scry-with-results-and-failures scry-results) - :: - =/ scry2=schematic:ford-gate [%scry [%c %x [~nul %desk] /two/scry]] - =/ same=schematic:ford-gate [%same scry2] - :: depend on scry2 for the duration of the test - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=scry - :: - call-args=[duct=~[/same] type=~ %build live=%.y same] - :: - ^= moves - :~ :* duct=~[/same] %give %made ~1234.5.6 %complete - %success %scry %noun scry-type 'scry-two' - == - :* duct=~[/same] %pass wire=/clay-sub/~nul/desk/~1234.5.6 - %c %warp ~nul %desk - `[%mult [%da ~1234.5.6] (sy [%x /scry/two] ~)] - == == == - :: - =/ scry1=schematic:ford-gate [%scry [%c %x [~nul %desk] /one/scry]] - =/ alts=schematic:ford-gate [%alts [scry1 scry2 ~]] - :: call the alts schematic - :: - :: The alts schematic should fail to read /scry/one, and should fallback - :: to /scry/two. - :: - =^ results2 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.7 - scry=scry - :: - call-args=[duct=~[/alts] type=~ %build live=%.y alts] - :: - ^= moves - :~ :* duct=~[/alts] %give %made ~1234.5.7 %complete - %success %alts %success %scry %noun scry-type 'scry-two' - == - :* duct=~[/alts] %pass wire=/clay-sub/~nul/desk/~1234.5.7 - %c %warp ~nul %desk - `[%mult [%da ~1234.5.7] (sy [%x /scry/two] [%x /scry/one] ~)] - == == == - :: - :: tell ford that /scry/one exists now - :: - =^ results3 ford-gate - %- ford-take :* - ford-gate - now=~1234.5.8 - scry=scry - :: - ^= take-args - :* wire=/clay-sub/~nul/desk/~1234.5.7 duct=~[/alts] - ^= wrapped-sign ^- (hypo sign:ford-gate) :- *type - [%c %wris [%da ~1234.5.8] (sy [%x /scry/one]~)] - == - :: - ^= moves - :~ :* duct=~[/alts] %give %made ~1234.5.8 %complete - %success %alts %success %scry %noun scry-type 'scry-one' - == - :: we subscribe to both paths because /same still exists. - :: - :* duct=~[/alts] %pass wire=/clay-sub/~nul/desk/~1234.5.8 - %c %warp ~nul %desk - `[%mult [%da ~1234.5.8] (sy [%x /scry/one] ~)] - == == == - :: - :: kill the /same build - :: - :: We should no longer subscribe to /scry/two in the resulting clay - :: subscription. - :: - =^ results4 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.9 - scry=scry - :: - call-args=[duct=~[/same] type=~ %kill ~] - :: - ^= moves - :~ :* duct=~[/same] %pass wire=/clay-sub/~nul/desk/~1234.5.6 - %c %warp ~nul %desk ~ - == == == - :: - =^ results5 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.10 - scry=scry - :: - call-args=[duct=~[/alts] type=~ %kill ~] - :: - ^= moves - :~ :* duct=~[/alts] %pass wire=/clay-sub/~nul/desk/~1234.5.8 - %c %warp ~nul %desk ~ - == == == - :: - ;: weld - results1 - results2 - results3 - results4 - results5 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-double-alts ^- tang - :: - =/ scry-type=type [%atom %tas ~] - :: - =/ scry-results=(map [term beam] (unit cage)) - %- my :~ - :- [%cx [[~nul %desk %da ~1234.5.6] /one/scry]] - ~ - :- [%cx [[~nul %desk %da ~1234.5.6] /two/scry]] - `[%noun scry-type 'scry-two'] - :- [%cx [[~nul %desk %da ~1234.5.6] /three/scry]] - ~ - :: - :- [%cx [[~nul %desk %da ~1234.5.7] /one/scry]] - ~ - :- [%cx [[~nul %desk %da ~1234.5.7] /two/scry]] - `[%noun scry-type 'scry-two'] - :- [%cx [[~nul %desk %da ~1234.5.7] /three/scry]] - ~ - :: - :- [%cx [[~nul %desk %da ~1234.5.8] /one/scry]] - ~ - :- [%cx [[~nul %desk %da ~1234.5.8] /two/scry]] - `[%noun scry-type 'scry-two'] - :- [%cx [[~nul %desk %da ~1234.5.8] /three/scry]] - `[%noun scry-type 'scry-three'] - :: - :- [%cx [[~nul %desk %da ~1234.5.9] /one/scry]] - `[%noun scry-type 'scry-one'] - :- [%cx [[~nul %desk %da ~1234.5.9] /two/scry]] - `[%noun scry-type 'scry-two-changed'] - :- [%cx [[~nul %desk %da ~1234.5.9] /three/scry]] - `[%noun scry-type 'scry-three'] - == - :: - =/ scry (scry-with-results-and-failures scry-results) - :: - =/ scry1=schematic:ford-gate [%scry [%c %x [~nul %desk] /one/scry]] - =/ scry2=schematic:ford-gate [%scry [%c %x [~nul %desk] /two/scry]] - =/ scry3=schematic:ford-gate [%scry [%c %x [~nul %desk] /three/scry]] - =/ alts1=schematic:ford-gate [%alts [scry1 scry2 ~]] - =/ alts2=schematic:ford-gate [%alts [scry3 scry2 ~]] - :: alts1 will depend on both scry1 and scry2 - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=scry - :: - call-args=[duct=~[/first] type=~ %build live=%.y alts1] - :: - ^= moves - :~ :* duct=~[/first] %give %made ~1234.5.6 %complete - %success %alts %success %scry %noun scry-type 'scry-two' - == - :* duct=~[/first] %pass wire=/clay-sub/~nul/desk/~1234.5.6 - %c %warp ~nul %desk - `[%mult [%da ~1234.5.6] (sy [%x /scry/one] [%x /scry/two] ~)] - == == == - :: alts2 will depend on both scry3 and scry2 - :: - =^ results2 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.7 - scry=scry - :: - call-args=[duct=~[/second] type=~ %build live=%.y alts2] - :: - ^= moves - :~ :* duct=~[/second] %give %made ~1234.5.7 %complete - %success %alts %success %scry %noun scry-type 'scry-two' - == - :* duct=~[/second] %pass wire=/clay-sub/~nul/desk/~1234.5.7 - %c %warp ~nul %desk ~ %mult [%da ~1234.5.7] - (sy [%x /scry/two] [%x /scry/three] ~) - == == == - :: - :: alts2 should now just return 'scry-three' - :: - =^ results3 ford-gate - %- ford-take :* - ford-gate - now=~1234.5.8 - scry=scry - :: - ^= take-args - :* wire=/clay-sub/~nul/desk/~1234.5.7 duct=~[/second] - ^= wrapped-sign ^- (hypo sign:ford-gate) :- *type - [%c %wris [%da ~1234.5.8] (sy [%x /scry/three]~)] - == - :: - ^= moves - :~ :* duct=~[/second] %give %made ~1234.5.8 %complete - %success %alts %success %scry %noun scry-type 'scry-three' - == - :* duct=~[/second] %pass wire=/clay-sub/~nul/desk/~1234.5.8 - %c %warp ~nul %desk ~ %mult [%da ~1234.5.8] - (sy [%x /scry/three] ~) - == == == - :: - =^ results4 ford-gate - %- ford-take :* - ford-gate - now=~1234.5.9 - scry=scry - :: - ^= take-args - :* wire=/clay-sub/~nul/desk/~1234.5.6 duct=~[/first] - ^= wrapped-sign ^- (hypo sign:ford-gate) :- *type - [%c %wris [%da ~1234.5.9] (sy [%x /scry/one] [%x /scry/two] ~)] - == - :: - ^= moves - :~ :* duct=~[/first] %give %made ~1234.5.9 %complete - %success %alts %success %scry %noun scry-type 'scry-one' - == - :* duct=~[/first] %pass wire=/clay-sub/~nul/desk/~1234.5.9 - %c %warp ~nul %desk ~ %mult [%da ~1234.5.9] - (sy [%x /scry/one] ~) - == == == - :: - =^ results5 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.10 - scry=scry - :: - call-args=[duct=~[/first] type=~ %kill ~] - :: - ^= moves - :~ :* duct=~[/first] %pass wire=/clay-sub/~nul/desk/~1234.5.9 - %c %warp ~nul %desk ~ - == == == - :: - =^ results6 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.11 - scry=scry - :: - call-args=[duct=~[/second] type=~ %kill ~] - :: - ^= moves - :~ :* duct=~[/second] %pass wire=/clay-sub/~nul/desk/~1234.5.8 - %c %warp ~nul %desk ~ - == == == - :: - ;: weld - results1 - results2 - results3 - results4 - results5 - results6 - (expect-ford-empty ford-gate ~nul) - == -:: +test-cache-reclamation-trivial: reclaim cache on a blank slate ford -:: -++ disabled-test-cache-reclamation-trivial - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=scry-is-forbidden - :: send a pinned literal, expects a %made response with pinned literal - :: - ^= call-args - [duct=~[/trivial] type=~ %build live=%.n [%$ %noun !>(**)]] - :: - ^= moves - :~ :* duct=~[/trivial] %give %made ~1234.5.6 - %complete %success %$ %noun !>(**) - == == - == - :: - =^ results2 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.7 - scry=scry-is-forbidden - :: ask ford to wipe its cache - :: - call-args=[duct=~[/trivial] type=~ %wipe 10] - :: cache wiping should never produce any moves - :: - moves=~ - == - :: - ;: welp - results1 - results2 - (expect-ford-empty ford-gate ~nul) - == -:: -++ disabled-test-cache-reclamation-live-rebuild - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=(scry-succeed ~1234.5.6 [%noun !>(42)]) - :: - ^= call-args - :* duct=~[/build] type=~ %build live=%.y - [%scry %c care=%x rail=[[~nul %desk] /bar/foo]] - == - :: - ^= moves - :~ :* duct=~[/build] %give %made ~1234.5.6 %complete %success - [%scry %noun !>(42)] - == - :* duct=~[/build] %pass wire=/clay-sub/~nul/desk - %c %warp ~nul %desk - `[%mult [%da ~1234.5.6] (sy [%x /foo/bar]~)] - == == == - :: - =^ results2 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.7 - scry=scry-is-forbidden - :: ask ford to wipe its cache - :: - call-args=[duct=~[/build] type=~ %wipe 10] - :: cache wiping should never produce any moves - :: - moves=~ - == - :: - =^ results3 ford-gate - %- ford-take :* - ford-gate - now=~1234.5.7 - scry=(scry-succeed ~1234.5.7 [%noun !>(43)]) - :: - ^= take-args - :* wire=/clay-sub/~nul/desk duct=~[/build] - ^= wrapped-sign ^- (hypo sign:ford-gate) :- *type - [%c %wris [%da ~1234.5.7] (sy [%x /foo/bar]~)] - == - :: - ^= moves - :~ :* duct=~[/build] %give %made ~1234.5.7 %complete %success - [%scry %noun !>(43)] - == - :* duct=~[/build] %pass wire=/clay-sub/~nul/desk - %c %warp ~nul %desk - `[%mult [%da ~1234.5.7] (sy [%x /foo/bar]~)] - == == == - :: - =^ results4 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.8 - scry=scry-is-forbidden - :: - call-args=[duct=~[/build] type=~ %kill ~] - :: - ^= moves - :~ :* duct=~[/build] %pass wire=/clay-sub/~nul/desk - %c %warp ~nul %desk ~ - == == == - :: - ;: weld - results1 - results2 - results3 - results4 - (expect-ford-empty ford-gate ~nul) - == -:: -++ disabled-test-cache-reclamation-live-promote - :: - =/ scry-type=type [%atom %tas ~] - :: - =/ scry-results=(map [term beam] cage) - %- my :~ - :- [%cx [[~nul %desk %da ~1234.5.6] /bar/foo]] - [%noun scry-type %it-doesnt-matter] - :: - :- [%cx [[~nul %desk %da ~1234.5.7] /bar/foo]] - [%noun scry-type %changed] - == - :: - =/ scry (scry-with-results scry-results) - :: - =/ formula=hoon (ream '`@tas`%constant') - =/ subject-schematic=schematic:ford-gate - [%scry %c %x [~nul %desk] /bar/foo] - :: - =/ ride=schematic:ford-gate [%ride formula subject-schematic] - =/ same=schematic:ford-gate [%same ride] - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=scry - :: - call-args=[duct=~[/ride] type=~ %build live=%.y same] - :: - ^= moves - :~ :* duct=~[/ride] %give %made ~1234.5.6 %complete - [%success [%ride scry-type %constant]] - == - :* duct=~[/ride] %pass wire=/clay-sub/~nul/desk - %c %warp ~nul %desk - `[%mult [%da ~1234.5.6] (sy [%x /foo/bar] ~)] - == == == - :: - =^ results2 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.7 - scry=scry-is-forbidden - :: ask ford to wipe its cache - :: - call-args=[duct=~[/ride] type=~ %wipe 10] - :: cache wiping should never produce any moves - :: - moves=~ - == - :: - =^ results3 ford-gate - %- ford-take :* - ford-gate - now=~1234.5.7 - scry=scry - :: - ^= take-args - :* wire=/clay-sub/~nul/desk duct=~[/ride] - ^= wrapped-sign ^- (hypo sign:ford-gate) :- *type - [%c %wris [%da ~1234.5.7] (sy [%x /foo/bar]~)] - == - :: - ^= moves - :~ :* duct=~[/ride] %pass wire=/clay-sub/~nul/desk - %c %warp ~nul %desk - `[%mult [%da ~1234.5.7] (sy [%x /foo/bar] ~)] - == == == - :: - =^ results4 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.8 - scry=scry-is-forbidden - :: - call-args=[duct=~[/ride] type=~ %kill ~] - :: - ^= moves - :~ :* duct=~[/ride] %pass wire=/clay-sub/~nul/desk - %c %warp ~nul %desk ~ - == == == - :: - ;: weld - results1 - results2 - results3 - results4 - (expect-ford-empty ford-gate ~nul) - == -:: tests that doing a cache reclamation during the five-oh-fora rebuild works -:: -++ disabled-test-five-oh-cache-reclamation ^- tang - :: - =/ scry-type=type - [%cell [%face %title [%atom %t ~]] [%face %contents -:!>("")]] - :: - =/ scry-results=(map [term beam] cage) - %- my :~ - :- [%cx [[~nul %desk %da ~1234.5.6] /a/posts]] - [%noun scry-type [title='post-a' contents="post-a-contents"]] - :: - :- [%cx [[~nul %desk %da ~1234.5.6] /b/posts]] - [%noun scry-type [title='post-b' contents="post-b-contents"]] - :: - :- [%cx [[~nul %desk %da ~1234.5.9] /a/posts]] - [%noun scry-type [title='post-a' contents="post-a-contents-changed"]] - :: - :: unchanged, but might be requested if cache entry gets wiped - :: - :- [%cx [[~nul %desk %da ~1234.5.9] /b/posts]] - [%noun scry-type [title='post-b' contents="post-b-contents"]] - == - :: - =/ scry (scry-with-results scry-results) - :: - =/ post-a=schematic:ford-gate [%scry [%c %x [~nul %desk] /a/posts]] - =/ title-a=schematic:ford-gate [%ride (ream '!: title') post-a] - :: - =/ post-b=schematic:ford-gate [%scry [%c %x [~nul %desk] /b/posts]] - =/ title-b=schematic:ford-gate [%ride (ream '!: title') post-b] - :: - =/ sidebar=schematic:ford-gate [title-a title-b] - :: - =/ rendered-a=schematic:ford-gate [post-a sidebar] - =/ rendered-b=schematic:ford-gate [post-b sidebar] - :: first, ask ford to build rendered-a - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=scry - :: - call-args=[duct=~[/post-a] type=~ %build live=%.y rendered-a] - :: - ^= comparator - |= moves=(list move:ford-gate) - ^- tang - :: - ?> ?=([^ ^ ~] moves) - %+ welp - %- verify-post-made :* - move=i.moves - duct=~[/post-a] - type=scry-type - date=~1234.5.6 - title='post-a' - contents="post-a-contents" - == - %+ expect-eq - !> :* duct=~[/post-a] %pass wire=/clay-sub/~nul/desk - %c %warp ~nul %desk - `[%mult [%da ~1234.5.6] (sy [%x /posts/a] [%x /posts/b] ~)] - == - !> i.t.moves - == - :: - =^ results2 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.7 - scry=scry - :: - call-args=[duct=~[/post-b] type=~ %build live=%.y rendered-b] - :: - ^= comparator - |= moves=(list move:ford-gate) - ^- tang - :: - ?> ?=([^ ~] moves) - %- verify-post-made :* - move=i.moves - duct=~[/post-b] - type=scry-type - date=~1234.5.7 - title='post-b' - contents="post-b-contents" - == == - :: - =^ results3 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.8 - scry=scry-is-forbidden - :: - call-args=[duct=~[/wipe] type=~ %wipe 10] - moves=~ - == - :: - =^ results4 ford-gate - %- ford-take-with-comparator :* - ford-gate - now=~1234.5.9 - scry=scry - :: - ^= take-args - :* wire=/clay-sub/~nul/desk duct=~[/post-a] - ^= wrapped-sign ^- (hypo sign:ford-gate) :- *type - [%c %wris [%da ~1234.5.9] (sy [%x /posts/a]~)] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - ^- tang - :: - =+ length=(lent moves) - :: deal with mug ordering - :: - :: This test depends on the mugs of types stored in ford, which is - :: dependent on the parse tree of this file. There are two valid - :: responses, one where we send a spurious move about %post-b - :: because it was the entry which was evicted from the cache and one - :: where we don't because it wasn't. Check both cases. - :: - ?: =(length 2) - :: the simple case where we don't send a spurious post-b %made - :: - ?> ?=([^ ^ ~] moves) - :: - %- verify-post-made :* - move=i.moves - duct=~[/post-a] - type=scry-type - date=~1234.5.9 - title='post-a' - contents="post-a-contents-changed" - == - :: the complex case - :: - :: Not only do we send a spurious %made, we don't have a set order - :: that these events happen in, so check both ways. - :: - ?> ?=([^ ^ ^ ~] moves) - :: - =/ post-a-first=tang - %+ welp - %- verify-post-made :* - move=i.moves - duct=~[/post-a] - type=scry-type - date=~1234.5.9 - title='post-a' - contents="post-a-contents-changed" - == - %- verify-post-made :* - move=i.t.moves - duct=~[/post-b] - type=scry-type - date=~1234.5.9 - title='post-b' - contents="post-b-contents" - == - :: if we got a ~ for post-a-first, everything is fine - :: - ?~ post-a-first - ~ - :: otherwise, its either post-b first or an error. - :: - :: Either way, return post-b first check. - :: - %+ welp - %- verify-post-made :* - move=i.moves - duct=~[/post-b] - type=scry-type - date=~1234.5.9 - title='post-b' - contents="post-b" - == - :: - %- verify-post-made :* - move=i.t.moves - duct=~[/post-a] - type=scry-type - date=~1234.5.9 - title='post-a' - contents="post-a-contents-changed" - == == - :: - =^ results5 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.10 - scry=scry-is-forbidden - :: - call-args=[duct=~[/post-b] type=~ %kill ~] - moves=~ - == - :: - =^ results6 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.11 - scry=scry-is-forbidden - :: - call-args=[duct=~[/post-a] type=~ %kill ~] - :: - ^= moves - :~ :* duct=~[/post-a] %pass wire=/clay-sub/~nul/desk - %c %warp ~nul %desk ~ - == == == - :: - ;: weld - results1 - results2 - results3 - results4 - results5 - results6 - (expect-ford-empty ford-gate ~nul) - == -:: -++ disabled-test-reef-slow - :: - =/ hoon-parsed=hoon - (rain /~nul/base/~1234.5.6/sys/hoon/hoon hoon-scry) - ~& %parsed-hoon - :: - =/ arvo-parsed=hoon - (rain /~nul/base/~1234.5.6/sys/arvo/hoon arvo-scry) - ~& %parsed-arvo - :: - =/ zuse-parsed=hoon - (rain /~nul/base/~1234.5.6/sys/zuse/hoon zuse-scry) - ~& %parsed-zuse - :: - =/ pit=vase !>(~) - =/ hoon-compiled=vase (slap pit hoon-parsed) - ~& %hoon-compiled - =/ arvo-compiled=vase (slap (slot 7 hoon-compiled) arvo-parsed) - ~& %arvo-compiled - =/ pit-compiled=vase (slap arvo-compiled [%cnts ~[[%& 1] %is] ~]) - ~& %pit-compiled - =/ zuse-compiled=vase (slap pit-compiled zuse-parsed) - ~& %zuse-compiled - :: - =/ scry-results=(map [term beam] cage) (with-reef ~1234.5.6 ~) - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results scry-results) - :: - ^= call-args - :* duct=~[/reef] type=~ %build live=%.n - [%reef [~nul %base]] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - ^- tang - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made *] i.moves) - =/ result result.p.card.i.moves - ?> ?=(%complete -.result) - ?> ?=([%success %reef *] +.result) - :: - =/ kernel=vase vase.build-result.result - :: - %+ weld - =/ result - q:(slym (slap (slap kernel [%limb %format]) [%limb %en-beam]) *beam) - %+ expect-eq - !> (en-beam *beam) - !> result - :: - %+ expect-eq - !> & - !> (slab %format p.kernel) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-reef-short-circuit ^- tang - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-reef ~1234.5.6) - :: - ^= call-args - :* duct=~[/reef] type=~ %build live=%.n - [%reef [~nul %home]] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - ^- tang - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made *] i.moves) - =/ result result.p.card.i.moves - ?> ?=(%complete -.result) - ?> ?=([%success %reef *] +.result) - :: - =/ kernel=vase vase.build-result.result - :: - %+ weld - =/ result - q:(slym (slap (slap kernel [%limb %format]) [%limb %en-beam]) *beam) - %+ expect-eq - !> (en-beam *beam) - !> result - :: - %+ expect-eq - !> & - !> (slab %format p.kernel) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-path ^- tang - :: - =/ scry-results=(map [term beam] (unit cage)) - %- my :~ - :- [%cx [[~nul %desk %da ~1234.5.6] /hoon/bar/foo/lib]] - `[%hoon !>(*hoon)] - :: - :- [%cx [[~nul %desk %da ~1234.5.6] /hoon/foo-bar/lib]] - ~ - == - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results-and-failures scry-results) - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - [%path disc=[~nul %desk] prefix='lib' raw-path='foo-bar'] - == - :: - ^= moves - :~ :* duct=~[/path] %give %made ~1234.5.6 %complete - %success %path [[~nul %desk] /hoon/bar/foo/lib] - == == == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-plan-hoon ^- tang - :: - =/ =hoon (ream '`@tas`%constant') - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=scry-is-forbidden - :: - ^= call-args - :* duct=~[/plan] type=~ %build live=%.n - %plan - source-path=[[~nul %home] /bar/foo] - query-string=`coin`[%$ *dime] - source-rail=[[~nul %desk] /bar/foo] - zuse-version=309 - structures=~ - libraries=~ - cranes=~ - sources=[hoon]~ - == - :: - ^= comparator - |= moves=(list move:ford-gate) - ^- tang - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made *] i.moves) - =/ result result.p.card.i.moves - ?> ?=(%complete -.result) - ?> ?=([%success %plan *] +.result) - :: - =/ =vase vase.build-result.result - :: - (expect-eq !>(%constant) vase) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-core ^- tang - :: - =/ hoon-src '`@tas`%constant' - =/ hoon-src-type=type [%atom %$ ~] - :: - =/ scry-results=(map [term beam] cage) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/foo-bar/lib]] - [%hoon hoon-src-type hoon-src] - == - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results scry-results) - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - [%core source-path=`rail:ford-gate`[[~nul %home] /hoon/foo-bar/lib]] - == - :: - ^= moves - :~ :* duct=~[/path] %give %made ~1234.5.6 %complete - %success %core [%atom %tas ~] %constant - == == == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-core-linker ^- tang - :: - =/ hoon-src-type=type [%atom %$ ~] - =/ scry-results=(map [term beam] cage) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/data/sur]] - :- %hoon - :- hoon-src-type - ''' - |% - += data-type - [msg=tape count=@ud] - -- - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/data/lib]] - :- %hoon - :- hoon-src-type - ''' - /- data - |% - ++ do - |= [a=data-type:data b=data-type:data] - ^- data-type:data - [(weld msg.a msg.b) (add count.a count.b)] - -- - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/program/gen]] - :- %hoon - :- hoon-src-type - ''' - /- *data - /+ combiner=data - (do:combiner `data-type`["one" 1] `data-type`["two" 2]) - ''' - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results scry-results) - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - [%core source-path=`rail:ford-gate`[[~nul %home] /hoon/program/gen]] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %core *] build-result.result) - :: - =/ =vase vase.build-result.result - :: - (expect-eq !>(["onetwo" 3]) vase) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-core-multi-hoon ^- tang - :: - =/ hoon-src-type=type [%atom %$ ~] - =/ scry-results=(map [term beam] cage) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/program/gen]] - :- %hoon - :- hoon-src-type - ''' - |% - += data-type - [msg=tape count=@ud] - -- - |% - ++ data - ^- data-type - ["one" 1] - -- - data - ''' - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results scry-results) - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - [%core source-path=`rail:ford-gate`[[~nul %home] /hoon/program/gen]] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %core *] build-result.result) - :: - =/ =vase vase.build-result.result - :: - (expect-eq !>(["one" 1]) vase) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-core-fsts-fssg ^- tang - :: - =/ hoon-src-type=type [%atom %$ ~] - =/ scry-results=(map [term beam] cage) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/program/gen]] - :- %hoon - :- hoon-src-type - ''' - /= one /~ `@u`1 - /= two /~ `@u`2 - (add one two) - ''' - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results scry-results) - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - [%core source-path=`rail:ford-gate`[[~nul %home] /hoon/program/gen]] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %core *] build-result.result) - :: - =/ =vase vase.build-result.result - :: - (expect-eq !>(3) vase) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-core-fsdt-fskt ^- tang - :: - =/ hoon-src-type=type [%atom %$ ~] - =/ scry-results=(map [term beam] cage) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/program/gen]] - :- %hoon - :- hoon-src-type - ''' - /= data /^ (list @ud) - /. /~ 1 - /~ 2 - /~ 3 - == - (weld data [4 5 ~]) - ''' - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results scry-results) - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - [%core source-path=`rail:ford-gate`[[~nul %home] /hoon/program/gen]] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %core *] build-result.result) - :: - =/ =vase vase.build-result.result - :: - (expect-eq !>([1 2 3 4 5 ~]) vase) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-core-fskt-nest-fail ^- tang - :: - =/ hoon-src-type=type [%atom %$ ~] - =/ scry-results=(map [term beam] cage) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/program/gen]] - :- %hoon - :- hoon-src-type - ''' - /= data /^ (list @u) - /~ 5 - data - ''' - == - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results scry-results) - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - [%core source-path=`rail:ford-gate`[[~nul %home] /hoon/program/gen]] - == - :: - ^= moves - :~ :* duct=~[/path] %give %made ~1234.5.6 %complete %error - :~ :- %leaf - "ford: %core on /~nul/home/0/gen/program/hoon failed:" - [%leaf "/^ failed: nest-fail"] - == == == == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-core-fssm ^- tang - :: - =/ hoon-src-type=type [%atom %$ ~] - =/ scry-results=(map [term beam] cage) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/program/gen]] - :- %hoon - :- hoon-src-type - ''' - /= data /; |=(a=@u [a a ~]) - /~ 5 - data - ''' - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results scry-results) - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - [%core source-path=`rail:ford-gate`[[~nul %home] /hoon/program/gen]] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %core *] build-result.result) - :: - =/ =vase vase.build-result.result - :: - (expect-eq !>([5 5 ~]) vase) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-core-fsbr ^- tang - :: - =/ hoon-src-type=type [%atom %$ ~] - =/ scry-results=(map [term beam] cage) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/program/gen]] - :- %hoon - :- hoon-src-type - ''' - /= data /| /^ (list @u) - /~ 5 - :: - /^ (list @u) - /~ [6 6 ~] - == - data - ''' - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results scry-results) - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - [%core source-path=`rail:ford-gate`[[~nul %home] /hoon/program/gen]] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %core *] build-result.result) - :: - =/ =vase vase.build-result.result - :: - (expect-eq !>([6 6 ~]) vase) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-core-fsbr-out-of-options ^- tang - :: - =/ hoon-src-type=type [%atom %$ ~] - =/ scry-results=(map [term beam] cage) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/program/gen]] - :- %hoon - :- hoon-src-type - ''' - /= data /| /^ (list @u) - /~ 5 - :: - /^ @u - /~ [6 6 ~] - == - data - ''' - == - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results scry-results) - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - [%core source-path=`rail:ford-gate`[[~nul %home] /hoon/program/gen]] - == - :: - ^= moves - :~ :* duct=~[/path] %give %made ~1234.5.6 %complete %error - :~ :- %leaf - "ford: %core on /~nul/home/0/gen/program/hoon failed:" - [%leaf "/| failed: out of options"] - == == == == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-plan-fszp-as-noun ^- tang - :: - =/ hoon-src-type=type [%atom %$ ~] - =/ scry-results=(map [term beam] cage) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/program/gen]] - :- %hoon - :- hoon-src-type - ''' - /= data /!noun/ - data - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/other/lib]] - :- %hoon - :- hoon-src-type - ''' - [1 2 3 ~] - ''' - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results scry-results) - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - :* %plan [[~nul %home] /other/lib] *coin - :* source-rail=[[~nul %desk] /bar/foo] - zuse-version=309 - structures=~ - libraries=~ - cranes=[%fsts %data [%fszp %noun]]~ - sources=[%wing [%data]~]~ - == == == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %plan *] build-result.result) - :: - =/ =vase vase.build-result.result - :: - (expect-eq !>([1 2 3 ~]) vase) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-core-fszp-as-mark ^- tang - :: - =/ hoon-src-type=type [%atom %$ ~] - =/ scry-results=(map [term beam] cage) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/program/gen]] - :- %hoon - :- hoon-src-type - ''' - /= data /: /===/lib/other - /!somemark/ - data - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/somemark/mar]] - :- %hoon - :- hoon-src-type - ''' - |_ [word=tape num=@] - ++ grab - |% - += noun [tape @] - -- - -- - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/other/lib]] - :- %hoon - :- hoon-src-type - ''' - ["five" 5] - ''' - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results scry-results) - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - %core [[~nul %home] /hoon/program/gen] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %core *] build-result.result) - :: - =/ =vase vase.build-result.result - :: - (expect-eq !>(["five" 5]) vase) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-core-fscl-fszp ^- tang - :: - =/ hoon-src-type=type [%atom %$ ~] - =/ scry-results=(map [term beam] cage) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/program/gen]] - :- %hoon - :- hoon-src-type - ''' - /= data /: /===/data - /!noun/ - data - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/data]] - :- %hoon - :- hoon-src-type - ''' - [1 2 3 ~] - ''' - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results scry-results) - :: - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - [%core source-path=`rail:ford-gate`[[~nul %home] /hoon/program/gen]] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %core *] build-result.result) - :: - =/ =vase vase.build-result.result - :: - (expect-eq !>([1 2 3 ~]) vase) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-core-fscm ^- tang - :: - =/ hoon-src-type=type [%atom %$ ~] - =/ scry-results=(map [term beam] cage) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/program/gen]] - :- %hoon - :- hoon-src-type - ''' - /= data /: /===/data - /!noun/ - data - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/data]] - :- %hoon - :- hoon-src-type - ''' - /, /other - /~ a=[3 2 1 ~] - :: - /data - /~ a=[1 2 3 ~] - == - a - ''' - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results scry-results) - :: - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - [%core source-path=`rail:ford-gate`[[~nul %home] /hoon/program/gen]] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %core *] build-result.result) - :: - =/ =vase vase.build-result.result - :: - (expect-eq !>([1 2 3 ~]) vase) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-plan-fsbc ^- tang - :: - =/ hoon-src-type=type [%atom %$ ~] - =/ scry-results=(map [term beam] cage) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/other/lib]] - :- %hoon - :- hoon-src-type - ''' - /= data /$ %+ cork fuel:html - |= gas/epic:eyre - [bem.gas (~(got by qix.gas) 'key')] - data - ''' - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results scry-results) - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - :* %plan [[~nul %home] /other/lib] - :~ %many - [%blob *cred:eyre] - [%$ [%t %key]] - [%$ [%t %value]] - [%$ %n ~] - == - :* source-rail=[[~nul %home] /hoon/other/lib] - zuse-version=309 - structures=~ - libraries=~ - cranes=[%fsts %data [%fszp %noun]]~ - sources=`(list hoon)`[[%wing [%data]~] ~] - == == == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %plan *] build-result.result) - :: - =/ =vase vase.build-result.result - :: - %+ expect-eq - !>([[[~nul %home [%da ~1234.5.6]] /other/lib] %value]) - vase - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-core-fscb ^- tang - :: - =/ hoon-src-type=type [%atom %$ ~] - =/ arch-type=type -:!>(*arch) - =/ scry-results=(map [term beam] cage) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/program/gen]] - :- %hoon - :- hoon-src-type - ''' - /= data /^ (map @ta @ud) - /: /===/data - /_ /!noun/ - data - ''' - :: - :- [%cy [[~nul %home %da ~1234.5.6] /data]] - :- %arch - :- arch-type - :- ~ - (my ~[[~.one ~] [~.two ~] [~.hoon ~]]) - :: - :- [%cy [[~nul %home %da ~1234.5.6] /one/data]] - :- %arch - :- arch-type - :- ~ - (my ~[[~.hoon ~]]) - :: - :- [%cy [[~nul %home %da ~1234.5.6] /two/data]] - :- %arch - :- arch-type - :- ~ - (my ~[[~.hoon ~]]) - :: - :: this "hoon" file should be filtered out - :: - :- [%cy [[~nul %home %da ~1234.5.6] /hoon/data]] - :- %arch - :- arch-type - :- fil=[~ u=0v6] - ~ - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/one/data]] - :- %hoon - :- hoon-src-type - ''' - 1 - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/two/data]] - :- %hoon - :- hoon-src-type - ''' - 2 - ''' - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results scry-results) - :: - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - [%core source-path=`rail:ford-gate`[[~nul %home] /hoon/program/gen]] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %core *] build-result.result) - :: - =/ =vase vase.build-result.result - :: - =/ expected (my [[%one 1] [%two 2] ~]) - (expect-eq !>(expected) vase) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-core-fspm ^- tang - :: - =/ hoon-src-type=type [%atom %$ ~] - =/ arch-type=type -:!>(*arch) - =/ scry-results=(map [term beam] (unit cage)) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/program/gen]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - /= data /&second&first&/~["four" 5 "six"] - data - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/first/mar]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - |_ [word=tape num=@] - ++ grab - |% - ++ noun |=([a=tape b=@ c=tape] [a b]) - -- - -- - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/second/mar]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - |_ num=@ - ++ grab - |% - ++ first |=([a=tape b=@] b) - -- - -- - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/noun/mar]] - ~ - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results-and-failures scry-results) - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - %core [[~nul %home] /hoon/program/gen] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %core *] build-result.result) - :: - =/ =vase vase.build-result.result - (expect-eq !>(5) vase) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-core-fszy-renderer ^- tang - :: - =/ hoon-src-type=type [%atom %$ ~] - =/ scry-results=(map [term beam] cage) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/program/gen]] - :- %hoon - :- hoon-src-type - ''' - /= data /: /===/data - /foo/ - data - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/foo/ren]] - :- %hoon - :- hoon-src-type - ''' - /= data /!noun/ - data - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/data]] - :- %hoon - :- hoon-src-type - ''' - [1 2 3 ~] - ''' - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results scry-results) - :: - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - %core [[~nul %home] /hoon/program/gen] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %core *] build-result.result) - :: - =/ =vase vase.build-result.result - :: - (expect-eq !>([1 2 3 ~]) vase) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-bunt ^- tang - :: - =/ hoon-src=@ta - ''' - |_ cell=^ - ++ grab - |% - ++ noun ^ - -- - -- - ''' - =/ scry-results=(map [term beam] cage) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/foo/mar]] - [%hoon !>(hoon-src)] - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results scry-results) - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - [%bunt [~nul %home] %foo] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %bunt *] build-result.result) - :: - =/ =vase q.cage.build-result.result - :: - (expect-eq !>([0 0]) vase) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-volt ^- tang - :: - =/ hoon-src=@ta - ''' - |_ cell=^ - ++ grab - |% - ++ noun ^ - -- - -- - ''' - :: - =/ scry-results=(map [term beam] cage) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/foo/mar]] - [%hoon !>(hoon-src)] - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results scry-results) - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - [%volt [~nul %home] %foo [12 13]] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %volt *] build-result.result) - :: - =/ =vase q.cage.build-result.result - :: - (expect-eq !>([12 13]) vase) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-vale ^- tang - :: - =/ hoon-src=@ta - ''' - |_ cell=^ - ++ grab - |% - ++ noun ^ - -- - -- - ''' - :: - =/ scry-results=(map [term beam] cage) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/foo/mar]] - [%hoon !>(hoon-src)] - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results scry-results) - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - [%vale [~nul %home] %foo [12 13]] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %vale *] build-result.result) - :: - =/ =vase q.cage.build-result.result - :: - (expect-eq !>([12 13]) vase) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-vale-error ^- tang - :: - =/ hoon-src=@ta - ''' - |_ cell=^ - ++ grab - |% - ++ noun ^ - -- - -- - ''' - :: - =/ scry-results=(map [term beam] cage) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/foo/mar]] - [%hoon !>(hoon-src)] - == - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results scry-results) - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - [%vale [~nul %home] %foo 42] - == - :: - ^= moves - :~ :* duct=~[/path] %give %made ~1234.5.6 %complete %error - :~ :- %leaf - %+ weld - "ford: %vale failed: invalid input for mark: " - "/~nul/home/~1234.5.6/mar/foo/hoon" - :: - :- %leaf - "ford: %call execution failed:" - == == == == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-cast ^- tang - :: - =/ foo-mark-src=@ta - ''' - |_ cell=^ - ++ grab - |% - ++ bar ^ - -- - -- - ''' - :: - =/ bar-mark-src=@ta - ''' - |_ sample=[@ @] - ++ grab - |% - += noun [@ @] - -- - -- - ''' - :: - =/ hoon-src-type=type [%atom %$ ~] - =/ arch-type=type -:!>(*arch) - :: - =/ scry-results=(map [term beam] (unit cage)) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/foo/mar]] - `[%hoon hoon-src-type foo-mark-src] - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/bar/mar]] - `[%hoon hoon-src-type bar-mark-src] - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/noun/mar]] - ~ - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results-and-failures scry-results) - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - [%cast [~nul %home] %foo [%vale [~nul %home] %bar [12 13]]] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %cast *] build-result.result) - :: - =/ =cage cage.build-result.result - :: - (expect-cage %foo !>([12 13]) cage) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-cast-grow ^- tang - :: - =/ foo-mark-src=@ta - ''' - |_ cell=^ - ++ grab - |% - ++ noun ^ - -- - -- - ''' - :: - =/ bar-mark-src=@ta - ''' - |_ sample=[@ @] - ++ grab - |% - += noun [@ @] - -- - ++ grow - |% - ++ foo sample - -- - -- - ''' - :: - =/ hoon-src-type=type [%atom %$ ~] - =/ arch-type=type -:!>(*arch) - :: - =/ scry-results=(map [term beam] (unit cage)) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/foo/mar]] - `[%hoon hoon-src-type foo-mark-src] - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/bar/mar]] - `[%hoon hoon-src-type bar-mark-src] - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/noun/mar]] - ~ - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results-and-failures scry-results) - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - [%cast [~nul %home] %foo [%vale [~nul %home] %bar [12 13]]] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %cast *] build-result.result) - :: - =/ =cage cage.build-result.result - :: - (expect-cage %foo !>([12 13]) cage) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-mute ^- tang - :: - =/ atom-type=type [%atom %$ ~] - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=scry-is-forbidden - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - %mute subject=[%$ %foo !>([a=42 b=[43 c=44]])] - ^= mutations ^- (list [wing schematic:ford-gate]) - :~ - [~[%a] [%$ %noun atom-type 2]] - [~[%c %b] [%$ %noun atom-type 4]] - == == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %mute *] build-result.result) - :: - =/ =cage cage.build-result.result - :: - (expect-cage %foo !>([2 43 4]) cage) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-bake-renderer ^- tang - :: - =/ hoon-src-type=type [%atom %$ ~] - =/ scry-results=(map [term beam] cage) - %+ with-reef ~1234.5.6 - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/foo/ren]] - :- %hoon - :- hoon-src-type - ''' - /= data /!noun/ - data - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/data]] - :- %hoon - :- hoon-src-type - ''' - [1 2 3 ~] - ''' - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results scry-results) - :: - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - [%bake %foo *coin `rail:ford-gate`[[~nul %home] /data]] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %bake *] build-result.result) - :: - =/ =cage cage.build-result.result - :: - (expect-cage %foo !>([1 2 3 ~]) cage) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-bake-mark ^- tang - :: - =/ hoon-src-type=type [%atom %$ ~] - =/ arch-type=type -:!>(*arch) - :: - =/ scry-results=(map [term beam] (unit cage)) - %+ with-reef-unit ~1234.5.6 - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/foo/mar]] - :^ ~ %hoon hoon-src-type - ''' - |_ cell=^ - ++ grab - |% - ++ bar ^ - -- - -- - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/bar/mar]] - :^ ~ %hoon hoon-src-type - ''' - |_ sample=[@ @] - ++ grab - |% - += noun [@ @] - -- - -- - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/foo/ren]] - ~ - :: - :- [%cx [[~nul %home %da ~1234.5.6] /bar/data]] - `[%bar !>([12 13])] - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/noun/mar]] - ~ - :: - :- [%cy [[~nul %home %da ~1234.5.6] /data]] - `[%arch !>(`arch`[fil=~ dir=(my [%bar ~]~)])] - :: - :- [%cy [[~nul %home %da ~1234.5.6] /bar/data]] - `[%arch !>(`arch`[fil=`*@uv dir=~])] - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results-and-failures scry-results) - :: - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - [%bake %foo *coin `rail:ford-gate`[[~nul %home] /data]] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ~| build-result.result - ?> ?=([%success %bake *] build-result.result) - :: - =/ =cage cage.build-result.result - :: - (expect-cage %foo !>([12 13]) cage) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: renderers can fail, and we should fall back to using the mark -:: -++ test-bake-mark-fallback ^- tang - :: - =/ hoon-src-type=type [%atom %$ ~] - =/ scry-results=(map [term beam] (unit cage)) - %+ with-reef-unit ~1234.5.6 - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/dat/ren]] - :^ ~ %hoon hoon-src-type - ''' - /= data /~ !! - data - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/dat/mar]] - :^ ~ %hoon hoon-src-type - ''' - |_ atom=@ - ++ grab - |% - ++ txt @ - -- - -- - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/txt/mar]] - ~ - :: - :- [%cx [[~nul %home %da ~1234.5.6] /txt/data]] - :^ ~ %txt hoon-src-type - ''' - one - ''' - :: - :- [%cy [[~nul %home %da ~1234.5.6] /data]] - `[%arch !>(`arch`[fil=~ dir=(my [%txt ~]~)])] - :: - :- [%cy [[~nul %home %da ~1234.5.6] /txt/data]] - `[%arch !>(`arch`[fil=`*@uv dir=~])] - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results-and-failures scry-results) - :: - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - [%bake %dat *coin `rail:ford-gate`[[~nul %home] /data]] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %bake *] build-result.result) - :: - =/ =cage cage.build-result.result - :: - (expect-cage %dat !>('one') cage) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-diff ^- tang - :: - =/ hoon-src-type=type [%atom %$ ~] - =/ arch-type=type -:!>(*arch) - :: - =/ scry-results=(map [term beam] cage) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/foo/mar]] - :+ %hoon hoon-src-type - ''' - |_ cell=^ - ++ grab - |% - ++ noun ^ - -- - ++ grad - |% - ++ diff |=(^ +<) - ++ form %foo - -- - -- - ''' - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results scry-results) - :: - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - :^ %diff [~nul %home] - [%$ %foo !>([12 13])] - [%$ %foo !>([17 18])] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %diff *] build-result.result) - :: - =/ =cage cage.build-result.result - :: - (expect-cage %foo !>([17 18]) cage) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-diff-form ^- tang - :: - =/ hoon-src-type=type [%atom %$ ~] - =/ arch-type=type -:!>(*arch) - :: - =/ scry-results=(map [term beam] (unit cage)) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/txt/mar]] - :^ ~ %hoon hoon-src-type - ''' - |_ txt=wain - ++ grab - |% - ++ noun wain - -- - ++ grad - |% - ++ form %txt-diff - ++ diff - |= other-txt=wain - ^- (urge:clay cord) - =, differ - (lusk txt other-txt (loss txt other-txt)) - -- - -- - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/txt-diff/mar]] - :^ ~ %hoon hoon-src-type - ''' - |_ txt-diff=(urge:clay cord) - ++ grab - |% - ++ noun (urge:clay cord) - -- - -- - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/diff/txt/mar]] - ~ - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results-and-failures scry-results) - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - :^ %diff [~nul %home] - [%$ %txt !>(~[%a %b])] - [%$ %txt !>(~[%a %d])] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %diff *] build-result.result) - :: - =/ =cage cage.build-result.result - :: - (expect-cage %txt-diff !>(~[[%& 1] [%| ~[%b] ~[%d]]]) cage) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-pact ^- tang - :: - =/ hoon-src-type=type [%atom %$ ~] - =/ arch-type=type -:!>(*arch) - :: - =/ scry-results=(map [term beam] (unit cage)) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/txt/mar]] - :^ ~ %hoon hoon-src-type - ''' - |_ txt=wain - ++ grab - |% - ++ noun wain - -- - ++ grad - |% - ++ form %txt-diff - ++ diff - |= other-txt=wain - ^- (urge:clay cord) - =, differ - (lusk txt other-txt (loss txt other-txt)) - ++ pact - |= diff=(urge:clay cord) - ^- wain - =, differ - (lurk txt diff) - -- - -- - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/txt-diff/mar]] - :^ ~ %hoon hoon-src-type - ''' - |_ txt-diff=(urge:clay cord) - ++ grab - |% - ++ noun (urge:clay cord) - -- - -- - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/diff/txt/mar]] - ~ - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results-and-failures scry-results) - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - :^ %pact [~nul %home] - [%$ %txt !>(~[%a %b])] - [%$ %txt-diff !>(~[[%& 1] [%| ~[%b] ~[%d]]])] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %pact *] build-result.result) - :: - =/ =cage cage.build-result.result - :: - (expect-cage %txt !>(~[%a %d]) cage) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-pact-mark ^- tang - :: - =/ hoon-src-type=type [%atom %$ ~] - =/ arch-type=type -:!>(*arch) - :: - =/ scry-results=(map [term beam] (unit cage)) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/txt/mar]] - :^ ~ %hoon hoon-src-type - ''' - |_ txt=wain - ++ grab - |% - ++ noun wain - -- - ++ grad - |% - ++ form %txt-diff - ++ diff - |= other-txt=wain - ^- (urge:clay cord) - =, differ - (lusk txt other-txt (loss txt other-txt)) - ++ pact - |= diff=(urge:clay cord) - ^- wain - =, differ - (lurk txt diff) - -- - -- - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/foo/mar]] - :^ ~ %hoon hoon-src-type - ''' - |_ foo=@t - ++ grab - |% - ++ noun @t - ++ txt of-wain:format - -- - ++ grow - |% - ++ txt (to-wain:format foo) - -- - ++ grad %txt - -- - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/txt-diff/mar]] - :^ ~ %hoon hoon-src-type - ''' - |_ txt-diff=(urge:clay cord) - ++ grab - |% - ++ noun (urge:clay cord) - -- - -- - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/diff/txt/mar]] - ~ - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/noun/mar]] - ~ - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results-and-failures scry-results) - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - :^ %pact [~nul %home] - :+ %$ %foo !> - ''' - a - b - ''' - [%$ %txt-diff !>(~[[%& 1] [%| ~[%b] ~[%d]]])] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %pact *] build-result.result) - :: - =/ =cage cage.build-result.result - :: - =/ expected ''' - a - d - ''' - :: - (expect-cage %foo !>(expected) cage) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-join ^- tang - :: - =/ hoon-src-type=type [%atom %$ ~] - :: - =/ scry-results=(map [term beam] (unit cage)) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/txt/mar]] - :^ ~ %hoon hoon-src-type - txt-scry - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/txt-diff/mar]] - :^ ~ %hoon hoon-src-type - diff-scry - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/diff/txt/mar]] - ~ - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results-and-failures scry-results) - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - :^ %join [~nul %home] %txt - :: replace %a with %c on the first line - :: - :- [%$ %txt-diff !>(~[[%| ~[%a] ~[%c]] [%& 1]])] - :: replace %b with %d on the second line - :: - [%$ %txt-diff !>(~[[%& 1] [%| ~[%b] ~[%d]]])] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %join *] build-result.result) - :: - =/ =cage cage.build-result.result - :: - =/ result=(urge:clay cord) ~[[%| ~[%a] ~[%c]] [%| ~[%b] ~[%d]]] - (expect-cage %txt-diff !>(result) cage) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-join-grad ^- tang - :: - =/ hoon-src-type=type [%atom %$ ~] - :: - =/ scry-results=(map [term beam] (unit cage)) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/txt/mar]] - :^ ~ %hoon hoon-src-type - txt-scry - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/txt-diff/mar]] - :^ ~ %hoon hoon-src-type - diff-scry - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/diff/txt/mar]] - ~ - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/hoon/mar]] - :^ ~ %hoon hoon-src-type - ''' - |_ foo=@t - ++ grab - |% - ++ noun @t - ++ txt of-wain:format - -- - ++ grow - |% - ++ txt (to-wain:format foo) - -- - ++ grad %txt - -- - ''' - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results-and-failures scry-results) - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - :^ %join [~nul %home] %hoon - :: replace %a with %c on the first line - :: - :- [%$ %txt-diff !>(~[[%| ~[%a] ~[%c]] [%& 1]])] - :: replace %b with %d on the second line - :: - [%$ %txt-diff !>(~[[%& 1] [%| ~[%b] ~[%d]]])] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %join *] build-result.result) - :: - =/ =cage cage.build-result.result - :: - =/ result=(urge:clay cord) ~[[%| ~[%a] ~[%c]] [%| ~[%b] ~[%d]]] - (expect-cage %txt-diff !>(result) cage) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-list ^- tang - :: - =/ ud-type=type [%atom %ud ~] - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=scry-is-forbidden - :: - ^= call-args - :* duct=~[/count] type=~ %build live=%.n - %list - :~ [%$ %noun ud-type 1] - [%$ %noun ud-type 2] - [%$ %noun ud-type 3] - == == - :: - ^= moves - :~ :* duct=~[/count] %give %made ~1234.5.6 %complete - %success %list - :~ [%success %$ %noun ud-type 1] - [%success %$ %noun ud-type 2] - [%success %$ %noun ud-type 3] - == == == == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-mash ^- tang - :: - =/ hoon-src-type=type [%atom %$ ~] - :: - =/ scry-results=(map [term beam] (unit cage)) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/txt/mar]] - :^ ~ %hoon hoon-src-type - txt-scry - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/txt-diff/mar]] - :^ ~ %hoon hoon-src-type - diff-scry - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/diff/txt/mar]] - ~ - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results-and-failures scry-results) - :: - ^= call-args - :* duct=~[/path] type=~ %build live=%.n - ^- schematic:ford-gate - :- %mash - :^ [~nul %home] %txt - :: replace %a with %c on the first line - :: - ^= first - :+ [~nul %home] %txt-diff - ^- schematic:ford-gate - [%$ %txt-diff !>(~[[%| ~[%a] ~[%c]] [%& 1]])] - :: replace %b with %d on the second line - :: - ^= second - :+ [~nul %home] %txt-diff - ^- schematic:ford-gate - [%$ %txt-diff !>(~[[%& 1] [%| ~[%b] ~[%d]]])] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=(^ moves) - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %mash *] build-result.result) - :: - =/ =cage cage.build-result.result - :: - =/ result=(urge:clay cord) ~[[%| ~[%a] ~[%c]] [%| ~[%b] ~[%d]]] - :: - (expect-cage %txt-diff !>(result) cage) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: tests multiple cores depending on a rich dependency tree -:: -:: Test why multiple app cores don't receive dependencies -:: -++ test-multi-core-same-dependency ^- tang - :: - =/ hoon-src-type=type [%atom %$ ~] - :: - =/ scry-results=(map [term beam] (unit cage)) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/gh/app]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - /? 314 - /- gh, plan-acct - /+ gh-parse, connector - :: - (add sur-gh-two:gh lib-connector-val:connector) - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/gh/sur]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - [sur-gh-one=1 sur-gh-two=2 sur-gh-three=3] - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/plan-acct/sur]] - ~ - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/acct/plan/sur]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - [sur-plan-acct=1 sur-plan-acct=2] - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/lib/old/lib]] - ~ - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/old-lib/lib]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - [old-lib-val=10 ~] - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/parse/gh/lib]] - ~ - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/gh-parse/lib]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - /- gh - /+ old-lib - =, old-lib - [lib-gh-parse-val=(add old-lib-val sur-gh-three:gh) ~] - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/connector/lib]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - /- gh - /+ old-lib - =, old-lib - [lib-connector-val=(add old-lib-val sur-gh-one:gh) ~] - ''' - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results-and-failures scry-results) - :: - ^= call-args - :* duct=~[/gh] type=~ %build live=%.y - %core [[~nul %home] /hoon/gh/app] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(2 (lent moves)) - ?> ?=([^ ^ ~] moves) - ?> ?=([* %give %made @da %complete %success %core *] i.moves) - :: - =/ =vase vase.build-result.result.p.card.i.moves - :: - %+ weld - (expect-eq !>(13) vase) - :: - =/ files=(set [%x path]) - %- sy :~ - [%x /lib/old-lib/hoon] - [%x /sur/gh/hoon] - [%x /sur/plan-acct/hoon] - [%x /sur/plan/acct/hoon] - [%x /lib/old/lib/hoon] - [%x /app/gh/hoon] - [%x /lib/gh/parse/hoon] - [%x /lib/gh-parse/hoon] - [%x /lib/connector/hoon] - [%x /sys/hoon/hoon] - [%x /sys/arvo/hoon] - [%x /sys/zuse/hoon] - == - :: - %+ expect-eq - !> ^- move:ford-gate - :* duct=~[/gh] %pass wire=/clay-sub/~nul/home/~1234.5.6 - %c %warp ~nul %home - `[%mult [%da ~1234.5.6] files] - == - !> i.t.moves - == - :: add a gh2 app which is the same as gh; move dates forward - :: - :: gh2 is the same except for adding one instead of two. - =. scry-results - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.7] /hoon/gh/app]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - /? 314 - /- gh, plan-acct - /+ gh-parse, connector - :: - (add sur-gh-two:gh lib-connector-val:connector) - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.7] /hoon/gh2/app]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - /? 314 - /- gh, plan-acct - /+ gh-parse, connector - :: - (add sur-gh-one:gh lib-connector-val:connector) - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.7] /hoon/gh/sur]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - [sur-gh-one=1 sur-gh-two=2 sur-gh-three=3] - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.7] /hoon/plan-acct/sur]] - ~ - :: - :- [%cx [[~nul %home %da ~1234.5.7] /hoon/acct/plan/sur]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - [sur-plan-acct=1 sur-plan-acct=2] - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.7] /hoon/lib/old/lib]] - ~ - :: - :- [%cx [[~nul %home %da ~1234.5.7] /hoon/old-lib/lib]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - [old-lib-val=10 ~] - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.7] /hoon/parse/gh/lib]] - ~ - :: - :- [%cx [[~nul %home %da ~1234.5.7] /hoon/gh-parse/lib]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - /- gh - /+ old-lib - =, old-lib - [lib-gh-parse-val=(add old-lib-val sur-gh-three:gh) ~] - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.7] /hoon/connector/lib]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - /- gh - /+ old-lib - =, old-lib - [lib-connector-val=(add old-lib-val sur-gh-one:gh) ~] - ''' - == - :: - =^ results2 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.7 - scry=(scry-with-results-and-failures scry-results) - :: - ^= call-args - :* duct=~[/gh2] type=~ %build live=%.y - %core [[~nul %home] /hoon/gh2/app] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(2 (lent moves)) - ?> ?=([^ ^ ~] moves) - ?> ?=([* %give %made @da %complete %success %core *] i.moves) - :: - =/ =vase vase.build-result.result.p.card.i.moves - :: - %+ weld - (expect-eq !>(12) vase) - :: - =/ files=(set [%x path]) - %- sy :~ - [%x /lib/old-lib/hoon] - [%x /sur/gh/hoon] - [%x /sur/plan-acct/hoon] - [%x /sur/plan/acct/hoon] - [%x /lib/old/lib/hoon] - [%x /app/gh2/hoon] - [%x /lib/gh/parse/hoon] - [%x /lib/gh-parse/hoon] - [%x /lib/connector/hoon] - [%x /sys/hoon/hoon] - [%x /sys/arvo/hoon] - [%x /sys/zuse/hoon] - == - :: - %+ expect-eq - !> ^- move:ford-gate - :* duct=~[/gh2] %pass wire=/clay-sub/~nul/home/~1234.5.7 - %c %warp ~nul %home - `[%mult [%da ~1234.5.7] files] - == - !> i.t.moves - == - :: - :: add a gh3 app which is the same as gh; move dates forward - :: - :: gh3 is the same except for adding zero instead of two. - =. scry-results - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.8] /hoon/gh/app]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - /? 314 - /- gh, plan-acct - /+ gh-parse, connector - :: - (add sur-gh-two:gh lib-connector-val:connector) - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.8] /hoon/gh2/app]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - /? 314 - /- gh, plan-acct - /+ gh-parse, connector - :: - (add sur-gh-one:gh lib-connector-val:connector) - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.8] /hoon/gh3/app]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - /? 314 - /- gh, plan-acct - /+ gh-parse, connector - :: - (add 0 lib-connector-val:connector) - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.8] /hoon/gh/sur]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - [sur-gh-one=1 sur-gh-two=2 sur-gh-three=3] - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.8] /hoon/plan-acct/sur]] - ~ - :: - :- [%cx [[~nul %home %da ~1234.5.8] /hoon/acct/plan/sur]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - [sur-plan-acct=1 sur-plan-acct=2] - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.8] /hoon/lib/old/lib]] - ~ - :: - :- [%cx [[~nul %home %da ~1234.5.8] /hoon/old-lib/lib]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - [old-lib-val=10 ~] - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.8] /hoon/parse/gh/lib]] - ~ - :: - :- [%cx [[~nul %home %da ~1234.5.8] /hoon/gh-parse/lib]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - /- gh - /+ old-lib - =, old-lib - [lib-gh-parse-val=(add old-lib-val sur-gh-three:gh) ~] - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.8] /hoon/connector/lib]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - /- gh - /+ old-lib - =, old-lib - [lib-connector-val=(add old-lib-val sur-gh-one:gh) ~] - ''' - == - :: - =^ results3 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.8 - scry=(scry-with-results-and-failures scry-results) - :: - ^= call-args - :* duct=~[/gh3] type=~ %build live=%.y - %core [[~nul %home] /hoon/gh3/app] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(2 (lent moves)) - ?> ?=([^ ^ ~] moves) - ?> ?=([* %give %made @da %complete %success %core *] i.moves) - :: - =/ =vase vase.build-result.result.p.card.i.moves - :: - %+ weld - (expect-eq !>(11) vase) - :: - =/ files=(set [%x path]) - %- sy :~ - [%x /lib/old-lib/hoon] - [%x /sur/gh/hoon] - [%x /sur/plan-acct/hoon] - [%x /sur/plan/acct/hoon] - [%x /lib/old/lib/hoon] - [%x /app/gh3/hoon] - [%x /lib/gh/parse/hoon] - [%x /lib/gh-parse/hoon] - [%x /lib/connector/hoon] - [%x /sys/hoon/hoon] - [%x /sys/arvo/hoon] - [%x /sys/zuse/hoon] - == - :: - %+ expect-eq - !> ^- move:ford-gate - :* duct=~[/gh3] %pass wire=/clay-sub/~nul/home/~1234.5.8 - %c %warp ~nul %home - `[%mult [%da ~1234.5.8] files] - == - !> i.t.moves - == - :: - :: change the implementation of /lib/connector/hoon - :: - =. scry-results - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.9] /hoon/gh/app]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - /? 314 - /- gh, plan-acct - /+ gh-parse, connector - :: - (add sur-gh-two:gh lib-connector-val:connector) - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.9] /hoon/gh2/app]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - /? 314 - /- gh, plan-acct - /+ gh-parse, connector - :: - (add sur-gh-one:gh lib-connector-val:connector) - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.9] /hoon/gh3/app]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - /? 314 - /- gh, plan-acct - /+ gh-parse, connector - :: - (add 0 lib-connector-val:connector) - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.9] /hoon/gh/sur]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - [sur-gh-one=1 sur-gh-two=2 sur-gh-three=3] - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.9] /hoon/plan-acct/sur]] - ~ - :: - :- [%cx [[~nul %home %da ~1234.5.9] /hoon/acct/plan/sur]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - [sur-plan-acct=1 sur-plan-acct=2] - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.9] /hoon/lib/old/lib]] - ~ - :: - :- [%cx [[~nul %home %da ~1234.5.9] /hoon/old-lib/lib]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - [old-lib-val=10 ~] - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.9] /hoon/parse/gh/lib]] - ~ - :: - :- [%cx [[~nul %home %da ~1234.5.9] /hoon/gh-parse/lib]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - /- gh - /+ old-lib - =, old-lib - [lib-gh-parse-val=(add old-lib-val sur-gh-three:gh) ~] - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.9] /hoon/connector/lib]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - /- gh - /+ old-lib - =, old-lib - [lib-connector-val=(add old-lib-val 5) ~] - ''' - == - :: - =^ results4 ford-gate - %- ford-take-with-comparator :* - ford-gate - now=~1234.5.9 - scry=(scry-with-results-and-failures scry-results) - :: - ^= take-args - :* wire=/clay-sub/~nul/home/~1234.5.6 duct=~[/gh] - ^= wrapped-sign ^- (hypo sign:ford-gate) :- *type - [%c %wris [%da ~1234.5.9] (sy [%x /lib/connector/hoon]~)] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(2 (lent moves)) - ?> ?=([^ ^ ~] moves) - ?> ?=([* %give %made @da %complete %success %core *] i.moves) - :: - =/ =vase vase.build-result.result.p.card.i.moves - :: - =/ files=(set [%x path]) - %- sy :~ - [%x /lib/old-lib/hoon] - [%x /sur/gh/hoon] - [%x /sur/plan-acct/hoon] - [%x /sur/plan/acct/hoon] - [%x /lib/old/lib/hoon] - [%x /app/gh/hoon] - [%x /lib/gh/parse/hoon] - [%x /lib/gh-parse/hoon] - [%x /lib/connector/hoon] - [%x /sys/hoon/hoon] - [%x /sys/arvo/hoon] - [%x /sys/zuse/hoon] - == - :: - ;: weld - (expect-eq !>(~[/gh]) !>(duct.i.moves)) - (expect-eq !>(17) vase.build-result.result.p.card.i.moves) - :: - %+ expect-eq - !> ^- move:ford-gate - :* duct=~[/gh] %pass wire=/clay-sub/~nul/home/~1234.5.9 - %c %warp ~nul %home - `[%mult [%da ~1234.5.9] files] - == - !> i.t.moves - == == - :: - =^ results5 ford-gate - %- ford-take-with-comparator :* - ford-gate - now=~1234.5.9 - scry=(scry-with-results-and-failures scry-results) - :: - ^= take-args - :* wire=/clay-sub/~nul/home/~1234.5.7 duct=~[/gh2] - ^= wrapped-sign ^- (hypo sign:ford-gate) :- *type - [%c %wris [%da ~1234.5.9] (sy [%x /lib/connector/hoon]~)] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(2 (lent moves)) - ?> ?=([^ ^ ~] moves) - ?> ?=([* %give %made @da %complete %success %core *] i.moves) - :: - =/ =vase vase.build-result.result.p.card.i.moves - :: - =/ files=(set [%x path]) - %- sy :~ - [%x /lib/old-lib/hoon] - [%x /sur/gh/hoon] - [%x /sur/plan-acct/hoon] - [%x /sur/plan/acct/hoon] - [%x /lib/old/lib/hoon] - [%x /app/gh2/hoon] - [%x /lib/gh/parse/hoon] - [%x /lib/gh-parse/hoon] - [%x /lib/connector/hoon] - [%x /sys/hoon/hoon] - [%x /sys/arvo/hoon] - [%x /sys/zuse/hoon] - == - :: - ;: weld - (expect-eq !>(~[/gh2]) !>(duct.i.moves)) - (expect-eq !>(16) vase.build-result.result.p.card.i.moves) - :: - %+ expect-eq - !> ^- move:ford-gate - :* duct=~[/gh2] %pass wire=/clay-sub/~nul/home/~1234.5.9 - %c %warp ~nul %home - `[%mult [%da ~1234.5.9] files] - == - !> i.t.moves - == == - :: - =^ results6 ford-gate - %- ford-take-with-comparator :* - ford-gate - now=~1234.5.9 - scry=(scry-with-results-and-failures scry-results) - :: - ^= take-args - :* wire=/clay-sub/~nul/home/~1234.5.8 duct=~[/gh3] - ^= wrapped-sign ^- (hypo sign:ford-gate) :- *type - [%c %wris [%da ~1234.5.9] (sy [%x /lib/connector/hoon]~)] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(2 (lent moves)) - ?> ?=([^ ^ ~] moves) - ?> ?=([* %give %made @da %complete %success %core *] i.moves) - :: - =/ =vase vase.build-result.result.p.card.i.moves - :: - =/ files=(set [%x path]) - %- sy :~ - [%x /lib/old-lib/hoon] - [%x /sur/gh/hoon] - [%x /sur/plan-acct/hoon] - [%x /sur/plan/acct/hoon] - [%x /lib/old/lib/hoon] - [%x /app/gh3/hoon] - [%x /lib/gh/parse/hoon] - [%x /lib/gh-parse/hoon] - [%x /lib/connector/hoon] - [%x /sys/hoon/hoon] - [%x /sys/arvo/hoon] - [%x /sys/zuse/hoon] - == - :: - ;: weld - (expect-eq !>(~[/gh3]) !>(duct.i.moves)) - (expect-eq !>(15) vase.build-result.result.p.card.i.moves) - :: - %+ expect-eq - !> ^- move:ford-gate - :* duct=~[/gh3] %pass wire=/clay-sub/~nul/home/~1234.5.9 - %c %warp ~nul %home - `[%mult [%da ~1234.5.9] files] - == - !> i.t.moves - == == - :: - =^ results7 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.10 - scry=scry-is-forbidden - :: - call-args=[duct=~[/gh] type=~ %kill ~] - :: - ^= moves - :~ :* duct=~[/gh] %pass /clay-sub/~nul/home/~1234.5.9 - %c %warp ~nul %home ~ - == == == - :: - =^ results8 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.11 - scry=scry-is-forbidden - :: - call-args=[duct=~[/gh2] type=~ %kill ~] - :: - ^= moves - :~ :* duct=~[/gh2] %pass /clay-sub/~nul/home/~1234.5.9 - %c %warp ~nul %home ~ - == == == - :: - =^ results9 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.12 - scry=scry-is-forbidden - :: - call-args=[duct=~[/gh3] type=~ %kill ~] - :: - ^= moves - :~ :* duct=~[/gh3] %pass /clay-sub/~nul/home/~1234.5.9 - %c %warp ~nul %home ~ - == == == - :: - ;: weld - results1 - results2 - results3 - results4 - results5 - results6 - results7 - results8 - results9 - (expect-ford-empty ford-gate ~nul) - == -:: tests that we can do the simple adjacent mark case, and that we use grab -:: when both available. -:: -++ test-walk-prefer-grab ^- tang - :: - =/ hoon-src-type=type [%atom %$ ~] - =/ arch-type=type -:!>(*arch) - :: - =/ scry-results=(map [term beam] cage) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/one/mar]] - :- %hoon - :- hoon-src-type - ''' - |_ [a=tape b=@ud] - :: convert to - ++ grow - |% - ++ two [b a "grow"] - -- - -- - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/two/mar]] - :- %hoon - :- hoon-src-type - ''' - |_ [a=@ud b=tape c=type] - ++ grab - |% - ++ one |=([a=tape b=@ud] [b a "grab"]) - -- - -- - ''' - :: - :: todo: %cy looks funny here - :: - :: make sure we can deal with random not-hoon files in mar - :- [%cy [[~nul %home %da ~1234.5.6] /js/dummy/mar]] - :- %js - :- hoon-src-type - ''' - window.onload = function() - ''' - == - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results scry-results) - :: - ^= call-args - :* duct=~[/walk] type=~ %build live=%.y - %walk [~nul %home] %one %two - == - :: - ^= moves - :~ ^- move:ford-gate - :* duct=~[/walk] %give %made ~1234.5.6 - %complete %success %walk - [%grab %one %two]~ - == - ^- move:ford-gate - :* duct=~[/walk] %pass /clay-sub/~nul/home/~1234.5.6 - %c %warp ~nul %home ~ %mult [%da ~1234.5.6] - %- sy :~ - [%x /mar/two/hoon] - [%x /mar/one/hoon] - [%x /sys/hoon/hoon] - [%x /sys/arvo/hoon] - [%x /sys/zuse/hoon] - == == == == - :: - =^ results2 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=scry-is-forbidden - :: - call-args=[duct=~[/walk] type=~ %kill ~] - :: - ^= moves - :~ :* duct=~[/walk] %pass /clay-sub/~nul/home/~1234.5.6 - %c %warp ~nul %home ~ - == == == - :: - ;: weld - results1 - results2 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-walk-large-graph ^- tang - :: - =^ results1 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results large-mark-graph) - :: - ^= call-args - :* duct=~[/walk] type=~ %build live=%.y - %walk [~nul %home] %one %four - == - :: - ^= moves - :~ ^- move:ford-gate - :* duct=~[/walk] %give %made ~1234.5.6 - %complete %success %walk - [[%grab %one %two] [%grab %two %four] ~] - == - ^- move:ford-gate - :* duct=~[/walk] %pass /clay-sub/~nul/home/~1234.5.6 - %c %warp ~nul %home ~ %mult [%da ~1234.5.6] - %- sy :~ - [%x /mar/one/hoon] - [%x /mar/two/hoon] - [%x /mar/four/hoon] - [%x /mar/five/hoon] - [%x /sys/hoon/hoon] - [%x /sys/arvo/hoon] - [%x /sys/zuse/hoon] - == == == == - :: - =^ results2 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.6 - scry=scry-is-forbidden - :: - call-args=[duct=~[/walk] type=~ %kill ~] - :: - ^= moves - :~ :* duct=~[/walk] %pass /clay-sub/~nul/home/~1234.5.6 - %c %warp ~nul %home ~ - == == == - :: - ;: weld - results1 - results2 - (expect-ford-empty ford-gate ~nul) - == -:: +test-walk-large-graph, except we're going to shove data through it. -:: -++ test-cast-large-graph ^- tang - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results large-mark-graph) - :: - ^= call-args - :* duct=~[/large] type=~ %build live=%.n - [%cast [~nul %home] %four [%volt [~nul %home] %one ["one" 1]]] - == - ^= comparator - |= moves=(list move:ford-gate) - :: - ?> =(1 (lent moves)) - ?> ?=([^ ~] moves) - ?> ?=([* %give %made @da %complete %success %cast *] i.moves) - :: - =/ result=cage cage.build-result.result.p.card.i.moves - :: - (expect-cage %four !>(["grab" "one"]) result) - == - :: - ;: weld - results1 - (expect-ford-empty ford-gate ~nul) - == -:: -++ test-complex-live-cranes - ^- tang - :: set the build-cache to 2 to force eviction - :: - =^ results0 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.5 - scry=scry-is-forbidden - :: - call-args=[duct=~[/config] type=~ %keep [2.048 0]] - moves=~ - == - :: - =/ hoon-src-type=type [%atom %$ ~] - =/ item-type=type -:!>([%item '']) - =/ arch-type=type -:!>(*arch) - :: - =/ scry-results1=(map [term beam] (unit cage)) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/program/app]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - /+ things - /= data - /^ box:things - /; |= a=(map knot item:things) - [*config:things a] - /: /===/web /_ /item/ - :: - data - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/things/lib]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - |% - +$ box [config (map knot item)] - +$ config [%config @t] - +$ item [%item @t] - -- - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/item/mar]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - /+ things - |_ item:things - :: convert to - ++ grab - |% - ++ noun item:things - -- - -- - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/item/ren]] - ~ - :: - :- [%cx [[~nul %home %da ~1234.5.6] /item/data1/web]] - :- ~ - :- %item - :- item-type - [%item 'one'] - :: - :- [%cy [[~nul %home %da ~1234.5.6] /web]] - `[%arch !>(`arch`[fil=~ dir=(my [[%data1 ~] ~])])] - :: - :- [%cy [[~nul %home %da ~1234.5.6] /data1/web]] - `[%arch !>(`arch`[fil=~ dir=(my [%item ~]~)])] - :: - :- [%cy [[~nul %home %da ~1234.5.6] /item/data1/web]] - `[%arch !>(`arch`[fil=`0v1 dir=~])] - == - :: - =^ results1 ford-gate - %- ford-call-with-comparator :* - ford-gate - now=~1234.5.6 - scry=(scry-with-results-and-failures scry-results1) - :: - ^= call-args - ^- [=duct type=* wrapped-task=(hobo task:able:ford-gate)] - :* duct=~[/app] type=~ %build live=%.y - [%core source-path=`rail:ford-gate`[[~nul %home] /hoon/program/app]] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - ^- tang - :: - ?> =(2 (lent moves)) - ?> ?=(^ moves) - :: - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %core *] build-result.result) - :: - =/ =vase vase.build-result.result - :: - =/ result=[[%config @t] (map knot [%item @t])] - :- [%config ''] - (my [%data1 [%item 'one']] ~) - :: - (expect-eq !>(result) vase) - :: - :: TODO: check the subscription? - == - :: - =/ scry-results2=(map [term beam] (unit cage)) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.7] /hoon/program/app]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - /+ things - /= data - /^ box:things - /; |= a=(map knot item:things) - [*config:things a] - /: /===/web /_ /item/ - :: - data - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.7] /hoon/things/lib]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - |% - +$ box [config (map knot item)] - +$ config [%config @t] - +$ item [%item @t] - -- - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.7] /hoon/item/mar]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - /+ things - |_ item:things - :: convert to - ++ grab - |% - ++ noun item:things - -- - -- - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.7] /hoon/item/ren]] - ~ - :: - :- [%cx [[~nul %home %da ~1234.5.7] /item/data1/web]] - :- ~ - :- %item - :- item-type - [%item 'one'] - :: - :- [%cx [[~nul %home %da ~1234.5.7] /item/data2/web]] - :- ~ - :- %item - :- item-type - [%item 'two'] - :: - :- [%cy [[~nul %home %da ~1234.5.7] /web]] - `[%arch !>(`arch`[fil=~ dir=(my [[%data1 ~] [%data2 ~] ~])])] - ::a - :- [%cy [[~nul %home %da ~1234.5.7] /data1/web]] - `[%arch !>(`arch`[fil=~ dir=(my [%item ~]~)])] - :: - :- [%cy [[~nul %home %da ~1234.5.7] /data2/web]] - `[%arch !>(`arch`[fil=~ dir=(my [%item ~]~)])] - - :- [%cy [[~nul %home %da ~1234.5.7] /item/data1/web]] - `[%arch !>(`arch`[fil=`0v1 dir=~])] - :: - :- [%cy [[~nul %home %da ~1234.5.7] /item/data2/web]] - `[%arch !>(`arch`[fil=`0v2 dir=~])] - == - :: - =^ results2 ford-gate - %- ford-take-with-comparator :* - ford-gate - now=~1234.5.7 - scry=(scry-with-results-and-failures scry-results2) - :: - ^= take-args - :* wire=/clay-sub/~nul/home/~1234.5.6 duct=~[/app] - ^= wrapped-sign ^- (hypo sign:ford-gate) :- *type - [%c %wris [%da ~1234.5.7] (sy [%y /web]~)] - == - :: - ^= comparator - |= moves=(list move:ford-gate) - ^- tang - :: - ?> =(2 (lent moves)) - ?> ?=(^ moves) - :: - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %core *] build-result.result) - :: - =/ =vase vase.build-result.result - :: - =/ result=[[%config @t] (map knot [%item @t])] - :- [%config ''] - (my [%data1 [%item 'one']] [%data2 [%item 'two']] ~) - :: - (expect-eq !>(result) vase) - :: - :: TODO: check the subscription? - == - :: - =/ scry-results3=(map [term beam] (unit cage)) - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.8] /hoon/program/app]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - /+ things - /= data - /^ box:things - /; |= a=(map knot item:things) - [*config:things a] - /: /===/web /_ /item/ - :: - data - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.8] /hoon/things/lib]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - |% - +$ box [config (map knot item)] - +$ config [%config @t] - +$ item [%item @t] - -- - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.8] /hoon/item/mar]] - :- ~ - :- %hoon - :- hoon-src-type - ''' - /+ things - |_ item:things - :: convert to - ++ grab - |% - ++ noun item:things - -- - -- - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.8] /hoon/item/ren]] - ~ - :: - :- [%cx [[~nul %home %da ~1234.5.8] /item/data1/web]] - :- ~ - :- %item - :- item-type - [%item 'one'] - :: - :- [%cx [[~nul %home %da ~1234.5.8] /item/data2/web]] - :- ~ - :- %item - :- item-type - [%item 'changed-two'] - :: - :- [%cy [[~nul %home %da ~1234.5.8] /web]] - `[%arch !>(`arch`[fil=~ dir=(my [[%data1 ~] [%data2 ~] ~])])] - ::a - :- [%cy [[~nul %home %da ~1234.5.8] /data1/web]] - `[%arch !>(`arch`[fil=~ dir=(my [%item ~]~)])] - :: - :- [%cy [[~nul %home %da ~1234.5.8] /data2/web]] - `[%arch !>(`arch`[fil=~ dir=(my [%item ~]~)])] - - :- [%cy [[~nul %home %da ~1234.5.8] /item/data1/web]] - `[%arch !>(`arch`[fil=`0v1 dir=~])] - :: - :- [%cy [[~nul %home %da ~1234.5.8] /item/data2/web]] - `[%arch !>(`arch`[fil=`0v222 dir=~])] - == - :: - =^ results3 ford-gate - %- ford-take-with-comparator :* - ford-gate - now=~1234.5.7 - scry=(scry-with-results-and-failures scry-results3) - :: - ^= take-args - :* wire=/clay-sub/~nul/home/~1234.5.7 duct=~[/app] - ^= wrapped-sign ^- (hypo sign:ford-gate) :- *type - :* %c %wris [%da ~1234.5.8] - (sy [%x /web/data2/item] [%y /web/data2/item] ~) - == == - :: - ^= comparator - |= moves=(list move:ford-gate) - ^- tang - :: - ?> =(2 (lent moves)) - ?> ?=(^ moves) - :: - ?> ?=([* %give %made @da %complete *] i.moves) - =/ result result.p.card.i.moves - ?> ?=([%success %core *] build-result.result) - :: - =/ =vase vase.build-result.result - :: - =/ result=[[%config @t] (map knot [%item @t])] - :- [%config ''] - (my [%data1 [%item 'one']] [%data2 [%item 'changed-two']] ~) - :: - (expect-eq !>(result) vase) - :: - :: TODO: check the subscription? - == - :: - =^ results4 ford-gate - %- ford-call :* - ford-gate - now=~1234.5.8 - scry=scry-is-forbidden - :: - call-args=[duct=~[/app] type=~ %kill ~] - :: - ^= moves - :~ :* duct=~[/app] %pass wire=/clay-sub/~nul/home/~1234.5.8 - %c %warp ~nul %home ~ - == == == - :: - ;: weld - results0 - results1 - results2 - results3 - results4 - (expect-ford-empty ford-gate ~nul) - == -:: |data: shared data between cases -:: +| data -++ large-mark-graph - ^- (map [term beam] cage) - :: - =/ hoon-src-type=type [%atom %$ ~] - =/ arch-type=type -:!>(*arch) - :: - %- my :~ - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/one/mar]] - :- %hoon - :- hoon-src-type - ''' - |_ [a=tape b=@ud] - :: convert to - ++ grow - |% - ++ two [b a "grow"] - ++ five b - -- - -- - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/two/mar]] - :- %hoon - :- hoon-src-type - ''' - |_ [a=@ud b=tape c=tape] - ++ grab - |% - ++ one |=([a=tape b=@ud] [b a "grab"]) - -- - -- - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/three/mar]] - :- %hoon - :- hoon-src-type - ''' - |_ [b=tape c=tape] - ++ grab - |% - ++ one |=([a=tape b=@ud] [a "grab"]) - -- - ++ grow - |% - ++ two - [b c] - -- - -- - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/four/mar]] - :- %hoon - :- hoon-src-type - ''' - |_ [c=tape b=tape] - ++ grab - |% - ++ two - |= [a=@ud b=tape c=tape] - [c b] - -- - -- - ''' - :: - :- [%cx [[~nul %home %da ~1234.5.6] /hoon/five/mar]] - :- %hoon - :- hoon-src-type - ''' - |_ a=@u - ++ grab - |% - ++ four - :: ignore the value entirely - |= [c=tape b=tape] - 5 - -- - ++ grow - |% - ++ one - [a "empty" "grow"] - -- - -- - ''' - == --- diff --git a/pkg/arvo/tests/sys/vane/gall.hoon b/pkg/arvo/tests/sys/vane/gall.hoon index 3dc70c6046..c4c71b6b5b 100644 --- a/pkg/arvo/tests/sys/vane/gall.hoon +++ b/pkg/arvo/tests/sys/vane/gall.hoon @@ -1,6 +1,5 @@ /+ *test -:: -/= gall-raw /: /===/sys/vane/gall /!noun/ +/= gall-raw /sys/vane/gall :: =/ test-pit=vase !>(..zuse) =/ gall-gate (gall-raw test-pit) @@ -19,43 +18,39 @@ =/ =task:able:gall [%init ~nec] [duct type task] :: - =/ expected-moves ~ + =/ expected-moves=(list move:gall-gate) ~ :: - =^ results gall-gate + =/ res (gall-call gall-gate time *sley call-args expected-moves) :: - results -:: +test-conf: test %conf + -.res +:: +test-conf: test %conf; TODO: test clay response :: ++ test-conf ^- tang :: =/ =duct ~[/init] =/ time (add ~1111.1.1 ~s1) - =/ =term %my-agent + =/ dap=term %my-agent =/ ship ~nec :: =/ call-args =/ =type -:!>(*task:able:gall) - =/ =task:able:gall - =/ =dock [ship term] - [%conf dock dock] + =/ =task:able:gall [%conf dap] [duct type task] :: =/ =move:gall-gate - =/ =path /sys/cor/[term]/(scot %p ship)/[term]/(scot %da time) + =/ =wire /sys/cor/[dap]/(scot %p ship)/home/(scot %da time) =/ =note-arvo - =/ =schematic:ford [%core [ship term] /hoon/[term]/app] - =/ =task:able:ford [%build %.y schematic] - [%f task] - [duct %pass path note-arvo] + [%c %warp ship %home ~ %sing %a da+time /app/[dap]/hoon] + [duct %pass wire note-arvo] :: =/ expected-moves=(list move:gall-gate) ~[move] :: - =^ results gall-gate + =/ res (gall-call gall-gate time *sley call-args expected-moves) :: - results + -.res :: +gall-call: have %gall run a +task and assert it produces expected-moves :: ++ gall-call @@ -65,16 +60,16 @@ call-args=[=duct =type wrapped-task=(hobo task:able:gall)] expected-moves=(list move:gall-gate) == - ^- [tang _gall-gate] - :: =/ gall-core (gall-gate our=~nec now=now eny=`@`0xdead.beef scry=scry) :: - =^ moves gall-gate (call:gall-core [duct ~ type wrapped-task]:call-args) + =/ res + =/ =type -:!>(*task:able:gall) + (call:gall-core duct.call-args dud=~ type wrapped-task.call-args) :: =/ output=tang %+ expect-eq !> expected-moves - !> moves + !> -.res :: - [output gall-gate] + [output +.res] -- diff --git a/pkg/arvo/tests/sys/vane/iris.hoon b/pkg/arvo/tests/sys/vane/iris.hoon index b706bfce24..6ea9913743 100644 --- a/pkg/arvo/tests/sys/vane/iris.hoon +++ b/pkg/arvo/tests/sys/vane/iris.hoon @@ -1,6 +1,5 @@ /+ *test -:: -/= http-client-raw /: /===/sys/vane/iris /!noun/ +/= http-client-raw /sys/vane/iris :: !: :: diff --git a/pkg/arvo/tests/sys/zuse/ordered-map.hoon b/pkg/arvo/tests/sys/zuse/ordered-map.hoon index 02851e339f..7764dc05b7 100644 --- a/pkg/arvo/tests/sys/zuse/ordered-map.hoon +++ b/pkg/arvo/tests/sys/zuse/ordered-map.hoon @@ -1,8 +1,7 @@ :: TODO: move +ordered-map to zuse :: /+ *test -/= ames /: /===/sys/vane/ames - /!noun/ +/= ames /sys/vane/ames :: =/ items-from-keys |= keys=(list @ud) diff --git a/pkg/herb/herb b/pkg/herb/herb index 30f6834bd7..315992f01d 100755 --- a/pkg/herb/herb +++ b/pkg/herb/herb @@ -76,6 +76,7 @@ class sourceAction(argparse.Action): def __init__(self, option_strings, dest, **kwargs): self.which = kwargs['which'] del kwargs['which'] + logging.debug('args %s %s %s' % (option_strings, dest, kwargs)) super(sourceAction, self).__init__(option_strings, dest, **kwargs) def __call__(self, parser, res, new_value, option_string): @@ -104,6 +105,10 @@ class sourceAction(argparse.Action): logging.debug(res.source) def construct_value(self, new_value): + # hack to allow dojo commands like '-test' without them parsing + # as bash command-line arguments + if new_value[0:4] == '####': + return self.construct_value(new_value[4:]) if new_value == '-': return self.construct_value(''.join(sys.stdin.readlines())) elif new_value[0:2] == '@@': diff --git a/pkg/interface/config/webpack.dev.js b/pkg/interface/config/webpack.dev.js index 319b1d1d7a..75e68ac1e3 100644 --- a/pkg/interface/config/webpack.dev.js +++ b/pkg/interface/config/webpack.dev.js @@ -46,11 +46,11 @@ module.exports = { module: { rules: [ { - test: /\.js?$/, + test: /\.(j|t)sx?$/, use: { loader: 'babel-loader', options: { - presets: ['@babel/preset-env', '@babel/preset-react'], + presets: ['@babel/preset-env', '@babel/typescript', '@babel/preset-react'], plugins: [ '@babel/plugin-proposal-object-rest-spread', '@babel/plugin-proposal-optional-chaining', @@ -74,7 +74,7 @@ module.exports = { ] }, resolve: { - extensions: ['.js'] + extensions: ['.js', '.ts', '.tsx'] }, devtool: 'inline-source-map', // devServer: { diff --git a/pkg/interface/config/webpack.prod.js b/pkg/interface/config/webpack.prod.js index 65df55fe0f..e19e15940e 100644 --- a/pkg/interface/config/webpack.prod.js +++ b/pkg/interface/config/webpack.prod.js @@ -15,7 +15,7 @@ module.exports = { use: { loader: 'babel-loader', options: { - presets: ['@babel/preset-env', '@babel/preset-react'], + presets: ['@babel/preset-env', '@babel/typescript', '@babel/preset-react'], plugins: [ '@babel/plugin-proposal-object-rest-spread', '@babel/plugin-proposal-optional-chaining', diff --git a/pkg/interface/dbug/src/index.js b/pkg/interface/dbug/src/index.js index 16e1127c55..26798ac2aa 100644 --- a/pkg/interface/dbug/src/index.js +++ b/pkg/interface/dbug/src/index.js @@ -9,6 +9,7 @@ api.setAuthTokens({ ship: window.ship }); +window.urb = new window.channel(); subscription.start(); ReactDOM.render(( diff --git a/pkg/interface/dbug/src/js/components/searchable-list.js b/pkg/interface/dbug/src/js/components/searchable-list.js index 27b17e9ea4..5b7e1d1de4 100644 --- a/pkg/interface/dbug/src/js/components/searchable-list.js +++ b/pkg/interface/dbug/src/js/components/searchable-list.js @@ -33,7 +33,7 @@ export class SearchableList extends Component { let items = props.items.filter(item => { return state.query.split(' ').reduce((match, query) => { - return match && item.key.includes(query); + return match && ('' + item.key).includes(query); }, true); }) items = items.map(item => @@ -46,4 +46,4 @@ export class SearchableList extends Component {
{items.length === 0 ? 'none' : items}
); } -} \ No newline at end of file +} diff --git a/pkg/interface/package-lock.json b/pkg/interface/package-lock.json index 18aa0ffd90..0fa9a66616 100644 --- a/pkg/interface/package-lock.json +++ b/pkg/interface/package-lock.json @@ -563,6 +563,23 @@ "@babel/helper-plugin-utils": "^7.8.3" } }, + "@babel/plugin-syntax-typescript": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.10.1.tgz", + "integrity": "sha512-X/d8glkrAtra7CaQGMiGs/OGa6XgUzqPcBXCIGFCpCqnfGlT0Wfbzo/B89xHhnInTaItPK8LALblVXcUOEh95Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.1.tgz", + "integrity": "sha512-fvoGeXt0bJc7VMWZGCAEBEMo/HAjW2mP8apF5eXK0wSqwLAVHAISCWRoLMBMUs2kqeaG77jltVqu4Hn8Egl3nA==", + "dev": true + } + } + }, "@babel/plugin-transform-arrow-functions": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.8.3.tgz", @@ -911,6 +928,187 @@ "@babel/helper-plugin-utils": "^7.8.3" } }, + "@babel/plugin-transform-typescript": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.10.1.tgz", + "integrity": "sha512-v+QWKlmCnsaimLeqq9vyCsVRMViZG1k2SZTlcZvB+TqyH570Zsij8nvVUZzOASCRiQFUxkLrn9Wg/kH0zgy5OQ==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/plugin-syntax-typescript": "^7.10.1" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", + "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.1" + } + }, + "@babel/generator": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.2.tgz", + "integrity": "sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA==", + "dev": true, + "requires": { + "@babel/types": "^7.10.2", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.2.tgz", + "integrity": "sha512-5C/QhkGFh1vqcziq1vAL6SI9ymzUp8BCYjFpvYVhWP4DlATIb3u5q3iUd35mvlyGs8fO7hckkW7i0tmH+5+bvQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.10.1", + "@babel/helper-member-expression-to-functions": "^7.10.1", + "@babel/helper-optimise-call-expression": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-replace-supers": "^7.10.1", + "@babel/helper-split-export-declaration": "^7.10.1" + } + }, + "@babel/helper-function-name": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz", + "integrity": "sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.1", + "@babel/template": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz", + "integrity": "sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.1.tgz", + "integrity": "sha512-u7XLXeM2n50gb6PWJ9hoO5oO7JFPaZtrh35t8RqKLT1jFKj9IWeD1zrcrYp1q1qiZTdEarfDWfTIP8nGsu0h5g==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.1.tgz", + "integrity": "sha512-a0DjNS1prnBsoKx83dP2falChcs7p3i8VMzdrSbfLhuQra/2ENC4sbri34dz/rWmDADsmF1q5GbfaXydh0Jbjg==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.1.tgz", + "integrity": "sha512-fvoGeXt0bJc7VMWZGCAEBEMo/HAjW2mP8apF5eXK0wSqwLAVHAISCWRoLMBMUs2kqeaG77jltVqu4Hn8Egl3nA==", + "dev": true + }, + "@babel/helper-replace-supers": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.1.tgz", + "integrity": "sha512-SOwJzEfpuQwInzzQJGjGaiG578UYmyi2Xw668klPWV5n07B73S0a9btjLk/52Mlcxa+5AdIYqws1KyXRfMoB7A==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.10.1", + "@babel/helper-optimise-call-expression": "^7.10.1", + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz", + "integrity": "sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz", + "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", + "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", + "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==", + "dev": true + }, + "@babel/template": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", + "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.1", + "@babel/parser": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/traverse": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.1.tgz", + "integrity": "sha512-C/cTuXeKt85K+p08jN6vMDz8vSV0vZcI0wmQ36o6mjbuo++kPMdpOYw23W2XH04dbRt9/nMEfA4W3eR21CD+TQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.1", + "@babel/generator": "^7.10.1", + "@babel/helper-function-name": "^7.10.1", + "@babel/helper-split-export-declaration": "^7.10.1", + "@babel/parser": "^7.10.1", + "@babel/types": "^7.10.1", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", + "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, "@babel/plugin-transform-unicode-regex": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.8.3.tgz", @@ -1024,6 +1222,24 @@ "@babel/plugin-transform-react-jsx-source": "^7.9.0" } }, + "@babel/preset-typescript": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.10.1.tgz", + "integrity": "sha512-m6GV3y1ShiqxnyQj10600ZVOFrSSAa8HQ3qIUk2r+gcGtHTIRw0dJnFLt1WNXpKjtVw7yw1DAPU/6ma2ZvgJuA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/plugin-transform-typescript": "^7.10.1" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.1.tgz", + "integrity": "sha512-fvoGeXt0bJc7VMWZGCAEBEMo/HAjW2mP8apF5eXK0wSqwLAVHAISCWRoLMBMUs2kqeaG77jltVqu4Hn8Egl3nA==", + "dev": true + } + } + }, "@babel/runtime": { "version": "7.9.6", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.6.tgz", @@ -1320,12 +1536,24 @@ "@types/node": "*" } }, + "@types/history": { + "version": "4.7.6", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.6.tgz", + "integrity": "sha512-GRTZLeLJ8ia00ZH8mxMO8t0aC9M1N9bN461Z2eaRurJo6Fpa+utgCwLzI4jQHcrdzuzp5WPN9jRwpsCQ1VhJ5w==", + "dev": true + }, "@types/html-minifier-terser": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.0.tgz", "integrity": "sha512-iYCgjm1dGPRuo12+BStjd1HiVQqhlRhWDOQigNxn023HcjnhsiFz9pc6CzJj4HwDCSQca9bxTL4PxJDbkdm3PA==", "dev": true }, + "@types/lodash": { + "version": "4.14.155", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.155.tgz", + "integrity": "sha512-vEcX7S7aPhsBCivxMwAANQburHBtfN9RdyXFk84IJmu2Z4Hkg1tOFgaslRiEqqvoLtbCBi6ika1EMspE+NZ9Lg==", + "dev": true + }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", @@ -1338,6 +1566,43 @@ "integrity": "sha512-x26ur3dSXgv5AwKS0lNfbjpCakGIduWU1DU91Zz58ONRWrIKGunmZBNv4P7N+e27sJkiGDsw/3fT4AtsqQBrBA==", "dev": true }, + "@types/prop-types": { + "version": "15.7.3", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", + "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==", + "dev": true + }, + "@types/react": { + "version": "16.9.38", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.38.tgz", + "integrity": "sha512-pHAeZbjjNRa/hxyNuLrvbxhhnKyKNiLC6I5fRF2Zr/t/S6zS41MiyzH4+c+1I9vVfvuRt1VS2Lodjr4ZWnxrdA==", + "dev": true, + "requires": { + "@types/prop-types": "*", + "csstype": "^2.2.0" + } + }, + "@types/react-router": { + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.7.tgz", + "integrity": "sha512-2ouP76VQafKjtuc0ShpwUebhHwJo0G6rhahW9Pb8au3tQTjYXd2jta4wv6U2tGLR/I42yuG00+UXjNYY0dTzbg==", + "dev": true, + "requires": { + "@types/history": "*", + "@types/react": "*" + } + }, + "@types/react-router-dom": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.1.5.tgz", + "integrity": "sha512-ArBM4B1g3BWLGbaGvwBGO75GNFbLDUthrDojV2vHLih/Tq8M+tgvY1DSwkuNrPSwdp/GUL93WSEpTZs8nVyJLw==", + "dev": true, + "requires": { + "@types/history": "*", + "@types/react": "*", + "@types/react-router": "*" + } + }, "@types/source-list-map": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", diff --git a/pkg/interface/package.json b/pkg/interface/package.json index 15701e275c..b2be946bd2 100644 --- a/pkg/interface/package.json +++ b/pkg/interface/package.json @@ -34,6 +34,10 @@ "@babel/plugin-proposal-optional-chaining": "^7.9.0", "@babel/preset-env": "^7.9.5", "@babel/preset-react": "^7.9.4", + "@babel/preset-typescript": "^7.10.1", + "@types/lodash": "^4.14.155", + "@types/react": "^16.9.38", + "@types/react-router-dom": "^5.1.5", "babel-eslint": "^10.1.0", "babel-loader": "^8.1.0", "clean-webpack-plugin": "^3.0.0", @@ -51,6 +55,8 @@ "scripts": { "lint": "eslint ./**/*.js", "lint-file": "eslint", + "tsc": "tsc", + "tsc:watch": "tsc --watch", "build:dev": "cross-env NODE_ENV=development webpack --config config/webpack.dev.js", "build:prod": "cross-env NODE_ENV=production webpack --config config/webpack.prod.js", "start": "webpack-dev-server", diff --git a/pkg/interface/src/App.js b/pkg/interface/src/App.js index e763554dcd..7e2e62afb2 100644 --- a/pkg/interface/src/App.js +++ b/pkg/interface/src/App.js @@ -15,7 +15,7 @@ import PublishApp from './apps/publish/app'; import StatusBar from './components/StatusBar'; import NotFound from './components/404'; -import GlobalStore from './store/global'; +import GlobalStore from './store/store'; import GlobalSubscription from './subscription/global'; import GlobalApi from './api/global'; @@ -55,11 +55,11 @@ export default class App extends React.Component { this.appChannel = new window.channel(); this.api = new GlobalApi(this.ship, this.appChannel, this.store); + this.subscription = + new GlobalSubscription(this.store, this.api, this.appChannel); } componentDidMount() { - this.subscription = - new GlobalSubscription(this.store, this.api, this.appChannel); this.subscription.start(); } @@ -68,6 +68,7 @@ export default class App extends React.Component { const associations = this.state.associations ? this.state.associations : { contacts: {} }; const selectedGroups = this.state.selectedGroups ? this.state.selectedGroups : []; + const { state } = this; return ( @@ -84,8 +85,8 @@ export default class App extends React.Component { render={ p => ( )} @@ -93,8 +94,9 @@ export default class App extends React.Component { ( )} @@ -104,6 +106,7 @@ export default class App extends React.Component { ship={this.ship} channel={channel} selectedGroups={selectedGroups} + subscription={this.subscription} {...p} /> )} @@ -111,8 +114,9 @@ export default class App extends React.Component { ( )} @@ -120,8 +124,10 @@ export default class App extends React.Component { ( )} @@ -129,8 +135,9 @@ export default class App extends React.Component { ( )} diff --git a/pkg/interface/src/api/base.js b/pkg/interface/src/api/base.js deleted file mode 100644 index eaffa3dc67..0000000000 --- a/pkg/interface/src/api/base.js +++ /dev/null @@ -1,46 +0,0 @@ -import _ from 'lodash'; -import { uuid } from '../lib/util'; - - -export default class BaseApi { - constructor(ship, channel, store) { - this.ship = ship; - this.channel = channel; - this.store = store; - this.bindPaths = []; - } - - subscribe(path, method, ship = this.ship, app, success, fail, quit) { - this.bindPaths = _.uniq([...this.bindPaths, path]); - - window.subscriptionId = this.channel.subscribe(ship, app, path, - (err) => { - fail(err); - }, - (event) => { - success({ - data: event, - from: { - ship, - path - } - }); - }, - (qui) => { - quit(qui); - }); - } - - action(appl, mark, data) { - return new Promise((resolve, reject) => { - this.channel.poke(window.ship, appl, mark, data, - (json) => { - resolve(json); - }, - (err) => { - reject(err); - }); - }); - } -} - diff --git a/pkg/interface/src/api/base.ts b/pkg/interface/src/api/base.ts new file mode 100644 index 0000000000..1aec1b22ce --- /dev/null +++ b/pkg/interface/src/api/base.ts @@ -0,0 +1,56 @@ +import _ from "lodash"; +import { uuid } from "../lib/util"; +import { Patp, Path } from "../types/noun"; +import BaseStore from '../store/base'; + +export default class BaseApi { + bindPaths: Path[] = []; + constructor(public ship: Patp, public channel: any, public store: BaseStore) {} + + unsubscribe(id: number) { + this.channel.unsubscribe(id); + + } + + subscribe(path: Path, method, ship = this.ship, app: string, success, fail, quit) { + this.bindPaths = _.uniq([...this.bindPaths, path]); + + return this.channel.subscribe( + this.ship, + app, + path, + (err) => { + fail(err); + }, + (event) => { + success({ + data: event, + from: { + ship, + path, + }, + }); + }, + (qui) => { + quit(qui); + } + ); + } + + action(appl: string, mark: string, data: any): Promise { + return new Promise((resolve, reject) => { + this.channel.poke( + (window as any).ship, + appl, + mark, + data, + (json) => { + resolve(json); + }, + (err) => { + reject(err); + } + ); + }); + } +} diff --git a/pkg/interface/src/api/chat.js b/pkg/interface/src/api/chat.js deleted file mode 100644 index aeb7d23e99..0000000000 --- a/pkg/interface/src/api/chat.js +++ /dev/null @@ -1,222 +0,0 @@ -import BaseApi from './base'; -import { uuid } from '../lib/util'; - -export default class ChatApi { - constructor(ship, channel, store) { - const helper = new PrivateHelper(ship, channel, store); - - this.ship = ship; - this.subscribe = helper.subscribe.bind(helper); - - this.groups = { - add: helper.groupAdd.bind(helper), - remove: helper.groupRemove.bind(helper) - }; - - this.chat = { - message: helper.chatMessage.bind(helper), - read: helper.chatRead.bind(helper) - }; - - this.chatView = { - create: helper.chatViewCreate.bind(helper), - delete: helper.chatViewDelete.bind(helper), - join: helper.chatViewJoin.bind(helper), - groupify: helper.chatViewGroupify.bind(helper) - }; - - this.chatHook = { - addSynced: helper.chatHookAddSynced.bind(helper) - }; - - this.invite = { - accept: helper.inviteAccept.bind(helper), - decline: helper.inviteDecline.bind(helper) - }; - - this.metadata = { - add: helper.metadataAdd.bind(helper) - }; - this.sidebarToggle = helper.sidebarToggle.bind(helper); - } -} - -class PrivateHelper extends BaseApi { - groupsAction(data) { - return this.action('group-store', 'group-action', data); - } - - groupAdd(members, path) { - return this.groupsAction({ - add: { - members, path - } - }); - } - - groupRemove(members, path) { - this.groupsAction({ - remove: { - members, path - } - }); - } - - chatAction(data) { - this.action('chat-store', 'json', data); - } - - addPendingMessage(msg) { - if (this.store.state.pendingMessages.has(msg.path)) { - this.store.state.pendingMessages.get(msg.path).unshift(msg.envelope); - } else { - this.store.state.pendingMessages.set(msg.path, [msg.envelope]); - } - - this.store.setState({ - pendingMessages: this.store.state.pendingMessages - }); - } - - chatMessage(path, author, when, letter) { - const data = { - message: { - path, - envelope: { - uid: uuid(), - number: 0, - author, - when, - letter - } - } - }; - - this.action('chat-hook', 'json', data).then(() => { - this.chatRead(path); - }); - data.message.envelope.author = data.message.envelope.author.substr(1); - this.addPendingMessage(data.message); - } - - chatRead(path, read) { - this.chatAction({ read: { path } }); - } - - chatHookAddSynced(ship, path, askHistory) { - return this.action('chat-hook', 'chat-hook-action', { - 'add-synced': { - ship, - path, - 'ask-history': askHistory - } - }); - } - - chatViewAction(data) { - return this.action('chat-view', 'json', data); - } - - chatViewCreate( - title, description, appPath, groupPath, - security, members, allowHistory - ) { - return this.chatViewAction({ - create: { - title, - description, - 'app-path': appPath, - 'group-path': groupPath, - security, - members, - 'allow-history': allowHistory - } - }); - } - - chatViewDelete(path) { - this.chatViewAction({ delete: { 'app-path': path } }); - } - - chatViewJoin(ship, path, askHistory) { - this.chatViewAction({ - join: { - ship, - 'app-path': path, - 'ask-history': askHistory - } - }); - } - - chatViewGroupify(path, group = null, inclusive = false) { - const action = { groupify: { 'app-path': path, existing: null } }; - if (group) { - action.groupify.existing = { - 'group-path': group, - inclusive: inclusive - }; - } - return this.chatViewAction(action); - } - - inviteAction(data) { - this.action('invite-store', 'json', data); - } - - inviteAccept(uid) { - this.inviteAction({ - accept: { - path: '/chat', - uid - } - }); - } - - inviteDecline(uid) { - this.inviteAction({ - decline: { - path: '/chat', - uid - } - }); - } - - metadataAction(data) { - return this.action('metadata-hook', 'metadata-action', data); - } - - metadataAdd(appPath, groupPath, title, description, dateCreated, color) { - const creator = `~${window.ship}`; - return this.metadataAction({ - add: { - 'group-path': groupPath, - resource: { - 'app-path': appPath, - 'app-name': 'chat' - }, - metadata: { - title, - description, - color, - 'date-created': dateCreated, - creator - } - } - }); - } - - sidebarToggle() { - let sidebarBoolean = true; - if (this.store.state.sidebarShown === true) { - sidebarBoolean = false; - } - this.store.handleEvent({ - data: { - local: { - sidebarToggle: sidebarBoolean - } - } - }); - } -} - diff --git a/pkg/interface/src/api/chat.ts b/pkg/interface/src/api/chat.ts new file mode 100644 index 0000000000..bfc8d3e5ae --- /dev/null +++ b/pkg/interface/src/api/chat.ts @@ -0,0 +1,159 @@ +import BaseApi from './base'; +import { uuid } from '../lib/util'; +import { Letter, ChatAction, Envelope } from '../types/chat-update'; +import { Patp, Path, PatpNoSig } from '../types/noun'; +import { StoreState } from '../store/type'; +import BaseStore from '../store/base'; + + +export default class ChatApi extends BaseApi { + + /** + * Fetch backlog + */ + fetchMessages(start: number, end: number, path: Path) { + fetch(`/chat-view/paginate/${start}/${end}${path}`) + .then(response => response.json()) + .then((json) => { + this.store.handleEvent({ + data: json + }); + }); + } + + /** + * Send a message to the chat at path + */ + message(path: Path, author: Patp, when: string, letter: Letter): Promise { + const data: ChatAction = { + message: { + path, + envelope: { + uid: uuid(), + number: 0, + author, + when, + letter + } + } + }; + + const promise = this.proxyHookAction(data).then(() => { + this.read(path); + }); + data.message.envelope.author = data.message.envelope.author.substr(1); + this.addPendingMessage(data.message.path, data.message.envelope); + return promise; + } + + /** + * Mark chat as read + */ + read(path: Path): Promise { + return this.storeAction({ read: { path } }); + } + + + /** + * Create a chat and setup metadata + */ + create( + title: string, description: string, appPath: string, groupPath: string, + security: any, members: PatpNoSig[], allowHistory: boolean + ): Promise { + return this.viewAction({ + create: { + title, + description, + 'app-path': appPath, + 'group-path': groupPath, + security, + members, + 'allow-history': allowHistory + } + }); + } + + /** + * Deletes a chat + * + * If we don't host the chat, then it just leaves + */ + delete(path: Path) { + this.viewAction({ delete: { 'app-path': path } }); + } + + /** + * Join a chat + */ + join(ship: Patp, path: Path, askHistory: boolean): Promise { + return this.viewAction({ + join: { + ship, + 'app-path': path, + 'ask-history': askHistory + } + }); + } + + /** + * Groupify a chat that we host + * + * Will delete the old chat, recreate it based on a proper group, + * and invite the current whitelist to that group. + * existing messages get moved over. + * + * :existing is provided, associates chat with that group instead + * creating a new one. :inclusive indicates whether or not to add + * chat members to the group, if they aren't there already. + */ + groupify(path: Path, group: Path | null = null, inclusive = false) { + let action: any = { groupify: { 'app-path': path, existing: null } }; + if (group) { + action.groupify.existing = { + 'group-path': group, + inclusive: inclusive + }; + } + return this.viewAction(action); + } + + /** + * Begin syncing a chat from the host + */ + addSynced(ship: Patp, path: Path, askHistory: boolean): Promise { + return this.action('chat-hook', 'chat-hook-action', { + 'add-synced': { + ship, + path, + 'ask-history': askHistory + } + }); + } + + + private storeAction(action: ChatAction): Promise { + return this.action('chat-store', 'json', action) + } + + private proxyHookAction(action: ChatAction): Promise { + return this.action('chat-hook', 'json', action); + } + + private viewAction(action: unknown): Promise { + return this.action('chat-view', 'json', action); + } + + private addPendingMessage(path: Path, envelope: Envelope) { + const pending = this.store.state.pendingMessages.get(path); + if (pending) { + pending.unshift(envelope); + } else { + this.store.state.pendingMessages.set(path, [envelope]); + } + + this.store.setState({ + pendingMessages: this.store.state.pendingMessages + }); + } +} diff --git a/pkg/interface/src/api/contacts.ts b/pkg/interface/src/api/contacts.ts new file mode 100644 index 0000000000..7c7d7689c8 --- /dev/null +++ b/pkg/interface/src/api/contacts.ts @@ -0,0 +1,62 @@ +import BaseApi from './base'; +import { StoreState } from '../store/type'; +import { Patp, Path } from '../types/noun'; +import { Contact, ContactEdit } from '../types/contact-update'; + +export default class ContactsApi extends BaseApi { + + create(path: Path, ships: Patp[] = [], title: string, description: string) { + return this.viewAction({ + create: { + path, + ships, + title, + description + } + }); + } + + share(recipient: Patp, path: Patp, ship: Patp, contact: Contact) { + return this.viewAction({ + share: { + recipient, path, ship, contact + } + }); + } + + delete(path: Path) { + return this.viewAction({ delete: { path } }); + } + + remove(path: Path, ship: Patp) { + return this.viewAction({ remove: { path, ship } }); + } + + + + edit(path: Path, ship: Patp, editField: ContactEdit) { + /* editField can be... + {nickname: ''} + {email: ''} + {phone: ''} + {website: ''} + {notes: ''} + {color: 'fff'} // with no 0x prefix + {avatar: null} + {avatar: {url: ''}} + */ + return this.hookAction({ + edit: { + path, ship, 'edit-field': editField + } + }); + } + + private hookAction(data) { + return this.action('contact-hook', 'contact-action', data); + } + + private viewAction(data) { + return this.action('contact-view', 'json', data); + } +} diff --git a/pkg/interface/src/api/global.js b/pkg/interface/src/api/global.js deleted file mode 100644 index 0ed2864645..0000000000 --- a/pkg/interface/src/api/global.js +++ /dev/null @@ -1,26 +0,0 @@ -import BaseApi from './base'; - -class PrivateHelper extends BaseApi { - setSelected(selected) { - this.store.handleEvent({ - data: { - local: { - selected: selected - } - } - }); - } - -} - -export default class GlobalApi { - constructor(ship, channel, store) { - const helper = new PrivateHelper(ship, channel, store); - - this.ship = ship; - this.subscribe = helper.subscribe.bind(helper); - - this.setSelected = helper.setSelected.bind(helper); - } -} - diff --git a/pkg/interface/src/api/global.ts b/pkg/interface/src/api/global.ts new file mode 100644 index 0000000000..9a06e48b5c --- /dev/null +++ b/pkg/interface/src/api/global.ts @@ -0,0 +1,31 @@ +import { Patp } from '../types/noun'; +import BaseApi from './base'; +import ChatApi from './chat'; +import { StoreState } from '../store/type'; +import GlobalStore from '../store/store'; +import LocalApi from './local'; +import InviteApi from './invite'; +import MetadataApi from './metadata'; +import ContactsApi from './contacts'; +import GroupsApi from './groups'; +import LaunchApi from './launch'; +import LinksApi from './links'; +import PublishApi from './publish'; + +export default class GlobalApi extends BaseApi { + chat = new ChatApi(this.ship, this.channel, this.store); + local = new LocalApi(this.ship, this.channel, this.store); + invite = new InviteApi(this.ship, this.channel, this.store); + metadata = new MetadataApi(this.ship, this.channel, this.store); + contacts = new ContactsApi(this.ship, this.channel, this.store); + groups = new GroupsApi(this.ship, this.channel, this.store); + launch = new LaunchApi(this.ship, this.channel, this.store); + links = new LinksApi(this.ship, this.channel, this.store); + publish = new PublishApi(this.ship, this.channel, this.store); + + + constructor(public ship: Patp, public channel: any, public store: GlobalStore) { + super(ship,channel,store); + } +} + diff --git a/pkg/interface/src/api/groups.js b/pkg/interface/src/api/groups.ts similarity index 73% rename from pkg/interface/src/api/groups.js rename to pkg/interface/src/api/groups.ts index a735201c83..73ed398c42 100644 --- a/pkg/interface/src/api/groups.js +++ b/pkg/interface/src/api/groups.ts @@ -1,37 +1,19 @@ import BaseApi from './base'; +import { StoreState } from '../store/type'; +import { Path, Patp } from '../types/noun'; -export default class GroupsApi { - constructor(ship, channel, store) { - const helper = new PrivateHelper(ship, channel, store); +export default class GroupsApi extends BaseApi { + add(path: Path, ships: Patp[] = []) { + return this.action('group-store', 'group-action', { + add: { members: ships, path } + }); + } - this.ship = ship; - this.subscribe = helper.subscribe.bind(helper); - - this.contactHook = { - edit: helper.contactEdit.bind(helper) - }; - - this.contactView = { - create: helper.contactCreate.bind(helper), - delete: helper.contactDelete.bind(helper), - remove: helper.contactRemove.bind(helper), - share: helper.contactShare.bind(helper) - }; - - this.group = { - add: helper.groupAdd.bind(helper), - remove: helper.groupRemove.bind(helper) - }; - - this.metadata = { - add: helper.metadataAdd.bind(helper) - }; - - this.invite = { - accept: helper.inviteAccept.bind(helper), - decline: helper.inviteDecline.bind(helper) - }; + remove(path: Path, ships: Patp[] = []) { + return this.action('group-store', 'group-action', { + remove: { members: ships, path } + }); } } @@ -51,17 +33,9 @@ class PrivateHelper extends BaseApi { }); } - groupAdd(path, ships = []) { - return this.action('group-store', 'group-action', { - add: { members: ships, path } - }); - } - groupRemove(path, ships) { - return this.action('group-store', 'group-action', { - remove: { members: ships, path } - }); - } + + contactShare(recipient, path, ship, contact) { return this.contactViewAction({ diff --git a/pkg/interface/src/api/invite.ts b/pkg/interface/src/api/invite.ts new file mode 100644 index 0000000000..0e81ffec35 --- /dev/null +++ b/pkg/interface/src/api/invite.ts @@ -0,0 +1,27 @@ +import BaseApi from "./base"; +import { StoreState } from "../store/type"; +import { Serial, Path } from "../types/noun"; + +export default class InviteApi extends BaseApi { + accept(app: Path, uid: Serial) { + return this.inviteAction({ + accept: { + path: app, + uid + } + }); + } + + decline(app: Path, uid: Serial) { + return this.inviteAction({ + decline: { + path: app, + uid + } + }); + } + + private inviteAction(action) { + return this.action('invite-store', 'json', action); + } +} diff --git a/pkg/interface/src/api/launch.js b/pkg/interface/src/api/launch.js deleted file mode 100644 index 214e1ee9e1..0000000000 --- a/pkg/interface/src/api/launch.js +++ /dev/null @@ -1,51 +0,0 @@ -import BaseApi from './base'; - -class PrivateHelper extends BaseApi { - launchAction(data) { - this.action('launch', 'launch-action', data); - } - - launchAdd(name, tile = { basic : { title: '', linkedUrl: '', iconUrl: '' }}) { - this.launchAction({ add: { name, tile } }); - } - - launchRemove(name) { - this.launchAction({ remove: name }); - } - - launchChangeOrder(orderedTiles = []) { - this.launchAction({ 'change-order': orderedTiles }); - } - - launchChangeFirstTime(firstTime = true) { - this.launchAction({ 'change-first-time': firstTime }); - } - - launchChangeIsShown(name, isShown = true) { - this.launchAction({ 'change-is-shown': { name, isShown }}); - } - - weatherAction(latlng) { - this.action('weather', 'json', latlng); - } -} - -export default class LaunchApi { - constructor(ship, channel, store) { - const helper = new PrivateHelper(ship, channel, store); - - this.ship = ship; - this.subscribe = helper.subscribe.bind(helper); - - this.launch = { - add: helper.launchAdd.bind(helper), - remove: helper.launchRemove.bind(helper), - changeOrder: helper.launchChangeOrder.bind(helper), - changeFirstTime: helper.launchChangeFirstTime.bind(helper), - changeIsShown: helper.launchChangeIsShown.bind(helper) - }; - - this.weather = helper.weatherAction.bind(helper); - } -} - diff --git a/pkg/interface/src/api/launch.ts b/pkg/interface/src/api/launch.ts new file mode 100644 index 0000000000..1e6fa4a33a --- /dev/null +++ b/pkg/interface/src/api/launch.ts @@ -0,0 +1,36 @@ +import BaseApi from './base'; +import { StoreState } from '../store/type'; + + +export default class LaunchApi extends BaseApi { + + add(name: string, tile = { basic : { title: '', linkedUrl: '', iconUrl: '' }}) { + this.launchAction({ add: { name, tile } }); + } + + remove(name: string) { + this.launchAction({ remove: name }); + } + + changeOrder(orderedTiles = []) { + this.launchAction({ 'change-order': orderedTiles }); + } + + changeFirstTime(firstTime = true) { + this.launchAction({ 'change-first-time': firstTime }); + } + + changeIsShown(name: string, isShown = true) { + this.launchAction({ 'change-is-shown': { name, isShown }}); + } + + weather(latlng: any) { + this.action('weather', 'json', latlng); + } + + private launchAction(data) { + this.action('launch', 'launch-action', data); + } + +} + diff --git a/pkg/interface/src/api/links.js b/pkg/interface/src/api/links.js deleted file mode 100644 index 683a3d0692..0000000000 --- a/pkg/interface/src/api/links.js +++ /dev/null @@ -1,222 +0,0 @@ -import { stringToTa } from '../lib/util'; - -import BaseApi from './base'; - -export default class LinksApi extends BaseApi { - constructor(ship, channel, store) { - super(ship, channel, store); - this.ship = ship; - - this.invite = { - accept: this.inviteAccept.bind(this), - decline: this.inviteDecline.bind(this) - }; - - this.groups = { - remove: this.groupRemove.bind(this) - }; - - this.fetchLink = this.fetchLink.bind(this); - } - - fetchLink(path, result, fail, quit) { - this.subscribe.bind(this)( - path, - 'PUT', - this.ship, - 'link-view', - result, - fail, - quit - ); - } - - groupsAction(data) { - this.action('group-store', 'group-action', data); - } - - groupRemove(path, members) { - this.groupsAction({ - remove: { - path, - members - } - }); - } - - inviteAction(data) { - this.action('invite-store', 'json', data); - } - - inviteAccept(uid) { - this.inviteAction({ - accept: { - path: '/link', - uid - } - }); - } - - inviteDecline(uid) { - this.inviteAction({ - decline: { - path: '/link', - uid - } - }); - } - - getCommentsPage(path, url, page) { - const strictUrl = stringToTa(url); - const endpoint = '/json/' + page + '/discussions/' + strictUrl + path; - this.fetchLink( - endpoint, - (res) => { - if (res.data['initial-discussions']) { - // these aren't returned with the response, - // so this ensures the reducers know them. - res.data['initial-discussions'].path = path; - res.data['initial-discussions'].url = url; - } - this.store.handleEvent(res); - }, - console.error, - () => {} // no-op on quit - ); - } - - getPage(path, page) { - const endpoint = '/json/' + page + '/submissions' + path; - this.fetchLink( - endpoint, - (dat) => { - this.store.handleEvent(dat); - }, - console.error, - () => {} // no-op on quit - ); - } - - getSubmission(path, url, callback) { - const strictUrl = stringToTa(url); - const endpoint = '/json/0/submission/' + strictUrl + path; - this.fetchLink( - endpoint, - (res) => { - if (res.data.submission) { - callback(res.data.submission); - } else { - console.error('unexpected submission response', res); - } - }, - console.error, - () => {} // no-op on quit - ); - } - - linkViewAction(data) { - return this.action('link-view', 'link-view-action', data); - } - - createCollection(path, title, description, members, realGroup) { - // members is either {group:'/group-path'} or {'ships':[~zod]}, - // with realGroup signifying if ships should become a managed group or not. - return this.linkViewAction({ - create: { path, title, description, members, realGroup } - }); - } - - deleteCollection(path) { - return this.linkViewAction({ - delete: { path } - }); - } - - inviteToCollection(path, ships) { - return this.linkViewAction({ - invite: { path, ships } - }); - } - - linkListenAction(data) { - return this.action('link-listen-hook', 'link-listen-action', data); - } - - joinCollection(path) { - return this.linkListenAction({ watch: path }); - } - - removeCollection(path) { - return this.linkListenAction({ leave: path }); - } - - linkAction(data) { - return this.action('link-store', 'link-action', data); - } - - postLink(path, url, title) { - return this.linkAction({ - save: { path, url, title } - }); - } - - postComment(path, url, comment) { - return this.linkAction({ - note: { path, url, udon: comment } - }); - } - - // leave url as null to mark all under path as read - seenLink(path, url = null) { - return this.linkAction({ - seen: { path, url } - }); - } - - metadataAction(data) { - return this.action('metadata-hook', 'metadata-action', data); - } - - metadataAdd(appPath, groupPath, title, description, dateCreated, color) { - return this.metadataAction({ - add: { - 'group-path': groupPath, - resource: { - 'app-path': appPath, - 'app-name': 'link' - }, - metadata: { - title, - description, - color, - 'date-created': dateCreated, - creator: `~${window.ship}` - } - } - }); - } - - sidebarToggle() { - let sidebarBoolean = true; - if (this.store.state.sidebarShown === true) { - sidebarBoolean = false; - } - this.store.handleEvent({ - data: { - local: { - sidebarToggle: sidebarBoolean - } - } - }); - } - - setSelected(selected) { - this.store.handleEvent({ - data: { - local: { - selected: selected - } - } - }); - } -} diff --git a/pkg/interface/src/api/links.ts b/pkg/interface/src/api/links.ts new file mode 100644 index 0000000000..de4af1e904 --- /dev/null +++ b/pkg/interface/src/api/links.ts @@ -0,0 +1,131 @@ +import { stringToTa } from '../lib/util'; + +import BaseApi from './base'; +import { StoreState } from '../store/type'; +import { Path } from '../types/noun'; + +export default class LinksApi extends BaseApi { + + + getCommentsPage(path: Path, url: string, page: number) { + const strictUrl = stringToTa(url); + const endpoint = '/json/' + page + '/discussions/' + strictUrl + path; + this.fetchLink( + endpoint, + (res) => { + if (res.data['link-update']['initial-discussions']) { + // these aren't returned with the response, + // so this ensures the reducers know them. + res.data['link-update']['initial-discussions'].path = path; + res.data['link-update']['initial-discussions'].url = url; + } + this.store.handleEvent(res); + }, + console.error, + () => {} // no-op on quit + ); + } + + getPage(path: Path, page: number) { + const endpoint = '/json/' + page + '/submissions' + path; + this.fetchLink( + endpoint, + (dat) => { + this.store.handleEvent(dat); + }, + console.error, + () => {} // no-op on quit + ); + } + + getSubmission(path: Path, url: string, callback) { + const strictUrl = stringToTa(url); + const endpoint = '/json/0/submission/' + strictUrl + path; + this.fetchLink( + endpoint, + (res) => { + if (res.data.submission) { + callback(res.data.submission); + } else { + console.error('unexpected submission response', res); + } + }, + console.error, + () => {} // no-op on quit + ); + } + + + + createCollection(path, title, description, members, realGroup) { + // members is either {group:'/group-path'} or {'ships':[~zod]}, + // with realGroup signifying if ships should become a managed group or not. + return this.viewAction({ + create: { path, title, description, members, realGroup } + }); + } + + deleteCollection(path) { + return this.viewAction({ + delete: { path } + }); + } + + inviteToCollection(path, ships) { + return this.viewAction({ + invite: { path, ships } + }); + } + + joinCollection(path) { + return this.linkListenAction({ watch: path }); + } + + removeCollection(path) { + return this.linkListenAction({ leave: path }); + } + + + postLink(path: Path, url: string, title: string) { + return this.linkAction({ + save: { path, url, title } + }); + } + + postComment(path: Path, url: string, comment: string) { + return this.linkAction({ + note: { path, url, udon: comment } + }); + } + + // leave url as null to mark all under path as read + seenLink(path: Path, url?: string) { + return this.linkAction({ + seen: { path, url: url || null } + }); + } + + private linkAction(data) { + return this.action('link-store', 'link-action', data); + } + + private viewAction(data) { + return this.action('link-view', 'link-view-action', data); + } + + private linkListenAction(data) { + return this.action('link-listen-hook', 'link-listen-action', data); + } + + private fetchLink(path: Path, result, fail, quit) { + this.subscribe.bind(this)( + path, + 'PUT', + this.ship, + 'link-view', + result, + fail, + quit + ); + } +} diff --git a/pkg/interface/src/api/local.ts b/pkg/interface/src/api/local.ts new file mode 100644 index 0000000000..9ae9716d08 --- /dev/null +++ b/pkg/interface/src/api/local.ts @@ -0,0 +1,28 @@ +import BaseApi from "./base"; +import { StoreState } from "../store/type"; +import { SelectedGroup } from "../types/local-update"; + + + +export default class LocalApi extends BaseApi { + setSelected(selected: SelectedGroup[]) { + this.store.handleEvent({ + data: { + local: { + selected + } + } + }) + } + + sidebarToggle() { + this.store.handleEvent({ + data: { + local: { + sidebarToggle: true + } + } + }) + } + +} diff --git a/pkg/interface/src/api/metadata.ts b/pkg/interface/src/api/metadata.ts new file mode 100644 index 0000000000..723abb9b19 --- /dev/null +++ b/pkg/interface/src/api/metadata.ts @@ -0,0 +1,31 @@ + +import BaseApi from './base'; +import { StoreState } from '../store/type'; +import { Path, Patp } from '../types/noun'; + +export default class MetadataApi extends BaseApi { + + metadataAdd(appName: string, appPath: Path, groupPath: Path, title: string, description: string, dateCreated: string, color: string) { + const creator = `~${this.ship}`; + return this.metadataAction({ + add: { + 'group-path': groupPath, + resource: { + 'app-path': appPath, + 'app-name': appName + }, + metadata: { + title, + description, + color, + 'date-created': dateCreated, + creator + } + } + }); + } + + private metadataAction(data) { + return this.action('metadata-hook', 'metadata-action', data); + } +} diff --git a/pkg/interface/src/api/publish.js b/pkg/interface/src/api/publish.ts similarity index 71% rename from pkg/interface/src/api/publish.js rename to pkg/interface/src/api/publish.ts index 68480118ba..4b60e66a10 100644 --- a/pkg/interface/src/api/publish.js +++ b/pkg/interface/src/api/publish.ts @@ -1,7 +1,10 @@ import BaseApi from './base'; +import { PublishResponse } from '../types/publish-response'; +import { PatpNoSig } from '../types/noun'; +import { BookId, NoteId } from '../types/publish-update'; export default class PublishApi extends BaseApi { - handleEvent(data) { + handleEvent(data: PublishResponse) { this.store.handleEvent({ data: { 'publish-response' : data } }); } @@ -16,7 +19,7 @@ export default class PublishApi extends BaseApi { }); } - fetchNotebook(host, book) { + fetchNotebook(host: PatpNoSig, book: BookId) { fetch(`/publish-view/${host}/${book}.json`) .then(response => response.json()) .then((json) => { @@ -29,7 +32,7 @@ export default class PublishApi extends BaseApi { }); } - fetchNote(host, book, note) { + fetchNote(host: PatpNoSig, book: BookId, note: NoteId) { fetch(`/publish-view/${host}/${book}/${note}.json`) .then(response => response.json()) .then((json) => { @@ -43,7 +46,7 @@ export default class PublishApi extends BaseApi { }); } - fetchNotesPage(host, book, start, length) { + fetchNotesPage(host: PatpNoSig, book: BookId, start: number, length: number) { fetch(`/publish-view/notes/${host}/${book}/${start}/${length}.json`) .then(response => response.json()) .then((json) => { @@ -58,7 +61,7 @@ export default class PublishApi extends BaseApi { }); } - fetchCommentsPage(host, book, note, start, length) { + fetchCommentsPage(host: PatpNoSig, book: BookId, note: NoteId, start: number, length: number) { fetch(`/publish-view/comments/${host}/${book}/${note}/${start}/${length}.json`) .then(response => response.json()) .then((json) => { @@ -74,30 +77,8 @@ export default class PublishApi extends BaseApi { }); } - groupAction(act) { - return this.action('group-store', 'group-action', act); - } - - inviteAction(act) { - return this.action('invite-store', 'invite-action', act); - } - - publishAction(act) { + publishAction(act: any) { return this.action('publish', 'publish-action', act); } - - sidebarToggle() { - let sidebarBoolean = true; - if (this.store.state.sidebarShown === true) { - sidebarBoolean = false; - } - this.store.handleEvent({ - data: { - local: { - sidebarToggle: sidebarBoolean - } - } - }); - } } diff --git a/pkg/interface/src/apps/chat/app.js b/pkg/interface/src/apps/chat/app.tsx similarity index 65% rename from pkg/interface/src/apps/chat/app.js rename to pkg/interface/src/apps/chat/app.tsx index 675910546f..371912ef6d 100644 --- a/pkg/interface/src/apps/chat/app.js +++ b/pkg/interface/src/apps/chat/app.tsx @@ -1,11 +1,6 @@ import React from 'react'; import { Route, Switch } from 'react-router-dom'; -import ChatApi from '../../api/chat'; -import ChatStore from '../../store/chat'; -import ChatSubscription from '../../subscription/chat'; - - import './css/custom.css'; import { Skeleton } from './components/skeleton'; @@ -16,19 +11,22 @@ import { SettingsScreen } from './components/settings'; import { NewScreen } from './components/new'; import { JoinScreen } from './components/join'; import { NewDmScreen } from './components/new-dm'; +import { PatpNoSig } from '../../types/noun'; +import GlobalApi from '../../api/global'; +import { StoreState } from '../../store/type'; +import GlobalSubscription from '../../subscription/global'; + +type ChatAppProps = StoreState & { + ship: PatpNoSig; + api: GlobalApi; + subscription: GlobalSubscription; +}; + +export default class ChatApp extends React.Component { + totalUnreads = 0; -export default class ChatApp extends React.Component { constructor(props) { super(props); - this.store = new ChatStore(); - this.state = this.store.state; - this.totalUnreads = 0; - this.resetControllers(); - } - - resetControllers() { - this.api = null; - this.subscription = null; } componentDidMount() { @@ -36,33 +34,31 @@ export default class ChatApp extends React.Component { // preload spinner asset new Image().src = '/~landscape/img/Spinner.png'; - this.store.setStateHandler(this.setState.bind(this)); - const channel = new this.props.channel(); - this.api = new ChatApi(this.props.ship, channel, this.store); + this.props.subscription.startApp('chat'); - this.subscription = new ChatSubscription(this.store, this.api, channel); - this.subscription.start(); + if (!this.props.sidebarShown) { + this.props.api.local.sidebarToggle(); + } } componentWillUnmount() { - this.subscription.delete(); - this.store.clear(); - this.store.setStateHandler(() => {}); - this.resetControllers(); + this.props.subscription.stopApp('chat'); } render() { - const { state, props } = this; + const { props } = this; const messagePreviews = {}; const unreads = {}; let totalUnreads = 0; const selectedGroups = props.selectedGroups ? props.selectedGroups : []; - const associations = state.associations ? state.associations : { chat: {}, contacts: {} }; + const associations = props.associations + ? props.associations + : { chat: {}, contacts: {} }; - Object.keys(state.inbox).forEach((stat) => { - const envelopes = state.inbox[stat].envelopes; + Object.keys(props.inbox).forEach((stat) => { + const envelopes = props.inbox[stat].envelopes; if (envelopes.length === 0) { messagePreviews[stat] = false; @@ -70,37 +66,54 @@ export default class ChatApp extends React.Component { messagePreviews[stat] = envelopes[0]; } - const unread = Math.max(state.inbox[stat].config.length - state.inbox[stat].config.read, 0); + const unread = Math.max( + props.inbox[stat].config.length - props.inbox[stat].config.read, + 0 + ); unreads[stat] = Boolean(unread); - if (unread && - (selectedGroups.length === 0 || selectedGroups.map(((e) => { - return e[0]; - })).includes(associations.chat?.[stat]?.['group-path']) || - associations.chat?.[stat]?.['group-path'].startsWith('/~/'))) { - totalUnreads += unread; + if ( + unread && + (selectedGroups.length === 0 || + selectedGroups + .map((e) => { + return e[0]; + }) + .includes(associations.chat?.[stat]?.['group-path']) || + associations.chat?.[stat]?.['group-path'].startsWith('/~/')) + ) { + totalUnreads += unread; } }); if (totalUnreads !== this.totalUnreads) { - document.title = totalUnreads > 0 ? `OS1 - Chat (${totalUnreads})` : 'OS1 - Chat'; + document.title = + totalUnreads > 0 ? `OS1 - Chat (${totalUnreads})` : 'OS1 - Chat'; this.totalUnreads = totalUnreads; } - const invites = state.invites ? state.invites : { '/chat': {}, '/contacts': {} }; + const { + invites, + s3, + sidebarShown, + inbox, + contacts, + permissions, + chatSynced, + api, + chatInitialized, + pendingMessages + } = props; - const contacts = state.contacts ? state.contacts : {}; - const s3 = state.s3 ? state.s3 : {}; - - const renderChannelSidebar = (props, station) => ( + const renderChannelSidebar = (props, station?) => ( @@ -117,14 +130,14 @@ export default class ChatApp extends React.Component { associations={associations} invites={invites} chatHideonMobile={true} - sidebarShown={state.sidebarShown} + sidebarShown={sidebarShown} sidebar={renderChannelSidebar(props)} >

Select, create, or join a chat to begin. -

+

@@ -143,15 +156,15 @@ export default class ChatApp extends React.Component { invites={invites} sidebarHideOnMobile={true} sidebar={renderChannelSidebar(props)} - sidebarShown={state.sidebarShown} + sidebarShown={sidebarShown} > @@ -169,15 +182,15 @@ export default class ChatApp extends React.Component { invites={invites} sidebarHideOnMobile={true} sidebar={renderChannelSidebar(props)} - sidebarShown={state.sidebarShown} + sidebarShown={sidebarShown} > @@ -188,8 +201,7 @@ export default class ChatApp extends React.Component { exact path="/~chat/join/(~)?/:ship?/:station?" render={(props) => { - let station = - `/${props.match.params.ship}/${props.match.params.station}`; + let station = `/${props.match.params.ship}/${props.match.params.station}`; const sig = props.match.url.includes('/~/'); if (sig) { station = '/~' + station; @@ -201,13 +213,13 @@ export default class ChatApp extends React.Component { invites={invites} sidebarHideOnMobile={true} sidebar={renderChannelSidebar(props)} - sidebarShown={state.sidebarShown} + sidebarShown={sidebarShown} > @@ -218,13 +230,12 @@ export default class ChatApp extends React.Component { exact path="/~chat/(popout)?/room/(~)?/:ship/:station+" render={(props) => { - let station = - `/${props.match.params.ship}/${props.match.params.station}`; + let station = `/${props.match.params.ship}/${props.match.params.station}`; const sig = props.match.url.includes('/~/'); if (sig) { station = '/~' + station; } - const mailbox = state.inbox[station] || { + const mailbox = inbox[station] || { config: { read: 0, length: 0 @@ -235,11 +246,11 @@ export default class ChatApp extends React.Component { let roomContacts = {}; const associatedGroup = station in associations['chat'] && - 'group-path' in associations.chat[station] + 'group-path' in associations.chat[station] ? associations.chat[station]['group-path'] : ''; - if ((associations.chat[station]) && (associatedGroup in contacts)) { + if (associations.chat[station] && associatedGroup in contacts) { roomContacts = contacts[associatedGroup]; } @@ -247,10 +258,12 @@ export default class ChatApp extends React.Component { station in associations['chat'] ? associations.chat[station] : {}; const permission = - station in state.permissions ? state.permissions[station] : { - who: new Set([]), - kind: 'white' - }; + station in permissions + ? permissions[station] + : { + who: new Set([]), + kind: 'white' + }; const popout = props.match.url.includes('/popout/'); return ( @@ -259,26 +272,25 @@ export default class ChatApp extends React.Component { invites={invites} sidebarHideOnMobile={true} popout={popout} - sidebarShown={state.sidebarShown} + sidebarShown={sidebarShown} sidebar={renderChannelSidebar(props, station)} > @@ -295,7 +307,7 @@ export default class ChatApp extends React.Component { station = '/~' + station; } - const permission = state.permissions[station] || { + const permission = permissions[station] || { kind: '', who: new Set([]) }; @@ -309,20 +321,20 @@ export default class ChatApp extends React.Component { associations={associations} invites={invites} sidebarHideOnMobile={true} - sidebarShown={state.sidebarShown} + sidebarShown={sidebarShown} popout={popout} sidebar={renderChannelSidebar(props, station)} > ); @@ -332,8 +344,7 @@ export default class ChatApp extends React.Component { exact path="/~chat/(popout)?/settings/(~)?/:ship/:station+" render={(props) => { - let station = - `/${props.match.params.ship}/${props.match.params.station}`; + let station = `/${props.match.params.ship}/${props.match.params.station}`; const sig = props.match.url.includes('/~/'); if (sig) { station = '/~' + station; @@ -341,7 +352,7 @@ export default class ChatApp extends React.Component { const popout = props.match.url.includes('/popout/'); - const permission = state.permissions[station] || { + const permission = permissions[station] || { kind: '', who: new Set([]) }; @@ -355,7 +366,7 @@ export default class ChatApp extends React.Component { invites={invites} sidebarHideOnMobile={true} popout={popout} - sidebarShown={state.sidebarShown} + sidebarShown={sidebarShown} sidebar={renderChannelSidebar(props, station)} > ); }} /> - ); + ); } } diff --git a/pkg/interface/src/apps/chat/components/chat.js b/pkg/interface/src/apps/chat/components/chat.tsx similarity index 56% rename from pkg/interface/src/apps/chat/components/chat.js rename to pkg/interface/src/apps/chat/components/chat.tsx index 4662758cc6..cd943f2ef6 100644 --- a/pkg/interface/src/apps/chat/components/chat.js +++ b/pkg/interface/src/apps/chat/components/chat.tsx @@ -1,19 +1,26 @@ -import React, { Component } from 'react'; -import _ from 'lodash'; -import moment from 'moment'; +import React, { Component } from "react"; +import _ from "lodash"; +import moment from "moment"; -import { Link } from 'react-router-dom'; +import { Link, RouteComponentProps } from "react-router-dom"; -import { ResubscribeElement } from './lib/resubscribe-element'; -import { BacklogElement } from './lib/backlog-element'; -import { Message } from './lib/message'; -import { SidebarSwitcher } from '../../../components/SidebarSwitch'; -import { ChatTabBar } from './lib/chat-tabbar'; -import { ChatInput } from './lib/chat-input'; -import { UnreadNotice } from './lib/unread-notice'; -import { deSig } from '../../../lib/util'; +import { ResubscribeElement } from "./lib/resubscribe-element"; +import { BacklogElement } from "./lib/backlog-element"; +import { Message } from "./lib/message"; +import { SidebarSwitcher } from "../../../components/SidebarSwitch"; +import { ChatTabBar } from "./lib/chat-tabbar"; +import { ChatInput } from "./lib/chat-input"; +import { UnreadNotice } from "./lib/unread-notice"; +import { deSig } from "../../../lib/util"; +import { ChatHookUpdate } from "../../../types/chat-hook-update"; +import ChatApi from "../../../api/chat"; +import { Inbox, Envelope } from "../../../types/chat-update"; +import { Contacts } from "../../../types/contact-update"; +import { Path, Patp } from "../../../types/noun"; +import GlobalApi from "../../../api/global"; +import { Association } from "../../../types/metadata-update"; -function getNumPending(props) { +function getNumPending(props: any) { const result = props.pendingMessages.has(props.station) ? props.pendingMessages.get(props.station).length : 0; @@ -25,26 +32,32 @@ const DEFAULT_BACKLOG_SIZE = 300; const MAX_BACKLOG_SIZE = 1000; function scrollIsAtTop(container) { - if ((navigator.userAgent.includes("Safari") && + if ( + (navigator.userAgent.includes("Safari") && navigator.userAgent.includes("Chrome")) || - navigator.userAgent.includes("Firefox") + navigator.userAgent.includes("Firefox") ) { return container.scrollTop === 0; } else if (navigator.userAgent.includes("Safari")) { - return container.scrollHeight + Math.round(container.scrollTop) <= - container.clientHeight + 10; + return ( + container.scrollHeight + Math.round(container.scrollTop) <= + container.clientHeight + 10 + ); } else { return false; } } function scrollIsAtBottom(container) { - if ((navigator.userAgent.includes("Safari") && + if ( + (navigator.userAgent.includes("Safari") && navigator.userAgent.includes("Chrome")) || - navigator.userAgent.includes("Firefox") + navigator.userAgent.includes("Firefox") ) { - return container.scrollHeight - Math.round(container.scrollTop) <= - container.clientHeight + 10; + return ( + container.scrollHeight - Math.round(container.scrollTop) <= + container.clientHeight + 10 + ); } else if (navigator.userAgent.includes("Safari")) { return container.scrollTop === 0; } else { @@ -52,7 +65,50 @@ function scrollIsAtBottom(container) { } } -export class ChatScreen extends Component { +type IMessage = Envelope & { pending?: boolean }; + +type ChatScreenProps = RouteComponentProps<{ + ship: Patp; + station: string; +}> & { + chatSynced: ChatHookUpdate; + station: any; + association: Association; + api: GlobalApi; + read: number; + length: number; + inbox: Inbox; + contacts: Contacts; + permission: any; + pendingMessages: Map; + s3: any; + popout: boolean; + sidebarShown: boolean; + chatInitialized: boolean; + envelopes: Envelope[]; +}; + +interface ChatScreenState { + numPages: number; + scrollLocked: boolean; + read: number; + active: boolean; + lastScrollHeight: number | null; +} + +export class ChatScreen extends Component { + hasAskedForMessages = false; + lastNumPending = 0; + + scrollContainer: HTMLElement | null = null; + + unreadMarker = null; + scrolledToMarker = false; + + activityTimeout: NodeJS.Timeout | null = null; + + scrollElement: HTMLElement | null = null; + constructor(props) { super(props); @@ -65,29 +121,22 @@ export class ChatScreen extends Component { lastScrollHeight: null, }; - this.hasAskedForMessages = false; - this.lastNumPending = 0; - - this.scrollContainer = null; this.onScroll = this.onScroll.bind(this); - this.unreadMarker = null; - this.scrolledToMarker = false; this.setUnreadMarker = this.setUnreadMarker.bind(this); - this.activityTimeout = true; this.handleActivity = this.handleActivity.bind(this); this.setInactive = this.setInactive.bind(this); - moment.updateLocale('en', { + moment.updateLocale("en", { calendar: { - sameDay: '[Today]', - nextDay: '[Tomorrow]', - nextWeek: 'dddd', - lastDay: '[Yesterday]', - lastWeek: '[Last] dddd', - sameElse: 'DD/MM/YYYY' - } + sameDay: "[Today]", + nextDay: "[Tomorrow]", + nextWeek: "dddd", + lastDay: "[Yesterday]", + lastWeek: "[Last] dddd", + sameElse: "DD/MM/YYYY", + }, }); } @@ -104,17 +153,17 @@ export class ChatScreen extends Component { document.removeEventListener("mousedown", this.handleActivity, false); document.removeEventListener("keypress", this.handleActivity, false); document.removeEventListener("touchmove", this.handleActivity, false); - if(this.activityTimeout) { + if (this.activityTimeout) { clearTimeout(this.activityTimeout); } } handleActivity() { - if(!this.state.active) { + if (!this.state.active) { this.setState({ active: true }); } - if(this.activityTimeout) { + if (this.activityTimeout) { clearTimeout(this.activityTimeout); } @@ -139,13 +188,13 @@ export class ChatScreen extends Component { const unreadUnloaded = unread - props.envelopes.length; const excessUnread = unreadUnloaded > MAX_BACKLOG_SIZE; - if(!excessUnread && unreadUnloaded + 20 > DEFAULT_BACKLOG_SIZE) { + if (!excessUnread && unreadUnloaded + 20 > DEFAULT_BACKLOG_SIZE) { this.askForMessages(unreadUnloaded + 20); } else { this.askForMessages(DEFAULT_BACKLOG_SIZE); } - if(excessUnread || props.read === props.length){ + if (excessUnread || props.read === props.length) { this.scrolledToMarker = true; this.setState( { @@ -156,7 +205,7 @@ export class ChatScreen extends Component { } ); } else { - this.setState({ scrollLocked: true, numPages: Math.ceil(unread/100) }); + this.setState({ scrollLocked: true, numPages: Math.ceil(unread / 100) }); } } @@ -168,34 +217,36 @@ export class ChatScreen extends Component { prevProps.match.params.ship !== props.match.params.ship ) { this.receivedNewChat(); - } else if (props.chatInitialized && - !(props.station in props.inbox) && - (Boolean(props.chatSynced) && !(props.station in props.chatSynced))) { - props.history.push('/~chat'); } else if ( - props.envelopes.length >= prevProps.envelopes.length + 10 + props.chatInitialized && + !(props.station in props.inbox) && + Boolean(props.chatSynced) && + !(props.station in props.chatSynced) ) { + props.history.push("/~chat"); + } else if (props.envelopes.length >= prevProps.envelopes.length + 10) { this.hasAskedForMessages = false; - } else if(props.length !== prevProps.length && - prevProps.length === prevState.read && - state.active + } else if ( + props.length !== prevProps.length && + prevProps.length === prevState.read && + state.active ) { this.setState({ read: props.length }); this.props.api.chat.read(this.props.station); } - if(!prevProps.chatInitialized && props.chatInitialized) { + if (!prevProps.chatInitialized && props.chatInitialized) { this.receivedNewChat(); } if ( - (props.length !== prevProps.length || - props.envelopes.length !== prevProps.envelopes.length || - getNumPending(props) !== this.lastNumPending || - state.numPages !== prevState.numPages) + props.length !== prevProps.length || + props.envelopes.length !== prevProps.envelopes.length || + getNumPending(props) !== this.lastNumPending || + state.numPages !== prevState.numPages ) { this.scrollToBottom(); - if(navigator.userAgent.includes("Firefox")) { + if (navigator.userAgent.includes("Firefox")) { this.recalculateScrollTop(); } @@ -219,7 +270,7 @@ export class ChatScreen extends Component { if (start > 0) { const end = start + size < props.length ? start + size : props.length; this.hasAskedForMessages = true; - props.subscription.fetchMessages(start + 1, end, props.station); + props.api.chat.fetchMessages(start + 1, end, props.station); } } @@ -231,31 +282,31 @@ export class ChatScreen extends Component { // Restore chat position on FF when new messages come in recalculateScrollTop() { - if(!this.scrollContainer) { + const { lastScrollHeight } = this.state; + if (!this.scrollContainer || !lastScrollHeight) { return; } - const { lastScrollHeight } = this.state; const target = this.scrollContainer; const newScrollTop = this.scrollContainer.scrollHeight - lastScrollHeight; - if(target.scrollTop !== 0 || newScrollTop === target.scrollTop) { + if (target.scrollTop !== 0 || newScrollTop === target.scrollTop) { return; } target.scrollTop = target.scrollHeight - lastScrollHeight; } onScroll(e) { - if(scrollIsAtTop(e.target)) { + if (scrollIsAtTop(e.target)) { // Save scroll position for FF - if (navigator.userAgent.includes('Firefox')) { + if (navigator.userAgent.includes("Firefox")) { this.setState({ - lastScrollHeight: e.target.scrollHeight + lastScrollHeight: e.target.scrollHeight, }); } this.setState( { numPages: this.state.numPages + 1, - scrollLocked: true + scrollLocked: true, }, () => { this.askForMessages(DEFAULT_BACKLOG_SIZE); @@ -265,21 +316,20 @@ export class ChatScreen extends Component { this.dismissUnread(); this.setState({ numPages: 1, - scrollLocked: false + scrollLocked: false, }); } } setUnreadMarker(ref) { - if(ref && !this.scrolledToMarker) { + if (ref && !this.scrolledToMarker) { this.setState({ scrollLocked: true }, () => { - ref.scrollIntoView({ block: 'center' }); - if(ref.offsetParent && - scrollIsAtBottom(ref.offsetParent)) { + ref.scrollIntoView({ block: "center" }); + if (ref.offsetParent && scrollIsAtBottom(ref.offsetParent)) { this.dismissUnread(); this.setState({ numPages: 1, - scrollLocked: false + scrollLocked: false, }); } }); @@ -298,38 +348,32 @@ export class ChatScreen extends Component { const { props, state } = this; - let messages = props.envelopes.slice(0); + let messages: IMessage[] = props.envelopes.slice(0); const lastMsgNum = messages.length > 0 ? messages.length : 0; if (messages.length > 100 * state.numPages) { messages = messages.slice(0, 100 * state.numPages); } - const pendingMessages = props.pendingMessages.has(props.station) - ? props.pendingMessages.get(props.station) - : []; - - pendingMessages.map((value) => { - return (value.pending = true); - }); + const pendingMessages: IMessage[] = ( + props.pendingMessages.get(props.station) || [] + ).map((value) => ({ ...value, pending: true })); messages = pendingMessages.concat(messages); const messageElements = messages.map((msg, i) => { // Render sigil if previous message is not by the same sender - const aut = ['author']; + const aut = ["author"]; const renderSigil = - _.get(messages[i + 1], aut) !== - _.get(msg, aut, msg.author); + _.get(messages[i + 1], aut) !== _.get(msg, aut, msg.author); const paddingTop = renderSigil; const paddingBot = - _.get(messages[i - 1], aut) !== - _.get(msg, aut, msg.author); + _.get(messages[i - 1], aut) !== _.get(msg, aut, msg.author); - const when = ['when']; + const when = ["when"]; const dayBreak = - moment(_.get(messages[i+1], when)).format('YYYY.MM.DD') !== - moment(_.get(messages[i], when)).format('YYYY.MM.DD'); + moment(_.get(messages[i + 1], when)).format("YYYY.MM.DD") !== + moment(_.get(messages[i], when)).format("YYYY.MM.DD"); const messageElem = ( ); - if(unread > 0 && i === unread - 1) { + if (unread > 0 && i === unread - 1) { return ( <> {messageElem} -
+

-

- New messages below -

+

New messages below


- { dayBreak && ( -

- {moment(_.get(messages[i], when)).calendar()} -

+ {dayBreak && ( +

+ {moment(_.get(messages[i], when)).calendar()} +

)} -
+
); - } else if(dayBreak) { + } else if (dayBreak) { return ( <> {messageElem} -
-

- {moment(_.get(messages[i], when)).calendar()} -

+
+

{moment(_.get(messages[i], when)).calendar()}

); @@ -378,47 +428,47 @@ export class ChatScreen extends Component { } }); - if (navigator.userAgent.includes('Firefox')) { + if (navigator.userAgent.includes("Firefox")) { return ( -
{ - this.scrollContainer = e; -}} +
{ + this.scrollContainer = e; + }} >
{ this.scrollElement = el; }} >
- {(props.chatInitialized && - !(props.station in props.inbox)) && ( - + {props.chatInitialized && !(props.station in props.inbox) && ( + + )} + {props.chatSynced && + !(props.station in props.chatSynced) && + messages.length > 0 ? ( + + ) : ( +
)} - {( - props.chatSynced && - !(props.station in props.chatSynced) && - (messages.length > 0) - ) ? ( - - ) : (
) - } {messageElements}
); -} else { + } else { return (
{ this.scrollElement = el; }} >
- {(props.chatInitialized && - !(props.station in props.inbox)) && ( - + {props.chatInitialized && !(props.station in props.inbox) && ( + + )} + {props.chatSynced && + !(props.station in props.chatSynced) && + messages.length > 0 ? ( + + ) : ( +
)} - {( - props.chatSynced && - !(props.station in props.chatSynced) && - (messages.length > 0) - ) ? ( - - ) : (
) - } {messageElements}
); -} + } } render() { @@ -457,16 +505,16 @@ ref={(e) => { const group = Array.from(props.permission.who.values()); - const isinPopout = props.popout ? 'popout/' : ''; + const isinPopout = props.popout ? "popout/" : ""; - const ownerContact = (window.ship in props.contacts) - ? props.contacts[window.ship] : false; + const ownerContact = + window.ship in props.contacts ? props.contacts[window.ship] : false; let title = props.station.substr(1); - if (props.association && 'metadata' in props.association) { + if (props.association && "metadata" in props.association) { title = - props.association.metadata.title !== '' + props.association.metadata.title !== "" ? props.association.metadata.title : props.station.substr(1); } @@ -475,8 +523,8 @@ ref={(e) => { const unreadMsg = unread > 0 && messages[unread - 1]; - - const showUnreadNotice = props.length !== props.read && props.read === state.read; + const showUnreadNotice = + props.length !== props.read && props.read === state.read; return (
{ >
- {'⟵ All Chats'} + {"⟵ All Chats"}
{ popout={props.popout} api={props.api} /> -

{title}

@@ -520,13 +573,13 @@ ref={(e) => { api={props.api} />
- { !!unreadMsg && showUnreadNotice && ( + {!!unreadMsg && showUnreadNotice && ( this.dismissUnread()} /> - ) } + )} {this.chatWindow(unread)} props.api.chatView.join(ship, station, true)); + }, () => props.api.chat.join(ship, station, true)); } if (state.station in props.inbox || @@ -78,7 +78,7 @@ export class JoinScreen extends Component { station, awaiting: true }, () => { - props.api.chatView.join(ship, station, true); + props.api.chat.join(ship, station, true); }); } diff --git a/pkg/interface/src/apps/chat/components/lib/resubscribe-element.js b/pkg/interface/src/apps/chat/components/lib/resubscribe-element.js index 1209008cca..61186a3751 100644 --- a/pkg/interface/src/apps/chat/components/lib/resubscribe-element.js +++ b/pkg/interface/src/apps/chat/components/lib/resubscribe-element.js @@ -2,7 +2,7 @@ import React, { Component } from 'react'; export class ResubscribeElement extends Component { onClickResubscribe() { - this.props.api.chatHook.addSynced( + this.props.api.chat.addSynced( this.props.host, this.props.station, true); diff --git a/pkg/interface/src/apps/chat/components/lib/sidebar-invite.js b/pkg/interface/src/apps/chat/components/lib/sidebar-invite.js index eca773d36e..de914c2552 100644 --- a/pkg/interface/src/apps/chat/components/lib/sidebar-invite.js +++ b/pkg/interface/src/apps/chat/components/lib/sidebar-invite.js @@ -2,11 +2,11 @@ import React, { Component } from 'react'; export class SidebarInvite extends Component { onAccept() { - this.props.api.invite.accept(this.props.uid); + this.props.api.invite.accept('/chat', this.props.uid); } onDecline() { - this.props.api.invite.decline(this.props.uid); + this.props.api.invite.decline('/chat', this.props.uid); } render() { diff --git a/pkg/interface/src/apps/chat/components/new-dm.js b/pkg/interface/src/apps/chat/components/new-dm.js index 4c63603d5d..72b384e748 100644 --- a/pkg/interface/src/apps/chat/components/new-dm.js +++ b/pkg/interface/src/apps/chat/components/new-dm.js @@ -63,7 +63,7 @@ export class NewDmScreen extends Component { }, () => { const groupPath = station; - props.api.chatView.create( + props.api.chat.create( `~${window.ship} <-> ~${state.ship}`, '', station, diff --git a/pkg/interface/src/apps/chat/components/new.js b/pkg/interface/src/apps/chat/components/new.js index d52c31e7c8..d6ba81b842 100644 --- a/pkg/interface/src/apps/chat/components/new.js +++ b/pkg/interface/src/apps/chat/components/new.js @@ -146,7 +146,7 @@ export class NewScreen extends Component { if (state.groups.length > 0) { groupPath = state.groups[0]; } - const submit = props.api.chatView.create( + const submit = props.api.chat.create( state.title, state.description, appPath, diff --git a/pkg/interface/src/apps/chat/components/settings.js b/pkg/interface/src/apps/chat/components/settings.js index 804ceebcca..9eee56b0a0 100644 --- a/pkg/interface/src/apps/chat/components/settings.js +++ b/pkg/interface/src/apps/chat/components/settings.js @@ -108,7 +108,8 @@ export class SettingsScreen extends Component { if (chatOwner) { this.setState({ awaiting: true, type: 'Editing chat...' }, (() => { - props.api.metadata.add( + props.api.metadata.metadataAdd( + 'chat', association['app-path'], association['group-path'], association.metadata.title, @@ -133,7 +134,7 @@ export class SettingsScreen extends Component { ? 'Deleting chat...' : 'Leaving chat...' }, (() => { - props.api.chatView.delete(props.station); + props.api.chat.delete(props.station); })); } @@ -145,7 +146,7 @@ export class SettingsScreen extends Component { awaiting: true, type: 'Converting chat...' }, (() => { - props.api.chatView.groupify( + props.api.chat.groupify( props.station, state.targetGroup, state.inclusive ).then(() => this.setState({ awaiting: false })); })); @@ -278,7 +279,8 @@ export class SettingsScreen extends Component { onBlur={() => { if (chatOwner) { this.setState({ awaiting: true, type: 'Editing chat...' }, (() => { - props.api.metadata.add( + props.api.metadata.metadataAdd( + 'chat', association['app-path'], association['group-path'], state.title, @@ -307,7 +309,8 @@ export class SettingsScreen extends Component { onBlur={() => { if (chatOwner) { this.setState({ awaiting: true, type: 'Editing chat...' }, (() => { - props.api.metadata.add( + props.api.metadata.metadataAdd( + 'chat', association['app-path'], association['group-path'], association.metadata.title, diff --git a/pkg/interface/src/apps/groups/app.js b/pkg/interface/src/apps/groups/app.js index 6ead32d3c1..2739486fbc 100644 --- a/pkg/interface/src/apps/groups/app.js +++ b/pkg/interface/src/apps/groups/app.js @@ -17,9 +17,6 @@ import GroupDetail from './components/lib/group-detail'; export default class GroupsApp extends Component { constructor(props) { super(props); - this.store = new GroupsStore(); - this.state = this.store.state; - this.resetControllers(); } componentDidMount() { @@ -27,41 +24,30 @@ export default class GroupsApp extends Component { // preload spinner asset new Image().src = '/~landscape/img/Spinner.png'; - this.store.setStateHandler(this.setState.bind(this)); - const channel = new this.props.channel(); - this.api = new GroupsApi(this.props.ship, channel, this.store); - - this.subscription = new GroupsSubscription(this.store, this.api, channel); - this.subscription.start(); + this.props.subscription.startApp('groups') } componentWillUnmount() { - this.subscription.delete(); - this.store.clear(); - this.store.setStateHandler(() => {}); - this.resetControllers(); + this.props.subscription.stopApp('groups') } - resetControllers() { - this.api = null; - this.subscription = null; - } render() { - const { state, props } = this; + const { props } = this; - const contacts = state.contacts ? state.contacts : {}; + const contacts = props.contacts || {}; const defaultContacts = - (Boolean(state.contacts) && '/~/default' in state.contacts) ? - state.contacts['/~/default'] : {}; - const groups = state.groups ? state.groups : {}; + (Boolean(props.contacts) && '/~/default' in props.contacts) ? + props.contacts['/~/default'] : {}; + const groups = props.groups ? props.groups : {}; const invites = - (Boolean(state.invites) && '/contacts' in state.invites) ? - state.invites['/contacts'] : {}; - const associations = state.associations ? state.associations : {}; + (Boolean(props.invites) && '/contacts' in props.invites) ? + props.invites['/contacts'] : {}; + const associations = props.associations ? props.associations : {}; const selectedGroups = props.selectedGroups ? props.selectedGroups : []; - const s3 = state.s3 ? state.s3 : {}; + const s3 = props.s3 ? props.s3 : {}; + const { api } = props; return ( @@ -72,7 +58,7 @@ export default class GroupsApp extends Component { activeDrawer="groups" selectedGroups={selectedGroups} history={props.history} - api={this.api} + api={api} contacts={contacts} groups={groups} invites={invites} @@ -95,7 +81,7 @@ export default class GroupsApp extends Component { ); @@ -129,7 +115,7 @@ export default class GroupsApp extends Component { @@ -153,7 +139,7 @@ export default class GroupsApp extends Component { activeDrawer={(detail || settings) ? 'detail' : 'contacts'} settings={settings} associations={associations} - api={this.api} + api={api} {...props} /> @@ -171,7 +157,7 @@ export default class GroupsApp extends Component { { - const submit = props.api.group.add(props.path, aud); + const submit = props.api.groups.add(props.path, aud); submit.then(() => { this.setState({ awaiting: false }); props.history.push('/~groups' + props.path); diff --git a/pkg/interface/src/apps/groups/components/lib/contact-card.js b/pkg/interface/src/apps/groups/components/lib/contact-card.js index 4e84fe1046..2402ea4005 100644 --- a/pkg/interface/src/apps/groups/components/lib/contact-card.js +++ b/pkg/interface/src/apps/groups/components/lib/contact-card.js @@ -141,7 +141,7 @@ export class ContactCard extends Component { type: 'Saving to group' }, () => { - props.api.contactHook.edit(props.path, ship, { + props.api.contacts.edit(props.path, ship, { avatar: { url: state.avatarToSet }}) @@ -161,7 +161,7 @@ export class ContactCard extends Component { if (hexTest && hexTest[1] !== currentColor && !props.share) { this.setState({ awaiting: true, type: 'Saving to group' }, () => { - props.api.contactHook.edit( + props.api.contacts.edit( props.path, `~${props.ship}`, { color: hexTest[1] }) .then(() => { this.setState({ awaiting: false }); @@ -180,7 +180,7 @@ export class ContactCard extends Component { const emailTestResult = emailTest.exec(state.emailToSet); if (emailTestResult) { this.setState({ awaiting: true, type: 'Saving to group' }, () => { - props.api.contactHook.edit( + props.api.contacts.edit( props.path, ship, { email: state.emailToSet }) .then(() => { this.setState({ awaiting: false }); @@ -197,7 +197,7 @@ export class ContactCard extends Component { return false; } this.setState({ awaiting: true, type: 'Saving to group' }, () => { - props.api.contactHook.edit( + props.api.contacts.edit( props.path, ship, { nickname: state.nickNameToSet }) .then(() => { this.setState({ awaiting: false }); @@ -214,7 +214,7 @@ export class ContactCard extends Component { return false; } this.setState({ awaiting: true, type: 'Saving to group' }, () => { - props.api.contactHook.edit( + props.api.contacts.edit( props.path, ship, { notes: state.notesToSet }) .then(() => { this.setState({ awaiting: false }); @@ -232,7 +232,7 @@ export class ContactCard extends Component { const phoneTestResult = phoneTest.exec(state.phoneToSet); if (phoneTestResult) { this.setState({ awaiting: true, type: 'Saving to group' }, () => { - props.api.contactHook.edit( + props.api.contacts.edit( props.path, ship, { phone: state.phoneToSet }) .then(() => { this.setState({ awaiting: false }); @@ -251,7 +251,7 @@ export class ContactCard extends Component { const websiteTestResult = websiteTest.exec(state.websiteToSet); if (websiteTestResult) { this.setState({ awaiting: true, type: 'Saving to group' }, () => { - props.api.contactHook.edit( + props.api.contacts.edit( props.path, ship, { website: state.websiteToSet }) .then(() => { this.setState({ awaiting: false }); @@ -264,7 +264,7 @@ export class ContactCard extends Component { this.setState( { emailToSet: '', awaiting: true, type: 'Removing from group' }, () => { - props.api.contactHook.edit(props.path, ship, { email: '' }) + props.api.contacts.edit(props.path, ship, { email: '' }) .then(() => { this.setState({ awaiting: false }); }); @@ -276,7 +276,7 @@ export class ContactCard extends Component { this.setState( { nicknameToSet: '', awaiting: true, type: 'Removing from group' }, () => { - props.api.contactHook.edit(props.path, ship, { nickname: '' }) + props.api.contacts.edit(props.path, ship, { nickname: '' }) .then(() => { this.setState({ awaiting: false }); }); @@ -288,7 +288,7 @@ export class ContactCard extends Component { this.setState( { phoneToSet: '', awaiting: true, type: 'Removing from group' }, () => { - props.api.contactHook.edit(props.path, ship, { phone: '' }).then(() => { + props.api.contacts.edit(props.path, ship, { phone: '' }).then(() => { this.setState({ awaiting: false }); }); } @@ -299,7 +299,7 @@ export class ContactCard extends Component { this.setState( { websiteToSet: '', awaiting: true, type: 'Removing from group' }, () => { - props.api.contactHook.edit(props.path, ship, { website: '' }).then(() => { + props.api.contacts.edit(props.path, ship, { website: '' }).then(() => { this.setState({ awaiting: false }); }); } @@ -314,7 +314,7 @@ export class ContactCard extends Component { type: 'Removing from group' }, () => { - props.api.contactHook.edit(props.path, ship, { avatar: null }).then(() => { + props.api.contacts.edit(props.path, ship, { avatar: null }).then(() => { this.setState({ awaiting: false }); }); } @@ -325,7 +325,7 @@ export class ContactCard extends Component { this.setState( { notesToSet: '', awaiting: true, type: 'Removing from group' }, () => { - props.api.contactHook.edit(props.path, ship, { notes: '' }).then(() => { + props.api.contacts.edit(props.path, ship, { notes: '' }).then(() => { this.setState({ awaiting: false }); }); } @@ -380,9 +380,10 @@ export class ContactCard extends Component { }; this.setState({ awaiting: true, type: 'Sharing with group' }, () => { - props.api.contactView + props.api.contacts .share(`~${props.ship}`, props.path, `~${window.ship}`, contact) .then(() => { + this.setState({ awaiting: false }); props.history.push(`/~groups/view${props.path}/${window.ship}`); }); }); @@ -402,7 +403,7 @@ export class ContactCard extends Component { avatar: null }; - props.api.contactView.share( + props.api.contacts.share( `~${props.ship}`, props.path, `~${window.ship}`, @@ -410,7 +411,7 @@ export class ContactCard extends Component { ); this.setState({ awaiting: true, type: 'Removing from group' }, () => { - props.api.contactView.delete(props.path).then(() => { + props.api.contacts.delete(props.path).then(() => { this.setState({ awaiting: false }); props.history.push('/~groups'); }); @@ -421,7 +422,7 @@ export class ContactCard extends Component { const { props } = this; this.setState({ awaiting: true, type: 'Removing from group' }, () => { - props.api.contactView.remove(props.path, `~${props.ship}`).then(() => { + props.api.contacts.remove(props.path, `~${props.ship}`).then(() => { this.setState({ awaiting: false }); props.history.push(`/~groups${props.path}`); }); diff --git a/pkg/interface/src/apps/groups/components/lib/contact-sidebar.js b/pkg/interface/src/apps/groups/components/lib/contact-sidebar.js index 80838ac354..620f75b529 100644 --- a/pkg/interface/src/apps/groups/components/lib/contact-sidebar.js +++ b/pkg/interface/src/apps/groups/components/lib/contact-sidebar.js @@ -99,7 +99,7 @@ export class ContactSidebar extends Component { style={{ paddingTop: 6 }} onClick={() => { this.setState({ awaiting: true }, (() => { - props.api.group.remove(props.path, [`~${member}`]) + props.api.groups.remove(props.path, [`~${member}`]) .then(() => { this.setState({ awaiting: false }); }); diff --git a/pkg/interface/src/apps/groups/components/lib/group-detail.js b/pkg/interface/src/apps/groups/components/lib/group-detail.js index 9d71acb0e1..5e1cc33434 100644 --- a/pkg/interface/src/apps/groups/components/lib/group-detail.js +++ b/pkg/interface/src/apps/groups/components/lib/group-detail.js @@ -198,7 +198,8 @@ export class GroupDetail extends Component { onBlur={() => { if (groupOwner) { this.setState({ awaiting: true }, (() => { - props.api.metadata.add( + props.api.metadata.metadataAdd( + 'contacts', association['app-path'], association['group-path'], this.state.title, @@ -227,7 +228,8 @@ export class GroupDetail extends Component { onBlur={() => { if (groupOwner) { this.setState({ awaiting: true }, (() => { - props.api.metadata.add( + props.api.metadata.metadataAdd( + 'contacts', association['app-path'], association['group-path'], association.metadata.title, @@ -250,7 +252,7 @@ export class GroupDetail extends Component { onClick={() => { if (groupOwner) { this.setState({ awaiting: true, type: 'Deleting' }, (() => { - props.api.contactView.delete(props.path).then(() => { + props.api.contacts.delete(props.path).then(() => { props.history.push('/~groups'); }); })); diff --git a/pkg/interface/src/apps/groups/components/lib/s3-upload.js b/pkg/interface/src/apps/groups/components/lib/s3-upload.js index e21e0c3fa0..ead7cb7e6e 100644 --- a/pkg/interface/src/apps/groups/components/lib/s3-upload.js +++ b/pkg/interface/src/apps/groups/components/lib/s3-upload.js @@ -84,7 +84,7 @@ export class S3Upload extends Component { accept="image/*" onChange={this.onChange.bind(this)} /> diff --git a/pkg/interface/src/apps/groups/components/lib/sidebar-invite.js b/pkg/interface/src/apps/groups/components/lib/sidebar-invite.js index fe05912d77..7fee7cb7ff 100644 --- a/pkg/interface/src/apps/groups/components/lib/sidebar-invite.js +++ b/pkg/interface/src/apps/groups/components/lib/sidebar-invite.js @@ -3,12 +3,12 @@ import React, { Component } from 'react'; export class SidebarInvite extends Component { onAccept() { const { props } = this; - props.api.invite.accept(props.uid); + props.api.invite.accept('/contacts', props.uid); props.history.push(`/~groups${props.invite.path}`); } onDecline() { - this.props.api.invite.decline(this.props.uid); + this.props.api.invite.decline('/contacts', this.props.uid); } render() { diff --git a/pkg/interface/src/apps/groups/components/new.js b/pkg/interface/src/apps/groups/components/new.js index 6a68781a23..46d1c1d004 100644 --- a/pkg/interface/src/apps/groups/components/new.js +++ b/pkg/interface/src/apps/groups/components/new.js @@ -67,7 +67,7 @@ export class NewScreen extends Component { invites: '', awaiting: true }, () => { - props.api.contactView.create( + props.api.contacts.create( group, aud, this.state.title, diff --git a/pkg/interface/src/apps/launch/app.js b/pkg/interface/src/apps/launch/app.js index 6e065e62ca..8c22cef35b 100644 --- a/pkg/interface/src/apps/launch/app.js +++ b/pkg/interface/src/apps/launch/app.js @@ -10,50 +10,28 @@ import Tiles from './components/tiles'; import Welcome from './components/welcome'; export default class LaunchApp extends React.Component { - constructor(props) { - super(props); - this.store = new LaunchStore(); - this.state = this.store.state; - this.resetControllers(); - } - - resetControllers() { - this.api = null; - this.subscription = null; - } componentDidMount() { document.title = 'OS1 - Home'; // preload spinner asset new Image().src = '/~landscape/img/Spinner.png'; - this.store.setStateHandler(this.setState.bind(this)); - const channel = new this.props.channel(); - this.api = new LaunchApi(this.props.ship, channel, this.store); - - this.subscription = new LaunchSubscription(this.store, this.api, channel); - this.subscription.start(); } - componentWillUnmount() { - this.subscription.delete(); - this.store.clear(); - this.store.setStateHandler(() => {}); - this.resetControllers(); - } + componentWillUnmount() {} render() { - const { state } = this; + const { props } = this; return (
- +
); diff --git a/pkg/interface/src/apps/launch/components/tiles/weather.js b/pkg/interface/src/apps/launch/components/tiles/weather.js index 05b54421c9..2874b1e4be 100644 --- a/pkg/interface/src/apps/launch/components/tiles/weather.js +++ b/pkg/interface/src/apps/launch/components/tiles/weather.js @@ -37,7 +37,7 @@ export default class WeatherTile extends React.Component { this.setState({ latlng }, (err) => { console.log(err); }, { maximumAge: Infinity, timeout: 10000 }); - this.props.api.weather(latlng); + this.props.api.launch.weather(latlng); this.setState({ manualEntry: !this.state.manualEntry }); } else { this.setState({ error: true }); diff --git a/pkg/interface/src/apps/links/app.js b/pkg/interface/src/apps/links/app.js index 04f628b67a..6703f9d761 100644 --- a/pkg/interface/src/apps/links/app.js +++ b/pkg/interface/src/apps/links/app.js @@ -22,10 +22,7 @@ import { makeRoutePath, amOwnerOfGroup, base64urlDecode } from '../../lib/util'; export class LinksApp extends Component { constructor(props) { super(props); - this.store = new LinksStore(); - this.state = this.store.state; this.totalUnseen = 0; - this.resetControllers(); } componentDidMount() { @@ -33,38 +30,29 @@ export class LinksApp extends Component { // preload spinner asset new Image().src = '/~landscape/img/Spinner.png'; - this.store.setStateHandler(this.setState.bind(this)); - - const channel = new this.props.channel(); - this.api = new LinksApi(this.props.ship, channel, this.store); - - this.subscription = new LinksSubscription(this.store, this.api, channel); - this.subscription.start(); + this.props.api.links.getPage('', 0); + this.props.subscription.startApp('link'); + if (!this.props.sidebarShown) { + this.props.api.local.sidebarToggle(); + } } componentWillUnmount() { - this.subscription.delete(); - this.store.clear(); - this.store.setStateHandler(() => {}); - this.resetControllers(); + this.props.subscription.stopApp('link'); } - resetControllers() { - this.api = null; - this.subscription = null; - } render() { - const { state, props } = this; + const { props } = this; - const contacts = state.contacts ? state.contacts : {}; - const groups = state.groups ? state.groups : {}; + const contacts = props.contacts ? props.contacts : {}; + const groups = props.groups ? props.groups : {}; - const associations = state.associations ? state.associations : { link: {}, contacts: {} }; - const links = state.links ? state.links : {}; - const comments = state.comments ? state.comments : {}; + const associations = props.associations ? props.associations : { link: {}, contacts: {} }; + const links = props.links ? props.links : {}; + const comments = props.linkComments ? props.linkComments : {}; - const seen = state.seen ? state.seen : {}; + const seen = props.linksSeen ? props.linksSeen : {}; const totalUnseen = _.reduce( seen, @@ -77,11 +65,15 @@ export class LinksApp extends Component { this.totalUnseen = totalUnseen; } - const invites = state.invites ? - state.invites : {}; + const invites = props.invites ? + props.invites : {}; const selectedGroups = props.selectedGroups ? props.selectedGroups : []; + const listening = props.linkListening; + + const { api, sidebarShown } = this.props; + return (
@@ -111,17 +103,17 @@ export class LinksApp extends Component { associations={associations} invites={invites} groups={groups} - sidebarShown={state.sidebarShown} + sidebarShown={sidebarShown} selectedGroups={selectedGroups} links={links} - listening={state.listening} - api={this.api} + listening={listening} + api={api} > @@ -134,7 +126,7 @@ export class LinksApp extends Component { const autoJoin = () => { try { - this.api.joinCollection(resourcePath); + api.links.joinCollection(resourcePath); props.history.push(makeRoutePath(resourcePath)); } catch(err) { setTimeout(autoJoin, 2000); @@ -159,14 +151,14 @@ export class LinksApp extends Component { invites={invites} groups={groups} selected={resourcePath} - sidebarShown={state.sidebarShown} + sidebarShown={sidebarShown} selectedGroups={selectedGroups} links={links} - listening={state.listening} - api={this.api} + listening={listening} + api={api} > @@ -198,15 +190,15 @@ export class LinksApp extends Component { invites={invites} groups={groups} selected={resourcePath} - sidebarShown={state.sidebarShown} + sidebarShown={sidebarShown} selectedGroups={selectedGroups} popout={popout} links={links} - listening={state.listening} - api={this.api} + listening={listening} + api={api} > @@ -253,13 +245,13 @@ export class LinksApp extends Component { invites={invites} groups={groups} selected={resourcePath} - sidebarShown={state.sidebarShown} + sidebarShown={sidebarShown} selectedGroups={selectedGroups} sidebarHideMobile={true} popout={popout} links={links} - listening={state.listening} - api={this.api} + listening={listening} + api={api} > ); @@ -311,13 +303,13 @@ export class LinksApp extends Component { invites={invites} groups={groups} selected={resourcePath} - sidebarShown={state.sidebarShown} + sidebarShown={sidebarShown} selectedGroups={selectedGroups} sidebarHideMobile={true} popout={popout} links={links} - listening={state.listening} - api={this.api} + listening={listening} + api={api} > ); diff --git a/pkg/interface/src/apps/links/components/lib/comments.js b/pkg/interface/src/apps/links/components/lib/comments.js index 6db7444ad1..bce3e456a0 100644 --- a/pkg/interface/src/apps/links/components/lib/comments.js +++ b/pkg/interface/src/apps/links/components/lib/comments.js @@ -16,7 +16,7 @@ export class Comments extends Component { this.props.comments.local[page] ) { this.setState({ requested: this.props.commentPage }); - this.props.api.getCommentsPage( + this.props.api.links.getCommentsPage( this.props.resourcePath, this.props.url, this.props.commentPage); diff --git a/pkg/interface/src/apps/links/components/lib/invite-element.js b/pkg/interface/src/apps/links/components/lib/invite-element.js index 864478a71a..94da5d5752 100644 --- a/pkg/interface/src/apps/links/components/lib/invite-element.js +++ b/pkg/interface/src/apps/links/components/lib/invite-element.js @@ -34,7 +34,7 @@ export class InviteElement extends Component { success: true, members: [] }, () => { - props.api.inviteToCollection(props.resourcePath, aud).then(() => { + props.api.links.inviteToCollection(props.resourcePath, aud).then(() => { this.setState({ awaiting: false }); }); }); diff --git a/pkg/interface/src/apps/links/components/lib/link-item.js b/pkg/interface/src/apps/links/components/lib/link-item.js index 10fcea9219..805e91ed5b 100644 --- a/pkg/interface/src/apps/links/components/lib/link-item.js +++ b/pkg/interface/src/apps/links/components/lib/link-item.js @@ -34,7 +34,7 @@ export class LinkItem extends Component { } markPostAsSeen() { - this.props.api.seenLink(this.props.resourcePath, this.props.url); + this.props.api.links.seenLink(this.props.resourcePath, this.props.url); } render() { diff --git a/pkg/interface/src/apps/links/components/lib/link-submit.js b/pkg/interface/src/apps/links/components/lib/link-submit.js index 73d2d90aad..36a5078db8 100644 --- a/pkg/interface/src/apps/links/components/lib/link-submit.js +++ b/pkg/interface/src/apps/links/components/lib/link-submit.js @@ -21,7 +21,7 @@ export class LinkSubmit extends Component { ? this.state.linkTitle : this.state.linkValue; this.setState({ disabled: true }); - this.props.api.postLink(this.props.resourcePath, link, title).then((r) => { + this.props.api.links.postLink(this.props.resourcePath, link, title).then((r) => { this.setState({ disabled: false, linkValue: '', diff --git a/pkg/interface/src/apps/links/components/lib/sidebar-invite.js b/pkg/interface/src/apps/links/components/lib/sidebar-invite.js index df4e0f2f9b..218c04b7fb 100644 --- a/pkg/interface/src/apps/links/components/lib/sidebar-invite.js +++ b/pkg/interface/src/apps/links/components/lib/sidebar-invite.js @@ -1,11 +1,11 @@ import React, { Component } from 'react'; export class SidebarInvite extends Component { onAccept() { - this.props.api.invite.accept(this.props.uid); + this.props.api.invite.accept('/link', this.props.uid); } onDecline() { - this.props.api.invite.decline(this.props.uid); + this.props.api.invite.decline('/link', this.props.uid); } render() { diff --git a/pkg/interface/src/apps/links/components/link.js b/pkg/interface/src/apps/links/components/link.js index 7c8cde9afb..a4fdc1e481 100644 --- a/pkg/interface/src/apps/links/components/link.js +++ b/pkg/interface/src/apps/links/components/link.js @@ -36,7 +36,7 @@ export class LinkDetail extends Component { componentDidUpdate(prevProps) { // if we have no preloaded data, and we aren't expecting it, get it if ((!this.state.data.title) && (this.props.api)) { - this.props.api?.getSubmission( + this.props.api?.links.getSubmission( this.props.resourcePath, this.props.url, this.updateData.bind(this) ); } @@ -69,7 +69,7 @@ export class LinkDetail extends Component { pending.add(this.state.comment); this.setState({ pending: pending, disabled: true }); - this.props.api.postComment( + this.props.api.links.postComment( this.props.resourcePath, url, this.state.comment diff --git a/pkg/interface/src/apps/links/components/links-list.js b/pkg/interface/src/apps/links/components/links-list.js index 9636a76e44..56cb7872ad 100644 --- a/pkg/interface/src/apps/links/components/links-list.js +++ b/pkg/interface/src/apps/links/components/links-list.js @@ -35,7 +35,7 @@ export class Links extends Component { !this.props.links[linkPage] || // don't have info? this.props.links.local[linkPage] // waiting on post confirmation? ) { - this.props.api?.getPage(this.props.resourcePath, this.props.page); + this.props.api?.links.getPage(this.props.resourcePath, this.props.page); } } diff --git a/pkg/interface/src/apps/links/components/new.js b/pkg/interface/src/apps/links/components/new.js index fc95a0f71e..844c141548 100644 --- a/pkg/interface/src/apps/links/components/new.js +++ b/pkg/interface/src/apps/links/components/new.js @@ -119,7 +119,7 @@ export class NewScreen extends Component { ships: [], disabled: true }, () => { - const submit = props.api.createCollection( + const submit = props.api.links.createCollection( appPath, state.title, state.description, diff --git a/pkg/interface/src/apps/links/components/settings.js b/pkg/interface/src/apps/links/components/settings.js index f7ddbbfa2f..7b9f38fb64 100644 --- a/pkg/interface/src/apps/links/components/settings.js +++ b/pkg/interface/src/apps/links/components/settings.js @@ -96,6 +96,7 @@ export class SettingsScreen extends Component { if (props.amOwner) { this.setState({ disabled: true }); props.api.metadataAdd( + 'link', props.resourcePath, props.groupPath, resource.metadata.title, @@ -117,7 +118,7 @@ export class SettingsScreen extends Component { disabled: true, type: 'Removing' }); - props.api.removeCollection(props.resourcePath) + props.api.links.removeCollection(props.resourcePath) .then(() => { this.setState({ isLoading: false @@ -133,7 +134,7 @@ export class SettingsScreen extends Component { disabled: true, type: 'Deleting' }); - props.api.deleteCollection(props.resourcePath) + props.api.links.deleteCollection(props.resourcePath) .then(() => { this.setState({ isLoading: false @@ -142,7 +143,7 @@ export class SettingsScreen extends Component { } markAllAsSeen() { - this.props.api.seenLink(this.props.resourcePath); + this.props.api.links.seenLink(this.props.resourcePath); } renderRemove() { @@ -208,7 +209,8 @@ export class SettingsScreen extends Component { onBlur={() => { if (props.amOwner) { this.setState({ disabled: true }); - props.api.metadataAdd( + props.api.metadata.metadataAdd( + 'link', props.resourcePath, props.groupPath, state.title, @@ -238,7 +240,8 @@ export class SettingsScreen extends Component { onBlur={() => { if (props.amOwner) { this.setState({ disabled: true }); - props.api.metadataAdd( + props.api.metadata.metadataAdd( + 'link', props.resourcePath, props.groupPath, resource.metadata.title, diff --git a/pkg/interface/src/apps/publish/app.js b/pkg/interface/src/apps/publish/app.js index 4551e51279..2bacadda12 100644 --- a/pkg/interface/src/apps/publish/app.js +++ b/pkg/interface/src/apps/publish/app.js @@ -19,15 +19,7 @@ import { EditPost } from './components/lib/edit-post'; export default class PublishApp extends React.Component { constructor(props) { super(props); - this.store = new PublishStore(); - this.state = this.store.state; this.unreadTotal = 0; - this.resetControllers(); - } - - resetControllers() { - this.api = null; - this.subscription = null; } componentDidMount() { @@ -35,31 +27,28 @@ export default class PublishApp extends React.Component { // preload spinner asset new Image().src = '/~landscape/img/Spinner.png'; - this.store.setStateHandler(this.setState.bind(this)); + this.props.subscription.startApp('publish'); - const channel = new this.props.channel(); - this.api = new PublishApi(this.props.ship, channel, this.store); + this.props.api.publish.fetchNotebooks(); + + if (!this.props.sidebarShown) { + this.props.api.local.sidebarToggle(); + } - this.subscription = new PublishSubscription(this.store, this.api, channel); - this.subscription.start(); - this.api.fetchNotebooks(); } componentWillUnmount() { - this.subscription.delete(); - this.store.clear(); - this.store.setStateHandler(() => {}); - this.resetControllers(); + this.props.subscription.stopApp('publish'); } render() { - const { state, props } = this; + const { props } = this; - const contacts = state.contacts ? state.contacts : {}; - const associations = state.associations ? state.associations : { contacts: {} }; + const contacts = props.contacts ? props.contacts : {}; + const associations = props.associations ? props.associations : { contacts: {} }; const selectedGroups = props.selectedGroups ? props.selectedGroups : []; - const notebooks = state.notebooks ? state.notebooks : {}; + const notebooks = props.notebooks ? props.notebooks : {}; const unreadTotal = _.chain(notebooks) .values() @@ -80,6 +69,8 @@ export default class PublishApp extends React.Component { this.unreadTotal = unreadTotal; } + const { api, groups, permissions, sidebarShown } = props; + return (
@@ -146,19 +137,19 @@ export default class PublishApp extends React.Component { popout={false} active={'rightPanel'} rightPanelHide={false} - sidebarShown={state.sidebarShown} - invites={state.invites} + sidebarShown={sidebarShown} + invites={props.invites} notebooks={notebooks} associations={associations} selectedGroups={selectedGroups} contacts={contacts} - api={this.api} + api={api} > @@ -190,22 +181,22 @@ export default class PublishApp extends React.Component { popout={popout} active={'rightPanel'} rightPanelHide={false} - sidebarShown={state.sidebarShown} - invites={state.invites} + sidebarShown={sidebarShown} + invites={props.invites} notebooks={notebooks} associations={associations} selectedGroups={selectedGroups} contacts={contacts} path={path} - api={this.api} + api={api} > @@ -216,28 +207,28 @@ export default class PublishApp extends React.Component { popout={popout} active={'rightPanel'} rightPanelHide={false} - sidebarShown={state.sidebarShown} - invites={state.invites} + sidebarShown={sidebarShown} + invites={props.invites} notebooks={notebooks} associations={associations} contacts={contacts} selectedGroups={selectedGroups} path={path} - api={this.api} + api={api} > @@ -256,7 +247,7 @@ export default class PublishApp extends React.Component { const bookGroupPath = notebooks?.[ship]?.[notebook]?.['subscribers-group-path']; - const notebookContacts = (bookGroupPath in state.contacts) + const notebookContacts = (bookGroupPath in contacts) ? contacts[bookGroupPath] : {}; const edit = Boolean(props.match.params.edit) || false; @@ -267,23 +258,23 @@ export default class PublishApp extends React.Component { popout={popout} active={'rightPanel'} rightPanelHide={false} - sidebarShown={state.sidebarShown} - invites={state.invites} + sidebarShown={sidebarShown} + invites={props.invites} notebooks={notebooks} selectedGroups={selectedGroups} associations={associations} contacts={contacts} path={path} - api={this.api} + api={api} > @@ -294,25 +285,25 @@ export default class PublishApp extends React.Component { popout={popout} active={'rightPanel'} rightPanelHide={false} - sidebarShown={state.sidebarShown} - invites={state.invites} + sidebarShown={sidebarShown} + invites={props.invites} notebooks={notebooks} associations={associations} selectedGroups={selectedGroups} contacts={contacts} path={path} - api={this.api} + api={api} > diff --git a/pkg/interface/src/apps/publish/components/lib/comments.js b/pkg/interface/src/apps/publish/components/lib/comments.js index 9e6ac6eb1d..32fdca68cc 100644 --- a/pkg/interface/src/apps/publish/components/lib/comments.js +++ b/pkg/interface/src/apps/publish/components/lib/comments.js @@ -53,7 +53,7 @@ export class Comments extends Component { this.textArea.value = ''; this.setState({ commentBody: '', awaiting: 'new' }); - const submit = this.props.api.publishAction(comment); + const submit = this.props.api.publish.publishAction(comment); submit.then(() => { this.setState({ awaiting: null }); }); @@ -87,11 +87,11 @@ export class Comments extends Component { this.setState({ awaiting: 'edit' }); - window.api + this.props.api.publish .publishAction(comment) .then(() => { - this.setState({ awaiting: null, editing: null }); -}); + this.setState({ awaiting: null, editing: null }); + }); } commentDelete(idx) { @@ -106,7 +106,7 @@ export class Comments extends Component { }; this.setState({ awaiting: { kind: 'del', what: idx } }); - window.api + this.props.api.publish .publishAction(comment) .then(() => { this.setState({ awaiting: null }); diff --git a/pkg/interface/src/apps/publish/components/lib/edit-post.js b/pkg/interface/src/apps/publish/components/lib/edit-post.js index beee1727c9..c22021a421 100644 --- a/pkg/interface/src/apps/publish/components/lib/edit-post.js +++ b/pkg/interface/src/apps/publish/components/lib/edit-post.js @@ -25,17 +25,19 @@ export class EditPost extends Component { componentDidUpdate(prevProps) { const { props, state } = this; + const contents = props.notebooks[props.ship]?.[props.book]?.notes?.[props.note]?.file; if (prevProps && prevProps.api !== props.api) { - if (!(props.notebooks[props.ship]?.[props.book]?.notes?.[props.note]?.file)) { + if (!contents) { props.api?.fetchNote(props.ship, props.book, props.note); - } else if (state.body === '') { - const notebook = props.notebooks[props.ship][props.book]; - const note = notebook.notes[props.note]; - const file = note.file; - const body = file.slice(file.indexOf(';>') + 3); - this.setState({ body: body }); } } + if (contents && state.body === '') { + const notebook = props.notebooks[props.ship][props.book]; + const note = notebook.notes[props.note]; + const file = note.file; + const body = file.slice(file.indexOf(';>') + 3); + this.setState({ body: body }); + } } postSubmit() { @@ -53,7 +55,7 @@ export class EditPost extends Component { } }; this.setState({ awaiting: true }); - this.props.api.publishAction(editNote).then(() => { + this.props.api.publish.publishAction(editNote).then(() => { const editIndex = props.location.pathname.indexOf('/edit'); const noteHref = props.location.pathname.slice(0, editIndex); this.setState({ awaiting: false }); @@ -95,7 +97,7 @@ export class EditPost extends Component { }; return ( -
+
{ + this.props.api.publish.publishAction(actionData).catch((err) => { console.log(err); }).then(() => { this.setState({ awaiting: text }); diff --git a/pkg/interface/src/apps/publish/components/lib/new-post.js b/pkg/interface/src/apps/publish/components/lib/new-post.js index ab8f742858..3700ba3597 100644 --- a/pkg/interface/src/apps/publish/components/lib/new-post.js +++ b/pkg/interface/src/apps/publish/components/lib/new-post.js @@ -37,14 +37,14 @@ export class NewPost extends Component { }; this.setState({ disabled: true }); - this.props.api.publishAction(newNote).then(() => { + this.props.api.publish.publishAction(newNote).then(() => { this.setState({ awaiting: newNote['new-note'].note }); }).catch((err) => { if (err.includes('note already exists')) { const timestamp = Math.floor(Date.now() / 1000); newNote['new-note'].note += '-' + timestamp; this.setState({ awaiting: newNote['new-note'].note }); - this.props.api.publishAction(newNote); + this.props.api.publish.publishAction(newNote); } else { this.setState({ disabled: false, awaiting: null }); } @@ -58,7 +58,7 @@ export class NewPost extends Component { componentDidUpdate(prevProps) { if (prevProps && prevProps.api !== this.props.api) { - this.props.api.fetchNotebook(this.props.ship, this.props.book); + this.props.api.publish.fetchNotebook(this.props.ship, this.props.book); } const notebook = this.props.notebooks[this.props.ship][this.props.book]; diff --git a/pkg/interface/src/apps/publish/components/lib/new.js b/pkg/interface/src/apps/publish/components/lib/new.js index 7b89f333c6..3a4ff38784 100644 --- a/pkg/interface/src/apps/publish/components/lib/new.js +++ b/pkg/interface/src/apps/publish/components/lib/new.js @@ -93,7 +93,7 @@ export class NewScreen extends Component { } }; this.setState({ awaiting: bookId, disabled: true }, () => { - props.api.publishAction(action).then(() => { + props.api.publish.publishAction(action).then(() => { }); }); } diff --git a/pkg/interface/src/apps/publish/components/lib/note.js b/pkg/interface/src/apps/publish/components/lib/note.js index a230d10ce5..01433fb9e1 100644 --- a/pkg/interface/src/apps/publish/components/lib/note.js +++ b/pkg/interface/src/apps/publish/components/lib/note.js @@ -49,7 +49,7 @@ export class Note extends Component { const { props } = this; if ((prevProps && prevProps.api !== props.api) || props.api) { if (!(props.notebooks[props.ship]?.[props.book]?.notes?.[props.note]?.file)) { - props.api.fetchNote(props.ship, props.book, props.note); + props.api.publish.fetchNote(props.ship, props.book, props.note); } if (prevProps) { @@ -63,7 +63,7 @@ export class Note extends Component { note: props.note } }; - props.api.publishAction(readAction); + props.api.publish.publishAction(readAction); } } } @@ -92,7 +92,7 @@ export class Note extends Component { const fullyLoaded = (loadedComments === allComments); if (atBottom && !fullyLoaded) { - this.props.api.fetchCommentsPage(this.props.ship, + this.props.api.publish.fetchCommentsPage(this.props.ship, this.props.book, this.props.note, loadedComments, 30); } } @@ -109,7 +109,7 @@ export class Note extends Component { const popout = (props.popout) ? 'popout/' : ''; const baseUrl = `/~publish/${popout}notebook/${props.ship}/${props.book}`; this.setState({ deleting: true }); - this.props.api.publishAction(deleteAction) + this.props.api.publish.publishAction(deleteAction) .then(() => { props.history.push(baseUrl); }); diff --git a/pkg/interface/src/apps/publish/components/lib/notebook.js b/pkg/interface/src/apps/publish/components/lib/notebook.js index 45088586ca..710e172785 100644 --- a/pkg/interface/src/apps/publish/components/lib/notebook.js +++ b/pkg/interface/src/apps/publish/components/lib/notebook.js @@ -25,7 +25,7 @@ export class Notebook extends Component { atBottom = true; } if (!notebook.notes && this.props.api) { - this.props.api.fetchNotebook(this.props.ship, this.props.book); + this.props.api.publish.fetchNotebook(this.props.ship, this.props.book); return; } @@ -35,7 +35,7 @@ export class Notebook extends Component { const fullyLoaded = (loadedNotes === allNotes); if (atBottom && !fullyLoaded) { - this.props.api.fetchNotesPage(this.props.ship, this.props.book, loadedNotes, 30); + this.props.api.publish.fetchNotesPage(this.props.ship, this.props.book, loadedNotes, 30); } } @@ -44,7 +44,7 @@ export class Notebook extends Component { if ((prevProps && (prevProps.api !== props.api)) || props.api) { const notebook = props.notebooks?.[props.ship]?.[props.book]; if (!notebook?.subscribers) { - props.api.fetchNotebook(props.ship, props.book); + props.api.publish.fetchNotebook(props.ship, props.book); } } } @@ -64,7 +64,7 @@ export class Notebook extends Component { book: this.props.book } }; - this.props.api.publishAction(action); + this.props.api.publish.publishAction(action); this.props.history.push('/~publish'); } diff --git a/pkg/interface/src/apps/publish/components/lib/settings.js b/pkg/interface/src/apps/publish/components/lib/settings.js index 409a794c45..13980e0b59 100644 --- a/pkg/interface/src/apps/publish/components/lib/settings.js +++ b/pkg/interface/src/apps/publish/components/lib/settings.js @@ -63,7 +63,7 @@ export class Settings extends Component { changeComments() { this.setState({ comments: !this.state.comments, disabled: true }, (() => { - this.props.api.publishAction({ + this.props.api.publish.publishAction({ 'edit-book': { book: this.props.book, title: this.props.notebook.title, @@ -84,7 +84,7 @@ export class Settings extends Component { } }; this.setState({ disabled: true, type: 'Deleting' }); - this.props.api.publishAction(action).then(() => { + this.props.api.publish.publishAction(action).then(() => { this.props.history.push('/~publish'); }); } @@ -108,7 +108,7 @@ export class Settings extends Component { disabled: true, type: 'Converting' }, (() => { - this.props.api.publishAction({ + this.props.api.publish.publishAction({ groupify: { book: props.book, target: state.targetGroup, @@ -253,7 +253,7 @@ export class Settings extends Component { disabled={this.state.disabled} onBlur={() => { this.setState({ disabled: true }); - this.props.api + this.props.api.publish .publishAction({ 'edit-book': { book: this.props.book, @@ -280,7 +280,7 @@ export class Settings extends Component { onChange={this.changeDescription} onBlur={() => { this.setState({ disabled: true }); - this.props.api + this.props.api.publish .publishAction({ 'edit-book': { book: this.props.book, diff --git a/pkg/interface/src/apps/publish/components/lib/sidebar-invite.js b/pkg/interface/src/apps/publish/components/lib/sidebar-invite.js index 13f96193d8..cbaed7421a 100644 --- a/pkg/interface/src/apps/publish/components/lib/sidebar-invite.js +++ b/pkg/interface/src/apps/publish/components/lib/sidebar-invite.js @@ -2,23 +2,11 @@ import React, { Component } from 'react'; export class SidebarInvite extends Component { onAccept() { - const action = { - accept: { - path: '/publish', - uid: this.props.uid - } - }; - this.props.api.inviteAction(action); + this.props.api.invite.accept('/publish', this.props.uid); } onDecline() { - const action = { - decline: { - path: '/publish', - uid: this.props.uid - } - }; - this.props.api.inviteAction(action); + this.props.api.invite.decline('/publish', this.props.uid); } render() { diff --git a/pkg/interface/src/apps/publish/components/lib/subscribers.js b/pkg/interface/src/apps/publish/components/lib/subscribers.js index 8d48153f53..9d932e656a 100644 --- a/pkg/interface/src/apps/publish/components/lib/subscribers.js +++ b/pkg/interface/src/apps/publish/components/lib/subscribers.js @@ -11,23 +11,11 @@ export class Subscribers extends Component { } addUser(who, path) { - const action = { - add: { - members: [who], - path: path - } - }; - this.props.api.groupAction(action); + this.props.api.groups.add(path, [who]); } removeUser(who, path) { - const action = { - remove: { - members: [who], - path: path - } - }; - this.props.api.groupAction(action); + this.props.api.groups.remove(path, [who]); } redirect(url) { diff --git a/pkg/interface/src/components/GroupFilter.js b/pkg/interface/src/components/GroupFilter.js index 9f29ce563a..3d4f4c197e 100644 --- a/pkg/interface/src/components/GroupFilter.js +++ b/pkg/interface/src/components/GroupFilter.js @@ -26,7 +26,7 @@ export default class GroupFilter extends Component { const selected = localStorage.getItem('urbit-selectedGroups'); if (selected) { this.setState({ selected: JSON.parse(selected) }, (() => { - this.props.api.setSelected(this.state.selected); + this.props.api.local.setSelected(this.state.selected); })); } } diff --git a/pkg/interface/src/components/SidebarSwitch.js b/pkg/interface/src/components/SidebarSwitch.js index 6733a4ca4c..285784ea09 100644 --- a/pkg/interface/src/components/SidebarSwitch.js +++ b/pkg/interface/src/components/SidebarSwitch.js @@ -15,7 +15,7 @@ export class SidebarSwitcher extends Component { { - this.props.api.sidebarToggle(); + this.props.api.local.sidebarToggle(); }} > ; + +export default class ChatReducer { + reduce(json: Cage, state: S) { + const data = json['chat-update']; if (data) { this.initial(data, state); this.pending(data, state); @@ -13,13 +19,13 @@ export default class ChatReducer { this.delete(data, state); } - data = _.get(json, 'chat-hook-update', false); - if (data) { - this.hook(data, state); + const hookUpdate = json['chat-hook-update']; + if (hookUpdate) { + this.hook(hookUpdate, state); } } - initial(json, state) { + initial(json: ChatUpdate, state: S) { const data = _.get(json, 'initial', false); if (data) { state.inbox = data; @@ -27,11 +33,11 @@ export default class ChatReducer { } } - hook(json, state) { + hook(json: ChatHookUpdate, state: S) { state.chatSynced = json; } - message(json, state) { + message(json: ChatUpdate, state: S) { const data = _.get(json, 'message', false); if (data) { state.inbox[data.path].envelopes.unshift(data.envelope); @@ -40,7 +46,7 @@ export default class ChatReducer { } } - messages(json, state) { + messages(json: ChatUpdate, state: S) { const data = _.get(json, 'messages', false); if (data) { state.inbox[data.path].envelopes = @@ -48,7 +54,7 @@ export default class ChatReducer { } } - read(json, state) { + read(json: ChatUpdate, state: S) { const data = _.get(json, 'read', false); if (data) { state.inbox[data.path].config.read = @@ -56,7 +62,7 @@ export default class ChatReducer { } } - create(json, state) { + create(json: ChatUpdate, state: S) { const data = _.get(json, 'create', false); if (data) { state.inbox[data.path] = { @@ -69,25 +75,25 @@ export default class ChatReducer { } } - delete(json, state) { + delete(json: ChatUpdate, state: S) { const data = _.get(json, 'delete', false); if (data) { delete state.inbox[data.path]; } } - pending(json, state) { + pending(json: ChatUpdate, state: S) { const msg = _.get(json, 'message', false); if (!msg || !state.pendingMessages.has(msg.path)) { return; } - const mailbox = state.pendingMessages.get(msg.path); + const mailbox = state.pendingMessages.get(msg.path) || []; for (const pendingMsg of mailbox) { if (msg.envelope.uid === pendingMsg.uid) { const index = mailbox.indexOf(pendingMsg); - state.pendingMessages.get(msg.path).splice(index, 1); + mailbox.splice(index, 1); } } } diff --git a/pkg/interface/src/reducers/contact-update.js b/pkg/interface/src/reducers/contact-update.ts similarity index 72% rename from pkg/interface/src/reducers/contact-update.js rename to pkg/interface/src/reducers/contact-update.ts index 56d4fda751..2cc7d04dc5 100644 --- a/pkg/interface/src/reducers/contact-update.js +++ b/pkg/interface/src/reducers/contact-update.ts @@ -1,7 +1,12 @@ import _ from 'lodash'; +import { StoreState } from '../store/type'; +import { Cage } from '../types/cage'; +import { ContactUpdate } from '../types/contact-update'; -export default class ContactReducer { - reduce(json, state) { +type ContactState = Pick; + +export default class ContactReducer { + reduce(json: Cage, state: S) { const data = _.get(json, 'contact-update', false); if (data) { this.initial(data, state); @@ -13,28 +18,28 @@ export default class ContactReducer { } } - initial(json, state) { + initial(json: ContactUpdate, state: S) { const data = _.get(json, 'initial', false); if (data) { state.contacts = data; } } - create(json, state) { + create(json: ContactUpdate, state: S) { const data = _.get(json, 'create', false); if (data) { state.contacts[data.path] = {}; } } - delete(json, state) { + delete(json: ContactUpdate, state: S) { const data = _.get(json, 'delete', false); if (data) { delete state.contacts[data.path]; } } - add(json, state) { + add(json: ContactUpdate, state: S) { const data = _.get(json, 'add', false); if ( data && @@ -44,7 +49,7 @@ export default class ContactReducer { } } - remove(json, state) { + remove(json: ContactUpdate, state: S) { const data = _.get(json, 'remove', false); if ( data && @@ -55,7 +60,7 @@ export default class ContactReducer { } } - edit(json, state) { + edit(json: ContactUpdate, state: S) { const data = _.get(json, 'edit', false); if ( data && diff --git a/pkg/interface/src/reducers/group-update.js b/pkg/interface/src/reducers/group-update.ts similarity index 71% rename from pkg/interface/src/reducers/group-update.js rename to pkg/interface/src/reducers/group-update.ts index f9bcb13215..a2d8e03de2 100644 --- a/pkg/interface/src/reducers/group-update.js +++ b/pkg/interface/src/reducers/group-update.ts @@ -1,8 +1,13 @@ import _ from 'lodash'; +import { StoreState } from '../store/type'; +import { Cage } from '../types/cage'; +import { GroupUpdate } from '../types/group-update'; -export default class GroupReducer { +type GroupState = Pick; - reduce(json, state) { +export default class GroupReducer { + + reduce(json: Cage, state: S) { const data = _.get(json, "group-update", false); if (data) { this.initial(data, state); @@ -15,7 +20,7 @@ export default class GroupReducer { } } - initial(json, state) { + initial(json: GroupUpdate, state: S) { const data = _.get(json, 'initial', false); if (data) { for (let group in data) { @@ -24,7 +29,7 @@ export default class GroupReducer { } } - add(json, state) { + add(json: GroupUpdate, state: S) { const data = _.get(json, 'add', false); if (data) { for (const member of data.members) { @@ -33,7 +38,7 @@ export default class GroupReducer { } } - remove(json, state) { + remove(json: GroupUpdate, state: S) { const data = _.get(json, 'remove', false); if (data) { for (const member of data.members) { @@ -42,21 +47,21 @@ export default class GroupReducer { } } - bundle(json, state) { + bundle(json: GroupUpdate, state: S) { const data = _.get(json, 'bundle', false); if (data) { state.groups[data.path] = new Set(); } } - unbundle(json, state) { + unbundle(json: GroupUpdate, state: S) { const data = _.get(json, 'unbundle', false); if (data) { delete state.groups[data.path]; } } - keys(json, state) { + keys(json: GroupUpdate, state: S) { const data = _.get(json, 'keys', false); if (data) { state.groupKeys = new Set(data.keys); diff --git a/pkg/interface/src/reducers/invite-update.js b/pkg/interface/src/reducers/invite-update.ts similarity index 63% rename from pkg/interface/src/reducers/invite-update.js rename to pkg/interface/src/reducers/invite-update.ts index d9be947d0c..d4b0f670c6 100644 --- a/pkg/interface/src/reducers/invite-update.js +++ b/pkg/interface/src/reducers/invite-update.ts @@ -1,10 +1,15 @@ import _ from 'lodash'; +import { StoreState } from '../store/type'; +import { Cage } from '../types/cage'; +import { InviteUpdate } from '../types/invite-update'; -export default class InviteReducer { - reduce(json, state) { - const data = _.get(json, 'invite-update', false); +type InviteState = Pick; + + +export default class InviteReducer { + reduce(json: Cage, state: S) { + const data = json['invite-update']; if (data) { - console.log(data); this.initial(data, state); this.create(data, state); this.delete(data, state); @@ -14,35 +19,35 @@ export default class InviteReducer { } } - initial(json, state) { + initial(json: InviteUpdate, state: S) { const data = _.get(json, 'initial', false); if (data) { state.invites = data; } } - create(json, state) { + create(json: InviteUpdate, state: S) { const data = _.get(json, 'create', false); if (data) { state.invites[data.path] = {}; } } - delete(json, state) { + delete(json: InviteUpdate, state: S) { const data = _.get(json, 'delete', false); if (data) { delete state.invites[data.path]; } } - invite(json, state) { + invite(json: InviteUpdate, state: S) { const data = _.get(json, 'invite', false); if (data) { state.invites[data.path][data.uid] = data.invite; } } - accepted(json, state) { + accepted(json: InviteUpdate, state: S) { const data = _.get(json, 'accepted', false); if (data) { console.log(data); @@ -50,7 +55,7 @@ export default class InviteReducer { } } - decline(json, state) { + decline(json: InviteUpdate, state: S) { const data = _.get(json, 'decline', false); if (data) { delete state.invites[data.path][data.uid]; diff --git a/pkg/interface/src/reducers/launch-update.js b/pkg/interface/src/reducers/launch-update.ts similarity index 67% rename from pkg/interface/src/reducers/launch-update.js rename to pkg/interface/src/reducers/launch-update.ts index a46e0f2c82..5e74af7933 100644 --- a/pkg/interface/src/reducers/launch-update.js +++ b/pkg/interface/src/reducers/launch-update.ts @@ -1,7 +1,12 @@ import _ from 'lodash'; +import { LaunchUpdate } from '../types/launch-update'; +import { Cage } from '../types/cage'; +import { StoreState } from '../store/type'; -export default class LaunchReducer { - reduce(json, state) { +type LaunchState = Pick; + +export default class LaunchReducer { + reduce(json: Cage, state: S) { const data = _.get(json, 'launch-update', false); if (data) { this.initial(data, state); @@ -18,32 +23,32 @@ export default class LaunchReducer { const locationData = _.get(json, 'location', false); if (locationData) { - state.location = locationData; + state.userLocation = locationData; } } - initial(json, state) { + initial(json: LaunchUpdate, state: S) { const data = _.get(json, 'initial', false); if (data) { state.launch = data; } } - changeFirstTime(json, state) { + changeFirstTime(json: LaunchUpdate, state: S) { const data = _.get(json, 'changeFirstTime', false); if (data) { state.launch.firstTime = data; } } - changeOrder(json, state) { + changeOrder(json: LaunchUpdate, state: S) { const data = _.get(json, 'changeOrder', false); if (data) { state.launch.tileOrdering = data; } } - changeIsShown(json, state) { + changeIsShown(json: LaunchUpdate, state: S) { const data = _.get(json, 'changeIsShown', false); console.log(json, data); if (data) { diff --git a/pkg/interface/src/reducers/link-update.js b/pkg/interface/src/reducers/link-update.ts similarity index 70% rename from pkg/interface/src/reducers/link-update.js rename to pkg/interface/src/reducers/link-update.ts index 027a5c56f0..d960ec0bb7 100644 --- a/pkg/interface/src/reducers/link-update.js +++ b/pkg/interface/src/reducers/link-update.ts @@ -1,20 +1,28 @@ import _ from 'lodash'; +import { StoreState } from '../store/type'; +import { LinkUpdate, Pagination } from '../types/link-update'; // page size as expected from link-view. // must change in parallel with the +page-size in /app/link-view to // ensure sane behavior. const PAGE_SIZE = 25; -export default class LinkUpdateReducer { - reduce(json, state) { - this.submissionsPage(json, state); - this.submissionsUpdate(json, state); - this.discussionsPage(json, state); - this.discussionsUpdate(json, state); - this.observationUpdate(json, state); +type LinkState = Pick; + +export default class LinkUpdateReducer { + reduce(json: any, state: S) { + const data = _.get(json, 'link-update', false); + if(data) { + this.submissionsPage(data, state); + this.submissionsUpdate(data, state); + this.discussionsPage(data, state); + this.discussionsUpdate(data, state); + this.observationUpdate(data, state); + } + } - submissionsPage(json, state) { + submissionsPage(json: LinkUpdate, state: S) { const data = _.get(json, 'initial-submissions', false); if (data) { // { "initial-submissions": { @@ -32,7 +40,12 @@ export default class LinkUpdateReducer { // if we didn't have any state for this path yet, initialize. if (!state.links[path]) { - state.links[path] = { local: {} }; + state.links[path] = { + local: {}, + totalItems: here.totalItems, + totalPages: here.totalPages, + unseenCount: here.unseenCount + }; } // since data contains an up-to-date full version of the page, @@ -47,17 +60,17 @@ export default class LinkUpdateReducer { // write seen status to a separate structure, // for easier modification later. - if (!state.seen[path]) { - state.seen[path] = {}; + if (!state.linksSeen[path]) { + state.linksSeen[path] = {}; } (here.page || []).map((submission) => { - state.seen[path][submission.url] = submission.seen; + state.linksSeen[path][submission.url] = submission.seen; }); } } } - submissionsUpdate(json, state) { + submissionsUpdate(json: LinkUpdate, state: S) { const data = _.get(json, 'submissions', false); if (data) { // { "submissions": { @@ -70,7 +83,7 @@ export default class LinkUpdateReducer { // stub in a comment count, which is more or less guaranteed to be 0 data.pages = data.pages.map((submission) => { submission.commentCount = 0; - state.seen[path][submission.url] = false; + state.linksSeen[path][submission.url] = false; return submission; }); @@ -83,7 +96,7 @@ export default class LinkUpdateReducer { } } - discussionsPage(json, state) { + discussionsPage(json: LinkUpdate, state: S) { const data = _.get(json, 'initial-discussions', false); if (data) { // { "initial-discussions": { @@ -100,13 +113,17 @@ export default class LinkUpdateReducer { const page = data.pageNumber; // if we didn't have any state for this path yet, initialize. - if (!state.comments[path]) { - state.comments[path] = {}; + if (!state.linkComments[path]) { + state.linkComments[path] = {}; } - if (!state.comments[path][url]) { - state.comments[path][url] = { local: {} }; - } - const here = state.comments[path][url]; + let comments = {...{ + local: {}, + totalPages: data.totalPages, + totalItems: data.totalItems + }, ...state.linkComments[path][url] }; + + state.linkComments[path][url] = comments; + const here = state.linkComments[path][url]; // since data contains an up-to-date full version of the page, // we can safely overwrite the one in state. @@ -117,7 +134,7 @@ export default class LinkUpdateReducer { } } - discussionsUpdate(json, state) { + discussionsUpdate(json: LinkUpdate, state: S) { const data = _.get(json, 'discussions', false); if (data) { // { "discussions": { @@ -130,13 +147,13 @@ export default class LinkUpdateReducer { const url = data.url; // add new comments to state, update totals - state.comments[path][url] = this._addNewItems( - data.comments, state.comments[path][url] + state.linkComments[path][url] = this._addNewItems( + data.comments || [], state.linkComments[path][url] ); } } - observationUpdate(json, state) { + observationUpdate(json: LinkUpdate, state: S) { const data = _.get(json, 'observation', false); if (data) { // { "observation": { @@ -145,10 +162,10 @@ export default class LinkUpdateReducer { // } } const path = data.path; - if (!state.seen[path]) { - state.seen[path] = {}; + if (!state.linksSeen[path]) { + state.linksSeen[path] = {}; } - const seen = state.seen[path]; + const seen = state.linksSeen[path]; // mark urls as seen data.urls.map((url) => { @@ -163,7 +180,7 @@ export default class LinkUpdateReducer { // - _addNewItems(items, pages, page = 0) { + _addNewItems(items: S[], pages: Pagination, page = 0) { if (!pages) { pages = { local: {}, diff --git a/pkg/interface/src/reducers/listen-update.js b/pkg/interface/src/reducers/listen-update.js deleted file mode 100644 index 401b15ca34..0000000000 --- a/pkg/interface/src/reducers/listen-update.js +++ /dev/null @@ -1,34 +0,0 @@ -import _ from 'lodash'; - -export default class ListenUpdateReducer { - reduce(json, state) { - const data = _.get(json, 'link-listen-update', false); - if (data) { - this.listening(data, state); - this.watch(data, state); - this.leave(data, state); - } - } - - listening(json, state) { - const data = _.get(json, 'listening', false); - if (data) { - state.listening = new Set(data); - } - } - - watch(json, state) { - const data = _.get(json, 'watch', false); - if (data) { - state.listening.add(data); - } - } - - leave(json, state) { - const data = _.get(json, 'leave', false); - if (data) { - state.listening.delete(data); - } - } -} - diff --git a/pkg/interface/src/reducers/listen-update.ts b/pkg/interface/src/reducers/listen-update.ts new file mode 100644 index 0000000000..0182048703 --- /dev/null +++ b/pkg/interface/src/reducers/listen-update.ts @@ -0,0 +1,39 @@ +import _ from 'lodash'; +import { StoreState } from '../store/type'; +import { Cage } from '../types/cage'; +import { LinkListenUpdate } from '../types/link-listen-update'; + +type LinkListenState = Pick; + +export default class LinkListenReducer { + reduce(json: Cage, state: S) { + const data = _.get(json, 'link-listen-update', false); + if (data) { + this.listening(data, state); + this.watch(data, state); + this.leave(data, state); + } + } + + listening(json: LinkListenUpdate, state: S) { + const data = _.get(json, 'listening', false); + if (data) { + state.linkListening = new Set(data); + } + } + + watch(json: LinkListenUpdate, state: S) { + const data = _.get(json, 'watch', false); + if (data) { + state.linkListening.add(data); + } + } + + leave(json: LinkListenUpdate, state: S) { + const data = _.get(json, 'leave', false); + if (data) { + state.linkListening.delete(data); + } + } +} + diff --git a/pkg/interface/src/reducers/local.js b/pkg/interface/src/reducers/local.js deleted file mode 100644 index 2df3edb4b1..0000000000 --- a/pkg/interface/src/reducers/local.js +++ /dev/null @@ -1,25 +0,0 @@ -import _ from 'lodash'; - -export default class LocalReducer { - reduce(json, state) { - const data = _.get(json, 'local', false); - if (data) { - this.sidebarToggle(data, state); - this.setSelected(data, state); - } - } - - sidebarToggle(obj, state) { - const data = _.has(obj, 'sidebarToggle', false); - if (data) { - state.sidebarShown = obj.sidebarToggle; - } - } - - setSelected(obj, state) { - const data = _.has(obj, 'selected', false); - if (data) { - state.selectedGroups = obj.selected; - } - } -} diff --git a/pkg/interface/src/reducers/local.ts b/pkg/interface/src/reducers/local.ts new file mode 100644 index 0000000000..2825a9152f --- /dev/null +++ b/pkg/interface/src/reducers/local.ts @@ -0,0 +1,28 @@ +import _ from 'lodash'; +import { StoreState } from '../store/type'; +import { Cage } from '../types/cage'; +import { LocalUpdate } from '../types/local-update'; + +type LocalState = Pick; + +export default class LocalReducer { + reduce(json: Cage, state: S) { + const data = json['local']; + if (data) { + this.sidebarToggle(data, state); + this.setSelected(data, state); + } + } + + sidebarToggle(obj: LocalUpdate, state: S) { + if ('sidebarToggle' in obj) { + state.sidebarShown = !state.sidebarShown; + } + } + + setSelected(obj: LocalUpdate, state: S) { + if ('selected' in obj) { + state.selectedGroups = obj.selected; + } + } +} diff --git a/pkg/interface/src/reducers/metadata-update.js b/pkg/interface/src/reducers/metadata-update.ts similarity index 79% rename from pkg/interface/src/reducers/metadata-update.js rename to pkg/interface/src/reducers/metadata-update.ts index 58fd1d257a..43d8b0492e 100644 --- a/pkg/interface/src/reducers/metadata-update.js +++ b/pkg/interface/src/reducers/metadata-update.ts @@ -1,8 +1,15 @@ import _ from 'lodash'; -export default class MetadataReducer { - reduce(json, state) { - let data = _.get(json, 'metadata-update', false); +import { StoreState } from '../store/type'; + +import { MetadataUpdate } from '../types/metadata-update'; +import { Cage } from '../types/cage'; + +type MetadataState = Pick; + +export default class MetadataReducer { + reduce(json: Cage, state: S) { + let data = json['metadata-update'] if (data) { console.log('data: ', data); this.associations(data, state); @@ -13,7 +20,7 @@ export default class MetadataReducer { } } - associations(json, state) { + associations(json: MetadataUpdate, state: S) { let data = _.get(json, 'associations', false); if (data) { let metadata = state.associations; @@ -34,7 +41,7 @@ export default class MetadataReducer { } } - add(json, state) { + add(json: MetadataUpdate, state: S) { let data = _.get(json, 'add', false); if (data) { let metadata = state.associations; @@ -53,7 +60,7 @@ export default class MetadataReducer { } } - update(json, state) { + update(json: MetadataUpdate, state: S) { let data = _.get(json, 'update-metadata', false); if (data) { let metadata = state.associations; @@ -72,7 +79,7 @@ export default class MetadataReducer { } } - remove(json, state) { + remove(json: MetadataUpdate, state: S) { let data = _.get(json, 'remove', false); if (data) { let metadata = state.associations; diff --git a/pkg/interface/src/reducers/permission-update.js b/pkg/interface/src/reducers/permission-update.ts similarity index 68% rename from pkg/interface/src/reducers/permission-update.js rename to pkg/interface/src/reducers/permission-update.ts index 929ee9dfde..6fc70188c7 100644 --- a/pkg/interface/src/reducers/permission-update.js +++ b/pkg/interface/src/reducers/permission-update.ts @@ -1,7 +1,12 @@ import _ from 'lodash'; +import { StoreState } from '../store/type'; +import { Cage } from '../types/cage'; +import { PermissionUpdate } from '../types/permission-update'; -export default class PermissionReducer { - reduce(json, state) { +type PermissionState = Pick; + +export default class PermissionReducer { + reduce(json: Cage, state: S) { const data = _.get(json, 'permission-update', false); if (data) { this.initial(data, state); @@ -12,7 +17,7 @@ export default class PermissionReducer { } } - initial(json, state) { + initial(json: PermissionUpdate, state: S) { const data = _.get(json, 'initial', false); if (data) { for (const perm in data) { @@ -24,7 +29,7 @@ export default class PermissionReducer { } } - create(json, state) { + create(json: PermissionUpdate, state: S) { const data = _.get(json, 'create', false); if (data) { state.permissions[data.path] = { @@ -34,14 +39,14 @@ export default class PermissionReducer { } } - delete(json, state) { + delete(json: PermissionUpdate, state: S) { const data = _.get(json, 'delete', false); if (data) { delete state.permissions[data.path]; } } - add(json, state) { + add(json: PermissionUpdate, state: S) { const data = _.get(json, 'add', false); if (data) { for (const member of data.who) { @@ -50,7 +55,7 @@ export default class PermissionReducer { } } - remove(json, state) { + remove(json: PermissionUpdate, state: S) { const data = _.get(json, 'remove', false); if (data) { for (const member of data.who) { diff --git a/pkg/interface/src/reducers/publish-response.js b/pkg/interface/src/reducers/publish-response.ts similarity index 96% rename from pkg/interface/src/reducers/publish-response.js rename to pkg/interface/src/reducers/publish-response.ts index d4cd66f025..260cae526d 100644 --- a/pkg/interface/src/reducers/publish-response.js +++ b/pkg/interface/src/reducers/publish-response.ts @@ -1,7 +1,11 @@ import _ from 'lodash'; +import { StoreState } from '../store/type'; +import { Cage } from '../types/cage'; -export default class PublishResponseReducer { - reduce(json, state) { +type PublishState = Pick; + +export default class PublishResponseReducer { + reduce(json: Cage, state: S) { const data = _.get(json, 'publish-response', false); if (!data) { return; } switch(data.type) { @@ -194,12 +198,4 @@ export default class PublishResponseReducer { throw Error("tried to fetch paginated comments, but we don't have the note"); } } - - sidebarToggle(json, state) { - let data = _.has(json.data, 'sidebarToggle', false); - if (data) { - state.sidebarShown = json.data.sidebarToggle; - } - } - } diff --git a/pkg/interface/src/reducers/publish-update.js b/pkg/interface/src/reducers/publish-update.ts similarity index 92% rename from pkg/interface/src/reducers/publish-update.js rename to pkg/interface/src/reducers/publish-update.ts index 7d0d963013..91a2c0d0b5 100644 --- a/pkg/interface/src/reducers/publish-update.js +++ b/pkg/interface/src/reducers/publish-update.ts @@ -1,9 +1,21 @@ import _ from 'lodash'; -export default class PublishUpdateReducer { - reduce(preJson, state){ - let json = _.get(preJson, "publish-update", false); - switch(Object.keys(json)[0]){ +import { PublishUpdate } from '../types/publish-update'; +import { Cage } from '../types/cage'; +import { StoreState } from '../store/type'; +import { getTagFromFrond } from '../types/noun'; + +type PublishState = Pick; + + +export default class PublishUpdateReducer { + reduce(data: Cage, state: S){ + let json = data["publish-update"]; + if(!json) { + return; + } + const tag = getTagFromFrond(json); + switch(tag){ case "add-book": this.addBook(json["add-book"], state); break; @@ -39,7 +51,7 @@ export default class PublishUpdateReducer { } } - addBook(json, state) { + addBook(json, state: S) { let host = Object.keys(json)[0]; let book = Object.keys(json[host])[0]; if (state.notebooks[host]) { @@ -49,7 +61,7 @@ export default class PublishUpdateReducer { } } - addNote(json, state) { + addNote(json, state: S) { let host = Object.keys(json)[0]; let book = Object.keys(json[host])[0]; let noteId = json[host][book]["note-id"]; @@ -77,13 +89,13 @@ export default class PublishUpdateReducer { let prevNoteId = state.notebooks[host][book]["notes-by-date"][1] || null; state.notebooks[host][book].notes[noteId]["prev-note"] = prevNoteId state.notebooks[host][book].notes[noteId]["next-note"] = null; - if (state.notebooks[host][book].notes[prevNoteId]) { + if (prevNoteId && state.notebooks[host][book].notes[prevNoteId]) { state.notebooks[host][book].notes[prevNoteId]["next-note"] = noteId; } } } - addComment(json, state) { + addComment(json, state: S) { let host = json.host let book = json.book let note = json.note @@ -97,7 +109,7 @@ export default class PublishUpdateReducer { if (state.notebooks[host][book].notes[note].comments) { let limboCommentIdx = _.findIndex(state.notebooks[host][book].notes[note].comments, (o) => { - let oldVal = o[Object.keys(o)[0]]; + let oldVal = o[getTagFromFrond(o)]; let newVal = comment[Object.keys(comment)[0]]; return (oldVal.pending && (oldVal.author === newVal.author) && diff --git a/pkg/interface/src/reducers/s3-update.js b/pkg/interface/src/reducers/s3-update.ts similarity index 63% rename from pkg/interface/src/reducers/s3-update.js rename to pkg/interface/src/reducers/s3-update.ts index 47c397e519..1915feec13 100644 --- a/pkg/interface/src/reducers/s3-update.js +++ b/pkg/interface/src/reducers/s3-update.ts @@ -1,7 +1,12 @@ import _ from 'lodash'; +import { StoreState } from '../store/type'; +import { Cage } from '../types/cage'; +import { S3Update } from '../types/s3-update'; -export default class S3Reducer{ - reduce(json, state) { +type S3State = Pick; + +export default class S3Reducer { + reduce(json: Cage, state: S) { const data = _.get(json, 's3-update', false); if (data) { this.credentials(data, state); @@ -15,14 +20,14 @@ export default class S3Reducer{ } } - credentials(json, state) { + credentials(json: S3Update, state: S) { const data = _.get(json, 'credentials', false); if (data) { state.s3.credentials = data; } } - configuration(json, state) { + configuration(json: S3Update, state: S) { const data = _.get(json, 'configuration', false); if (data) { state.s3.configuration = { @@ -32,14 +37,14 @@ export default class S3Reducer{ } } - currentBucket(json, state) { + currentBucket(json: S3Update, state: S) { const data = _.get(json, 'setCurrentBucket', false); - if (data) { - state.s3.configuration.currentBucket = data; + if (data && state.s3) { + } } - addBucket(json, state) { + addBucket(json: S3Update, state: S) { const data = _.get(json, 'addBucket', false); if (data) { state.s3.configuration.buckets = @@ -47,31 +52,30 @@ export default class S3Reducer{ } } - removeBucket(json, state) { + removeBucket(json: S3Update, state: S) { const data = _.get(json, 'removeBucket', false); if (data) { - state.s3.configuration.buckets = - state.s3.configuration.buckets.delete(data); + state.s3.configuration.buckets.delete(data); } } - endpoint(json, state) { + endpoint(json: S3Update, state: S) { const data = _.get(json, 'setEndpoint', false); - if (data) { + if (data && state.s3.credentials) { state.s3.credentials.endpoint = data; } } - accessKeyId(json, state) { + accessKeyId(json: S3Update , state: S) { const data = _.get(json, 'setAccessKeyId', false); - if (data) { + if (data && state.s3.credentials) { state.s3.credentials.accessKeyId = data; } } - secretAccessKey(json, state) { + secretAccessKey(json: S3Update, state: S) { const data = _.get(json, 'setSecretAccessKey', false); - if (data) { + if (data && state.s3.credentials) { state.s3.credentials.secretAccessKey = data; } } diff --git a/pkg/interface/src/store/base.js b/pkg/interface/src/store/base.ts similarity index 63% rename from pkg/interface/src/store/base.js rename to pkg/interface/src/store/base.ts index d54a23bedd..da026c33ed 100644 --- a/pkg/interface/src/store/base.js +++ b/pkg/interface/src/store/base.ts @@ -1,20 +1,21 @@ -export default class BaseStore { +export default class BaseStore { + state: S; + setState: (s: Partial) => void = (s) => {}; constructor() { this.state = this.initialState(); - this.setState = () => {}; } initialState() { - return {}; + return {} as S; } - setStateHandler(setState) { + setStateHandler(setState: (s: Partial) => void) { this.setState = setState; } clear() { this.handleEvent({ - data: { clear: true } + data: { clear: true }, }); } @@ -25,7 +26,7 @@ export default class BaseStore { return; } - if ('clear' in json && json.clear) { + if ("clear" in json && json.clear) { this.setState(this.initialState()); return; } @@ -38,4 +39,3 @@ export default class BaseStore { // extend me! } } - diff --git a/pkg/interface/src/store/chat.js b/pkg/interface/src/store/chat.js deleted file mode 100644 index fc3881b992..0000000000 --- a/pkg/interface/src/store/chat.js +++ /dev/null @@ -1,51 +0,0 @@ -import ContactReducer from '../reducers/contact-update'; -import ChatReducer from '../reducers/chat-update'; -import InviteReducer from '../reducers/invite-update'; -import PermissionReducer from '../reducers/permission-update'; -import MetadataReducer from '../reducers/metadata-update'; -import S3Reducer from '../reducers/s3-update'; -import LocalReducer from '../reducers/local'; - -import BaseStore from './base'; - -export default class ChatStore extends BaseStore { - constructor() { - super(); - this.permissionReducer = new PermissionReducer(); - this.contactReducer = new ContactReducer(); - this.chatReducer = new ChatReducer(); - this.inviteReducer = new InviteReducer(); - this.s3Reducer = new S3Reducer(); - this.metadataReducer = new MetadataReducer(); - this.localReducer = new LocalReducer(); - } - - initialState() { - return { - inbox: {}, - chatSynced: null, - contacts: {}, - permissions: {}, - invites: {}, - associations: { - chat: {}, - contacts: {} - }, - sidebarShown: true, - pendingMessages: new Map([]), - chatInitialized: false, - s3: {} - }; - } - - reduce(data, state) { - this.permissionReducer.reduce(data, this.state); - this.contactReducer.reduce(data, this.state); - this.chatReducer.reduce(data, this.state); - this.inviteReducer.reduce(data, this.state); - this.metadataReducer.reduce(data, this.state); - this.localReducer.reduce(data, this.state); - this.s3Reducer.reduce(data, this.state); - } -} - diff --git a/pkg/interface/src/store/store.ts b/pkg/interface/src/store/store.ts new file mode 100644 index 0000000000..71021e80e5 --- /dev/null +++ b/pkg/interface/src/store/store.ts @@ -0,0 +1,92 @@ +import BaseStore from './base'; +import InviteReducer from '../reducers/invite-update'; +import MetadataReducer from '../reducers/metadata-update'; +import LocalReducer from '../reducers/local'; +import ChatReducer from '../reducers/chat-update'; + +import { StoreState } from './type'; +import { Cage } from '../types/cage'; +import ContactReducer from '../reducers/contact-update'; +import LinkUpdateReducer from '../reducers/link-update'; +import S3Reducer from '../reducers/s3-update'; +import GroupReducer from '../reducers/group-update'; +import PermissionReducer from '../reducers/permission-update'; +import PublishUpdateReducer from '../reducers/publish-update'; +import PublishResponseReducer from '../reducers/publish-response'; +import LaunchReducer from '../reducers/launch-update'; +import LinkListenReducer from '../reducers/listen-update'; + + +export default class GlobalStore extends BaseStore { + inviteReducer = new InviteReducer(); + metadataReducer = new MetadataReducer(); + localReducer = new LocalReducer(); + chatReducer = new ChatReducer(); + contactReducer = new ContactReducer(); + linkReducer = new LinkUpdateReducer(); + linkListenReducer = new LinkListenReducer(); + s3Reducer = new S3Reducer(); + groupReducer = new GroupReducer(); + permissionReducer = new PermissionReducer(); + publishUpdateReducer = new PublishUpdateReducer(); + publishResponseReducer = new PublishResponseReducer(); + launchReducer = new LaunchReducer(); + + + initialState(): StoreState { + return { + pendingMessages: new Map(), + chatInitialized: false, + sidebarShown: true, + invites: {}, + associations: { + chat: {}, + contacts: {}, + link: {}, + publish: {} + }, + groups: {}, + groupKeys: new Set(), + launch: { + firstTime: false, + tileOrdering: [], + tiles: {}, + }, + weather: {}, + userLocation: null, + permissions: {}, + s3: { + configuration: { + buckets: new Set(), + currentBucket: '' + }, + credentials: null + }, + links: {}, + linksSeen: {}, + linkListening: new Set(), + linkComments: {}, + notebooks: {}, + contacts: {}, + selectedGroups: [], + inbox: {}, + chatSynced: null, + }; + } + + reduce(data: Cage, state: StoreState) { + this.inviteReducer.reduce(data, this.state); + this.metadataReducer.reduce(data, this.state); + this.localReducer.reduce(data, this.state); + this.chatReducer.reduce(data, this.state); + this.contactReducer.reduce(data, this.state); + this.linkReducer.reduce(data, this.state); + this.s3Reducer.reduce(data, this.state); + this.groupReducer.reduce(data, this.state); + this.permissionReducer.reduce(data, this.state); + this.publishUpdateReducer.reduce(data, this.state); + this.publishResponseReducer.reduce(data, this.state); + this.launchReducer.reduce(data, this.state); + this.linkListenReducer.reduce(data, this.state); + } +} diff --git a/pkg/interface/src/store/type.ts b/pkg/interface/src/store/type.ts new file mode 100644 index 0000000000..bd82148fe0 --- /dev/null +++ b/pkg/interface/src/store/type.ts @@ -0,0 +1,52 @@ +import { Inbox, Envelope } from '../types/chat-update'; +import { ChatHookUpdate } from '../types/chat-hook-update'; +import { Path } from '../types/noun'; +import { Invites } from '../types/invite-update'; +import { SelectedGroup } from '../types/local-update'; +import { Associations } from '../types/metadata-update'; +import { Rolodex } from '../types/contact-update'; +import { Notebooks } from '../types/publish-update'; +import { Groups } from '../types/group-update'; +import { S3State } from '../types/s3-update'; +import { Permissions } from '../types/permission-update'; +import { LaunchState, WeatherState } from '../types/launch-update'; +import { LinkComments, LinkCollections, LinkSeen } from '../types/link-update'; + +export interface StoreState { + // local state + sidebarShown: boolean; + selectedGroups: SelectedGroup[]; + // invite state + invites: Invites; + // metadata state + associations: Associations; + // contact state + contacts: Rolodex; + // groups state + groups: Groups; + groupKeys: Set; + permissions: Permissions; + s3: S3State; + + + // App specific states + // launch state + launch: LaunchState; + weather: WeatherState | {} | null; + userLocation: string | null; + + // links state + linksSeen: LinkSeen; + linkListening: Set; + links: LinkCollections; + linkComments: LinkComments; + + // publish state + notebooks: Notebooks; + + // Chat state + chatInitialized: boolean; + chatSynced: ChatHookUpdate | null; + inbox: Inbox; + pendingMessages: Map; +} diff --git a/pkg/interface/src/subscription/base.js b/pkg/interface/src/subscription/base.ts similarity index 53% rename from pkg/interface/src/subscription/base.js rename to pkg/interface/src/subscription/base.ts index d710425e25..7a4e6fdb7b 100644 --- a/pkg/interface/src/subscription/base.js +++ b/pkg/interface/src/subscription/base.ts @@ -1,8 +1,9 @@ -export default class BaseSubscription { - constructor(store, api, channel) { - this.store = store; - this.api = api; - this.channel = channel; +import BaseStore from "../store/base"; +import BaseApi from "../api/base"; +import { Path } from "../types/noun"; + +export default class BaseSubscription { + constructor(public store: BaseStore, public api: BaseApi, public channel: any) { this.channel.setOnChannelError(this.onChannelError.bind(this)); } @@ -12,14 +13,14 @@ export default class BaseSubscription { onChannelError(err) { console.error('event source error: ', err); - setTimeout(2000, () => { + setTimeout(() => { this.store.clear(); this.start(); - }); + }, 2000); } - subscribe(path, app) { - this.api.subscribe(path, 'PUT', this.api.ship, app, + subscribe(path: Path, app: string) { + return this.api.subscribe(path, 'PUT', this.api.ship, app, this.handleEvent.bind(this), (err) => { console.log(err); @@ -30,6 +31,10 @@ export default class BaseSubscription { }); } + unsubscribe(id: number) { + this.api.unsubscribe(id); + } + start() { // extend } diff --git a/pkg/interface/src/subscription/global.js b/pkg/interface/src/subscription/global.js deleted file mode 100644 index 993b885aae..0000000000 --- a/pkg/interface/src/subscription/global.js +++ /dev/null @@ -1,9 +0,0 @@ -import BaseSubscription from './base'; - -export default class GlobalSubscription extends BaseSubscription { - start() { - this.subscribe('/all', 'invite-store'); - this.subscribe('/app-name/contacts', 'metadata-store'); - } -} - diff --git a/pkg/interface/src/subscription/global.ts b/pkg/interface/src/subscription/global.ts new file mode 100644 index 0000000000..e7682c8eb3 --- /dev/null +++ b/pkg/interface/src/subscription/global.ts @@ -0,0 +1,68 @@ +import BaseSubscription from './base'; +import { StoreState } from '../store/type'; +import { Path } from '../types/noun'; + + +/** + * Path to subscribe on and app to subscribe to + */ +type AppSubscription = [Path, string]; + +const chatSubscriptions: AppSubscription[] = [ + ['/primary', 'chat-view'], + ['/synced', 'chat-hook'] +]; + +const publishSubscriptions: AppSubscription[] = [ + ['/primary', 'publish'], + ['/all', 'group-store'] +]; + +const linkSubscriptions: AppSubscription[] = [ + ['/json/seen', 'link-view'], + ['/listening', 'link-listen-hook'] +] + +const groupSubscriptions: AppSubscription[] = [ + ['/all', 'group-store'], + ['/synced', 'contact-hook'] +]; + +type AppName = 'publish' | 'chat' | 'link' | 'groups'; +const appSubscriptions: Record = { + chat: chatSubscriptions, + publish: publishSubscriptions, + link: linkSubscriptions, + groups: groupSubscriptions +}; + +export default class GlobalSubscription extends BaseSubscription { + openSubscriptions: Record = { + chat: [], + publish: [], + link: [], + groups: [] + }; + start() { + this.subscribe('/all', 'invite-store'); + this.subscribe('/all', 'permission-store'); + this.subscribe('/primary', 'contact-view'); + this.subscribe('/all', 'metadata-store'); + this.subscribe('/all', 's3-store'); + this.subscribe('/all', 'launch'); + this.subscribe('/all', 'weather'); + } + + startApp(app: AppName) { + if(this.openSubscriptions[app].length > 0) { + console.log(`${app} already started`); + return; + } + this.openSubscriptions[app] = appSubscriptions[app].map(([path, agent]) => this.subscribe(path, agent)); + } + + stopApp(app: AppName) { + this.openSubscriptions[app].map(id => this.unsubscribe(id)) + this.openSubscriptions[app] = []; + } +} diff --git a/pkg/interface/src/types/cage.ts b/pkg/interface/src/types/cage.ts new file mode 100644 index 0000000000..6ff126bef2 --- /dev/null +++ b/pkg/interface/src/types/cage.ts @@ -0,0 +1,35 @@ +import { ChatUpdate } from "./chat-update"; +import { ChatHookUpdate } from "./chat-hook-update"; +import { ContactUpdate } from "./contact-update"; +import { InviteUpdate } from "./invite-update"; +import { LocalUpdate } from "./local-update"; +import { MetadataUpdate } from "./metadata-update"; +import { PublishUpdate } from './publish-update'; +import { PublishResponse } from "./publish-response"; +import { GroupUpdate } from "./group-update"; +import { PermissionUpdate } from "./permission-update"; +import { LaunchUpdate, WeatherState } from "./launch-update"; +import { LinkListenUpdate } from './link-listen-update'; + +interface MarksToTypes { + readonly json: any; + readonly "chat-update": ChatUpdate; + readonly "chat-hook-update": ChatHookUpdate; + readonly "contact-update": ContactUpdate; + readonly "invite-update": InviteUpdate; + readonly "metadata-update": MetadataUpdate; + readonly 'publish-update': PublishUpdate; + readonly "publish-response": PublishResponse; + readonly "group-update": GroupUpdate; + readonly "permission-update": PermissionUpdate; + readonly "launch-update": LaunchUpdate; + readonly "link-listen-update": LinkListenUpdate; + // not really marks but w/e + readonly 'local': LocalUpdate; + readonly 'weather': WeatherState | {}; + readonly 'location': string; +} + +export type Cage = Partial; + +export type Mark = keyof MarksToTypes; diff --git a/pkg/interface/src/types/chat-hook-update.ts b/pkg/interface/src/types/chat-hook-update.ts new file mode 100644 index 0000000000..3ee335407c --- /dev/null +++ b/pkg/interface/src/types/chat-hook-update.ts @@ -0,0 +1,5 @@ +import { Patp } from './noun'; + +export interface ChatHookUpdate { + [p: string]: Patp; +} diff --git a/pkg/interface/src/types/chat-update.ts b/pkg/interface/src/types/chat-update.ts new file mode 100644 index 0000000000..63b23eee11 --- /dev/null +++ b/pkg/interface/src/types/chat-update.ts @@ -0,0 +1,95 @@ +import { Path, Patp } from './noun'; + +export type ChatUpdate = + ChatUpdateInitial +| ChatUpdateCreate +| ChatUpdateDelete +| ChatUpdateMessage +| ChatUpdateMessages +| ChatUpdateRead; + +export type ChatAction = + ChatUpdateCreate +| ChatUpdateDelete +| ChatUpdateMessage +| ChatUpdateRead; + +interface ChatUpdateInitial { + initial: Inbox; +} + +interface ChatUpdateCreate { + create: Path; +} + +interface ChatUpdateDelete { + delete: Path; +} + +interface ChatUpdateMessage { + message: { + path: Path; + envelope: Envelope; + } +} + +interface ChatUpdateMessages { + messages: { + path: Path; + envelopes: Envelope[]; + } +} + +interface ChatUpdateRead { + read: { + path: Path; + }; +} + + + +// Data structures +// TODO: move to seperate file? + +export interface Inbox { + [chatName: string]: Mailbox; +} + +interface Mailbox { + config: MailboxConfig; + envelopes: Envelope[]; +} + +interface MailboxConfig { + length: number; + read: number; +} + +export interface Envelope { + uid: string; + number: number; + author: Patp; + when: string; + letter: Letter; +} + +interface LetterText { + text: string; +} + +interface LetterUrl { + url: string; +} + +interface LetterCode { + code: { + expression: string; + output: string; + } +} + +interface LetterMe { + narrative: string; +} + +export type Letter = LetterText | LetterUrl | LetterCode | LetterMe; diff --git a/pkg/interface/src/types/contact-update.ts b/pkg/interface/src/types/contact-update.ts new file mode 100644 index 0000000000..c08509af31 --- /dev/null +++ b/pkg/interface/src/types/contact-update.ts @@ -0,0 +1,85 @@ +import { Path, Patp } from "./noun"; + +export type ContactUpdate = + | ContactUpdateCreate + | ContactUpdateDelete + | ContactUpdateAdd + | ContactUpdateRemove + | ContactUpdateEdit + | ContactUpdateInitial + | ContactUpdateContacts; + +interface ContactUpdateCreate { + create: Path; +} + +interface ContactUpdateDelete { + delete: Path; +} + +interface ContactUpdateAdd { + add: { + path: Path; + ship: Patp; + contact: Contact; + }; +} + +interface ContactUpdateRemove { + remove: { + path: Path; + ship: Patp; + }; +} + +interface ContactUpdateEdit { + edit: { + path: Path; + ship: Patp; + "edit-field": ContactEdit; + }; +} + +interface ContactUpdateInitial { + initial: Rolodex; +} + +interface ContactUpdateContacts { + contacts: { + path: Path; + contacts: Contacts; + }; +} + +// + +type ContactAvatar = ContactAvatarUrl | ContactAvatarOcts; + +export type Rolodex = { + [p in Path]: Contacts; +}; + +export type Contacts = { + [p in Patp]: Contact; +}; + +interface ContactAvatarUrl { + url: string; +} + +interface ContactAvatarOcts { + octs: string; +} +export interface Contact { + nickname: string; + email: string; + phone: string; + website: string; + notes: string; + color: string; + avatar: ContactAvatar | null; +} + +export type ContactEdit = { + [k in keyof Contact]: Contact[k]; +}; diff --git a/pkg/interface/src/types/global.ts b/pkg/interface/src/types/global.ts new file mode 100644 index 0000000000..d43a77b1b7 --- /dev/null +++ b/pkg/interface/src/types/global.ts @@ -0,0 +1,7 @@ +import { PatpNoSig } from "./noun"; + +declare global { + interface Window { + ship: PatpNoSig; + } +} diff --git a/pkg/interface/src/types/group-update.ts b/pkg/interface/src/types/group-update.ts new file mode 100644 index 0000000000..588468f270 --- /dev/null +++ b/pkg/interface/src/types/group-update.ts @@ -0,0 +1,59 @@ +import { PatpNoSig, Path } from './noun'; + +export type Group = Set + +export type Groups = { + [p in Path]: Group; +} + +interface GroupUpdateInitial { + initial: Groups; +} + +interface GroupUpdateAdd { + add: { + members: PatpNoSig[]; + path: Path; + } +} + +interface GroupUpdateRemove { + remove: { + members: PatpNoSig[]; + path: Path; + } +} + +interface GroupUpdateBundle { + bundle: { + path: Path; + } +} + +interface GroupUpdateUnbundle { + unbundle: { + path: Path; + } +} + +interface GroupUpdateKeys { + keys: { + keys: Path[]; + } +} + +interface GroupUpdatePath { + path: { + path: Path; + members: PatpNoSig[]; + } +} + +export type GroupUpdate = + GroupUpdateInitial +| GroupUpdateAdd +| GroupUpdateRemove +| GroupUpdateBundle +| GroupUpdateUnbundle +| GroupUpdateKeys +| GroupUpdatePath; diff --git a/pkg/interface/src/types/invite-update.ts b/pkg/interface/src/types/invite-update.ts new file mode 100644 index 0000000000..a1eb2ed917 --- /dev/null +++ b/pkg/interface/src/types/invite-update.ts @@ -0,0 +1,67 @@ +import { Serial, PatpNoSig, Path } from './noun'; + +export type InviteUpdate = + InviteUpdateInitial +| InviteUpdateCreate +| InviteUpdateDelete +| InviteUpdateInvite +| InviteUpdateAccepted +| InviteUpdateDecline; + + +interface InviteUpdateInitial { + initial: Invites; +} + +interface InviteUpdateCreate { + create: { + path: Path; + }; +} + +interface InviteUpdateDelete { + delete: { + path: Path; + }; +} + +interface InviteUpdateInvite { + invite: { + path: Path; + uid: Serial; + invite: Invite; + }; +} + +interface InviteUpdateAccepted { + accepted: { + path: Path; + uid: Serial; + }; +} + +interface InviteUpdateDecline { + decline: { + path: Path; + uid: Serial; + }; +} + +// actual datastructures + + +export type Invites = { + [p in Path]: AppInvites; +}; + +export type AppInvites = { + [s in Serial]: Invite; +}; + +export interface Invite { + app: string; + path: Path; + recipeint: PatpNoSig; + ship: PatpNoSig; + text: string; +} diff --git a/pkg/interface/src/types/launch-update.ts b/pkg/interface/src/types/launch-update.ts new file mode 100644 index 0000000000..b8a337b5ef --- /dev/null +++ b/pkg/interface/src/types/launch-update.ts @@ -0,0 +1,83 @@ + +export type LaunchUpdate = + LaunchUpdateInitial +| LaunchUpdateFirstTime +| LaunchUpdateOrder +| LaunchUpdateIsShown; + + +interface LaunchUpdateInitial { + initial: LaunchState; +} + +interface LaunchUpdateFirstTime { + changeFirstTime: boolean; +} + +interface LaunchUpdateOrder { + changeOrder: string[]; +} + +interface LaunchUpdateIsShown { + changeIsShown: { + name: string; + isShown: boolean; + } +} + +export interface LaunchState { + firstTime: boolean; + tileOrdering: string[]; + tiles: { + [app: string]: Tile; + } +} + +interface Tile { + isShown: boolean; + type: TileType; +} + +type TileType = TileTypeBasic | TileTypeCustom; + +interface TileTypeBasic { + basic: { + iconUrl: string; + linkedUrl: string; + title: string; + } +} + +interface TileTypeCustom { + custom: null; +} + +interface WeatherDay { + apparentTemperature: number; + cloudCover: number; + dewPoint: number; + humidity: number; + icon: string; + ozone: number; + precipIntensity: number; + precipProbability: number; + precipType: string; + pressure: number; + summary: string; + temperature: number; + time: number; + uvIndex: number; + visibility: number; + windBearing: number; + windGust: number; + windSpeed: number; +} + +export interface WeatherState { + currently: WeatherDay; + daily: { + data: WeatherDay[]; + icon: string; + summary: string; + } +} diff --git a/pkg/interface/src/types/link-listen-update.ts b/pkg/interface/src/types/link-listen-update.ts new file mode 100644 index 0000000000..3ba9f76c7b --- /dev/null +++ b/pkg/interface/src/types/link-listen-update.ts @@ -0,0 +1,18 @@ +import { Path } from './noun'; + +interface LinkListenUpdateListening { + listening: Path[]; +} + +interface LinkListenUpdateWatch { + watch: Path; +} + +interface LinkListenUpdateLeave { + leave: Path; +} + +export type LinkListenUpdate = + LinkListenUpdateListening +| LinkListenUpdateWatch +| LinkListenUpdateLeave; diff --git a/pkg/interface/src/types/link-update.ts b/pkg/interface/src/types/link-update.ts new file mode 100644 index 0000000000..4cbfeb1d5b --- /dev/null +++ b/pkg/interface/src/types/link-update.ts @@ -0,0 +1,84 @@ +import { PatpNoSig, Path } from "./noun"; + +export type LinkCollections = { + [p in Path]: Collection; +}; + +export type LinkSeen = { + [p in Path]: { + [url: string]: boolean; + }; +}; + +export type Pagination = { + local: LocalPages; + [p: number]: S[]; + totalItems: number; + totalPages: number; +} + +export type LinkComments = { + [p in Path]: { + [url: string]: Pagination & { + totalItems: number; + totalPages: number; + } + } +} + +interface LinkComment { + ship: PatpNoSig; + time: number; + udon: string; +} + +interface CollectionStats { + unseenCount: number; +} + +type LocalPages = { + [p: number]: boolean; +} + +type Collection = CollectionStats & Pagination; + +interface Link { + commentCount: number; + seen: boolean; + ship: PatpNoSig; + time: number; + title: string; + url: string; +} + +interface LinkInitialSubmissions { + 'initial-submissions': { + [p in Path]: CollectionStats & { + pageNumber?: number; + pages?: Link[]; + } + }; +}; + +interface LinkUpdateSubmission { + 'submissions': { + path: Path; + pages: Link[]; + } +} + +interface LinkInitialDiscussion { + 'intitial-discussion': { + path: Path; + url: string; + page: Comment[]; + totalItems: number; + totalPages: number; + pageNumber: number; + } +} + +export type LinkUpdate = + LinkInitialSubmissions +| LinkUpdateSubmission +| LinkInitialDiscussion; diff --git a/pkg/interface/src/types/local-update.ts b/pkg/interface/src/types/local-update.ts new file mode 100644 index 0000000000..f4a5df60ac --- /dev/null +++ b/pkg/interface/src/types/local-update.ts @@ -0,0 +1,15 @@ +import { Path } from './noun'; + +export type LocalUpdate = + LocalUpdateSidebarToggle +| LocalUpdateSelectedGroups; + +interface LocalUpdateSidebarToggle { + sidebarToggle: boolean; +} + +interface LocalUpdateSelectedGroups { + selected: SelectedGroup[]; +} + +export type SelectedGroup = [Path, string]; diff --git a/pkg/interface/src/types/metadata-update.ts b/pkg/interface/src/types/metadata-update.ts new file mode 100644 index 0000000000..1489201f39 --- /dev/null +++ b/pkg/interface/src/types/metadata-update.ts @@ -0,0 +1,54 @@ +import { AppName, Path, Patp } from './noun'; + + +export type MetadataUpdate = + MetadataUpdateInitial +| MetadataUpdateAdd +| MetadataUpdateUpdate +| MetadataUpdateRemove; + +interface MetadataUpdateInitial { + associations: ResourceAssociations; +} + +type ResourceAssociations = { + [p in Path]: Association; +} + +type MetadataUpdateAdd = { + add: Association; +} + +type MetadataUpdateUpdate = { + update: Association; +} + +type MetadataUpdateRemove = { + remove: Resource & { + 'group-path': Path; + } +} + +export type Associations = Record; + +type AppAssociations = { + [p in Path]: Association; +} + +interface Resource { + 'app-path': Path; + 'app-name': AppName; +} + +export type Association = Resource & { + 'group-path': Path; + metadata: Metadata; +}; + +interface Metadata { + color: string; + creator: Patp; + 'date-created': string; + description: string; + title: string; +} diff --git a/pkg/interface/src/types/noun.ts b/pkg/interface/src/types/noun.ts new file mode 100644 index 0000000000..1cda24f02c --- /dev/null +++ b/pkg/interface/src/types/noun.ts @@ -0,0 +1,25 @@ +// an urbit style path render as string +export type Path = string; + +// patp including leading sig +export type Patp = string; + +// patp excluding leading sig +export type PatpNoSig = string; + +// @uvH encoded string +export type Serial = string; + +// name of app +export type AppName = 'chat' | 'link' | 'contacts' | 'publish'; + +export function getTagFromFrond(frond: O): keyof O { + const tags = Object.keys(frond) as Array; + const tag = tags[0]; + if(!tag) { + throw new Error("bad frond"); + } + return tag; + + +} diff --git a/pkg/interface/src/types/permission-update.ts b/pkg/interface/src/types/permission-update.ts new file mode 100644 index 0000000000..6d076f2c7d --- /dev/null +++ b/pkg/interface/src/types/permission-update.ts @@ -0,0 +1,55 @@ +import { Path, PatpNoSig } from './noun'; + +export type PermissionUpdate = + PermissionUpdateInitial +| PermissionUpdateCreate +| PermissionUpdateDelete +| PermissionUpdateRemove +| PermissionUpdateAdd; + +interface PermissionUpdateInitial { + initial: { + [p in Path]: { + who: PatpNoSig[]; + kind: PermissionKind; + }; + } +} + +interface PermissionUpdateCreate { + create: { + path: Path; + kind: PermissionKind; + who: PatpNoSig[]; + } +} + +interface PermissionUpdateDelete { + delete: { + path: Path; + } +} + +interface PermissionUpdateAdd { + add: { + path: Path; + who: PatpNoSig[]; + } +} + +interface PermissionUpdateRemove { + remove: { + path: Path; + who: PatpNoSig[]; + } +} + +export type Permissions = { + [p in Path]: Permission; +}; +export interface Permission { + who: Set; + kind: PermissionKind; +} + +export type PermissionKind = 'white' | 'black'; diff --git a/pkg/interface/src/types/publish-response.ts b/pkg/interface/src/types/publish-response.ts new file mode 100644 index 0000000000..addc559211 --- /dev/null +++ b/pkg/interface/src/types/publish-response.ts @@ -0,0 +1,48 @@ +import { Notebooks, Notebook, Note, BookId, NoteId } from './publish-update'; +import { Patp } from './noun'; + +export type PublishResponse = + NotebooksResponse +| NotebookResponse +| NoteResponse +| NotesPageResponse +| CommentsPageResponse; + +interface NotebooksResponse { + type: 'notebooks'; + data: Notebooks; +} + +interface NotebookResponse { + type: 'notebook'; + data: Notebook; + host: Patp; + notebook: BookId; +} + +interface NoteResponse { + type: 'note'; + data: Note; + host: Patp; + notebook: BookId; + note: NoteId; +} + +interface NotesPageResponse { + type: 'notes-page'; + data: Note[]; + host: Patp; + notebook: BookId; + startIndex: number; + length: number; +} + +interface CommentsPageResponse { + type: 'comments-page'; + data: Comment[]; + host: Patp; + notebook: BookId; + note: NoteId; + startIndex: number; + length: number; +} diff --git a/pkg/interface/src/types/publish-update.ts b/pkg/interface/src/types/publish-update.ts new file mode 100644 index 0000000000..7dec8a82bd --- /dev/null +++ b/pkg/interface/src/types/publish-update.ts @@ -0,0 +1,158 @@ +import { Patp, PatpNoSig, Path } from './noun'; + + +export type NoteId = string; +export type BookId = string; + + +export type PublishUpdate = + PublishUpdateAddBook +| PublishUpdateAddNote +| PublishUpdateAddComment +| PublishUpdateEditBook +| PublishUpdateEditNote +| PublishUpdateEditComment +| PublishUpdateDelBook +| PublishUpdateDelNote +| PublishUpdateDelComment; + + +type PublishUpdateBook = { + [s in Patp]: { + [b in BookId]: { + title: string; + 'date-created': number; + about: string; + 'num-notes': number; + 'num-unread': number; + comments: boolean; + 'writers-group-path': Path; + 'subscribers-group-path': Path; + }; + }; +} + +type PublishUpdateNote = { + [s in Patp]: { + [b in BookId]: { + 'note-id': NoteId; + author: Patp; + title: string; + 'date-created': string; + snippet: string; + file: string; + 'num-comments': number; + comments: Comment[]; + read: boolean; + pending: boolean; + }; + }; +}; + +interface PublishUpdateAddBook { + 'add-book': PublishUpdateBook; +} + +interface PublishUpdateEditBook { + 'edit-book': PublishUpdateBook; +} + +interface PublishUpdateDelBook { + 'del-book': { + host: Patp; + book: string; + } +} + +interface PublishUpdateAddNote { + 'add-note': PublishUpdateNote; +} + +interface PublishUpdateEditNote { + 'edit-note': PublishUpdateNote; +} + +interface PublishUpdateDelNote { + 'del-note': { + host: Patp; + book: BookId; + note: NoteId; + } +} + +interface PublishUpdateAddComment { + 'add-comment': { + who: Patp; + host: BookId; + note: NoteId; + body: string; + } +} + +interface PublishUpdateEditComment { + 'edit-comment': { + host: Patp; + book: BookId; + note: NoteId; + body: string; + comment: Comment; + } +} + +interface PublishUpdateDelComment { + 'del-comment': { + host: Patp; + book: BookId; + note: NoteId; + comment: string; + } +} + +export type Notebooks = { + [host in Patp]: { + [book in BookId]: Notebook; + } +} + + +export interface Notebook { + about: string; + comments: boolean; + 'date-created': number; + notes: Notes; + 'notes-by-date': NoteId[]; + 'num-notes': number; + 'num-unread': number; + subscribers: PatpNoSig[]; + 'subscribers-group-path': Path; + title: string; + 'writers-group-path': Path; +} + +type Notes = { + [id in NoteId]: Note; +}; + +export interface Note { + author: Patp; + comments: Comment[]; + 'date-created': number; + file: string; + 'next-note': NoteId | null; + 'note-id': NoteId; + 'num-comments': number; + pending: boolean; + 'prev-note': NoteId | null; + read: boolean; + snippet: string; + title: string; +} + +interface Comment { + [date: string]: { + author: Patp; + content: string; + 'date-created': number; + pending: boolean; + }; +} diff --git a/pkg/interface/src/types/s3-update.ts b/pkg/interface/src/types/s3-update.ts new file mode 100644 index 0000000000..3dfa516229 --- /dev/null +++ b/pkg/interface/src/types/s3-update.ts @@ -0,0 +1,63 @@ + + + export interface S3Credentials { + endpoint: string; + accessKeyId: string; + secretAccessKey: string; + } + +export interface S3Configuration { + buckets: Set; + currentBucket: string; +} + +export interface S3State { + configuration: S3Configuration; + credentials: S3Credentials | null; +} + +interface S3UpdateCredentials { + credentials: S3Credentials; +} + +interface S3UpdateConfiguration { + configuration: { + buckets: string[]; + currentBucket: string; + } +} + +interface S3UpdateCurrentBucket { + setCurrentBucket: string; +} + +interface S3UpdateAddBucket { + addBucket: string; +} + +interface S3UpdateRemoveBucket { + removeBucket: string; +} + +interface S3UpdateEndpoint { + setEndpoint: string; +} + +interface S3UpdateAccessKeyId { + setAccessKeyId: string; +} + +interface S3UpdateSecretAccessKey { + setSecretAccessKey: string; +} + + +export type S3Update = + S3UpdateCredentials +| S3UpdateConfiguration +| S3UpdateCurrentBucket +| S3UpdateAddBucket +| S3UpdateRemoveBucket +| S3UpdateEndpoint +| S3UpdateAccessKeyId +| S3UpdateSecretAccessKey; diff --git a/pkg/interface/tsconfig.json b/pkg/interface/tsconfig.json new file mode 100644 index 0000000000..5ec2a3e518 --- /dev/null +++ b/pkg/interface/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "allowSyntheticDefaultImports": true, + "noFallthroughCasesInSwitch": true, + "noUnusedParameters": false, + "noImplicitReturns": true, + "moduleResolution": "node", + "esModuleInterop": true, + "noUnusedLocals": false, + "noImplicitAny": false, + "noEmit": true, + "target": "es2015", + "module": "es2015", + "strict": true, + "jsx": "react" + }, + "include": [ + "src/**/*" + ], + "exclude": [ + "node_modules", + "dist" + ] +}