Merge branch 'philip/glob' (#3139)

* philip/glob:
  interface: don't require urbitrc for build:prod
  maintainers: add glob-making instructions
  publish: loosen +noun:grab
  glob: autostart and make ota-able
  glob: added app to distribute js outside clay

Signed-off-by: Philip Monk <phil@pcmonk.me>
This commit is contained in:
Philip Monk 2020-07-21 11:22:16 -07:00
commit d641210c6f
No known key found for this signature in database
GPG Key ID: B66E1F02604E44EC
17 changed files with 344 additions and 408 deletions

View File

@ -119,7 +119,7 @@ the network.
Take [this PR][1], as an example. This constituted a great hotfix. It's a
single commit, targeting a problem that existed on the network at the time.
Here's it should be released and deployed OTA.
Here's how it should be released and deployed OTA.
[1]: https://github.com/urbit/urbit/pull/2025
@ -159,15 +159,30 @@ so that I can type e.g. `git mu origin/foo 1337`.
### Prepare a release commit
You should create Landscape or alternative pill builds, if or as appropriate
(i.e., if anything in Landscape changed -- don't trust any compiled JS/CSS
that's included in the commit), and commit these in a release commit.
You should always create a solid pill, in particular, as it's convenient for
tooling to be able to boot directly from a given release.
If you're making a Vere release, just play it safe and update all the pills.
For an Urbit OS release, after all the merge commits, make a release with the
commit message "release: urbit-os-v1.0.xx". This commit should have an
up-to-date solid pill. If neither the pill nor the JS need to be updated (e.g
if the pill was updated in the previous merge commit), consider making the
release commit with --allow-empty.
If anything in `pkg/interface` has changed, ensure it has been built and
deployed properly. For most things, it is sufficient to run `npm install; npm
run build:prod` in `pkg/interface`.
However, if you've made a change to Landscape's JS, then you will need to build
a "glob" and upload it to bootstrap.urbit.org. To do this, run `npm install;
npm run build:prod` in `pkg/interface`, and add the resulting
`pkg/arvo/app/landscape/index.js` to a fakezod at that path (or just create a
new fakezod with `urbit -F zod -B bin/solid.pill -A pkg/arvo`). Run
`:glob|make`, and this will output a file in `fakezod/.urb/put/glob-0vXXX.glob`.
Upload this file to bootstrap.urbit.org, and modify `+hash` at the top of
`pkg/arvo/app/glob.hoon` to match the hash in the filename. Do not commit the
produced `index.js` and make sure it doesn't end up in your pills (they should
be less than 10MB each).
### Tag the resulting commit
What you should do here depends on the type of release being made.
@ -205,7 +220,7 @@ You can get the "contributions" section by the shortlog between the
last release and this release:
```
git log --pretty=short LAST_RELEASE.. | git shortlog
git shortlog LAST_RELEASE..
```
I originally tried to curate this list somewhat, but now just paste it

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6614c1334e3e27722a31e0ae41cfda9b5e1915d5fe75daa3a0ec8423a9574bc6
size 16649737
oid sha256:3027176667ec79c666fa63622c8d72d9f032bcc04653ba9791f027340782757e
size 6270089

View File

@ -318,7 +318,11 @@
%watch-ack
?~ p.sign
[~ this]
%- (slog leaf+"eth-watcher couldn't start listen to thread" u.p.sign)
%- (slog leaf+"eth-watcher couldn't start listening to thread" u.p.sign)
:: TODO: kill thread that may have started, although it may not
:: have started yet since we get this response before the
:: %start-spider poke is processed
::
[~ (clear-running t.wire)]
::
%kick [~ (clear-running t.wire)]

View File

@ -1,14 +1,14 @@
/- srv=file-server
/- srv=file-server, glob
/+ *server, default-agent, verb, dbug
|%
+$ card card:agent:gall
+$ versioned-state
$% state-zero
+$ serving (map url-base=path [=content public=?])
+$ content
$% [%clay =path]
[%glob =glob:glob]
==
::
+$ serving (map url-base=path [clay-base=path public=?])
+$ state-zero
$: %0
+$ state-1
$: %1
=configuration:srv
=serving
==
@ -17,7 +17,7 @@
%+ verb |
%- agent:dbug
::
=| state-zero
=| state-1
=* state -
^- agent:gall
|_ =bowl:gall
@ -33,7 +33,7 @@
%+ turn
^- (list path)
[/ /'~landscape' ~]
|=(pax=path [pax [/app/landscape %.n]])
|=(pax=path [pax [clay+/app/landscape %.n]])
==
:~ (connect /)
(connect /'~landscape')
@ -49,7 +49,32 @@
++ on-load
|= old-vase=vase
^- (quip card _this)
[~ this(state !<(state-zero old-vase))]
|^
=+ !<(old-state=versioned-state old-vase)
=? old-state ?=(%0 -.old-state)
%= old-state
- %1
serving-0
%- ~(run by serving-0.old-state)
|= [=clay=path public=?]
^- [content ?]
[[%clay clay-path] public]
==
?> ?=(%1 -.old-state)
[~ this(state old-state)]
::
+$ versioned-state
$% state-1
state-0
==
::
+$ serving-0 (map url-base=path [=clay=path public=?])
+$ state-0
$: %0
=configuration:srv
=serving-0
==
--
::
++ on-poke
|= [=mark =vase]
@ -75,7 +100,14 @@
?: (~(has by serving) url-base)
~|("url already bound to {<(~(got by serving) url-base.act)>}" !!)
:- [%pass url-base %arvo %e %connect [~ url-base] %file-server]~
this(serving (~(put by serving) url-base [clay-base.act public.act]))
this(serving (~(put by serving) url-base clay+clay-base.act public.act))
::
%serve-glob
=* url-base url-base.act
?: (~(has by serving) url-base)
~|("url already bound to {<(~(got by serving) url-base.act)>}" !!)
:- [%pass url-base %arvo %e %connect [~ url-base] %file-server]~
this(serving (~(put by serving) url-base glob+glob.act public.act))
::
%unserve-dir
:- [%pass url-base.act %arvo %e %disconnect [~ url-base.act]]~
@ -84,9 +116,9 @@
%toggle-permission
?. (~(has by serving) url-base.act)
~|("url is not bound" !!)
=/ [clay-base=path public=?] (~(got by serving) url-base.act)
=/ [=content public=?] (~(got by serving) url-base.act)
:- ~
this(serving (~(put by serving) url-base.act [clay-base !public]))
this(serving (~(put by serving) url-base.act [content !public]))
::
%set-landscape-homepage-prefix
=. landscape-homepage-prefix.configuration prefix.act
@ -133,23 +165,37 @@
|= req-line=request-line
^- [simple-payload:http ?]
=/ pax=path (snoc site.req-line (need ext.req-line))
=/ clay-path=(unit [path ?]) (get-clay-path pax)
?~ clay-path [not-found:gen %.n]
=/ content=(unit [=content suffix=path public=?]) (get-content pax)
?~ content [not-found:gen %.n]
?- -.content.u.content
%clay
=/ scry-path
:* (scot %p our.bowl)
q.byk.bowl
(scot %da now.bowl)
(lowercase -.u.clay-path)
(lowercase (weld path.content.u.content suffix.u.content))
==
?. .^(? %cu scry-path) [not-found:gen %.n]
=/ file (as-octs:mimes:html .^(@ %cx scry-path))
:_ +.u.clay-path
:_ public.u.content
?+ ext.req-line not-found:gen
[~ %html] (html-response:gen file)
[~ %js] (js-response:gen file)
[~ %css] (css-response:gen file)
[~ %png] (png-response:gen file)
==
::
%glob
=/ data=(unit mime)
(~(get by glob.content.u.content) suffix.u.content)
?~ data
[not-found:gen %.n]
:_ public.u.content
=/ mime-type=@t (rsh 3 1 (crip <p.u.data>))
:: Should maybe inspect to see how long cache should hold
::
[[200 ['content-type' mime-type] max-1-da:gen ~] `q.u.data]
==
::
++ lowercase
|= upper=(list @t)
@ -162,24 +208,24 @@
char
(add char ^~((sub 'a' 'A')))
::
++ get-clay-path
++ get-content
|= pax=path
^- (unit [path ?])
=/ first-try (match-clay-path pax (~(del by serving) /))
^- (unit [content path ?])
=/ first-try (match-content-path pax (~(del by serving) /))
?^ first-try first-try
=/ root (~(get by serving) /)
?~ root ~
(match-clay-path pax (~(gas by *^serving) [[/ u.root] ~]))
(match-content-path pax (~(gas by *^serving) [[/ u.root] ~]))
::
++ match-clay-path
++ match-content-path
|= [pax=path =^serving]
^- (unit [path ?])
^- (unit [content path ?])
%- ~(rep by serving)
|= [[url-base=path clay-base=path public=?] out=(unit [path ?])]
|= [[url-base=path =content public=?] out=(unit [content path ?])]
?^ out out
=/ suf (get-suffix url-base pax)
?~ suf ~
`[(weld clay-base u.suf) public]
`[content u.suf public]
::
++ get-suffix
|= [a=path b=path]

187
pkg/arvo/app/glob.hoon Normal file
View File

@ -0,0 +1,187 @@
/- glob
/+ default-agent, verb, dbug
|%
++ hash 0v5.8ftoc.8afop.f4kkn.r4kil.lk95a
+$ state-0 [%0 hash=@uv glob=(unit (each glob:glob tid=@ta))]
+$ all-states
$% state-0
==
+$ card card:agent:gall
--
|%
++ wait-timeout
|= [=path now=@da]
^- card
[%pass [%timer path] %arvo %b %wait (add now ~m30)]
::
++ wait-start
|= now=@da
^- card
[%pass /start %arvo %b %wait now]
::
++ poke-file-server
|= [our=@p =cage]
^- card
[%pass /serving/(scot %uv hash) %agent [our %file-server] %poke cage]
::
++ poke-spider
|= [=path our=@p =cage]
^- card
[%pass [%running path] %agent [our %spider] %poke cage]
::
++ watch-spider
|= [=path our=@p =sub=path]
^- card
[%pass [%running path] %agent [our %spider] %watch sub-path]
::
++ leave-spider
|= [=path our=@p]
^- card
[%pass [%running path] %agent [our %spider] %leave ~]
--
=| state=state-0
=. hash.state hash
=/ serve-path=path /'~landscape'/js/index
^- agent:gall
%+ verb |
%- agent:dbug
^- agent:gall
|_ =bowl:gall
+* this .
def ~(. (default-agent this %|) bowl)
++ on-init
^- (quip card _this)
:: delay through timer to make sure %spider has started
[[(wait-start now.bowl) ~] this]
::
++ on-save !>(state)
++ on-load
|= old-state=vase
^- (quip card _this)
~& > %initting
=+ !<(old=all-states old-state)
?> ?=(%0 -.old)
?~ glob.old
on-init
?: ?=(%& -.u.glob.old)
?: =(hash.old hash.state)
`this(state old)
on-init
=/ cancel-cards
=/ args [tid.p.u.glob.old &]
:~ (leave-spider /(scot %uv hash.old) our.bowl)
(poke-spider /(scot %uv hash.old) our.bowl %spider-stop !>(args))
==
=^ init-cards this on-init
[(weld cancel-cards init-cards) this]
::
++ on-poke
|= [=mark =vase]
^- (quip card _this)
?+ mark (on-poke:def mark vase)
%glob-make
:_ this
=/ home=path /(scot %p our.bowl)/home/(scot %da now.bowl)
=+ .^(=tube:clay %cc (weld home /js/mime))
=+ .^(js=@t %cx (weld home /app/landscape/js/index/js))
=+ !<(=mime (tube !>(js)))
=/ =glob:glob (~(put by *glob:glob) /js mime)
=/ =path /(cat 3 'glob-' (scot %uv (sham glob)))/glob
[%pass /make %agent [our.bowl %hood] %poke %drum-put !>([path (jam glob)])]~
::
%noun
?: =(%kick q.vase)
(on-load !>(state(hash *@uv)))
(on-poke:def mark vase)
==
::
++ on-watch on-watch:def
++ on-leave on-leave:def
++ on-peek on-peek:def
++ on-agent
|= [=wire =sign:agent:gall]
^- (quip card _this)
?: ?=([%serving @ ~] wire)
(on-agent:def wire sign)
?: ?=([%make ~] wire)
(on-agent:def wire sign)
?. ?=([%running @ ~] wire)
%- (slog leaf+"glob: strange on-agent! {<wire -.sign>}" ~)
(on-agent:def wire sign)
?- -.sign
%poke-ack
?~ p.sign
[~ this]
%- (slog leaf+"glob: couldn't start thread; will retry" u.p.sign)
:_ this(glob.state ~) :_ ~
(leave-spider t.wire our.bowl)
::
%watch-ack
?~ p.sign
[~ this]
%- (slog leaf+"glob: couldn't listen to thread; will retry" u.p.sign)
[~ this(glob.state ~)]
::
%kick
=? glob.state ?=([~ %| *] glob.state)
~
`this
::
%fact
=/ produced-hash (slav %uv i.t.wire)
?. =(hash.state produced-hash)
[~ this]
?+ p.cage.sign (on-agent:def wire sign)
%thread-fail
=+ !<([=term =tang] q.cage.sign)
%- (slog leaf+"glob: thread failed; will retry" leaf+<term> tang)
[~ this(glob.state ~)]
::
%thread-done
=+ !<(=glob:glob q.cage.sign)
?. =(hash.state (sham glob))
%: mean
leaf+"glob: hash doesn't match!"
>expected=hash.state<
>got=(sham glob)<
~
==
:_ this(glob.state `[%& glob]) :_ ~
%+ poke-file-server our.bowl
[%file-server-action !>([%serve-glob serve-path glob %&])]
==
==
::
++ on-arvo
|= [=wire =sign-arvo]
^- (quip card _this)
?: ?=([%start ~] wire)
=/ new-tid=@ta (cat 3 'glob--' (scot %uv eny.bowl))
=/ args [~ `new-tid %glob !>([hash.state ~])]
=/ action !>([%unserve-dir serve-path])
:_ this(glob.state `[%| new-tid])
:~ (poke-file-server our.bowl %file-server-action action)
(wait-timeout /[new-tid] now.bowl)
(watch-spider /(scot %uv hash.state) our.bowl /thread-result/[new-tid])
(poke-spider /(scot %uv hash.state) our.bowl %spider-start !>(args))
==
?. ?=([%timer @ ~] wire)
%- (slog leaf+"glob: strange on-arvo wire: {<wire [- +<]:sign-arvo>}" ~)
`this
?. ?=(%wake +<.sign-arvo)
%- (slog leaf+"glob: strange on-arvo sign: {<wire [- +<]:sign-arvo>}" ~)
`this
?: ?=([~ %& *] glob.state)
`this
?. ?| ?=(~ glob.state)
=(i.t.wire tid.p.u.glob.state)
==
`this
?^ error.sign-arvo
%- (slog leaf+"glob: timer handling failed; will retry" ~)
[[(wait-timeout t.wire now.bowl)]~ this]
%- (slog leaf+"glob: timed out; retrying" ~)
(on-load !>(state(hash *@uv)))
::
++ on-fail on-fail:def
--

View File

@ -2,6 +2,12 @@
/+ drum=hood-drum, helm=hood-helm, kiln=hood-kiln
|%
+$ state
$: %8
drum=state:drum
helm=state:helm
kiln=state:kiln
==
+$ state-7
$: %7
drum=state:drum
helm=state:helm
@ -9,6 +15,7 @@
==
+$ any-state
$% state
state-7
[ver=?(%1 %2 %3 %4 %5 %6) lac=(map @tas fin-any-state)]
==
+$ any-state-tuple

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,3 @@
:- %say
|= *
[%glob-make ~]

View File

@ -102,6 +102,7 @@
%metadata-hook
%s3-store
%file-server
%glob
==
::
++ deft-fish :: default connects
@ -204,7 +205,7 @@
==
::
++ on-load
|= [hood-version=?(%1 %2 %3 %4 %5 %6 %7) old=any-state]
|= [hood-version=?(%1 %2 %3 %4 %5 %6 %7 %8) old=any-state]
=< se-abet =< se-view
=. sat old
=. dev (~(gut by bin) ost *source)
@ -226,6 +227,8 @@
(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 (lte hood-version %7)
(se-born | %home %glob)
..on-load
::
++ reap-phat :: ack connect

View File

@ -35,7 +35,7 @@
?~(caz this $(caz t.caz, this (emit i.caz)))
::
++ on-load
|= [hood-version=?(%1 %2 %3 %4 %5 %6 %7) old=any-state]
|= [hood-version=@ud old=any-state]
=< abet
=? old ?=(%0 -.old) (state-0-to-1 old)
?> ?=(%1 -.old)

View File

@ -77,7 +77,7 @@
~[leaf+"from {<sud>}" leaf+"on {<who>}" leaf+"to {<syd>}"]
::
++ on-load
|= [hood-version=?(%1 %2 %3 %4 %5 %6 %7) old=any-state]
|= [hood-version=@ud old=any-state]
=< abet
=? . ?=(%0 -.old)
=/ recognized-ota=(unit [syd=desk her=ship sud=desk])

View File

@ -366,14 +366,20 @@
?> ?=(^ full-file.client-response)
(pure:m q.data.u.full-file.client-response)
::
++ fetch-json
++ fetch-cord
|= url=tape
=/ m (strand ,json)
=/ m (strand ,cord)
^- form:m
=/ =request:http [%'GET' (crip url) ~ ~]
;< ~ bind:m (send-request request)
;< =client-response:iris bind:m take-client-response
;< =cord bind:m (extract-body client-response)
(extract-body client-response)
::
++ fetch-json
|= url=tape
=/ m (strand ,json)
^- form:m
;< =cord bind:m (fetch-cord url)
=/ json=(unit json) (de-json:html cord)
?~ json
(strand-fail %json-parse-error ~)

View File

@ -59,7 +59,7 @@
old-parser
==
--
++ noun comment
++ noun ?(comment-2 comment-3)
--
++ grad %mime
--

View File

@ -1,6 +1,8 @@
/- glob
|%
+$ action
$% [%serve-dir url-base=path clay-base=path public=?]
[%serve-glob url-base=path =glob:glob public=?]
[%unserve-dir url-base=path]
[%toggle-permission url-base=path]
[%set-landscape-homepage-prefix prefix=(unit term)]

3
pkg/arvo/sur/glob.hoon Normal file
View File

@ -0,0 +1,3 @@
|%
+$ glob (map path mime)
--

12
pkg/arvo/ted/glob.hoon Normal file
View File

@ -0,0 +1,12 @@
/- spider, glob
/+ strandio
=, strand=strand:spider
^- thread:spider
|= arg=vase
=/ m (strand ,vase)
^- form:m
=+ !<([hash=@uv ~] arg)
=/ url "https://bootstrap.urbit.org/glob-{(scow %uv hash)}.glob"
;< =cord bind:m (fetch-cord:strandio url)
=+ ;;(=glob:glob (cue cord))
(pure:m !>(glob))

View File

@ -1,7 +1,6 @@
const path = require('path');
// const HtmlWebpackPlugin = require('html-webpack-plugin');
// const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const urbitrc = require('./urbitrc');
module.exports = {
mode: 'production',