From 66c5a99b6e1d9b6d931563f6cb54053d5767d547 Mon Sep 17 00:00:00 2001 From: Philip C Monk Date: Wed, 27 Jan 2016 16:50:06 -0500 Subject: [PATCH] cleanup --- ape/gh.hoon | 147 ++++++++++++++++++++++++++------------ ape/github.hoon | 38 +++++++++- lib/gh-parse.hoon | 5 ++ mar/gh/issue-comment.hoon | 1 + mar/gh/issues.hoon | 1 + sur/gh.hoon | 9 +++ 6 files changed, 154 insertions(+), 47 deletions(-) diff --git a/ape/gh.hoon b/ape/gh.hoon index 47591e3aed..6af53da080 100644 --- a/ape/gh.hoon +++ b/ape/gh.hoon @@ -1,26 +1,58 @@ +:: This is a driver for the Github API v3. +:: +:: You can interact with this in a few different ways: +:: +:: - .^(%gx /=gh=/read-unauth{/endpoint}) or subscribe to +:: /scry/x/read-unauth{/endpoint} for unauthenticated reads. +:: +:: - .^(%gx /=gh=/read-auth{/endpoint}) or subscribe to +:: /scry/x/read-auth{/endpoint} for authenticated reads. +:: +:: - subscribe to /scry/x/listen/{owner}/{repo}/{events...} +:: for webhook-powered event notifications. For event list, +:: see https://developer.github.com/webhooks/. +:: +:: See the %github app for example usage. /? 314 /- gh => |% ++ move (pair bone card) ++ sub-result $% [%json json] + [%gh-issues issues:gh] + [%gh-issue-comment issue-comment:gh] == ++ card $% [%diff sub-result] [%them wire (unit hiss)] [%hiss wire [~ ~] %httr [%hiss hiss]] == + ++ hook-response + $% [%gh-issues issues:gh] + [%gh-issue-comment issue-comment:gh] + == -- |_ [hid=bowl cnt=@ hook=(map ,@t ,[id=@t listeners=(set bone)])] ::++ prep ,_`. +:: +:: This core manages everything related to a particular request. +:: +:: Each request has a particular 'style', which is currently +:: one of 'read-auth', 'read-unauth', or 'listen'. ++scry +:: handles all three types of requests. ++ help |= [style=@tas pax=path] =| mow=(list move) |% + :: Resolve core. ++ abet ^- [(list move) _+>.$] [(flop mow) +>.$] + :: + :: Append path to api.github.com and parse to a purl. ++ real-pax (scan "https://api.github.com{<`path`pax>}" auri:epur) + :: + :: Send a hiss with the correct authentication ++ send-hiss |= [aut=? hiz=hiss] ^+ +> @@ -29,8 +61,8 @@ ?. aut [ost.hid %them wir ~ hiz] [ost.hid %hiss wir `~ %httr [%hiss hiz]] +>.$(mow [new-move mow]) - ++ auth - ['Authorization' 'Basic cGhpbGlwY21vbmt0ZXN0OjEzMzdwYXNzd29yZA==' ~] + :: + :: Decide how to handle a request based on its style. ++ scry ^+ . =- ~& [%requesting -] - @@ -39,24 +71,36 @@ %read-auth read-auth %listen listen == + :: ++ read-unauth (send-hiss | real-pax %get ~ ~) ++ read-auth (send-hiss & real-pax %get ~ ~) + :: + :: Create or update a webhook to listen for a set of events. ++ listen ^+ . ?> ?=([@ @ *] pax) - =+ xap=t.t.pax + =+ events=t.t.pax |- ^+ +>.$ - ?~ xap + ?~ events +>.$ - ?: (~(has by hook) i.xap) - =. +>.$ =>((update-hook i.xap) ?>(?=([@ @ *] pax) .)) - $(xap t.xap) - =. +>.$ =>((create-hook i.xap) ?>(?=([@ @ *] pax) .)) - $(xap t.xap) + ?: (~(has by hook) i.events) + =. +>.$ =>((update-hook i.events) ?>(?=([@ @ *] pax) .)) + $(events t.events) + =. +>.$ =>((create-hook i.events) ?>(?=([@ @ *] pax) .)) + $(events t.events) + :: + :: Set up a webhook. ++ create-hook |= event=@t ^+ +> ?> ?=([@ @ *] pax) + =+ clean-event=`tape`(turn (trip event) |=(a=@tD ?:(=('_' a) '-' a))) + =. hook + %+ ~(put by hook) (crip clean-event) + =+ %+ fall + (~(get by hook) (crip clean-event)) + *[id=@t listeners=(set bone)] + [id (~(put in listeners) ost.hid)] %- send-hiss :* & %+ scan @@ -70,13 +114,15 @@ events/a/~[s/event] ::(turn `(list ,@t)`t.t.pax |=(a=@t s/a)) :- %config %- jobe :~ - =+ =+ `tape`(turn (trip event) |=(a=@tD ?:(=('_' a) '-' a))) - "http://107.170.195.5:8445/~/to/gh/gh-{-}.json?anon&wire=/" + =+ =+ clean-event + "http://107.170.195.5:8443/~/to/gh/gh-{-}.json?anon&wire=/" [%url s/(crip -)] [%'content_type' s/%json] == == == + :: + :: Add current bone to the list of subscribers for this event. ++ update-hook |= event=@t ^+ +> @@ -87,37 +133,32 @@ %+ ~(put by hook) event hok(listeners (~(put in listeners.hok) ost.hid)) == - :: :* %+ scan - :: =+ [(trip i.pax) (trip i.t.pax)] - :: "https://api.github.com/repos/{-<}/{->}/hooks/{(trip (need hook))}" - :: auri:epur - :: %post ~ ~ - :: %- taco %- crip %- pojo %- jobe :~ - :: [%'add_events' a/(turn `(list ,@t)`t.t.pax |=(a=@t s/a))] - :: == - :: == -- :: -++ poke-json - |= jon=json +:: Pokes that haven't already been caught are handled here. +:: These should be only from webhooks firing, so if we get any +:: mark that we shouldn't get from a webhook, we reject it. +:: Otherwise, we spam out the event to everyone who's listening +:: for that event. +++ poke + |= response=hook-response ^- [(list move) _+>.$] - =+ ^- [repo=json sender=json hok=(list ,@t) hook-id=@t zen=json] - %- need - %. jon - => jo - (ot repository/some sender/some hook/(ot events/(ar so) ~) 'hook_id'^no zen/some ~) - ?. ?=([@ ~] hok) - ~& [%weird-hook hook-id hok] - [~ +>.$] - ~& [%id hook-id hok] - =+ old-bones=`(set bone)`(biff (~(get by hook) i.hok) tail) - [~ +>.$(hook (~(put by hook) i.hok [hook-id (~(put in old-bones) ost.hid)]))] + =+ hook-data=(~(get by hook) (rsh 3 3 -.response)) + ?~ hook-data + ~& [%strange-hook hook response] + `+>.$ + ~& response=response + :_ +>.$ + %+ turn (~(tap in listeners.u.hook-data)) + |= ost=bone + [ost %diff response] :: -++ poke-gh-issues - |= issue=issues:gh - ^- [(list move) _+>.$] - ~& issue - `+>.$ +:: When a peek on a path blocks, ford turns it into a peer on +:: /scry/{care}/{path}. You can also just peer to this +:: directly. +:: +:: After some sanity checking we hand control to ++scry in +:: ++help. ++ peer-scry-x |= pax=path ^- [(list move) _+>.$] @@ -125,12 +166,8 @@ =- ~& [%peered -] - [abet(cnt now.hid)]:scry:(help i.pax t.pax) :: -++ poke-gh-issue-comment - |= comment=issue-comment:gh - ^- [(list move) _+>.$] - ~& comment - `+>.$ -:: +:: HTTP response. We make sure the response is good, then +:: produce the result (as JSON) to whoever sent the request. ++ sigh-httr-x thou-x ++ thou-x |= [way=wire res=httr] @@ -147,8 +184,30 @@ (jobe err/s/%request-rejected code/(jone p.res) msg/u.- ~) u.- :: +:: We can't actually give the response to pretty much anything +:: without blocking, so we just block unconditionally. ++ peek |= [ren=@tas tyl=path] ^- (unit (unit (pair mark ,*))) ~ ::``noun/[ren tyl] -- + + + + +:: +::++ poke-json +:: |= jon=json +:: ^- [(list move) _+>.$] +:: =+ ^- [repo=json sender=json hok=(list ,@t) hook-id=@t zen=json] +:: %- need +:: %. jon +:: => jo +:: (ot repository/some sender/some hook/(ot events/(ar so) ~) 'hook_id'^no zen/some ~) +:: ?. ?=([@ ~] hok) +:: ~& [%weird-hook hook-id hok] +:: [~ +>.$] +:: ~& [%id hook-id hok] +:: =+ old-bones=`(set bone)`(biff (~(get by hook) i.hok) tail) +:: [~ +>.$(hook (~(put by hook) i.hok [hook-id (~(put in old-bones) ost.hid)]))] +. diff --git a/ape/github.hoon b/ape/github.hoon index 7434286616..b327032a8a 100644 --- a/ape/github.hoon +++ b/ape/github.hoon @@ -1,11 +1,43 @@ +:: This is a command-line ui for the %gh Github driver. +:: +:: Usage: +:: :github &path /read-unauth{/endpoint} +:: :github &path /read-auth{/endpoint} +:: :github &path /listen/{owner}/{repo}/{events...} +:: +/- gh +!: +=> |% + ++ diff-result + $% [%gh-issue issues:gh] + [%gh-issue-comment issue-comment:gh] + == + -- |_ [hid=bowl *] ++ poke-path |= pax=path :_ +>.$ :_ ~ [ost.hid %peer /into-the-mist [our.hid %gh] scry/x/pax] -++ diff-json-into-the-mist - |= [way=wire jon=json] - ~& (pojo jon) +++ diff-gh-issues + |= [way=wire issues:gh] + %- %- slog :~ + leaf/"in repository {(trip login.owner.repository)}/{(trip name.repository)}:" + leaf/"{(trip login.sender)} {(trip -.action)} issue #{} {}" + ?+ -.action *tank + ?(%assigned %unassigned) + leaf/"to {(trip login.assignee.action)}" + ?(%labeled %unlabeled) + leaf/"with {(trip name.label.action)}" + == + == + [~ +>.$] +++ diff-gh-issue-comment + |= [way=wire issue-comment:gh] + %- %- slog :~ + leaf/"in repository {(trip login.owner.repository)}/{(trip name.repository)}:" + leaf/"{(trip login.sender)} commented on issue #{} {}:" + leaf/(trip body.comment) + == [~ +>.$] ++ peek |= [ren=@tas tyl=path] diff --git a/lib/gh-parse.hoon b/lib/gh-parse.hoon index 56183cd242..44a303f6fc 100644 --- a/lib/gh-parse.hoon +++ b/lib/gh-parse.hoon @@ -1,3 +1,8 @@ +:: This library includes parsing functions for the json objects +:: that Github's API produces. In general, the conversion from +:: JSON to urbit types should be performed in marks, so those +:: marks should include this library. +:: /- gh |% ++ repository diff --git a/mar/gh/issue-comment.hoon b/mar/gh/issue-comment.hoon index 5371f42451..ceb2a2a6e5 100644 --- a/mar/gh/issue-comment.hoon +++ b/mar/gh/issue-comment.hoon @@ -1,3 +1,4 @@ +:: Converts the result of an 'issues' event into a issues:gh. /- gh /+ gh-parse |_ issue-comment=issue-comment:gh diff --git a/mar/gh/issues.hoon b/mar/gh/issues.hoon index 8fe90043db..399a724ce2 100644 --- a/mar/gh/issues.hoon +++ b/mar/gh/issues.hoon @@ -1,3 +1,4 @@ +:: Converts the result of an 'issues' event into a issues:gh. /- gh /+ gh-parse |_ issues=issues:gh diff --git a/sur/gh.hoon b/sur/gh.hoon index dec853cc0e..18b2bb3e4f 100644 --- a/sur/gh.hoon +++ b/sur/gh.hoon @@ -1,3 +1,12 @@ +:: https://developer.github.com/v3/ +:: +:: These types correspond to the types that Github's API +:: produces, so please check Github's documentation for +:: details. +:: +:: For parsing JSON into these types, check out the gh-parse +:: library. +:: |% ++ repository $: id=id