From cdc405993b7921ce1ba1b3e0edd333f334e7dca8 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 5 Jun 2020 12:01:16 -0600 Subject: [PATCH 002/388] Install some packages --- .gitignore | 1 + package.json | 12 ++ yarn.lock | 404 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 417 insertions(+) create mode 100644 .gitignore create mode 100644 package.json create mode 100644 yarn.lock diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/package.json b/package.json new file mode 100644 index 0000000..25b30d4 --- /dev/null +++ b/package.json @@ -0,0 +1,12 @@ +{ + "name": "fast-sandbox", + "version": "0", + "license": "MIT", + "private": true, + "dependencies": { + "express": "^4.17.1", + "express-ws": "^4.0.0", + "heroku-ssl-redirect": "^0.0.4", + "node-pty": "^0.9.0" + } +} diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..2fe1220 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,404 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +accepts@~1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + dependencies: + mime-types "~2.1.24" + negotiator "0.6.2" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== + +body-parser@1.19.0: + version "1.19.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" + integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== + dependencies: + bytes "3.1.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "1.7.2" + iconv-lite "0.4.24" + on-finished "~2.3.0" + qs "6.7.0" + raw-body "2.4.0" + type-is "~1.6.17" + +bytes@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" + integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== + +content-disposition@0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" + integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== + dependencies: + safe-buffer "5.1.2" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" + integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +express-ws@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/express-ws/-/express-ws-4.0.0.tgz#dabd8dc974516418902a41fe6e30ed949b4d36c4" + integrity sha512-KEyUw8AwRET2iFjFsI1EJQrJ/fHeGiJtgpYgEWG3yDv4l/To/m3a2GaYfeGyB3lsWdvbesjF5XCMx+SVBgAAYw== + dependencies: + ws "^5.2.0" + +express@^4.17.1: + version "4.17.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" + integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== + dependencies: + accepts "~1.3.7" + array-flatten "1.1.1" + body-parser "1.19.0" + content-disposition "0.5.3" + content-type "~1.0.4" + cookie "0.4.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "~1.1.2" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.5" + qs "6.7.0" + range-parser "~1.2.1" + safe-buffer "5.1.2" + send "0.17.1" + serve-static "1.14.1" + setprototypeof "1.1.1" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +finalhandler@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +heroku-ssl-redirect@^0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/heroku-ssl-redirect/-/heroku-ssl-redirect-0.0.4.tgz#21ba0707aa503b50a412a0946abfaa88ef7d082c" + integrity sha1-IboHB6pQO1CkEqCUar+qiO99CCw= + +http-errors@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" + integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-errors@~1.7.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +inherits@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +mime-db@1.44.0: + version "1.44.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" + integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== + +mime-types@~2.1.24: + version "2.1.27" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" + integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== + dependencies: + mime-db "1.44.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +nan@^2.14.0: + version "2.14.1" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" + integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== + +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== + +node-pty@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/node-pty/-/node-pty-0.9.0.tgz#8f9bcc0d1c5b970a3184ffd533d862c7eb6590a6" + integrity sha512-MBnCQl83FTYOu7B4xWw10AW77AAh7ThCE1VXEv+JeWj8mSpGo+0bwgsV+b23ljBFwEM9OmsOv3kM27iUPPm84g== + dependencies: + nan "^2.14.0" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +proxy-addr@~2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" + integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.9.1" + +qs@6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" + integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" + integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== + dependencies: + bytes "3.1.0" + http-errors "1.7.2" + iconv-lite "0.4.24" + unpipe "1.0.0" + +safe-buffer@5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +send@0.17.1: + version "0.17.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" + integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.7.2" + mime "1.6.0" + ms "2.1.1" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + +serve-static@1.14.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" + integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.1" + +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + +"statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + +type-is@~1.6.17, type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +ws@^5.2.0: + version "5.2.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" + integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA== + dependencies: + async-limiter "~1.0.0" From ff86d1f06ddb05355eefda65cdc8abd5adf351b3 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 5 Jun 2020 12:01:40 -0600 Subject: [PATCH 003/388] Add MIT License --- LICENSE.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE.md diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..ad907d4 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +# MIT License + +Copyright (c) 2020 Radon Rosborough + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 5e3a4a44fb565457f769577840a070ced8c12870 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 5 Jun 2020 19:20:01 -0600 Subject: [PATCH 004/388] Install some packages into a Docker image --- Dockerfile | 4 ++++ scripts/docker-install.bash | 41 +++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 Dockerfile create mode 100755 scripts/docker-install.bash diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..9fc89e5 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,4 @@ +FROM ubuntu:rolling + +COPY scripts/docker-install.bash /tmp/ +RUN /tmp/docker-install.bash diff --git a/scripts/docker-install.bash b/scripts/docker-install.bash new file mode 100755 index 0000000..566fe41 --- /dev/null +++ b/scripts/docker-install.bash @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +packages=" + +# Handy utilities +bsdmainutils +curl +emacs-nox +git +make +nano +vim +wget + +# C/C++ +clang + +# Haskell +cabal-install +ghc + +# Node.js +nodejs +npm + +# Python +python3 +python3-pip +python3-venv + +" + +export DEBIAN_FRONTEND=noninteractive +apt-get update +apt-get install -y $(grep -v "^#" <<< "$packages") +rm -rf /var/lib/apt/lists/* + +rm "$0" From 9a9ab44755e68c860d1657bf9143aab22220cd3c Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 5 Jun 2020 19:26:19 -0600 Subject: [PATCH 005/388] Add Makefile to run Docker container --- Dockerfile | 2 ++ Makefile | 14 ++++++++++++++ scripts/docker.bash | 10 ++++++++++ 3 files changed, 26 insertions(+) create mode 100644 Makefile create mode 100755 scripts/docker.bash diff --git a/Dockerfile b/Dockerfile index 9fc89e5..e754b62 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,3 +2,5 @@ FROM ubuntu:rolling COPY scripts/docker-install.bash /tmp/ RUN /tmp/docker-install.bash + +EXPOSE 6119 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..04f776a --- /dev/null +++ b/Makefile @@ -0,0 +1,14 @@ +UID := $(shell id -u) + +.PHONY: help +help: ## Show this message + @echo "usage:" >&2 + @grep -h "[#]# " $(MAKEFILE_LIST) | \ + sed 's/^/ make /' | \ + sed 's/:[^#]*[#]# /|/' | \ + column -t -s'|' >&2 + +.PHONY: docker +docker: ## Run shell with source code and deps inside Docker + scripts/docker.bash build . -t fast-sandbox --build-arg "UID=$(UID)" + scripts/docker.bash run -it --rm -v "$PWD" -p 6119:6119 fast-sandbox diff --git a/scripts/docker.bash b/scripts/docker.bash new file mode 100755 index 0000000..16490c1 --- /dev/null +++ b/scripts/docker.bash @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +if [[ "$OSTYPE" != darwin* ]] && [[ "$EUID" != 0 ]]; then + exec sudo -E docker "$@" +else + exec docker "$@" +fi From f8b9e20cb8b0bf0c117c6ef5aa87c708285251b1 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 5 Jun 2020 19:31:11 -0600 Subject: [PATCH 006/388] Handle UID stuff --- Dockerfile | 11 +++++++++-- scripts/docker-install.bash | 14 ++++++++++++++ scripts/pid1.bash | 10 ++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100755 scripts/pid1.bash diff --git a/Dockerfile b/Dockerfile index e754b62..6ed8ef3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,13 @@ FROM ubuntu:rolling -COPY scripts/docker-install.bash /tmp/ -RUN /tmp/docker-install.bash +ARG UID +COPY scripts/docker-install.bash /tmp/ +RUN /tmp/docker-install.bash "$UID" + +USER $UID +WORKDIR /home/docker EXPOSE 6119 + +ENTRYPOINT ["/usr/local/bin/pid1.bash"] +COPY scripts/pid1.bash /usr/local/bin/ diff --git a/scripts/docker-install.bash b/scripts/docker-install.bash index 566fe41..f3a7400 100755 --- a/scripts/docker-install.bash +++ b/scripts/docker-install.bash @@ -3,6 +3,13 @@ set -e set -o pipefail +if (( $# != 1 )); then + echo "usage: docker-install.bash UID" >&2 + exit 1 +fi + +uid="$1" + packages=" # Handy utilities @@ -38,4 +45,11 @@ apt-get update apt-get install -y $(grep -v "^#" <<< "$packages") rm -rf /var/lib/apt/lists/* +if (( "$uid" != 0 )); then + useradd --uid="$uid" --create-home --groups sudo docker + passwd -d docker +else + ln -s /root /home/docker +fi + rm "$0" diff --git a/scripts/pid1.bash b/scripts/pid1.bash new file mode 100755 index 0000000..ce990ca --- /dev/null +++ b/scripts/pid1.bash @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +export LANG=C.UTF-8 +export LC_ALL=C.UTF-8 +export SHELL="$(which bash)" + +exec "$@" From e937c8ffc5d7d68332952bd95e1000ad8135d555 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 5 Jun 2020 19:37:25 -0600 Subject: [PATCH 007/388] Simple Express server with "Hello world" --- package.json | 1 + src/server.js | 14 ++++++++++++++ static/index.html | 10 ++++++++++ yarn.lock | 5 +++++ 4 files changed, 30 insertions(+) create mode 100644 src/server.js create mode 100644 static/index.html diff --git a/package.json b/package.json index 25b30d4..a070453 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "license": "MIT", "private": true, "dependencies": { + "app-root-path": "^3.0.0", "express": "^4.17.1", "express-ws": "^4.0.0", "heroku-ssl-redirect": "^0.0.4", diff --git a/src/server.js b/src/server.js new file mode 100644 index 0000000..875c365 --- /dev/null +++ b/src/server.js @@ -0,0 +1,14 @@ +const appRoot = require("app-root-path"); +const express = require("express"); +const sslRedirect = require("heroku-ssl-redirect"); + +const app = express(); +const host = process.env.HOST || "localhost"; +const port = parseInt(process.env.PORT) || 6119; + +app.use(sslRedirect()); +app.use("/", express.static(appRoot + "/static")); + +app.listen(port, host, () => + console.log(`Listening on http://${host}:${port}`) +); diff --git a/static/index.html b/static/index.html new file mode 100644 index 0000000..c0008f1 --- /dev/null +++ b/static/index.html @@ -0,0 +1,10 @@ + + + + + Fast Sandbox + + + Hello, world! + + diff --git a/yarn.lock b/yarn.lock index 2fe1220..5bc799a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,6 +10,11 @@ accepts@~1.3.7: mime-types "~2.1.24" negotiator "0.6.2" +app-root-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-3.0.0.tgz#210b6f43873227e18a4b810a032283311555d5ad" + integrity sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw== + array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" From 4b82e93042fc31ea85778ff271ec7d105f81d812 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 5 Jun 2020 19:47:39 -0600 Subject: [PATCH 008/388] Fix up pid1 --- Dockerfile | 1 + Makefile | 2 +- scripts/pid1.bash | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 6ed8ef3..4a1c43d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,3 +11,4 @@ EXPOSE 6119 ENTRYPOINT ["/usr/local/bin/pid1.bash"] COPY scripts/pid1.bash /usr/local/bin/ +CMD bash diff --git a/Makefile b/Makefile index 04f776a..0a1a32d 100644 --- a/Makefile +++ b/Makefile @@ -11,4 +11,4 @@ help: ## Show this message .PHONY: docker docker: ## Run shell with source code and deps inside Docker scripts/docker.bash build . -t fast-sandbox --build-arg "UID=$(UID)" - scripts/docker.bash run -it --rm -v "$PWD" -p 6119:6119 fast-sandbox + scripts/docker.bash run -it --rm -v "$(PWD):/home/docker/src" -p 6119:6119 fast-sandbox diff --git a/scripts/pid1.bash b/scripts/pid1.bash index ce990ca..21b5099 100755 --- a/scripts/pid1.bash +++ b/scripts/pid1.bash @@ -7,4 +7,8 @@ export LANG=C.UTF-8 export LC_ALL=C.UTF-8 export SHELL="$(which bash)" +if [[ -d src ]]; then + cd src +fi + exec "$@" From c7a62924e69e1bedbd5b5a1c99aca8be3d5dfbd2 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 5 Jun 2020 22:21:55 -0600 Subject: [PATCH 009/388] API draft, lang config, more utils --- README.md | 58 +++++++++++++++++++++++++++++++++++++ dynamic/app.html | 10 +++++++ langs.json | 17 +++++++++++ scripts/docker-install.bash | 6 ++++ scripts/pid1.bash | 2 ++ src/server.js | 10 +++++++ 6 files changed, 103 insertions(+) create mode 100644 README.md create mode 100644 dynamic/app.html create mode 100644 langs.json diff --git a/README.md b/README.md new file mode 100644 index 0000000..8fd7c57 --- /dev/null +++ b/README.md @@ -0,0 +1,58 @@ +# Fast Sandbox + +This project is a work in progress and does not contain any serious +documentation. + +## API + + POST /api/v1/ws?lang=python + +The API is based on message passing. + +### Server messages + +Received output from process. + + { + "event": "terminalOutput", + "output": ">>> " + } + +Package name completions. + + { + "event": "packageNameCompletions", + "packageNameCompletions": ["Flask", "Flask-Talisman"], + "messageSerial": 42 + } + +### Client messages + +Received input from user. + + { + "event": "terminalInput", + "input": "print('Hello, world!')\n" + } + +User wants to run code. + + { + "event": "runCode", + "code": "import this" + } + +User wants to install a package. + + { + "event": "installPackage", + "packageName": "Flask" + } + +Complete package names. + + { + "event": "completePackageName", + "partialPackageName": "fla", + "messageSerial": 42 + } diff --git a/dynamic/app.html b/dynamic/app.html new file mode 100644 index 0000000..fc2765f --- /dev/null +++ b/dynamic/app.html @@ -0,0 +1,10 @@ + + + + + Fast Sandbox + + + Editor :) + + diff --git a/langs.json b/langs.json new file mode 100644 index 0000000..c838694 --- /dev/null +++ b/langs.json @@ -0,0 +1,17 @@ +{ + "c": { + "name": "C" + }, + "c++": { + "name": "C++" + }, + "haskell": { + "name": "Haskell" + }, + "nodejs": { + "name": "Node.js" + }, + "python": { + "name": "Python" + } +} diff --git a/scripts/docker-install.bash b/scripts/docker-install.bash index f3a7400..1391aba 100755 --- a/scripts/docker-install.bash +++ b/scripts/docker-install.bash @@ -19,6 +19,7 @@ emacs-nox git make nano +sudo vim wget @@ -45,6 +46,11 @@ apt-get update apt-get install -y $(grep -v "^#" <<< "$packages") rm -rf /var/lib/apt/lists/* +cd /tmp +wget -nv https://github.com/watchexec/watchexec/releases/download/1.13.1/watchexec-1.13.1-x86_64-unknown-linux-gnu.deb +dpkg -i watchexec-*.deb +rm watchexec-*.deb + if (( "$uid" != 0 )); then useradd --uid="$uid" --create-home --groups sudo docker passwd -d docker diff --git a/scripts/pid1.bash b/scripts/pid1.bash index 21b5099..1ceaa37 100755 --- a/scripts/pid1.bash +++ b/scripts/pid1.bash @@ -7,6 +7,8 @@ export LANG=C.UTF-8 export LC_ALL=C.UTF-8 export SHELL="$(which bash)" +export HOST=0.0.0.0 + if [[ -d src ]]; then cd src fi diff --git a/src/server.js b/src/server.js index 875c365..b21e2bb 100644 --- a/src/server.js +++ b/src/server.js @@ -1,4 +1,7 @@ const appRoot = require("app-root-path"); + +const langs = require(appRoot + "/langs"); + const express = require("express"); const sslRedirect = require("heroku-ssl-redirect"); @@ -7,6 +10,13 @@ const host = process.env.HOST || "localhost"; const port = parseInt(process.env.PORT) || 6119; app.use(sslRedirect()); +app.get("/:lang", (req, res) => { + if (langs[req.params.lang]) { + res.sendFile(appRoot + "/dynamic/app.html"); + } else { + res.send(`No such language: ${req.params.lang}`); + } +}); app.use("/", express.static(appRoot + "/static")); app.listen(port, host, () => From 73e74516a78918ba7da21cf1d8fa821ae0447e8d Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 6 Jun 2020 10:28:13 -0600 Subject: [PATCH 010/388] JavaScript build system hell --- .gitignore | 3 + backend/src/api.ts | 54 + backend/src/global.d.ts | 1 + backend/src/langs.ts | 27 + backend/src/server.ts | 42 + {dynamic => frontend/pages}/app.html | 1 + {static => frontend/pages}/index.html | 0 frontend/src/app.ts | 1 + langs.json | 17 - package.json | 16 +- src/server.js | 24 - tsconfig.json | 9 + webpack.config.js | 10 + yarn.lock | 2835 ++++++++++++++++++++++++- 14 files changed, 2991 insertions(+), 49 deletions(-) create mode 100644 backend/src/api.ts create mode 100644 backend/src/global.d.ts create mode 100644 backend/src/langs.ts create mode 100644 backend/src/server.ts rename {dynamic => frontend/pages}/app.html (75%) rename {static => frontend/pages}/index.html (100%) create mode 100644 frontend/src/app.ts delete mode 100644 langs.json delete mode 100644 src/server.js create mode 100644 tsconfig.json create mode 100644 webpack.config.js diff --git a/.gitignore b/.gitignore index 3c3629e..1a03776 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ +*.log +.log node_modules +out diff --git a/backend/src/api.ts b/backend/src/api.ts new file mode 100644 index 0000000..54dfadc --- /dev/null +++ b/backend/src/api.ts @@ -0,0 +1,54 @@ +import * as pty from "node-pty"; +import { IPty } from "node-pty"; + +import { LangConfig, langs } from "./langs"; + +export class Session { + config: LangConfig; + term: IPty; + ws: WebSocket; + + constructor(ws, lang) { + this.ws = ws; + this.config = langs[lang]; + this.term = null; + this.run(); + ws.on("message", this.handleClientMessage); + } + handleClientMessage(msg) { + try { + msg = JSON.parse(msg); + } catch (err) { + console.error(`failed to parse client message: ${msg}`); + return; + } + switch (msg.event) { + case "terminalInput": + if (!this.term) { + console.error(`terminalInput: no terminal`); + } else if (typeof msg.input !== "string") { + console.error(`terminalInput: missing or malformed input field`); + } else { + this.term.write(msg.input); + } + break; + default: + console.error(`unknown client message type: ${msg.event}`); + break; + } + } + run() { + const cmdline = this.config.cmdline; + if (this.term) { + this.term.kill(); + } + this.term = pty.spawn(cmdline[0], cmdline.slice(1), { + name: "xterm-color", + cwd: process.env.PWD, + env: process.env, + }); + this.term.on("data", (data) => + this.ws.send(JSON.stringify({ event: "terminalOutput", output: data })) + ); + } +} diff --git a/backend/src/global.d.ts b/backend/src/global.d.ts new file mode 100644 index 0000000..3aad786 --- /dev/null +++ b/backend/src/global.d.ts @@ -0,0 +1 @@ +declare module "heroku-ssl-redirect"; diff --git a/backend/src/langs.ts b/backend/src/langs.ts new file mode 100644 index 0000000..2ee1631 --- /dev/null +++ b/backend/src/langs.ts @@ -0,0 +1,27 @@ +export interface LangConfig { + cmdline: string[]; + name: string; +} + +export const langs = { + c: { + cmdline: ["echo", "not implemented"], + name: "C", + }, + "c++": { + cmdline: ["echo", "not implemented"], + name: "C++", + }, + haskell: { + cmdline: ["ghci"], + name: "Haskell", + }, + nodejs: { + cmdline: ["node"], + name: "Node.js", + }, + python: { + cmdline: ["python3"], + name: "Python", + }, +}; diff --git a/backend/src/server.ts b/backend/src/server.ts new file mode 100644 index 0000000..a32c637 --- /dev/null +++ b/backend/src/server.ts @@ -0,0 +1,42 @@ +import * as appRoot from "app-root-path"; +import * as express from "express"; +import * as ws from "express-ws"; +import * as sslRedirect from "heroku-ssl-redirect"; + +import * as api from "./api"; +import { langs } from "./langs"; + +const app = ws(express()).app; +const host = process.env.HOST || "localhost"; +const port = parseInt(process.env.PORT) || 6119; + +app.use(sslRedirect()); +app.get("/", (_, res) => { + res.sendFile(appRoot.path + "/frontend/pages/index.html"); +}); +app.get("/:lang", (req, res) => { + if (langs[req.params.lang]) { + res.sendFile(appRoot.path + "/frontend/pages/app.html"); + } else { + res.send(`No such language: ${req.params.lang}`); + } +}); +app.use("/js", express.static(appRoot.path + "/frontend/out")); +app.use("/api/v1/ws", (req, res, next) => { + if (!req.query.lang) { + res.status(400); + res.send("No language specified"); + } else if (!langs[req.query.lang as string]) { + res.status(400); + res.send(`No such language: ${req.query.lang}`); + } else { + return next(); + } +}); +app.ws("/api/v1/ws", (ws, req) => { + new api.Session(ws, req.query.lang); +}); + +app.listen(port, host, () => + console.log(`Listening on http://${host}:${port}`) +); diff --git a/dynamic/app.html b/frontend/pages/app.html similarity index 75% rename from dynamic/app.html rename to frontend/pages/app.html index fc2765f..6c318f8 100644 --- a/dynamic/app.html +++ b/frontend/pages/app.html @@ -3,6 +3,7 @@ Fast Sandbox + Editor :) diff --git a/static/index.html b/frontend/pages/index.html similarity index 100% rename from static/index.html rename to frontend/pages/index.html diff --git a/frontend/src/app.ts b/frontend/src/app.ts new file mode 100644 index 0000000..f95c728 --- /dev/null +++ b/frontend/src/app.ts @@ -0,0 +1 @@ +console.log("Hi there"); diff --git a/langs.json b/langs.json deleted file mode 100644 index c838694..0000000 --- a/langs.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "c": { - "name": "C" - }, - "c++": { - "name": "C++" - }, - "haskell": { - "name": "Haskell" - }, - "nodejs": { - "name": "Node.js" - }, - "python": { - "name": "Python" - } -} diff --git a/package.json b/package.json index a070453..0a82d6a 100644 --- a/package.json +++ b/package.json @@ -4,10 +4,24 @@ "license": "MIT", "private": true, "dependencies": { + "@types/app-root-path": "^1.2.4", + "@types/express": "^4.17.6", + "@types/express-ws": "^3.0.0", "app-root-path": "^3.0.0", "express": "^4.17.1", "express-ws": "^4.0.0", "heroku-ssl-redirect": "^0.0.4", - "node-pty": "^0.9.0" + "node-pty": "^0.9.0", + "typescript": "^3.9.5", + "webpack": "^4.43.0", + "webpack-cli": "^3.3.11" + }, + "scripts": { + "backend": "tsc", + "backend-dev": "tsc --watch", + "frontend": "webpack --production", + "frontend-dev": "webpack --development --watch", + "server": "node server.js", + "server-dev": "watchexec -w backend/out -r -n node backend/out/server.js" } } diff --git a/src/server.js b/src/server.js deleted file mode 100644 index b21e2bb..0000000 --- a/src/server.js +++ /dev/null @@ -1,24 +0,0 @@ -const appRoot = require("app-root-path"); - -const langs = require(appRoot + "/langs"); - -const express = require("express"); -const sslRedirect = require("heroku-ssl-redirect"); - -const app = express(); -const host = process.env.HOST || "localhost"; -const port = parseInt(process.env.PORT) || 6119; - -app.use(sslRedirect()); -app.get("/:lang", (req, res) => { - if (langs[req.params.lang]) { - res.sendFile(appRoot + "/dynamic/app.html"); - } else { - res.send(`No such language: ${req.params.lang}`); - } -}); -app.use("/", express.static(appRoot + "/static")); - -app.listen(port, host, () => - console.log(`Listening on http://${host}:${port}`) -); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..a27d286 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "outDir": "./backend/out", + "resolveJsonModule": true, + "rootDir": "./backend/src", + "sourceMap": true + }, + "include": ["backend/src"] +} diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..9fd1a19 --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,10 @@ +const path = require("path"); + +module.exports = { + entry: "./frontend/src/app.ts", + mode: process.env.NODE_ENV || "production", + output: { + path: path.resolve(__dirname, "frontend/out"), + filename: "app.js", + }, +}; diff --git a/yarn.lock b/yarn.lock index 5bc799a..0f90b56 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,244 @@ # yarn lockfile v1 +"@types/app-root-path@^1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/app-root-path/-/app-root-path-1.2.4.tgz#a78b703282b32ac54de768f5512ecc3569919dc7" + integrity sha1-p4twMoKzKsVN52j1US7MNWmRncc= + +"@types/body-parser@*": + version "1.19.0" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.0.tgz#0685b3c47eb3006ffed117cdd55164b61f80538f" + integrity sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.33" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.33.tgz#31610c901eca573b8713c3330abc6e6b9f588546" + integrity sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A== + dependencies: + "@types/node" "*" + +"@types/express-serve-static-core@*": + version "4.17.7" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.7.tgz#dfe61f870eb549dc6d7e12050901847c7d7e915b" + integrity sha512-EMgTj/DF9qpgLXyc+Btimg+XoH7A2liE8uKul8qSmMTHCeNYzydDKFdsJskDvw42UsesCnhO63dO0Grbj8J4Dw== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express-ws@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/express-ws/-/express-ws-3.0.0.tgz#89674edba2e9141916fc4d4d30fbd4f810e6b80b" + integrity sha512-GxsWec7Vp6h7sJuK0PwnZHeXNZnOwQn8kHAbCfvii66it5jXHTWzSg5cgHVtESwJfBLOe9SJ5wmM7C6gsDoyQw== + dependencies: + "@types/express" "*" + "@types/express-serve-static-core" "*" + "@types/ws" "*" + +"@types/express@*", "@types/express@^4.17.6": + version "4.17.6" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.6.tgz#6bce49e49570507b86ea1b07b806f04697fac45e" + integrity sha512-n/mr9tZI83kd4azlPG5y997C/M4DNABK9yErhFM6hKdym4kkmd9j0vtsJyjFIwfRBxtrxZtAfGZCNRIBMFLK5w== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "*" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/mime@*": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.2.tgz#857a118d8634c84bba7ae14088e4508490cd5da5" + integrity sha512-4kPlzbljFcsttWEq6aBW0OZe6BDajAmyvr2xknBG92tejQnvdGtT9+kXSZ580DqpxY9qG2xeQVF9Dq0ymUTo5Q== + +"@types/node@*": + version "14.0.11" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.11.tgz#61d4886e2424da73b7b25547f59fdcb534c165a3" + integrity sha512-lCvvI24L21ZVeIiyIUHZ5Oflv1hhHQ5E1S25IRlKIXaRkVgmXpJMI3wUJkmym2bTbCe+WoIibQnMVAU3FguaOg== + +"@types/qs@*": + version "6.9.3" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.3.tgz#b755a0934564a200d3efdf88546ec93c369abd03" + integrity sha512-7s9EQWupR1fTc2pSMtXRQ9w9gLOcrJn+h7HOXw4evxyvVqMi4f+q7d2tnFe3ng3SNHjtK+0EzGMGFUQX4/AQRA== + +"@types/range-parser@*": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" + integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== + +"@types/serve-static@*": + version "1.13.4" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.4.tgz#6662a93583e5a6cabca1b23592eb91e12fa80e7c" + integrity sha512-jTDt0o/YbpNwZbQmE/+2e+lfjJEJJR0I3OFaKQKPWkASkCoW3i6fsUnqudSMcNAfbtmADGu8f4MV4q+GqULmug== + dependencies: + "@types/express-serve-static-core" "*" + "@types/mime" "*" + +"@types/ws@*": + version "7.2.5" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.2.5.tgz#513f28b04a1ea1aa9dc2cad3f26e8e37c88aae49" + integrity sha512-4UEih9BI1nBKii385G9id1oFrSkLcClbwtDfcYj8HJLQqZVAtb/42vXVrYvRWCcufNF/a+rZD3MxNwghA7UmCg== + dependencies: + "@types/node" "*" + +"@webassemblyjs/ast@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" + integrity sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA== + dependencies: + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" + +"@webassemblyjs/floating-point-hex-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz#3c3d3b271bddfc84deb00f71344438311d52ffb4" + integrity sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA== + +"@webassemblyjs/helper-api-error@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz#203f676e333b96c9da2eeab3ccef33c45928b6a2" + integrity sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw== + +"@webassemblyjs/helper-buffer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz#a1442d269c5feb23fcbc9ef759dac3547f29de00" + integrity sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA== + +"@webassemblyjs/helper-code-frame@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz#647f8892cd2043a82ac0c8c5e75c36f1d9159f27" + integrity sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA== + dependencies: + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/helper-fsm@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz#c05256b71244214671f4b08ec108ad63b70eddb8" + integrity sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw== + +"@webassemblyjs/helper-module-context@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz#25d8884b76839871a08a6c6f806c3979ef712f07" + integrity sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g== + dependencies: + "@webassemblyjs/ast" "1.9.0" + +"@webassemblyjs/helper-wasm-bytecode@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz#4fed8beac9b8c14f8c58b70d124d549dd1fe5790" + integrity sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw== + +"@webassemblyjs/helper-wasm-section@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz#5a4138d5a6292ba18b04c5ae49717e4167965346" + integrity sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + +"@webassemblyjs/ieee754@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz#15c7a0fbaae83fb26143bbacf6d6df1702ad39e4" + integrity sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.0.tgz#f19ca0b76a6dc55623a09cffa769e838fa1e1c95" + integrity sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.0.tgz#04d33b636f78e6a6813227e82402f7637b6229ab" + integrity sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w== + +"@webassemblyjs/wasm-edit@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz#3fe6d79d3f0f922183aa86002c42dd256cfee9cf" + integrity sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/helper-wasm-section" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-opt" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/wasm-gen@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz#50bc70ec68ded8e2763b01a1418bf43491a7a49c" + integrity sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wasm-opt@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz#2211181e5b31326443cc8112eb9f0b9028721a61" + integrity sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + +"@webassemblyjs/wasm-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz#9d48e44826df4a6598294aa6c87469d642fff65e" + integrity sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wast-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz#3031115d79ac5bd261556cecc3fa90a3ef451914" + integrity sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/floating-point-hex-parser" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-code-frame" "1.9.0" + "@webassemblyjs/helper-fsm" "1.9.0" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/wast-printer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz#4935d54c85fef637b00ce9f52377451d00d47899" + integrity sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" + "@xtuc/long" "4.2.2" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + accepts@~1.3.7: version "1.3.7" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" @@ -10,21 +248,191 @@ accepts@~1.3.7: mime-types "~2.1.24" negotiator "0.6.2" +acorn@^6.4.1: + version "6.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" + integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== + +ajv-errors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" + integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== + +ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" + integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== + +ajv@^6.1.0, ajv@^6.10.2: + version "6.12.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.2.tgz#c629c5eced17baf314437918d2da88c99d5958cd" + integrity sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +anymatch@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" + integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + app-root-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-3.0.0.tgz#210b6f43873227e18a4b810a032283311555d5ad" integrity sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw== +aproba@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +asn1.js@^4.0.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +assert@^1.1.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" + integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== + dependencies: + object-assign "^4.1.1" + util "0.10.3" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== + async-limiter@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base64-js@^1.0.2: + version "1.3.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" + integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== + +binary-extensions@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c" + integrity sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow== + +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +bluebird@^3.5.5: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.4.0: + version "4.11.9" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828" + integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw== + +bn.js@^5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.2.tgz#c9686902d3c9a27729f43ab10f9d79c2004da7b0" + integrity sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA== + body-parser@1.19.0: version "1.19.0" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" @@ -41,11 +449,315 @@ body-parser@1.19.0: raw-body "2.4.0" type-is "~1.6.17" +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= + dependencies: + bn.js "^4.1.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.0.tgz#545d0b1b07e6b2c99211082bf1b12cce7a0b0e11" + integrity sha512-hEZC1KEeYuoHRqhGhTy6gWrpJA3ZDjFWv0DE61643ZnOXAKJb3u7yWcrU0mMc9SwAqK1n7myPGndkp0dFG7NFA== + dependencies: + bn.js "^5.1.1" + browserify-rsa "^4.0.1" + create-hash "^1.2.0" + create-hmac "^1.1.7" + elliptic "^6.5.2" + inherits "^2.0.4" + parse-asn1 "^5.1.5" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== + dependencies: + pako "~1.0.5" + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= + +buffer@^4.3.0: + version "4.9.2" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= + bytes@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== +cacache@^12.0.2: + version "12.0.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" + integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ== + dependencies: + bluebird "^3.5.5" + chownr "^1.1.1" + figgy-pudding "^3.5.1" + glob "^7.1.4" + graceful-fs "^4.1.15" + infer-owner "^1.0.3" + lru-cache "^5.1.1" + mississippi "^3.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.3" + ssri "^6.0.1" + unique-filename "^1.1.1" + y18n "^4.0.0" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +camelcase@^5.0.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +chalk@2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chokidar@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" + optionalDependencies: + fsevents "^1.2.7" + +chokidar@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.0.tgz#b30611423ce376357c765b9b8f904b9fba3c0be8" + integrity sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.4.0" + optionalDependencies: + fsevents "~2.1.2" + +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + +chrome-trace-event@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" + integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== + dependencies: + tslib "^1.9.0" + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== + dependencies: + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concat-stream@^1.5.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +console-browserify@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" + integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== + +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= + content-disposition@0.5.3: version "0.5.3" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" @@ -68,43 +780,329 @@ cookie@0.4.0: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== -debug@2.6.9: +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +create-ecdh@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" + integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== + dependencies: + bn.js "^4.1.0" + elliptic "^6.0.0" + +create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +cross-spawn@6.0.5, cross-spawn@^6.0.0: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +crypto-browserify@^3.11.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +cyclist@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" + integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= + +debug@2.6.9, debug@^2.2.0, debug@^2.3.3: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" +decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= +des.js@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" + integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + destroy@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= +detect-file@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" + integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +domain-browser@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== + +duplexify@^3.4.2, duplexify@^3.6.0: + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= +elliptic@^6.0.0, elliptic@^6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" + integrity sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw== + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +enhanced-resolve@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f" + integrity sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.4.0" + tapable "^1.0.0" + +enhanced-resolve@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz#2937e2b8066cd0fe7ce0990a98f0d71a35189f66" + integrity sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.5.0" + tapable "^1.0.0" + +errno@^0.1.3, errno@~0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" + integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== + dependencies: + prr "~1.0.1" + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +eslint-scope@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" + integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +esrecurse@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== + dependencies: + estraverse "^4.1.0" + +estraverse@^4.1.0, estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + etag@~1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= +events@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.1.0.tgz#84279af1b34cb75aa88bf5ff291f6d0bd9b31a59" + integrity sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg== + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expand-tilde@^2.0.0, expand-tilde@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI= + dependencies: + homedir-polyfill "^1.0.1" + express-ws@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/express-ws/-/express-ws-4.0.0.tgz#dabd8dc974516418902a41fe6e30ed949b4d36c4" @@ -148,6 +1146,72 @@ express@^4.17.1: utils-merge "1.0.1" vary "~1.1.2" +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +fast-deep-equal@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" + integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +figgy-pudding@^3.5.1: + version "3.5.2" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" + integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== + +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + finalhandler@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" @@ -161,21 +1225,257 @@ finalhandler@~1.1.2: statuses "~1.5.0" unpipe "~1.0.0" +find-cache-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" + integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== + dependencies: + commondir "^1.0.1" + make-dir "^2.0.0" + pkg-dir "^3.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +findup-sync@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1" + integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg== + dependencies: + detect-file "^1.0.0" + is-glob "^4.0.0" + micromatch "^3.0.4" + resolve-dir "^1.0.1" + +flush-write-stream@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" + integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== + dependencies: + inherits "^2.0.3" + readable-stream "^2.3.6" + +for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + forwarded@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= +from2@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@^1.2.7: + version "1.2.13" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" + integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== + dependencies: + bindings "^1.5.0" + nan "^2.12.1" + +fsevents@~2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" + integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== + +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-parent@~5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" + integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== + dependencies: + is-glob "^4.0.1" + +glob@^7.1.3, glob@^7.1.4: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global-modules@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" + integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== + dependencies: + global-prefix "^3.0.0" + +global-modules@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" + integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== + dependencies: + global-prefix "^1.0.1" + is-windows "^1.0.1" + resolve-dir "^1.0.0" + +global-prefix@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" + integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4= + dependencies: + expand-tilde "^2.0.2" + homedir-polyfill "^1.0.1" + ini "^1.3.4" + is-windows "^1.0.1" + which "^1.2.14" + +global-prefix@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" + integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== + dependencies: + ini "^1.3.5" + kind-of "^6.0.2" + which "^1.3.1" + +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2: + version "4.2.4" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" + integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +hash-base@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== + dependencies: + inherits "^2.0.4" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + heroku-ssl-redirect@^0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/heroku-ssl-redirect/-/heroku-ssl-redirect-0.0.4.tgz#21ba0707aa503b50a412a0946abfaa88ef7d082c" integrity sha1-IboHB6pQO1CkEqCUar+qiO99CCw= +hmac-drbg@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +homedir-polyfill@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" + integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== + dependencies: + parse-passwd "^1.0.0" + http-errors@1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" @@ -198,6 +1498,11 @@ http-errors@~1.7.2: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= + iconv-lite@0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -205,26 +1510,386 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" +ieee754@^1.1.4: + version "1.1.13" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= + +import-local@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" + integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== + dependencies: + pkg-dir "^3.0.0" + resolve-cwd "^2.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +infer-owner@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= + inherits@2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= -inherits@2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +ini@^1.3.4, ini@^1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + +interpret@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" + integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== + +invert-kv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" + integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= + dependencies: + binary-extensions "^1.0.0" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-windows@^1.0.1, is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +lcid@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" + integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== + dependencies: + invert-kv "^2.0.0" + +loader-runner@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" + integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== + +loader-utils@1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" + integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== + dependencies: + big.js "^5.2.2" + emojis-list "^2.0.0" + json5 "^1.0.1" + +loader-utils@^1.2.3: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" + integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^1.0.1" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +make-dir@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + +map-age-cleaner@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== + dependencies: + p-defer "^1.0.0" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= +mem@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" + integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== + dependencies: + map-age-cleaner "^0.1.1" + mimic-fn "^2.0.0" + p-is-promise "^2.0.0" + +memory-fs@^0.4.0, memory-fs@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +memory-fs@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" + integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" @@ -235,6 +1900,33 @@ methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= +micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + mime-db@1.44.0: version "1.44.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" @@ -252,6 +1944,76 @@ mime@1.6.0: resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== +mimic-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.0, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +mississippi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" + integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^3.0.0" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@^0.5.1, mkdirp@^0.5.3: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -262,16 +2024,72 @@ ms@2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== -nan@^2.14.0: +nan@^2.12.1, nan@^2.14.0: version "2.14.1" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + negotiator@0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== +neo-async@^2.5.0, neo-async@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" + integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +node-libs-browser@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" + integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== + dependencies: + assert "^1.1.1" + browserify-zlib "^0.2.0" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^3.0.0" + https-browserify "^1.0.0" + os-browserify "^0.3.0" + path-browserify "0.0.1" + process "^0.11.10" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.3.3" + stream-browserify "^2.0.1" + stream-http "^2.7.2" + string_decoder "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.11.0" + vm-browserify "^1.0.1" + node-pty@^0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/node-pty/-/node-pty-0.9.0.tgz#8f9bcc0d1c5b970a3184ffd533d862c7eb6590a6" @@ -279,6 +2097,53 @@ node-pty@^0.9.0: dependencies: nan "^2.14.0" +normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + dependencies: + path-key "^2.0.0" + +object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" @@ -286,16 +2151,180 @@ on-finished@~2.3.0: dependencies: ee-first "1.1.1" +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= + +os-locale@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" + integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== + dependencies: + execa "^1.0.0" + lcid "^2.0.0" + mem "^4.0.0" + +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-is-promise@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" + integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== + +p-limit@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +pako@~1.0.5: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + +parallel-transform@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" + integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg== + dependencies: + cyclist "^1.0.1" + inherits "^2.0.3" + readable-stream "^2.1.5" + +parse-asn1@^5.0.0, parse-asn1@^5.1.5: + version "5.1.5" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e" + integrity sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ== + dependencies: + asn1.js "^4.0.0" + browserify-aes "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" + +parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= + parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +path-browserify@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" + integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= +pbkdf2@^3.0.3: + version "3.1.1" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94" + integrity sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +picomatch@^2.0.4, picomatch@^2.2.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" + integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== + dependencies: + find-up "^3.0.0" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= + proxy-addr@~2.0.5: version "2.0.6" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" @@ -304,11 +2333,93 @@ proxy-addr@~2.0.5: forwarded "~0.1.2" ipaddr.js "1.9.1" +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + +punycode@^1.2.4: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + qs@6.7.0: version "6.7.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== +querystring-es3@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + range-parser@~1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" @@ -324,16 +2435,165 @@ raw-body@2.4.0: iconv-lite "0.4.24" unpipe "1.0.0" -safe-buffer@5.1.2: +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +readdirp@~3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.4.0.tgz#9fdccdf9e9155805449221ac645e8303ab5b9ada" + integrity sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ== + dependencies: + picomatch "^2.2.1" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +repeat-element@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= + dependencies: + resolve-from "^3.0.0" + +resolve-dir@^1.0.0, resolve-dir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" + integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M= + dependencies: + expand-tilde "^2.0.0" + global-modules "^1.0.0" + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + integrity sha1-six699nWiBvItuZTM17rywoYh0g= + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +rimraf@^2.5.4, rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= + dependencies: + aproba "^1.1.1" + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + "safer-buffer@>= 2.1.2 < 3": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +schema-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" + integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== + dependencies: + ajv "^6.1.0" + ajv-errors "^1.0.0" + ajv-keywords "^3.1.0" + +semver@^5.5.0, semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + send@0.17.1: version "0.17.1" resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" @@ -353,6 +2613,13 @@ send@0.17.1: range-parser "~1.2.1" statuses "~1.5.0" +serialize-javascript@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-3.1.0.tgz#8bf3a9170712664ef2561b44b691eafe399214ea" + integrity sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg== + dependencies: + randombytes "^2.1.0" + serve-static@1.14.1: version "1.14.1" resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" @@ -363,21 +2630,329 @@ serve-static@1.14.1: parseurl "~1.3.3" send "0.17.1" +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setimmediate@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= + setprototypeof@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +signal-exit@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" + integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +source-list-map@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + +source-map-resolve@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@~0.5.12: + version "0.5.19" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" + integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + +source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +ssri@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" + integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== + dependencies: + figgy-pudding "^3.5.1" + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + "statuses@>= 1.5.0 < 2", statuses@~1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= +stream-browserify@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" + integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-each@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" + integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + +stream-http@^2.7.2: + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.6" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +stream-shift@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" + integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== + +string-width@^3.0.0, string-width@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string_decoder@^1.0.0, string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + +supports-color@6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" + integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== + dependencies: + has-flag "^3.0.0" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +tapable@^1.0.0, tapable@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" + integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== + +terser-webpack-plugin@^1.4.3: + version "1.4.4" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.4.tgz#2c63544347324baafa9a56baaddf1634c8abfc2f" + integrity sha512-U4mACBHIegmfoEe5fdongHESNJWqsGU+W0S/9+BmYGVQDw1+c2Ow05TpMhxjPK1sRb7cuYq1BPl1e5YHJMTCqA== + dependencies: + cacache "^12.0.2" + find-cache-dir "^2.1.0" + is-wsl "^1.1.0" + schema-utils "^1.0.0" + serialize-javascript "^3.1.0" + source-map "^0.6.1" + terser "^4.1.2" + webpack-sources "^1.4.0" + worker-farm "^1.7.0" + +terser@^4.1.2: + version "4.7.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.7.0.tgz#15852cf1a08e3256a80428e865a2fa893ffba006" + integrity sha512-Lfb0RiZcjRDXCC3OSHJpEkxJ9Qeqs6mp2v4jf2MHfy8vGERmVDuvjXdd/EnP5Deme5F2yBRBymKmKHCBg2echw== + dependencies: + commander "^2.20.0" + source-map "~0.6.1" + source-map-support "~0.5.12" + +through2@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +timers-browserify@^2.0.4: + version "2.0.11" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.11.tgz#800b1f3eee272e5bc53ee465a04d0e804c31211f" + integrity sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ== + dependencies: + setimmediate "^1.0.4" + +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + toidentifier@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== +tslib@^1.9.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" + integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== + +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= + type-is@~1.6.17, type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -386,24 +2961,270 @@ type-is@~1.6.17, type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +typescript@^3.9.5: + version "3.9.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.5.tgz#586f0dba300cde8be52dd1ac4f7e1009c1b13f36" + integrity sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ== + +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + +unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" + integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== + dependencies: + imurmurhash "^0.1.4" + unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +upath@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= + dependencies: + inherits "2.0.1" + +util@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" + integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== + dependencies: + inherits "2.0.3" + utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= +v8-compile-cache@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe" + integrity sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w== + vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= +vm-browserify@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" + integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== + +watchpack-chokidar2@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz#9948a1866cbbd6cb824dea13a7ed691f6c8ddff0" + integrity sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA== + dependencies: + chokidar "^2.1.8" + +watchpack@^1.6.1: + version "1.7.2" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.2.tgz#c02e4d4d49913c3e7e122c3325365af9d331e9aa" + integrity sha512-ymVbbQP40MFTp+cNMvpyBpBtygHnPzPkHqoIwRRj/0B8KhqQwV8LaKjtbaxF2lK4vl8zN9wCxS46IFCU5K4W0g== + dependencies: + graceful-fs "^4.1.2" + neo-async "^2.5.0" + optionalDependencies: + chokidar "^3.4.0" + watchpack-chokidar2 "^2.0.0" + +webpack-cli@^3.3.11: + version "3.3.11" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.11.tgz#3bf21889bf597b5d82c38f215135a411edfdc631" + integrity sha512-dXlfuml7xvAFwYUPsrtQAA9e4DOe58gnzSxhgrO/ZM/gyXTBowrsYeubyN4mqGhYdpXMFNyQ6emjJS9M7OBd4g== + dependencies: + chalk "2.4.2" + cross-spawn "6.0.5" + enhanced-resolve "4.1.0" + findup-sync "3.0.0" + global-modules "2.0.0" + import-local "2.0.0" + interpret "1.2.0" + loader-utils "1.2.3" + supports-color "6.1.0" + v8-compile-cache "2.0.3" + yargs "13.2.4" + +webpack-sources@^1.4.0, webpack-sources@^1.4.1: + version "1.4.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" + integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack@^4.43.0: + version "4.43.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.43.0.tgz#c48547b11d563224c561dad1172c8aa0b8a678e6" + integrity sha512-GW1LjnPipFW2Y78OOab8NJlCflB7EFskMih2AHdvjbpKMeDJqEgSx24cXXXiPS65+WSwVyxtDsJH6jGX2czy+g== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/wasm-edit" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + acorn "^6.4.1" + ajv "^6.10.2" + ajv-keywords "^3.4.1" + chrome-trace-event "^1.0.2" + enhanced-resolve "^4.1.0" + eslint-scope "^4.0.3" + json-parse-better-errors "^1.0.2" + loader-runner "^2.4.0" + loader-utils "^1.2.3" + memory-fs "^0.4.1" + micromatch "^3.1.10" + mkdirp "^0.5.3" + neo-async "^2.6.1" + node-libs-browser "^2.2.1" + schema-utils "^1.0.0" + tapable "^1.1.3" + terser-webpack-plugin "^1.4.3" + watchpack "^1.6.1" + webpack-sources "^1.4.1" + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which@^1.2.14, which@^1.2.9, which@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +worker-farm@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" + integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== + dependencies: + errno "~0.1.7" + +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== + dependencies: + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + ws@^5.2.0: version "5.2.2" resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA== dependencies: async-limiter "~1.0.0" + +xtend@^4.0.0, xtend@~4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yargs-parser@^13.1.0: + version "13.1.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" + integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs@13.2.4: + version "13.2.4" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83" + integrity sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg== + dependencies: + cliui "^5.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + os-locale "^3.1.0" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.1.0" From 0961498f65493243f544f8f73be6a88b57856f25 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 6 Jun 2020 10:41:55 -0600 Subject: [PATCH 011/388] Embed terminal on frontend app --- backend/src/server.ts | 1 + frontend/pages/app.html | 3 +- frontend/src/app.ts | 13 +++- frontend/styles/app.css | 7 ++ package.json | 6 +- webpack.config.js | 11 +++ yarn.lock | 158 +++++++++++++++++++++++++++++++++++++++- 7 files changed, 192 insertions(+), 7 deletions(-) create mode 100644 frontend/styles/app.css diff --git a/backend/src/server.ts b/backend/src/server.ts index a32c637..6ddee1b 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -21,6 +21,7 @@ app.get("/:lang", (req, res) => { res.send(`No such language: ${req.params.lang}`); } }); +app.use("/css", express.static(appRoot.path + "/frontend/styles")); app.use("/js", express.static(appRoot.path + "/frontend/out")); app.use("/api/v1/ws", (req, res, next) => { if (!req.query.lang) { diff --git a/frontend/pages/app.html b/frontend/pages/app.html index 6c318f8..31e1e0c 100644 --- a/frontend/pages/app.html +++ b/frontend/pages/app.html @@ -3,9 +3,10 @@ Fast Sandbox + - Editor :) +
diff --git a/frontend/src/app.ts b/frontend/src/app.ts index f95c728..a295f7a 100644 --- a/frontend/src/app.ts +++ b/frontend/src/app.ts @@ -1 +1,12 @@ -console.log("Hi there"); +import { Terminal } from "xterm"; +import { FitAddon } from "xterm-addon-fit"; + +import "xterm/css/xterm.css"; + +const term = new Terminal(); +const fitAddon = new FitAddon(); +term.loadAddon(fitAddon); +term.open(document.getElementById("terminal")); + +fitAddon.fit(); +window.addEventListener("resize", () => fitAddon.fit()); diff --git a/frontend/styles/app.css b/frontend/styles/app.css new file mode 100644 index 0000000..dc2f5e8 --- /dev/null +++ b/frontend/styles/app.css @@ -0,0 +1,7 @@ +body { + margin: 0; +} + +#terminal { + height: 100vh; +} diff --git a/package.json b/package.json index 0a82d6a..5662796 100644 --- a/package.json +++ b/package.json @@ -8,13 +8,17 @@ "@types/express": "^4.17.6", "@types/express-ws": "^3.0.0", "app-root-path": "^3.0.0", + "css-loader": "^3.5.3", "express": "^4.17.1", "express-ws": "^4.0.0", "heroku-ssl-redirect": "^0.0.4", "node-pty": "^0.9.0", + "style-loader": "^1.2.1", "typescript": "^3.9.5", "webpack": "^4.43.0", - "webpack-cli": "^3.3.11" + "webpack-cli": "^3.3.11", + "xterm": "^4.6.0", + "xterm-addon-fit": "^0.4.0" }, "scripts": { "backend": "tsc", diff --git a/webpack.config.js b/webpack.config.js index 9fd1a19..b26ce12 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -3,8 +3,19 @@ const path = require("path"); module.exports = { entry: "./frontend/src/app.ts", mode: process.env.NODE_ENV || "production", + module: { + rules: [ + { + test: /\.css$/i, + use: ["style-loader", "css-loader"], + }, + ], + }, output: { path: path.resolve(__dirname, "frontend/out"), filename: "app.js", }, + performance: { + hints: false, + }, }; diff --git a/yarn.lock b/yarn.lock index 0f90b56..ad43c5d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -50,6 +50,11 @@ "@types/qs" "*" "@types/serve-static" "*" +"@types/json-schema@^7.0.4": + version "7.0.4" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339" + integrity sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA== + "@types/mime@*": version "2.0.2" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.2.tgz#857a118d8634c84bba7ae14088e4508490cd5da5" @@ -263,7 +268,7 @@ ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== -ajv@^6.1.0, ajv@^6.10.2: +ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.2: version "6.12.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.2.tgz#c629c5eced17baf314437918d2da88c99d5958cd" integrity sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ== @@ -611,12 +616,12 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" -camelcase@^5.0.0: +camelcase@^5.0.0, camelcase@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -chalk@2.4.2: +chalk@2.4.2, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -861,6 +866,30 @@ crypto-browserify@^3.11.0: randombytes "^2.0.0" randomfill "^1.0.3" +css-loader@^3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.5.3.tgz#95ac16468e1adcd95c844729e0bb167639eb0bcf" + integrity sha512-UEr9NH5Lmi7+dguAm+/JSPovNjYbm2k3TK58EiwQHzOHH5Jfq1Y+XoP2bQO6TMn7PptMd0opxxedAWcaSTRKHw== + dependencies: + camelcase "^5.3.1" + cssesc "^3.0.0" + icss-utils "^4.1.1" + loader-utils "^1.2.3" + normalize-path "^3.0.0" + postcss "^7.0.27" + postcss-modules-extract-imports "^2.0.0" + postcss-modules-local-by-default "^3.0.2" + postcss-modules-scope "^2.2.0" + postcss-modules-values "^3.0.0" + postcss-value-parser "^4.0.3" + schema-utils "^2.6.6" + semver "^6.3.0" + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + cyclist@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" @@ -1510,6 +1539,13 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" +icss-utils@^4.0.0, icss-utils@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" + integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA== + dependencies: + postcss "^7.0.14" + ieee754@^1.1.4: version "1.1.13" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" @@ -1533,6 +1569,11 @@ imurmurhash@^0.1.4: resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= +indexes-of@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" + integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= + infer-owner@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" @@ -1755,6 +1796,13 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" +json5@^2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" + integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== + dependencies: + minimist "^1.2.5" + kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -1809,6 +1857,15 @@ loader-utils@^1.2.3: emojis-list "^3.0.0" json5 "^1.0.1" +loader-utils@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0" + integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + locate-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" @@ -2310,6 +2367,62 @@ posix-character-classes@^0.1.0: resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= +postcss-modules-extract-imports@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e" + integrity sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ== + dependencies: + postcss "^7.0.5" + +postcss-modules-local-by-default@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz#e8a6561be914aaf3c052876377524ca90dbb7915" + integrity sha512-jM/V8eqM4oJ/22j0gx4jrp63GSvDH6v86OqyTHHUvk4/k1vceipZsaymiZ5PvocqZOl5SFHiFJqjs3la0wnfIQ== + dependencies: + icss-utils "^4.1.1" + postcss "^7.0.16" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.0.0" + +postcss-modules-scope@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz#385cae013cc7743f5a7d7602d1073a89eaae62ee" + integrity sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ== + dependencies: + postcss "^7.0.6" + postcss-selector-parser "^6.0.0" + +postcss-modules-values@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz#5b5000d6ebae29b4255301b4a3a54574423e7f10" + integrity sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg== + dependencies: + icss-utils "^4.0.0" + postcss "^7.0.6" + +postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz#934cf799d016c83411859e09dcecade01286ec5c" + integrity sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg== + dependencies: + cssesc "^3.0.0" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" + integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== + +postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.27, postcss@^7.0.5, postcss@^7.0.6: + version "7.0.32" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.32.tgz#4310d6ee347053da3433db2be492883d62cec59d" + integrity sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw== + dependencies: + chalk "^2.4.2" + source-map "^0.6.1" + supports-color "^6.1.0" + process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" @@ -2589,11 +2702,25 @@ schema-utils@^1.0.0: ajv-errors "^1.0.0" ajv-keywords "^3.1.0" +schema-utils@^2.6.6: + version "2.7.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7" + integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== + dependencies: + "@types/json-schema" "^7.0.4" + ajv "^6.12.2" + ajv-keywords "^3.4.1" + semver@^5.5.0, semver@^5.6.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== +semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + send@0.17.1: version "0.17.1" resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" @@ -2843,7 +2970,15 @@ strip-eof@^1.0.0: resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= -supports-color@6.1.0: +style-loader@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.2.1.tgz#c5cbbfbf1170d076cfdd86e0109c5bba114baa1a" + integrity sha512-ByHSTQvHLkWE9Ir5+lGbVOXhxX10fbprhLvdg96wedFZb4NDekDPxVKv5Fwmio+QcMlkkNfuK+5W1peQ5CUhZg== + dependencies: + loader-utils "^2.0.0" + schema-utils "^2.6.6" + +supports-color@6.1.0, supports-color@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== @@ -2981,6 +3116,11 @@ union-value@^1.0.0: is-extendable "^0.1.1" set-value "^2.0.1" +uniq@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" + integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= + unique-filename@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" @@ -3194,6 +3334,16 @@ xtend@^4.0.0, xtend@~4.0.1: resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== +xterm-addon-fit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/xterm-addon-fit/-/xterm-addon-fit-0.4.0.tgz#06e0c5d0a6aaacfb009ef565efa1c81e93d90193" + integrity sha512-p4BESuV/g2L6pZzFHpeNLLnep9mp/DkF3qrPglMiucSFtD8iJxtMufEoEJbN8LZwB4i+8PFpFvVuFrGOSpW05w== + +xterm@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.6.0.tgz#1b49b32e546409c110fbe8ece0b4a388504a937d" + integrity sha512-98211RIDrAECqpsxs6gbilwMcxLtxSDIvtzZUIqP1xIByXtuccJ4pmMhHGJATZeEGe/reARPMqwPINK8T7jGZg== + y18n@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" From fb87fc0bcf0187cfb84e505077d0b76fff487c39 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 6 Jun 2020 10:47:48 -0600 Subject: [PATCH 012/388] Connect to websocket from server --- frontend/src/app.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/frontend/src/app.ts b/frontend/src/app.ts index a295f7a..456c261 100644 --- a/frontend/src/app.ts +++ b/frontend/src/app.ts @@ -10,3 +10,20 @@ term.open(document.getElementById("terminal")); fitAddon.fit(); window.addEventListener("resize", () => fitAddon.fit()); + +const socket = new WebSocket( + (document.location.protocol === "http:" ? "ws://" : "wss://") + + document.location.host + + "/api/v1/ws" +); + +socket.onopen = () => console.log("Successfully connected to server"); +socket.onmessage = (event) => console.log(event); +socket.onclose = (event) => { + if (event.wasClean) { + console.log("Connection closed cleanly"); + } else { + console.error("Connection died"); + } +}; +socket.onerror = (event) => console.error("Connection error:", event); From 19c42a8049064db041fdf356441855326ff62ccd Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 6 Jun 2020 11:17:15 -0600 Subject: [PATCH 013/388] Successfully receive websocket data on frontend --- backend/src/api.ts | 3 ++- backend/src/server.ts | 38 +++++++++++++++++++++++++------------ frontend/src/app.ts | 6 ++++-- scripts/docker-install.bash | 14 +++++++++++++- 4 files changed, 45 insertions(+), 16 deletions(-) diff --git a/backend/src/api.ts b/backend/src/api.ts index 54dfadc..4aca096 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -1,5 +1,6 @@ import * as pty from "node-pty"; import { IPty } from "node-pty"; +import * as WebSocket from "ws"; import { LangConfig, langs } from "./langs"; @@ -8,7 +9,7 @@ export class Session { term: IPty; ws: WebSocket; - constructor(ws, lang) { + constructor(ws: WebSocket, lang: string) { this.ws = ws; this.config = langs[lang]; this.term = null; diff --git a/backend/src/server.ts b/backend/src/server.ts index 6ddee1b..dd191db 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -1,5 +1,6 @@ import * as appRoot from "app-root-path"; import * as express from "express"; +import { Request } from "express"; import * as ws from "express-ws"; import * as sslRedirect from "heroku-ssl-redirect"; @@ -10,6 +11,14 @@ const app = ws(express()).app; const host = process.env.HOST || "localhost"; const port = parseInt(process.env.PORT) || 6119; +app.set("query parser", (qs: string) => new URLSearchParams(qs)); + +function getQueryParams(req: Request): URLSearchParams { + // This is safe because we set the query parser for Express to + // return URLSearchParams objects. + return (req.query as unknown) as URLSearchParams; +} + app.use(sslRedirect()); app.get("/", (_, res) => { res.sendFile(appRoot.path + "/frontend/pages/index.html"); @@ -23,19 +32,24 @@ app.get("/:lang", (req, res) => { }); app.use("/css", express.static(appRoot.path + "/frontend/styles")); app.use("/js", express.static(appRoot.path + "/frontend/out")); -app.use("/api/v1/ws", (req, res, next) => { - if (!req.query.lang) { - res.status(400); - res.send("No language specified"); - } else if (!langs[req.query.lang as string]) { - res.status(400); - res.send(`No such language: ${req.query.lang}`); - } else { - return next(); - } -}); app.ws("/api/v1/ws", (ws, req) => { - new api.Session(ws, req.query.lang); + const lang = getQueryParams(req).get("lang"); + if (!lang) { + ws.send( + JSON.stringify({ event: "error", errorMessage: "No language specified" }) + ); + ws.close(); + } else if (!langs[lang]) { + ws.send( + JSON.stringify({ + event: "error", + errorMessage: `No such language: ${lang}`, + }) + ); + ws.close(); + } else { + new api.Session(ws, getQueryParams(req).get("lang")); + } }); app.listen(port, host, () => diff --git a/frontend/src/app.ts b/frontend/src/app.ts index 456c261..9d82e20 100644 --- a/frontend/src/app.ts +++ b/frontend/src/app.ts @@ -3,6 +3,8 @@ import { FitAddon } from "xterm-addon-fit"; import "xterm/css/xterm.css"; +const lang = document.location.pathname.slice(1); + const term = new Terminal(); const fitAddon = new FitAddon(); term.loadAddon(fitAddon); @@ -14,11 +16,11 @@ window.addEventListener("resize", () => fitAddon.fit()); const socket = new WebSocket( (document.location.protocol === "http:" ? "ws://" : "wss://") + document.location.host + - "/api/v1/ws" + `/api/v1/ws?lang=${lang}` ); socket.onopen = () => console.log("Successfully connected to server"); -socket.onmessage = (event) => console.log(event); +socket.onmessage = (event) => console.log(JSON.parse(event.data)); socket.onclose = (event) => { if (event.wasClean) { console.log("Connection closed cleanly"); diff --git a/scripts/docker-install.bash b/scripts/docker-install.bash index 1391aba..7f6ffcb 100755 --- a/scripts/docker-install.bash +++ b/scripts/docker-install.bash @@ -10,6 +10,17 @@ fi uid="$1" +export DEBIAN_FRONTEND=noninteractive +apt-get update +apt-get install -y curl gnupg +rm -rf /var/lib/apt/lists/* + +curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - + +tee -a /etc/apt/sources.list.d/yarn.list >/dev/null <<"EOF" +deb https://dl.yarnpkg.com/debian/ stable main +EOF + packages=" # Handy utilities @@ -20,6 +31,7 @@ git make nano sudo +tmux vim wget @@ -32,7 +44,7 @@ ghc # Node.js nodejs -npm +yarn # Python python3 From aa57cc7e742762c1b35d670120ed463d2986b4a4 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 6 Jun 2020 12:27:19 -0600 Subject: [PATCH 014/388] Fifth Circle of Webpack --- frontend/src/app.ts | 30 +++++++++++++++++++++++++----- package.json | 1 + tsconfig-webpack.json | 8 ++++++++ webpack.config.js | 8 ++++++++ yarn.lock | 31 +++++++++++++++++++++++++------ 5 files changed, 67 insertions(+), 11 deletions(-) create mode 100644 tsconfig-webpack.json diff --git a/frontend/src/app.ts b/frontend/src/app.ts index 9d82e20..6069d5b 100644 --- a/frontend/src/app.ts +++ b/frontend/src/app.ts @@ -19,13 +19,33 @@ const socket = new WebSocket( `/api/v1/ws?lang=${lang}` ); -socket.onopen = () => console.log("Successfully connected to server"); -socket.onmessage = (event) => console.log(JSON.parse(event.data)); -socket.onclose = (event) => { +socket.addEventListener("open", () => + console.log("Successfully connected to server") +); +socket.addEventListener("message", (event) => { + let message: any; + try { + message = JSON.parse(event.data); + } catch (err) { + console.error("Malformed message from server:", event.data); + return; + } + switch (message?.event) { + case "terminalOutput": + console.log(message.output); + break; + default: + console.error("Unexpected message from server:", message); + break; + } +}); +socket.addEventListener("close", (event) => { if (event.wasClean) { console.log("Connection closed cleanly"); } else { console.error("Connection died"); } -}; -socket.onerror = (event) => console.error("Connection error:", event); +}); +socket.addEventListener("onerror", (event) => + console.error("Connection error:", event) +); diff --git a/package.json b/package.json index 5662796..ed09a6d 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "heroku-ssl-redirect": "^0.0.4", "node-pty": "^0.9.0", "style-loader": "^1.2.1", + "ts-loader": "^7.0.5", "typescript": "^3.9.5", "webpack": "^4.43.0", "webpack-cli": "^3.3.11", diff --git a/tsconfig-webpack.json b/tsconfig-webpack.json new file mode 100644 index 0000000..358bebf --- /dev/null +++ b/tsconfig-webpack.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "outDir": "./frontend/out", + "rootDir": "./frontend/src" + }, + "extends": "./tsconfig.json", + "include": ["frontend/src"] +} diff --git a/webpack.config.js b/webpack.config.js index b26ce12..6678260 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -9,6 +9,14 @@ module.exports = { test: /\.css$/i, use: ["style-loader", "css-loader"], }, + { + test: /\.tsx?$/i, + loader: "ts-loader", + options: { + configFile: "tsconfig-webpack.json", + }, + exclude: /node_modules/, + }, ], }, output: { diff --git a/yarn.lock b/yarn.lock index ad43c5d..c66dcc9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -478,7 +478,7 @@ braces@^2.3.1, braces@^2.3.2: split-string "^3.0.2" to-regex "^3.0.1" -braces@~3.0.2: +braces@^3.0.1, braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== @@ -621,7 +621,7 @@ camelcase@^5.0.0, camelcase@^5.3.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -chalk@2.4.2, chalk@^2.4.2: +chalk@2.4.2, chalk@^2.3.0, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -1035,7 +1035,7 @@ enhanced-resolve@4.1.0: memory-fs "^0.4.0" tapable "^1.0.0" -enhanced-resolve@^4.1.0: +enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz#2937e2b8066cd0fe7ce0990a98f0d71a35189f66" integrity sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA== @@ -1848,7 +1848,7 @@ loader-utils@1.2.3: emojis-list "^2.0.0" json5 "^1.0.1" -loader-utils@^1.2.3: +loader-utils@^1.0.2, loader-utils@^1.2.3: version "1.4.0" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== @@ -1976,6 +1976,14 @@ micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: snapdragon "^0.8.1" to-regex "^3.0.2" +micromatch@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" + integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== + dependencies: + braces "^3.0.1" + picomatch "^2.0.5" + miller-rabin@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" @@ -2345,7 +2353,7 @@ pbkdf2@^3.0.3: safe-buffer "^5.0.1" sha.js "^2.4.8" -picomatch@^2.0.4, picomatch@^2.2.1: +picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== @@ -2716,7 +2724,7 @@ semver@^5.5.0, semver@^5.6.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@^6.3.0: +semver@^6.0.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== @@ -3078,6 +3086,17 @@ toidentifier@1.0.0: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== +ts-loader@^7.0.5: + version "7.0.5" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-7.0.5.tgz#789338fb01cb5dc0a33c54e50558b34a73c9c4c5" + integrity sha512-zXypEIT6k3oTc+OZNx/cqElrsbBtYqDknf48OZos0NQ3RTt045fBIU8RRSu+suObBzYB355aIPGOe/3kj9h7Ig== + dependencies: + chalk "^2.3.0" + enhanced-resolve "^4.0.0" + loader-utils "^1.0.2" + micromatch "^4.0.0" + semver "^6.0.0" + tslib@^1.9.0: version "1.13.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" From 660203f5986743d0c37aebacbe0830c69f7d1c85 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 6 Jun 2020 12:34:26 -0600 Subject: [PATCH 015/388] Write websocket data to terminal --- frontend/src/app.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/frontend/src/app.ts b/frontend/src/app.ts index 6069d5b..33898ef 100644 --- a/frontend/src/app.ts +++ b/frontend/src/app.ts @@ -32,11 +32,15 @@ socket.addEventListener("message", (event) => { } switch (message?.event) { case "terminalOutput": - console.log(message.output); - break; + if (typeof message.output !== "string") { + console.error("Unexpected message from server:", message); + return; + } + term.write(message.output); + return; default: console.error("Unexpected message from server:", message); - break; + return; } }); socket.addEventListener("close", (event) => { From 7df0eea51d1785a00c85e5a3d9749a74ed2df273 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 6 Jun 2020 13:00:43 -0600 Subject: [PATCH 016/388] Oh godddddddd --- webpack.config.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/webpack.config.js b/webpack.config.js index 6678260..3dc3436 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,8 +1,13 @@ const path = require("path"); +const webpack = require("webpack"); -module.exports = { +function isProduction(argv) { + return !argv.development; +} + +module.exports = (_, argv) => ({ entry: "./frontend/src/app.ts", - mode: process.env.NODE_ENV || "production", + mode: isProduction(argv) ? "production" : "development", module: { rules: [ { @@ -26,4 +31,4 @@ module.exports = { performance: { hints: false, }, -}; +}); From 250509ffe14541fda5bf6988db4d3c46392ebe81 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 6 Jun 2020 13:52:27 -0600 Subject: [PATCH 017/388] Fully interactive terminal! --- backend/src/api.ts | 11 ++++++----- frontend/src/app.ts | 4 ++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/backend/src/api.ts b/backend/src/api.ts index 4aca096..e521b6d 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -16,9 +16,10 @@ export class Session { this.run(); ws.on("message", this.handleClientMessage); } - handleClientMessage(msg) { + handleClientMessage = (event: string) => { + let msg: any; try { - msg = JSON.parse(msg); + msg = JSON.parse(event); } catch (err) { console.error(`failed to parse client message: ${msg}`); return; @@ -37,8 +38,8 @@ export class Session { console.error(`unknown client message type: ${msg.event}`); break; } - } - run() { + }; + run = () => { const cmdline = this.config.cmdline; if (this.term) { this.term.kill(); @@ -51,5 +52,5 @@ export class Session { this.term.on("data", (data) => this.ws.send(JSON.stringify({ event: "terminalOutput", output: data })) ); - } + }; } diff --git a/frontend/src/app.ts b/frontend/src/app.ts index 33898ef..f95f6db 100644 --- a/frontend/src/app.ts +++ b/frontend/src/app.ts @@ -53,3 +53,7 @@ socket.addEventListener("close", (event) => { socket.addEventListener("onerror", (event) => console.error("Connection error:", event) ); + +term.onData((data) => + socket.send(JSON.stringify({ event: "terminalInput", input: data })) +); From 22ea7a3e750885720e4519234338c691cb10210b Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 6 Jun 2020 14:16:22 -0600 Subject: [PATCH 018/388] Add support for 12 new languages --- backend/src/langs.ts | 48 +++++++++++++++++++++++++++++++++++++ scripts/docker-install.bash | 47 ++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 2ee1631..bc3329a 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -4,6 +4,10 @@ export interface LangConfig { } export const langs = { + bash: { + cmdline: ["bash"], + name: "Bash", + }, c: { cmdline: ["echo", "not implemented"], name: "C", @@ -12,10 +16,38 @@ export const langs = { cmdline: ["echo", "not implemented"], name: "C++", }, + clojure: { + cmdline: ["clojure"], + name: "Clojure", + }, + emacs: { + cmdline: ["emacs"], + name: "Emacs Lisp", + }, + fish: { + cmdline: ["env", "SHELL=/usr/bin/fish", "fish"], + name: "Fish", + }, + go: { + cmdline: ["echo", "not implemented"], + name: "Go", + }, haskell: { cmdline: ["ghci"], name: "Haskell", }, + java: { + cmdline: ["echo", "not implemented"], + name: "Java", + }, + julia: { + cmdline: ["julia"], + name: "Julia", + }, + lua: { + cmdline: ["lua"], + name: "Lua", + }, nodejs: { cmdline: ["node"], name: "Node.js", @@ -24,4 +56,20 @@ export const langs = { cmdline: ["python3"], name: "Python", }, + ruby: { + cmdline: ["irb"], + name: "Ruby", + }, + rust: { + cmdline: ["echo", "not implemented"], + name: "Rust", + }, + vim: { + cmdline: ["vim"], + name: "Vimscript", + }, + zsh: { + cmdline: ["env", "SHELL=/usr/bin/zsh", "zsh"], + name: "Zsh", + }, }; diff --git a/scripts/docker-install.bash b/scripts/docker-install.bash index 7f6ffcb..96810f8 100755 --- a/scripts/docker-install.bash +++ b/scripts/docker-install.bash @@ -23,25 +23,57 @@ EOF packages=" +# Needed for project infrastructure +bash +git +make +nodejs +yarn + # Handy utilities bsdmainutils curl emacs-nox git make +man-db nano sudo tmux vim wget +# Bash +bash + # C/C++ clang +# Clojure +clojure + +# Emacs Lisp +emacs-nox + +# Fish +fish + +# Go +golang + # Haskell cabal-install ghc +# Java +default-jdk + +# Julia +julia + +# Lua +lua5.3 + # Node.js nodejs yarn @@ -51,6 +83,18 @@ python3 python3-pip python3-venv +# Ruby +ruby + +# Rust +rustc + +# Vimscript +vim + +# Zsh +zsh + " export DEBIAN_FRONTEND=noninteractive @@ -70,4 +114,7 @@ else ln -s /root /home/docker fi +touch /home/docker/.zshrc +chown docker:docker /home/docker/.zshrc + rm "$0" From c66cf63f3dadf392e3e4ad5b738747a50d1c3766 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 6 Jun 2020 14:54:07 -0600 Subject: [PATCH 019/388] Embed Monaco editor on frontend --- frontend/pages/app.html | 3 +- frontend/src/app.ts | 3 ++ frontend/styles/app.css | 9 ++-- package.json | 3 ++ webpack.config.js | 4 ++ yarn.lock | 114 +++++++++++++++++++++++++++++++++++++++- 6 files changed, 130 insertions(+), 6 deletions(-) diff --git a/frontend/pages/app.html b/frontend/pages/app.html index 31e1e0c..70890e7 100644 --- a/frontend/pages/app.html +++ b/frontend/pages/app.html @@ -7,6 +7,7 @@ -
+
+
diff --git a/frontend/src/app.ts b/frontend/src/app.ts index f95f6db..d45b689 100644 --- a/frontend/src/app.ts +++ b/frontend/src/app.ts @@ -1,3 +1,4 @@ +import * as monaco from "monaco-editor"; import { Terminal } from "xterm"; import { FitAddon } from "xterm-addon-fit"; @@ -57,3 +58,5 @@ socket.addEventListener("onerror", (event) => term.onData((data) => socket.send(JSON.stringify({ event: "terminalInput", input: data })) ); + +monaco.editor.create(document.getElementById("editor")); diff --git a/frontend/styles/app.css b/frontend/styles/app.css index dc2f5e8..ac4e3d7 100644 --- a/frontend/styles/app.css +++ b/frontend/styles/app.css @@ -1,7 +1,10 @@ body { margin: 0; -} - -#terminal { height: 100vh; } + +.column { + width: 50%; + height: 100%; + float: left; +} diff --git a/package.json b/package.json index ed09a6d..aa21f70 100644 --- a/package.json +++ b/package.json @@ -11,10 +11,13 @@ "css-loader": "^3.5.3", "express": "^4.17.1", "express-ws": "^4.0.0", + "file-loader": "^6.0.0", "heroku-ssl-redirect": "^0.0.4", + "monaco-editor": "^0.20.0", "node-pty": "^0.9.0", "style-loader": "^1.2.1", "ts-loader": "^7.0.5", + "ttf-loader": "^1.0.2", "typescript": "^3.9.5", "webpack": "^4.43.0", "webpack-cli": "^3.3.11", diff --git a/webpack.config.js b/webpack.config.js index 3dc3436..1f47039 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -22,6 +22,10 @@ module.exports = (_, argv) => ({ }, exclude: /node_modules/, }, + { + test: /\.ttf$/, + use: ["file-loader"], + }, ], }, output: { diff --git a/yarn.lock b/yarn.lock index c66dcc9..76eeb4e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -316,6 +316,13 @@ aproba@^1.1.1: resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== +argparse@^1.0.6: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" @@ -378,6 +385,14 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== +babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" @@ -802,6 +817,11 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= +core-js@^2.4.0: + version "2.6.11" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c" + integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg== + core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -1219,6 +1239,14 @@ figgy-pudding@^3.5.1: resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== +file-loader@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.0.0.tgz#97bbfaab7a2460c07bcbd72d3a6922407f67649f" + integrity sha512-/aMOAYEFXDdjG0wytpTL5YQLfZnnTmLNjn+AIrJ/6HVnTfDqLsVKUUwkDf4I4kgex36BvjuXEn/TX9B/1ESyqQ== + dependencies: + loader-utils "^2.0.0" + schema-utils "^2.6.5" + file-uri-to-path@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" @@ -1723,6 +1751,11 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-in-browser@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-in-browser/-/is-in-browser-1.1.3.tgz#56ff4db683a078c6082eb95dad7dc62e1d04f835" + integrity sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU= + is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" @@ -1779,6 +1812,11 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= +"js-tokens@^3.0.0 || ^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + json-parse-better-errors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" @@ -1803,6 +1841,15 @@ json5@^2.1.2: dependencies: minimist "^1.2.5" +jss@^9.5.1: + version "9.8.7" + resolved "https://registry.yarnpkg.com/jss/-/jss-9.8.7.tgz#ed9763fc0f2f0260fc8260dac657af61e622ce05" + integrity sha512-awj3XRZYxbrmmrx9LUSj5pXSUfm12m8xzi/VKeqI1ZwWBtQ0kVPTs3vYs32t4rFw83CgFDukA8wKzOE9sMQnoQ== + dependencies: + is-in-browser "^1.1.3" + symbol-observable "^1.1.0" + warning "^3.0.0" + kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -1874,6 +1921,13 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" +loose-envify@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -1957,6 +2011,11 @@ methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= +microbuffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/microbuffer/-/microbuffer-1.0.0.tgz#8b3832ed40c87d51f47bb234913a698a756d19d2" + integrity sha1-izgy7UDIfVH0e7I0kTppinVtGdI= + micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" @@ -2067,6 +2126,11 @@ mkdirp@^0.5.1, mkdirp@^0.5.3: dependencies: minimist "^1.2.5" +monaco-editor@^0.20.0: + version "0.20.0" + resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.20.0.tgz#5d5009343a550124426cb4d965a4d27a348b4dea" + integrity sha512-hkvf4EtPJRMQlPC3UbMoRs0vTAFAYdzFQ+gpMb8A+9znae1c43q8Mab9iVsgTcg/4PNiLGGn3SlDIa8uvK1FIQ== + move-concurrently@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" @@ -2271,7 +2335,7 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== -pako@~1.0.5: +pako@^1.0.0, pako@~1.0.5: version "1.0.11" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== @@ -2594,6 +2658,11 @@ readdirp@~3.4.0: dependencies: picomatch "^2.2.1" +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== + regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" @@ -2710,7 +2779,7 @@ schema-utils@^1.0.0: ajv-errors "^1.0.0" ajv-keywords "^3.1.0" -schema-utils@^2.6.6: +schema-utils@^2.6.5, schema-utils@^2.6.6: version "2.7.0" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7" integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== @@ -2891,6 +2960,11 @@ split-string@^3.0.1, split-string@^3.0.2: dependencies: extend-shallow "^3.0.0" +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + ssri@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" @@ -3000,6 +3074,11 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" +symbol-observable@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== + tapable@^1.0.0, tapable@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" @@ -3102,6 +3181,25 @@ tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== +ttf-loader@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/ttf-loader/-/ttf-loader-1.0.2.tgz#ac1d5824ac9ff2fe3daaa9836170072e1fb6f6f2" + integrity sha512-IMlcqjkSxqfOD4UpPrJ+LGm98JQ5URDFami19mR7lfjNR1XAEoG93Xd3loGYUMSxuhfzSTxsnLXu8emIawx/6A== + dependencies: + babel-runtime "^6.26.0" + jss "^9.5.1" + ttf2woff "^2.0.1" + uuid "^3.2.1" + +ttf2woff@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ttf2woff/-/ttf2woff-2.0.2.tgz#09a7cee59abd3c15282b57ed84ac7c7770749f1f" + integrity sha512-X68badwBjAy/+itU49scLjXUL094up+rHuYk+YAOTTBYSUMOmLZ7VyhZJuqQESj1gnyLAC2/5V8Euv+mExmyPA== + dependencies: + argparse "^1.0.6" + microbuffer "^1.0.0" + pako "^1.0.0" + tty-browserify@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" @@ -3221,6 +3319,11 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= +uuid@^3.2.1: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + v8-compile-cache@2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe" @@ -3236,6 +3339,13 @@ vm-browserify@^1.0.1: resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== +warning@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/warning/-/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c" + integrity sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w= + dependencies: + loose-envify "^1.0.0" + watchpack-chokidar2@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz#9948a1866cbbd6cb824dea13a7ed691f6c8ddff0" From 27ab1f7b6ad9066b47807f7bd0381187874609bb Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 6 Jun 2020 15:01:53 -0600 Subject: [PATCH 020/388] Add "run" button --- frontend/pages/app.html | 15 +++++++++++++-- frontend/styles/app.css | 14 ++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/frontend/pages/app.html b/frontend/pages/app.html index 70890e7..0ea4b89 100644 --- a/frontend/pages/app.html +++ b/frontend/pages/app.html @@ -3,11 +3,22 @@ Fast Sandbox + -
-
+ +
+
+
+
diff --git a/frontend/styles/app.css b/frontend/styles/app.css index ac4e3d7..ea93b76 100644 --- a/frontend/styles/app.css +++ b/frontend/styles/app.css @@ -3,6 +3,20 @@ body { height: 100vh; } +#header { + height: 50px; + padding: 5px; +} + +#runButton { + position: absolute; + left: 50%; +} + +#app { + height: calc(100% - 50px); +} + .column { width: 50%; height: 100%; From 10c868fbd31a3b1459143e09f2c934bf51661891 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 6 Jun 2020 15:23:21 -0600 Subject: [PATCH 021/388] Per-language syntax highlighting --- backend/src/api.ts | 6 ++++++ backend/src/langs.ts | 18 ++++++++++++++++++ frontend/src/app.ts | 14 +++++++++++++- webpack.config.js | 1 + 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/backend/src/api.ts b/backend/src/api.ts index e521b6d..00aa8ae 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -13,6 +13,12 @@ export class Session { this.ws = ws; this.config = langs[lang]; this.term = null; + this.ws.send( + JSON.stringify({ + event: "setMonacoLanguage", + monacoLanguage: this.config.monacoLang, + }) + ); this.run(); ws.on("message", this.handleClientMessage); } diff --git a/backend/src/langs.ts b/backend/src/langs.ts index bc3329a..a364d54 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1,5 +1,6 @@ export interface LangConfig { cmdline: string[]; + monacoLang: string; name: string; } @@ -7,69 +8,86 @@ export const langs = { bash: { cmdline: ["bash"], name: "Bash", + monacoLang: "shell", }, c: { cmdline: ["echo", "not implemented"], name: "C", + monacoLang: "c", }, "c++": { cmdline: ["echo", "not implemented"], name: "C++", + monacoLang: "cpp", }, clojure: { cmdline: ["clojure"], name: "Clojure", + monacoLang: "clojure", }, emacs: { cmdline: ["emacs"], name: "Emacs Lisp", + monacoLang: "plaintext", }, fish: { cmdline: ["env", "SHELL=/usr/bin/fish", "fish"], name: "Fish", + monacoLang: "plaintext", }, go: { cmdline: ["echo", "not implemented"], name: "Go", + monacoLang: "go", }, haskell: { cmdline: ["ghci"], name: "Haskell", + monacoLang: "plaintext", }, java: { cmdline: ["echo", "not implemented"], name: "Java", + monacoLang: "java", }, julia: { cmdline: ["julia"], name: "Julia", + monacoLang: "plaintext", }, lua: { cmdline: ["lua"], name: "Lua", + monacoLang: "lua", }, nodejs: { cmdline: ["node"], name: "Node.js", + monacoLang: "javascript", }, python: { cmdline: ["python3"], name: "Python", + monacoLang: "python", }, ruby: { cmdline: ["irb"], name: "Ruby", + monacoLang: "ruby", }, rust: { cmdline: ["echo", "not implemented"], name: "Rust", + monacoLang: "rust", }, vim: { cmdline: ["vim"], name: "Vimscript", + monacoLang: "plaintext", }, zsh: { cmdline: ["env", "SHELL=/usr/bin/zsh", "zsh"], name: "Zsh", + monacoLang: "shell", }, }; diff --git a/frontend/src/app.ts b/frontend/src/app.ts index d45b689..0fc0f12 100644 --- a/frontend/src/app.ts +++ b/frontend/src/app.ts @@ -39,6 +39,13 @@ socket.addEventListener("message", (event) => { } term.write(message.output); return; + case "setMonacoLanguage": + if (typeof message.monacoLanguage !== "string") { + console.error("Unexpected message from server:", message); + return; + } + monaco.editor.setModelLanguage(editor.getModel(), message.monacoLanguage); + return; default: console.error("Unexpected message from server:", message); return; @@ -59,4 +66,9 @@ term.onData((data) => socket.send(JSON.stringify({ event: "terminalInput", input: data })) ); -monaco.editor.create(document.getElementById("editor")); +const editor = monaco.editor.create(document.getElementById("editor")); +window.addEventListener("resize", () => editor.layout()); + +document.getElementById("runButton").addEventListener("click", () => { + socket.send(JSON.stringify({ event: "runCode", code: editor.getValue() })); +}); diff --git a/webpack.config.js b/webpack.config.js index 1f47039..4f0d4c1 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -30,6 +30,7 @@ module.exports = (_, argv) => ({ }, output: { path: path.resolve(__dirname, "frontend/out"), + publicPath: "/js/", filename: "app.js", }, performance: { From f4178588b73e9798dfd79165d22072f0f64bd881 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 6 Jun 2020 15:47:12 -0600 Subject: [PATCH 022/388] You can run Python code now --- backend/src/api.ts | 48 ++++++++++++++++-- backend/src/langs.ts | 35 +++++++------ frontend/src/app.ts | 3 ++ package.json | 3 +- yarn.lock | 118 ++++++++----------------------------------- 5 files changed, 85 insertions(+), 122 deletions(-) diff --git a/backend/src/api.ts b/backend/src/api.ts index 00aa8ae..c4e4baf 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -1,10 +1,14 @@ +import * as fs from "fs"; import * as pty from "node-pty"; import { IPty } from "node-pty"; +import * as path from "path"; +import * as tmp from "tmp"; import * as WebSocket from "ws"; import { LangConfig, langs } from "./langs"; export class Session { + code: string; config: LangConfig; term: IPty; ws: WebSocket; @@ -13,13 +17,14 @@ export class Session { this.ws = ws; this.config = langs[lang]; this.term = null; + this.code = ""; this.ws.send( JSON.stringify({ event: "setMonacoLanguage", monacoLanguage: this.config.monacoLang, }) ); - this.run(); + this.run().catch(console.error); ws.on("message", this.handleClientMessage); } handleClientMessage = (event: string) => { @@ -30,7 +35,7 @@ export class Session { console.error(`failed to parse client message: ${msg}`); return; } - switch (msg.event) { + switch (msg?.event) { case "terminalInput": if (!this.term) { console.error(`terminalInput: no terminal`); @@ -40,19 +45,52 @@ export class Session { this.term.write(msg.input); } break; + case "runCode": + if (typeof msg.code !== "string") { + console.error(`runCode: missing or malformed code field`); + } else { + this.code = msg.code; + this.run(); + } + break; default: console.error(`unknown client message type: ${msg.event}`); break; } }; - run = () => { - const cmdline = this.config.cmdline; + run = async () => { + const { repl, file, run } = this.config; if (this.term) { this.term.kill(); } + this.ws.send(JSON.stringify({ event: "terminalClear" })); + const tmpdir: string = await new Promise((resolve, reject) => + tmp.dir({ unsafeCleanup: true }, (err, path) => { + if (err) { + reject(err); + } else { + resolve(path); + } + }) + ); + let cmdline: string[]; + if (this.code || !repl) { + await new Promise((resolve, reject) => + fs.writeFile(path.resolve(tmpdir, file), this.code, (err) => { + if (err) { + reject(err); + } else { + resolve(); + } + }) + ); + cmdline = run; + } else { + cmdline = repl; + } this.term = pty.spawn(cmdline[0], cmdline.slice(1), { name: "xterm-color", - cwd: process.env.PWD, + cwd: tmpdir, env: process.env, }); this.term.on("data", (data) => diff --git a/backend/src/langs.ts b/backend/src/langs.ts index a364d54..812ae57 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1,92 +1,91 @@ export interface LangConfig { - cmdline: string[]; + repl?: string[]; + file?: string; + run?: string[]; monacoLang: string; name: string; } export const langs = { bash: { - cmdline: ["bash"], + repl: ["bash"], name: "Bash", monacoLang: "shell", }, c: { - cmdline: ["echo", "not implemented"], name: "C", monacoLang: "c", }, "c++": { - cmdline: ["echo", "not implemented"], name: "C++", monacoLang: "cpp", }, clojure: { - cmdline: ["clojure"], + repl: ["clojure"], name: "Clojure", monacoLang: "clojure", }, emacs: { - cmdline: ["emacs"], + repl: ["emacs"], name: "Emacs Lisp", monacoLang: "plaintext", }, fish: { - cmdline: ["env", "SHELL=/usr/bin/fish", "fish"], + repl: ["env", "SHELL=/usr/bin/fish", "fish"], name: "Fish", monacoLang: "plaintext", }, go: { - cmdline: ["echo", "not implemented"], name: "Go", monacoLang: "go", }, haskell: { - cmdline: ["ghci"], + repl: ["ghci"], name: "Haskell", monacoLang: "plaintext", }, java: { - cmdline: ["echo", "not implemented"], name: "Java", monacoLang: "java", }, julia: { - cmdline: ["julia"], + repl: ["julia"], name: "Julia", monacoLang: "plaintext", }, lua: { - cmdline: ["lua"], + repl: ["lua"], name: "Lua", monacoLang: "lua", }, nodejs: { - cmdline: ["node"], + repl: ["node"], name: "Node.js", monacoLang: "javascript", }, python: { - cmdline: ["python3"], + repl: ["python3", "-u"], + file: "main.py", + run: ["python3", "-u", "-i", "main.py"], name: "Python", monacoLang: "python", }, ruby: { - cmdline: ["irb"], + repl: ["irb"], name: "Ruby", monacoLang: "ruby", }, rust: { - cmdline: ["echo", "not implemented"], name: "Rust", monacoLang: "rust", }, vim: { - cmdline: ["vim"], + repl: ["vim"], name: "Vimscript", monacoLang: "plaintext", }, zsh: { - cmdline: ["env", "SHELL=/usr/bin/zsh", "zsh"], + repl: ["env", "SHELL=/usr/bin/zsh", "zsh"], name: "Zsh", monacoLang: "shell", }, diff --git a/frontend/src/app.ts b/frontend/src/app.ts index 0fc0f12..db206e3 100644 --- a/frontend/src/app.ts +++ b/frontend/src/app.ts @@ -32,6 +32,9 @@ socket.addEventListener("message", (event) => { return; } switch (message?.event) { + case "terminalClear": + term.reset(); + return; case "terminalOutput": if (typeof message.output !== "string") { console.error("Unexpected message from server:", message); diff --git a/package.json b/package.json index aa21f70..44516e6 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "@types/app-root-path": "^1.2.4", "@types/express": "^4.17.6", "@types/express-ws": "^3.0.0", + "@types/tmp": "^0.2.0", "app-root-path": "^3.0.0", "css-loader": "^3.5.3", "express": "^4.17.1", @@ -16,8 +17,8 @@ "monaco-editor": "^0.20.0", "node-pty": "^0.9.0", "style-loader": "^1.2.1", + "tmp": "^0.2.1", "ts-loader": "^7.0.5", - "ttf-loader": "^1.0.2", "typescript": "^3.9.5", "webpack": "^4.43.0", "webpack-cli": "^3.3.11", diff --git a/yarn.lock b/yarn.lock index 76eeb4e..1759012 100644 --- a/yarn.lock +++ b/yarn.lock @@ -83,6 +83,11 @@ "@types/express-serve-static-core" "*" "@types/mime" "*" +"@types/tmp@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@types/tmp/-/tmp-0.2.0.tgz#e3f52b4d7397eaa9193592ef3fdd44dc0af4298c" + integrity sha512-flgpHJjntpBAdJD43ShRosQvNC0ME97DCfGvZEDlAThQmnerRXrLbX6YgzRBQCZTthET9eAWFAMaYP0m0Y4HzQ== + "@types/ws@*": version "7.2.5" resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.2.5.tgz#513f28b04a1ea1aa9dc2cad3f26e8e37c88aae49" @@ -316,13 +321,6 @@ aproba@^1.1.1: resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== -argparse@^1.0.6: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" @@ -385,14 +383,6 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -babel-runtime@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" - integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.11.0" - balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" @@ -817,11 +807,6 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= -core-js@^2.4.0: - version "2.6.11" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c" - integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg== - core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -1751,11 +1736,6 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" -is-in-browser@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/is-in-browser/-/is-in-browser-1.1.3.tgz#56ff4db683a078c6082eb95dad7dc62e1d04f835" - integrity sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU= - is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" @@ -1812,11 +1792,6 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= -"js-tokens@^3.0.0 || ^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - json-parse-better-errors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" @@ -1841,15 +1816,6 @@ json5@^2.1.2: dependencies: minimist "^1.2.5" -jss@^9.5.1: - version "9.8.7" - resolved "https://registry.yarnpkg.com/jss/-/jss-9.8.7.tgz#ed9763fc0f2f0260fc8260dac657af61e622ce05" - integrity sha512-awj3XRZYxbrmmrx9LUSj5pXSUfm12m8xzi/VKeqI1ZwWBtQ0kVPTs3vYs32t4rFw83CgFDukA8wKzOE9sMQnoQ== - dependencies: - is-in-browser "^1.1.3" - symbol-observable "^1.1.0" - warning "^3.0.0" - kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -1921,13 +1887,6 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" -loose-envify@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -2011,11 +1970,6 @@ methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= -microbuffer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/microbuffer/-/microbuffer-1.0.0.tgz#8b3832ed40c87d51f47bb234913a698a756d19d2" - integrity sha1-izgy7UDIfVH0e7I0kTppinVtGdI= - micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" @@ -2335,7 +2289,7 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== -pako@^1.0.0, pako@~1.0.5: +pako@~1.0.5: version "1.0.11" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== @@ -2658,11 +2612,6 @@ readdirp@~3.4.0: dependencies: picomatch "^2.2.1" -regenerator-runtime@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" - integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== - regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" @@ -2733,6 +2682,13 @@ rimraf@^2.5.4, rimraf@^2.6.3: dependencies: glob "^7.1.3" +rimraf@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" @@ -2960,11 +2916,6 @@ split-string@^3.0.1, split-string@^3.0.2: dependencies: extend-shallow "^3.0.0" -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - ssri@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" @@ -3074,11 +3025,6 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" -symbol-observable@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" - integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== - tapable@^1.0.0, tapable@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" @@ -3123,6 +3069,13 @@ timers-browserify@^2.0.4: dependencies: setimmediate "^1.0.4" +tmp@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + to-arraybuffer@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" @@ -3181,25 +3134,6 @@ tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== -ttf-loader@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/ttf-loader/-/ttf-loader-1.0.2.tgz#ac1d5824ac9ff2fe3daaa9836170072e1fb6f6f2" - integrity sha512-IMlcqjkSxqfOD4UpPrJ+LGm98JQ5URDFami19mR7lfjNR1XAEoG93Xd3loGYUMSxuhfzSTxsnLXu8emIawx/6A== - dependencies: - babel-runtime "^6.26.0" - jss "^9.5.1" - ttf2woff "^2.0.1" - uuid "^3.2.1" - -ttf2woff@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/ttf2woff/-/ttf2woff-2.0.2.tgz#09a7cee59abd3c15282b57ed84ac7c7770749f1f" - integrity sha512-X68badwBjAy/+itU49scLjXUL094up+rHuYk+YAOTTBYSUMOmLZ7VyhZJuqQESj1gnyLAC2/5V8Euv+mExmyPA== - dependencies: - argparse "^1.0.6" - microbuffer "^1.0.0" - pako "^1.0.0" - tty-browserify@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" @@ -3319,11 +3253,6 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= -uuid@^3.2.1: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - v8-compile-cache@2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe" @@ -3339,13 +3268,6 @@ vm-browserify@^1.0.1: resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== -warning@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/warning/-/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c" - integrity sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w= - dependencies: - loose-envify "^1.0.0" - watchpack-chokidar2@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz#9948a1866cbbd6cb824dea13a7ed691f6c8ddff0" From d5430812bc117005a4467ecdc6ce4820daf1ca9a Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 7 Jun 2020 15:36:07 -0600 Subject: [PATCH 023/388] You can run many languages now --- backend/src/api.ts | 11 +++++++++-- backend/src/langs.ts | 10 +++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/backend/src/api.ts b/backend/src/api.ts index c4e4baf..a527732 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -58,6 +58,13 @@ export class Session { break; } }; + parseCmdline = (cmdline: string[] | string) => { + if (typeof cmdline === "string") { + return ["bash", "-c", cmdline]; + } else { + return cmdline; + } + }; run = async () => { const { repl, file, run } = this.config; if (this.term) { @@ -84,9 +91,9 @@ export class Session { } }) ); - cmdline = run; + cmdline = this.parseCmdline(run); } else { - cmdline = repl; + cmdline = this.parseCmdline(repl); } this.term = pty.spawn(cmdline[0], cmdline.slice(1), { name: "xterm-color", diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 812ae57..856dc5b 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1,7 +1,7 @@ export interface LangConfig { repl?: string[]; file?: string; - run?: string[]; + run?: string[] | string; monacoLang: string; name: string; } @@ -9,6 +9,8 @@ export interface LangConfig { export const langs = { bash: { repl: ["bash"], + file: "main.bash", + run: ["bash", "--rcfile", "main.bash"], name: "Bash", monacoLang: "shell", }, @@ -41,6 +43,8 @@ export const langs = { }, haskell: { repl: ["ghci"], + file: "Main.hs", + run: ["ghci", "Main.hs"], name: "Haskell", monacoLang: "plaintext", }, @@ -60,6 +64,8 @@ export const langs = { }, nodejs: { repl: ["node"], + file: "main.js", + run: 'node -i -e "$(< main.js)"', name: "Node.js", monacoLang: "javascript", }, @@ -86,6 +92,8 @@ export const langs = { }, zsh: { repl: ["env", "SHELL=/usr/bin/zsh", "zsh"], + file: ".zshrc", + run: ["env", "ZDOTDIR=.", "zsh"], name: "Zsh", monacoLang: "shell", }, From 2239a3685d8929e0b2610361af64fe0f664f26c7 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 7 Jun 2020 16:01:02 -0600 Subject: [PATCH 024/388] Improving layout --- frontend/pages/app.html | 4 +--- frontend/src/app.ts | 5 ++++- frontend/styles/app.css | 10 +++------- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/frontend/pages/app.html b/frontend/pages/app.html index 0ea4b89..12ccfd3 100644 --- a/frontend/pages/app.html +++ b/frontend/pages/app.html @@ -13,12 +13,10 @@ -
+
diff --git a/frontend/src/app.ts b/frontend/src/app.ts index db206e3..b4c693e 100644 --- a/frontend/src/app.ts +++ b/frontend/src/app.ts @@ -69,7 +69,10 @@ term.onData((data) => socket.send(JSON.stringify({ event: "terminalInput", input: data })) ); -const editor = monaco.editor.create(document.getElementById("editor")); +const editor = monaco.editor.create(document.getElementById("editor"), { + minimap: { enabled: false }, + scrollbar: { verticalScrollbarSize: 0 }, +}); window.addEventListener("resize", () => editor.layout()); document.getElementById("runButton").addEventListener("click", () => { diff --git a/frontend/styles/app.css b/frontend/styles/app.css index ea93b76..02430c2 100644 --- a/frontend/styles/app.css +++ b/frontend/styles/app.css @@ -3,18 +3,14 @@ body { height: 100vh; } -#header { - height: 50px; - padding: 5px; -} - #runButton { position: absolute; - left: 50%; + top: 25px; + right: calc(50% + 25px); } #app { - height: calc(100% - 50px); + height: 100%; } .column { From b31e49d40de841ea5f71263b9c475982843a4a81 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 7 Jun 2020 16:04:32 -0600 Subject: [PATCH 025/388] Finish improving layout --- frontend/styles/app.css | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/frontend/styles/app.css b/frontend/styles/app.css index 02430c2..5b320be 100644 --- a/frontend/styles/app.css +++ b/frontend/styles/app.css @@ -3,12 +3,6 @@ body { height: 100vh; } -#runButton { - position: absolute; - top: 25px; - right: calc(50% + 25px); -} - #app { height: 100%; } @@ -18,3 +12,17 @@ body { height: 100%; float: left; } + +#editor { + overflow: hidden; +} + +#terminal { + background: black; +} + +#runButton { + position: absolute; + top: 25px; + right: calc(50% + 25px); +} From 76a1c8fa1d1bf97d93fc84b44b6d5bff6270c7cb Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 7 Jun 2020 16:24:45 -0600 Subject: [PATCH 026/388] Automatic reconnect to server with exp backoff --- frontend/src/app.ts | 109 +++++++++++++++++++++++++------------------- 1 file changed, 63 insertions(+), 46 deletions(-) diff --git a/frontend/src/app.ts b/frontend/src/app.ts index b4c693e..206180b 100644 --- a/frontend/src/app.ts +++ b/frontend/src/app.ts @@ -14,56 +14,73 @@ term.open(document.getElementById("terminal")); fitAddon.fit(); window.addEventListener("resize", () => fitAddon.fit()); -const socket = new WebSocket( - (document.location.protocol === "http:" ? "ws://" : "wss://") + - document.location.host + - `/api/v1/ws?lang=${lang}` -); +const initialRetryDelayMs = 200; +let retryDelayMs = initialRetryDelayMs; -socket.addEventListener("open", () => - console.log("Successfully connected to server") -); -socket.addEventListener("message", (event) => { - let message: any; - try { - message = JSON.parse(event.data); - } catch (err) { - console.error("Malformed message from server:", event.data); - return; - } - switch (message?.event) { - case "terminalClear": - term.reset(); +function tryConnect() { + console.log("Connecting to server..."); + socket = new WebSocket( + (document.location.protocol === "http:" ? "ws://" : "wss://") + + document.location.host + + `/api/v1/ws?lang=${lang}` + ); + socket.addEventListener("open", () => { + retryDelayMs = initialRetryDelayMs; + console.log("Successfully connected to server"); + }); + socket.addEventListener("message", (event: MessageEvent) => { + let message: any; + try { + message = JSON.parse(event.data); + } catch (err) { + console.error("Malformed message from server:", event.data); return; - case "terminalOutput": - if (typeof message.output !== "string") { + } + switch (message?.event) { + case "terminalClear": + term.reset(); + return; + case "terminalOutput": + if (typeof message.output !== "string") { + console.error("Unexpected message from server:", message); + return; + } + term.write(message.output); + return; + case "setMonacoLanguage": + if (typeof message.monacoLanguage !== "string") { + console.error("Unexpected message from server:", message); + return; + } + monaco.editor.setModelLanguage( + editor.getModel(), + message.monacoLanguage + ); + return; + default: console.error("Unexpected message from server:", message); return; - } - term.write(message.output); - return; - case "setMonacoLanguage": - if (typeof message.monacoLanguage !== "string") { - console.error("Unexpected message from server:", message); - return; - } - monaco.editor.setModelLanguage(editor.getModel(), message.monacoLanguage); - return; - default: - console.error("Unexpected message from server:", message); - return; - } -}); -socket.addEventListener("close", (event) => { - if (event.wasClean) { - console.log("Connection closed cleanly"); - } else { - console.error("Connection died"); - } -}); -socket.addEventListener("onerror", (event) => - console.error("Connection error:", event) -); + } + }); + socket.addEventListener("close", (event: CloseEvent) => { + if (event.wasClean) { + console.log("Connection closed cleanly"); + } else { + console.error("Connection died"); + } + scheduleConnect(); + }); +} + +function scheduleConnect() { + const delay = retryDelayMs * Math.random(); + console.log(`Trying to reconnect in ${Math.floor(delay)}ms`); + setTimeout(tryConnect, delay); + retryDelayMs *= 2; +} + +let socket = null; +tryConnect(); term.onData((data) => socket.send(JSON.stringify({ event: "terminalInput", input: data })) From 6784a2bdae3bf7ae076322cbf248a49c93b367af Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 7 Jun 2020 16:45:54 -0600 Subject: [PATCH 027/388] Update Node.js and fix prompt interleaving --- backend/src/api.ts | 8 ++++++-- backend/src/langs.ts | 5 ++++- scripts/docker-install.bash | 7 +++++-- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/backend/src/api.ts b/backend/src/api.ts index a527732..dece1ea 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -66,7 +66,7 @@ export class Session { } }; run = async () => { - const { repl, file, run } = this.config; + const { repl, file, suffix, run } = this.config; if (this.term) { this.term.kill(); } @@ -82,8 +82,12 @@ export class Session { ); let cmdline: string[]; if (this.code || !repl) { + let code = this.code; + if (suffix) { + code += suffix; + } await new Promise((resolve, reject) => - fs.writeFile(path.resolve(tmpdir, file), this.code, (err) => { + fs.writeFile(path.resolve(tmpdir, file), code, (err) => { if (err) { reject(err); } else { diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 856dc5b..3978b15 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1,6 +1,8 @@ export interface LangConfig { repl?: string[]; file?: string; + prefix?: string; + suffix?: string; run?: string[] | string; monacoLang: string; name: string; @@ -65,7 +67,8 @@ export const langs = { nodejs: { repl: ["node"], file: "main.js", - run: 'node -i -e "$(< main.js)"', + suffix: '\n;require("repl").start();', + run: "node main.js", name: "Node.js", monacoLang: "javascript", }, diff --git a/scripts/docker-install.bash b/scripts/docker-install.bash index 96810f8..91b60ba 100755 --- a/scripts/docker-install.bash +++ b/scripts/docker-install.bash @@ -12,13 +12,16 @@ uid="$1" export DEBIAN_FRONTEND=noninteractive apt-get update -apt-get install -y curl gnupg +apt-get install -y curl gnupg lsb-release rm -rf /var/lib/apt/lists/* curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - +curl -sS https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - -tee -a /etc/apt/sources.list.d/yarn.list >/dev/null <<"EOF" +tee -a /etc/apt/sources.list.d/custom.list >/dev/null <<"EOF" +deb https://deb.nodesource.com/node_14.x focal main deb https://dl.yarnpkg.com/debian/ stable main +deb-src https://deb.nodesource.com/node_14.x EOF packages=" From 869816c6ab93772f8722eb637d69d6007af1a039 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 7 Jun 2020 16:51:46 -0600 Subject: [PATCH 028/388] Fix ghci death throes --- backend/src/api.ts | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/backend/src/api.ts b/backend/src/api.ts index dece1ea..b35f03c 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -10,13 +10,13 @@ import { LangConfig, langs } from "./langs"; export class Session { code: string; config: LangConfig; - term: IPty; + term: { pty: IPty; live: boolean }; ws: WebSocket; constructor(ws: WebSocket, lang: string) { this.ws = ws; this.config = langs[lang]; - this.term = null; + this.term = { pty: null, live: false }; this.code = ""; this.ws.send( JSON.stringify({ @@ -42,7 +42,7 @@ export class Session { } else if (typeof msg.input !== "string") { console.error(`terminalInput: missing or malformed input field`); } else { - this.term.write(msg.input); + this.term.pty.write(msg.input); } break; case "runCode": @@ -67,8 +67,9 @@ export class Session { }; run = async () => { const { repl, file, suffix, run } = this.config; - if (this.term) { - this.term.kill(); + if (this.term.pty) { + this.term.pty.kill(); + this.term.live = false; } this.ws.send(JSON.stringify({ event: "terminalClear" })); const tmpdir: string = await new Promise((resolve, reject) => @@ -99,13 +100,21 @@ export class Session { } else { cmdline = this.parseCmdline(repl); } - this.term = pty.spawn(cmdline[0], cmdline.slice(1), { - name: "xterm-color", - cwd: tmpdir, - env: process.env, + const term = { + pty: pty.spawn(cmdline[0], cmdline.slice(1), { + name: "xterm-color", + cwd: tmpdir, + env: process.env, + }), + live: true, + }; + this.term = term; + term.pty.on("data", (data) => { + // Capture term in closure so that we don't keep sending output + // from the old pty even after it's been killed (see ghci). + if (term.live) { + this.ws.send(JSON.stringify({ event: "terminalOutput", output: data })); + } }); - this.term.on("data", (data) => - this.ws.send(JSON.stringify({ event: "terminalOutput", output: data })) - ); }; } From 2b8e0fd217a88ab79b04c950defdfede99360d29 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 7 Jun 2020 17:14:01 -0600 Subject: [PATCH 029/388] Templates, and C works now --- backend/src/api.ts | 34 ++++++++++++------- backend/src/langs.ts | 67 ++++++++++++++++++++++--------------- frontend/src/app.ts | 14 ++++++++ scripts/docker-install.bash | 1 + 4 files changed, 76 insertions(+), 40 deletions(-) diff --git a/backend/src/api.ts b/backend/src/api.ts index b35f03c..9142ce2 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -24,6 +24,14 @@ export class Session { monacoLanguage: this.config.monacoLang, }) ); + if (this.config.template) { + this.ws.send( + JSON.stringify({ + event: "insertTemplate", + template: this.config.template, + }) + ); + } this.run().catch(console.error); ws.on("message", this.handleClientMessage); } @@ -58,15 +66,8 @@ export class Session { break; } }; - parseCmdline = (cmdline: string[] | string) => { - if (typeof cmdline === "string") { - return ["bash", "-c", cmdline]; - } else { - return cmdline; - } - }; run = async () => { - const { repl, file, suffix, run } = this.config; + const { repl, file, suffix, compile, run } = this.config; if (this.term.pty) { this.term.pty.kill(); this.term.live = false; @@ -81,8 +82,10 @@ export class Session { } }) ); - let cmdline: string[]; - if (this.code || !repl) { + let cmdline: string; + if (!run) { + cmdline = `echo 'Support for ${this.config.name} is not yet implemented.`; + } else if (this.code) { let code = this.code; if (suffix) { code += suffix; @@ -96,12 +99,17 @@ export class Session { } }) ); - cmdline = this.parseCmdline(run); + cmdline = run; + if (compile) { + cmdline = compile + " && " + run; + } + } else if (repl) { + cmdline = repl; } else { - cmdline = this.parseCmdline(repl); + return; } const term = { - pty: pty.spawn(cmdline[0], cmdline.slice(1), { + pty: pty.spawn("bash", ["-c", cmdline], { name: "xterm-color", cwd: tmpdir, env: process.env, diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 3978b15..1a34cfb 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1,103 +1,116 @@ export interface LangConfig { - repl?: string[]; + name: string; + monacoLang: string; + repl?: string; file?: string; prefix?: string; suffix?: string; - run?: string[] | string; - monacoLang: string; - name: string; + compile?: string; + run?: string; + template?: string; } -export const langs = { +export const langs: { [key: string]: LangConfig } = { bash: { - repl: ["bash"], - file: "main.bash", - run: ["bash", "--rcfile", "main.bash"], name: "Bash", monacoLang: "shell", + repl: "bash", + file: "main.bash", + run: "bash --rcfile main.bash", + template: 'echo "Hello, world!"', }, c: { name: "C", monacoLang: "c", + file: "main.c", + compile: "clang -Wall -Wextra main.c -o main", + run: "./main", + template: `#include + +int main() { + printf("Hello, world!\\n"); + return 0; +} +`, }, "c++": { name: "C++", monacoLang: "cpp", }, clojure: { - repl: ["clojure"], name: "Clojure", monacoLang: "clojure", + repl: "clojure", }, emacs: { - repl: ["emacs"], name: "Emacs Lisp", monacoLang: "plaintext", + repl: "emacs", }, fish: { - repl: ["env", "SHELL=/usr/bin/fish", "fish"], name: "Fish", monacoLang: "plaintext", + repl: "SHELL=/usr/bin/fish fish", }, go: { name: "Go", monacoLang: "go", }, haskell: { - repl: ["ghci"], - file: "Main.hs", - run: ["ghci", "Main.hs"], name: "Haskell", monacoLang: "plaintext", + repl: "ghci", + file: "Main.hs", + run: "ghci Main.hs", }, java: { name: "Java", monacoLang: "java", }, julia: { - repl: ["julia"], name: "Julia", monacoLang: "plaintext", + repl: "julia", }, lua: { - repl: ["lua"], name: "Lua", monacoLang: "lua", + repl: "lua", }, nodejs: { - repl: ["node"], + name: "Node.js", + monacoLang: "javascript", + repl: "node", file: "main.js", suffix: '\n;require("repl").start();', run: "node main.js", - name: "Node.js", - monacoLang: "javascript", }, python: { - repl: ["python3", "-u"], - file: "main.py", - run: ["python3", "-u", "-i", "main.py"], name: "Python", monacoLang: "python", + repl: "python3 -u", + file: "main.py", + run: "python3 -u -i main.py", }, ruby: { - repl: ["irb"], name: "Ruby", monacoLang: "ruby", + repl: "irb", }, rust: { name: "Rust", monacoLang: "rust", }, vim: { - repl: ["vim"], name: "Vimscript", monacoLang: "plaintext", + repl: "vim", }, zsh: { - repl: ["env", "SHELL=/usr/bin/zsh", "zsh"], - file: ".zshrc", - run: ["env", "ZDOTDIR=.", "zsh"], name: "Zsh", monacoLang: "shell", + repl: "SHELL=/usr/bin/zsh zsh", + file: ".zshrc", + run: "ZDOTDIR=. zsh", }, }; diff --git a/frontend/src/app.ts b/frontend/src/app.ts index 206180b..930755c 100644 --- a/frontend/src/app.ts +++ b/frontend/src/app.ts @@ -17,6 +17,8 @@ window.addEventListener("resize", () => fitAddon.fit()); const initialRetryDelayMs = 200; let retryDelayMs = initialRetryDelayMs; +let allowInsertingTemplate = true; + function tryConnect() { console.log("Connecting to server..."); socket = new WebSocket( @@ -57,6 +59,15 @@ function tryConnect() { message.monacoLanguage ); return; + case "insertTemplate": + if (typeof message.template !== "string") { + console.error("Unexpected message from server:", message); + return; + } + if (allowInsertingTemplate) { + editor.getModel().setValue(message.template); + } + return; default: console.error("Unexpected message from server:", message); return; @@ -91,6 +102,9 @@ const editor = monaco.editor.create(document.getElementById("editor"), { scrollbar: { verticalScrollbarSize: 0 }, }); window.addEventListener("resize", () => editor.layout()); +editor.onDidChangeModelContent(() => { + allowInsertingTemplate = false; +}); document.getElementById("runButton").addEventListener("click", () => { socket.send(JSON.stringify({ event: "runCode", code: editor.getValue() })); diff --git a/scripts/docker-install.bash b/scripts/docker-install.bash index 91b60ba..82f3f6a 100755 --- a/scripts/docker-install.bash +++ b/scripts/docker-install.bash @@ -38,6 +38,7 @@ bsdmainutils curl emacs-nox git +lsof make man-db nano From e2a3e719bfa33e6472359f1a007c4d7092b7053e Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 7 Jun 2020 19:30:05 -0600 Subject: [PATCH 030/388] All languages 17 working now --- backend/src/api.ts | 72 ++++++++++++++++++++------ backend/src/langs.ts | 114 +++++++++++++++++++++++++++++++++++++----- backend/src/server.ts | 5 ++ frontend/src/app.ts | 8 ++- 4 files changed, 171 insertions(+), 28 deletions(-) diff --git a/backend/src/api.ts b/backend/src/api.ts index 9142ce2..4872cdf 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -1,3 +1,5 @@ +"use strict"; + import * as fs from "fs"; import * as pty from "node-pty"; import { IPty } from "node-pty"; @@ -18,19 +20,27 @@ export class Session { this.config = langs[lang]; this.term = { pty: null, live: false }; this.code = ""; - this.ws.send( - JSON.stringify({ - event: "setMonacoLanguage", - monacoLanguage: this.config.monacoLang, - }) - ); - if (this.config.template) { + try { this.ws.send( JSON.stringify({ - event: "insertTemplate", - template: this.config.template, + event: "setMonacoLanguage", + monacoLanguage: this.config.monacoLang, }) ); + } catch (err) { + // + } + if (this.config.template) { + try { + this.ws.send( + JSON.stringify({ + event: "insertTemplate", + template: this.config.template, + }) + ); + } catch (err) { + // + } } this.run().catch(console.error); ws.on("message", this.handleClientMessage); @@ -67,12 +77,16 @@ export class Session { } }; run = async () => { - const { repl, file, suffix, compile, run } = this.config; + const { repl, main, suffix, compile, run, hacks } = this.config; if (this.term.pty) { this.term.pty.kill(); this.term.live = false; } - this.ws.send(JSON.stringify({ event: "terminalClear" })); + try { + this.ws.send(JSON.stringify({ event: "terminalClear" })); + } catch (err) { + // + } const tmpdir: string = await new Promise((resolve, reject) => tmp.dir({ unsafeCleanup: true }, (err, path) => { if (err) { @@ -84,14 +98,14 @@ export class Session { ); let cmdline: string; if (!run) { - cmdline = `echo 'Support for ${this.config.name} is not yet implemented.`; + cmdline = `echo 'Support for ${this.config.name} is not yet implemented.'`; } else if (this.code) { let code = this.code; if (suffix) { code += suffix; } await new Promise((resolve, reject) => - fs.writeFile(path.resolve(tmpdir, file), code, (err) => { + fs.writeFile(path.resolve(tmpdir, main), code, (err) => { if (err) { reject(err); } else { @@ -108,6 +122,30 @@ export class Session { } else { return; } + if (hacks && hacks.includes("ghci-config") && run) { + if (this.code) { + const contents = ":load Main\nmain\n"; + await new Promise((resolve, reject) => { + fs.writeFile(path.resolve(tmpdir, ".ghci"), contents, (err) => { + if (err) { + reject(err); + } else { + resolve(); + } + }); + }); + } else { + await new Promise((resolve, reject) => + fs.unlink(path.resolve(tmpdir, ".ghci"), (err) => { + if (err && err.code !== "ENOENT") { + reject(err); + } else { + resolve(); + } + }) + ); + } + } const term = { pty: pty.spawn("bash", ["-c", cmdline], { name: "xterm-color", @@ -121,7 +159,13 @@ export class Session { // Capture term in closure so that we don't keep sending output // from the old pty even after it's been killed (see ghci). if (term.live) { - this.ws.send(JSON.stringify({ event: "terminalOutput", output: data })); + try { + this.ws.send( + JSON.stringify({ event: "terminalOutput", output: data }) + ); + } catch (err) { + // + } } }); }; diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 1a34cfb..34223a2 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1,28 +1,32 @@ +"use strict"; + export interface LangConfig { name: string; monacoLang: string; repl?: string; - file?: string; + main?: string; prefix?: string; suffix?: string; compile?: string; run?: string; template?: string; + hacks?: "ghci-config"[]; } export const langs: { [key: string]: LangConfig } = { bash: { name: "Bash", monacoLang: "shell", - repl: "bash", - file: "main.bash", + repl: "bash --rcfile /dev/null", + main: "main.bash", run: "bash --rcfile main.bash", - template: 'echo "Hello, world!"', + template: `echo "Hello, world!" +`, }, c: { name: "C", monacoLang: "c", - file: "main.c", + main: "main.c", compile: "clang -Wall -Wextra main.c -o main", run: "./main", template: `#include @@ -36,81 +40,167 @@ int main() { "c++": { name: "C++", monacoLang: "cpp", + main: "main.cpp", + compile: "clang++ -Wall -Wextra main.cpp -o main", + run: "./main", + template: `#include + +int main() { + std::cout << "Hello, world!" << std::endl; + return 0; +} +`, }, clojure: { name: "Clojure", monacoLang: "clojure", repl: "clojure", + main: "main.clj", + run: "clojure -i main.clj -r", + template: `(println "Hello, world!") +`, }, emacs: { name: "Emacs Lisp", monacoLang: "plaintext", - repl: "emacs", + repl: "emacs --eval '(ielm)'", + main: "main.el", + run: "emacs --load main.el --eval '(ielm)'", + template: `(message "Hello, world!") +`, }, fish: { name: "Fish", monacoLang: "plaintext", repl: "SHELL=/usr/bin/fish fish", + main: "main.fish", + run: 'fish -C "$(< main.fish)"', + template: `echo "Hello, world!" +`, }, go: { name: "Go", monacoLang: "go", + main: "main.go", + compile: "go build main.go", + run: "./main", + template: `package main + +import "fmt" + +func main() { + fmt.Println("Hello, world!") +} +`, }, haskell: { name: "Haskell", monacoLang: "plaintext", repl: "ghci", - file: "Main.hs", - run: "ghci Main.hs", + main: "Main.hs", + run: "ghci", + template: `module Main where + +main :: IO () +main = putStrLn "Hello, world!" +`, + hacks: ["ghci-config"], }, java: { name: "Java", monacoLang: "java", + main: "Main.java", + compile: "javac Main.java", + run: "java Main", + template: `public class Main { + public static void main(String[] args) { + System.out.println("Hello, world!"); + } +} +`, }, julia: { name: "Julia", monacoLang: "plaintext", repl: "julia", + main: "main.jl", + run: "julia -L main.jl", + template: `println("Hello, world!") +`, }, lua: { name: "Lua", monacoLang: "lua", repl: "lua", + main: "main.lua", + run: "lua -i main.lua", + template: `print("Hello, world!") +`, }, nodejs: { name: "Node.js", monacoLang: "javascript", repl: "node", - file: "main.js", - suffix: '\n;require("repl").start();', + main: "main.js", + suffix: ` +require("repl").start(); +`, run: "node main.js", + template: `console.log("Hello, world!") +`, }, python: { name: "Python", monacoLang: "python", repl: "python3 -u", - file: "main.py", + main: "main.py", run: "python3 -u -i main.py", + template: `print("Hello, world!") +`, }, ruby: { name: "Ruby", monacoLang: "ruby", repl: "irb", + main: "main.rb", + suffix: ` +require 'irb' +IRB.setup(ARGV[0], argv: []) +workspace = IRB::WorkSpace.new(binding) +binding_irb = IRB::Irb.new(workspace) +binding_irb.run(IRB.conf) +`, + run: "ruby main.rb", + template: `puts "Hello, world!" +`, }, rust: { name: "Rust", monacoLang: "rust", + main: "main.rs", + compile: "rustc main.rs", + run: "./main", + template: `fn main() { + println!("Hello, world!"); +} +`, }, vim: { name: "Vimscript", monacoLang: "plaintext", repl: "vim", + main: "main.vim", + run: `vim -c "$(< main.vim)"`, + template: `:echo "Hello, world!" +`, }, zsh: { name: "Zsh", monacoLang: "shell", repl: "SHELL=/usr/bin/zsh zsh", - file: ".zshrc", + main: ".zshrc", run: "ZDOTDIR=. zsh", + template: `echo "Hello, world!" +`, }, }; diff --git a/backend/src/server.ts b/backend/src/server.ts index dd191db..981276e 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -1,3 +1,5 @@ +"use strict"; + import * as appRoot from "app-root-path"; import * as express from "express"; import { Request } from "express"; @@ -23,6 +25,9 @@ app.use(sslRedirect()); app.get("/", (_, res) => { res.sendFile(appRoot.path + "/frontend/pages/index.html"); }); +app.get("/cpp", (_, res) => { + res.redirect("/c++"); +}); app.get("/:lang", (req, res) => { if (langs[req.params.lang]) { res.sendFile(appRoot.path + "/frontend/pages/app.html"); diff --git a/frontend/src/app.ts b/frontend/src/app.ts index 930755c..6bf6b89 100644 --- a/frontend/src/app.ts +++ b/frontend/src/app.ts @@ -1,3 +1,5 @@ +"use strict"; + import * as monaco from "monaco-editor"; import { Terminal } from "xterm"; import { FitAddon } from "xterm-addon-fit"; @@ -24,10 +26,9 @@ function tryConnect() { socket = new WebSocket( (document.location.protocol === "http:" ? "ws://" : "wss://") + document.location.host + - `/api/v1/ws?lang=${lang}` + `/api/v1/ws?lang=${encodeURIComponent(lang)}` ); socket.addEventListener("open", () => { - retryDelayMs = initialRetryDelayMs; console.log("Successfully connected to server"); }); socket.addEventListener("message", (event: MessageEvent) => { @@ -38,6 +39,9 @@ function tryConnect() { console.error("Malformed message from server:", event.data); return; } + if (message?.event && message?.event !== "error") { + retryDelayMs = initialRetryDelayMs; + } switch (message?.event) { case "terminalClear": term.reset(); From 473c50c421a72a14ffaed93ba4d28a4bccfba2a4 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 7 Jun 2020 22:46:58 -0600 Subject: [PATCH 031/388] ALL THE LANGUAGES --- backend/src/langs.ts | 79 ++++++++++++++++++++++++++++++++++++- backend/src/server.ts | 3 -- scripts/docker-install.bash | 50 +++++++++++++++++++++-- 3 files changed, 125 insertions(+), 7 deletions(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 34223a2..586a0b5 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -37,7 +37,7 @@ int main() { } `, }, - "c++": { + cpp: { name: "C++", monacoLang: "cpp", main: "main.cpp", @@ -49,6 +49,27 @@ int main() { std::cout << "Hello, world!" << std::endl; return 0; } +`, + }, + crystal: { + name: "Crystal", + monacoLang: "plaintext", + main: "main.cr", + run: "crystal main.cr", + template: `puts "Hello, world!" +`, + }, + csharp: { + name: "C#", + monacoLang: "csharp", + main: "main.cs", + compile: "mcs main.cs", + run: "./main.exe", + template: `class main { + static void Main(string[] args) { + System.Console.WriteLine("Hello, world!"); + } +} `, }, clojure: { @@ -58,6 +79,15 @@ int main() { main: "main.clj", run: "clojure -i main.clj -r", template: `(println "Hello, world!") +`, + }, + elixir: { + name: "Elixir", + monacoLang: "plaintext", + repl: "iex", + main: "main.exs", + run: "iex main.exs", + template: `IO.puts("Hello, world!") `, }, emacs: { @@ -76,6 +106,15 @@ int main() { main: "main.fish", run: 'fish -C "$(< main.fish)"', template: `echo "Hello, world!" +`, + }, + fsharp: { + name: "F#", + monacoLang: "fsharp", + repl: "fsharpi", + main: "main.fsx", + run: "fsharpi --use:main.fsx", + template: `printfn "Hello, world!" `, }, go: { @@ -126,6 +165,15 @@ main = putStrLn "Hello, world!" main: "main.jl", run: "julia -L main.jl", template: `println("Hello, world!") +`, + }, + kotlin: { + name: "Kotlin", + monacoLang: "kotlin", + repl: "kotlinc", + main: "main.kts", + run: "kotlinc -script main.kts; kotlinc", + template: `println("Hello, world!") `, }, lua: { @@ -156,6 +204,15 @@ require("repl").start(); main: "main.py", run: "python3 -u -i main.py", template: `print("Hello, world!") +`, + }, + r: { + name: "R", + monacoLang: "r", + repl: "R", + main: ".Rprofile", + run: "R --no-save", + template: `print("Hello, world!") `, }, ruby: { @@ -183,6 +240,26 @@ binding_irb.run(IRB.conf) template: `fn main() { println!("Hello, world!"); } +`, + }, + scheme: { + name: "Scheme", + monacoLang: "scheme", + repl: "mit-scheme", + main: "main.scm", + run: "mit-scheme --load main.scm", + template: `(begin + (display "Hello, world!") + (newline)) +`, + }, + swift: { + name: "Swift", + monacoLang: "swift", + main: "main.swift", + compile: "swiftc main.swift", + run: "./main", + template: `print("Hello, world!") `, }, vim: { diff --git a/backend/src/server.ts b/backend/src/server.ts index 981276e..8abea8f 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -25,9 +25,6 @@ app.use(sslRedirect()); app.get("/", (_, res) => { res.sendFile(appRoot.path + "/frontend/pages/index.html"); }); -app.get("/cpp", (_, res) => { - res.redirect("/c++"); -}); app.get("/:lang", (req, res) => { if (langs[req.params.lang]) { res.sendFile(appRoot.path + "/frontend/pages/app.html"); diff --git a/scripts/docker-install.bash b/scripts/docker-install.bash index 82f3f6a..07de95d 100755 --- a/scripts/docker-install.bash +++ b/scripts/docker-install.bash @@ -12,14 +12,23 @@ uid="$1" export DEBIAN_FRONTEND=noninteractive apt-get update -apt-get install -y curl gnupg lsb-release +apt-get install -y apt-transport-https curl gnupg lsb-release rm -rf /var/lib/apt/lists/* -curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - -curl -sS https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - +curl -sSL https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - +curl -sSL https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - +curl -sSL https://keybase.io/crystal/pgp_keys.asc | apt-key add - +apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9 + +cd /tmp +wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb +dpkg -i packages-microsoft-prod.deb +rm packages-microsoft-prod.deb tee -a /etc/apt/sources.list.d/custom.list >/dev/null <<"EOF" +deb https://cloud.r-project.org/bin/linux/ubuntu focal-cran40/ deb https://deb.nodesource.com/node_14.x focal main +deb https://dist.crystal-lang.org/apt crystal main deb https://dl.yarnpkg.com/debian/ stable main deb-src https://deb.nodesource.com/node_14.x EOF @@ -53,12 +62,24 @@ bash # C/C++ clang +# C# +mono-mcs + # Clojure clojure +# Crystal +crystal + +# Elixir +elixir + # Emacs Lisp emacs-nox +# F# +fsharp + # Fish fish @@ -87,12 +108,21 @@ python3 python3-pip python3-venv +# R +r-base + # Ruby ruby # Rust rustc +# Scheme +mit-scheme + +# Swift +libpython2.7 + # Vimscript vim @@ -111,6 +141,20 @@ wget -nv https://github.com/watchexec/watchexec/releases/download/1.13.1/watchex dpkg -i watchexec-*.deb rm watchexec-*.deb +cd /tmp +wget -nv https://github.com/JetBrains/kotlin/releases/download/v1.3.72/kotlin-compiler-1.3.72.zip +unzip kotlin-*.zip +cp kotlinc/bin/* /usr/bin/ +cp kotlinc/lib/* /usr/lib/ +rm -rf kotlin-*.zip kotlinc + +cd /tmp +wget -nv https://swift.org/builds/swift-5.2.4-release/ubuntu2004/swift-5.2.4-RELEASE/swift-5.2.4-RELEASE-ubuntu20.04.tar.gz +mkdir /opt/swift +tar -xf swift-*.tar.gz -C /opt/swift --strip-components=2 +ln -s /opt/swift/bin/swiftc /usr/bin/swiftc +rm swift-*.tar.gz + if (( "$uid" != 0 )); then useradd --uid="$uid" --create-home --groups sudo docker passwd -d docker From 371831593c6ef8e0c830f079dae57519e185a297 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 8 Jun 2020 11:15:12 -0600 Subject: [PATCH 032/388] even more languages --- Dockerfile | 2 +- backend/src/langs.ts | 92 +++++++++++++++++++++++++++++++++++-- scripts/docker-install.bash | 35 +++++++++++++- 3 files changed, 122 insertions(+), 7 deletions(-) diff --git a/Dockerfile b/Dockerfile index 4a1c43d..93dacb2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:rolling +FROM ubuntu:focal ARG UID diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 586a0b5..ec50166 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -79,6 +79,29 @@ int main() { main: "main.clj", run: "clojure -i main.clj -r", template: `(println "Hello, world!") +`, + }, + coffeescript: { + name: "CoffeeScript", + monacoLang: "coffee", + repl: "coffee", + main: "main.coffee", + compile: "coffee -b -c main.coffee", + run: `node -e ' +eval.apply(this, [require("fs").readFileSync("main.js", {encoding: "utf-8"})]) +require("/usr/lib/node_modules/coffeescript/repl").start() +'`, + template: `console.log "Hello, world!" +`, + }, + dart: { + name: "Dart", + monacoLang: "dart", + main: "main.dart", + run: "dart main.dart", + template: `void main() { + print('Hello, world!'); +} `, }, elixir: { @@ -97,6 +120,20 @@ int main() { main: "main.el", run: "emacs --load main.el --eval '(ielm)'", template: `(message "Hello, world!") +`, + }, + erlang: { + name: "Erlang", + monacoLang: "plaintext", + repl: "erl", + main: "main.erl", + compile: "erl -compile main", + run: "erl -s main main", + template: `-module(main). +-export([main/0]). + +main() -> + io:fwrite("Hello, world!\n"). `, }, fish: { @@ -183,6 +220,15 @@ main = putStrLn "Hello, world!" main: "main.lua", run: "lua -i main.lua", template: `print("Hello, world!") +`, + }, + nim: { + name: "Nim", + monacoLang: "plaintext", + main: "main.nim", + compile: "nim compile main.nim", + run: "./main", + template: `echo "Hello, world!" `, }, nodejs: { @@ -190,11 +236,22 @@ main = putStrLn "Hello, world!" monacoLang: "javascript", repl: "node", main: "main.js", - suffix: ` -require("repl").start(); -`, - run: "node main.js", + run: `node -e ' +eval.apply(this, [require("fs").readFileSync("main.js", {encoding: "utf-8"})]) +require("repl").start() +'`, template: `console.log("Hello, world!") +`, + }, + php: { + name: "PHP", + monacoLang: "php", + repl: "php -a", + main: "main.php", + run: "php -d auto_prepend_file=main.php -a", + template: ` main.js", + run: "NODE_PATH=/usr/lib/node_modules node main.js", + template: `print_string("Hello, world!\\n") `, }, ruby: { @@ -251,6 +317,15 @@ binding_irb.run(IRB.conf) template: `(begin (display "Hello, world!") (newline)) +`, + }, + sqlite: { + name: "SQLite", + monacoLang: "sql", + repl: "sqlite3", + main: "main.sql", + run: `sqlite3 -cmd "$(< main.sql)"`, + template: `SELECT "Hello, world!" `, }, swift: { @@ -260,6 +335,15 @@ binding_irb.run(IRB.conf) compile: "swiftc main.swift", run: "./main", template: `print("Hello, world!") +`, + }, + typescript: { + name: "TypeScript", + monacoLang: "typescript", + repl: "ts-node", + main: "main.ts", + run: `ts-node -i -e "$(< main.ts)"`, + template: `console.log("Hello, world!"); `, }, vim: { diff --git a/scripts/docker-install.bash b/scripts/docker-install.bash index 07de95d..43bcd4a 100755 --- a/scripts/docker-install.bash +++ b/scripts/docker-install.bash @@ -12,10 +12,11 @@ uid="$1" export DEBIAN_FRONTEND=noninteractive apt-get update -apt-get install -y apt-transport-https curl gnupg lsb-release +apt-get install -y apt-transport-https curl gnupg lsb-release wget rm -rf /var/lib/apt/lists/* curl -sSL https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - +curl -sSL https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - curl -sSL https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - curl -sSL https://keybase.io/crystal/pgp_keys.asc | apt-key add - apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9 @@ -26,11 +27,12 @@ dpkg -i packages-microsoft-prod.deb rm packages-microsoft-prod.deb tee -a /etc/apt/sources.list.d/custom.list >/dev/null <<"EOF" +deb [arch=amd64] https://storage.googleapis.com/download.dartlang.org/linux/debian stable main deb https://cloud.r-project.org/bin/linux/ubuntu focal-cran40/ deb https://deb.nodesource.com/node_14.x focal main deb https://dist.crystal-lang.org/apt crystal main deb https://dl.yarnpkg.com/debian/ stable main -deb-src https://deb.nodesource.com/node_14.x +deb-src https://deb.nodesource.com/node_14.x focal main EOF packages=" @@ -40,6 +42,7 @@ bash git make nodejs +npm yarn # Handy utilities @@ -47,6 +50,7 @@ bsdmainutils curl emacs-nox git +jq lsof make man-db @@ -71,12 +75,18 @@ clojure # Crystal crystal +# Dart +dart + # Elixir elixir # Emacs Lisp emacs-nox +# Erlang +erlang + # F# fsharp @@ -99,10 +109,16 @@ julia # Lua lua5.3 +# Nim +nim + # Node.js nodejs yarn +# PHP +php + # Python python3 python3-pip @@ -120,6 +136,9 @@ rustc # Scheme mit-scheme +# SQLite +sqlite + # Swift libpython2.7 @@ -136,11 +155,22 @@ apt-get update apt-get install -y $(grep -v "^#" <<< "$packages") rm -rf /var/lib/apt/lists/* +# CoffeeScript +npm install -g coffeescript + +# TypeScript +npm install -g ts-node typescript + +# ReasonML +npm install -g bs-platform + +# Needed for project infrastructure cd /tmp wget -nv https://github.com/watchexec/watchexec/releases/download/1.13.1/watchexec-1.13.1-x86_64-unknown-linux-gnu.deb dpkg -i watchexec-*.deb rm watchexec-*.deb +# Kotlin cd /tmp wget -nv https://github.com/JetBrains/kotlin/releases/download/v1.3.72/kotlin-compiler-1.3.72.zip unzip kotlin-*.zip @@ -148,6 +178,7 @@ cp kotlinc/bin/* /usr/bin/ cp kotlinc/lib/* /usr/lib/ rm -rf kotlin-*.zip kotlinc +# Swift cd /tmp wget -nv https://swift.org/builds/swift-5.2.4-release/ubuntu2004/swift-5.2.4-RELEASE/swift-5.2.4-RELEASE-ubuntu20.04.tar.gz mkdir /opt/swift From 548c1c11621c1680cdcd13b61cc2db4041e7c259 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 8 Jun 2020 12:24:58 -0600 Subject: [PATCH 033/388] repl.it superiority!! --- backend/src/langs.ts | 72 +++++++++++++++++++++++++++++++++ scripts/docker-install.bash | 81 ++++++++++++++++++++++++++++++++++++- 2 files changed, 152 insertions(+), 1 deletion(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index ec50166..4061f60 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -21,6 +21,51 @@ export const langs: { [key: string]: LangConfig } = { main: "main.bash", run: "bash --rcfile main.bash", template: `echo "Hello, world!" +`, + }, + basic: { + name: "BASIC", + monacoLang: "plaintext", + repl: "bwbasic", + main: "main.bas", + run: "bwbasic main.bas", + template: `PRINT "Hello, world!" +`, + }, + brainf: { + name: "Brainf***", + monacoLang: "plaintext", + repl: "brainf-repl", + main: "main.bf", + run: "brainf-repl main.bf", + template: `++++++++ +[ + >++++ + [ + >++ + >+++ + >+++ + >+ + <<<<- + ] + >+ + >+ + >- + >>+ + [<] + + <- +] + +>>. +>---. ++++++++..+++. +>>. +<-. +<. ++++.------.--------. +>>+. +>++. `, }, c: { @@ -143,6 +188,15 @@ main() -> main: "main.fish", run: 'fish -C "$(< main.fish)"', template: `echo "Hello, world!" +`, + }, + forth: { + name: "Forth", + monacoLang: "plaintext", + repl: "gforth", + main: "main.fs", + run: "gforth main.fs", + template: `." Hello, world!" CR `, }, fsharp: { @@ -211,6 +265,16 @@ main = putStrLn "Hello, world!" main: "main.kts", run: "kotlinc -script main.kts; kotlinc", template: `println("Hello, world!") +`, + }, + lolcode: { + name: "LOLCODE", + monacoLang: "plaintext", + main: "main.lol", + run: "lci main.lol", + template: `HAI 1.2 + VISIBLE "Hello, world!" +KTHXBYE `, }, lua: { @@ -346,6 +410,14 @@ binding_irb.run(IRB.conf) template: `console.log("Hello, world!"); `, }, + unlambda: { + name: "Unlambda", + monacoLang: "plaintext", + repl: "unlambda-repl", + main: "main.unl", + run: "unlambda-repl main.unl", + template: "`.\n`.!`.d`.l`.r`.o`.w`. `.,`.o`.l`.l`.e`.Hi\n", + }, vim: { name: "Vimscript", monacoLang: "plaintext", diff --git a/scripts/docker-install.bash b/scripts/docker-install.bash index 43bcd4a..9087e1c 100755 --- a/scripts/docker-install.bash +++ b/scripts/docker-install.bash @@ -42,7 +42,6 @@ bash git make nodejs -npm yarn # Handy utilities @@ -60,9 +59,15 @@ tmux vim wget +# BASIC +bwbasic + # Bash bash +# BrainF +beef + # C/C++ clang @@ -93,6 +98,9 @@ fsharp # Fish fish +# Forth +gforth + # Go golang @@ -106,6 +114,9 @@ default-jdk # Julia julia +# LOLCODE +cmake + # Lua lua5.3 @@ -142,6 +153,9 @@ sqlite # Swift libpython2.7 +# Unlambda +unlambda + # Vimscript vim @@ -186,6 +200,71 @@ tar -xf swift-*.tar.gz -C /opt/swift --strip-components=2 ln -s /opt/swift/bin/swiftc /usr/bin/swiftc rm swift-*.tar.gz +# LOLCODE +cd /tmp +git clone https://github.com/justinmeza/lci.git +pushd lci >/dev/null +python3 install.py --prefix=/usr +popd >/dev/null +rm -rf lci + +# BrainF +tee /usr/bin/brainf-repl >/dev/null <<"EOF" +#!/usr/bin/env python3 +import argparse +import readline +import subprocess +import tempfile + +parser = argparse.ArgumentParser() +parser.add_argument("file", nargs="?") +args = parser.parse_args() + +if args.file: + subprocess.run(["beef", args.file]) +while True: + try: + code = input("bf> ") + except KeyboardInterrupt: + print("^C") + continue + except EOFError: + print("^D") + break + with tempfile.NamedTemporaryFile(mode="w") as f: + f.write(code) + f.flush() + subprocess.run(["beef", f.name]) +EOF +chmod +x /usr/bin/brainf-repl + +# Unlambda +tee /usr/bin/unlambda-repl >/dev/null <<"EOF" +#!/usr/bin/env python3 +import argparse +import readline +import subprocess + +parser = argparse.ArgumentParser() +parser.add_argument("file", nargs="?") +args = parser.parse_args() + +if args.file: + with open(args.file) as f: + subprocess.run(["unlambda"], input=f.read(), encoding="utf-8") +while True: + try: + code = input("λ> ") + except KeyboardInterrupt: + print("^C") + continue + except EOFError: + print("^D") + break + subprocess.run(["unlambda"], input=code, encoding="utf-8") +EOF +chmod +x /usr/bin/unlambda-repl + if (( "$uid" != 0 )); then useradd --uid="$uid" --create-home --groups sudo docker passwd -d docker From 1ae424f32886f4447e966c1351eb90d40f36d151 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 8 Jun 2020 16:06:32 -0600 Subject: [PATCH 034/388] More languages, we need all the languages --- backend/src/api.ts | 4 ++ backend/src/langs.ts | 104 +++++++++++++++++++++++++++++++++++- package.json | 1 + scripts/docker-install.bash | 43 +++++++++++++++ yarn.lock | 5 ++ 5 files changed, 155 insertions(+), 2 deletions(-) diff --git a/backend/src/api.ts b/backend/src/api.ts index 4872cdf..8188d63 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -1,6 +1,7 @@ "use strict"; import * as fs from "fs"; +import * as mkdirp from "mkdirp"; import * as pty from "node-pty"; import { IPty } from "node-pty"; import * as path from "path"; @@ -104,6 +105,9 @@ export class Session { if (suffix) { code += suffix; } + if (main.includes("/")) { + await mkdirp(path.dirname(path.resolve(tmpdir, main))); + } await new Promise((resolve, reject) => fs.writeFile(path.resolve(tmpdir, main), code, (err) => { if (err) { diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 4061f60..bd5d926 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -156,6 +156,15 @@ require("/usr/lib/node_modules/coffeescript/repl").start() main: "main.exs", run: "iex main.exs", template: `IO.puts("Hello, world!") +`, + }, + elvish: { + name: "Elvish", + monacoLang: "plaintext", + repl: "SHELL=/usr/bin/elvish HOME=. elvish", + main: ".elvish/rc.elv", + run: "SHELL=/usr/bin/elvish HOME=. elvish", + template: `echo "Hello, world!" `, }, emacs: { @@ -186,7 +195,7 @@ main() -> monacoLang: "plaintext", repl: "SHELL=/usr/bin/fish fish", main: "main.fish", - run: 'fish -C "$(< main.fish)"', + run: 'SHELL=/usr/bin/fish fish -C "$(< main.fish)"', template: `echo "Hello, world!" `, }, @@ -197,6 +206,17 @@ main() -> main: "main.fs", run: "gforth main.fs", template: `." Hello, world!" CR +`, + }, + fortran: { + name: "FORTRAN", + monacoLang: "plaintext", + main: "main.f", + compile: "flang main.f -o main", + run: "./main", + template: ` program hello + print *, "Hello, world!" + end program hello `, }, fsharp: { @@ -265,6 +285,15 @@ main = putStrLn "Hello, world!" main: "main.kts", run: "kotlinc -script main.kts; kotlinc", template: `println("Hello, world!") +`, + }, + ksh: { + name: "Ksh", + monacoLang: "shell", + repl: "SHELL=/usr/bin/ksh HOME=. ksh", + main: ".kshrc", + run: "SHELL=/usr/bin/ksh HOME=. ksh", + template: `echo "Hello, world!" `, }, lolcode: { @@ -305,6 +334,32 @@ eval.apply(this, [require("fs").readFileSync("main.js", {encoding: "utf-8"})]) require("repl").start() '`, template: `console.log("Hello, world!") +`, + }, + objectivec: { + name: "Objective-C", + monacoLang: "objective-c", + main: "main.m", + compile: + "gcc $(gnustep-config --objc-flags) main.m $(gnustep-config --base-libs) -o main", + run: "./main", + template: `#import + +int main() { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSLog(@"Hello, world!"); + [pool drain]; + return 0; +} +`, + }, + perl: { + name: "Perl", + monacoLang: "perl", + repl: "re.pl", + main: "main.pl", + run: "re.pl --rcfile ./main.pl", + template: `print("Hello, world!\\n") `, }, php: { @@ -316,6 +371,15 @@ require("repl").start() template: ` Date: Tue, 9 Jun 2020 12:58:21 -0600 Subject: [PATCH 035/388] A lot more languages --- backend/src/langs.ts | 455 +++++++++++++++++++++++++++++++++++- scripts/docker-install.bash | 214 ++++++++++++++++- 2 files changed, 660 insertions(+), 9 deletions(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index bd5d926..c8a5814 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -4,16 +4,70 @@ export interface LangConfig { name: string; monacoLang: string; repl?: string; - main?: string; + main: string; prefix?: string; suffix?: string; compile?: string; - run?: string; - template?: string; + run: string; + template: string; hacks?: "ghci-config"[]; } export const langs: { [key: string]: LangConfig } = { + ada: { + name: "Ada", + monacoLang: "plaintext", + main: "main.adb", + compile: "x86_64-linux-gnu-gnatmake-9 main.adb", + run: "./main", + template: `with Ada.Text_IO; + +procedure Main is +begin + Ada.Text_IO.Put_Line("Hello, world!"); +end Main; +`, + }, + algol: { + name: "ALGOL 68", + monacoLang: "plaintext", + main: "main.alg", + run: "a68g main.alg", + template: `print(("Hello, world!",new line)) +`, + }, + arm: { + name: "ARM", + monacoLang: "plaintext", + main: "main.S", + compile: "arm-linux-gnueabihf-gcc main.S -o main -static", + run: "qemu-arm-static main", + template: ` .text + .globl main +main: + mov r7, #4 + mov r0, #1 + ldr r1, =message + mov r2, #14 + swi 0 + mov r7, #1 + mov r0, #0 + swi 0 + .data +message: + .string "Hello, world!\\n" +`, + }, + ats: { + name: "ATS", + monacoLang: "postiats", + main: "main.dats", + compile: "patscc main.dats -o main", + run: "./main", + template: `val _ = print ("Hello, world!\\n") +implement main0 () = () +`, + }, bash: { name: "Bash", monacoLang: "shell", @@ -30,6 +84,14 @@ export const langs: { [key: string]: LangConfig } = { main: "main.bas", run: "bwbasic main.bas", template: `PRINT "Hello, world!" +`, + }, + befunge: { + name: "Befunge", + monacoLang: "plaintext", + main: "main.be", + run: "befunge-repl main.be", + template: `64+"!dlrow ,olleH">:#,_@ `, }, brainf: { @@ -80,6 +142,24 @@ int main() { printf("Hello, world!\\n"); return 0; } +`, + }, + cmd: { + name: "Cmd", + monacoLang: "bat", + repl: "wine cmd", + main: "main.bat", + run: `pkill wineserver64; while pgrep wineserver64 >/dev/null; do sleep 0.05; done; wine cmd /k main.bat`, + template: `echo "Hello, world!" +`, + }, + commonlisp: { + name: "Common Lisp", + monacoLang: "plaintext", + repl: "rlwrap sbcl", + main: "main.lisp", + run: "rlwrap sbcl --userinit main.lisp", + template: `(format t "Hello, world!") `, }, cpp: { @@ -124,6 +204,28 @@ int main() { main: "main.clj", run: "clojure -i main.clj -r", template: `(println "Hello, world!") +`, + }, + clojurescript: { + name: "ClojureScript", + monacoLang: "clojure", + repl: "lumo -r", + main: "main.cljs", + run: "lumo -i main.cljs -r", + template: `(println "Hello, world!") +`, + }, + cobol: { + name: "COBOL", + monacoLang: "plaintext", + main: "main.cbl", + compile: "cobc -free -x main.cbl -o main", + run: "./main", + template: `IDENTIFICATION DIVISION. +PROGRAM-ID. MAIN. +PROCEDURE DIVISION. + DISPLAY "Hello, world!". + STOP RUN. `, }, coffeescript: { @@ -137,6 +239,19 @@ eval.apply(this, [require("fs").readFileSync("main.js", {encoding: "utf-8"})]) require("/usr/lib/node_modules/coffeescript/repl").start() '`, template: `console.log "Hello, world!" +`, + }, + d: { + name: "D", + monacoLang: "plaintext", + main: "main.d", + compile: "dmd main.d", + run: "./main", + template: `import std.stdio; + +void main() { + writeln("Hello, world!"); +} `, }, dart: { @@ -156,6 +271,18 @@ require("/usr/lib/node_modules/coffeescript/repl").start() main: "main.exs", run: "iex main.exs", template: `IO.puts("Hello, world!") +`, + }, + elm: { + name: "Elm", + monacoLang: "plaintext", + repl: "elm repl", + main: "Main.elm", + run: "cp /opt/elm/elm.json elm.json && run-elm Main.elm; elm repl", + template: `module Main exposing (..) + +output : String +output = "Hello, world!" `, }, elvish: { @@ -187,7 +314,7 @@ require("/usr/lib/node_modules/coffeescript/repl").start() -export([main/0]). main() -> - io:fwrite("Hello, world!\n"). + io:fwrite("Hello, world!\\n"). `, }, fish: { @@ -256,6 +383,31 @@ main = putStrLn "Hello, world!" `, hacks: ["ghci-config"], }, + intercal: { + name: "INTERCAL", + monacoLang: "plaintext", + main: "main.i", + compile: "ick main.i", + run: "./main", + template: `DO ,1 <- #14 +PLEASE DO ,1 SUB #1 <- #238 +DO ,1 SUB #2 <- #108 +DO ,1 SUB #3 <- #112 +DO ,1 SUB #4 <- #0 +DO ,1 SUB #5 <- #64 +DO ,1 SUB #6 <- #194 +DO ,1 SUB #7 <- #48 +PLEASE DO ,1 SUB #8 <- #22 +DO ,1 SUB #9 <- #248 +DO ,1 SUB #10 <- #168 +DO ,1 SUB #11 <- #24 +DO ,1 SUB #12 <- #16 +PLEASE DO ,1 SUB #13 <- #162 +DO ,1 SUB #14 <- #52 +PLEASE READ OUT ,1 +PLEASE GIVE UP +`, + }, java: { name: "Java", monacoLang: "java", @@ -276,6 +428,18 @@ main = putStrLn "Hello, world!" main: "main.jl", run: "julia -L main.jl", template: `println("Hello, world!") +`, + }, + kalyn: { + name: "Kalyn", + monacoLang: "plaintext", + main: "src-kalyn/Main.kalyn", + compile: "kalyn", + run: "out-kalyn/Main", + template: `(import "/opt/kalyn/Stdlib.kalyn") + +(public def main (IO Empty) + (print "Hello, world!\\n")) `, }, kotlin: { @@ -313,6 +477,47 @@ KTHXBYE main: "main.lua", run: "lua -i main.lua", template: `print("Hello, world!") +`, + }, + malbolge: { + name: "Malbolge", + monacoLang: "plaintext", + main: "main.mb", + run: "malbolge main.mb", + template: + " (=<`#9]~6ZY32Vx/4Rs+0No-&Jk)\"Fh}|Bcy?`=*z]Kw%oG4UUS0/@-ejc(:'8dc\n", + }, + mips: { + name: "MIPS", + monacoLang: "mips", + main: "main.S", + compile: "mips64-linux-gnuabi64-gcc main.S -o main -static", + run: "qemu-mips64-static main", + template: ` .text + .global main +main: + li $v0, 5001 + li $a0, 1 + dla $a1, message + li $a2, 14 + syscall + li $v0, 5058 + li $a0, 0 + syscall + .data +message: + .string "Hello, world!\\n" +`, + }, + mumps: { + name: "MUMPS", + monacoLang: "plaintext", + main: "main.m", + run: + "gtm_dist=/usr/lib/x86_64-linux-gnu/fis-gtm/V6.3-007_x86_64 /usr/lib/x86_64-linux-gnu/fis-gtm/V6.3-007_x86_64/utf8/mumps -r main main.m", + template: `main() + write "Hello, world!",! + quit `, }, nim: { @@ -351,6 +556,27 @@ int main() { [pool drain]; return 0; } +`, + }, + octave: { + name: "Octave", + monacoLang: "plaintext", + repl: "octave", + main: "main.m", + run: "octave --persist main.m", + template: `disp("Hello, world!") +`, + }, + pascal: { + name: "Pascal", + monacoLang: "pascal", + main: "main.pas", + compile: "fpc main.pas", + run: "./main", + template: `program Main; +begin + writeln('Hello, world!'); +end. `, }, perl: { @@ -380,6 +606,18 @@ echo "Hello, world!\\n"; main: "main.ps1", run: "SHELL=/usr/bin/pwsh pwsh -NoExit main.ps1", template: `Write-Host "Hello, world!" +`, + }, + prolog: { + name: "Prolog", + monacoLang: "plaintext", + repl: "prolog", + main: "main.pl", + run: "prolog main.pl", + template: `:- initialization main. + +main :- + write("Hello, world!"), nl. `, }, python: { @@ -398,6 +636,16 @@ echo "Hello, world!\\n"; main: ".Rprofile", run: "R --no-save", template: `print("Hello, world!") +`, + }, + racket: { + name: "Racket", + monacoLang: "plaintext", + repl: "racket", + main: "main.rkt", + run: `racket -i -e '(enter! "main.rkt") (display "[ type (enter! \\"main.rkt\\") to access local variables ]\\n")'`, + template: `#lang racket/base +(display "Hello, world!\\n") `, }, reasonml: { @@ -407,6 +655,28 @@ echo "Hello, world!\\n"; compile: "bsc main.re > main.js", run: "NODE_PATH=/usr/lib/node_modules node main.js", template: `print_string("Hello, world!\\n") +`, + }, + riscv: { + name: "RISC-V", + monacoLang: "plaintext", + main: "main.S", + compile: "riscv64-linux-gnu-gcc main.S -o main -static", + run: "qemu-riscv64-static main", + template: ` .text + .global main +main: + addi a7, x0, 64 + addi a0, x0, 1 + la a1, message + addi a2, x0, 14 + ecall + addi a7, x0, 93 + addi a0, x0, 0 + ecall + .data +message: + .string "Hello, world!\\n" `, }, ruby: { @@ -463,6 +733,123 @@ binding_irb.run(IRB.conf) main: ".profile", run: "SHELL=/usr/bin/sh HOME=. posh -l", template: `echo "Hello, world!" +`, + }, + shakespeare: { + name: "Shakespeare", + monacoLang: "plaintext", + repl: "shakespeare console", + main: "main.spl", + suffix: "\n[A pause]", + run: "shakespeare debug main.spl", + template: `The Infamous Hello World Program. + +Romeo, a young man with a remarkable patience. +Juliet, a likewise young woman of remarkable grace. +Ophelia, a remarkable woman much in dispute with Hamlet. +Hamlet, the flatterer of Andersen Insulting A/S. + + + Act I: Hamlet's insults and flattery. + + Scene I: The insulting of Romeo. + +[Enter Hamlet and Romeo] + +Hamlet: + You lying stupid fatherless big smelly half-witted coward! + You are as stupid as the difference between a handsome rich brave + hero and thyself! Speak your mind! + + You are as brave as the sum of your fat little stuffed misused dusty + old rotten codpiece and a beautiful fair warm peaceful sunny summer's + day. You are as healthy as the difference between the sum of the + sweetest reddest rose and my father and yourself! Speak your mind! + + You are as cowardly as the sum of yourself and the difference + between a big mighty proud kingdom and a horse. Speak your mind. + + Speak your mind! + +[Exit Romeo] + + Scene II: The praising of Juliet. + +[Enter Juliet] + +Hamlet: + Thou art as sweet as the sum of the sum of Romeo and his horse and his + black cat! Speak thy mind! + +[Exit Juliet] + + Scene III: The praising of Ophelia. + +[Enter Ophelia] + +Hamlet: + Thou art as lovely as the product of a large rural town and my amazing + bottomless embroidered purse. Speak thy mind! + + Thou art as loving as the product of the bluest clearest sweetest sky + and the sum of a squirrel and a white horse. Thou art as beautiful as + the difference between Juliet and thyself. Speak thy mind! + +[Exeunt Ophelia and Hamlet] + + + Act II: Behind Hamlet's back. + + Scene I: Romeo and Juliet's conversation. + +[Enter Romeo and Juliet] + +Romeo: + Speak your mind. You are as worried as the sum of yourself and the + difference between my small smooth hamster and my nose. Speak your + mind! + +Juliet: + Speak YOUR mind! You are as bad as Hamlet! You are as small as the + difference between the square of the difference between my little pony + and your big hairy hound and the cube of your sorry little + codpiece. Speak your mind! + +[Exit Romeo] + + Scene II: Juliet and Ophelia's conversation. + +[Enter Ophelia] + +Juliet: + Thou art as good as the quotient between Romeo and the sum of a small + furry animal and a leech. Speak your mind! + +Ophelia: + Thou art as disgusting as the quotient between Romeo and twice the + difference between a mistletoe and an oozing infected blister! Speak + your mind! + +[Exeunt] +`, + }, + smalltalk: { + name: "Smalltalk", + monacoLang: "plaintext", + repl: "gst", + main: "main.st", + run: "gst main.st; gst", + template: `'Hello, world!' displayNl ! +`, + }, + snobol: { + name: "SNOBOL", + monacoLang: "plaintext", + repl: "snobol4", + main: "main.sno", + run: "snobol4 main.sno; snobol4", + template: ` OUTPUT = "Hello, world!" +END `, }, sqlite: { @@ -472,6 +859,15 @@ binding_irb.run(IRB.conf) main: "main.sql", run: `sqlite3 -cmd "$(< main.sql)"`, template: `SELECT "Hello, world!" +`, + }, + standardml: { + name: "Standard ML", + monacoLang: "plaintext", + repl: "rlwrap sml", + main: "main.sml", + run: "rlwrap sml main.sml", + template: `print "Hello, world!\\n"; `, }, swift: { @@ -525,6 +921,57 @@ binding_irb.run(IRB.conf) main: "main.vim", run: `vim -c "$(< main.vim)"`, template: `:echo "Hello, world!" +`, + }, + visualbasic: { + name: "Visual Basic", + monacoLang: "vb", + main: "main.vb", + compile: "vbnc main.vb", + run: "mono main.exe", + template: `Module Main + Sub Main(args As String()) + Console.WriteLine("Hello, world!") + End Sub +End Module +`, + }, + whitespace: { + name: "Whitespace", + monacoLang: "plaintext", + main: "main.ws", + run: "whitespace main.ws", + template: `Hello, world! \t \t \n\t\n \t\t \t \t\n\t\n \t\t \t\t \n\t\n \t\t \t\t \n\t\n \t\t \t\t\t\t\n\t\n \t \t\t \n\t\n \t \n\t\n \t\t\t \t\t\t\n\t\n \t\t \t\t\t\t\n\t\n \t\t\t \t \n\t\n \t\t \t\t \n\t\n \t\t \t \n\t\n \n\n\n`, + }, + wolframlanguage: { + name: "Wolfram Language", + monacoLang: "plaintext", + repl: "mathics", + main: "main.wls", + run: "mathics --persist main.wls", + template: `Print["Hello, world!"] +`, + }, + x86: { + name: "x86", + monacoLang: "plaintext", + main: "main.S", + compile: "clang main.S -o main", + run: "./main", + template: ` .text + .globl main +main: + movq $1, %rax + movq $1, %rdi + leaq message(%rip), %rsi + movq $14, %rdx + syscall + movq $60, %rax + movq $0, %rdi + syscall + .data +message: + .string "Hello, world!\\n" `, }, zsh: { diff --git a/scripts/docker-install.bash b/scripts/docker-install.bash index e6a8b4e..f3a75b4 100755 --- a/scripts/docker-install.bash +++ b/scripts/docker-install.bash @@ -10,9 +10,11 @@ fi uid="$1" +dpkg --add-architecture i386 + export DEBIAN_FRONTEND=noninteractive apt-get update -apt-get install -y apt-transport-https curl gnupg lsb-release wget +apt-get install -y apt-transport-https curl gnupg lsb-release software-properties-common wget rm -rf /var/lib/apt/lists/* curl -sSL https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - @@ -35,6 +37,8 @@ deb https://dl.yarnpkg.com/debian/ stable main deb-src https://deb.nodesource.com/node_14.x focal main EOF +add-apt-repository -y -n ppa:deadsnakes/ppa + packages=" # Needed for project infrastructure @@ -42,6 +46,7 @@ bash git make nodejs +python3-pip yarn # Handy utilities @@ -49,6 +54,7 @@ bsdmainutils curl emacs-nox git +htop jq lsof make @@ -59,6 +65,19 @@ tmux vim wget +# Ada +gnat + +# Algol +algol68g + +# ARM +gcc-arm-linux-gnueabihf +qemu-system-static + +# ATS +ats2-lang + # BASIC bwbasic @@ -77,6 +96,17 @@ mono-mcs # Clojure clojure +# Cmd +wine +wine32 + +# COBOL +gnucobol + +# Common Lisp +rlwrap +sbcl + # Crystal crystal @@ -114,12 +144,18 @@ golang cabal-install ghc +# INTERCAL +intercal + # Java default-jdk # Julia julia +# Kalyn +haskell-stack + # Ksh ksh @@ -129,6 +165,13 @@ cmake # Lua lua5.3 +# MIPS +gcc-mips64-linux-gnuabi64 +qemu-system-static + +# MUMPS +fis-gtm + # Nim nim @@ -140,6 +183,12 @@ yarn gcc gnustep-devel +# Octave +octave + +# Pascal +fpc + # Perl perl perlconsole @@ -147,6 +196,9 @@ perlconsole # PHP php +# Prolog +swi-prolog + # Python python3 python3-pip @@ -155,6 +207,13 @@ python3-venv # R r-base +# Racket +racket + +# RISC-V +gcc-riscv64-linux-gnu +qemu-system-static + # Ruby ruby @@ -170,9 +229,19 @@ mit-scheme # Sh posh +# Smalltalk +gnu-smalltalk + +# SNOBOL +m4 + # SQLite sqlite +# Standard ML +rlwrap +smlnj + # Swift libpython2.7 @@ -188,6 +257,15 @@ unlambda # Vimscript vim +# Visual Basic +mono-vbnc + +# Wolfram Language +python3.7 + +# x86 +clang + # Zsh zsh @@ -198,17 +276,37 @@ apt-get update apt-get install -y $(grep -v "^#" <<< "$packages") rm -rf /var/lib/apt/lists/* +npm config set unsafe-perm true + +# Befunge +npm install -g befunge93 prompt-sync + +# ClojureScript +npm install -g lumo-cljs + # CoffeeScript npm install -g coffeescript -# TypeScript -npm install -g ts-node typescript +# Elm +npm install -g run-elm + +# Perl +cpan Devel::REPL # ReasonML npm install -g bs-platform -# Perl -cpan Devel::REPL +# Shakespeare +pip3 install shakespearelang + +# TypeScript +npm install -g ts-node typescript + +# Whitespace +pip3 install whitespace + +# Wolfram Language +python3.7 -m pip install install mathics # Needed for project infrastructure cd /tmp @@ -216,6 +314,18 @@ wget -nv https://github.com/watchexec/watchexec/releases/download/1.13.1/watchex dpkg -i watchexec-*.deb rm watchexec-*.deb +# D +cd /tmp +wget -nv http://downloads.dlang.org/releases/2.x/2.092.0/dmd_2.092.0-0_amd64.deb + +# Elm +cd /tmp +wget -nv https://github.com/elm/compiler/releases/download/0.19.1/binary-for-linux-64-bit.gz +gunzip binary-for-linux-64-bit.gz +chmod +x binary-for-linux-64-bit +mv binary-for-linux-64-bit /usr/bin/elm +rm binary-for-linux-64-bit.gz + # Kotlin cd /tmp wget -nv https://github.com/JetBrains/kotlin/releases/download/v1.3.72/kotlin-compiler-1.3.72.zip @@ -231,6 +341,16 @@ mkdir /opt/powershell tar -xf powershell-*.tar.gz -C /opt/powershell ln -s /opt/powershell/pwsh /usr/bin/pwsh +# SNOBOL +wget -nv ftp://ftp.snobol4.org/snobol/snobol4-2.0.tar.gz +tar -xf snobol4-*.tar.gz +rm snobol4-*.tar.gz +pushd snobol4-* +make || true +mv snobol4 /usr/bin/snobol4 +popd +rm -rf snobol4-* + # Swift cd /tmp wget -nv https://swift.org/builds/swift-5.2.4-release/ubuntu2004/swift-5.2.4-RELEASE/swift-5.2.4-RELEASE-ubuntu20.04.tar.gz @@ -239,6 +359,17 @@ tar -xf swift-*.tar.gz -C /opt/swift --strip-components=2 ln -s /opt/swift/bin/swiftc /usr/bin/swiftc rm swift-*.tar.gz +# Kalyn +cd /tmp +git clone https://github.com/raxod502/kalyn +pushd kalyn >/dev/null +stack build kalyn +mv "$(stack exec which kalyn)" /usr/bin/kalyn +mkdir /opt/kalyn +cp -R src-kalyn/Stdlib src-kalyn/Stdlib.kalyn /opt/kalyn/ +popd +rm -rf kalyn + # LOLCODE cd /tmp git clone https://github.com/justinmeza/lci.git @@ -247,6 +378,50 @@ python3 install.py --prefix=/usr popd >/dev/null rm -rf lci +# Malbolge +cd /tmp +git clone https://github.com/bipinu/malbolge.git +clang malbolge/malbolge.c -o /usr/bin/malbolge +rm -rf malbolge + +# ActionScript +tee /usr/bin/amxmlc >/dev/null <<"EOF" +#!/bin/sh +exec /opt/actionscript/bin/amxmlc "$@" +EOF +chmod +x /usr/bin/amxmlc + +# Befunge +tee /usr/bin/befunge-repl >/dev/null <<"EOF" +#!/usr/bin/env -S NODE_PATH=/usr/lib/node_modules node +const fs = require("fs"); + +const Befunge = require("befunge93"); +const prompt = require("prompt-sync")(); + +const befunge = new Befunge(); +befunge.onInput = prompt; +befunge.onOutput = (output) => { + if (typeof output === "string") { + process.stdout.write(output); + } else { + process.stdout.write(output + " "); + } +}; + +const args = process.argv.slice(2); +if (args.length !== 1) { + console.error("usage: befunge-repl FILE"); + process.exit(1); +} + +befunge.run(fs.readFileSync(args[0], { encoding: "utf-8" })).catch((err) => { + console.error(err); + process.exit(1); +}); +EOF +chmod +x /usr/bin/befunge-repl + # BrainF tee /usr/bin/brainf-repl >/dev/null <<"EOF" #!/usr/bin/env python3 @@ -279,6 +454,35 @@ while True: EOF chmod +x /usr/bin/brainf-repl +# Elm +mkdir /opt/elm +tee /opt/elm/elm.json >/dev/null <<"EOF" +{ + "type": "application", + "source-directories": [ + "." + ], + "elm-version": "0.19.1", + "dependencies": { + "direct": { + "elm/browser": "1.0.2", + "elm/core": "1.0.5", + "elm/html": "1.0.0" + }, + "indirect": { + "elm/json": "1.1.3", + "elm/time": "1.0.0", + "elm/url": "1.0.0", + "elm/virtual-dom": "1.0.2" + } + }, + "test-dependencies": { + "direct": {}, + "indirect": {} + } +} +EOF + # Unlambda tee /usr/bin/unlambda-repl >/dev/null <<"EOF" #!/usr/bin/env python3 From 846caf2ad89f0b8db0e115c2446db27ba783927e Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Tue, 9 Jun 2020 13:34:07 -0600 Subject: [PATCH 036/388] At this point the number of languages is absurd --- backend/src/langs.ts | 23 +++++++++++++++++++++++ scripts/docker-install.bash | 13 +++++++++++++ 2 files changed, 36 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index c8a5814..a13e378 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -368,6 +368,15 @@ import "fmt" func main() { fmt.Println("Hello, world!") } +`, + }, + groovy: { + name: "Groovy", + monacoLang: "plaintext", + repl: "groovysh", + main: "main.groovy", + run: "groovysh main.groovy", + template: `print "Hello, world!"; `, }, haskell: { @@ -383,6 +392,20 @@ main = putStrLn "Hello, world!" `, hacks: ["ghci-config"], }, + ink: { + name: "Ink", + monacoLang: "plaintext", + repl: "ink", + main: "main.ink", + run: "ink main.ink; ink", + template: `std := load('../../opt/ink/std') +str := load('../../opt/ink/str') + +log := std.log + +log('Hello, world!') +`, + }, intercal: { name: "INTERCAL", monacoLang: "plaintext", diff --git a/scripts/docker-install.bash b/scripts/docker-install.bash index f3a75b4..b109650 100755 --- a/scripts/docker-install.bash +++ b/scripts/docker-install.bash @@ -140,6 +140,9 @@ gforth # Go golang +# Groovy +groovy + # Haskell cabal-install ghc @@ -326,6 +329,16 @@ chmod +x binary-for-linux-64-bit mv binary-for-linux-64-bit /usr/bin/elm rm binary-for-linux-64-bit.gz +# Ink +cd /tmp +wget -nv https://github.com/thesephist/ink/releases/download/v0.1.7/ink-linux +wget -nv https://github.com/thesephist/ink/releases/download/v0.1.7/std.ink +wget -nv https://github.com/thesephist/ink/releases/download/v0.1.7/str.ink +chmod +x ink-linux +mv ink-linux /usr/bin/ink +mkdir /opt/ink +mv std.ink str.ink /opt/ink/ + # Kotlin cd /tmp wget -nv https://github.com/JetBrains/kotlin/releases/download/v1.3.72/kotlin-compiler-1.3.72.zip From f9e183e58efd2fe0db8e2299621d0ab0fccd9781 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Tue, 9 Jun 2020 14:39:45 -0600 Subject: [PATCH 037/388] Rename, ejs, homepage, build errors, css --- Makefile | 4 ++-- backend/src/api.ts | 6 ++--- backend/src/server.ts | 7 ++++-- frontend/pages/{app.html => app.ejs} | 3 ++- frontend/pages/index.ejs | 29 ++++++++++++++++++++++++ frontend/pages/index.html | 10 --------- frontend/styles/app.css | 6 +++++ frontend/styles/index.css | 33 ++++++++++++++++++++++++++++ package.json | 3 ++- scripts/docker-install.bash | 18 ++++++++------- yarn.lock | 29 ++++++++++++++++++++++++ 11 files changed, 121 insertions(+), 27 deletions(-) rename frontend/pages/{app.html => app.ejs} (83%) create mode 100644 frontend/pages/index.ejs delete mode 100644 frontend/pages/index.html create mode 100644 frontend/styles/index.css diff --git a/Makefile b/Makefile index 0a1a32d..ca6c03f 100644 --- a/Makefile +++ b/Makefile @@ -10,5 +10,5 @@ help: ## Show this message .PHONY: docker docker: ## Run shell with source code and deps inside Docker - scripts/docker.bash build . -t fast-sandbox --build-arg "UID=$(UID)" - scripts/docker.bash run -it --rm -v "$(PWD):/home/docker/src" -p 6119:6119 fast-sandbox + scripts/docker.bash build . -t riju --build-arg "UID=$(UID)" + scripts/docker.bash run -it --rm -v "$(PWD):/home/docker/src" -p 6119:6119 riju diff --git a/backend/src/api.ts b/backend/src/api.ts index 8188d63..e917c4b 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -78,7 +78,7 @@ export class Session { } }; run = async () => { - const { repl, main, suffix, compile, run, hacks } = this.config; + const { name, repl, main, suffix, compile, run, hacks } = this.config; if (this.term.pty) { this.term.pty.kill(); this.term.live = false; @@ -119,12 +119,12 @@ export class Session { ); cmdline = run; if (compile) { - cmdline = compile + " && " + run; + cmdline = `( ${compile} ) && ( ${run} )`; } } else if (repl) { cmdline = repl; } else { - return; + cmdline = `echo '${name} has no REPL, press Run to see it in action'`; } if (hacks && hacks.includes("ghci-config") && run) { if (this.code) { diff --git a/backend/src/server.ts b/backend/src/server.ts index 8abea8f..8f31a62 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -14,6 +14,7 @@ const host = process.env.HOST || "localhost"; const port = parseInt(process.env.PORT) || 6119; app.set("query parser", (qs: string) => new URLSearchParams(qs)); +app.set("view engine", "ejs"); function getQueryParams(req: Request): URLSearchParams { // This is safe because we set the query parser for Express to @@ -23,11 +24,13 @@ function getQueryParams(req: Request): URLSearchParams { app.use(sslRedirect()); app.get("/", (_, res) => { - res.sendFile(appRoot.path + "/frontend/pages/index.html"); + res.render(appRoot.path + "/frontend/pages/index", { langs }); }); app.get("/:lang", (req, res) => { if (langs[req.params.lang]) { - res.sendFile(appRoot.path + "/frontend/pages/app.html"); + res.render(appRoot.path + "/frontend/pages/app", { + name: langs[req.params.lang].name, + }); } else { res.send(`No such language: ${req.params.lang}`); } diff --git a/frontend/pages/app.html b/frontend/pages/app.ejs similarity index 83% rename from frontend/pages/app.html rename to frontend/pages/app.ejs index 12ccfd3..4b7849d 100644 --- a/frontend/pages/app.html +++ b/frontend/pages/app.ejs @@ -2,7 +2,7 @@ - Fast Sandbox + <%= name %> - Riju
+ Switch to a different language diff --git a/frontend/pages/index.ejs b/frontend/pages/index.ejs new file mode 100644 index 0000000..fd5ba8e --- /dev/null +++ b/frontend/pages/index.ejs @@ -0,0 +1,29 @@ + + + + + Riju + + + +

Riju: online access to any programming language

+ Select a language to get started immediately: +
+ <% for (const [id, {name}] of Object.entries(langs)) { %> + class="language"> +
+ <%= name %> +
+
+ <% } %> +
+

+ + Created by + Radon Rosborough. + Check out the project + on GitHub. + +

+ + diff --git a/frontend/pages/index.html b/frontend/pages/index.html deleted file mode 100644 index c0008f1..0000000 --- a/frontend/pages/index.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - Fast Sandbox - - - Hello, world! - - diff --git a/frontend/styles/app.css b/frontend/styles/app.css index 5b320be..6adf8e0 100644 --- a/frontend/styles/app.css +++ b/frontend/styles/app.css @@ -26,3 +26,9 @@ body { top: 25px; right: calc(50% + 25px); } + +#backButton { + position: absolute; + left: 25px; + bottom: 25px; +} diff --git a/frontend/styles/index.css b/frontend/styles/index.css new file mode 100644 index 0000000..0b2d9a1 --- /dev/null +++ b/frontend/styles/index.css @@ -0,0 +1,33 @@ +body { + display: flex; + flex-direction: column; + align-items: center; + font-family: sans-serif; + text-align: center; + padding-bottom: 20px; +} + +.grid { + display: flex; + flex-wrap: wrap; + justify-content: center; + margin-top: 20px; +} + +div.language { + width: 120px; + height: 60px; + border: solid; + margin: 5px; + padding: 5px; + display: flex; + justify-content: center; + align-items: center; + text-align: center; + font-size: 18px; +} + +a.language { + text-decoration: none; + color: black; +} diff --git a/package.json b/package.json index 6999c00..ffe5304 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "fast-sandbox", + "name": "riju", "version": "0", "license": "MIT", "private": true, @@ -10,6 +10,7 @@ "@types/tmp": "^0.2.0", "app-root-path": "^3.0.0", "css-loader": "^3.5.3", + "ejs": "^3.1.3", "express": "^4.17.1", "express-ws": "^4.0.0", "file-loader": "^6.0.0", diff --git a/scripts/docker-install.bash b/scripts/docker-install.bash index b109650..96cbbb2 100755 --- a/scripts/docker-install.bash +++ b/scripts/docker-install.bash @@ -73,7 +73,7 @@ algol68g # ARM gcc-arm-linux-gnueabihf -qemu-system-static +qemu-user-static # ATS ats2-lang @@ -170,7 +170,7 @@ lua5.3 # MIPS gcc-mips64-linux-gnuabi64 -qemu-system-static +qemu-user-static # MUMPS fis-gtm @@ -215,7 +215,7 @@ racket # RISC-V gcc-riscv64-linux-gnu -qemu-system-static +qemu-user-static # Ruby ruby @@ -309,7 +309,7 @@ npm install -g ts-node typescript pip3 install whitespace # Wolfram Language -python3.7 -m pip install install mathics +python3.7 -m pip install mathics # Needed for project infrastructure cd /tmp @@ -320,6 +320,8 @@ rm watchexec-*.deb # D cd /tmp wget -nv http://downloads.dlang.org/releases/2.x/2.092.0/dmd_2.092.0-0_amd64.deb +dpkg -i dmd_*.deb +rm dmd_*.deb # Elm cd /tmp @@ -327,7 +329,6 @@ wget -nv https://github.com/elm/compiler/releases/download/0.19.1/binary-for-lin gunzip binary-for-linux-64-bit.gz chmod +x binary-for-linux-64-bit mv binary-for-linux-64-bit /usr/bin/elm -rm binary-for-linux-64-bit.gz # Ink cd /tmp @@ -353,15 +354,16 @@ wget -nv https://github.com/PowerShell/PowerShell/releases/download/v7.0.1/power mkdir /opt/powershell tar -xf powershell-*.tar.gz -C /opt/powershell ln -s /opt/powershell/pwsh /usr/bin/pwsh +rm powershell-*.tar.gz # SNOBOL wget -nv ftp://ftp.snobol4.org/snobol/snobol4-2.0.tar.gz tar -xf snobol4-*.tar.gz rm snobol4-*.tar.gz -pushd snobol4-* +pushd snobol4-* >/dev/null make || true mv snobol4 /usr/bin/snobol4 -popd +popd >/dev/null rm -rf snobol4-* # Swift @@ -380,7 +382,7 @@ stack build kalyn mv "$(stack exec which kalyn)" /usr/bin/kalyn mkdir /opt/kalyn cp -R src-kalyn/Stdlib src-kalyn/Stdlib.kalyn /opt/kalyn/ -popd +popd >/dev/null rm -rf kalyn # LOLCODE diff --git a/yarn.lock b/yarn.lock index ecb6c2b..727f04b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -378,6 +378,11 @@ async-limiter@~1.0.0: resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== +async@0.9.x: + version "0.9.2" + resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" + integrity sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0= + atob@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" @@ -991,6 +996,13 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= +ejs@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.3.tgz#514d967a8894084d18d3d47bd169a1c0560f093d" + integrity sha512-wmtrUGyfSC23GC/B1SMv2ogAUgbQEtDmTIhfqielrG5ExIM9TP4UoYdi90jLF1aTcsWCJNEO0UrgKzP0y3nTSg== + dependencies: + jake "^10.6.1" + elliptic@^6.0.0, elliptic@^6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" @@ -1237,6 +1249,13 @@ file-uri-to-path@1.0.0: resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== +filelist@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.1.tgz#f10d1a3ae86c1694808e8f20906f43d4c9132dbb" + integrity sha512-8zSK6Nu0DQIC08mUC46sWGXi+q3GGpKydAG36k+JDba6VRpkevvOWUW5a/PhShij4+vHT9M+ghgG7eM+a9JDUQ== + dependencies: + minimatch "^3.0.4" + fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" @@ -1792,6 +1811,16 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= +jake@^10.6.1: + version "10.8.2" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.2.tgz#ebc9de8558160a66d82d0eadc6a2e58fbc500a7b" + integrity sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A== + dependencies: + async "0.9.x" + chalk "^2.4.2" + filelist "^1.0.1" + minimatch "^3.0.4" + json-parse-better-errors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" From 6295e51d907ba26ebd0398bdd3e68b0c34fba12e Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Tue, 9 Jun 2020 15:17:46 -0600 Subject: [PATCH 038/388] Getting things ready for deploy to Heroku --- .circleci/config.yml | 21 +++++++++++++++++++++ .dockerignore | 1 + Dockerfile => Dockerfile.dev | 0 Dockerfile.prod | 21 +++++++++++++++++++++ Makefile | 20 +++++++++++++++++--- backend/src/langs.ts | 2 +- frontend/pages/index.ejs | 4 ++-- package.json | 2 +- scripts/pid1.bash | 4 ++-- 9 files changed, 66 insertions(+), 9 deletions(-) create mode 100644 .circleci/config.yml create mode 120000 .dockerignore rename Dockerfile => Dockerfile.dev (100%) create mode 100644 Dockerfile.prod diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..c06af7e --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,21 @@ +version: 2 +jobs: + build_and_deploy: + docker: + - image: docker:18.09 + steps: + - checkout + - setup_remote_docker + - run: apk add --no-cache --no-progress bash curl make + - run: curl https://cli-assets.heroku.com/install.sh | sh + - run: make deploy +workflows: + version: 2 + ci: + jobs: + - build_and_deploy: + filters: + branches: + only: master + tags: + ignore: /.*/ diff --git a/.dockerignore b/.dockerignore new file mode 120000 index 0000000..3e4e48b --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +.gitignore \ No newline at end of file diff --git a/Dockerfile b/Dockerfile.dev similarity index 100% rename from Dockerfile rename to Dockerfile.dev diff --git a/Dockerfile.prod b/Dockerfile.prod new file mode 100644 index 0000000..f49da8f --- /dev/null +++ b/Dockerfile.prod @@ -0,0 +1,21 @@ +FROM ubuntu:focal + +ARG UID + +COPY scripts/docker-install.bash /tmp/ +RUN /tmp/docker-install.bash "$UID" + +USER $UID +WORKDIR /home/docker +EXPOSE 6119 + +ENTRYPOINT ["/usr/local/bin/pid1.bash"] +COPY scripts/pid1.bash /usr/local/bin/ + +RUN sudo deluser docker sudo +ADD --chown=docker:docker . /home/docker/src +WORKDIR src +RUN yarn install +RUN yarn run backend +RUN yarn run frontend +CMD yarn run server diff --git a/Makefile b/Makefile index ca6c03f..9632810 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,21 @@ help: ## Show this message sed 's/:[^#]*[#]# /|/' | \ column -t -s'|' >&2 +.PHONY: image +image-dev: ## Build Docker image for development + scripts/docker.bash build . -f Dockerfile.dev -t riju --build-arg "UID=$(UID)" + +.PHONY: image +image-prod: ## Build Docker image for production + scripts/docker.bash build . -f Dockerfile.prod -t riju:prod --build-arg "UID=$(UID)" + .PHONY: docker -docker: ## Run shell with source code and deps inside Docker - scripts/docker.bash build . -t riju --build-arg "UID=$(UID)" - scripts/docker.bash run -it --rm -v "$(PWD):/home/docker/src" -p 6119:6119 riju +docker: image-dev ## Run shell with source code and deps inside Docker + scripts/docker.bash run -it --rm -v "$(PWD):/home/docker/src" -p 6119:6119 riju bash + +.PHONY: deploy +deploy: image-prod ## Deploy to Heroku + scripts/docker.bash tag riju:prod registry.heroku.com/riju-sandbox/web + heroku auth:token | scripts/docker.bash login --username=_ --password-stdin registry.heroku.com + scripts/docker.bash push registry.heroku.com/riju-sandbox/web + heroku container:release web -a riju-sandbox diff --git a/backend/src/langs.ts b/backend/src/langs.ts index a13e378..a5309af 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -149,7 +149,7 @@ int main() { monacoLang: "bat", repl: "wine cmd", main: "main.bat", - run: `pkill wineserver64; while pgrep wineserver64 >/dev/null; do sleep 0.05; done; wine cmd /k main.bat`, + run: `wine cmd /k main.bat`, template: `echo "Hello, world!" `, }, diff --git a/frontend/pages/index.ejs b/frontend/pages/index.ejs index fd5ba8e..e5a2544 100644 --- a/frontend/pages/index.ejs +++ b/frontend/pages/index.ejs @@ -6,8 +6,8 @@ -

Riju: online access to any programming language

- Select a language to get started immediately: +

Riju: online playground for every programming language

+ Pick your favorite language to get started:
<% for (const [id, {name}] of Object.entries(langs)) { %> class="language"> diff --git a/package.json b/package.json index ffe5304..d6cf16e 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "backend-dev": "tsc --watch", "frontend": "webpack --production", "frontend-dev": "webpack --development --watch", - "server": "node server.js", + "server": "node backend/out/server.js", "server-dev": "watchexec -w backend/out -r -n node backend/out/server.js" } } diff --git a/scripts/pid1.bash b/scripts/pid1.bash index 1ceaa37..3e88423 100755 --- a/scripts/pid1.bash +++ b/scripts/pid1.bash @@ -9,8 +9,8 @@ export SHELL="$(which bash)" export HOST=0.0.0.0 -if [[ -d src ]]; then - cd src +if [[ -d /home/docker/src ]]; then + cd /home/docker/src fi exec "$@" From 6d0e1f266e1bfd0143376bff0d8e3498da8c82be Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Tue, 9 Jun 2020 15:26:01 -0600 Subject: [PATCH 039/388] Update README --- README.md | 64 +++++++++---------------------------------------------- 1 file changed, 10 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index 8fd7c57..df80baf 100644 --- a/README.md +++ b/README.md @@ -1,58 +1,14 @@ -# Fast Sandbox +# Riju -This project is a work in progress and does not contain any serious -documentation. +Riju is an online playground for every programming language. In less +than a second, you can start playing with a Python interpreter or +compiling INTERCAL code. -## API +Check out the [live application](https://riju-sandbox.herokuapp.com/)! - POST /api/v1/ws?lang=python +**You should not do any sensitive work on Riju, as NO GUARANTEES are +made about its security or privacy. (No warranty etc etc.)** -The API is based on message passing. - -### Server messages - -Received output from process. - - { - "event": "terminalOutput", - "output": ">>> " - } - -Package name completions. - - { - "event": "packageNameCompletions", - "packageNameCompletions": ["Flask", "Flask-Talisman"], - "messageSerial": 42 - } - -### Client messages - -Received input from user. - - { - "event": "terminalInput", - "input": "print('Hello, world!')\n" - } - -User wants to run code. - - { - "event": "runCode", - "code": "import this" - } - -User wants to install a package. - - { - "event": "installPackage", - "packageName": "Flask" - } - -Complete package names. - - { - "event": "completePackageName", - "partialPackageName": "fla", - "messageSerial": 42 - } +This project is a work in progress, and I don't intend on thoroughly +documenting it until it has reached feature-completeness. As such, +you have reached the end of the README :) From e6974442666cbde89dccf52ada74e851e6510b2e Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Tue, 9 Jun 2020 15:29:05 -0600 Subject: [PATCH 040/388] Add nodejs for CircleCI --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c06af7e..92ad620 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -6,7 +6,7 @@ jobs: steps: - checkout - setup_remote_docker - - run: apk add --no-cache --no-progress bash curl make + - run: apk add --no-cache --no-progress bash curl make nodejs - run: curl https://cli-assets.heroku.com/install.sh | sh - run: make deploy workflows: From ed6ad511e62844113438d611d957f055eca7f92c Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Tue, 9 Jun 2020 15:58:22 -0600 Subject: [PATCH 041/388] Minor fixes --- Makefile | 4 ++-- scripts/docker-install.bash | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 9632810..b820880 100644 --- a/Makefile +++ b/Makefile @@ -8,11 +8,11 @@ help: ## Show this message sed 's/:[^#]*[#]# /|/' | \ column -t -s'|' >&2 -.PHONY: image +.PHONY: image-dev image-dev: ## Build Docker image for development scripts/docker.bash build . -f Dockerfile.dev -t riju --build-arg "UID=$(UID)" -.PHONY: image +.PHONY: image-prod image-prod: ## Build Docker image for production scripts/docker.bash build . -f Dockerfile.prod -t riju:prod --build-arg "UID=$(UID)" diff --git a/scripts/docker-install.bash b/scripts/docker-install.bash index 96cbbb2..64eeca1 100755 --- a/scripts/docker-install.bash +++ b/scripts/docker-install.bash @@ -291,7 +291,7 @@ npm install -g lumo-cljs npm install -g coffeescript # Elm -npm install -g run-elm +npm install -g @kachkaev/run-elm # Perl cpan Devel::REPL @@ -531,7 +531,8 @@ if (( "$uid" != 0 )); then useradd --uid="$uid" --create-home --groups sudo docker passwd -d docker else - ln -s /root /home/docker + useradd --create-home --groups sudo docker + passwd -d docker fi touch /home/docker/.zshrc From 9c48a4880b98df27449da19da8295340afe6f90e Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Tue, 9 Jun 2020 16:49:18 -0600 Subject: [PATCH 042/388] Deal with Swift being big --- scripts/docker-install.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/docker-install.bash b/scripts/docker-install.bash index 64eeca1..74f855b 100755 --- a/scripts/docker-install.bash +++ b/scripts/docker-install.bash @@ -368,7 +368,7 @@ rm -rf snobol4-* # Swift cd /tmp -wget -nv https://swift.org/builds/swift-5.2.4-release/ubuntu2004/swift-5.2.4-RELEASE/swift-5.2.4-RELEASE-ubuntu20.04.tar.gz +wget https://swift.org/builds/swift-5.2.4-release/ubuntu2004/swift-5.2.4-RELEASE/swift-5.2.4-RELEASE-ubuntu20.04.tar.gz mkdir /opt/swift tar -xf swift-*.tar.gz -C /opt/swift --strip-components=2 ln -s /opt/swift/bin/swiftc /usr/bin/swiftc From b3f126b3bd8e6b9162755beca028c60f5fae2445 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Tue, 9 Jun 2020 18:07:25 -0600 Subject: [PATCH 043/388] Deal with Apple and Google both being dumb --- scripts/docker-install.bash | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/scripts/docker-install.bash b/scripts/docker-install.bash index 74f855b..c002340 100755 --- a/scripts/docker-install.bash +++ b/scripts/docker-install.bash @@ -317,6 +317,10 @@ wget -nv https://github.com/watchexec/watchexec/releases/download/1.13.1/watchex dpkg -i watchexec-*.deb rm watchexec-*.deb +cd /tmp +git clone https://github.com/circulosmeos/gdown.pl.git +mv gdown.pl/gdown.pl /usr/bin/gdown + # D cd /tmp wget -nv http://downloads.dlang.org/releases/2.x/2.092.0/dmd_2.092.0-0_amd64.deb @@ -368,11 +372,11 @@ rm -rf snobol4-* # Swift cd /tmp -wget https://swift.org/builds/swift-5.2.4-release/ubuntu2004/swift-5.2.4-RELEASE/swift-5.2.4-RELEASE-ubuntu20.04.tar.gz +gdown "https://drive.google.com/uc?export=download&id=1eE1-VuZz0gv-fITaGVT_r1UunCLjS-JT" swift.tar.gz mkdir /opt/swift -tar -xf swift-*.tar.gz -C /opt/swift --strip-components=2 +tar -xf swift.tar.gz -C /opt/swift --strip-components=2 ln -s /opt/swift/bin/swiftc /usr/bin/swiftc -rm swift-*.tar.gz +rm swift.tar.gz # Kalyn cd /tmp From 1568c032554c457db762a6facd94e35b31fc5891 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Tue, 9 Jun 2020 22:06:56 -0600 Subject: [PATCH 044/388] Add flag --- README.md | 13 ++++++++----- flag.png | Bin 0 -> 15567 bytes 2 files changed, 8 insertions(+), 5 deletions(-) create mode 100644 flag.png diff --git a/README.md b/README.md index df80baf..df5a4e2 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,17 @@ # Riju -Riju is an online playground for every programming language. In less -than a second, you can start playing with a Python interpreter or -compiling INTERCAL code. +Riju is a very fast online playground for every programming language. +In less than a second, you can start playing with a Python interpreter +or compiling INTERCAL code. Check out the [live application](https://riju-sandbox.herokuapp.com/)! -**You should not do any sensitive work on Riju, as NO GUARANTEES are -made about its security or privacy. (No warranty etc etc.)** +**You should not write any sensitive code on Riju, as NO GUARANTEES +are made about the security or privacy of your data. (No warranty etc +etc.)** This project is a work in progress, and I don't intend on thoroughly documenting it until it has reached feature-completeness. As such, you have reached the end of the README :) + +[![Flag](flag.png)](https://www.reddit.com/r/Breath_of_the_Wild/comments/947ewf/flag_of_the_gerudo_based_on_the_flag_of_kazakhstan/) diff --git a/flag.png b/flag.png new file mode 100644 index 0000000000000000000000000000000000000000..3400cb8bd86a868d35e47a2ef67ef437f2869bf3 GIT binary patch literal 15567 zcmd_RWmH_jvj;dq0>L2xfaL z$^X5#`*HW3{jlfkr#aKNy1Kf$yYB6(-!JT=k_hV;uGO5b)-31h&&NufESH}wmCeVzAGUb1T3~W<(7j%2 zJ#2xr-TH02C1|b0YOUB}K3e=_>F=lw`br*n8KQr>S~U~GzW&#Ce>mlQw|&y@)l$0Z zW{t=GP~zTT!eW}rm=oSY(ucG4y7@%eF-P3}(bWCn)uT1+R zDN_Lquo$srh~CLc#Z2&PjP>i1@y*J`2JQikesw$^%?!$O?YgeU3jci!#BFOxo0<8H)9u%ffghNIa( zM{@p`@M8h~4g}r3|&r8u$JF*ySvZrA&>r z63gZ6PkRFiv)}nv3ygQ#L)Xh4*DIWlrgOLIedpsOw;KHBqJ);SHJ5X=VZTIX!Z|%4 zdio#`HAqfUT-_t}VBzNT3#rAY$IlE~B=OJ_pYzknYO5bwm~e=-(a=1@i2l;Sgx-Vy zq*f9~oC~RsCjA#}C`%nv_!snW45mf))ySgh-I6==hG#3X%&u-4%8IU{85t}~hdc10 zn56W>0$DnYRnm9*O>*t0ii*={U*3uvKKa6lrwv-hLLmb2AqSv>hQ$8=-t-EZ{CX`x z259Myz58Ey*Y;#kS18fF%XL-LL~84}|-F0h6Fi{Pc0MSv3jl3fHN`a z;$0fWI7J=rfw>54jh!;TDWUz$2N+%?m%XK-XT^Byfsh+3;G~7F&bem6p8(HnYQy8S z93A!l_=Rrd!JEb}&M8yniKM%0IbJQsG zcZS_zP(##mo-OSCUi?56)#B7S<5=dXu~+rC>WWxQTE+`G${b6^u$D&fo41<7XL`tU znU$ zG=@4p6c8b?Y?|gd+BK~9?}Z(G!@I*cD!9TnzGk{T3UtNO{%fagUh1e}?PL$T!=;WF z**JWXq?TufbA9&_{tXL7(Bc7Mo@qkOZDK zhfQDOEuaJEf4GA#rBJU8&<`aHJG1>Zo3IUH1?;m9rcpDW1rT~O6S477X;l)jw;g?3=0VXMsPzvM z1)LP%1S`c6LqlTeQm@cRjTcvxBR#4``|>iRC7exO=9WaO@=)LGjvFa;T!I9NC7!NY z@m#QUb(Nrg6$dR8dv0)mJ*wq&I%s2#@nfH@vu(5L7oEA{e~lV97zbyJf6&30G(;Be z@0x{>`jv4@CPaM4G>57mte)U$4jR}>ecwUW)+w- zDBX?tte+NoU$#qnpq5wkC{YFG4oY)-j%f5LyEQuC+-eOMuLAQ1rMlt%lRS~ly$m}u z@xXEvKe>;W`InYwMNZ!jv~Z1b7g`WQQz@KS zz9HeSwYF*YL+3bvZvc@dXx8QLrJr5wA&4IMru^t2k`*sTFU#)R_Al9o5DiS z+XA{BBfl zOGS^4nSHh$Xkf~{E2aYYHh22er-yj$G}?xW5&c>AS^noslfR_g))ARPNbeu#`tyE~n(HqR3FlM;$9@%01YU`w{wb`)Yx> z#bYF8aZEVsP(d?q-He7fGwJ*M7JRbVxfYEFpV0!O&&h0iU=2?n&=A`{f>LQ=c;ut^ z`~pbi)m$Wx34W<4YEDR&oy7;zJ?Ceue?-et{IS&2ib{Zf|w$3o(I7 zyaOB-y_mM;?4|vSW|9sx7K*cmP2r+ef7U*S8}DO+6+qAUNAbmK``13Xswh?z%u&Pp z*4}a1PbkTb10Z%(i=(S!IMKPB7;1wqan6*~tN#;(uSqmp(mI^{FS4fMzl$LKfl> z!k#+|ACS-a3x^wwWLe%S)pHE6#RzzuPYV28oRwDk4-ASZ3Ibi7>`f z++$sR3Q(@7j{yS#=uM+xYJYV*u56o@_;IA0KjQcbeY*Xf<1V1!d*cl2#z9i7mqO^J zY)mNw-%UvB+wE|{y0MXz>gE0&&I|dS9ABqwD@PqsST`1ua=jv=nUvu->y(JFO8Fz^ zz)NKKohr#_KEh5vDOSyuuozMB(O1!-hIn%hWGzWIQQ9&_+uwCB;*e%+rV ztE8{K{Py?TyR@#%T3~28p;Dj$jpH3|j8KmnO++6Tx zQ_I5no>ESI^3glL1$%AUvTM!XR(Q;hJp1y+`yST2Rd04Gqw7f+Gr^17Df zyPU968|Bo^p~@vCE8h?1mv}%n#%uPnKq}NwUOSpDCjgfi+c_79Va|`?l$ajM zPWHnUB9gtbN1~ij-{`g+CeTlaQa?Q@455c!et!$M6K3Db{Z>?L_hZ%MH^~4A5l{N@ zQO;ry2|ShEVUoz8{$qwcZP#&s2p!bm>Vl-XFDl7hM7X|f7#m!%`e}-iPWkkr^6G>y z5F2H}#-KVi_W_k77%V~_;M&k}42wN~ezthp=3jj73F9{N?Ypz`(_=V6h% z(w2T|`mYXH0de!A$KJ8V{*0TO=03|;UH)cZY5DNB`9X?W_bG`Q2daEg**i>QtY#l{ zV6N(K=pgX6rq5>|IYq05lHoA<;#Kg&{4pwp!w$vJn#fh0{C|Xxky+qW!At3^ywHrP zKi9dDU|q#)GH<)a!5cr@xVJc%`YrtPFmnP+fAQ}t3AlcS560Jny>9I0ts(m_z?;fL z%o_tuO{2|VX}N?XQTyfGhX#>9zyCAKSPi7<@_ZN+p>sD;*OVoH<@Uf%?j;D3MDHIXxX$;CW(`s;W5aI09A* z2hw>R2(NCcJu8~2yO`o|^$Z{EE`48*{Sd5{H%V&Uvs|ljB%CGN2q_ii@|wo z;lm^(Yo};JtQ=`BI8*swbh`PXG)z<&_voLVAaotBG)?TuM$?w7tjc5(Ya4+gdxV>u;+#SunwoDIN zpc45kg2$6te=TfbwX$o>|5DxS zP%%e8nz{ESL;bba3gdX=fb&lV6#;lm8l~NU&g_bEk}g;2C3O5#KZKZq6>h?BTb0bZ z`I``rnbSYJTH9SZ5WoGp6PZFgfmg)hS*eXW^XT5W$OUh+gGNjFrqb<)9iEVej33U2 z1jSpH7s888x(8K3mK3j@*M>Ejp9E+qHlpiw++HhvUz^5pF&w0cnhjpqwcdq1dPeNR znkC)p&L+WJb5g+*_!%d51jVIdH+e(%SDj17a{5ZVI=z-bPWb4#mV%_bv&aK*dLW3Q z@k1$Ten@UuM&a(@)QWRFVZQn>UE;O5r>9c;kXQ1&RLFl(dvd3Ak#ctS&Xug zgIP_;$KG^Vw@=S6?NvHt{Whr4G~4Zi_<1dhlAvZGI_UdqH^CYlo2SIEa%Mus3}4BO z(N({2&Zlokvb|W}cx~qdyIag}G`>I?a0YX4mvN_NNy?n=J>`dz7A_dTiL`e5~CGHoFj^5Ei)Y0%!0Sk(L!XE@Wz8BGG#evTyle zES>k0+9lu%_p*~Mw=kDnVS-l^3Z9JhY_@(Vy!G94%v;jaH_+5cEuCEWy-h9f{YmpNxAJ~HCcX_^i>K|{$KF(QxuEcZyx=@=#b3cjb<$ts^0=6T zfrtP1V)g8>;)|f4;)at+{wo^3<`$j9HgS+Pg4yQ*x10HGYNCI5pV{{&jPI>#9qkRO z2Ym!2Z&vRkcGGQ(%%a-{kM5{Asy@ld6EZk}?;HLOnk_jtZRd4az4xGo?lyQGatptm zHXLot+2G7d+fP#q9{6~zzie{0$!b=6P>Vle%BCh_SNz z%3#6O&=iGf4QtR7q{5-ZYW9BKmNM;a^7z(ptHtGp zE=GjZ@1M}SB@x2p!}5JgL03tQ!N9WyC$N0$P6mnrW4tCVwZi?Ukt1q~GB) z5E6?fn_A*b`R`(Xa0kO{1;LDM#}X0Hr_+U=7Q_v(sJQP_qQSwi66?K~Df`IgZqN-9nVCW>}c*j&IzKiE0hbk4xOr)s?=f<>E+JEMxOMC za6!%B{J->0A=0arkLt-_8vTRkN|D(r!J7m=7H;N~w(eTD-zSbzteFZSno9T2$ElH{ ztaN$W*s1zjyvn7lr$+m3#Y_p4?k0(Yhvq!h?>>LHzv~yasR?N#(rN0M7uzGU-#rvX zNp$)geZ3*^Qaeht*S{LqL$gU!hTZ(PZ+ExLW%ItwX0oABX^;JiGMuryh*5C}j@G&g z;U!y6z|}XTsMqm%RBt*L$o~dwOp8@ytMjZ2O%qwy_y&{Q^VaslpZ&WE7L`A|d~l?7 zh^@XX3IU7Q1WZ~64si6>sa|Te3kqi>1cfQvtH7=rf6?S8kSLXcThbK82Y4p+6hPH9=ofDX* z6CsVBOWirE-_1wVsVV-`5L^9dy+Mh(t-SRBT$u;gXJ^m#9iy71g>OI`XoB1!8wP{c z7==iKzXn{;2^W;44E3Q3JD3^;>nI!378zMOo>J3hHg~5fzd2FW`r_ZPrKmbE?4+=x z9W_+RTGm?T>aH8~=c~tM+rFiJ$Mv48m%b11<_m3hrlL7_%|8>aC!&OfI*ziNada#S zzr8dMRT?>wo=BdD?wqbXD|-C1ROb?-uy7vO=bB^pP5qo%A;(K8?Av59O%*lLQ zMzi48F$!rZ$2D|fwgn(WB=EI6alQQnyEf$JZ7SxyZ!CK7n!lEjA8lN%$kXUax`gbU zW}z1qHZ+s1t-c{#A{f!lYkKTp%muJVe70eP;pK+hENaV-m7*G8&baDAd zq`l{-$DruwAUJYJ&yW?#*Ouhvjrh@9J3_lv_d&MnU5S;$r9ZXbI-M0$8PQR)dHHB{ z^$m_z7K2Kh%Kd|=p=Q=i6l-;uyeFB54EJ2%n!7%=@tDJRj_K5Rp;Lyq3Rcq&CR;2f zeIeA)7n`w0cthwulHSinn28S_ypDK%Q#t2)!oE^d>jZMM@x^FqXACMDnWAy1JnF&=kcyVy&g-qtzGEj?j zg`Xx))!~)QRvDA;vy5Dr5oT|V8(wu95fFL(`7lQxEw$b$U0#Vs_x;1 zv+}w&wKz(C9tq~!a#iK^yJbwlND%8oXXnY%TG(G2?u< zrzeJv=PORurtiQW0T$T~FtsQsc*Ni-A005ehkk_aJ#v>PF{_zl%}bx7+M**x41P2` zAhLNH@U7)*d1zB6cB|I=s#>$fAGjDiYsXsepYzsDx5R2Y5RDR7&^&lXa(zK4)iByT zc)1*L7)%}jWEHFqjUS)86k9;TiQ*Hhab zJOf7TjRagD!=zeA^>dES6*3t`g{d!OGAlya92OF*&u1cIUndf<90yd61HPB%l7ip; z^SyBC$^4RyiCmE{dX^a1Q&$BoH`+*oSU{62u$cFX6>%@qC-nIs-ki^MZ$xPsG3SBt zTosJ)3!~;DHoLKX3>Pd{53YkPSU7|lzgslnl%Y1%jt|TtZ2_*QazXt}5}>}qB^7|n zO8fkJfpPA`Hsf)7dmMo`ZE;V}SkRf*aJ230h_?uhRipYH^ z``JZpk~8Wdtw5kKRBbDmHsW{gERLVy4tq)ra~&p2nS%RsKj2t4!rvEYbD<5<>I8C@ z9hVG5ti3ZQ{t$;NZpb#~E9gf*AC$Fqa!+GW;P>T_fhdVj84q33+Mzqwy}r)dOjFbB zsy4)3_}Dc$o~Xrpk6z|pa=Vvr&x-08wm+P?3sTwA6&Ji2;WdAx4YcD zMIkyGrT_b+x9zskb@#5c^ceN`QkELHMx7-HeUuy+;uVycE7zvyHSzT0ED&dBUi+a& z(Rs0plByZCN=do{F*Lj-yyyhp-gw*_FH7eQ+1ge41(UibZ4lLsoz{E27jwWn0OCF$ z5=->v#Q~p8n|4(`2t-o#4+{W;{QXvT@BHnW`^ArA9rB0?313NXKxcGI!Ldi-Xk9Tu zXQV>yMqU^J`zr84Rq)Zs^0uS?7z%%@FG3eU=;<7o;Ql$i!#t)(LaniJGRGV;pobxs zPRTw;4Sz=P{+k6J@IE2X{&m+lFXE+>d%9t;xIN0PyXoq)mURqwDvm*Fm2d%GlUdJ- zWaTe#->W8=ukw0&CEw@_2vx}9n%*Pcrm|-b;r24M{Awa9ekr=g zO%w8#h1%R#(4m_zK&n#1?*bjhyPoO!%B0_&tao^!Am(6s#oX+Zh{RH69&&HA$Ei@Vsj_gU z_U?4uKf|{nQKQ-8C?hX}R3*EfaI`Ia>mK3&u@7^g)I_I2d{|7X=`nkwSw1q?hWFCC z4h`lqmI}6gFL)~0v~RC$rO%@K%CBX+h$P_yk-~$NRX2^ze?DUzP&MgJizZ-x8^mQ% zDK4iz2En}iO)|DiTK@BNYI+GPn!S-P{9j+Jb%@s%8siD13!V%4-9Uk<%FCRzWnC4; z7f)GbRL7ilOb+)BX-|pWjs#HVMfuCyz3(Q~h10OcU-%Q?g2b3St%tpUZx>>1?jK#|F$rTd2T!b1p1%}#-!*@p?} z8Rq|h+qaP!$17Cx3G%_qeKJPHWp2d8y;1u0u+yCWYbIW*Veo8C*YOf=cZ%l|ypIL8 zv*^t}vdD$fPEkio+D~aClX&YKrG`PYNz@z)8Zw5$kx#%J`HNZuyVQdG-M>|t znKmCQchW)(RjuSm0k5LP2fM%_mhUs7=#PR_f8AG%(JtJ~X$^x=)JdbmfwcF=tOm2W z(N;ZtU-H5wu5o*JSP7(;ITi(6CeT?+ri=W9U=reUZTW5j&ZJY zu9}BQS)aRjs`%L_UppL7i6H}5uF^injsq2K2o2o*=7D7Y@esr$W_WW*c;j>ZmbscB zpKdB)bcP1>3BAa<>&SaFLrSE(TgPD1M@B=oh}~y4@G)&}OW6pW4@EOAi@TKZg7$1L zpAk29I9N?Zx3bhY_1-|=((kO3(HfJT6Z{eh7x1N>+_x)}sdY7#`+A>uSfQ)-PWp#G zmr7%Dohz1<&G$aAF+Lpu0e8((SN0vF@@mS#!Gz&&qq*(Tg<#GbVQ=%Vql)%Eg(Wta zIT|$Nz*T(cF}m8iq%}K%{HOA_OMB9JXi$OM=^c+(X)AVVvUACq5~exL7T<=i7C^lggr@1(=sElxJZd0ie<<^z z|5e6uRa{%aq$#(imK?j&_((PLU7~x;*!K~xPKrG?#m2FFVY=n~uc#M-w%wROc0>!v zj_^TWVfzi=*%oUSpWj%?BW)Hox${yA`@VW?fkzM$iKae|?p$dQ`y}2_dS@^(Tus*h zy{LT}HP@V@f%%oTezd%bVuqMH^w)i#I8IR&wt>!2HL3G9A=6Mslm13j8le&Hm>%Mr6N%#L*$+j}Caf&|-J3 zwB@^X(zq!3>GYHK={7K>v;BS4`B=%X#t-ET(>+wHh}4n(8?b^p>0U7&iUPN*R9?1K zmxD2Rv)fN(ma+&Tv!sZLJg>0k3zkll(Ei&DlY>d{0KQh?nQos~Z#HUQ1U>vb?3TEF zfA*P45`Lc)b!d1gr23P4m#c~K%Vv*ERQMx)czd9z76lEN8uoStf)`L5l>F;9&@7UR=ov_Eb@RY)zf=M>Q{ z6<*HuB#_+u#k-AGa{9+;wKN!)d*M&j;j$;mD!(vqlxku~V^;R;sxJOmf;V$o%1QDy z4s5^Kz)X+sPXD?Z@2TSUfr>Td1#YPLhe>22ZPNjX>eIcdRH`MOMXw8VNPWrf4tqmc z^G1RzrFBMSNi007ApMQJ(9{r_=M{KAq%$H<&yV)b*{If{lp2eNQ`B(Mrz2a$Ss80J z0oTn?swPI#l6O3dt^j-B&nHQ1R0}Fw|vb!G;ZTj=wf!NcFp3s3z8C{mO=o zdAWO+x4I9%5e`oCbE3;5Tw7K0vnU$GMYKpg6{=! z=tfEgnfRG%#+~!q_PK<3(J2c(u!-sW9pP%bx7Dvnl#_(4mrIsB^#9M~_>|r^ z{_OLUv)wZ+2<&ChY3(oW_A^&sc7~Kx7cBCsjA@3r|H^g?LthP(`I!Sqg7(>8!W08t z8j%xW1Kku>HluLO{AKp>Eo}16#)9bosu(OIvp6NKR5QR*6K1@BrLC@1vHUGk9b!z0 zqy#J4KNDN6iFQj>5oHDk6wTk6Q7hG! z$Z@#uL_Z7tU&=L9T4~hsy*UlN_B26m&=k{Wh|PJwOY^L#2dj@fG}z=pXK-$JQ<}5$ zmND?=qss-)At$#^Jo>a`z)${;!}#|9sUE%h#&}-~PrZI|$0o>7aAiknGOPo>i0!)t zpQ=_{mL5C_X!p7O&aoxR5e^pO3Lp$?IBZuu@+1jNgvl=+ETNGVbiBA+K-CcT4J}&n zzjaJ+aoi)B22+~qZPN#zM1(LwUp@Ho-qWzK2XaPux>neIE!dJC5+M7`Sz#V#!E_-Z z^aGhoBLDHv^G{lWVUG86Mi@o1CWB7`?PpSV8eAoCad~TATef@lE3!{!%;ct{y-YITQ7en-F6<2R@Hc+ zDggM2;Mta@wh!OewQxQeO1*lns?cD5iy9|3hDfx;U@?^{>JQ!$SgBN$->X;J46MzplSJrn5J1VJCJNxZD+ySQU2OW!4)$ zYX=IaLXT#N$r-=P@VJAtPRkZxiyoh0hqPa1ssR88E{>_;v0gCXm6h>r0tG`?}a9Qk|Dw zRyqJbv=s0NnrI{2YpS;{UHtnrlUCFNa9S~-qJW!$`K!SY=u&R)6>l%Uc!*HAA`$~f)z#=KNC@VR_jRA?i7 z8_!T$m9~_6X3hG?!6%lg6F(_A`|aOF3G2;j-^yO)99^v`-%ULs&%3WjaM`5h+;CwI znlDcf)plB_Y>Kc_h9}bp1W?1h3ugV=Wau7bNIF`9KoW5B3`OW*ye0|R0aJJ3v-Ja* zgLhfRSF8C_KeOknu0No0L~d)t4N>Bsm>)*!z&)T5BDSPrHq^IqqAvp=w)QXb2rn2i zc#BcK=u1{3M&q&-dhJRTqaQ{UW;cTNmR5=cfGi;J4G&|Q(kw3L1I)!$zD3k8Ds{}xcFIKfZFKD^7>l3UK9bn zC@5%BPmyANO6Yr%dys=J4p~S;SVrHe)nIGMPhRc>cVuJ`cq(df#ee{!7n1)2 z8hX)p*iW*+X&HBrgC(BzA3)2GRoWP@zT(m4x>WonCFb^MzD(tMVuYRQ&IuR3koHh9 zf2dWFNk@m)?VA+qyP3f83fND;XHo?Ma4Wy%H>HJ%KJA6w9Dm<=NV>$_+HeAsDGCnH zlVN*l{ApLoM-)XlR0#nNnjF~#Em%T6Uvt3Bk>(}2q7hJ}_ZrgFcBa!Y(@&P3wUTAW zDFC$z?yFe7KciU1~qCd?pM~oSEF7NDe>*h%>Txd&WijI+8{jXKy z0_)s9_z%gREtL^EPIf&?&XSPd#SsakT6zN9lr(^TEp)t4>3AbyR-_J(4u~$nW=oaJ z_sS<~N41=v3V>A|f?|)NM{Uc?mid~{Xoo)ijQhR0WQ830p}rSD3CbnI#+TNiv^fa} zYZy-?TwXfQ|AqCKDJaHV|NPbxeQD!O71JKRG7J;R#p9EV`Wt+}FJ{>jwhBqb(>~QS zy^bSyQ|Qq1H6$N3`L5D^2&r0+X#<>17=z>zB4MlxlX?C%)PnOi^SYEo|E4h?u&1}I zMW}e(F8|>3vjE9+65kOzOYUVdfI!LF4{?B0-M2op zKOr#v^jPJKLQ@lJmV-UplVWA}4=xzUVXI&+%XL9we0MGW1%E-B%t^RZSnbXcfIT(5 zgbg`_N~)L-jG_I*68@&G7QYb%1AwTclc3obVd>dyRZ$cuq@(r~G>o+rx5U)|05PS& z*UXttr>fcHu16e-k1a!XidHRkqooZXrr7QWZK5T+11$ds>&RFmd@F+JR`@Mv&`geN zz;pUiB@l?FKX}%e?P3;(*?i(k55CE<2MLTQAC+1D-k|c)OK8s zetk;~5Lq^v>J{&7Hi7+T`C8XTKbI8GGlq~TIN^5N&oi(1p13CceIL13un#!^9`+yc@ zMf{x7dpWSSW5idU9zb25cls}z&u!P|wO!(WJ*G~M;yle7>+nLpt6+t#h_DXjjj=suq zjYsF!8J@Ou(T`c(MHp6@uMM?&D4Y|BBBovVrx?cH6S=$ogD?Jvbf%GczGnQfmj>32 z`aXDD>>pg2JW21QvlreIR|a`>XEnL-MC@!~cV$W>9>IU&%)>$31;H`sMAb z{{XI4j_jgzsGk*STij`jG2#3ELsu6SWamo}Xx#}{MWF;e9}OLhML-j=U;;u`SslOL zPF*^F`8jr|k9b{JMhO-8_El)a!$dIfH0K5psM~iX4XSskmO2dsmmFV4#tsb-f}RVk zqUeow;Rm#!705ypVi!@712DfSu6_TZ%e@f1@k1~|j*8N{*mq8-u;WS`DqA0bi0Vx> zCS{kNXG|;3uu_WmiuHkrMmRK1o6JEJSsSv@hESF^~;r+E;f~_E12xUy+iCNVlY{GMqnO%}7hkcw#etXp9)tKRQPU&C;^&KnpALKRA8S z!3>D+?eD?5#mhoefQ(^lGx4U;zWV?R53@or38AL+GYNtd@LFLSjbnwt6un40T1XHB zlPLcChpGpGCqnNHJL89muhX=gf6Vwrg3@WA#tKp}R?)Qry5gBj7L;S0077Rk))V$p z=~$SbD@XufS1|gG8vCzWJ-%WULAU!ybAa$~t}(k(PIWz*1{92cMpoFG#8H?;Ly#cy z*KeLNtTCT?&G&;49EnfP@@ER28oLdCRbcEd&(MorYF4!?7#y@!i=(5XXtEY2+8QdR z%}Wthfzd!w6Mzz6B6ujjhjtygYkBP&zb3lVH+l=c3#Nt6|4hr~3zLxBL4n<2 zQO9;{FHI<&pP;j9eHVsAYvoJW_YA9bkz_0HoWO?V-_oVFt#`Dp5N?}CMYK#P;&tk96& zC(ktunR=wCFRH0gKu~_jD+?^Ua)_0s_HY#c@-g#;csm;r{o@FIXjjPRao zmHJ2DY9c`T!g+g!WDWW+29ub9;X@i?bP&`8ogErH25^s1LGc~VQ)T_XMgAh#U%GW= z$ks0qlLr~f(>Qm2y*!67A^r>!Ml!gR#@q_|3IQ~!{T*4{BCVG|wH9Qk3=~of5QP*F zULbUU7{vD*D37$NcGUQ3U;^sh2p8i#IW&PPh|@npSJk0gC5b+n2`ft U<6Arj7|I|yDJ990_l95p58R$#^#A|> literal 0 HcmV?d00001 From f1b0c27e5d908f6a6e96c264511320947432e938 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Wed, 10 Jun 2020 16:45:13 -0600 Subject: [PATCH 045/388] Add option to use TLS --- backend/src/server.ts | 28 ++++++++++++++++++++++++---- package.json | 1 - yarn.lock | 5 ----- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/backend/src/server.ts b/backend/src/server.ts index 8f31a62..408a52c 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -1,17 +1,21 @@ "use strict"; +import * as fs from "fs"; +import * as https from "https"; + import * as appRoot from "app-root-path"; import * as express from "express"; import { Request } from "express"; import * as ws from "express-ws"; -import * as sslRedirect from "heroku-ssl-redirect"; import * as api from "./api"; import { langs } from "./langs"; -const app = ws(express()).app; const host = process.env.HOST || "localhost"; const port = parseInt(process.env.PORT) || 6119; +const useTLS = process.env.TLS ? true : false; + +const app = ws(express()).app; app.set("query parser", (qs: string) => new URLSearchParams(qs)); app.set("view engine", "ejs"); @@ -22,7 +26,13 @@ function getQueryParams(req: Request): URLSearchParams { return (req.query as unknown) as URLSearchParams; } -app.use(sslRedirect()); +app.use((req, res, next) => { + if (useTLS && req.headers["x-forwarded-proto"] !== "https") { + res.redirect(301, "https://" + req.hostname + req.originalUrl); + } else { + next(); + } +}); app.get("/", (_, res) => { res.render(appRoot.path + "/frontend/pages/index", { langs }); }); @@ -57,6 +67,16 @@ app.ws("/api/v1/ws", (ws, req) => { } }); -app.listen(port, host, () => +const secureApp = useTLS + ? https.createServer( + { + key: fs.readFileSync("/etc/letsencrypt/live/riju.codes/privkey.pem"), + cert: fs.readFileSync("/etc/letsencrypt/live/riju.codes/fullchain.pem"), + }, + app + ) + : app; + +secureApp.listen(port, host, () => console.log(`Listening on http://${host}:${port}`) ); diff --git a/package.json b/package.json index d6cf16e..c32b9d0 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,6 @@ "express": "^4.17.1", "express-ws": "^4.0.0", "file-loader": "^6.0.0", - "heroku-ssl-redirect": "^0.0.4", "mkdirp": "^1.0.4", "monaco-editor": "^0.20.0", "node-pty": "^0.9.0", diff --git a/yarn.lock b/yarn.lock index 727f04b..5957887 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1516,11 +1516,6 @@ hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.1" -heroku-ssl-redirect@^0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/heroku-ssl-redirect/-/heroku-ssl-redirect-0.0.4.tgz#21ba0707aa503b50a412a0946abfaa88ef7d082c" - integrity sha1-IboHB6pQO1CkEqCUar+qiO99CCw= - hmac-drbg@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" From 7ea28d4ff3e4764ffb3f067bcae171e8a55c1026 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Wed, 10 Jun 2020 16:49:21 -0600 Subject: [PATCH 046/388] Document project setup --- README.md | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index df5a4e2..ccc1ee1 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,37 @@ are made about the security or privacy of your data. (No warranty etc etc.)** This project is a work in progress, and I don't intend on thoroughly -documenting it until it has reached feature-completeness. As such, -you have reached the end of the README :) +documenting it until it has reached feature-completeness. + +## Project setup + +To run the webserver, all you need is Yarn. Just run `yarn install` as +usual to install dependencies. For production, it's: + + $ yarn backend + $ yarn frontend + $ yarn server + +For development with file watching and automatic server rebooting and +all that, it's: + + $ yarn backend-dev + $ yarn frontend-dev + $ yarn server-dev + +The webserver listens on `localhost:6119`. Now, although the server +itself will work, the only languages that will work are the ones that +happen to be installed on your machine. (I'm sure you can find a few +that are already.) If you want to test with *all* the languages (or +you're working on adding a new language), then you need to use Docker. +Running the app is exactly the same as before, you just have to jump +into the container first: + + $ make docker + +Note that building the image takes 30 minutes and requires about 15 GB +of disk space. + +## Flag [![Flag](flag.png)](https://www.reddit.com/r/Breath_of_the_Wild/comments/947ewf/flag_of_the_gerudo_based_on_the_flag_of_kazakhstan/) From 73d05cb61bee8aaac32d2ea83b7da0bf847e103c Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Wed, 10 Jun 2020 17:34:36 -0600 Subject: [PATCH 047/388] Add some infra for deployment --- scripts/certbot-post.sh | 3 +++ scripts/certbot-pre.sh | 3 +++ scripts/riju.service | 8 ++++++++ 3 files changed, 14 insertions(+) create mode 100755 scripts/certbot-post.sh create mode 100755 scripts/certbot-pre.sh create mode 100644 scripts/riju.service diff --git a/scripts/certbot-post.sh b/scripts/certbot-post.sh new file mode 100755 index 0000000..85c2533 --- /dev/null +++ b/scripts/certbot-post.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +systemctl start riju diff --git a/scripts/certbot-pre.sh b/scripts/certbot-pre.sh new file mode 100755 index 0000000..fdc7e0e --- /dev/null +++ b/scripts/certbot-pre.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +systemctl stop riju diff --git a/scripts/riju.service b/scripts/riju.service new file mode 100644 index 0000000..67fe9ab --- /dev/null +++ b/scripts/riju.service @@ -0,0 +1,8 @@ +[Unit] +Description=Riju online coding sandbox + +[Service] +ExecStart=docker run -p 0.0.0.0:6119 riju + +[Install] +WantedBy=multi-user.target From b4636c46aeb5c8e7911268f85dbc7c35a5557f12 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Wed, 10 Jun 2020 17:35:08 -0600 Subject: [PATCH 048/388] Split docker-install.bash into many layers I've been running into trouble where something will fail inscrutably in docker-install.bash or when pushing a large layer or something else of that nature, and those errors really suck when it's just one big layer. This should aid development and deployment both. --- Dockerfile.dev | 30 +- Dockerfile.prod | 34 +- scripts/docker-install-phase1.bash | 35 ++ scripts/docker-install-phase2.bash | 39 +++ scripts/docker-install-phase3a.bash | 63 ++++ scripts/docker-install-phase3b.bash | 70 ++++ scripts/docker-install-phase3c.bash | 70 ++++ scripts/docker-install-phase3d.bash | 64 ++++ scripts/docker-install-phase4.bash | 39 +++ ...nstall.bash => docker-install-phase5.bash} | 326 ------------------ scripts/docker-install-phase6.bash | 19 + 11 files changed, 456 insertions(+), 333 deletions(-) create mode 100755 scripts/docker-install-phase1.bash create mode 100755 scripts/docker-install-phase2.bash create mode 100755 scripts/docker-install-phase3a.bash create mode 100755 scripts/docker-install-phase3b.bash create mode 100755 scripts/docker-install-phase3c.bash create mode 100755 scripts/docker-install-phase3d.bash create mode 100755 scripts/docker-install-phase4.bash rename scripts/{docker-install.bash => docker-install-phase5.bash} (57%) create mode 100644 scripts/docker-install-phase6.bash diff --git a/Dockerfile.dev b/Dockerfile.dev index 93dacb2..aa2536a 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -2,10 +2,34 @@ FROM ubuntu:focal ARG UID -COPY scripts/docker-install.bash /tmp/ -RUN /tmp/docker-install.bash "$UID" +COPY scripts/docker-install-phase1.bash /tmp/ +RUN /tmp/docker-install-phase1.bash -USER $UID +COPY scripts/docker-install-phase2.bash /tmp/ +RUN /tmp/docker-install-phase2.bash + +COPY scripts/docker-install-phase3a.bash /tmp/ +RUN /tmp/docker-install-phase3a.bash + +COPY scripts/docker-install-phase3b.bash /tmp/ +RUN /tmp/docker-install-phase3b.bash + +COPY scripts/docker-install-phase3c.bash /tmp/ +RUN /tmp/docker-install-phase3c.bash + +COPY scripts/docker-install-phase3d.bash /tmp/ +RUN /tmp/docker-install-phase3d.bash + +COPY scripts/docker-install-phase4.bash /tmp/ +RUN /tmp/docker-install-phase4.bash + +COPY scripts/docker-install-phase5.bash /tmp/ +RUN /tmp/docker-install-phase5.bash + +COPY scripts/docker-install-phase6.bash /tmp/ +RUN /tmp/docker-install-phase6.bash "$UID" + +USER docker WORKDIR /home/docker EXPOSE 6119 diff --git a/Dockerfile.prod b/Dockerfile.prod index f49da8f..4f260f1 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -1,11 +1,37 @@ FROM ubuntu:focal +# This is just here so we can reuse the Docker cache between dev and +# prod, it's not actually read by anything. ARG UID -COPY scripts/docker-install.bash /tmp/ -RUN /tmp/docker-install.bash "$UID" +COPY scripts/docker-install-phase1.bash /tmp/ +RUN /tmp/docker-install-phase1.bash -USER $UID +COPY scripts/docker-install-phase2.bash /tmp/ +RUN /tmp/docker-install-phase2.bash + +COPY scripts/docker-install-phase3a.bash /tmp/ +RUN /tmp/docker-install-phase3a.bash + +COPY scripts/docker-install-phase3b.bash /tmp/ +RUN /tmp/docker-install-phase3b.bash + +COPY scripts/docker-install-phase3c.bash /tmp/ +RUN /tmp/docker-install-phase3c.bash + +COPY scripts/docker-install-phase3d.bash /tmp/ +RUN /tmp/docker-install-phase3d.bash + +COPY scripts/docker-install-phase4.bash /tmp/ +RUN /tmp/docker-install-phase4.bash + +COPY scripts/docker-install-phase5.bash /tmp/ +RUN /tmp/docker-install-phase5.bash + +COPY scripts/docker-install-phase6.bash /tmp/ +RUN /tmp/docker-install-phase6.bash + +USER docker WORKDIR /home/docker EXPOSE 6119 @@ -14,7 +40,7 @@ COPY scripts/pid1.bash /usr/local/bin/ RUN sudo deluser docker sudo ADD --chown=docker:docker . /home/docker/src -WORKDIR src +WORKDIR /home/docker/src RUN yarn install RUN yarn run backend RUN yarn run frontend diff --git a/scripts/docker-install-phase1.bash b/scripts/docker-install-phase1.bash new file mode 100755 index 0000000..fa3932b --- /dev/null +++ b/scripts/docker-install-phase1.bash @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +dpkg --add-architecture i386 + +export DEBIAN_FRONTEND=noninteractive +apt-get update +apt-get install -y apt-transport-https curl gnupg lsb-release software-properties-common wget +rm -rf /var/lib/apt/lists/* + +curl -sSL https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - +curl -sSL https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - +curl -sSL https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - +curl -sSL https://keybase.io/crystal/pgp_keys.asc | apt-key add - +apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9 + +cd /tmp +wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb +dpkg -i packages-microsoft-prod.deb +rm packages-microsoft-prod.deb + +tee -a /etc/apt/sources.list.d/custom.list >/dev/null <<"EOF" +deb [arch=amd64] https://storage.googleapis.com/download.dartlang.org/linux/debian stable main +deb https://cloud.r-project.org/bin/linux/ubuntu focal-cran40/ +deb https://deb.nodesource.com/node_14.x focal main +deb https://dist.crystal-lang.org/apt crystal main +deb https://dl.yarnpkg.com/debian/ stable main +deb-src https://deb.nodesource.com/node_14.x focal main +EOF + +add-apt-repository -y -n ppa:deadsnakes/ppa + +rm "$0" diff --git a/scripts/docker-install-phase2.bash b/scripts/docker-install-phase2.bash new file mode 100755 index 0000000..5ec38e5 --- /dev/null +++ b/scripts/docker-install-phase2.bash @@ -0,0 +1,39 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +packages=" + +# Needed for project infrastructure +bash +git +make +nodejs +python3-pip +yarn + +# Handy utilities +bsdmainutils +curl +emacs-nox +git +htop +jq +lsof +make +man-db +nano +sudo +tmux +vim +wget + +" + +export DEBIAN_FRONTEND=noninteractive +apt-get update +apt-get install -y $(grep -v "^#" <<< "$packages") +rm -rf /var/lib/apt/lists/* + +rm "$0" diff --git a/scripts/docker-install-phase3a.bash b/scripts/docker-install-phase3a.bash new file mode 100755 index 0000000..770409d --- /dev/null +++ b/scripts/docker-install-phase3a.bash @@ -0,0 +1,63 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +packages=" + +# Ada +gnat + +# Algol +algol68g + +# ARM +gcc-arm-linux-gnueabihf +qemu-user-static + +# ATS +ats2-lang + +# BASIC +bwbasic + +# Bash +bash + +# BrainF +beef + +# C/C++ +clang + +# C# +mono-mcs + +# Clojure +clojure + +# Cmd +wine +wine32 + +# COBOL +gnucobol + +# Common Lisp +rlwrap +sbcl + +# Crystal +crystal + +# Dart +dart + +" + +export DEBIAN_FRONTEND=noninteractive +apt-get update +apt-get install -y $(grep -v "^#" <<< "$packages") +rm -rf /var/lib/apt/lists/* + +rm "$0" diff --git a/scripts/docker-install-phase3b.bash b/scripts/docker-install-phase3b.bash new file mode 100755 index 0000000..38303f3 --- /dev/null +++ b/scripts/docker-install-phase3b.bash @@ -0,0 +1,70 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +packages=" + +# Elixir +elixir + +# Elvish +elvish + +# Emacs Lisp +emacs-nox + +# Erlang +erlang + +# F# +fsharp + +# Fish +fish + +# FORTRAN +flang-7 + +# Forth +gforth + +# Go +golang + +# Groovy +groovy + +# Haskell +cabal-install +ghc + +# INTERCAL +intercal + +# Java +default-jdk + +# Julia +julia + +# Kalyn +haskell-stack + +# Ksh +ksh + +# LOLCODE +cmake + +# Lua +lua5.3 + +" + +export DEBIAN_FRONTEND=noninteractive +apt-get update +apt-get install -y $(grep -v "^#" <<< "$packages") +rm -rf /var/lib/apt/lists/* + +rm "$0" diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash new file mode 100755 index 0000000..6ca413b --- /dev/null +++ b/scripts/docker-install-phase3c.bash @@ -0,0 +1,70 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +packages=" + +# MIPS +gcc-mips64-linux-gnuabi64 +qemu-user-static + +# MUMPS +fis-gtm + +# Nim +nim + +# Node.js +nodejs +yarn + +# Objective-C +gcc +gnustep-devel + +# Octave +octave + +# Pascal +fpc + +# Perl +perl +perlconsole + +# PHP +php + +# Prolog +swi-prolog + +# Python +python3 +python3-pip +python3-venv + +# R +r-base + +# Racket +racket + +# RISC-V +gcc-riscv64-linux-gnu +qemu-user-static + +# Ruby +ruby + +# Rust +rustc + +" + +export DEBIAN_FRONTEND=noninteractive +apt-get update +apt-get install -y $(grep -v "^#" <<< "$packages") +rm -rf /var/lib/apt/lists/* + +rm "$0" diff --git a/scripts/docker-install-phase3d.bash b/scripts/docker-install-phase3d.bash new file mode 100755 index 0000000..74f09b7 --- /dev/null +++ b/scripts/docker-install-phase3d.bash @@ -0,0 +1,64 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +packages=" + +# Scala +scala + +# Scheme +mit-scheme + +# Sh +posh + +# Smalltalk +gnu-smalltalk + +# SNOBOL +m4 + +# SQLite +sqlite + +# Standard ML +rlwrap +smlnj + +# Swift +libpython2.7 + +# Tcl +tcl + +# Tcsh +tcsh + +# Unlambda +unlambda + +# Vimscript +vim + +# Visual Basic +mono-vbnc + +# Wolfram Language +python3.7 + +# x86 +clang + +# Zsh +zsh + +" + +export DEBIAN_FRONTEND=noninteractive +apt-get update +apt-get install -y $(grep -v "^#" <<< "$packages") +rm -rf /var/lib/apt/lists/* + +rm "$0" diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash new file mode 100755 index 0000000..70ba663 --- /dev/null +++ b/scripts/docker-install-phase4.bash @@ -0,0 +1,39 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +npm config set unsafe-perm true +PERL_MM_USE_DEFAULT=1 cpan App::cpanminus + +# Befunge +npm install -g befunge93 prompt-sync + +# ClojureScript +npm install -g lumo-cljs + +# CoffeeScript +npm install -g coffeescript + +# Elm +npm install -g @kachkaev/run-elm + +# Perl +cpanm -n Devel::REPL + +# ReasonML +npm install -g bs-platform + +# Shakespeare +pip3 install shakespearelang + +# TypeScript +npm install -g ts-node typescript + +# Whitespace +pip3 install whitespace + +# Wolfram Language +python3.7 -m pip install mathics + +rm "$0" diff --git a/scripts/docker-install.bash b/scripts/docker-install-phase5.bash similarity index 57% rename from scripts/docker-install.bash rename to scripts/docker-install-phase5.bash index c002340..62fab91 100755 --- a/scripts/docker-install.bash +++ b/scripts/docker-install-phase5.bash @@ -3,314 +3,6 @@ set -e set -o pipefail -if (( $# != 1 )); then - echo "usage: docker-install.bash UID" >&2 - exit 1 -fi - -uid="$1" - -dpkg --add-architecture i386 - -export DEBIAN_FRONTEND=noninteractive -apt-get update -apt-get install -y apt-transport-https curl gnupg lsb-release software-properties-common wget -rm -rf /var/lib/apt/lists/* - -curl -sSL https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - -curl -sSL https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - -curl -sSL https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - -curl -sSL https://keybase.io/crystal/pgp_keys.asc | apt-key add - -apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9 - -cd /tmp -wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -dpkg -i packages-microsoft-prod.deb -rm packages-microsoft-prod.deb - -tee -a /etc/apt/sources.list.d/custom.list >/dev/null <<"EOF" -deb [arch=amd64] https://storage.googleapis.com/download.dartlang.org/linux/debian stable main -deb https://cloud.r-project.org/bin/linux/ubuntu focal-cran40/ -deb https://deb.nodesource.com/node_14.x focal main -deb https://dist.crystal-lang.org/apt crystal main -deb https://dl.yarnpkg.com/debian/ stable main -deb-src https://deb.nodesource.com/node_14.x focal main -EOF - -add-apt-repository -y -n ppa:deadsnakes/ppa - -packages=" - -# Needed for project infrastructure -bash -git -make -nodejs -python3-pip -yarn - -# Handy utilities -bsdmainutils -curl -emacs-nox -git -htop -jq -lsof -make -man-db -nano -sudo -tmux -vim -wget - -# Ada -gnat - -# Algol -algol68g - -# ARM -gcc-arm-linux-gnueabihf -qemu-user-static - -# ATS -ats2-lang - -# BASIC -bwbasic - -# Bash -bash - -# BrainF -beef - -# C/C++ -clang - -# C# -mono-mcs - -# Clojure -clojure - -# Cmd -wine -wine32 - -# COBOL -gnucobol - -# Common Lisp -rlwrap -sbcl - -# Crystal -crystal - -# Dart -dart - -# Elixir -elixir - -# Elvish -elvish - -# Emacs Lisp -emacs-nox - -# Erlang -erlang - -# F# -fsharp - -# Fish -fish - -# FORTRAN -flang-7 - -# Forth -gforth - -# Go -golang - -# Groovy -groovy - -# Haskell -cabal-install -ghc - -# INTERCAL -intercal - -# Java -default-jdk - -# Julia -julia - -# Kalyn -haskell-stack - -# Ksh -ksh - -# LOLCODE -cmake - -# Lua -lua5.3 - -# MIPS -gcc-mips64-linux-gnuabi64 -qemu-user-static - -# MUMPS -fis-gtm - -# Nim -nim - -# Node.js -nodejs -yarn - -# Objective-C -gcc -gnustep-devel - -# Octave -octave - -# Pascal -fpc - -# Perl -perl -perlconsole - -# PHP -php - -# Prolog -swi-prolog - -# Python -python3 -python3-pip -python3-venv - -# R -r-base - -# Racket -racket - -# RISC-V -gcc-riscv64-linux-gnu -qemu-user-static - -# Ruby -ruby - -# Rust -rustc - -# Scala -scala - -# Scheme -mit-scheme - -# Sh -posh - -# Smalltalk -gnu-smalltalk - -# SNOBOL -m4 - -# SQLite -sqlite - -# Standard ML -rlwrap -smlnj - -# Swift -libpython2.7 - -# Tcl -tcl - -# Tcsh -tcsh - -# Unlambda -unlambda - -# Vimscript -vim - -# Visual Basic -mono-vbnc - -# Wolfram Language -python3.7 - -# x86 -clang - -# Zsh -zsh - -" - -export DEBIAN_FRONTEND=noninteractive -apt-get update -apt-get install -y $(grep -v "^#" <<< "$packages") -rm -rf /var/lib/apt/lists/* - -npm config set unsafe-perm true - -# Befunge -npm install -g befunge93 prompt-sync - -# ClojureScript -npm install -g lumo-cljs - -# CoffeeScript -npm install -g coffeescript - -# Elm -npm install -g @kachkaev/run-elm - -# Perl -cpan Devel::REPL - -# ReasonML -npm install -g bs-platform - -# Shakespeare -pip3 install shakespearelang - -# TypeScript -npm install -g ts-node typescript - -# Whitespace -pip3 install whitespace - -# Wolfram Language -python3.7 -m pip install mathics - # Needed for project infrastructure cd /tmp wget -nv https://github.com/watchexec/watchexec/releases/download/1.13.1/watchexec-1.13.1-x86_64-unknown-linux-gnu.deb @@ -403,13 +95,6 @@ git clone https://github.com/bipinu/malbolge.git clang malbolge/malbolge.c -o /usr/bin/malbolge rm -rf malbolge -# ActionScript -tee /usr/bin/amxmlc >/dev/null <<"EOF" -#!/bin/sh -exec /opt/actionscript/bin/amxmlc "$@" -EOF -chmod +x /usr/bin/amxmlc - # Befunge tee /usr/bin/befunge-repl >/dev/null <<"EOF" #!/usr/bin/env -S NODE_PATH=/usr/lib/node_modules node @@ -531,15 +216,4 @@ while True: EOF chmod +x /usr/bin/unlambda-repl -if (( "$uid" != 0 )); then - useradd --uid="$uid" --create-home --groups sudo docker - passwd -d docker -else - useradd --create-home --groups sudo docker - passwd -d docker -fi - -touch /home/docker/.zshrc -chown docker:docker /home/docker/.zshrc - rm "$0" diff --git a/scripts/docker-install-phase6.bash b/scripts/docker-install-phase6.bash new file mode 100644 index 0000000..83c3efb --- /dev/null +++ b/scripts/docker-install-phase6.bash @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +uid="$1" + +if [[ -n "$uid" ]] && (( "$uid" != 0 )); then + useradd --uid="$uid" --create-home --groups sudo docker + passwd -d docker +else + useradd --create-home --groups sudo docker + passwd -d docker +fi + +touch /home/docker/.zshrc +chown docker:docker /home/docker/.zshrc + +rm "$0" From 5883cc67c7412c377ced5601cdd3137c1f3936a8 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Wed, 10 Jun 2020 21:14:50 -0600 Subject: [PATCH 049/388] Prepare new deployment infrastructure --- .circleci/config.yml | 8 ++---- frontend/pages/index.ejs | 2 +- scripts/certbot-post.bash | 6 ++++ scripts/certbot-post.sh | 3 -- scripts/certbot-pre.bash | 6 ++++ scripts/certbot-pre.sh | 3 -- scripts/deploy.bash | 18 ++++++++++++ scripts/docker-install-phase6.bash | 0 scripts/install.py | 45 ++++++++++++++++++++++++++++++ scripts/riju.service | 2 +- 10 files changed, 80 insertions(+), 13 deletions(-) create mode 100755 scripts/certbot-post.bash delete mode 100755 scripts/certbot-post.sh create mode 100755 scripts/certbot-pre.bash delete mode 100755 scripts/certbot-pre.sh create mode 100755 scripts/deploy.bash mode change 100644 => 100755 scripts/docker-install-phase6.bash create mode 100755 scripts/install.py diff --git a/.circleci/config.yml b/.circleci/config.yml index 92ad620..c4e90f3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,13 +2,11 @@ version: 2 jobs: build_and_deploy: docker: - - image: docker:18.09 + - image: alpine steps: - checkout - - setup_remote_docker - - run: apk add --no-cache --no-progress bash curl make nodejs - - run: curl https://cli-assets.heroku.com/install.sh | sh - - run: make deploy + - run: apk add --no-cache --no-progress bash openssh + - run: scripts/deploy.bash workflows: version: 2 ci: diff --git a/frontend/pages/index.ejs b/frontend/pages/index.ejs index e5a2544..e32c189 100644 --- a/frontend/pages/index.ejs +++ b/frontend/pages/index.ejs @@ -6,7 +6,7 @@ -

Riju: online playground for every programming language

+

Riju: fast online playground for every programming language

Pick your favorite language to get started:
<% for (const [id, {name}] of Object.entries(langs)) { %> diff --git a/scripts/certbot-post.bash b/scripts/certbot-post.bash new file mode 100755 index 0000000..a151447 --- /dev/null +++ b/scripts/certbot-post.bash @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +systemctl start riju diff --git a/scripts/certbot-post.sh b/scripts/certbot-post.sh deleted file mode 100755 index 85c2533..0000000 --- a/scripts/certbot-post.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -systemctl start riju diff --git a/scripts/certbot-pre.bash b/scripts/certbot-pre.bash new file mode 100755 index 0000000..5bd2098 --- /dev/null +++ b/scripts/certbot-pre.bash @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +systemctl stop riju diff --git a/scripts/certbot-pre.sh b/scripts/certbot-pre.sh deleted file mode 100755 index fdc7e0e..0000000 --- a/scripts/certbot-pre.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -systemctl stop riju diff --git a/scripts/deploy.bash b/scripts/deploy.bash new file mode 100755 index 0000000..2011095 --- /dev/null +++ b/scripts/deploy.bash @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +tmpdir="$(mktemp -d)" +keyfile="${tmpdir}/id" + +if [[ -n "$DEPLOY_KEY" ]]; then + printf '%s\n' "$DEPLOY_KEY" | base64 -d > "$keyfile" +elif [[ -f "$HOME/.ssh/id_rsa_riju_deploy" ]]; then + cp "$HOME/.ssh/id_rsa_riju_deploy" "$keyfile" +else + echo 'deploy.bash: you must set $DEPLOY_KEY' >&2 + exit 1 +fi + +ssh -o IdentitiesOnly=yes -i "${keyfile}" deploy@209.141.54.122 /usr/bin/riju-install diff --git a/scripts/docker-install-phase6.bash b/scripts/docker-install-phase6.bash old mode 100644 new mode 100755 diff --git a/scripts/install.py b/scripts/install.py new file mode 100755 index 0000000..e776d5d --- /dev/null +++ b/scripts/install.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 + +import argparse +import errno +import os +import re +import signal +import subprocess +import sys +import tempfile +import time + +for pid in ( + subprocess.run(["pgrep", "-x", "riju-install"], check=True, stdout=subprocess.PIPE) + .stdout.decode() + .splitlines() +): + print(f"Found existing process {pid}, trying to kill ...", file=sys.stderr) + pid = int(pid) + os.kill(pid, signal.SIGTERM) + while True: + time.sleep(0.01) + try: + os.kill(pid, 0) + except OSError as e: + if e.errno == errno.ESRCH: + break + +with tempfile.TemporaryDirectory() as tmpdir: + os.chdir(tmpdir.name) + subprocess.run( + [ + "git", + "clone", + "https://github.com/raxod502/riju.git", + "--single-branch", + "--depth=1", + "--no-tags", + ], + check=True, + ) + os.chdir("riju") + subprocess.run(["make", "image-prod"], check=True) + subprocess.run(["docker", "system", "prune", "-f"], check=True) + subprocess.run(["systemctl", "restart", "riju"], check=True) diff --git a/scripts/riju.service b/scripts/riju.service index 67fe9ab..3ba25a9 100644 --- a/scripts/riju.service +++ b/scripts/riju.service @@ -2,7 +2,7 @@ Description=Riju online coding sandbox [Service] -ExecStart=docker run -p 0.0.0.0:6119 riju +ExecStart=docker run --rm -p 0.0.0.0:80:6119 riju:prod [Install] WantedBy=multi-user.target From 96575f71e9699fdc3de807dee3fda75724e6a497 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Thu, 11 Jun 2020 09:45:39 -0600 Subject: [PATCH 050/388] Update IP address --- scripts/deploy.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/deploy.bash b/scripts/deploy.bash index 2011095..500c756 100755 --- a/scripts/deploy.bash +++ b/scripts/deploy.bash @@ -15,4 +15,4 @@ else exit 1 fi -ssh -o IdentitiesOnly=yes -i "${keyfile}" deploy@209.141.54.122 /usr/bin/riju-install +ssh -o IdentitiesOnly=yes -i "${keyfile}" deploy@209.141.40.107 /usr/bin/riju-install From b3430a2f2c30dd135ab0f2ee85d5c2509df5ac8a Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Thu, 11 Jun 2020 10:45:43 -0600 Subject: [PATCH 051/388] Disable host key checking, upgrade Stack For some reason Ubuntu ships a super old version which doesn't even work because of a bug that was fixed a long time ago?? Thanks guys... --- scripts/deploy.bash | 3 ++- scripts/docker-install-phase3b.bash | 3 --- scripts/docker-install-phase5.bash | 6 ++++++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/scripts/deploy.bash b/scripts/deploy.bash index 500c756..7763808 100755 --- a/scripts/deploy.bash +++ b/scripts/deploy.bash @@ -15,4 +15,5 @@ else exit 1 fi -ssh -o IdentitiesOnly=yes -i "${keyfile}" deploy@209.141.40.107 /usr/bin/riju-install +ssh -o IdentitiesOnly=yes -o StrictHostKeyChecking=no \ + -i "${keyfile}" deploy@209.141.40.107 /usr/bin/riju-install diff --git a/scripts/docker-install-phase3b.bash b/scripts/docker-install-phase3b.bash index 38303f3..b4ced0b 100755 --- a/scripts/docker-install-phase3b.bash +++ b/scripts/docker-install-phase3b.bash @@ -48,9 +48,6 @@ default-jdk # Julia julia -# Kalyn -haskell-stack - # Ksh ksh diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index 62fab91..5bce5c1 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -13,6 +13,12 @@ cd /tmp git clone https://github.com/circulosmeos/gdown.pl.git mv gdown.pl/gdown.pl /usr/bin/gdown +cd /tmp +wget https://get.haskellstack.org/stable/linux-x86_64-static.tar.gz +tar -xf linux-x86_64-static.tar.gz +mv stack-*-linux-x86_64-static/stack /usr/bin/stack +rm -rf stack-*-linux-x86_64-static linux-x86_64-static.tar.gz + # D cd /tmp wget -nv http://downloads.dlang.org/releases/2.x/2.092.0/dmd_2.092.0-0_amd64.deb From 4ea197cabe64b89dbcfe168d773fc0d342c9719a Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Thu, 11 Jun 2020 13:57:36 -0600 Subject: [PATCH 052/388] Get TLS cert&key inside container, fix SSH options --- backend/src/server.ts | 8 ++++++-- scripts/deploy.bash | 6 +++++- scripts/riju-serve.bash | 14 ++++++++++++++ scripts/riju.service | 2 +- 4 files changed, 26 insertions(+), 4 deletions(-) create mode 100755 scripts/riju-serve.bash diff --git a/backend/src/server.ts b/backend/src/server.ts index 408a52c..0cb1a08 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -70,8 +70,12 @@ app.ws("/api/v1/ws", (ws, req) => { const secureApp = useTLS ? https.createServer( { - key: fs.readFileSync("/etc/letsencrypt/live/riju.codes/privkey.pem"), - cert: fs.readFileSync("/etc/letsencrypt/live/riju.codes/fullchain.pem"), + key: Buffer.from(process.env.TLS_PRIVATE_KEY, "base64").toString( + "ascii" + ), + cert: Buffer.from(process.env.TLS_CERTIFICATE, "base64").toString( + "ascii" + ), }, app ) diff --git a/scripts/deploy.bash b/scripts/deploy.bash index 7763808..0752b56 100755 --- a/scripts/deploy.bash +++ b/scripts/deploy.bash @@ -15,5 +15,9 @@ else exit 1 fi -ssh -o IdentitiesOnly=yes -o StrictHostKeyChecking=no \ +chmod go-rw "$keyfile" +ssh -o IdentitiesOnly=yes \ + -o StrictHostKeyChecking=no \ + -o UserKnownHostsFile=/dev/null \ + -o LogLevel=QUIET \ -i "${keyfile}" deploy@209.141.40.107 /usr/bin/riju-install diff --git a/scripts/riju-serve.bash b/scripts/riju-serve.bash new file mode 100755 index 0000000..13f0a9e --- /dev/null +++ b/scripts/riju-serve.bash @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +TLS=1 +TLS_PRIVATE_KEY="$(base64 -d /etc/letsencrypt/live/riju.codes/privkey.pem)" +TLS_CERTIFICATE="$(base64 -d /etc/letsencrypt/live/riju.codes/fullchain.pem)" + +# Do this separately so that errors in command substitution will crash +# the script. +export TLS TLS_PRIVATE_KEY TLS_CERTIFICATE + +docker run --rm -p 0.0.0.0:80:6119 riju:prod diff --git a/scripts/riju.service b/scripts/riju.service index 3ba25a9..7c20330 100644 --- a/scripts/riju.service +++ b/scripts/riju.service @@ -2,7 +2,7 @@ Description=Riju online coding sandbox [Service] -ExecStart=docker run --rm -p 0.0.0.0:80:6119 riju:prod +ExecStart=riju-serve [Install] WantedBy=multi-user.target From 66fea5be40533d337da52a72d65621cd10fa25c2 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Thu, 11 Jun 2020 14:41:42 -0600 Subject: [PATCH 053/388] Misc fixups for production setup --- Dockerfile.dev | 1 + Dockerfile.prod | 3 ++- Makefile | 2 +- backend/src/server.ts | 38 +++++++++++++++++++++++--------------- scripts/install.py | 10 +++++----- scripts/riju-serve.bash | 7 ++++--- 6 files changed, 36 insertions(+), 25 deletions(-) diff --git a/Dockerfile.dev b/Dockerfile.dev index aa2536a..db554bb 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -32,6 +32,7 @@ RUN /tmp/docker-install-phase6.bash "$UID" USER docker WORKDIR /home/docker EXPOSE 6119 +EXPOSE 6120 ENTRYPOINT ["/usr/local/bin/pid1.bash"] COPY scripts/pid1.bash /usr/local/bin/ diff --git a/Dockerfile.prod b/Dockerfile.prod index 4f260f1..ce45293 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -34,12 +34,13 @@ RUN /tmp/docker-install-phase6.bash USER docker WORKDIR /home/docker EXPOSE 6119 +EXPOSE 6120 ENTRYPOINT ["/usr/local/bin/pid1.bash"] COPY scripts/pid1.bash /usr/local/bin/ RUN sudo deluser docker sudo -ADD --chown=docker:docker . /home/docker/src +COPY --chown=docker:docker . /home/docker/src WORKDIR /home/docker/src RUN yarn install RUN yarn run backend diff --git a/Makefile b/Makefile index b820880..261f45b 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ image-prod: ## Build Docker image for production .PHONY: docker docker: image-dev ## Run shell with source code and deps inside Docker - scripts/docker.bash run -it --rm -v "$(PWD):/home/docker/src" -p 6119:6119 riju bash + scripts/docker.bash run -it --rm -v "$(PWD):/home/docker/src" -p 6119:6119 -p 6120:6120 riju bash .PHONY: deploy deploy: image-prod ## Deploy to Heroku diff --git a/backend/src/server.ts b/backend/src/server.ts index 0cb1a08..b71a093 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -1,6 +1,6 @@ "use strict"; -import * as fs from "fs"; +import * as http from "http"; import * as https from "https"; import * as appRoot from "app-root-path"; @@ -13,6 +13,7 @@ import { langs } from "./langs"; const host = process.env.HOST || "localhost"; const port = parseInt(process.env.PORT) || 6119; +const tlsPort = parseInt(process.env.TLS_PORT) || 6120; const useTLS = process.env.TLS ? true : false; const app = ws(express()).app; @@ -26,13 +27,6 @@ function getQueryParams(req: Request): URLSearchParams { return (req.query as unknown) as URLSearchParams; } -app.use((req, res, next) => { - if (useTLS && req.headers["x-forwarded-proto"] !== "https") { - res.redirect(301, "https://" + req.hostname + req.originalUrl); - } else { - next(); - } -}); app.get("/", (_, res) => { res.render(appRoot.path + "/frontend/pages/index", { langs }); }); @@ -67,8 +61,9 @@ app.ws("/api/v1/ws", (ws, req) => { } }); -const secureApp = useTLS - ? https.createServer( +if (useTLS) { + https + .createServer( { key: Buffer.from(process.env.TLS_PRIVATE_KEY, "base64").toString( "ascii" @@ -79,8 +74,21 @@ const secureApp = useTLS }, app ) - : app; - -secureApp.listen(port, host, () => - console.log(`Listening on http://${host}:${port}`) -); + .listen(tlsPort, host, () => + console.log(`Listening on https://${host}:${tlsPort}`) + ); + http + .createServer((req, res) => { + res.writeHead(301, { + Location: "https://" + req.headers["host"] + req.url, + }); + res.end(); + }) + .listen(port, host, () => + console.log(`Listening on http://${host}:${port}`) + ); +} else { + app.listen(port, host, () => + console.log(`Listening on http://${host}:${port}`) + ); +} diff --git a/scripts/install.py b/scripts/install.py index e776d5d..a517979 100755 --- a/scripts/install.py +++ b/scripts/install.py @@ -10,11 +10,11 @@ import sys import tempfile import time -for pid in ( - subprocess.run(["pgrep", "-x", "riju-install"], check=True, stdout=subprocess.PIPE) - .stdout.decode() - .splitlines() -): +result = subprocess.run( + ["pgrep", "-x", "riju-install"], check=True, stdout=subprocess.PIPE +) +assert result.returncode in {0, 1} +for pid in result.stdout.decode().splitlines(): print(f"Found existing process {pid}, trying to kill ...", file=sys.stderr) pid = int(pid) os.kill(pid, signal.SIGTERM) diff --git a/scripts/riju-serve.bash b/scripts/riju-serve.bash index 13f0a9e..15269dd 100755 --- a/scripts/riju-serve.bash +++ b/scripts/riju-serve.bash @@ -4,11 +4,12 @@ set -e set -o pipefail TLS=1 -TLS_PRIVATE_KEY="$(base64 -d /etc/letsencrypt/live/riju.codes/privkey.pem)" -TLS_CERTIFICATE="$(base64 -d /etc/letsencrypt/live/riju.codes/fullchain.pem)" +TLS_PRIVATE_KEY="$(base64 /etc/letsencrypt/live/riju.codes/privkey.pem)" +TLS_CERTIFICATE="$(base64 /etc/letsencrypt/live/riju.codes/fullchain.pem)" # Do this separately so that errors in command substitution will crash # the script. export TLS TLS_PRIVATE_KEY TLS_CERTIFICATE -docker run --rm -p 0.0.0.0:80:6119 riju:prod +docker run -e TLS -e TLS_PRIVATE_KEY -e TLS_CERTIFICATE \ + --rm -p 0.0.0.0:80:6119 -p 0.0.0.0:443:6120 riju:prod From db89ef25d90ca60ce9a631f4afc6a07f399814d2 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Thu, 11 Jun 2020 14:44:24 -0600 Subject: [PATCH 054/388] Handle return code correctly --- scripts/install.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/scripts/install.py b/scripts/install.py index a517979..67e55da 100755 --- a/scripts/install.py +++ b/scripts/install.py @@ -10,9 +10,7 @@ import sys import tempfile import time -result = subprocess.run( - ["pgrep", "-x", "riju-install"], check=True, stdout=subprocess.PIPE -) +result = subprocess.run(["pgrep", "-x", "riju-install"], stdout=subprocess.PIPE) assert result.returncode in {0, 1} for pid in result.stdout.decode().splitlines(): print(f"Found existing process {pid}, trying to kill ...", file=sys.stderr) From db6644d980f7428d29cc13d2bf98212edd7ccccc Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Thu, 11 Jun 2020 14:54:08 -0600 Subject: [PATCH 055/388] Automatically update installed scripts --- scripts/install-scripts.bash | 13 +++++++++++++ scripts/install.py | 1 + 2 files changed, 14 insertions(+) create mode 100755 scripts/install-scripts.bash diff --git a/scripts/install-scripts.bash b/scripts/install-scripts.bash new file mode 100755 index 0000000..0474625 --- /dev/null +++ b/scripts/install-scripts.bash @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +cp scripts/riju.service /etc/systemd/system/riju.service +cp scripts/certbot-pre.bash /etc/letsencrypt/renewal-hooks/pre/riju +cp scripts/certbot-post.bash /etc/letsencrypt/renewal-hooks/post/riju +cp scripts/install.py /usr/bin/riju-install +chgrp deploy /usr/bin/riju-install +chmod u=rwxs,g=rx,o= /usr/bin/riju-install + +systemctl daemon-reload diff --git a/scripts/install.py b/scripts/install.py index 67e55da..e18ba03 100755 --- a/scripts/install.py +++ b/scripts/install.py @@ -39,5 +39,6 @@ with tempfile.TemporaryDirectory() as tmpdir: ) os.chdir("riju") subprocess.run(["make", "image-prod"], check=True) + subprocess.run(["scripts/install-scripts.bash"], check=True) subprocess.run(["docker", "system", "prune", "-f"], check=True) subprocess.run(["systemctl", "restart", "riju"], check=True) From 1fe7d174a0344353d68f1be56ed57af46bca54e8 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Thu, 11 Jun 2020 14:58:17 -0600 Subject: [PATCH 056/388] Further corrections --- Makefile | 7 ++----- scripts/install.py | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 261f45b..2a7ef42 100644 --- a/Makefile +++ b/Makefile @@ -21,8 +21,5 @@ docker: image-dev ## Run shell with source code and deps inside Docker scripts/docker.bash run -it --rm -v "$(PWD):/home/docker/src" -p 6119:6119 -p 6120:6120 riju bash .PHONY: deploy -deploy: image-prod ## Deploy to Heroku - scripts/docker.bash tag riju:prod registry.heroku.com/riju-sandbox/web - heroku auth:token | scripts/docker.bash login --username=_ --password-stdin registry.heroku.com - scripts/docker.bash push registry.heroku.com/riju-sandbox/web - heroku container:release web -a riju-sandbox +deploy: ## Deploy current master from GitHub to production + scripts/deploy.bash diff --git a/scripts/install.py b/scripts/install.py index e18ba03..5da8ab9 100755 --- a/scripts/install.py +++ b/scripts/install.py @@ -25,7 +25,7 @@ for pid in result.stdout.decode().splitlines(): break with tempfile.TemporaryDirectory() as tmpdir: - os.chdir(tmpdir.name) + os.chdir(tmpdir) subprocess.run( [ "git", From 8246ab32d0b4435f234c81eb93c89374f17493a7 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Thu, 11 Jun 2020 15:06:26 -0600 Subject: [PATCH 057/388] Fix setuid bit on riju-install --- scripts/install-scripts.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/install-scripts.bash b/scripts/install-scripts.bash index 0474625..d97e6af 100755 --- a/scripts/install-scripts.bash +++ b/scripts/install-scripts.bash @@ -8,6 +8,6 @@ cp scripts/certbot-pre.bash /etc/letsencrypt/renewal-hooks/pre/riju cp scripts/certbot-post.bash /etc/letsencrypt/renewal-hooks/post/riju cp scripts/install.py /usr/bin/riju-install chgrp deploy /usr/bin/riju-install -chmod u=rwxs,g=rx,o= /usr/bin/riju-install +chmod u=rwxs,g=rxs,o= /usr/bin/riju-install systemctl daemon-reload From f15cd4f3cfa5a0cbc9c825cd8fcd5fd4a2555e9c Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Thu, 11 Jun 2020 15:22:59 -0600 Subject: [PATCH 058/388] Don't use setuid, it doesn't work --- scripts/deploy.bash | 2 +- scripts/install-scripts.bash | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/scripts/deploy.bash b/scripts/deploy.bash index 0752b56..78fe5de 100755 --- a/scripts/deploy.bash +++ b/scripts/deploy.bash @@ -20,4 +20,4 @@ ssh -o IdentitiesOnly=yes \ -o StrictHostKeyChecking=no \ -o UserKnownHostsFile=/dev/null \ -o LogLevel=QUIET \ - -i "${keyfile}" deploy@209.141.40.107 /usr/bin/riju-install + -i "${keyfile}" deploy@209.141.40.107 diff --git a/scripts/install-scripts.bash b/scripts/install-scripts.bash index d97e6af..4c3e6c9 100755 --- a/scripts/install-scripts.bash +++ b/scripts/install-scripts.bash @@ -7,7 +7,5 @@ cp scripts/riju.service /etc/systemd/system/riju.service cp scripts/certbot-pre.bash /etc/letsencrypt/renewal-hooks/pre/riju cp scripts/certbot-post.bash /etc/letsencrypt/renewal-hooks/post/riju cp scripts/install.py /usr/bin/riju-install -chgrp deploy /usr/bin/riju-install -chmod u=rwxs,g=rxs,o= /usr/bin/riju-install systemctl daemon-reload From 92831f5f51e1427e1709239abfe608811cc7955a Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Thu, 11 Jun 2020 17:48:13 -0600 Subject: [PATCH 059/388] Log on successful deploy --- scripts/install.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/install.py b/scripts/install.py index 5da8ab9..389959f 100755 --- a/scripts/install.py +++ b/scripts/install.py @@ -42,3 +42,5 @@ with tempfile.TemporaryDirectory() as tmpdir: subprocess.run(["scripts/install-scripts.bash"], check=True) subprocess.run(["docker", "system", "prune", "-f"], check=True) subprocess.run(["systemctl", "restart", "riju"], check=True) + +print("==> Successfully deployed Riju! <==", file=sys.stderr) From 466f897c58e5cb93e1bab339c3c0a6358b57ab0a Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Thu, 11 Jun 2020 17:54:12 -0600 Subject: [PATCH 060/388] Attempt to make websocket compatible with TLS --- backend/src/server.ts | 60 ++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/backend/src/server.ts b/backend/src/server.ts index b71a093..6d900c1 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -16,7 +16,7 @@ const port = parseInt(process.env.PORT) || 6119; const tlsPort = parseInt(process.env.TLS_PORT) || 6120; const useTLS = process.env.TLS ? true : false; -const app = ws(express()).app; +const app = express(); app.set("query parser", (qs: string) => new URLSearchParams(qs)); app.set("view engine", "ejs"); @@ -41,29 +41,37 @@ app.get("/:lang", (req, res) => { }); app.use("/css", express.static(appRoot.path + "/frontend/styles")); app.use("/js", express.static(appRoot.path + "/frontend/out")); -app.ws("/api/v1/ws", (ws, req) => { - const lang = getQueryParams(req).get("lang"); - if (!lang) { - ws.send( - JSON.stringify({ event: "error", errorMessage: "No language specified" }) - ); - ws.close(); - } else if (!langs[lang]) { - ws.send( - JSON.stringify({ - event: "error", - errorMessage: `No such language: ${lang}`, - }) - ); - ws.close(); - } else { - new api.Session(ws, getQueryParams(req).get("lang")); - } -}); + +function addWebsocket(baseApp) { + const app = ws(baseApp).app; + app.ws("/api/v1/ws", (ws, req) => { + const lang = getQueryParams(req).get("lang"); + if (!lang) { + ws.send( + JSON.stringify({ + event: "error", + errorMessage: "No language specified", + }) + ); + ws.close(); + } else if (!langs[lang]) { + ws.send( + JSON.stringify({ + event: "error", + errorMessage: `No such language: ${lang}`, + }) + ); + ws.close(); + } else { + new api.Session(ws, getQueryParams(req).get("lang")); + } + }); + return app; +} if (useTLS) { - https - .createServer( + addWebsocket( + https.createServer( { key: Buffer.from(process.env.TLS_PRIVATE_KEY, "base64").toString( "ascii" @@ -74,9 +82,9 @@ if (useTLS) { }, app ) - .listen(tlsPort, host, () => - console.log(`Listening on https://${host}:${tlsPort}`) - ); + ).listen(tlsPort, host, () => + console.log(`Listening on https://${host}:${tlsPort}`) + ); http .createServer((req, res) => { res.writeHead(301, { @@ -88,7 +96,7 @@ if (useTLS) { console.log(`Listening on http://${host}:${port}`) ); } else { - app.listen(port, host, () => + addWebsocket(app).listen(port, host, () => console.log(`Listening on http://${host}:${port}`) ); } From ba84695d13c3d4ccaa489b7c690a91fe3ec6497e Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Thu, 11 Jun 2020 18:15:29 -0600 Subject: [PATCH 061/388] Better attempt for websocket/TLS compatibility --- backend/src/server.ts | 31 +++++++++++++++---------------- scripts/install.py | 5 +++++ 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/backend/src/server.ts b/backend/src/server.ts index 6d900c1..d5d70bb 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -42,8 +42,8 @@ app.get("/:lang", (req, res) => { app.use("/css", express.static(appRoot.path + "/frontend/styles")); app.use("/js", express.static(appRoot.path + "/frontend/out")); -function addWebsocket(baseApp) { - const app = ws(baseApp).app; +function addWebsocket(baseApp: express.Express, httpsServer: https.Server) { + const app = ws(baseApp, httpsServer).app; app.ws("/api/v1/ws", (ws, req) => { const lang = getQueryParams(req).get("lang"); if (!lang) { @@ -70,19 +70,17 @@ function addWebsocket(baseApp) { } if (useTLS) { - addWebsocket( - https.createServer( - { - key: Buffer.from(process.env.TLS_PRIVATE_KEY, "base64").toString( - "ascii" - ), - cert: Buffer.from(process.env.TLS_CERTIFICATE, "base64").toString( - "ascii" - ), - }, - app - ) - ).listen(tlsPort, host, () => + const httpsServer = https.createServer( + { + key: Buffer.from(process.env.TLS_PRIVATE_KEY, "base64").toString("ascii"), + cert: Buffer.from(process.env.TLS_CERTIFICATE, "base64").toString( + "ascii" + ), + }, + app + ); + addWebsocket(app, httpsServer); + httpsServer.listen(tlsPort, host, () => console.log(`Listening on https://${host}:${tlsPort}`) ); http @@ -96,7 +94,8 @@ if (useTLS) { console.log(`Listening on http://${host}:${port}`) ); } else { - addWebsocket(app).listen(port, host, () => + addWebsocket(app, undefined); + app.listen(port, host, () => console.log(`Listening on http://${host}:${port}`) ); } diff --git a/scripts/install.py b/scripts/install.py index 389959f..4c0ec75 100755 --- a/scripts/install.py +++ b/scripts/install.py @@ -41,6 +41,11 @@ with tempfile.TemporaryDirectory() as tmpdir: subprocess.run(["make", "image-prod"], check=True) subprocess.run(["scripts/install-scripts.bash"], check=True) subprocess.run(["docker", "system", "prune", "-f"], check=True) + existing_containers = subprocess.run( + ["docker", "ps", "-q"], check=True, stdout=subprocess.PIPE + ).output.splitlines() + if existing_containers: + subprocess.run(["docker", "kill", *existing_containers], check=True) subprocess.run(["systemctl", "restart", "riju"], check=True) print("==> Successfully deployed Riju! <==", file=sys.stderr) From 0a05a0eb92b5f265ad2df6b432531001604b5215 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 12 Jun 2020 11:42:11 -0600 Subject: [PATCH 062/388] Load editor more quickly, add loading indicator --- backend/src/api.ts | 22 ---------------------- backend/src/server.ts | 2 +- frontend/pages/app.ejs | 7 +++++-- frontend/src/app.ts | 38 ++++++++++++-------------------------- 4 files changed, 18 insertions(+), 51 deletions(-) diff --git a/backend/src/api.ts b/backend/src/api.ts index e917c4b..5105cc8 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -21,28 +21,6 @@ export class Session { this.config = langs[lang]; this.term = { pty: null, live: false }; this.code = ""; - try { - this.ws.send( - JSON.stringify({ - event: "setMonacoLanguage", - monacoLanguage: this.config.monacoLang, - }) - ); - } catch (err) { - // - } - if (this.config.template) { - try { - this.ws.send( - JSON.stringify({ - event: "insertTemplate", - template: this.config.template, - }) - ); - } catch (err) { - // - } - } this.run().catch(console.error); ws.on("message", this.handleClientMessage); } diff --git a/backend/src/server.ts b/backend/src/server.ts index d5d70bb..5801027 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -33,7 +33,7 @@ app.get("/", (_, res) => { app.get("/:lang", (req, res) => { if (langs[req.params.lang]) { res.render(appRoot.path + "/frontend/pages/app", { - name: langs[req.params.lang].name, + config: { id: req.params.lang, ...langs[req.params.lang] }, }); } else { res.send(`No such language: ${req.params.lang}`); diff --git a/frontend/pages/app.ejs b/frontend/pages/app.ejs index 4b7849d..bc2e09a 100644 --- a/frontend/pages/app.ejs +++ b/frontend/pages/app.ejs @@ -2,7 +2,7 @@ - <%= name %> - Riju + <%= config.name %> - Riju - + + diff --git a/frontend/src/app.ts b/frontend/src/app.ts index 6bf6b89..e9a08ad 100644 --- a/frontend/src/app.ts +++ b/frontend/src/app.ts @@ -6,7 +6,13 @@ import { FitAddon } from "xterm-addon-fit"; import "xterm/css/xterm.css"; -const lang = document.location.pathname.slice(1); +interface RijuConfig { + id: string; + monacoLang: string; + template: string; +} + +const config: RijuConfig = (window as any).rijuConfig; const term = new Terminal(); const fitAddon = new FitAddon(); @@ -16,17 +22,17 @@ term.open(document.getElementById("terminal")); fitAddon.fit(); window.addEventListener("resize", () => fitAddon.fit()); +term.write("Connecting to server..."); + const initialRetryDelayMs = 200; let retryDelayMs = initialRetryDelayMs; -let allowInsertingTemplate = true; - function tryConnect() { console.log("Connecting to server..."); socket = new WebSocket( (document.location.protocol === "http:" ? "ws://" : "wss://") + document.location.host + - `/api/v1/ws?lang=${encodeURIComponent(lang)}` + `/api/v1/ws?lang=${encodeURIComponent(config.id)}` ); socket.addEventListener("open", () => { console.log("Successfully connected to server"); @@ -53,25 +59,6 @@ function tryConnect() { } term.write(message.output); return; - case "setMonacoLanguage": - if (typeof message.monacoLanguage !== "string") { - console.error("Unexpected message from server:", message); - return; - } - monaco.editor.setModelLanguage( - editor.getModel(), - message.monacoLanguage - ); - return; - case "insertTemplate": - if (typeof message.template !== "string") { - console.error("Unexpected message from server:", message); - return; - } - if (allowInsertingTemplate) { - editor.getModel().setValue(message.template); - } - return; default: console.error("Unexpected message from server:", message); return; @@ -106,9 +93,8 @@ const editor = monaco.editor.create(document.getElementById("editor"), { scrollbar: { verticalScrollbarSize: 0 }, }); window.addEventListener("resize", () => editor.layout()); -editor.onDidChangeModelContent(() => { - allowInsertingTemplate = false; -}); +editor.getModel().setValue(config.template); +monaco.editor.setModelLanguage(editor.getModel(), config.monacoLang); document.getElementById("runButton").addEventListener("click", () => { socket.send(JSON.stringify({ event: "runCode", code: editor.getValue() })); From a96ed753b21192bbaa0eb8611050baa2b55cdc40 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 12 Jun 2020 11:55:52 -0600 Subject: [PATCH 063/388] Improve deployment script --- scripts/{install.py => deploy-phase1.py} | 14 ++------------ scripts/deploy-phase2.py | 23 +++++++++++++++++++++++ scripts/install-scripts.bash | 2 +- 3 files changed, 26 insertions(+), 13 deletions(-) rename scripts/{install.py => deploy-phase1.py} (60%) create mode 100755 scripts/deploy-phase2.py diff --git a/scripts/install.py b/scripts/deploy-phase1.py similarity index 60% rename from scripts/install.py rename to scripts/deploy-phase1.py index 4c0ec75..832e2fa 100755 --- a/scripts/install.py +++ b/scripts/deploy-phase1.py @@ -10,7 +10,7 @@ import sys import tempfile import time -result = subprocess.run(["pgrep", "-x", "riju-install"], stdout=subprocess.PIPE) +result = subprocess.run(["pgrep", "-x", "riju-deploy"], stdout=subprocess.PIPE) assert result.returncode in {0, 1} for pid in result.stdout.decode().splitlines(): print(f"Found existing process {pid}, trying to kill ...", file=sys.stderr) @@ -38,14 +38,4 @@ with tempfile.TemporaryDirectory() as tmpdir: check=True, ) os.chdir("riju") - subprocess.run(["make", "image-prod"], check=True) - subprocess.run(["scripts/install-scripts.bash"], check=True) - subprocess.run(["docker", "system", "prune", "-f"], check=True) - existing_containers = subprocess.run( - ["docker", "ps", "-q"], check=True, stdout=subprocess.PIPE - ).output.splitlines() - if existing_containers: - subprocess.run(["docker", "kill", *existing_containers], check=True) - subprocess.run(["systemctl", "restart", "riju"], check=True) - -print("==> Successfully deployed Riju! <==", file=sys.stderr) + subprocess.run(["scripts/deploy-phase2.py"]) diff --git a/scripts/deploy-phase2.py b/scripts/deploy-phase2.py new file mode 100755 index 0000000..e161eff --- /dev/null +++ b/scripts/deploy-phase2.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python3 + +import argparse +import errno +import os +import re +import signal +import subprocess +import sys +import tempfile +import time + +subprocess.run(["make", "image-prod"], check=True) +subprocess.run(["docker", "system", "prune", "-f"], check=True) +existing_containers = subprocess.run( + ["docker", "ps", "-q"], check=True, stdout=subprocess.PIPE +).output.splitlines() +subprocess.run(["scripts/install-scripts.bash"], check=True) +if existing_containers: + subprocess.run(["docker", "kill", *existing_containers], check=True) +subprocess.run(["systemctl", "restart", "riju"], check=True) + +print("==> Successfully deployed Riju! <==", file=sys.stderr) diff --git a/scripts/install-scripts.bash b/scripts/install-scripts.bash index 4c3e6c9..c0e3154 100755 --- a/scripts/install-scripts.bash +++ b/scripts/install-scripts.bash @@ -6,6 +6,6 @@ set -o pipefail cp scripts/riju.service /etc/systemd/system/riju.service cp scripts/certbot-pre.bash /etc/letsencrypt/renewal-hooks/pre/riju cp scripts/certbot-post.bash /etc/letsencrypt/renewal-hooks/post/riju -cp scripts/install.py /usr/bin/riju-install +cp scripts/deploy-phase1.py /usr/bin/riju-deploy systemctl daemon-reload From 81278fa86b51b030465a90a0a9291864e946a1cf Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 12 Jun 2020 12:07:42 -0600 Subject: [PATCH 064/388] Various improvements for systemd --- scripts/install-scripts.bash | 1 + scripts/riju-serve.bash | 2 +- scripts/riju.service | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/install-scripts.bash b/scripts/install-scripts.bash index c0e3154..5f5c741 100755 --- a/scripts/install-scripts.bash +++ b/scripts/install-scripts.bash @@ -4,6 +4,7 @@ set -e set -o pipefail cp scripts/riju.service /etc/systemd/system/riju.service +cp scripts/riju-serve.bash /usr/bin/riju-serve cp scripts/certbot-pre.bash /etc/letsencrypt/renewal-hooks/pre/riju cp scripts/certbot-post.bash /etc/letsencrypt/renewal-hooks/post/riju cp scripts/deploy-phase1.py /usr/bin/riju-deploy diff --git a/scripts/riju-serve.bash b/scripts/riju-serve.bash index 15269dd..ff6630c 100755 --- a/scripts/riju-serve.bash +++ b/scripts/riju-serve.bash @@ -11,5 +11,5 @@ TLS_CERTIFICATE="$(base64 /etc/letsencrypt/live/riju.codes/fullchain.pem)" # the script. export TLS TLS_PRIVATE_KEY TLS_CERTIFICATE -docker run -e TLS -e TLS_PRIVATE_KEY -e TLS_CERTIFICATE \ +docker run -it -e TLS -e TLS_PRIVATE_KEY -e TLS_CERTIFICATE \ --rm -p 0.0.0.0:80:6119 -p 0.0.0.0:443:6120 riju:prod diff --git a/scripts/riju.service b/scripts/riju.service index 7c20330..2854d1f 100644 --- a/scripts/riju.service +++ b/scripts/riju.service @@ -1,8 +1,12 @@ [Unit] Description=Riju online coding sandbox +Requires=docker.service +After=docker.service [Service] +Type=exec ExecStart=riju-serve +Restart=always [Install] WantedBy=multi-user.target From 2df2132e2cc2cb89c957dfbb7b56c6255ee1f46a Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 12 Jun 2020 12:12:38 -0600 Subject: [PATCH 065/388] Fix usage of stdout --- scripts/deploy-phase2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/deploy-phase2.py b/scripts/deploy-phase2.py index e161eff..adbf088 100755 --- a/scripts/deploy-phase2.py +++ b/scripts/deploy-phase2.py @@ -14,7 +14,7 @@ subprocess.run(["make", "image-prod"], check=True) subprocess.run(["docker", "system", "prune", "-f"], check=True) existing_containers = subprocess.run( ["docker", "ps", "-q"], check=True, stdout=subprocess.PIPE -).output.splitlines() +).stdout.splitlines() subprocess.run(["scripts/install-scripts.bash"], check=True) if existing_containers: subprocess.run(["docker", "kill", *existing_containers], check=True) From d570a7f9e7ede698be374536e9e5dcab1b75e8d0 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 12 Jun 2020 12:22:18 -0600 Subject: [PATCH 066/388] Only -t is supported (this is not a complete fix) --- scripts/riju-serve.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/riju-serve.bash b/scripts/riju-serve.bash index ff6630c..fb06a66 100755 --- a/scripts/riju-serve.bash +++ b/scripts/riju-serve.bash @@ -11,5 +11,5 @@ TLS_CERTIFICATE="$(base64 /etc/letsencrypt/live/riju.codes/fullchain.pem)" # the script. export TLS TLS_PRIVATE_KEY TLS_CERTIFICATE -docker run -it -e TLS -e TLS_PRIVATE_KEY -e TLS_CERTIFICATE \ +docker run -t -e TLS -e TLS_PRIVATE_KEY -e TLS_CERTIFICATE \ --rm -p 0.0.0.0:80:6119 -p 0.0.0.0:443:6120 riju:prod From 406c64e68dfc856546b1917f9f1866af5873db93 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 12 Jun 2020 12:26:21 -0600 Subject: [PATCH 067/388] Optimize prod image build for Docker cache --- Dockerfile.prod | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Dockerfile.prod b/Dockerfile.prod index ce45293..1090cfa 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -40,9 +40,17 @@ ENTRYPOINT ["/usr/local/bin/pid1.bash"] COPY scripts/pid1.bash /usr/local/bin/ RUN sudo deluser docker sudo + +RUN mkdir /tmp/riju +COPY --chown=docker:docker package.json yarn.lock /tmp/riju/ +RUN cd /tmp/riju && yarn install +COPY --chown=docker:docker webpack.config.js tsconfig.json tsconfig-webpack.json /tmp/riju/ +COPY --chown=docker:docker frontend /tmp/riju/frontend +RUN cd /tmp/riju && yarn run frontend +COPY --chown=docker:docker backend /tmp/riju/backend +RUN cd /tmp/riju && yarn run backend COPY --chown=docker:docker . /home/docker/src +RUN cp -R /tmp/riju/* /home/docker/src/ && rm -rf /tmp/riju + WORKDIR /home/docker/src -RUN yarn install -RUN yarn run backend -RUN yarn run frontend CMD yarn run server From 144202adf1db8b251c8281f0807d69ac7947a7c9 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 12 Jun 2020 12:34:51 -0600 Subject: [PATCH 068/388] Make 'docker stop' work properly --- Dockerfile.dev | 2 +- Dockerfile.prod | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile.dev b/Dockerfile.dev index db554bb..fc15487 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -36,4 +36,4 @@ EXPOSE 6120 ENTRYPOINT ["/usr/local/bin/pid1.bash"] COPY scripts/pid1.bash /usr/local/bin/ -CMD bash +CMD ["bash"] diff --git a/Dockerfile.prod b/Dockerfile.prod index 1090cfa..277bb38 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -53,4 +53,4 @@ COPY --chown=docker:docker . /home/docker/src RUN cp -R /tmp/riju/* /home/docker/src/ && rm -rf /tmp/riju WORKDIR /home/docker/src -CMD yarn run server +CMD ["yarn", "run", "server"] From 74f6cf153cad1a05cbcfa00b01cc6a4070b81105 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 12 Jun 2020 12:45:34 -0600 Subject: [PATCH 069/388] Fix up riju-serve script for interactive use --- scripts/riju-serve.bash | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scripts/riju-serve.bash b/scripts/riju-serve.bash index fb06a66..13e4bb4 100755 --- a/scripts/riju-serve.bash +++ b/scripts/riju-serve.bash @@ -11,5 +11,11 @@ TLS_CERTIFICATE="$(base64 /etc/letsencrypt/live/riju.codes/fullchain.pem)" # the script. export TLS TLS_PRIVATE_KEY TLS_CERTIFICATE -docker run -t -e TLS -e TLS_PRIVATE_KEY -e TLS_CERTIFICATE \ +if [[ -t 1 ]]; then + it=-it +else + it= +fi + +docker run ${it} -e TLS -e TLS_PRIVATE_KEY -e TLS_CERTIFICATE \ --rm -p 0.0.0.0:80:6119 -p 0.0.0.0:443:6120 riju:prod From 75232829d6afebb982cd1ae1cff7ff17a40bffa2 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 12 Jun 2020 13:39:07 -0600 Subject: [PATCH 070/388] Migrate to DigitalOcean --- scripts/deploy.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/deploy.bash b/scripts/deploy.bash index 78fe5de..7dc7108 100755 --- a/scripts/deploy.bash +++ b/scripts/deploy.bash @@ -20,4 +20,4 @@ ssh -o IdentitiesOnly=yes \ -o StrictHostKeyChecking=no \ -o UserKnownHostsFile=/dev/null \ -o LogLevel=QUIET \ - -i "${keyfile}" deploy@209.141.40.107 + -i "${keyfile}" deploy@138.68.247.206 From 0dbb5610630711c00102ddf7ccff9f3c71330f33 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 12 Jun 2020 14:51:15 -0600 Subject: [PATCH 071/388] Add aliases, redirect to lowercase --- backend/src/langs.ts | 104 ++++++++++++++++++++++++++++++++++++++++++ backend/src/server.ts | 20 ++++++-- package.json | 2 + yarn.lock | 10 ++++ 4 files changed, 133 insertions(+), 3 deletions(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index a5309af..fcfd69a 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1,6 +1,7 @@ "use strict"; export interface LangConfig { + aliases?: string[]; name: string; monacoLang: string; repl?: string; @@ -15,6 +16,7 @@ export interface LangConfig { export const langs: { [key: string]: LangConfig } = { ada: { + aliases: ["adb"], name: "Ada", monacoLang: "plaintext", main: "main.adb", @@ -29,6 +31,7 @@ end Main; `, }, algol: { + aliases: ["alg"], name: "ALGOL 68", monacoLang: "plaintext", main: "main.alg", @@ -59,6 +62,7 @@ message: `, }, ats: { + aliases: ["dats"], name: "ATS", monacoLang: "postiats", main: "main.dats", @@ -69,6 +73,7 @@ implement main0 () = () `, }, bash: { + aliases: ["bashrc", "bourneshell"], name: "Bash", monacoLang: "shell", repl: "bash --rcfile /dev/null", @@ -78,6 +83,7 @@ implement main0 () = () `, }, basic: { + aliases: ["bas", "qbasic"], name: "BASIC", monacoLang: "plaintext", repl: "bwbasic", @@ -87,6 +93,7 @@ implement main0 () = () `, }, befunge: { + aliases: ["be"], name: "Befunge", monacoLang: "plaintext", main: "main.be", @@ -95,6 +102,7 @@ implement main0 () = () `, }, brainf: { + aliases: ["brainfuck", "bf"], name: "Brainf***", monacoLang: "plaintext", repl: "brainf-repl", @@ -131,6 +139,7 @@ implement main0 () = () `, }, c: { + aliases: ["gcc", "llvm", "clang", "h", "cc", "c99", "c11", "c18"], name: "C", monacoLang: "c", main: "main.c", @@ -145,6 +154,7 @@ int main() { `, }, cmd: { + aliases: ["bat", "batch", "wine"], name: "Cmd", monacoLang: "bat", repl: "wine cmd", @@ -154,6 +164,7 @@ int main() { `, }, commonlisp: { + aliases: ["lisp", "sbcl"], name: "Common Lisp", monacoLang: "plaintext", repl: "rlwrap sbcl", @@ -163,6 +174,26 @@ int main() { `, }, cpp: { + aliases: [ + "c++", + "g++", + "clang++", + "c++98", + "c++03", + "c++11", + "c++14", + "c++17", + "c++20", + "cpp98", + "cpp03", + "cpp11", + "cpp14", + "cpp17", + "cpp20", + "hpp", + "cxx", + "hxx", + ], name: "C++", monacoLang: "cpp", main: "main.cpp", @@ -177,6 +208,7 @@ int main() { `, }, crystal: { + aliases: ["cr"], name: "Crystal", monacoLang: "plaintext", main: "main.cr", @@ -185,6 +217,7 @@ int main() { `, }, csharp: { + aliases: ["cs", "mcs"], name: "C#", monacoLang: "csharp", main: "main.cs", @@ -198,6 +231,7 @@ int main() { `, }, clojure: { + aliases: ["clj"], name: "Clojure", monacoLang: "clojure", repl: "clojure", @@ -207,6 +241,7 @@ int main() { `, }, clojurescript: { + aliases: ["cljs", "lumo"], name: "ClojureScript", monacoLang: "clojure", repl: "lumo -r", @@ -216,6 +251,7 @@ int main() { `, }, cobol: { + aliases: ["cbl", "cobc"], name: "COBOL", monacoLang: "plaintext", main: "main.cbl", @@ -229,6 +265,7 @@ PROCEDURE DIVISION. `, }, coffeescript: { + aliases: ["coffee"], name: "CoffeeScript", monacoLang: "coffee", repl: "coffee", @@ -242,6 +279,7 @@ require("/usr/lib/node_modules/coffeescript/repl").start() `, }, d: { + aliases: ["dmd"], name: "D", monacoLang: "plaintext", main: "main.d", @@ -265,6 +303,7 @@ void main() { `, }, elixir: { + aliases: ["iex", "exs"], name: "Elixir", monacoLang: "plaintext", repl: "iex", @@ -286,6 +325,7 @@ output = "Hello, world!" `, }, elvish: { + aliases: ["elv"], name: "Elvish", monacoLang: "plaintext", repl: "SHELL=/usr/bin/elvish HOME=. elvish", @@ -295,6 +335,7 @@ output = "Hello, world!" `, }, emacs: { + aliases: ["emacslisp", "elisp", "gnuemacs", "xemacs", "ielm"], name: "Emacs Lisp", monacoLang: "plaintext", repl: "emacs --eval '(ielm)'", @@ -304,6 +345,7 @@ output = "Hello, world!" `, }, erlang: { + aliases: ["erl"], name: "Erlang", monacoLang: "plaintext", repl: "erl", @@ -327,6 +369,7 @@ main() -> `, }, forth: { + aliases: ["fs", "gforth"], name: "Forth", monacoLang: "plaintext", repl: "gforth", @@ -336,6 +379,15 @@ main() -> `, }, fortran: { + aliases: [ + "f", + "flang", + "fortran77", + "fortran90", + "fortran95", + "fortran2003", + "fortran2008", + ], name: "FORTRAN", monacoLang: "plaintext", main: "main.f", @@ -347,6 +399,7 @@ main() -> `, }, fsharp: { + aliases: ["fsharpi", "fsx", "fs"], name: "F#", monacoLang: "fsharp", repl: "fsharpi", @@ -356,6 +409,7 @@ main() -> `, }, go: { + aliases: ["golang"], name: "Go", monacoLang: "go", main: "main.go", @@ -380,6 +434,7 @@ func main() { `, }, haskell: { + aliases: ["ghc", "ghci", "hs"], name: "Haskell", monacoLang: "plaintext", repl: "ghci", @@ -407,6 +462,7 @@ log('Hello, world!') `, }, intercal: { + aliases: ["i", "ick"], name: "INTERCAL", monacoLang: "plaintext", main: "main.i", @@ -432,6 +488,7 @@ PLEASE GIVE UP `, }, java: { + aliases: ["javac"], name: "Java", monacoLang: "java", main: "Main.java", @@ -445,6 +502,7 @@ PLEASE GIVE UP `, }, julia: { + aliases: ["jl"], name: "Julia", monacoLang: "plaintext", repl: "julia", @@ -466,6 +524,7 @@ PLEASE GIVE UP `, }, kotlin: { + aliases: ["kts", "kotlinc"], name: "Kotlin", monacoLang: "kotlin", repl: "kotlinc", @@ -475,6 +534,7 @@ PLEASE GIVE UP `, }, ksh: { + aliases: ["kshell"], name: "Ksh", monacoLang: "shell", repl: "SHELL=/usr/bin/ksh HOME=. ksh", @@ -484,6 +544,7 @@ PLEASE GIVE UP `, }, lolcode: { + aliases: ["lol", "lci"], name: "LOLCODE", monacoLang: "plaintext", main: "main.lol", @@ -503,6 +564,7 @@ KTHXBYE `, }, malbolge: { + aliases: ["mb"], name: "Malbolge", monacoLang: "plaintext", main: "main.mb", @@ -511,6 +573,7 @@ KTHXBYE " (=<`#9]~6ZY32Vx/4Rs+0No-&Jk)\"Fh}|Bcy?`=*z]Kw%oG4UUS0/@-ejc(:'8dc\n", }, mips: { + aliases: ["mips64"], name: "MIPS", monacoLang: "mips", main: "main.S", @@ -533,6 +596,7 @@ message: `, }, mumps: { + aliases: ["mlang", "gtm", "fisgtm"], name: "MUMPS", monacoLang: "plaintext", main: "main.m", @@ -553,6 +617,7 @@ message: `, }, nodejs: { + aliases: ["node", "js", "javascript", "web", "jsx", "v8", "closure"], name: "Node.js", monacoLang: "javascript", repl: "node", @@ -565,6 +630,7 @@ require("repl").start() `, }, objectivec: { + aliases: ["objc", "gnustep"], name: "Objective-C", monacoLang: "objective-c", main: "main.m", @@ -582,6 +648,7 @@ int main() { `, }, octave: { + aliases: ["matlab", "m", "mathworks"], name: "Octave", monacoLang: "plaintext", repl: "octave", @@ -591,6 +658,7 @@ int main() { `, }, pascal: { + aliases: ["pas", "fpc"], name: "Pascal", monacoLang: "pascal", main: "main.pas", @@ -603,6 +671,7 @@ end. `, }, perl: { + aliases: ["pl", "repl"], name: "Perl", monacoLang: "perl", repl: "re.pl", @@ -612,6 +681,7 @@ end. `, }, php: { + aliases: ["phpcli"], name: "PHP", monacoLang: "php", repl: "php -a", @@ -623,6 +693,7 @@ echo "Hello, world!\\n"; `, }, powershell: { + aliases: ["pwsh", "ps1"], name: "PowerShell", monacoLang: "powershell", repl: "SHELL=/usr/bin/pwsh pwsh", @@ -644,6 +715,7 @@ main :- `, }, python: { + aliases: ["python3", "python2", "py"], name: "Python", monacoLang: "python", repl: "python3 -u", @@ -653,6 +725,7 @@ main :- `, }, r: { + aliases: ["rlang"], name: "R", monacoLang: "r", repl: "R", @@ -662,6 +735,7 @@ main :- `, }, racket: { + aliases: ["rkt"], name: "Racket", monacoLang: "plaintext", repl: "racket", @@ -672,6 +746,7 @@ main :- `, }, reasonml: { + aliases: ["re", "reason", "bsc", "buckle", "bucklescript"], name: "ReasonML", monacoLang: "plaintext", main: "main.re", @@ -681,6 +756,7 @@ main :- `, }, riscv: { + aliases: ["risc"], name: "RISC-V", monacoLang: "plaintext", main: "main.S", @@ -703,6 +779,7 @@ message: `, }, ruby: { + aliases: ["irb", "rb"], name: "Ruby", monacoLang: "ruby", repl: "irb", @@ -719,6 +796,7 @@ binding_irb.run(IRB.conf) `, }, rust: { + aliases: ["rs", "rustc"], name: "Rust", monacoLang: "rust", main: "main.rs", @@ -739,6 +817,7 @@ binding_irb.run(IRB.conf) `, }, scheme: { + aliases: ["scm", "mitscheme"], name: "Scheme", monacoLang: "scheme", repl: "mit-scheme", @@ -750,6 +829,7 @@ binding_irb.run(IRB.conf) `, }, sh: { + aliases: ["shell", "posix", "posixsh", "ash", "dash", "posh"], name: "Sh", monacoLang: "shell", repl: "SHELL=/usr/bin/sh HOME=. posh -l", @@ -759,6 +839,7 @@ binding_irb.run(IRB.conf) `, }, shakespeare: { + aliases: ["spl"], name: "Shakespeare", monacoLang: "plaintext", repl: "shakespeare console", @@ -857,6 +938,7 @@ Ophelia: `, }, smalltalk: { + aliases: ["gst", "st"], name: "Smalltalk", monacoLang: "plaintext", repl: "gst", @@ -866,6 +948,7 @@ Ophelia: `, }, snobol: { + aliases: ["snobol4", "spitbol", "sno"], name: "SNOBOL", monacoLang: "plaintext", repl: "snobol4", @@ -876,6 +959,7 @@ END `, }, sqlite: { + aliases: ["sql", "db", "sqlite3"], name: "SQLite", monacoLang: "sql", repl: "sqlite3", @@ -885,6 +969,7 @@ END `, }, standardml: { + aliases: ["sml", "ml"], name: "Standard ML", monacoLang: "plaintext", repl: "rlwrap sml", @@ -894,6 +979,7 @@ END `, }, swift: { + aliases: ["swiftc"], name: "Swift", monacoLang: "swift", main: "main.swift", @@ -903,6 +989,7 @@ END `, }, tcl: { + aliases: ["tclsh", "tclshrc"], name: "Tcl", monacoLang: "tcl", repl: "tclsh", @@ -912,6 +999,7 @@ END `, }, tcsh: { + aliases: ["tcshell", "tcshrc"], name: "Tcsh", monacoLang: "shell", repl: "SHELL=/usr/bin/tcsh HOME=. tcsh", @@ -921,6 +1009,7 @@ END `, }, typescript: { + aliases: ["ts", "tsnode", "tsc"], name: "TypeScript", monacoLang: "typescript", repl: "ts-node", @@ -930,6 +1019,7 @@ END `, }, unlambda: { + aliases: ["unl"], name: "Unlambda", monacoLang: "plaintext", repl: "unlambda-repl", @@ -938,6 +1028,7 @@ END template: "`.\n`.!`.d`.l`.r`.o`.w`. `.,`.o`.l`.l`.e`.Hi\n", }, vim: { + aliases: ["viml", "vimscript"], name: "Vimscript", monacoLang: "plaintext", repl: "vim", @@ -947,6 +1038,7 @@ END `, }, visualbasic: { + aliases: ["vbasic", "vb", "vbnc"], name: "Visual Basic", monacoLang: "vb", main: "main.vb", @@ -960,6 +1052,7 @@ End Module `, }, whitespace: { + aliases: ["ws"], name: "Whitespace", monacoLang: "plaintext", main: "main.ws", @@ -967,6 +1060,15 @@ End Module template: `Hello, world! \t \t \n\t\n \t\t \t \t\n\t\n \t\t \t\t \n\t\n \t\t \t\t \n\t\n \t\t \t\t\t\t\n\t\n \t \t\t \n\t\n \t \n\t\n \t\t\t \t\t\t\n\t\n \t\t \t\t\t\t\n\t\n \t\t\t \t \n\t\n \t\t \t\t \n\t\n \t\t \t \n\t\n \n\n\n`, }, wolframlanguage: { + aliases: [ + "wolfram", + "mathematica", + "mathics", + "wolframmathematica", + "wls", + "expreduce", + "symja", + ], name: "Wolfram Language", monacoLang: "plaintext", repl: "mathics", @@ -976,6 +1078,7 @@ End Module `, }, x86: { + aliases: ["s", "asm", "assembly", "x86-64"], name: "x86", monacoLang: "plaintext", main: "main.S", @@ -998,6 +1101,7 @@ message: `, }, zsh: { + aliases: ["zshell", "zshrc"], name: "Zsh", monacoLang: "shell", repl: "SHELL=/usr/bin/zsh zsh", diff --git a/backend/src/server.ts b/backend/src/server.ts index 5801027..c2fce2a 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -7,6 +7,7 @@ import * as appRoot from "app-root-path"; import * as express from "express"; import { Request } from "express"; import * as ws from "express-ws"; +import * as _ from "lodash"; import * as api from "./api"; import { langs } from "./langs"; @@ -30,13 +31,26 @@ function getQueryParams(req: Request): URLSearchParams { app.get("/", (_, res) => { res.render(appRoot.path + "/frontend/pages/index", { langs }); }); +for (const [lang, { aliases }] of Object.entries(langs)) { + if (aliases) { + for (const alias of aliases) { + app.get(`/${_.escapeRegExp(alias)}`, (_, res) => { + res.redirect(301, `/${lang}`); + }); + } + } +} app.get("/:lang", (req, res) => { - if (langs[req.params.lang]) { + const lang = req.params.lang; + const lowered = lang.toLowerCase(); + if (lowered !== lang) { + res.redirect(301, `/${lowered}`); + } else if (langs[lang]) { res.render(appRoot.path + "/frontend/pages/app", { - config: { id: req.params.lang, ...langs[req.params.lang] }, + config: { id: lang, ...langs[lang] }, }); } else { - res.send(`No such language: ${req.params.lang}`); + res.send(`No such language: ${lang}`); } }); app.use("/css", express.static(appRoot.path + "/frontend/styles")); diff --git a/package.json b/package.json index c32b9d0..c533794 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "@types/app-root-path": "^1.2.4", "@types/express": "^4.17.6", "@types/express-ws": "^3.0.0", + "@types/lodash": "^4.14.155", "@types/tmp": "^0.2.0", "app-root-path": "^3.0.0", "css-loader": "^3.5.3", @@ -14,6 +15,7 @@ "express": "^4.17.1", "express-ws": "^4.0.0", "file-loader": "^6.0.0", + "lodash": "^4.17.15", "mkdirp": "^1.0.4", "monaco-editor": "^0.20.0", "node-pty": "^0.9.0", diff --git a/yarn.lock b/yarn.lock index 5957887..04f1960 100644 --- a/yarn.lock +++ b/yarn.lock @@ -55,6 +55,11 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339" integrity sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA== +"@types/lodash@^4.14.155": + version "4.14.155" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.155.tgz#e2b4514f46a261fd11542e47519c20ebce7bc23a" + integrity sha512-vEcX7S7aPhsBCivxMwAANQburHBtfN9RdyXFk84IJmu2Z4Hkg1tOFgaslRiEqqvoLtbCBi6ika1EMspE+NZ9Lg== + "@types/mime@*": version "2.0.2" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.2.tgz#857a118d8634c84bba7ae14088e4508490cd5da5" @@ -1911,6 +1916,11 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" +lodash@^4.17.15: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" + integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" From 4ccb25a94782706ea8cc46ecc8c823055462c6f8 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 12 Jun 2020 15:03:03 -0600 Subject: [PATCH 072/388] Enable strict mode on all TypeScript --- backend/src/api.ts | 8 +++----- backend/src/langs.ts | 2 -- backend/src/server.ts | 19 +++++++++++-------- frontend/src/app.ts | 22 +++++++++++----------- package.json | 1 + tsconfig.json | 3 ++- yarn.lock | 7 +++++++ 7 files changed, 35 insertions(+), 27 deletions(-) diff --git a/backend/src/api.ts b/backend/src/api.ts index 5105cc8..f6dbe51 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -1,5 +1,3 @@ -"use strict"; - import * as fs from "fs"; import * as mkdirp from "mkdirp"; import * as pty from "node-pty"; @@ -13,7 +11,7 @@ import { LangConfig, langs } from "./langs"; export class Session { code: string; config: LangConfig; - term: { pty: IPty; live: boolean }; + term: { pty: IPty | null; live: boolean }; ws: WebSocket; constructor(ws: WebSocket, lang: string) { @@ -39,7 +37,7 @@ export class Session { } else if (typeof msg.input !== "string") { console.error(`terminalInput: missing or malformed input field`); } else { - this.term.pty.write(msg.input); + this.term.pty!.write(msg.input); } break; case "runCode": @@ -132,7 +130,7 @@ export class Session { pty: pty.spawn("bash", ["-c", cmdline], { name: "xterm-color", cwd: tmpdir, - env: process.env, + env: process.env as { [key: string]: string }, }), live: true, }; diff --git a/backend/src/langs.ts b/backend/src/langs.ts index fcfd69a..021d4f8 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1,5 +1,3 @@ -"use strict"; - export interface LangConfig { aliases?: string[]; name: string; diff --git a/backend/src/server.ts b/backend/src/server.ts index c2fce2a..9134449 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -1,5 +1,3 @@ -"use strict"; - import * as http from "http"; import * as https from "https"; @@ -13,8 +11,8 @@ import * as api from "./api"; import { langs } from "./langs"; const host = process.env.HOST || "localhost"; -const port = parseInt(process.env.PORT) || 6119; -const tlsPort = parseInt(process.env.TLS_PORT) || 6120; +const port = parseInt(process.env.PORT || "") || 6119; +const tlsPort = parseInt(process.env.TLS_PORT || "") || 6120; const useTLS = process.env.TLS ? true : false; const app = express(); @@ -56,7 +54,10 @@ app.get("/:lang", (req, res) => { app.use("/css", express.static(appRoot.path + "/frontend/styles")); app.use("/js", express.static(appRoot.path + "/frontend/out")); -function addWebsocket(baseApp: express.Express, httpsServer: https.Server) { +function addWebsocket( + baseApp: express.Express, + httpsServer: https.Server | undefined +) { const app = ws(baseApp, httpsServer).app; app.ws("/api/v1/ws", (ws, req) => { const lang = getQueryParams(req).get("lang"); @@ -77,7 +78,7 @@ function addWebsocket(baseApp: express.Express, httpsServer: https.Server) { ); ws.close(); } else { - new api.Session(ws, getQueryParams(req).get("lang")); + new api.Session(ws, lang); } }); return app; @@ -86,8 +87,10 @@ function addWebsocket(baseApp: express.Express, httpsServer: https.Server) { if (useTLS) { const httpsServer = https.createServer( { - key: Buffer.from(process.env.TLS_PRIVATE_KEY, "base64").toString("ascii"), - cert: Buffer.from(process.env.TLS_CERTIFICATE, "base64").toString( + key: Buffer.from(process.env.TLS_PRIVATE_KEY || "", "base64").toString( + "ascii" + ), + cert: Buffer.from(process.env.TLS_CERTIFICATE || "", "base64").toString( "ascii" ), }, diff --git a/frontend/src/app.ts b/frontend/src/app.ts index e9a08ad..95deb8d 100644 --- a/frontend/src/app.ts +++ b/frontend/src/app.ts @@ -1,5 +1,3 @@ -"use strict"; - import * as monaco from "monaco-editor"; import { Terminal } from "xterm"; import { FitAddon } from "xterm-addon-fit"; @@ -17,7 +15,7 @@ const config: RijuConfig = (window as any).rijuConfig; const term = new Terminal(); const fitAddon = new FitAddon(); term.loadAddon(fitAddon); -term.open(document.getElementById("terminal")); +term.open(document.getElementById("terminal")!); fitAddon.fit(); window.addEventListener("resize", () => fitAddon.fit()); @@ -81,21 +79,23 @@ function scheduleConnect() { retryDelayMs *= 2; } -let socket = null; +let socket: WebSocket | null = null; tryConnect(); -term.onData((data) => - socket.send(JSON.stringify({ event: "terminalInput", input: data })) +term.onData( + (data) => + socket && + socket.send(JSON.stringify({ event: "terminalInput", input: data })) ); -const editor = monaco.editor.create(document.getElementById("editor"), { +const editor = monaco.editor.create(document.getElementById("editor")!, { minimap: { enabled: false }, scrollbar: { verticalScrollbarSize: 0 }, }); window.addEventListener("resize", () => editor.layout()); -editor.getModel().setValue(config.template); -monaco.editor.setModelLanguage(editor.getModel(), config.monacoLang); +editor.getModel()!.setValue(config.template); +monaco.editor.setModelLanguage(editor.getModel()!, config.monacoLang); -document.getElementById("runButton").addEventListener("click", () => { - socket.send(JSON.stringify({ event: "runCode", code: editor.getValue() })); +document.getElementById("runButton")!.addEventListener("click", () => { + socket?.send(JSON.stringify({ event: "runCode", code: editor.getValue() })); }); diff --git a/package.json b/package.json index c533794..6fdb2a0 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "@types/express": "^4.17.6", "@types/express-ws": "^3.0.0", "@types/lodash": "^4.14.155", + "@types/mkdirp": "^1.0.1", "@types/tmp": "^0.2.0", "app-root-path": "^3.0.0", "css-loader": "^3.5.3", diff --git a/tsconfig.json b/tsconfig.json index a27d286..9e16e58 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,7 +3,8 @@ "outDir": "./backend/out", "resolveJsonModule": true, "rootDir": "./backend/src", - "sourceMap": true + "sourceMap": true, + "strict": true }, "include": ["backend/src"] } diff --git a/yarn.lock b/yarn.lock index 04f1960..1fa7b4a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -65,6 +65,13 @@ resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.2.tgz#857a118d8634c84bba7ae14088e4508490cd5da5" integrity sha512-4kPlzbljFcsttWEq6aBW0OZe6BDajAmyvr2xknBG92tejQnvdGtT9+kXSZ580DqpxY9qG2xeQVF9Dq0ymUTo5Q== +"@types/mkdirp@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-1.0.1.tgz#0930b948914a78587de35458b86c907b6e98bbf6" + integrity sha512-HkGSK7CGAXncr8Qn/0VqNtExEE+PHMWb+qlR1faHMao7ng6P3tAaoWWBMdva0gL5h4zprjIO89GJOLXsMcDm1Q== + dependencies: + "@types/node" "*" + "@types/node@*": version "14.0.11" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.11.tgz#61d4886e2424da73b7b25547f59fdcb534c165a3" From 42769446a03a80162032c2185676066b739ec7d1 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 12 Jun 2020 16:57:25 -0600 Subject: [PATCH 073/388] Don't hardcode the IP address --- scripts/deploy.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/deploy.bash b/scripts/deploy.bash index 7dc7108..c70c13b 100755 --- a/scripts/deploy.bash +++ b/scripts/deploy.bash @@ -20,4 +20,4 @@ ssh -o IdentitiesOnly=yes \ -o StrictHostKeyChecking=no \ -o UserKnownHostsFile=/dev/null \ -o LogLevel=QUIET \ - -i "${keyfile}" deploy@138.68.247.206 + -i "${keyfile}" deploy@riju.codes From 9ec5ecc224a2714c57c4887256855e1e78382035 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 12 Jun 2020 18:12:33 -0600 Subject: [PATCH 074/388] Clean up /tmp --- scripts/docker-install-phase4.bash | 3 +++ scripts/docker-install-phase5.bash | 1 + scripts/docker-install-phase6.bash | 2 ++ 3 files changed, 6 insertions(+) diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 70ba663..69fe156 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -5,6 +5,7 @@ set -o pipefail npm config set unsafe-perm true PERL_MM_USE_DEFAULT=1 cpan App::cpanminus +rm -rf /tmp/cpan_install_*.txt # Befunge npm install -g befunge93 prompt-sync @@ -36,4 +37,6 @@ pip3 install whitespace # Wolfram Language python3.7 -m pip install mathics +rm -f /tmp/core-js-banners + rm "$0" diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index 5bce5c1..4ccbe29 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -12,6 +12,7 @@ rm watchexec-*.deb cd /tmp git clone https://github.com/circulosmeos/gdown.pl.git mv gdown.pl/gdown.pl /usr/bin/gdown +rm -rf gdown.pl cd /tmp wget https://get.haskellstack.org/stable/linux-x86_64-static.tar.gz diff --git a/scripts/docker-install-phase6.bash b/scripts/docker-install-phase6.bash index 83c3efb..cc0efa2 100755 --- a/scripts/docker-install-phase6.bash +++ b/scripts/docker-install-phase6.bash @@ -5,6 +5,8 @@ set -o pipefail uid="$1" +rm -rf /tmp/hsperfdata_root + if [[ -n "$uid" ]] && (( "$uid" != 0 )); then useradd --uid="$uid" --create-home --groups sudo docker passwd -d docker From e9ff1d92d39193a4328991324e666a7fee70abfa Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 12 Jun 2020 18:13:22 -0600 Subject: [PATCH 075/388] Clean up temporary directories --- backend/src/api.ts | 43 ++++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/backend/src/api.ts b/backend/src/api.ts index f6dbe51..de321f9 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -13,14 +13,19 @@ export class Session { config: LangConfig; term: { pty: IPty | null; live: boolean }; ws: WebSocket; + tmpdir: string | null; + tmpdirCleanup: (() => void) | null; constructor(ws: WebSocket, lang: string) { this.ws = ws; this.config = langs[lang]; this.term = { pty: null, live: false }; this.code = ""; - this.run().catch(console.error); + this.tmpdir = null; + this.tmpdirCleanup = null; ws.on("message", this.handleClientMessage); + ws.on("close", this.cleanup); + this.run().catch(console.error); } handleClientMessage = (event: string) => { let msg: any; @@ -64,15 +69,18 @@ export class Session { } catch (err) { // } - const tmpdir: string = await new Promise((resolve, reject) => - tmp.dir({ unsafeCleanup: true }, (err, path) => { - if (err) { - reject(err); - } else { - resolve(path); - } - }) - ); + if (this.tmpdir == null) { + ({ path: this.tmpdir, cleanup: this.tmpdirCleanup } = await new Promise( + (resolve, reject) => + tmp.dir({ unsafeCleanup: true }, (err, path, cleanup) => { + if (err) { + reject(err); + } else { + resolve({ path, cleanup }); + } + }) + )); + } let cmdline: string; if (!run) { cmdline = `echo 'Support for ${this.config.name} is not yet implemented.'`; @@ -82,10 +90,10 @@ export class Session { code += suffix; } if (main.includes("/")) { - await mkdirp(path.dirname(path.resolve(tmpdir, main))); + await mkdirp(path.dirname(path.resolve(this.tmpdir!, main))); } await new Promise((resolve, reject) => - fs.writeFile(path.resolve(tmpdir, main), code, (err) => { + fs.writeFile(path.resolve(this.tmpdir!, main), code, (err) => { if (err) { reject(err); } else { @@ -106,7 +114,7 @@ export class Session { if (this.code) { const contents = ":load Main\nmain\n"; await new Promise((resolve, reject) => { - fs.writeFile(path.resolve(tmpdir, ".ghci"), contents, (err) => { + fs.writeFile(path.resolve(this.tmpdir!, ".ghci"), contents, (err) => { if (err) { reject(err); } else { @@ -116,7 +124,7 @@ export class Session { }); } else { await new Promise((resolve, reject) => - fs.unlink(path.resolve(tmpdir, ".ghci"), (err) => { + fs.unlink(path.resolve(this.tmpdir!, ".ghci"), (err) => { if (err && err.code !== "ENOENT") { reject(err); } else { @@ -129,7 +137,7 @@ export class Session { const term = { pty: pty.spawn("bash", ["-c", cmdline], { name: "xterm-color", - cwd: tmpdir, + cwd: this.tmpdir!, env: process.env as { [key: string]: string }, }), live: true, @@ -149,4 +157,9 @@ export class Session { } }); }; + cleanup = () => { + if (this.tmpdirCleanup) { + this.tmpdirCleanup(); + } + }; } From afad563d5643b901a753a574ad85976eabc67c4b Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 22 Jun 2020 12:35:38 -0600 Subject: [PATCH 076/388] Automatically allocate one uid per session --- Dockerfile.prod | 7 +- README.md | 12 ++-- backend/src/api.ts | 67 ++++++++++++++----- backend/src/users.ts | 100 ++++++++++++++++++++++++++++ package.json | 13 +++- scripts/compile-system.bash | 26 ++++++++ scripts/pid1.bash | 1 + scripts/setup.bash | 7 ++ system/src/riju-system-privileged.c | 55 +++++++++++++++ yarn.lock | 30 +++++++++ 10 files changed, 291 insertions(+), 27 deletions(-) create mode 100644 backend/src/users.ts create mode 100755 scripts/compile-system.bash create mode 100755 scripts/setup.bash create mode 100644 system/src/riju-system-privileged.c diff --git a/Dockerfile.prod b/Dockerfile.prod index 277bb38..063ce53 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -38,8 +38,7 @@ EXPOSE 6120 ENTRYPOINT ["/usr/local/bin/pid1.bash"] COPY scripts/pid1.bash /usr/local/bin/ - -RUN sudo deluser docker sudo +CMD ["yarn", "run", "server"] RUN mkdir /tmp/riju COPY --chown=docker:docker package.json yarn.lock /tmp/riju/ @@ -49,8 +48,10 @@ COPY --chown=docker:docker frontend /tmp/riju/frontend RUN cd /tmp/riju && yarn run frontend COPY --chown=docker:docker backend /tmp/riju/backend RUN cd /tmp/riju && yarn run backend +COPY --chown=docker:docker system /tmp/riju/system +RUN cd /tmp/riju && RIJU_PRIVILEGED=1 yarn run system COPY --chown=docker:docker . /home/docker/src RUN cp -R /tmp/riju/* /home/docker/src/ && rm -rf /tmp/riju WORKDIR /home/docker/src -CMD ["yarn", "run", "server"] +RUN sudo deluser docker sudo diff --git a/README.md b/README.md index ccc1ee1..e5c140b 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ usual to install dependencies. For production, it's: $ yarn backend $ yarn frontend + $ yarn system $ yarn server For development with file watching and automatic server rebooting and @@ -27,15 +28,18 @@ all that, it's: $ yarn backend-dev $ yarn frontend-dev + $ yarn system-dev $ yarn server-dev The webserver listens on `localhost:6119`. Now, although the server itself will work, the only languages that will work are the ones that happen to be installed on your machine. (I'm sure you can find a few -that are already.) If you want to test with *all* the languages (or -you're working on adding a new language), then you need to use Docker. -Running the app is exactly the same as before, you just have to jump -into the container first: +that are already.) Also, sandboxing using UNIX filesystem permissions +will be disabled, because that requires root privileges. If you want +to test with *all* the languages plus sandboxing (or you're working on +adding a new language), then you need to use Docker. Running the app +is exactly the same as before, you just have to jump into the +container first: $ make docker diff --git a/backend/src/api.ts b/backend/src/api.ts index de321f9..c3b5e59 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -1,64 +1,88 @@ import * as fs from "fs"; -import * as mkdirp from "mkdirp"; -import * as pty from "node-pty"; -import { IPty } from "node-pty"; import * as path from "path"; -import * as tmp from "tmp"; import * as WebSocket from "ws"; +import * as mkdirp from "mkdirp"; +import * as nodeCleanup from "node-cleanup"; +import * as pty from "node-pty"; +import { IPty } from "node-pty"; +import * as tmp from "tmp"; +import { v4 as getUUID } from "uuid"; + import { LangConfig, langs } from "./langs"; +import { borrowUser } from "./users"; export class Session { + id: string; code: string; config: LangConfig; term: { pty: IPty | null; live: boolean }; ws: WebSocket; tmpdir: string | null; tmpdirCleanup: (() => void) | null; + uid: number | null; + uidCleanup: (() => Promise) | null; + + log = (msg: string) => console.log(`[${this.id}] ${msg}`); constructor(ws: WebSocket, lang: string) { + this.id = getUUID(); + this.log(`Creating session, language ${lang}`); this.ws = ws; this.config = langs[lang]; this.term = { pty: null, live: false }; this.code = ""; this.tmpdir = null; this.tmpdirCleanup = null; + this.uid = null; + this.uidCleanup = null; ws.on("message", this.handleClientMessage); - ws.on("close", this.cleanup); - this.run().catch(console.error); + ws.on("close", () => + this.cleanup().catch((err) => + this.log(`Error during session cleanup: ${err}`) + ) + ); + nodeCleanup(); + this.run().catch((err) => this.log(`Error while running: ${err}`)); } handleClientMessage = (event: string) => { let msg: any; try { msg = JSON.parse(event); } catch (err) { - console.error(`failed to parse client message: ${msg}`); + this.log(`Failed to parse client message: ${msg}`); return; } switch (msg?.event) { case "terminalInput": if (!this.term) { - console.error(`terminalInput: no terminal`); + this.log(`Got terminal input before pty was started`); } else if (typeof msg.input !== "string") { - console.error(`terminalInput: missing or malformed input field`); + this.log(`Got malformed terminal input message`); } else { this.term.pty!.write(msg.input); } break; case "runCode": if (typeof msg.code !== "string") { - console.error(`runCode: missing or malformed code field`); + this.log(`Got malformed run message`); } else { this.code = msg.code; this.run(); } break; default: - console.error(`unknown client message type: ${msg.event}`); + this.log(`Got unknown message type: ${msg.event}`); break; } }; run = async () => { + if (this.uid === null) { + ({ uid: this.uid, cleanup: this.uidCleanup } = await borrowUser( + this.log + )); + } + this.log(`Borrowed uid ${this.uid}`); const { name, repl, main, suffix, compile, run, hacks } = this.config; if (this.term.pty) { this.term.pty.kill(); @@ -72,13 +96,16 @@ export class Session { if (this.tmpdir == null) { ({ path: this.tmpdir, cleanup: this.tmpdirCleanup } = await new Promise( (resolve, reject) => - tmp.dir({ unsafeCleanup: true }, (err, path, cleanup) => { - if (err) { - reject(err); - } else { - resolve({ path, cleanup }); + tmp.dir( + { unsafeCleanup: true, dir: "riju" }, + (err, path, cleanup) => { + if (err) { + reject(err); + } else { + resolve({ path, cleanup }); + } } - }) + ) )); } let cmdline: string; @@ -157,9 +184,13 @@ export class Session { } }); }; - cleanup = () => { + cleanup = async () => { + this.log(`Cleaning up session`); if (this.tmpdirCleanup) { this.tmpdirCleanup(); } + if (this.uidCleanup) { + await this.uidCleanup(); + } }; } diff --git a/backend/src/users.ts b/backend/src/users.ts new file mode 100644 index 0000000..6e3c8f4 --- /dev/null +++ b/backend/src/users.ts @@ -0,0 +1,100 @@ +import { spawn } from "child_process"; +import * as fs from "fs"; +import * as process from "process"; + +import * as AsyncLock from "async-lock"; +import * as _ from "lodash"; +import * as parsePasswd from "parse-passwd"; + +// Keep in sync with system/src/riju-system-privileged.c +const MIN_UID = 2000; +const MAX_UID = 65000; + +const PRIVILEGED = process.env.RIJU_PRIVILEGED ? true : false; +const CUR_UID = parseInt(process.env.UID || "") || null; + +let availIds: number[] | null = null; +let nextId: number | null = null; +let lock = new AsyncLock(); + +async function readExistingUsers(log: (msg: string) => void) { + availIds = parsePasswd( + await new Promise((resolve, reject) => + fs.readFile("/etc/passwd", "utf-8", (err, data) => { + if (err) { + reject(err); + } else { + resolve(data); + } + }) + ) + ) + .filter(({ username }) => username.startsWith("riju_user")) + .map(({ uid }) => parseInt(uid)) + .filter((uid) => !isNaN(uid) && uid >= MIN_UID && uid < MAX_UID); + nextId = (_.max(availIds) || MIN_UID - 1) + 1; + log(`Found ${availIds.length} existing users, next ID is ${nextId}`); +} + +async function createUser(log: (msg: string) => void): Promise { + if (nextId! >= MAX_UID) { + throw new Error("too many users"); + } + return await new Promise((resolve, reject) => { + const uid = nextId!; + const useradd = spawn("system/out/riju-system-privileged", [ + "useradd", + `${uid}`, + ]); + let output = ""; + useradd.stdout.on("data", (data) => { + output += `${data}`; + }); + useradd.stderr.on("data", (data) => { + output += `${data}`; + }); + useradd.on("close", (code) => { + output = output.trim(); + if (output) { + log("Output from useradd:\n" + output); + } + if (code === 0) { + log(`Created new user with ID ${uid}`); + nextId! += 1; + resolve(uid); + } else { + reject(`useradd failed with error code ${code}`); + } + }); + }); +} + +export async function borrowUser(log: (msg: string) => void) { + if (!PRIVILEGED) { + if (CUR_UID === null) { + throw new Error("unable to determine current UID"); + } else { + return { uid: CUR_UID, cleanup: async () => {} }; + } + } else { + return await lock.acquire("key", async () => { + if (availIds === null || nextId === null) { + await readExistingUsers(log); + } + let uid: number; + if (availIds!.length > 0) { + uid = availIds!.pop()!; + } else { + uid = await createUser(log); + } + return { + uid, + cleanup: async () => { + await lock.acquire("key", () => { + availIds!.push(uid); + }); + }, + }; + }); + } +} diff --git a/package.json b/package.json index 6fdb2a0..3f23bc1 100644 --- a/package.json +++ b/package.json @@ -5,12 +5,16 @@ "private": true, "dependencies": { "@types/app-root-path": "^1.2.4", + "@types/async-lock": "^1.1.2", "@types/express": "^4.17.6", "@types/express-ws": "^3.0.0", "@types/lodash": "^4.14.155", "@types/mkdirp": "^1.0.1", + "@types/parse-passwd": "^1.0.0", "@types/tmp": "^0.2.0", + "@types/uuid": "^8.0.0", "app-root-path": "^3.0.0", + "async-lock": "^1.2.4", "css-loader": "^3.5.3", "ejs": "^3.1.3", "express": "^4.17.1", @@ -19,11 +23,14 @@ "lodash": "^4.17.15", "mkdirp": "^1.0.4", "monaco-editor": "^0.20.0", + "node-cleanup": "^2.1.2", "node-pty": "^0.9.0", + "parse-passwd": "^1.0.0", "style-loader": "^1.2.1", "tmp": "^0.2.1", "ts-loader": "^7.0.5", "typescript": "^3.9.5", + "uuid": "^8.1.0", "webpack": "^4.43.0", "webpack-cli": "^3.3.11", "xterm": "^4.6.0", @@ -34,7 +41,9 @@ "backend-dev": "tsc --watch", "frontend": "webpack --production", "frontend-dev": "webpack --development --watch", - "server": "node backend/out/server.js", - "server-dev": "watchexec -w backend/out -r -n node backend/out/server.js" + "server": "scripts/setup.bash && node backend/out/server.js", + "server-dev": "watchexec -w backend/out -r 'scripts/setup.bash && node backend/out/server.js'", + "system": "scripts/compile-system.bash", + "system-dev": "watchexec -w system/src -n scripts/compile-system.bash" } } diff --git a/scripts/compile-system.bash b/scripts/compile-system.bash new file mode 100755 index 0000000..ac3a77f --- /dev/null +++ b/scripts/compile-system.bash @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +if [[ ! -d system/src ]]; then + echo "compile-system.bash: no system/src directory" >&2 + exit 1 +fi + +function verbosely { + echo "$@" + "$@" +} + +mkdir -p system/out +rm -f system/out/* +for src in system/src/*.c; do + out="${src/src/out}" + out="${out/.c}" + verbosely clang -Wall -Wextra -Werror -std=c11 "${src}" -o "${out}" + if [[ "${out}" == *-privileged && -n "${RIJU_PRIVILEGED}" ]]; then + sudo chown root:docker "${out}" + sudo chmod a=,g=rx,u=rwxs "${out}" + fi +done diff --git a/scripts/pid1.bash b/scripts/pid1.bash index 3e88423..ceea05c 100755 --- a/scripts/pid1.bash +++ b/scripts/pid1.bash @@ -8,6 +8,7 @@ export LC_ALL=C.UTF-8 export SHELL="$(which bash)" export HOST=0.0.0.0 +export RIJU_PRIVILEGED=yes if [[ -d /home/docker/src ]]; then cd /home/docker/src diff --git a/scripts/setup.bash b/scripts/setup.bash new file mode 100755 index 0000000..b884776 --- /dev/null +++ b/scripts/setup.bash @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +mkdir -p /tmp/riju +rm -rf /tmp/riju/* diff --git a/system/src/riju-system-privileged.c b/system/src/riju-system-privileged.c new file mode 100644 index 0000000..6ada086 --- /dev/null +++ b/system/src/riju-system-privileged.c @@ -0,0 +1,55 @@ +#define _GNU_SOURCE +#include +#include +#include +#include + +// Keep in sync with backend/src/users.ts +const int MIN_UID = 2000; +const int MAX_UID = 65000; + +void die(const char *msg) +{ + fprintf(stderr, "%s\n", msg); + exit(1); +} + +void die_with_usage() +{ + die("usage:\n" + " riju-system-privileged useradd UID"); +} + +void useradd(int uid) +{ + char *cmdline; + if (asprintf(&cmdline, "useradd -M -N -l -r -u %1$d riju_user%1$d", uid) < 0) { + die("asprintf failed"); + } + int status = system(cmdline); + if (status) { + die("useradd failed"); + } +} + +int main(int argc, char **argv) +{ + setuid(0); + if (argc < 2) + die_with_usage(); + if (!strcmp(argv[1], "useradd")) { + if (argc != 3) + die_with_usage(); + char *endptr; + long uid = strtol(argv[2], &endptr, 10); + if (!argv[2] || *endptr) { + die("uid must be an integer"); + } + if (uid < MIN_UID || uid >= MAX_UID) { + die("uid is out of range"); + } + useradd(uid); + return 0; + } + die_with_usage(); +} diff --git a/yarn.lock b/yarn.lock index 1fa7b4a..a312345 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7,6 +7,11 @@ resolved "https://registry.yarnpkg.com/@types/app-root-path/-/app-root-path-1.2.4.tgz#a78b703282b32ac54de768f5512ecc3569919dc7" integrity sha1-p4twMoKzKsVN52j1US7MNWmRncc= +"@types/async-lock@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@types/async-lock/-/async-lock-1.1.2.tgz#cbc26a34b11b83b28f7783a843c393b443ef8bef" + integrity sha512-j9n4bb6RhgFIydBe0+kpjnBPYumDaDyU8zvbWykyVMkku+c2CSu31MZkLeaBfqIwU+XCxlDpYDfyMQRkM0AkeQ== + "@types/body-parser@*": version "1.19.0" resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.0.tgz#0685b3c47eb3006ffed117cdd55164b61f80538f" @@ -77,6 +82,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.11.tgz#61d4886e2424da73b7b25547f59fdcb534c165a3" integrity sha512-lCvvI24L21ZVeIiyIUHZ5Oflv1hhHQ5E1S25IRlKIXaRkVgmXpJMI3wUJkmym2bTbCe+WoIibQnMVAU3FguaOg== +"@types/parse-passwd@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/parse-passwd/-/parse-passwd-1.0.0.tgz#72fc50feb14d484547f40ba7da54dfcfc711dcf1" + integrity sha512-+kETlH3XJMQKUpJ4dYfU4MlfYqyjKwsOC9PLJcGiUhPcHrNEgvcEbllSJ5HlsvflDLswTtyDoKJEUcCQg2l9PA== + "@types/qs@*": version "6.9.3" resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.3.tgz#b755a0934564a200d3efdf88546ec93c369abd03" @@ -100,6 +110,11 @@ resolved "https://registry.yarnpkg.com/@types/tmp/-/tmp-0.2.0.tgz#e3f52b4d7397eaa9193592ef3fdd44dc0af4298c" integrity sha512-flgpHJjntpBAdJD43ShRosQvNC0ME97DCfGvZEDlAThQmnerRXrLbX6YgzRBQCZTthET9eAWFAMaYP0m0Y4HzQ== +"@types/uuid@^8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.0.0.tgz#165aae4819ad2174a17476dbe66feebd549556c0" + integrity sha512-xSQfNcvOiE5f9dyd4Kzxbof1aTrLobL278pGLKOZI6esGfZ7ts9Ka16CzIN6Y8hFHE1C7jIBZokULhK1bOgjRw== + "@types/ws@*": version "7.2.5" resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.2.5.tgz#513f28b04a1ea1aa9dc2cad3f26e8e37c88aae49" @@ -390,6 +405,11 @@ async-limiter@~1.0.0: resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== +async-lock@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/async-lock/-/async-lock-1.2.4.tgz#80d0d612383045dd0c30eb5aad08510c1397cb91" + integrity sha512-UBQJC2pbeyGutIfYmErGc9RaJYnpZ1FHaxuKwb0ahvGiiCkPUf3p67Io+YLPmmv3RHY+mF6JEtNW8FlHsraAaA== + async@0.9.x: version "0.9.2" resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" @@ -2190,6 +2210,11 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== +node-cleanup@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/node-cleanup/-/node-cleanup-2.1.2.tgz#7ac19abd297e09a7f72a71545d951b517e4dde2c" + integrity sha1-esGavSl+Caf3KnFUXZUbUX5N3iw= + node-libs-browser@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" @@ -3299,6 +3324,11 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= +uuid@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.1.0.tgz#6f1536eb43249f473abc6bd58ff983da1ca30d8d" + integrity sha512-CI18flHDznR0lq54xBycOVmphdCYnQLKn8abKn7PXUiKUGdEd+/l9LWNJmugXel4hXq7S+RMNl34ecyC9TntWg== + v8-compile-cache@2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe" From 91fe6ffd653609be8a73487419a81c03979433d9 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 22 Jun 2020 15:28:27 -0600 Subject: [PATCH 077/388] Drop privileges to respective uid --- Dockerfile.dev | 4 + Dockerfile.prod | 9 +- Makefile | 2 +- README.md | 14 +- backend/src/api.ts | 140 +++++++------ backend/src/config.ts | 3 + backend/src/langs.ts | 28 +-- backend/src/users.ts | 39 +--- backend/src/util.ts | 83 ++++++++ frontend/src/app.ts | 162 +++++++------- package.json | 12 +- scripts/docker-install-phase0.bash | 12 ++ scripts/docker-install-phase1.bash | 1 + scripts/docker-install-phase2.bash | 1 + scripts/docker-install-phase3a.bash | 1 + scripts/docker-install-phase3b.bash | 1 + scripts/docker-install-phase3c.bash | 1 + scripts/docker-install-phase3d.bash | 1 + scripts/docker-install-phase4.bash | 1 + scripts/docker-install-phase5.bash | 1 + scripts/docker-install-phase6.bash | 11 +- scripts/riju-serve.bash | 2 +- scripts/setup.bash | 5 +- system/src/riju-system-privileged.c | 112 ++++++++-- yarn.lock | 313 ++++++++++++++++++++++++++-- 25 files changed, 716 insertions(+), 243 deletions(-) create mode 100644 backend/src/config.ts create mode 100644 backend/src/util.ts create mode 100755 scripts/docker-install-phase0.bash diff --git a/Dockerfile.dev b/Dockerfile.dev index fc15487..efe6904 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -2,6 +2,9 @@ FROM ubuntu:focal ARG UID +COPY scripts/docker-install-phase0.bash /tmp/ +RUN /tmp/docker-install-phase0.bash + COPY scripts/docker-install-phase1.bash /tmp/ RUN /tmp/docker-install-phase1.bash @@ -31,6 +34,7 @@ RUN /tmp/docker-install-phase6.bash "$UID" USER docker WORKDIR /home/docker +RUN chmod go-rwx /home/docker EXPOSE 6119 EXPOSE 6120 diff --git a/Dockerfile.prod b/Dockerfile.prod index 063ce53..a69919d 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -4,6 +4,9 @@ FROM ubuntu:focal # prod, it's not actually read by anything. ARG UID +COPY scripts/docker-install-phase0.bash /tmp/ +RUN /tmp/docker-install-phase0.bash + COPY scripts/docker-install-phase1.bash /tmp/ RUN /tmp/docker-install-phase1.bash @@ -33,6 +36,7 @@ RUN /tmp/docker-install-phase6.bash USER docker WORKDIR /home/docker +RUN chmod go-rwx /home/docker EXPOSE 6119 EXPOSE 6120 @@ -40,7 +44,7 @@ ENTRYPOINT ["/usr/local/bin/pid1.bash"] COPY scripts/pid1.bash /usr/local/bin/ CMD ["yarn", "run", "server"] -RUN mkdir /tmp/riju +RUN mkdir /tmp/riju /tmp/riju/scripts COPY --chown=docker:docker package.json yarn.lock /tmp/riju/ RUN cd /tmp/riju && yarn install COPY --chown=docker:docker webpack.config.js tsconfig.json tsconfig-webpack.json /tmp/riju/ @@ -48,10 +52,11 @@ COPY --chown=docker:docker frontend /tmp/riju/frontend RUN cd /tmp/riju && yarn run frontend COPY --chown=docker:docker backend /tmp/riju/backend RUN cd /tmp/riju && yarn run backend +COPY --chown=docker:docker scripts/compile-system.bash /tmp/riju/scripts COPY --chown=docker:docker system /tmp/riju/system RUN cd /tmp/riju && RIJU_PRIVILEGED=1 yarn run system COPY --chown=docker:docker . /home/docker/src -RUN cp -R /tmp/riju/* /home/docker/src/ && rm -rf /tmp/riju +RUN sudo cp -a /tmp/riju/* /home/docker/src/ && rm -rf /tmp/riju WORKDIR /home/docker/src RUN sudo deluser docker sudo diff --git a/Makefile b/Makefile index 2a7ef42..5ee1504 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ image-prod: ## Build Docker image for production .PHONY: docker docker: image-dev ## Run shell with source code and deps inside Docker - scripts/docker.bash run -it --rm -v "$(PWD):/home/docker/src" -p 6119:6119 -p 6120:6120 riju bash + scripts/docker.bash run -it --rm -v "$(PWD):/home/docker/src" -p 6119:6119 -p 6120:6120 -h riju riju bash .PHONY: deploy deploy: ## Deploy current master from GitHub to production diff --git a/README.md b/README.md index e5c140b..7aee9be 100644 --- a/README.md +++ b/README.md @@ -18,18 +18,18 @@ documenting it until it has reached feature-completeness. To run the webserver, all you need is Yarn. Just run `yarn install` as usual to install dependencies. For production, it's: - $ yarn backend - $ yarn frontend - $ yarn system + $ yarn backend |- or run all three with 'yarn build' + $ yarn frontend | + $ yarn system | $ yarn server For development with file watching and automatic server rebooting and all that, it's: - $ yarn backend-dev - $ yarn frontend-dev - $ yarn system-dev - $ yarn server-dev + $ yarn backend-dev |- or run all four with 'yarn dev' + $ yarn frontend-dev | + $ yarn system-dev | + $ yarn server-dev | The webserver listens on `localhost:6119`. Now, although the server itself will work, the only languages that will work are the ones that diff --git a/backend/src/api.ts b/backend/src/api.ts index c3b5e59..9897468 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -1,49 +1,48 @@ -import * as fs from "fs"; import * as path from "path"; import * as WebSocket from "ws"; -import * as mkdirp from "mkdirp"; -import * as nodeCleanup from "node-cleanup"; import * as pty from "node-pty"; import { IPty } from "node-pty"; -import * as tmp from "tmp"; import { v4 as getUUID } from "uuid"; +import { PRIVILEGED } from "./config"; import { LangConfig, langs } from "./langs"; import { borrowUser } from "./users"; +import { callPrivileged, getEnv, spawnPrivileged } from "./util"; export class Session { - id: string; + uuid: string; code: string; config: LangConfig; term: { pty: IPty | null; live: boolean }; ws: WebSocket; - tmpdir: string | null; - tmpdirCleanup: (() => void) | null; + homedir: string | null; uid: number | null; uidCleanup: (() => Promise) | null; - log = (msg: string) => console.log(`[${this.id}] ${msg}`); + log = (msg: string) => console.log(`[${this.uuid}] ${msg}`); constructor(ws: WebSocket, lang: string) { - this.id = getUUID(); + this.uuid = getUUID(); this.log(`Creating session, language ${lang}`); this.ws = ws; this.config = langs[lang]; this.term = { pty: null, live: false }; this.code = ""; - this.tmpdir = null; - this.tmpdirCleanup = null; + this.homedir = null; this.uid = null; this.uidCleanup = null; ws.on("message", this.handleClientMessage); ws.on("close", () => - this.cleanup().catch((err) => - this.log(`Error during session cleanup: ${err}`) - ) + this.cleanup().catch((err) => { + this.log(`Error during session cleanup`); + console.log(err); + }) ); - nodeCleanup(); - this.run().catch((err) => this.log(`Error while running: ${err}`)); + this.run().catch((err) => { + this.log(`Error while setting up environment for pty`); + console.log(err); + }); } handleClientMessage = (event: string) => { let msg: any; @@ -81,9 +80,18 @@ export class Session { ({ uid: this.uid, cleanup: this.uidCleanup } = await borrowUser( this.log )); + this.log(`Borrowed uid ${this.uid}`); } - this.log(`Borrowed uid ${this.uid}`); - const { name, repl, main, suffix, compile, run, hacks } = this.config; + const { + name, + repl, + main, + suffix, + alwaysCreate, + compile, + run, + hacks, + } = this.config; if (this.term.pty) { this.term.pty.kill(); this.term.live = false; @@ -93,20 +101,9 @@ export class Session { } catch (err) { // } - if (this.tmpdir == null) { - ({ path: this.tmpdir, cleanup: this.tmpdirCleanup } = await new Promise( - (resolve, reject) => - tmp.dir( - { unsafeCleanup: true, dir: "riju" }, - (err, path, cleanup) => { - if (err) { - reject(err); - } else { - resolve({ path, cleanup }); - } - } - ) - )); + if (this.homedir == null) { + this.homedir = `/tmp/riju/${this.uuid}`; + await callPrivileged(["setup", `${this.uid}`, this.uuid], this.log); } let cmdline: string; if (!run) { @@ -117,22 +114,33 @@ export class Session { code += suffix; } if (main.includes("/")) { - await mkdirp(path.dirname(path.resolve(this.tmpdir!, main))); + await spawnPrivileged( + this.uid, + this.uuid, + ["mkdir", "-p", path.dirname(path.resolve(this.homedir, main))], + this.log + ); } - await new Promise((resolve, reject) => - fs.writeFile(path.resolve(this.tmpdir!, main), code, (err) => { - if (err) { - reject(err); - } else { - resolve(); - } - }) + await spawnPrivileged( + this.uid, + this.uuid, + ["sh", "-c", `cat > ${path.resolve(this.homedir, main)}`], + this.log, + { input: code } ); cmdline = run; if (compile) { cmdline = `( ${compile} ) && ( ${run} )`; } } else if (repl) { + if (alwaysCreate) { + await spawnPrivileged( + this.uid, + this.uuid, + ["touch", `${path.resolve(this.homedir, main)}`], + this.log + ); + } cmdline = repl; } else { cmdline = `echo '${name} has no REPL, press Run to see it in action'`; @@ -140,32 +148,38 @@ export class Session { if (hacks && hacks.includes("ghci-config") && run) { if (this.code) { const contents = ":load Main\nmain\n"; - await new Promise((resolve, reject) => { - fs.writeFile(path.resolve(this.tmpdir!, ".ghci"), contents, (err) => { - if (err) { - reject(err); - } else { - resolve(); - } - }); - }); + await spawnPrivileged( + this.uid, + this.uuid, + ["sh", "-c", `cat > ${path.resolve(this.homedir, ".ghci")}`], + this.log, + { input: contents } + ); } else { - await new Promise((resolve, reject) => - fs.unlink(path.resolve(this.tmpdir!, ".ghci"), (err) => { - if (err && err.code !== "ENOENT") { - reject(err); - } else { - resolve(); - } - }) + await spawnPrivileged( + this.uid, + this.uuid, + ["rm", "-f", path.resolve(this.homedir, ".ghci")], + this.log ); } } + const args = PRIVILEGED + ? [ + "/home/docker/src/system/out/riju-system-privileged", + "spawn", + `${this.uid}`, + `${this.uuid}`, + "bash", + "-c", + cmdline, + ] + : ["bash", "-c", cmdline]; + const env = getEnv(this.uuid); const term = { - pty: pty.spawn("bash", ["-c", cmdline], { + pty: pty.spawn(args[0], args.slice(1), { name: "xterm-color", - cwd: this.tmpdir!, - env: process.env as { [key: string]: string }, + env, }), live: true, }; @@ -186,8 +200,8 @@ export class Session { }; cleanup = async () => { this.log(`Cleaning up session`); - if (this.tmpdirCleanup) { - this.tmpdirCleanup(); + if (this.homedir) { + await callPrivileged(["teardown", this.uuid], this.log); } if (this.uidCleanup) { await this.uidCleanup(); diff --git a/backend/src/config.ts b/backend/src/config.ts new file mode 100644 index 0000000..133630c --- /dev/null +++ b/backend/src/config.ts @@ -0,0 +1,3 @@ +import * as process from "process"; + +export const PRIVILEGED = process.env.RIJU_PRIVILEGED ? true : false; diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 021d4f8..3859c38 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -6,6 +6,7 @@ export interface LangConfig { main: string; prefix?: string; suffix?: string; + alwaysCreate?: boolean; compile?: string; run: string; template: string; @@ -220,7 +221,7 @@ int main() { monacoLang: "csharp", main: "main.cs", compile: "mcs main.cs", - run: "./main.exe", + run: "mono main.exe", template: `class main { static void Main(string[] args) { System.Console.WriteLine("Hello, world!"); @@ -326,9 +327,9 @@ output = "Hello, world!" aliases: ["elv"], name: "Elvish", monacoLang: "plaintext", - repl: "SHELL=/usr/bin/elvish HOME=. elvish", + repl: `SHELL=/usr/bin/elvish HOME="$PWD" elvish`, main: ".elvish/rc.elv", - run: "SHELL=/usr/bin/elvish HOME=. elvish", + run: `SHELL=/usr/bin/elvish HOME="$PWD" elvish`, template: `echo "Hello, world!" `, }, @@ -451,8 +452,8 @@ main = putStrLn "Hello, world!" repl: "ink", main: "main.ink", run: "ink main.ink; ink", - template: `std := load('../../opt/ink/std') -str := load('../../opt/ink/str') + template: `std := load('../../../opt/ink/std') +str := load('../../../opt/ink/str') log := std.log @@ -535,9 +536,9 @@ PLEASE GIVE UP aliases: ["kshell"], name: "Ksh", monacoLang: "shell", - repl: "SHELL=/usr/bin/ksh HOME=. ksh", + repl: `SHELL=/usr/bin/ksh HOME="$PWD" ksh`, main: ".kshrc", - run: "SHELL=/usr/bin/ksh HOME=. ksh", + run: `SHELL=/usr/bin/ksh HOME="$PWD" ksh`, template: `echo "Hello, world!" `, }, @@ -830,9 +831,9 @@ binding_irb.run(IRB.conf) aliases: ["shell", "posix", "posixsh", "ash", "dash", "posh"], name: "Sh", monacoLang: "shell", - repl: "SHELL=/usr/bin/sh HOME=. posh -l", + repl: `SHELL=/usr/bin/sh HOME="$PWD" posh -l`, main: ".profile", - run: "SHELL=/usr/bin/sh HOME=. posh -l", + run: `SHELL=/usr/bin/sh HOME="$PWD" posh -l`, template: `echo "Hello, world!" `, }, @@ -992,7 +993,7 @@ END monacoLang: "tcl", repl: "tclsh", main: ".tclshrc", - run: "HOME=. tclsh", + run: `HOME="$PWD" tclsh`, template: `puts {Hello, world!} `, }, @@ -1000,9 +1001,9 @@ END aliases: ["tcshell", "tcshrc"], name: "Tcsh", monacoLang: "shell", - repl: "SHELL=/usr/bin/tcsh HOME=. tcsh", + repl: `SHELL=/usr/bin/tcsh HOME="$PWD" tcsh`, main: ".tcshrc", - run: "SHELL=/usr/bin/tcsh HOME=. tcsh", + run: `SHELL=/usr/bin/tcsh HOME="$PWD" tcsh`, template: `echo "Hello, world!" `, }, @@ -1104,7 +1105,8 @@ message: monacoLang: "shell", repl: "SHELL=/usr/bin/zsh zsh", main: ".zshrc", - run: "SHELL=/usr/bin/zsh ZDOTDIR=. zsh", + alwaysCreate: true, + run: `SHELL=/usr/bin/zsh ZDOTDIR="$PWD" zsh`, template: `echo "Hello, world!" `, }, diff --git a/backend/src/users.ts b/backend/src/users.ts index 6e3c8f4..0742a6b 100644 --- a/backend/src/users.ts +++ b/backend/src/users.ts @@ -1,16 +1,17 @@ import { spawn } from "child_process"; import * as fs from "fs"; -import * as process from "process"; import * as AsyncLock from "async-lock"; import * as _ from "lodash"; import * as parsePasswd from "parse-passwd"; +import { PRIVILEGED } from "./config"; +import { callPrivileged } from "./util"; + // Keep in sync with system/src/riju-system-privileged.c const MIN_UID = 2000; const MAX_UID = 65000; -const PRIVILEGED = process.env.RIJU_PRIVILEGED ? true : false; const CUR_UID = parseInt(process.env.UID || "") || null; let availIds: number[] | null = null; @@ -29,7 +30,7 @@ async function readExistingUsers(log: (msg: string) => void) { }) ) ) - .filter(({ username }) => username.startsWith("riju_user")) + .filter(({ username }) => username.startsWith("riju")) .map(({ uid }) => parseInt(uid)) .filter((uid) => !isNaN(uid) && uid >= MIN_UID && uid < MAX_UID); nextId = (_.max(availIds) || MIN_UID - 1) + 1; @@ -40,33 +41,11 @@ async function createUser(log: (msg: string) => void): Promise { if (nextId! >= MAX_UID) { throw new Error("too many users"); } - return await new Promise((resolve, reject) => { - const uid = nextId!; - const useradd = spawn("system/out/riju-system-privileged", [ - "useradd", - `${uid}`, - ]); - let output = ""; - useradd.stdout.on("data", (data) => { - output += `${data}`; - }); - useradd.stderr.on("data", (data) => { - output += `${data}`; - }); - useradd.on("close", (code) => { - output = output.trim(); - if (output) { - log("Output from useradd:\n" + output); - } - if (code === 0) { - log(`Created new user with ID ${uid}`); - nextId! += 1; - resolve(uid); - } else { - reject(`useradd failed with error code ${code}`); - } - }); - }); + const uid = nextId!; + await callPrivileged(["useradd", `${uid}`], log); + log(`Created new user with ID ${uid}`); + nextId! += 1; + return uid; } export async function borrowUser(log: (msg: string) => void) { diff --git a/backend/src/util.ts b/backend/src/util.ts new file mode 100644 index 0000000..235252c --- /dev/null +++ b/backend/src/util.ts @@ -0,0 +1,83 @@ +import { spawn, SpawnOptions } from "child_process"; +import * as process from "process"; + +interface Options extends SpawnOptions { + input?: string; +} + +export function getEnv(uuid: string) { + const cwd = `/tmp/riju/${uuid}`; + return { + HOME: cwd, + HOSTNAME: "riju", + LANG: "C.UTF-8", + LC_ALL: "C.UTF-8", + PATH: "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/bin", + PWD: cwd, + SHELL: "/usr/bin/bash", + TERM: "xterm-color", + }; +} + +export async function call( + args: string[], + log: (msg: string) => void, + options?: Options +) { + options = options || {}; + const input = options.input; + delete options.input; + const proc = spawn(args[0], args.slice(1), options); + if (input) { + proc.stdin!.end(input); + } + let output = ""; + proc.stdout!.on("data", (data: Buffer) => { + output += `${data}`; + }); + proc.stderr!.on("data", (data: Buffer) => { + output += `${data}`; + }); + await new Promise((resolve, reject) => { + proc.on("error", reject); + proc.on("close", (code: number) => { + output = output.trim(); + if (output) { + log(`Output from ${args[0]}:\n` + output); + } + if (code === 0) { + resolve(); + } else { + reject(`command ${args[0]} failed with error code ${code}`); + } + }); + }); +} + +export async function callPrivileged( + args: string[], + log: (msg: string) => void, + options?: Options +) { + await call( + ["/home/docker/src/system/out/riju-system-privileged"].concat(args), + log, + options + ); +} + +export async function spawnPrivileged( + uid: number, + uuid: string, + args: string[], + log: (msg: string) => void, + options?: Options +) { + options = options || {}; + options.env = getEnv(uuid); + await callPrivileged( + ["spawn", `${uid}`, `${uuid}`].concat(args), + log, + options + ); +} diff --git a/frontend/src/app.ts b/frontend/src/app.ts index 95deb8d..28bdd2f 100644 --- a/frontend/src/app.ts +++ b/frontend/src/app.ts @@ -10,92 +10,98 @@ interface RijuConfig { template: string; } -const config: RijuConfig = (window as any).rijuConfig; +async function main() { + const config: RijuConfig = (window as any).rijuConfig; -const term = new Terminal(); -const fitAddon = new FitAddon(); -term.loadAddon(fitAddon); -term.open(document.getElementById("terminal")!); + const term = new Terminal(); + const fitAddon = new FitAddon(); + term.loadAddon(fitAddon); + term.open(document.getElementById("terminal")!); -fitAddon.fit(); -window.addEventListener("resize", () => fitAddon.fit()); + fitAddon.fit(); + window.addEventListener("resize", () => fitAddon.fit()); -term.write("Connecting to server..."); - -const initialRetryDelayMs = 200; -let retryDelayMs = initialRetryDelayMs; - -function tryConnect() { - console.log("Connecting to server..."); - socket = new WebSocket( - (document.location.protocol === "http:" ? "ws://" : "wss://") + - document.location.host + - `/api/v1/ws?lang=${encodeURIComponent(config.id)}` + await new Promise((resolve) => + term.write("Connecting to server...", resolve) ); - socket.addEventListener("open", () => { - console.log("Successfully connected to server"); - }); - socket.addEventListener("message", (event: MessageEvent) => { - let message: any; - try { - message = JSON.parse(event.data); - } catch (err) { - console.error("Malformed message from server:", event.data); - return; - } - if (message?.event && message?.event !== "error") { - retryDelayMs = initialRetryDelayMs; - } - switch (message?.event) { - case "terminalClear": - term.reset(); + + const initialRetryDelayMs = 200; + let retryDelayMs = initialRetryDelayMs; + + function tryConnect() { + console.log("Connecting to server..."); + socket = new WebSocket( + (document.location.protocol === "http:" ? "ws://" : "wss://") + + document.location.host + + `/api/v1/ws?lang=${encodeURIComponent(config.id)}` + ); + socket.addEventListener("open", () => { + console.log("Successfully connected to server"); + }); + socket.addEventListener("message", (event: MessageEvent) => { + let message: any; + try { + message = JSON.parse(event.data); + } catch (err) { + console.error("Malformed message from server:", event.data); return; - case "terminalOutput": - if (typeof message.output !== "string") { + } + if (message?.event && message?.event !== "error") { + retryDelayMs = initialRetryDelayMs; + } + switch (message?.event) { + case "terminalClear": + term.reset(); + return; + case "terminalOutput": + if (typeof message.output !== "string") { + console.error("Unexpected message from server:", message); + return; + } + term.write(message.output); + return; + default: console.error("Unexpected message from server:", message); return; - } - term.write(message.output); - return; - default: - console.error("Unexpected message from server:", message); - return; - } + } + }); + socket.addEventListener("close", (event: CloseEvent) => { + if (event.wasClean) { + console.log("Connection closed cleanly"); + } else { + console.error("Connection died"); + } + scheduleConnect(); + }); + } + + function scheduleConnect() { + const delay = retryDelayMs * Math.random(); + console.log(`Trying to reconnect in ${Math.floor(delay)}ms`); + setTimeout(tryConnect, delay); + retryDelayMs *= 2; + } + + let socket: WebSocket | null = null; + tryConnect(); + + term.onData( + (data) => + socket && + socket.send(JSON.stringify({ event: "terminalInput", input: data })) + ); + + const editor = monaco.editor.create(document.getElementById("editor")!, { + minimap: { enabled: false }, + scrollbar: { verticalScrollbarSize: 0 }, }); - socket.addEventListener("close", (event: CloseEvent) => { - if (event.wasClean) { - console.log("Connection closed cleanly"); - } else { - console.error("Connection died"); - } - scheduleConnect(); + window.addEventListener("resize", () => editor.layout()); + editor.getModel()!.setValue(config.template); + monaco.editor.setModelLanguage(editor.getModel()!, config.monacoLang); + + document.getElementById("runButton")!.addEventListener("click", () => { + socket?.send(JSON.stringify({ event: "runCode", code: editor.getValue() })); }); } -function scheduleConnect() { - const delay = retryDelayMs * Math.random(); - console.log(`Trying to reconnect in ${Math.floor(delay)}ms`); - setTimeout(tryConnect, delay); - retryDelayMs *= 2; -} - -let socket: WebSocket | null = null; -tryConnect(); - -term.onData( - (data) => - socket && - socket.send(JSON.stringify({ event: "terminalInput", input: data })) -); - -const editor = monaco.editor.create(document.getElementById("editor")!, { - minimap: { enabled: false }, - scrollbar: { verticalScrollbarSize: 0 }, -}); -window.addEventListener("resize", () => editor.layout()); -editor.getModel()!.setValue(config.template); -monaco.editor.setModelLanguage(editor.getModel()!, config.monacoLang); - -document.getElementById("runButton")!.addEventListener("click", () => { - socket?.send(JSON.stringify({ event: "runCode", code: editor.getValue() })); -}); +main().catch(console.error); diff --git a/package.json b/package.json index 3f23bc1..5b3d502 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "riju", - "version": "0", + "version": "0.0.0", "license": "MIT", "private": true, "dependencies": { @@ -11,6 +11,7 @@ "@types/lodash": "^4.14.155", "@types/mkdirp": "^1.0.1", "@types/parse-passwd": "^1.0.0", + "@types/rimraf": "^3.0.0", "@types/tmp": "^0.2.0", "@types/uuid": "^8.0.0", "app-root-path": "^3.0.0", @@ -21,13 +22,12 @@ "express-ws": "^4.0.0", "file-loader": "^6.0.0", "lodash": "^4.17.15", - "mkdirp": "^1.0.4", "monaco-editor": "^0.20.0", "node-cleanup": "^2.1.2", "node-pty": "^0.9.0", + "npm-run-all": "^4.1.5", "parse-passwd": "^1.0.0", "style-loader": "^1.2.1", - "tmp": "^0.2.1", "ts-loader": "^7.0.5", "typescript": "^3.9.5", "uuid": "^8.1.0", @@ -38,12 +38,14 @@ }, "scripts": { "backend": "tsc", - "backend-dev": "tsc --watch", + "backend-dev": "tsc --watch --preserveWatchOutput", "frontend": "webpack --production", "frontend-dev": "webpack --development --watch", "server": "scripts/setup.bash && node backend/out/server.js", "server-dev": "watchexec -w backend/out -r 'scripts/setup.bash && node backend/out/server.js'", "system": "scripts/compile-system.bash", - "system-dev": "watchexec -w system/src -n scripts/compile-system.bash" + "system-dev": "watchexec -w system/src -n scripts/compile-system.bash", + "build": "run-s backend frontend system", + "dev": "run-p backend-dev frontend-dev system-dev server-dev" } } diff --git a/scripts/docker-install-phase0.bash b/scripts/docker-install-phase0.bash new file mode 100755 index 0000000..7382789 --- /dev/null +++ b/scripts/docker-install-phase0.bash @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail +set -x + +export DEBIAN_FRONTEND=noninteractive +apt-get update +(yes || true) | unminimize +rm -rf /var/lib/apt/lists/* + +rm "$0" diff --git a/scripts/docker-install-phase1.bash b/scripts/docker-install-phase1.bash index fa3932b..5f47de2 100755 --- a/scripts/docker-install-phase1.bash +++ b/scripts/docker-install-phase1.bash @@ -2,6 +2,7 @@ set -e set -o pipefail +set -x dpkg --add-architecture i386 diff --git a/scripts/docker-install-phase2.bash b/scripts/docker-install-phase2.bash index 5ec38e5..ac8fdf2 100755 --- a/scripts/docker-install-phase2.bash +++ b/scripts/docker-install-phase2.bash @@ -2,6 +2,7 @@ set -e set -o pipefail +set -x packages=" diff --git a/scripts/docker-install-phase3a.bash b/scripts/docker-install-phase3a.bash index 770409d..ea98b4c 100755 --- a/scripts/docker-install-phase3a.bash +++ b/scripts/docker-install-phase3a.bash @@ -2,6 +2,7 @@ set -e set -o pipefail +set -x packages=" diff --git a/scripts/docker-install-phase3b.bash b/scripts/docker-install-phase3b.bash index b4ced0b..60e9aad 100755 --- a/scripts/docker-install-phase3b.bash +++ b/scripts/docker-install-phase3b.bash @@ -2,6 +2,7 @@ set -e set -o pipefail +set -x packages=" diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index 6ca413b..e14bf0c 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -2,6 +2,7 @@ set -e set -o pipefail +set -x packages=" diff --git a/scripts/docker-install-phase3d.bash b/scripts/docker-install-phase3d.bash index 74f09b7..dca024b 100755 --- a/scripts/docker-install-phase3d.bash +++ b/scripts/docker-install-phase3d.bash @@ -2,6 +2,7 @@ set -e set -o pipefail +set -x packages=" diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 69fe156..8274235 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -2,6 +2,7 @@ set -e set -o pipefail +set -x npm config set unsafe-perm true PERL_MM_USE_DEFAULT=1 cpan App::cpanminus diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index 4ccbe29..ea3cce3 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -2,6 +2,7 @@ set -e set -o pipefail +set -x # Needed for project infrastructure cd /tmp diff --git a/scripts/docker-install-phase6.bash b/scripts/docker-install-phase6.bash index cc0efa2..eefee5a 100755 --- a/scripts/docker-install-phase6.bash +++ b/scripts/docker-install-phase6.bash @@ -2,19 +2,22 @@ set -e set -o pipefail +set -x uid="$1" rm -rf /tmp/hsperfdata_root if [[ -n "$uid" ]] && (( "$uid" != 0 )); then - useradd --uid="$uid" --create-home --groups sudo docker - passwd -d docker + useradd --uid="$uid" --password "!" --create-home --groups sudo docker else - useradd --create-home --groups sudo docker - passwd -d docker + useradd --password "!" --create-home --groups sudo docker fi +tee /etc/sudoers.d/99-passwordless >/dev/null <<"EOF" +%sudo ALL=(ALL:ALL) NOPASSWD: ALL +EOF + touch /home/docker/.zshrc chown docker:docker /home/docker/.zshrc diff --git a/scripts/riju-serve.bash b/scripts/riju-serve.bash index 13e4bb4..123fbbf 100755 --- a/scripts/riju-serve.bash +++ b/scripts/riju-serve.bash @@ -18,4 +18,4 @@ else fi docker run ${it} -e TLS -e TLS_PRIVATE_KEY -e TLS_CERTIFICATE \ - --rm -p 0.0.0.0:80:6119 -p 0.0.0.0:443:6120 riju:prod + --rm -p 0.0.0.0:80:6119 -p 0.0.0.0:443:6120 -h riju riju:prod diff --git a/scripts/setup.bash b/scripts/setup.bash index b884776..08923fb 100755 --- a/scripts/setup.bash +++ b/scripts/setup.bash @@ -4,4 +4,7 @@ set -e set -o pipefail mkdir -p /tmp/riju -rm -rf /tmp/riju/* +if [[ -x system/out/riju-system-privileged ]]; then + system/out/riju-system-privileged teardown "*" +fi +chmod a=x,u=rwx /tmp/riju diff --git a/system/src/riju-system-privileged.c b/system/src/riju-system-privileged.c index 6ada086..8ad72d1 100644 --- a/system/src/riju-system-privileged.c +++ b/system/src/riju-system-privileged.c @@ -1,14 +1,18 @@ #define _GNU_SOURCE +#include +#include #include #include #include +#include +#include #include // Keep in sync with backend/src/users.ts const int MIN_UID = 2000; const int MAX_UID = 65000; -void die(const char *msg) +void die(char *msg) { fprintf(stderr, "%s\n", msg); exit(1); @@ -17,19 +21,84 @@ void die(const char *msg) void die_with_usage() { die("usage:\n" - " riju-system-privileged useradd UID"); + " riju-system-privileged useradd UID\n" + " riju-system-privileged spawn UID CMDLINE...\n" + " riju-system-privileged setup UID UUID\n" + " riju-system-privileged teardown UUID"); +} + +int parseUID(char *str) +{ + char *endptr; + long uid = strtol(str, &endptr, 10); + if (!*str || *endptr) + die("uid must be an integer"); + if (uid < MIN_UID || uid >= MAX_UID) + die("uid is out of range"); + return uid; +} + +char *parseUUID(char *uuid) +{ + if (!*uuid) + die("illegal uuid"); + for (char *ptr = uuid; *ptr; ++ptr) + if (!((*ptr >= 'a' && *ptr <= 'z') || (*ptr >= '0' && *ptr <= '9') || *ptr == '-')) + die("illegal uuid"); + return uuid; } void useradd(int uid) { char *cmdline; - if (asprintf(&cmdline, "useradd -M -N -l -r -u %1$d riju_user%1$d", uid) < 0) { + if (asprintf(&cmdline, "groupadd -g %1$d riju%1$d", uid) < 0) die("asprintf failed"); - } int status = system(cmdline); - if (status) { + if (status) + die("groupadd failed"); + if (asprintf(&cmdline, "useradd -M -N -l -r -u %1$d -g %1$d -p '!' riju%1$d", uid) < 0) + die("asprintf failed"); + status = system(cmdline); + if (status) die("useradd failed"); - } +} + +void spawn(int uid, char *uuid, char **cmdline) +{ + char *cwd; + if (asprintf(&cwd, "/tmp/riju/%s", uuid) < 0) + die("asprintf failed"); + if (chdir(cwd) < 0) + die("chdir failed"); + if (setgid(uid) < 0) + die("setgid failed"); + if (setgroups(0, NULL) < 0) + die("setgroups failed"); + if (setuid(uid) < 0) + die("setuid failed"); + umask(077); + execvp(cmdline[0], cmdline); + die("execvp failed"); +} + +void setup(int uid, char *uuid) +{ + char *cmdline; + if (asprintf(&cmdline, "install -d -o riju%1$d -g riju%1$d -m 700 /tmp/riju/%2$s", uid, uuid) < 0) + die("asprintf failed"); + int status = system(cmdline); + if (status) + die("install failed"); +} + +void teardown(char *uuid) +{ + char *cmdline; + if (asprintf(&cmdline, "rm -rf /tmp/riju/%s", uuid) < 0) + die("asprintf failed"); + int status = system(cmdline); + if (status) + die("rm failed"); } int main(int argc, char **argv) @@ -40,15 +109,28 @@ int main(int argc, char **argv) if (!strcmp(argv[1], "useradd")) { if (argc != 3) die_with_usage(); - char *endptr; - long uid = strtol(argv[2], &endptr, 10); - if (!argv[2] || *endptr) { - die("uid must be an integer"); - } - if (uid < MIN_UID || uid >= MAX_UID) { - die("uid is out of range"); - } - useradd(uid); + useradd(parseUID(argv[2])); + return 0; + } + if (!strcmp(argv[1], "spawn")) { + if (argc < 5) + die_with_usage(); + spawn(parseUID(argv[2]), parseUUID(argv[3]), &argv[4]); + return 0; + } + if (!strcmp(argv[1], "setup")) { + if (argc != 4) + die_with_usage(); + int uid = parseUID(argv[2]); + char *uuid = parseUUID(argv[3]); + setup(uid, uuid); + return 0; + } + if (!strcmp(argv[1], "teardown")) { + if (argc != 3) + die_with_usage(); + char *uuid = strcmp(argv[2], "*") ? parseUUID(argv[2]) : "*"; + teardown(uuid); return 0; } die_with_usage(); diff --git a/yarn.lock b/yarn.lock index a312345..72b89b7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -55,6 +55,14 @@ "@types/qs" "*" "@types/serve-static" "*" +"@types/glob@*": + version "7.1.2" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.2.tgz#06ca26521353a545d94a0adc74f38a59d232c987" + integrity sha512-VgNIkxK+j7Nz5P7jvUZlRvhuPSmsEfS03b0alKcq5V/STUKAa3Plemsn5mrQUO7am6OErJ4rhGEGJbACclrtRA== + dependencies: + "@types/minimatch" "*" + "@types/node" "*" + "@types/json-schema@^7.0.4": version "7.0.4" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339" @@ -70,6 +78,11 @@ resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.2.tgz#857a118d8634c84bba7ae14088e4508490cd5da5" integrity sha512-4kPlzbljFcsttWEq6aBW0OZe6BDajAmyvr2xknBG92tejQnvdGtT9+kXSZ580DqpxY9qG2xeQVF9Dq0ymUTo5Q== +"@types/minimatch@*": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" + integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== + "@types/mkdirp@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-1.0.1.tgz#0930b948914a78587de35458b86c907b6e98bbf6" @@ -97,6 +110,14 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== +"@types/rimraf@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/rimraf/-/rimraf-3.0.0.tgz#b9d03f090ece263671898d57bb7bb007023ac19f" + integrity sha512-7WhJ0MdpFgYQPXlF4Dx+DhgvlPCfz/x5mHaeDQAKhcenvQP1KCpLQ18JklAqeGMYSAT2PxLpzd0g2/HE7fj7hQ== + dependencies: + "@types/glob" "*" + "@types/node" "*" + "@types/serve-static@*": version "1.13.4" resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.4.tgz#6662a93583e5a6cabca1b23592eb91e12fa80e7c" @@ -663,7 +684,7 @@ camelcase@^5.0.0, camelcase@^5.3.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -chalk@2.4.2, chalk@^2.3.0, chalk@^2.4.2: +chalk@2.4.2, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -880,7 +901,7 @@ create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: safe-buffer "^5.0.1" sha.js "^2.4.8" -cross-spawn@6.0.5, cross-spawn@^6.0.0: +cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== @@ -954,6 +975,13 @@ decode-uri-component@^0.2.0: resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= +define-properties@^1.1.2, define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + define-property@^0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" @@ -1100,6 +1128,39 @@ errno@^0.1.3, errno@~0.1.7: dependencies: prr "~1.0.1" +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.17.0-next.1, es-abstract@^1.17.5: + version "1.17.6" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.6.tgz#9142071707857b2cacc7b89ecb670316c3e2d52a" + integrity sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw== + dependencies: + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + is-callable "^1.2.0" + is-regex "^1.1.0" + object-inspect "^1.7.0" + object-keys "^1.1.1" + object.assign "^4.1.0" + string.prototype.trimend "^1.0.1" + string.prototype.trimstart "^1.0.1" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -1410,6 +1471,11 @@ fsevents@~2.1.2: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + get-caller-file@^2.0.1: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" @@ -1500,6 +1566,11 @@ has-flag@^3.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= +has-symbols@^1.0.0, has-symbols@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" + integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== + has-value@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" @@ -1531,6 +1602,13 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.0.0" +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + hash-base@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" @@ -1564,6 +1642,11 @@ homedir-polyfill@^1.0.1: dependencies: parse-passwd "^1.0.0" +hosted-git-info@^2.1.4: + version "2.8.8" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" + integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== + http-errors@1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" @@ -1695,6 +1778,11 @@ is-accessor-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + is-binary-path@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" @@ -1714,6 +1802,11 @@ is-buffer@^1.1.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== +is-callable@^1.1.4, is-callable@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb" + integrity sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw== + is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" @@ -1728,6 +1821,11 @@ is-data-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" +is-date-object@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" + integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== + is-descriptor@^0.1.0: version "0.1.6" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" @@ -1801,11 +1899,25 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" +is-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.0.tgz#ece38e389e490df0dc21caea2bd596f987f767ff" + integrity sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw== + dependencies: + has-symbols "^1.0.1" + is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= +is-symbol@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" + integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== + dependencies: + has-symbols "^1.0.1" + is-windows@^1.0.1, is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" @@ -1848,7 +1960,7 @@ jake@^10.6.1: filelist "^1.0.1" minimatch "^3.0.4" -json-parse-better-errors@^1.0.2: +json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== @@ -1903,6 +2015,16 @@ lcid@^2.0.0: dependencies: invert-kv "^2.0.0" +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + loader-runner@^2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" @@ -2021,6 +2143,11 @@ memory-fs@^0.5.0: errno "^0.1.3" readable-stream "^2.0.1" +memorystream@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" + integrity sha1-htcJCzDORV1j+64S3aUaR93K+bI= + merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" @@ -2141,11 +2268,6 @@ mkdirp@^0.5.1, mkdirp@^0.5.3: dependencies: minimist "^1.2.5" -mkdirp@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - monaco-editor@^0.20.0: version "0.20.0" resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.20.0.tgz#5d5009343a550124426cb4d965a4d27a348b4dea" @@ -2251,6 +2373,16 @@ node-pty@^0.9.0: dependencies: nan "^2.14.0" +normalize-package-data@^2.3.2: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" @@ -2263,6 +2395,21 @@ normalize-path@^3.0.0, normalize-path@~3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== +npm-run-all@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba" + integrity sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ== + dependencies: + ansi-styles "^3.2.1" + chalk "^2.4.1" + cross-spawn "^6.0.5" + memorystream "^0.3.1" + minimatch "^3.0.4" + pidtree "^0.3.0" + read-pkg "^3.0.0" + shell-quote "^1.6.1" + string.prototype.padend "^3.0.0" + npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" @@ -2284,6 +2431,16 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" +object-inspect@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0" + integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA== + +object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + object-visit@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" @@ -2291,6 +2448,16 @@ object-visit@^1.0.0: dependencies: isobject "^3.0.0" +object.assign@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" @@ -2386,6 +2553,14 @@ parse-asn1@^5.0.0, parse-asn1@^5.1.5: pbkdf2 "^3.0.3" safe-buffer "^5.1.1" +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + parse-passwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" @@ -2426,11 +2601,23 @@ path-key@^2.0.0, path-key@^2.0.1: resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== + dependencies: + pify "^3.0.0" + pbkdf2@^3.0.3: version "3.1.1" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94" @@ -2447,6 +2634,16 @@ picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== +pidtree@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.1.tgz#ef09ac2cc0533df1f3250ccf2c4d366b0d12114a" + integrity sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA== + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + pify@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" @@ -2645,6 +2842,15 @@ raw-body@2.4.0: iconv-lite "0.4.24" unpipe "1.0.0" +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + "readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" @@ -2741,6 +2947,13 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= +resolve@^1.10.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" + integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== + dependencies: + path-parse "^1.0.6" + ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" @@ -2753,13 +2966,6 @@ rimraf@^2.5.4, rimraf@^2.6.3: dependencies: glob "^7.1.3" -rimraf@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" @@ -2815,7 +3021,7 @@ schema-utils@^2.6.5, schema-utils@^2.6.6: ajv "^6.12.2" ajv-keywords "^3.4.1" -semver@^5.5.0, semver@^5.6.0: +"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.6.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== @@ -2906,6 +3112,11 @@ shebang-regex@^1.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= +shell-quote@^1.6.1: + version "1.7.2" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" + integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== + signal-exit@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" @@ -2980,6 +3191,32 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +spdx-correct@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.5" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654" + integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q== + split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" @@ -3048,6 +3285,30 @@ string-width@^3.0.0, string-width@^3.1.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" +string.prototype.padend@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.1.0.tgz#dc08f57a8010dc5c153550318f67e13adbb72ac3" + integrity sha512-3aIv8Ffdp8EZj8iLwREGpQaUZiPyrWrpzMBHvkiSW/bK/EGve9np07Vwy7IJ5waydpGXzQZu/F8Oze2/IWkBaA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + +string.prototype.trimend@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" + integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + +string.prototype.trimstart@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" + integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + string_decoder@^1.0.0, string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" @@ -3069,6 +3330,11 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" @@ -3140,13 +3406,6 @@ timers-browserify@^2.0.4: dependencies: setimmediate "^1.0.4" -tmp@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" - integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== - dependencies: - rimraf "^3.0.0" - to-arraybuffer@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" @@ -3334,6 +3593,14 @@ v8-compile-cache@2.0.3: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe" integrity sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w== +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" From 06bb57fed894cd133a09f6356319094dbf92924f Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 22 Jun 2020 20:51:48 -0600 Subject: [PATCH 078/388] Log on returning uid --- backend/src/api.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/src/api.ts b/backend/src/api.ts index 9897468..2c905e9 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -205,6 +205,7 @@ export class Session { } if (this.uidCleanup) { await this.uidCleanup(); + this.log(`Returned uid ${this.uid}`); } }; } From 3255a26d732c7c1a421f111089975f357d2725e4 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 22 Jun 2020 20:57:44 -0600 Subject: [PATCH 079/388] Add TeX --- backend/src/langs.ts | 10 ++++++++++ scripts/docker-install-phase2.bash | 2 ++ scripts/docker-install-phase3d.bash | 3 +++ 3 files changed, 15 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 3859c38..eeabee9 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1005,6 +1005,16 @@ END main: ".tcshrc", run: `SHELL=/usr/bin/tcsh HOME="$PWD" tcsh`, template: `echo "Hello, world!" +`, + }, + tex: { + aliases: ["latex", "xetex", "plaintex"], + name: "TeX", + monacoLang: "plaintext", + repl: "tex", + main: "main.tex", + run: "tex main.tex", + template: `\\message{Hello, world!} `, }, typescript: { diff --git a/scripts/docker-install-phase2.bash b/scripts/docker-install-phase2.bash index ac8fdf2..37d96fd 100755 --- a/scripts/docker-install-phase2.bash +++ b/scripts/docker-install-phase2.bash @@ -15,6 +15,7 @@ python3-pip yarn # Handy utilities +apt-file bsdmainutils curl emacs-nox @@ -24,6 +25,7 @@ jq lsof make man-db +moreutils nano sudo tmux diff --git a/scripts/docker-install-phase3d.bash b/scripts/docker-install-phase3d.bash index dca024b..6ff69b4 100755 --- a/scripts/docker-install-phase3d.bash +++ b/scripts/docker-install-phase3d.bash @@ -37,6 +37,9 @@ tcl # Tcsh tcsh +# TeX +texlive-binaries + # Unlambda unlambda From 881d8d6976f5c188871043fcc3dd853e30065cf2 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 22 Jun 2020 21:04:22 -0600 Subject: [PATCH 080/388] Report errors on frontend --- backend/src/api.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/backend/src/api.ts b/backend/src/api.ts index 2c905e9..27f9ba0 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -42,6 +42,19 @@ export class Session { this.run().catch((err) => { this.log(`Error while setting up environment for pty`); console.log(err); + try { + this.ws.send(JSON.stringify({ event: "terminalClear" })); + this.ws.send( + JSON.stringify({ + event: "terminalOutput", + output: `Riju encountered an unexpected error: ${err} +\rYou may want to save your code and refresh the page. +`, + }) + ); + } catch (err) { + // + } }); } handleClientMessage = (event: string) => { From fc9cbbc7c69ea35a8efc815783a78dd32f0ac890 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Thu, 25 Jun 2020 07:44:10 -0600 Subject: [PATCH 081/388] Report errors properly in deploy script --- scripts/deploy-phase1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/deploy-phase1.py b/scripts/deploy-phase1.py index 832e2fa..be09219 100755 --- a/scripts/deploy-phase1.py +++ b/scripts/deploy-phase1.py @@ -38,4 +38,4 @@ with tempfile.TemporaryDirectory() as tmpdir: check=True, ) os.chdir("riju") - subprocess.run(["scripts/deploy-phase2.py"]) + subprocess.run(["scripts/deploy-phase2.py"], check=True) From 4425f31b886f5fa215063a9f1f2cae229a53a7bb Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Tue, 23 Jun 2020 14:51:43 -0600 Subject: [PATCH 082/388] LSP working with Python!! --- backend/src/api.ts | 41 + backend/src/langs.ts | 11 + frontend/src/app.ts | 107 +++ package.json | 7 + scripts/docker-install-phase5.bash | 9 + webpack.config.js | 23 +- yarn.lock | 1286 +++++++++++++++++++++++++++- 7 files changed, 1473 insertions(+), 11 deletions(-) diff --git a/backend/src/api.ts b/backend/src/api.ts index 27f9ba0..c2b617d 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -1,8 +1,10 @@ +import { ChildProcess, spawn } from "child_process"; import * as path from "path"; import * as WebSocket from "ws"; import * as pty from "node-pty"; import { IPty } from "node-pty"; +import * as rpc from "vscode-jsonrpc"; import { v4 as getUUID } from "uuid"; import { PRIVILEGED } from "./config"; @@ -15,6 +17,11 @@ export class Session { code: string; config: LangConfig; term: { pty: IPty | null; live: boolean }; + lsp: { + proc: ChildProcess; + reader: rpc.StreamMessageReader; + writer: rpc.StreamMessageWriter; + } | null; ws: WebSocket; homedir: string | null; uid: number | null; @@ -28,6 +35,7 @@ export class Session { this.ws = ws; this.config = langs[lang]; this.term = { pty: null, live: false }; + this.lsp = null; this.code = ""; this.homedir = null; this.uid = null; @@ -83,6 +91,13 @@ export class Session { this.run(); } break; + case "lspInput": + if (!this.lsp) { + this.log(`Got LSP input before language server was started`); + } else { + this.lsp.writer.write(msg.input); + } + break; default: this.log(`Got unknown message type: ${msg.event}`); break; @@ -103,6 +118,7 @@ export class Session { alwaysCreate, compile, run, + lsp, hacks, } = this.config; if (this.term.pty) { @@ -210,6 +226,31 @@ export class Session { } } }); + if (lsp && this.lsp === null) { + const lspArgs = PRIVILEGED + ? [ + "/home/docker/src/system/out/riju-system-privileged", + "spawn", + `${this.uid}`, + `${this.uuid}`, + "bash", + "-c", + lsp, + ] + : ["bash", "-c", lsp]; + const proc = spawn(lspArgs[0], lspArgs.slice(1), { + env: getEnv(this.uuid), + }); + this.lsp = { + proc, + reader: new rpc.StreamMessageReader(proc.stdout), + writer: new rpc.StreamMessageWriter(proc.stdin), + }; + this.lsp.reader.listen((data) => { + this.ws.send(JSON.stringify({ event: "lspOutput", output: data })); + }); + this.ws.send(JSON.stringify({ event: "lspStarted" })); + } }; cleanup = async () => { this.log(`Cleaning up session`); diff --git a/backend/src/langs.ts b/backend/src/langs.ts index eeabee9..0cd07d3 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -9,6 +9,9 @@ export interface LangConfig { alwaysCreate?: boolean; compile?: string; run: string; + lsp?: string; + lspInit?: any; + lspConfig?: any; template: string; hacks?: "ghci-config"[]; } @@ -720,6 +723,14 @@ main :- repl: "python3 -u", main: "main.py", run: "python3 -u -i main.py", + lsp: "Microsoft.Python.LanguageServer", + lspInit: { + interpreter: { + properties: { + InterpreterPath: "/usr/bin/python3", + }, + }, + }, template: `print("Hello, world!") `, }, diff --git a/frontend/src/app.ts b/frontend/src/app.ts index 28bdd2f..a5b9c1c 100644 --- a/frontend/src/app.ts +++ b/frontend/src/app.ts @@ -1,4 +1,17 @@ import * as monaco from "monaco-editor"; +import { + createConnection, + MonacoLanguageClient, + MonacoServices, +} from "monaco-languageclient"; +import { Disposable } from "vscode"; +import { createMessageConnection } from "vscode-jsonrpc"; +import { + AbstractMessageReader, + DataCallback, +} from "vscode-jsonrpc/lib/messageReader"; +import { AbstractMessageWriter } from "vscode-jsonrpc/lib/messageWriter"; +import { Message } from "vscode-jsonrpc/lib/messages"; import { Terminal } from "xterm"; import { FitAddon } from "xterm-addon-fit"; @@ -7,9 +20,67 @@ import "xterm/css/xterm.css"; interface RijuConfig { id: string; monacoLang: string; + lspInit?: any; + lspConfig?: any; template: string; } +class RijuMessageReader extends AbstractMessageReader { + state: "initial" | "listening" | "closed" = "initial"; + callback: DataCallback | null = null; + messageQueue: any[] = []; + socket: WebSocket; + + constructor(socket: WebSocket) { + super(); + this.socket = socket; + this.socket.addEventListener("message", (event: MessageEvent) => { + this.readMessage(event.data); + }); + } + + listen(callback: DataCallback): void { + if (this.state === "initial") { + this.state = "listening"; + this.callback = callback; + while (this.messageQueue.length > 0) { + this.readMessage(this.messageQueue.pop()!); + } + } + } + + readMessage(rawMessage: string): void { + if (this.state === "initial") { + this.messageQueue.splice(0, 0, rawMessage); + } else if (this.state === "listening") { + let message: any; + try { + message = JSON.parse(rawMessage); + } catch (err) { + return; + } + switch (message?.event) { + case "lspOutput": + this.callback!(message?.output); + break; + } + } + } +} + +class RijuMessageWriter extends AbstractMessageWriter { + socket: WebSocket; + + constructor(socket: WebSocket) { + super(); + this.socket = socket; + } + + write(msg: Message): void { + this.socket.send(JSON.stringify({ event: "lspInput", input: msg })); + } +} + async function main() { const config: RijuConfig = (window as any).rijuConfig; @@ -29,6 +100,7 @@ async function main() { let retryDelayMs = initialRetryDelayMs; function tryConnect() { + let clientDisposable: Disposable | null = null; console.log("Connecting to server..."); socket = new WebSocket( (document.location.protocol === "http:" ? "ws://" : "wss://") + @@ -60,6 +132,36 @@ async function main() { } term.write(message.output); return; + case "lspStarted": + const connection = createMessageConnection( + new RijuMessageReader(socket!), + new RijuMessageWriter(socket!) + ); + const client = new MonacoLanguageClient({ + name: "Riju", + clientOptions: { + documentSelector: [{ pattern: "**" }], + middleware: { + workspace: { + configuration: () => { + return [config.lspConfig || {}]; + }, + }, + }, + initializationOptions: config.lspInit || {}, + }, + connectionProvider: { + get: (errorHandler, closeHandler) => + Promise.resolve( + createConnection(connection, errorHandler, closeHandler) + ), + }, + }); + clientDisposable = client.start(); + return; + case "lspOutput": + // Should be handled by RijuMessageReader + return; default: console.error("Unexpected message from server:", message); return; @@ -71,6 +173,9 @@ async function main() { } else { console.error("Connection died"); } + if (clientDisposable) { + clientDisposable.dispose(); + } scheduleConnect(); }); } @@ -102,6 +207,8 @@ async function main() { document.getElementById("runButton")!.addEventListener("click", () => { socket?.send(JSON.stringify({ event: "runCode", code: editor.getValue() })); }); + + MonacoServices.install(editor); } main().catch(console.error); diff --git a/package.json b/package.json index 5b3d502..c5a08b2 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,8 @@ "license": "MIT", "private": true, "dependencies": { + "@babel/core": "^7.10.3", + "@babel/preset-env": "^7.10.3", "@types/app-root-path": "^1.2.4", "@types/async-lock": "^1.1.2", "@types/express": "^4.17.6", @@ -16,6 +18,7 @@ "@types/uuid": "^8.0.0", "app-root-path": "^3.0.0", "async-lock": "^1.2.4", + "babel-loader": "^8.1.0", "css-loader": "^3.5.3", "ejs": "^3.1.3", "express": "^4.17.1", @@ -23,6 +26,8 @@ "file-loader": "^6.0.0", "lodash": "^4.17.15", "monaco-editor": "^0.20.0", + "monaco-editor-webpack-plugin": "^1.9.0", + "monaco-languageclient": "^0.13.0", "node-cleanup": "^2.1.2", "node-pty": "^0.9.0", "npm-run-all": "^4.1.5", @@ -31,6 +36,8 @@ "ts-loader": "^7.0.5", "typescript": "^3.9.5", "uuid": "^8.1.0", + "vscode": "^1.1.37", + "vscode-jsonrpc": "^5.0.1", "webpack": "^4.43.0", "webpack-cli": "^3.3.11", "xterm": "^4.6.0", diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index ea3cce3..003017c 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -60,6 +60,15 @@ tar -xf powershell-*.tar.gz -C /opt/powershell ln -s /opt/powershell/pwsh /usr/bin/pwsh rm powershell-*.tar.gz +# Python +cd /tmp +xml="$(curl -sSL "https://pvsc.blob.core.windows.net/python-language-server-stable?restype=container&comp=list&prefix=Python-Language-Server-linux-x64")" +nupkg="$(echo "$xml" | grep -Eo 'https://[^<]+\.nupkg' | tail -n1)" +wget -nv "${nupkg}" +unzip -d /opt/mspyls Python-Language-Server-linux-x64.*.nupkg +chmod +x /opt/mspyls/Microsoft.Python.LanguageServer +ln -s /opt/mspyls/Microsoft.Python.LanguageServer /usr/bin/Microsoft.Python.LanguageServer + # SNOBOL wget -nv ftp://ftp.snobol4.org/snobol/snobol4-2.0.tar.gz tar -xf snobol4-*.tar.gz diff --git a/webpack.config.js b/webpack.config.js index 4f0d4c1..f742d30 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,11 +1,13 @@ const path = require("path"); -const webpack = require("webpack"); + +const MonacoWebpackPlugin = require("monaco-editor-webpack-plugin"); function isProduction(argv) { return !argv.development; } module.exports = (_, argv) => ({ + devtool: isProduction(argv) ? undefined : "source-map", entry: "./frontend/src/app.ts", mode: isProduction(argv) ? "production" : "development", module: { @@ -26,8 +28,21 @@ module.exports = (_, argv) => ({ test: /\.ttf$/, use: ["file-loader"], }, + { + test: /\.js$/, + use: { + loader: "babel-loader", + options: { + presets: ["@babel/preset-env"], + }, + }, + include: /vscode-jsonrpc/, + }, ], }, + node: { + net: "mock", + }, output: { path: path.resolve(__dirname, "frontend/out"), publicPath: "/js/", @@ -36,4 +51,10 @@ module.exports = (_, argv) => ({ performance: { hints: false, }, + plugins: [new MonacoWebpackPlugin()], + resolve: { + alias: { + vscode: require.resolve("monaco-languageclient/lib/vscode-compatibility"), + }, + }, }); diff --git a/yarn.lock b/yarn.lock index 72b89b7..2f3509f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,798 @@ # yarn lockfile v1 +"@babel/code-frame@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.3.tgz#324bcfd8d35cd3d47dae18cde63d752086435e9a" + integrity sha512-fDx9eNW0qz0WkUeqL6tXEXzVlPh6Y5aCDEZesl0xBGA8ndRukX91Uk44ZqnkECp01NAZUdCAl+aiQNGi0k88Eg== + dependencies: + "@babel/highlight" "^7.10.3" + +"@babel/compat-data@^7.10.1", "@babel/compat-data@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.10.3.tgz#9af3e033f36e8e2d6e47570db91e64a846f5d382" + integrity sha512-BDIfJ9uNZuI0LajPfoYV28lX8kyCPMHY6uY4WH1lJdcicmAfxCK5ASzaeV0D/wsUaRH/cLk+amuxtC37sZ8TUg== + dependencies: + browserslist "^4.12.0" + invariant "^2.2.4" + semver "^5.5.0" + +"@babel/core@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.10.3.tgz#73b0e8ddeec1e3fdd7a2de587a60e17c440ec77e" + integrity sha512-5YqWxYE3pyhIi84L84YcwjeEgS+fa7ZjK6IBVGTjDVfm64njkR2lfDhVR5OudLk8x2GK59YoSyVv+L/03k1q9w== + dependencies: + "@babel/code-frame" "^7.10.3" + "@babel/generator" "^7.10.3" + "@babel/helper-module-transforms" "^7.10.1" + "@babel/helpers" "^7.10.1" + "@babel/parser" "^7.10.3" + "@babel/template" "^7.10.3" + "@babel/traverse" "^7.10.3" + "@babel/types" "^7.10.3" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.1" + json5 "^2.1.2" + lodash "^4.17.13" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + +"@babel/generator@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.10.3.tgz#32b9a0d963a71d7a54f5f6c15659c3dbc2a523a5" + integrity sha512-drt8MUHbEqRzNR0xnF8nMehbY11b1SDkRw03PSNH/3Rb2Z35oxkddVSi3rcaak0YJQ86PCuE7Qx1jSFhbLNBMA== + dependencies: + "@babel/types" "^7.10.3" + jsesc "^2.5.1" + lodash "^4.17.13" + source-map "^0.5.0" + +"@babel/helper-annotate-as-pure@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.1.tgz#f6d08acc6f70bbd59b436262553fb2e259a1a268" + integrity sha512-ewp3rvJEwLaHgyWGe4wQssC2vjks3E80WiUe2BpMb0KhreTjMROCbxXcEovTrbeGVdQct5VjQfrv9EgC+xMzCw== + dependencies: + "@babel/types" "^7.10.1" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.10.1": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.3.tgz#4e9012d6701bef0030348d7f9c808209bd3e8687" + integrity sha512-lo4XXRnBlU6eRM92FkiZxpo1xFLmv3VsPFk61zJKMm7XYJfwqXHsYJTY6agoc4a3L8QPw1HqWehO18coZgbT6A== + dependencies: + "@babel/helper-explode-assignable-expression" "^7.10.3" + "@babel/types" "^7.10.3" + +"@babel/helper-compilation-targets@^7.10.2": + version "7.10.2" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.2.tgz#a17d9723b6e2c750299d2a14d4637c76936d8285" + integrity sha512-hYgOhF4To2UTB4LTaZepN/4Pl9LD4gfbJx8A34mqoluT8TLbof1mhUlYuNWTEebONa8+UlCC4X0TEXu7AOUyGA== + dependencies: + "@babel/compat-data" "^7.10.1" + browserslist "^4.12.0" + invariant "^2.2.4" + levenary "^1.1.1" + semver "^5.5.0" + +"@babel/helper-create-class-features-plugin@^7.10.1": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.3.tgz#2783daa6866822e3d5ed119163b50f0fc3ae4b35" + integrity sha512-iRT9VwqtdFmv7UheJWthGc/h2s7MqoweBF9RUj77NFZsg9VfISvBTum3k6coAhJ8RWv2tj3yUjA03HxPd0vfpQ== + dependencies: + "@babel/helper-function-name" "^7.10.3" + "@babel/helper-member-expression-to-functions" "^7.10.3" + "@babel/helper-optimise-call-expression" "^7.10.3" + "@babel/helper-plugin-utils" "^7.10.3" + "@babel/helper-replace-supers" "^7.10.1" + "@babel/helper-split-export-declaration" "^7.10.1" + +"@babel/helper-create-regexp-features-plugin@^7.10.1", "@babel/helper-create-regexp-features-plugin@^7.8.3": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.1.tgz#1b8feeab1594cbcfbf3ab5a3bbcabac0468efdbd" + integrity sha512-Rx4rHS0pVuJn5pJOqaqcZR4XSgeF9G/pO/79t+4r7380tXFJdzImFnxMU19f83wjSrmKHq6myrM10pFHTGzkUA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.10.1" + "@babel/helper-regex" "^7.10.1" + regexpu-core "^4.7.0" + +"@babel/helper-define-map@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.10.3.tgz#d27120a5e57c84727b30944549b2dfeca62401a8" + integrity sha512-bxRzDi4Sin/k0drWCczppOhov1sBSdBvXJObM1NLHQzjhXhwRtn7aRWGvLJWCYbuu2qUk3EKs6Ci9C9ps8XokQ== + dependencies: + "@babel/helper-function-name" "^7.10.3" + "@babel/types" "^7.10.3" + lodash "^4.17.13" + +"@babel/helper-explode-assignable-expression@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.3.tgz#9dc14f0cfa2833ea830a9c8a1c742b6e7461b05e" + integrity sha512-0nKcR64XrOC3lsl+uhD15cwxPvaB6QKUDlD84OT9C3myRbhJqTMYir69/RWItUvHpharv0eJ/wk7fl34ONSwZw== + dependencies: + "@babel/traverse" "^7.10.3" + "@babel/types" "^7.10.3" + +"@babel/helper-function-name@^7.10.1", "@babel/helper-function-name@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.3.tgz#79316cd75a9fa25ba9787ff54544307ed444f197" + integrity sha512-FvSj2aiOd8zbeqijjgqdMDSyxsGHaMt5Tr0XjQsGKHD3/1FP3wksjnLAWzxw7lvXiej8W1Jt47SKTZ6upQNiRw== + dependencies: + "@babel/helper-get-function-arity" "^7.10.3" + "@babel/template" "^7.10.3" + "@babel/types" "^7.10.3" + +"@babel/helper-get-function-arity@^7.10.1", "@babel/helper-get-function-arity@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.3.tgz#3a28f7b28ccc7719eacd9223b659fdf162e4c45e" + integrity sha512-iUD/gFsR+M6uiy69JA6fzM5seno8oE85IYZdbVVEuQaZlEzMO2MXblh+KSPJgsZAUx0EEbWXU0yJaW7C9CdAVg== + dependencies: + "@babel/types" "^7.10.3" + +"@babel/helper-hoist-variables@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.3.tgz#d554f52baf1657ffbd7e5137311abc993bb3f068" + integrity sha512-9JyafKoBt5h20Yv1+BXQMdcXXavozI1vt401KBiRc2qzUepbVnd7ogVNymY1xkQN9fekGwfxtotH2Yf5xsGzgg== + dependencies: + "@babel/types" "^7.10.3" + +"@babel/helper-member-expression-to-functions@^7.10.1", "@babel/helper-member-expression-to-functions@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.3.tgz#bc3663ac81ac57c39148fef4c69bf48a77ba8dd6" + integrity sha512-q7+37c4EPLSjNb2NmWOjNwj0+BOyYlssuQ58kHEWk1Z78K5i8vTUsteq78HMieRPQSl/NtpQyJfdjt3qZ5V2vw== + dependencies: + "@babel/types" "^7.10.3" + +"@babel/helper-module-imports@^7.10.1", "@babel/helper-module-imports@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.3.tgz#766fa1d57608e53e5676f23ae498ec7a95e1b11a" + integrity sha512-Jtqw5M9pahLSUWA+76nhK9OG8nwYXzhQzVIGFoNaHnXF/r4l7kz4Fl0UAW7B6mqC5myoJiBP5/YQlXQTMfHI9w== + dependencies: + "@babel/types" "^7.10.3" + +"@babel/helper-module-transforms@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.10.1.tgz#24e2f08ee6832c60b157bb0936c86bef7210c622" + integrity sha512-RLHRCAzyJe7Q7sF4oy2cB+kRnU4wDZY/H2xJFGof+M+SJEGhZsb+GFj5j1AD8NiSaVBJ+Pf0/WObiXu/zxWpFg== + dependencies: + "@babel/helper-module-imports" "^7.10.1" + "@babel/helper-replace-supers" "^7.10.1" + "@babel/helper-simple-access" "^7.10.1" + "@babel/helper-split-export-declaration" "^7.10.1" + "@babel/template" "^7.10.1" + "@babel/types" "^7.10.1" + lodash "^4.17.13" + +"@babel/helper-optimise-call-expression@^7.10.1", "@babel/helper-optimise-call-expression@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.3.tgz#f53c4b6783093195b0f69330439908841660c530" + integrity sha512-kT2R3VBH/cnSz+yChKpaKRJQJWxdGoc6SjioRId2wkeV3bK0wLLioFpJROrX0U4xr/NmxSSAWT/9Ih5snwIIzg== + dependencies: + "@babel/types" "^7.10.3" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.1", "@babel/helper-plugin-utils@^7.10.3", "@babel/helper-plugin-utils@^7.8.0": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.3.tgz#aac45cccf8bc1873b99a85f34bceef3beb5d3244" + integrity sha512-j/+j8NAWUTxOtx4LKHybpSClxHoq6I91DQ/mKgAXn5oNUPIUiGppjPIX3TDtJWPrdfP9Kfl7e4fgVMiQR9VE/g== + +"@babel/helper-regex@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.10.1.tgz#021cf1a7ba99822f993222a001cc3fec83255b96" + integrity sha512-7isHr19RsIJWWLLFn21ubFt223PjQyg1HY7CZEMRr820HttHPpVvrsIN3bUOo44DEfFV4kBXO7Abbn9KTUZV7g== + dependencies: + lodash "^4.17.13" + +"@babel/helper-remap-async-to-generator@^7.10.1", "@babel/helper-remap-async-to-generator@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.3.tgz#18564f8a6748be466970195b876e8bba3bccf442" + integrity sha512-sLB7666ARbJUGDO60ZormmhQOyqMX/shKBXZ7fy937s+3ID8gSrneMvKSSb+8xIM5V7Vn6uNVtOY1vIm26XLtA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.10.1" + "@babel/helper-wrap-function" "^7.10.1" + "@babel/template" "^7.10.3" + "@babel/traverse" "^7.10.3" + "@babel/types" "^7.10.3" + +"@babel/helper-replace-supers@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.10.1.tgz#ec6859d20c5d8087f6a2dc4e014db7228975f13d" + integrity sha512-SOwJzEfpuQwInzzQJGjGaiG578UYmyi2Xw668klPWV5n07B73S0a9btjLk/52Mlcxa+5AdIYqws1KyXRfMoB7A== + dependencies: + "@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-simple-access@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.10.1.tgz#08fb7e22ace9eb8326f7e3920a1c2052f13d851e" + integrity sha512-VSWpWzRzn9VtgMJBIWTZ+GP107kZdQ4YplJlCmIrjoLVSi/0upixezHCDG8kpPVTBJpKfxTH01wDhh+jS2zKbw== + dependencies: + "@babel/template" "^7.10.1" + "@babel/types" "^7.10.1" + +"@babel/helper-split-export-declaration@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz#c6f4be1cbc15e3a868e4c64a17d5d31d754da35f" + integrity sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g== + dependencies: + "@babel/types" "^7.10.1" + +"@babel/helper-validator-identifier@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.3.tgz#60d9847f98c4cea1b279e005fdb7c28be5412d15" + integrity sha512-bU8JvtlYpJSBPuj1VUmKpFGaDZuLxASky3LhaKj3bmpSTY6VWooSM8msk+Z0CZoErFye2tlABF6yDkT3FOPAXw== + +"@babel/helper-wrap-function@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.10.1.tgz#956d1310d6696257a7afd47e4c42dfda5dfcedc9" + integrity sha512-C0MzRGteVDn+H32/ZgbAv5r56f2o1fZSA/rj/TYo8JEJNHg+9BdSmKBUND0shxWRztWhjlT2cvHYuynpPsVJwQ== + dependencies: + "@babel/helper-function-name" "^7.10.1" + "@babel/template" "^7.10.1" + "@babel/traverse" "^7.10.1" + "@babel/types" "^7.10.1" + +"@babel/helpers@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.10.1.tgz#a6827b7cb975c9d9cef5fd61d919f60d8844a973" + integrity sha512-muQNHF+IdU6wGgkaJyhhEmI54MOZBKsFfsXFhboz1ybwJ1Kl7IHlbm2a++4jwrmY5UYsgitt5lfqo1wMFcHmyw== + dependencies: + "@babel/template" "^7.10.1" + "@babel/traverse" "^7.10.1" + "@babel/types" "^7.10.1" + +"@babel/highlight@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.3.tgz#c633bb34adf07c5c13156692f5922c81ec53f28d" + integrity sha512-Ih9B/u7AtgEnySE2L2F0Xm0GaM729XqqLfHkalTsbjXGyqmf/6M0Cu0WpvqueUlW+xk88BHw9Nkpj49naU+vWw== + dependencies: + "@babel/helper-validator-identifier" "^7.10.3" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.10.3.tgz#7e71d892b0d6e7d04a1af4c3c79d72c1f10f5315" + integrity sha512-oJtNJCMFdIMwXGmx+KxuaD7i3b8uS7TTFYW/FNG2BT8m+fmGHoiPYoH0Pe3gya07WuFmM5FCDIr1x0irkD/hyA== + +"@babel/plugin-proposal-async-generator-functions@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.3.tgz#5a02453d46e5362e2073c7278beab2e53ad7d939" + integrity sha512-WUUWM7YTOudF4jZBAJIW9D7aViYC/Fn0Pln4RIHlQALyno3sXSjqmTA4Zy1TKC2D49RCR8Y/Pn4OIUtEypK3CA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.3" + "@babel/helper-remap-async-to-generator" "^7.10.3" + "@babel/plugin-syntax-async-generators" "^7.8.0" + +"@babel/plugin-proposal-class-properties@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.1.tgz#046bc7f6550bb08d9bd1d4f060f5f5a4f1087e01" + integrity sha512-sqdGWgoXlnOdgMXU+9MbhzwFRgxVLeiGBqTrnuS7LC2IBU31wSsESbTUreT2O418obpfPdGUR2GbEufZF1bpqw== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.1" + +"@babel/plugin-proposal-dynamic-import@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.1.tgz#e36979dc1dc3b73f6d6816fc4951da2363488ef0" + integrity sha512-Cpc2yUVHTEGPlmiQzXj026kqwjEQAD9I4ZC16uzdbgWgitg/UHKHLffKNCQZ5+y8jpIZPJcKcwsr2HwPh+w3XA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.1" + "@babel/plugin-syntax-dynamic-import" "^7.8.0" + +"@babel/plugin-proposal-json-strings@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.1.tgz#b1e691ee24c651b5a5e32213222b2379734aff09" + integrity sha512-m8r5BmV+ZLpWPtMY2mOKN7wre6HIO4gfIiV+eOmsnZABNenrt/kzYBwrh+KOfgumSWpnlGs5F70J8afYMSJMBg== + dependencies: + "@babel/helper-plugin-utils" "^7.10.1" + "@babel/plugin-syntax-json-strings" "^7.8.0" + +"@babel/plugin-proposal-nullish-coalescing-operator@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.1.tgz#02dca21673842ff2fe763ac253777f235e9bbf78" + integrity sha512-56cI/uHYgL2C8HVuHOuvVowihhX0sxb3nnfVRzUeVHTWmRHTZrKuAh/OBIMggGU/S1g/1D2CRCXqP+3u7vX7iA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.1" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + +"@babel/plugin-proposal-numeric-separator@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.1.tgz#a9a38bc34f78bdfd981e791c27c6fdcec478c123" + integrity sha512-jjfym4N9HtCiNfyyLAVD8WqPYeHUrw4ihxuAynWj6zzp2gf9Ey2f7ImhFm6ikB3CLf5Z/zmcJDri6B4+9j9RsA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.1" + "@babel/plugin-syntax-numeric-separator" "^7.10.1" + +"@babel/plugin-proposal-object-rest-spread@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.10.3.tgz#b8d0d22f70afa34ad84b7a200ff772f9b9fce474" + integrity sha512-ZZh5leCIlH9lni5bU/wB/UcjtcVLgR8gc+FAgW2OOY+m9h1II3ItTO1/cewNUcsIDZSYcSaz/rYVls+Fb0ExVQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-transform-parameters" "^7.10.1" + +"@babel/plugin-proposal-optional-catch-binding@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.1.tgz#c9f86d99305f9fa531b568ff5ab8c964b8b223d2" + integrity sha512-VqExgeE62YBqI3ogkGoOJp1R6u12DFZjqwJhqtKc2o5m1YTUuUWnos7bZQFBhwkxIFpWYJ7uB75U7VAPPiKETA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.1" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" + +"@babel/plugin-proposal-optional-chaining@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.10.3.tgz#9a726f94622b653c0a3a7a59cdce94730f526f7c" + integrity sha512-yyG3n9dJ1vZ6v5sfmIlMMZ8azQoqx/5/nZTSWX1td6L1H1bsjzA8TInDChpafCZiJkeOFzp/PtrfigAQXxI1Ng== + dependencies: + "@babel/helper-plugin-utils" "^7.10.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.0" + +"@babel/plugin-proposal-private-methods@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.1.tgz#ed85e8058ab0fe309c3f448e5e1b73ca89cdb598" + integrity sha512-RZecFFJjDiQ2z6maFprLgrdnm0OzoC23Mx89xf1CcEsxmHuzuXOdniEuI+S3v7vjQG4F5sa6YtUp+19sZuSxHg== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.1" + +"@babel/plugin-proposal-unicode-property-regex@^7.10.1", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.1.tgz#dc04feb25e2dd70c12b05d680190e138fa2c0c6f" + integrity sha512-JjfngYRvwmPwmnbRZyNiPFI8zxCZb8euzbCG/LxyKdeTb59tVciKo9GK9bi6JYKInk1H11Dq9j/zRqIH4KigfQ== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.1" + +"@babel/plugin-syntax-async-generators@^7.8.0": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.1.tgz#d5bc0645913df5b17ad7eda0fa2308330bde34c5" + integrity sha512-Gf2Yx/iRs1JREDtVZ56OrjjgFHCaldpTnuy9BHla10qyVT3YkIIGEtoDWhyop0ksu1GvNjHIoYRBqm3zoR1jyQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.1" + +"@babel/plugin-syntax-dynamic-import@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" + integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-json-strings@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.1.tgz#25761ee7410bc8cf97327ba741ee94e4a61b7d99" + integrity sha512-uTd0OsHrpe3tH5gRPTxG8Voh99/WCU78vIm5NMRYPAqC8lR4vajt6KkCAknCHrx24vkPdd/05yfdGSB4EIY2mg== + dependencies: + "@babel/helper-plugin-utils" "^7.10.1" + +"@babel/plugin-syntax-object-rest-spread@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-top-level-await@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.1.tgz#8b8733f8c57397b3eaa47ddba8841586dcaef362" + integrity sha512-hgA5RYkmZm8FTFT3yu2N9Bx7yVVOKYT6yEdXXo6j2JTm0wNxgqaGeQVaSHRjhfnQbX91DtjFB6McRFSlcJH3xQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.1" + +"@babel/plugin-transform-arrow-functions@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.1.tgz#cb5ee3a36f0863c06ead0b409b4cc43a889b295b" + integrity sha512-6AZHgFJKP3DJX0eCNJj01RpytUa3SOGawIxweHkNX2L6PYikOZmoh5B0d7hIHaIgveMjX990IAa/xK7jRTN8OA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.1" + +"@babel/plugin-transform-async-to-generator@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.1.tgz#e5153eb1a3e028f79194ed8a7a4bf55f862b2062" + integrity sha512-XCgYjJ8TY2slj6SReBUyamJn3k2JLUIiiR5b6t1mNCMSvv7yx+jJpaewakikp0uWFQSF7ChPPoe3dHmXLpISkg== + dependencies: + "@babel/helper-module-imports" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-remap-async-to-generator" "^7.10.1" + +"@babel/plugin-transform-block-scoped-functions@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.1.tgz#146856e756d54b20fff14b819456b3e01820b85d" + integrity sha512-B7K15Xp8lv0sOJrdVAoukKlxP9N59HS48V1J3U/JGj+Ad+MHq+am6xJVs85AgXrQn4LV8vaYFOB+pr/yIuzW8Q== + dependencies: + "@babel/helper-plugin-utils" "^7.10.1" + +"@babel/plugin-transform-block-scoping@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.10.1.tgz#47092d89ca345811451cd0dc5d91605982705d5e" + integrity sha512-8bpWG6TtF5akdhIm/uWTyjHqENpy13Fx8chg7pFH875aNLwX8JxIxqm08gmAT+Whe6AOmaTeLPe7dpLbXt+xUw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.1" + lodash "^4.17.13" + +"@babel/plugin-transform-classes@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.3.tgz#8d9a656bc3d01f3ff69e1fccb354b0f9d72ac544" + integrity sha512-irEX0ChJLaZVC7FvvRoSIxJlmk0IczFLcwaRXUArBKYHCHbOhe57aG8q3uw/fJsoSXvZhjRX960hyeAGlVBXZw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.10.1" + "@babel/helper-define-map" "^7.10.3" + "@babel/helper-function-name" "^7.10.3" + "@babel/helper-optimise-call-expression" "^7.10.3" + "@babel/helper-plugin-utils" "^7.10.3" + "@babel/helper-replace-supers" "^7.10.1" + "@babel/helper-split-export-declaration" "^7.10.1" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.3.tgz#d3aa6eef67cb967150f76faff20f0abbf553757b" + integrity sha512-GWzhaBOsdbjVFav96drOz7FzrcEW6AP5nax0gLIpstiFaI3LOb2tAg06TimaWU6YKOfUACK3FVrxPJ4GSc5TgA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.3" + +"@babel/plugin-transform-destructuring@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.1.tgz#abd58e51337815ca3a22a336b85f62b998e71907" + integrity sha512-V/nUc4yGWG71OhaTH705pU8ZSdM6c1KmmLP8ys59oOYbT7RpMYAR3MsVOt6OHL0WzG7BlTU076va9fjJyYzJMA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.1" + +"@babel/plugin-transform-dotall-regex@^7.10.1", "@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.1.tgz#920b9fec2d78bb57ebb64a644d5c2ba67cc104ee" + integrity sha512-19VIMsD1dp02RvduFUmfzj8uknaO3uiHHF0s3E1OHnVsNj8oge8EQ5RzHRbJjGSetRnkEuBYO7TG1M5kKjGLOA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.1" + +"@babel/plugin-transform-duplicate-keys@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.1.tgz#c900a793beb096bc9d4d0a9d0cde19518ffc83b9" + integrity sha512-wIEpkX4QvX8Mo9W6XF3EdGttrIPZWozHfEaDTU0WJD/TDnXMvdDh30mzUl/9qWhnf7naicYartcEfUghTCSNpA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.1" + +"@babel/plugin-transform-exponentiation-operator@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.1.tgz#279c3116756a60dd6e6f5e488ba7957db9c59eb3" + integrity sha512-lr/przdAbpEA2BUzRvjXdEDLrArGRRPwbaF9rvayuHRvdQ7lUTTkZnhZrJ4LE2jvgMRFF4f0YuPQ20vhiPYxtA== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.1" + +"@babel/plugin-transform-for-of@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.1.tgz#ff01119784eb0ee32258e8646157ba2501fcfda5" + integrity sha512-US8KCuxfQcn0LwSCMWMma8M2R5mAjJGsmoCBVwlMygvmDUMkTCykc84IqN1M7t+agSfOmLYTInLCHJM+RUoz+w== + dependencies: + "@babel/helper-plugin-utils" "^7.10.1" + +"@babel/plugin-transform-function-name@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.1.tgz#4ed46fd6e1d8fde2a2ec7b03c66d853d2c92427d" + integrity sha512-//bsKsKFBJfGd65qSNNh1exBy5Y9gD9ZN+DvrJ8f7HXr4avE5POW6zB7Rj6VnqHV33+0vXWUwJT0wSHubiAQkw== + dependencies: + "@babel/helper-function-name" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.1" + +"@babel/plugin-transform-literals@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.1.tgz#5794f8da82846b22e4e6631ea1658bce708eb46a" + integrity sha512-qi0+5qgevz1NHLZroObRm5A+8JJtibb7vdcPQF1KQE12+Y/xxl8coJ+TpPW9iRq+Mhw/NKLjm+5SHtAHCC7lAw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.1" + +"@babel/plugin-transform-member-expression-literals@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.1.tgz#90347cba31bca6f394b3f7bd95d2bbfd9fce2f39" + integrity sha512-UmaWhDokOFT2GcgU6MkHC11i0NQcL63iqeufXWfRy6pUOGYeCGEKhvfFO6Vz70UfYJYHwveg62GS83Rvpxn+NA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.1" + +"@babel/plugin-transform-modules-amd@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.1.tgz#65950e8e05797ebd2fe532b96e19fc5482a1d52a" + integrity sha512-31+hnWSFRI4/ACFr1qkboBbrTxoBIzj7qA69qlq8HY8p7+YCzkCT6/TvQ1a4B0z27VeWtAeJd6pr5G04dc1iHw== + dependencies: + "@babel/helper-module-transforms" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.1" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-commonjs@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.1.tgz#d5ff4b4413ed97ffded99961056e1fb980fb9301" + integrity sha512-AQG4fc3KOah0vdITwt7Gi6hD9BtQP/8bhem7OjbaMoRNCH5Djx42O2vYMfau7QnAzQCa+RJnhJBmFFMGpQEzrg== + dependencies: + "@babel/helper-module-transforms" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-simple-access" "^7.10.1" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-systemjs@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.3.tgz#004ae727b122b7b146b150d50cba5ffbff4ac56b" + integrity sha512-GWXWQMmE1GH4ALc7YXW56BTh/AlzvDWhUNn9ArFF0+Cz5G8esYlVbXfdyHa1xaD1j+GnBoCeoQNlwtZTVdiG/A== + dependencies: + "@babel/helper-hoist-variables" "^7.10.3" + "@babel/helper-module-transforms" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.3" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-umd@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.1.tgz#ea080911ffc6eb21840a5197a39ede4ee67b1595" + integrity sha512-EIuiRNMd6GB6ulcYlETnYYfgv4AxqrswghmBRQbWLHZxN4s7mupxzglnHqk9ZiUpDI4eRWewedJJNj67PWOXKA== + dependencies: + "@babel/helper-module-transforms" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.1" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.10.3.tgz#a4f8444d1c5a46f35834a410285f2c901c007ca6" + integrity sha512-I3EH+RMFyVi8Iy/LekQm948Z4Lz4yKT7rK+vuCAeRm0kTa6Z5W7xuhRxDNJv0FPya/her6AUgrDITb70YHtTvA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.8.3" + +"@babel/plugin-transform-new-target@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.1.tgz#6ee41a5e648da7632e22b6fb54012e87f612f324" + integrity sha512-MBlzPc1nJvbmO9rPr1fQwXOM2iGut+JC92ku6PbiJMMK7SnQc1rytgpopveE3Evn47gzvGYeCdgfCDbZo0ecUw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.1" + +"@babel/plugin-transform-object-super@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.1.tgz#2e3016b0adbf262983bf0d5121d676a5ed9c4fde" + integrity sha512-WnnStUDN5GL+wGQrJylrnnVlFhFmeArINIR9gjhSeYyvroGhBrSAXYg/RHsnfzmsa+onJrTJrEClPzgNmmQ4Gw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-replace-supers" "^7.10.1" + +"@babel/plugin-transform-parameters@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.1.tgz#b25938a3c5fae0354144a720b07b32766f683ddd" + integrity sha512-tJ1T0n6g4dXMsL45YsSzzSDZCxiHXAQp/qHrucOq5gEHncTA3xDxnd5+sZcoQp+N1ZbieAaB8r/VUCG0gqseOg== + dependencies: + "@babel/helper-get-function-arity" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.1" + +"@babel/plugin-transform-property-literals@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.1.tgz#cffc7315219230ed81dc53e4625bf86815b6050d" + integrity sha512-Kr6+mgag8auNrgEpbfIWzdXYOvqDHZOF0+Bx2xh4H2EDNwcbRb9lY6nkZg8oSjsX+DH9Ebxm9hOqtKW+gRDeNA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.1" + +"@babel/plugin-transform-regenerator@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.3.tgz#6ec680f140a5ceefd291c221cb7131f6d7e8cb6d" + integrity sha512-H5kNeW0u8mbk0qa1jVIVTeJJL6/TJ81ltD4oyPx0P499DhMJrTmmIFCmJ3QloGpQG8K9symccB7S7SJpCKLwtw== + dependencies: + regenerator-transform "^0.14.2" + +"@babel/plugin-transform-reserved-words@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.1.tgz#0fc1027312b4d1c3276a57890c8ae3bcc0b64a86" + integrity sha512-qN1OMoE2nuqSPmpTqEM7OvJ1FkMEV+BjVeZZm9V9mq/x1JLKQ4pcv8riZJMNN3u2AUGl0ouOMjRr2siecvHqUQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.1" + +"@babel/plugin-transform-shorthand-properties@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.1.tgz#e8b54f238a1ccbae482c4dce946180ae7b3143f3" + integrity sha512-AR0E/lZMfLstScFwztApGeyTHJ5u3JUKMjneqRItWeEqDdHWZwAOKycvQNCasCK/3r5YXsuNG25funcJDu7Y2g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.1" + +"@babel/plugin-transform-spread@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.10.1.tgz#0c6d618a0c4461a274418460a28c9ccf5239a7c8" + integrity sha512-8wTPym6edIrClW8FI2IoaePB91ETOtg36dOkj3bYcNe7aDMN2FXEoUa+WrmPc4xa1u2PQK46fUX2aCb+zo9rfw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.1" + +"@babel/plugin-transform-sticky-regex@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.1.tgz#90fc89b7526228bed9842cff3588270a7a393b00" + integrity sha512-j17ojftKjrL7ufX8ajKvwRilwqTok4q+BjkknmQw9VNHnItTyMP5anPFzxFJdCQs7clLcWpCV3ma+6qZWLnGMA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-regex" "^7.10.1" + +"@babel/plugin-transform-template-literals@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.3.tgz#69d39b3d44b31e7b4864173322565894ce939b25" + integrity sha512-yaBn9OpxQra/bk0/CaA4wr41O0/Whkg6nqjqApcinxM7pro51ojhX6fv1pimAnVjVfDy14K0ULoRL70CA9jWWA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.3" + +"@babel/plugin-transform-typeof-symbol@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.1.tgz#60c0239b69965d166b80a84de7315c1bc7e0bb0e" + integrity sha512-qX8KZcmbvA23zDi+lk9s6hC1FM7jgLHYIjuLgULgc8QtYnmB3tAVIYkNoKRQ75qWBeyzcoMoK8ZQmogGtC/w0g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.1" + +"@babel/plugin-transform-unicode-escapes@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.1.tgz#add0f8483dab60570d9e03cecef6c023aa8c9940" + integrity sha512-zZ0Poh/yy1d4jeDWpx/mNwbKJVwUYJX73q+gyh4bwtG0/iUlzdEu0sLMda8yuDFS6LBQlT/ST1SJAR6zYwXWgw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.1" + +"@babel/plugin-transform-unicode-regex@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.1.tgz#6b58f2aea7b68df37ac5025d9c88752443a6b43f" + integrity sha512-Y/2a2W299k0VIUdbqYm9X2qS6fE0CUBhhiPpimK6byy7OJ/kORLlIX+J6UrjgNu5awvs62k+6RSslxhcvVw2Tw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.1" + +"@babel/preset-env@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.10.3.tgz#3e58c9861bbd93b6a679987c7e4bd365c56c80c9" + integrity sha512-jHaSUgiewTmly88bJtMHbOd1bJf2ocYxb5BWKSDQIP5tmgFuS/n0gl+nhSrYDhT33m0vPxp+rP8oYYgPgMNQlg== + dependencies: + "@babel/compat-data" "^7.10.3" + "@babel/helper-compilation-targets" "^7.10.2" + "@babel/helper-module-imports" "^7.10.3" + "@babel/helper-plugin-utils" "^7.10.3" + "@babel/plugin-proposal-async-generator-functions" "^7.10.3" + "@babel/plugin-proposal-class-properties" "^7.10.1" + "@babel/plugin-proposal-dynamic-import" "^7.10.1" + "@babel/plugin-proposal-json-strings" "^7.10.1" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.10.1" + "@babel/plugin-proposal-numeric-separator" "^7.10.1" + "@babel/plugin-proposal-object-rest-spread" "^7.10.3" + "@babel/plugin-proposal-optional-catch-binding" "^7.10.1" + "@babel/plugin-proposal-optional-chaining" "^7.10.3" + "@babel/plugin-proposal-private-methods" "^7.10.1" + "@babel/plugin-proposal-unicode-property-regex" "^7.10.1" + "@babel/plugin-syntax-async-generators" "^7.8.0" + "@babel/plugin-syntax-class-properties" "^7.10.1" + "@babel/plugin-syntax-dynamic-import" "^7.8.0" + "@babel/plugin-syntax-json-strings" "^7.8.0" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + "@babel/plugin-syntax-numeric-separator" "^7.10.1" + "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.0" + "@babel/plugin-syntax-top-level-await" "^7.10.1" + "@babel/plugin-transform-arrow-functions" "^7.10.1" + "@babel/plugin-transform-async-to-generator" "^7.10.1" + "@babel/plugin-transform-block-scoped-functions" "^7.10.1" + "@babel/plugin-transform-block-scoping" "^7.10.1" + "@babel/plugin-transform-classes" "^7.10.3" + "@babel/plugin-transform-computed-properties" "^7.10.3" + "@babel/plugin-transform-destructuring" "^7.10.1" + "@babel/plugin-transform-dotall-regex" "^7.10.1" + "@babel/plugin-transform-duplicate-keys" "^7.10.1" + "@babel/plugin-transform-exponentiation-operator" "^7.10.1" + "@babel/plugin-transform-for-of" "^7.10.1" + "@babel/plugin-transform-function-name" "^7.10.1" + "@babel/plugin-transform-literals" "^7.10.1" + "@babel/plugin-transform-member-expression-literals" "^7.10.1" + "@babel/plugin-transform-modules-amd" "^7.10.1" + "@babel/plugin-transform-modules-commonjs" "^7.10.1" + "@babel/plugin-transform-modules-systemjs" "^7.10.3" + "@babel/plugin-transform-modules-umd" "^7.10.1" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.10.3" + "@babel/plugin-transform-new-target" "^7.10.1" + "@babel/plugin-transform-object-super" "^7.10.1" + "@babel/plugin-transform-parameters" "^7.10.1" + "@babel/plugin-transform-property-literals" "^7.10.1" + "@babel/plugin-transform-regenerator" "^7.10.3" + "@babel/plugin-transform-reserved-words" "^7.10.1" + "@babel/plugin-transform-shorthand-properties" "^7.10.1" + "@babel/plugin-transform-spread" "^7.10.1" + "@babel/plugin-transform-sticky-regex" "^7.10.1" + "@babel/plugin-transform-template-literals" "^7.10.3" + "@babel/plugin-transform-typeof-symbol" "^7.10.1" + "@babel/plugin-transform-unicode-escapes" "^7.10.1" + "@babel/plugin-transform-unicode-regex" "^7.10.1" + "@babel/preset-modules" "^0.1.3" + "@babel/types" "^7.10.3" + browserslist "^4.12.0" + core-js-compat "^3.6.2" + invariant "^2.2.2" + levenary "^1.1.1" + semver "^5.5.0" + +"@babel/preset-modules@^0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.3.tgz#13242b53b5ef8c883c3cf7dddd55b36ce80fbc72" + integrity sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" + "@babel/plugin-transform-dotall-regex" "^7.4.4" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + +"@babel/runtime@^7.8.4": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.10.3.tgz#670d002655a7c366540c67f6fd3342cd09500364" + integrity sha512-RzGO0RLSdokm9Ipe/YD+7ww8X2Ro79qiXZF3HU9ljrM+qnJmH1Vqth+hbiQZy761LnMJTMitHDuKVYTk3k4dLw== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/template@^7.10.1", "@babel/template@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.3.tgz#4d13bc8e30bf95b0ce9d175d30306f42a2c9a7b8" + integrity sha512-5BjI4gdtD+9fHZUsaxPHPNpwa+xRkDO7c7JbhYn2afvrkDu5SfAAbi9AIMXw2xEhO/BR35TqiW97IqNvCo/GqA== + dependencies: + "@babel/code-frame" "^7.10.3" + "@babel/parser" "^7.10.3" + "@babel/types" "^7.10.3" + +"@babel/traverse@^7.10.1", "@babel/traverse@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.10.3.tgz#0b01731794aa7b77b214bcd96661f18281155d7e" + integrity sha512-qO6623eBFhuPm0TmmrUFMT1FulCmsSeJuVGhiLodk2raUDFhhTECLd9E9jC4LBIWziqt4wgF6KuXE4d+Jz9yug== + dependencies: + "@babel/code-frame" "^7.10.3" + "@babel/generator" "^7.10.3" + "@babel/helper-function-name" "^7.10.3" + "@babel/helper-split-export-declaration" "^7.10.1" + "@babel/parser" "^7.10.3" + "@babel/types" "^7.10.3" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.13" + +"@babel/types@^7.10.1", "@babel/types@^7.10.3", "@babel/types@^7.4.4": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.10.3.tgz#6535e3b79fea86a6b09e012ea8528f935099de8e" + integrity sha512-nZxaJhBXBQ8HVoIcGsf9qWep3Oh3jCENK54V4mRF7qaJabVsAYdbTtmSD8WmAp1R6ytPiu5apMwSXyxB1WlaBA== + dependencies: + "@babel/helper-validator-identifier" "^7.10.3" + lodash "^4.17.13" + to-fast-properties "^2.0.0" + +"@tootallnate/once@1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" + integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== + "@types/app-root-path@^1.2.4": version "1.2.4" resolved "https://registry.yarnpkg.com/@types/app-root-path/-/app-root-path-1.2.4.tgz#a78b703282b32ac54de768f5512ecc3569919dc7" @@ -311,6 +1103,20 @@ acorn@^6.4.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== +agent-base@4, agent-base@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" + integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== + dependencies: + es6-promisify "^5.0.0" + +agent-base@6: + version "6.0.0" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.0.tgz#5d0101f19bbfaed39980b22ae866de153b93f09a" + integrity sha512-j1Q7cSCqN+AwrmDd+pzgqc0/NpC655x2bUf5ZjRIO77DcNBFmh+OgRNzF6OKdCC9RSCb19fGd99+bhXFdkRNqw== + dependencies: + debug "4" + ajv-errors@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" @@ -441,6 +1247,24 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== +babel-loader@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.1.0.tgz#c611d5112bd5209abe8b9fa84c3e4da25275f1c3" + integrity sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw== + dependencies: + find-cache-dir "^2.1.0" + loader-utils "^1.4.0" + mkdirp "^0.5.3" + pify "^4.0.1" + schema-utils "^2.6.5" + +babel-plugin-dynamic-import-node@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" + integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== + dependencies: + object.assign "^4.1.0" + balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" @@ -553,6 +1377,11 @@ brorand@^1.0.1: resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + browserify-aes@^1.0.0, browserify-aes@^1.0.4: version "1.2.0" resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" @@ -614,6 +1443,16 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" +browserslist@^4.12.0, browserslist@^4.8.5: + version "4.12.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.12.0.tgz#06c6d5715a1ede6c51fc39ff67fd647f740b656d" + integrity sha512-UH2GkcEDSI0k/lRkuDSzFl9ZZ87skSy9w2XAn1MsZnL+4c4rqbBd3e82UWHbYDpztABrPBhZsTEeuxVfHppqDg== + dependencies: + caniuse-lite "^1.0.30001043" + electron-to-chromium "^1.3.413" + node-releases "^1.1.53" + pkg-up "^2.0.0" + buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" @@ -684,7 +1523,12 @@ camelcase@^5.0.0, camelcase@^5.3.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -chalk@2.4.2, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: +caniuse-lite@^1.0.30001043: + version "1.0.30001087" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001087.tgz#4a0bdc5998a114fcf8b7954e7ba6c2c29831c54a" + integrity sha512-KAQRGtt+eGCQBSp2iZTQibdCf9oe6cNTi5lmpsW38NnxP4WMYzfU6HCRmh4kJyh6LrTM9/uyElK4xcO93kafpg== + +chalk@2.4.2, chalk@^2.0.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -786,6 +1630,11 @@ color-name@1.1.3: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= +commander@2.15.1: + version "2.15.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" + integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== + commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -838,6 +1687,13 @@ content-type@~1.0.4: resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== +convert-source-map@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" + integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== + dependencies: + safe-buffer "~5.1.1" + cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" @@ -865,6 +1721,14 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= +core-js-compat@^3.6.2: + version "3.6.5" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.6.5.tgz#2a51d9a4e25dfd6e690251aa81f99e3c05481f1c" + integrity sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng== + dependencies: + browserslist "^4.8.5" + semver "7.0.0" + core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -965,6 +1829,27 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3: dependencies: ms "2.0.0" +debug@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +debug@4, debug@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +debug@^3.1.0: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -1027,6 +1912,11 @@ detect-file@^1.0.0: resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= +diff@3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + diffie-hellman@^5.0.0: version "5.0.3" resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" @@ -1063,6 +1953,11 @@ ejs@^3.1.3: dependencies: jake "^10.6.1" +electron-to-chromium@^1.3.413: + version "1.3.481" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.481.tgz#0d59e72a0aaeb876b43fb1d6e84bf0dfc99617e8" + integrity sha512-q2PeCP2PQXSYadDo9uNY+uHXjdB9PcsUpCVoGlY8TZOPHGlXdevlqW9PkKeqCxn2QBkGB8b6AcMO++gh8X82bA== + elliptic@^6.0.0, elliptic@^6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" @@ -1161,12 +2056,24 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +es6-promise@^4.0.3: + version "4.2.8" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== + +es6-promisify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= + dependencies: + es6-promise "^4.0.3" + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= -escape-string-regexp@^1.0.5: +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= @@ -1191,6 +2098,11 @@ estraverse@^4.1.0, estraverse@^4.1.1: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + etag@~1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" @@ -1388,6 +2300,13 @@ find-cache-dir@^2.1.0: make-dir "^2.0.0" pkg-dir "^3.0.0" +find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + find-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" @@ -1476,6 +2395,11 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +gensync@^1.0.0-beta.1: + version "1.0.0-beta.1" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" + integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== + get-caller-file@^2.0.1: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" @@ -1508,7 +2432,24 @@ glob-parent@~5.1.0: dependencies: is-glob "^4.0.1" -glob@^7.1.3, glob@^7.1.4: +glob-to-regexp@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" + integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= + +glob@7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== @@ -1556,11 +2497,21 @@ global-prefix@^3.0.0: kind-of "^6.0.2" which "^1.3.1" +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2: version "4.2.4" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== +growl@1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -1626,6 +2577,11 @@ hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.1" +he@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" + integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0= + hmac-drbg@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -1669,11 +2625,44 @@ http-errors@~1.7.2: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" +http-proxy-agent@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" + integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg== + dependencies: + agent-base "4" + debug "3.1.0" + +http-proxy-agent@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" + integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== + dependencies: + "@tootallnate/once" "1" + agent-base "6" + debug "4" + https-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= +https-proxy-agent@^2.2.1: + version "2.2.4" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b" + integrity sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg== + dependencies: + agent-base "^4.3.0" + debug "^3.1.0" + +https-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" + integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== + dependencies: + agent-base "6" + debug "4" + iconv-lite@0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -1754,6 +2743,13 @@ interpret@1.2.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== +invariant@^2.2.2, invariant@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + invert-kv@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" @@ -1960,6 +2956,21 @@ jake@^10.6.1: filelist "^1.0.1" minimatch "^3.0.4" +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= + json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" @@ -2015,6 +3026,18 @@ lcid@^2.0.0: dependencies: invert-kv "^2.0.0" +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + +levenary@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/levenary/-/levenary-1.1.1.tgz#842a9ee98d2075aa7faeedbe32679e9205f46f77" + integrity sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ== + dependencies: + leven "^3.1.0" + load-json-file@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" @@ -2039,7 +3062,7 @@ loader-utils@1.2.3: emojis-list "^2.0.0" json5 "^1.0.1" -loader-utils@^1.0.2, loader-utils@^1.2.3: +loader-utils@^1.0.2, loader-utils@^1.2.3, loader-utils@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== @@ -2057,6 +3080,14 @@ loader-utils@^2.0.0: emojis-list "^3.0.0" json5 "^2.1.2" +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + locate-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" @@ -2065,11 +3096,18 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" -lodash@^4.17.15: +lodash@^4.17.13, lodash@^4.17.15: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== +loose-envify@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -2225,13 +3263,18 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= -minimatch@^3.0.4: +minimatch@3.0.4, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= + minimist@^1.2.0, minimist@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" @@ -2261,6 +3304,13 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" +mkdirp@0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= + dependencies: + minimist "0.0.8" + mkdirp@^0.5.1, mkdirp@^0.5.3: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" @@ -2268,11 +3318,45 @@ mkdirp@^0.5.1, mkdirp@^0.5.3: dependencies: minimist "^1.2.5" +mocha@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6" + integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ== + dependencies: + browser-stdout "1.3.1" + commander "2.15.1" + debug "3.1.0" + diff "3.5.0" + escape-string-regexp "1.0.5" + glob "7.1.2" + growl "1.10.5" + he "1.1.1" + minimatch "3.0.4" + mkdirp "0.5.1" + supports-color "5.4.0" + +monaco-editor-webpack-plugin@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/monaco-editor-webpack-plugin/-/monaco-editor-webpack-plugin-1.9.0.tgz#5b547281b9f404057dc5d8c5722390df9ac90be6" + integrity sha512-tOiiToc94E1sb50BgZ8q8WK/bxus77SRrwCqIpAB5er3cpX78SULbEBY4YPOB8kDolOzKRt30WIHG/D6gz69Ww== + dependencies: + loader-utils "^1.2.3" + monaco-editor@^0.20.0: version "0.20.0" resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.20.0.tgz#5d5009343a550124426cb4d965a4d27a348b4dea" integrity sha512-hkvf4EtPJRMQlPC3UbMoRs0vTAFAYdzFQ+gpMb8A+9znae1c43q8Mab9iVsgTcg/4PNiLGGn3SlDIa8uvK1FIQ== +monaco-languageclient@^0.13.0: + version "0.13.0" + resolved "https://registry.yarnpkg.com/monaco-languageclient/-/monaco-languageclient-0.13.0.tgz#59b68b42fb7633171502d6557f597c2752f6c266" + integrity sha512-aCwd33dTitwV5QwY56rpYHwzEGXei8TZ+yvZcvP3gEMd6Mizr8m3pOuoknDi2SUfLuNAHS6+ulvLgZlNQB5awg== + dependencies: + glob-to-regexp "^0.3.0" + vscode-jsonrpc "^5.0.0" + vscode-languageclient "^6.0.0" + vscode-uri "^2.1.1" + move-concurrently@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" @@ -2295,6 +3379,11 @@ ms@2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== +ms@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + nan@^2.12.1, nan@^2.14.0: version "2.14.1" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" @@ -2373,6 +3462,11 @@ node-pty@^0.9.0: dependencies: nan "^2.14.0" +node-releases@^1.1.53: + version "1.1.58" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.58.tgz#8ee20eef30fa60e52755fcc0942def5a734fe935" + integrity sha512-NxBudgVKiRh/2aPWMgPR7bPTX0VPmGx5QBwCtdHitnqFE5/O8DeBXuIMH1nwNnw/aMo6AjOrpsHzfY3UbUJ7yg== + normalize-package-data@^2.3.2: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" @@ -2508,6 +3602,13 @@ p-is-promise@^2.0.0: resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + p-limit@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" @@ -2515,6 +3616,13 @@ p-limit@^2.0.0: dependencies: p-try "^2.0.0" +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + p-locate@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" @@ -2522,6 +3630,11 @@ p-locate@^3.0.0: dependencies: p-limit "^2.0.0" +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" @@ -2656,6 +3769,13 @@ pkg-dir@^3.0.0: dependencies: find-up "^3.0.0" +pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" + integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= + dependencies: + find-up "^2.1.0" + posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" @@ -2717,6 +3837,11 @@ postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.27, postcss@^7.0.5, postcss@^7.0. source-map "^0.6.1" supports-color "^6.1.0" +private@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== + process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" @@ -2889,6 +4014,31 @@ readdirp@~3.4.0: dependencies: picomatch "^2.2.1" +regenerate-unicode-properties@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" + integrity sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA== + dependencies: + regenerate "^1.4.0" + +regenerate@^1.4.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.1.tgz#cad92ad8e6b591773485fbe05a485caf4f457e6f" + integrity sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A== + +regenerator-runtime@^0.13.4: + version "0.13.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697" + integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA== + +regenerator-transform@^0.14.2: + version "0.14.4" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.4.tgz#5266857896518d1616a78a0479337a30ea974cc7" + integrity sha512-EaJaKPBI9GvKpvUz2mz4fhx7WPgvwRLY9v3hlNHWmAuJHI13T4nwKnNvm5RWJzEdnI5g5UwtOww+S8IdoUC2bw== + dependencies: + "@babel/runtime" "^7.8.4" + private "^0.1.8" + regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" @@ -2897,6 +4047,30 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" +regexpu-core@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.0.tgz#fcbf458c50431b0bb7b45d6967b8192d91f3d938" + integrity sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ== + dependencies: + regenerate "^1.4.0" + regenerate-unicode-properties "^8.2.0" + regjsgen "^0.5.1" + regjsparser "^0.6.4" + unicode-match-property-ecmascript "^1.0.4" + unicode-match-property-value-ecmascript "^1.2.0" + +regjsgen@^0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" + integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== + +regjsparser@^0.6.4: + version "0.6.4" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.4.tgz#a769f8684308401a66e9b529d2436ff4d0666272" + integrity sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw== + dependencies: + jsesc "~0.5.0" + remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" @@ -2947,7 +4121,7 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@^1.10.0: +resolve@^1.10.0, resolve@^1.3.2: version "1.17.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== @@ -3021,11 +4195,16 @@ schema-utils@^2.6.5, schema-utils@^2.6.6: ajv "^6.12.2" ajv-keywords "^3.4.1" -"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.6.0: +"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.6.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== +semver@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" + integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== + semver@^6.0.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" @@ -3168,7 +4347,7 @@ source-map-resolve@^0.5.0: source-map-url "^0.4.0" urix "^0.1.0" -source-map-support@~0.5.12: +source-map-support@^0.5.0, source-map-support@~0.5.12: version "0.5.19" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== @@ -3181,7 +4360,7 @@ source-map-url@^0.4.0: resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= -source-map@^0.5.6: +source-map@^0.5.0, source-map@^0.5.6: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= @@ -3348,6 +4527,13 @@ style-loader@^1.2.1: loader-utils "^2.0.0" schema-utils "^2.6.6" +supports-color@5.4.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" + integrity sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w== + dependencies: + has-flag "^3.0.0" + supports-color@6.1.0, supports-color@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" @@ -3411,6 +4597,11 @@ to-arraybuffer@^1.0.0: resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + to-object-path@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" @@ -3487,6 +4678,29 @@ typescript@^3.9.5: resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.5.tgz#586f0dba300cde8be52dd1ac4f7e1009c1b13f36" integrity sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ== +unicode-canonical-property-names-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" + integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== + +unicode-match-property-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" + integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== + dependencies: + unicode-canonical-property-names-ecmascript "^1.0.4" + unicode-property-aliases-ecmascript "^1.0.4" + +unicode-match-property-value-ecmascript@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz#0d91f600eeeb3096aa962b1d6fc88876e64ea531" + integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ== + +unicode-property-aliases-ecmascript@^1.0.4: + version "1.1.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz#dd57a99f6207bedff4628abefb94c50db941c8f4" + integrity sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg== + union-value@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" @@ -3611,6 +4825,58 @@ vm-browserify@^1.0.1: resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== +vscode-jsonrpc@^5.0.0, vscode-jsonrpc@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-5.0.1.tgz#9bab9c330d89f43fc8c1e8702b5c36e058a01794" + integrity sha512-JvONPptw3GAQGXlVV2utDcHx0BiY34FupW/kI6mZ5x06ER5DdPG/tXWMVHjTNULF5uKPOUUD0SaXg5QaubJL0A== + +vscode-languageclient@^6.0.0: + version "6.1.3" + resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-6.1.3.tgz#c979c5bb5855714a0307e998c18ca827c1b3953a" + integrity sha512-YciJxk08iU5LmWu7j5dUt9/1OLjokKET6rME3cI4BRpiF6HZlusm2ZwPt0MYJ0lV5y43sZsQHhyon2xBg4ZJVA== + dependencies: + semver "^6.3.0" + vscode-languageserver-protocol "^3.15.3" + +vscode-languageserver-protocol@^3.15.3: + version "3.15.3" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.3.tgz#3fa9a0702d742cf7883cb6182a6212fcd0a1d8bb" + integrity sha512-zrMuwHOAQRhjDSnflWdJG+O2ztMWss8GqUUB8dXLR/FPenwkiBNkMIJJYfSN6sgskvsF0rHAoBowNQfbyZnnvw== + dependencies: + vscode-jsonrpc "^5.0.1" + vscode-languageserver-types "3.15.1" + +vscode-languageserver-types@3.15.1: + version "3.15.1" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz#17be71d78d2f6236d414f0001ce1ef4d23e6b6de" + integrity sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ== + +vscode-test@^0.4.1: + version "0.4.3" + resolved "https://registry.yarnpkg.com/vscode-test/-/vscode-test-0.4.3.tgz#461ebf25fc4bc93d77d982aed556658a2e2b90b8" + integrity sha512-EkMGqBSefZH2MgW65nY05rdRSko15uvzq4VAPM5jVmwYuFQKE7eikKXNJDRxL+OITXHB6pI+a3XqqD32Y3KC5w== + dependencies: + http-proxy-agent "^2.1.0" + https-proxy-agent "^2.2.1" + +vscode-uri@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.1.2.tgz#c8d40de93eb57af31f3c715dd650e2ca2c096f1c" + integrity sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A== + +vscode@^1.1.37: + version "1.1.37" + resolved "https://registry.yarnpkg.com/vscode/-/vscode-1.1.37.tgz#c2a770bee4bb3fff765e2b72c7bcc813b8a6bb0a" + integrity sha512-vJNj6IlN7IJPdMavlQa1KoFB3Ihn06q1AiN3ZFI/HfzPNzbKZWPPuiU+XkpNOfGU5k15m4r80nxNPlM7wcc0wg== + dependencies: + glob "^7.1.2" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + mocha "^5.2.0" + semver "^5.4.1" + source-map-support "^0.5.0" + vscode-test "^0.4.1" + watchpack-chokidar2@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz#9948a1866cbbd6cb824dea13a7ed691f6c8ddff0" From 337658a8bf2c6e7803edebafc762a4a0009d35b9 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 5 Jul 2020 12:21:59 -0600 Subject: [PATCH 083/388] Misc bugfixes and robustness improvements --- README.md | 4 +- backend/src/api.ts | 63 ++++++++++++++++++----------- backend/src/users.ts | 9 ++--- backend/src/util.ts | 16 ++++---- package.json | 4 +- scripts/docker-install-phase5.bash | 2 +- scripts/setup.bash | 2 +- system/src/riju-system-privileged.c | 29 +++++++++---- 8 files changed, 79 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index 7aee9be..c290c31 100644 --- a/README.md +++ b/README.md @@ -43,8 +43,8 @@ container first: $ make docker -Note that building the image takes 30 minutes and requires about 15 GB -of disk space. +Note that building the image takes about 30 minutes on high-end +hardware and ethernet, and it requires about 15 GB of disk space. ## Flag diff --git a/backend/src/api.ts b/backend/src/api.ts index c2b617d..a92d501 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -10,7 +10,12 @@ import { v4 as getUUID } from "uuid"; import { PRIVILEGED } from "./config"; import { LangConfig, langs } from "./langs"; import { borrowUser } from "./users"; -import { callPrivileged, getEnv, spawnPrivileged } from "./util"; +import { + callPrivileged, + getEnv, + rijuSystemPrivileged, + spawnPrivileged, +} from "./util"; export class Session { uuid: string; @@ -193,17 +198,15 @@ export class Session { ); } } - const args = PRIVILEGED - ? [ - "/home/docker/src/system/out/riju-system-privileged", - "spawn", - `${this.uid}`, - `${this.uuid}`, - "bash", - "-c", - cmdline, - ] - : ["bash", "-c", cmdline]; + const args = [ + rijuSystemPrivileged, + "spawn", + `${this.uid}`, + `${this.uuid}`, + "bash", + "-c", + cmdline, + ]; const env = getEnv(this.uuid); const term = { pty: pty.spawn(args[0], args.slice(1), { @@ -227,17 +230,15 @@ export class Session { } }); if (lsp && this.lsp === null) { - const lspArgs = PRIVILEGED - ? [ - "/home/docker/src/system/out/riju-system-privileged", - "spawn", - `${this.uid}`, - `${this.uuid}`, - "bash", - "-c", - lsp, - ] - : ["bash", "-c", lsp]; + const lspArgs = [ + rijuSystemPrivileged, + "spawn", + `${this.uid}`, + `${this.uuid}`, + "bash", + "-c", + lsp, + ]; const proc = spawn(lspArgs[0], lspArgs.slice(1), { env: getEnv(this.uuid), }); @@ -254,6 +255,22 @@ export class Session { }; cleanup = async () => { this.log(`Cleaning up session`); + if (this.term.pty) { + await spawnPrivileged( + this.uid!, + this.uuid, + ["kill", "-9", `${this.term.pty.pid}`], + this.log + ); + } + if (this.lsp !== null) { + await spawnPrivileged( + this.uid!, + this.uuid, + ["kill", "-9", `${this.lsp.proc.pid}`], + this.log + ); + } if (this.homedir) { await callPrivileged(["teardown", this.uuid], this.log); } diff --git a/backend/src/users.ts b/backend/src/users.ts index 0742a6b..89862b5 100644 --- a/backend/src/users.ts +++ b/backend/src/users.ts @@ -1,5 +1,6 @@ import { spawn } from "child_process"; import * as fs from "fs"; +import * as os from "os"; import * as AsyncLock from "async-lock"; import * as _ from "lodash"; @@ -12,7 +13,7 @@ import { callPrivileged } from "./util"; const MIN_UID = 2000; const MAX_UID = 65000; -const CUR_UID = parseInt(process.env.UID || "") || null; +const CUR_UID = os.userInfo().uid; let availIds: number[] | null = null; let nextId: number | null = null; @@ -50,11 +51,7 @@ async function createUser(log: (msg: string) => void): Promise { export async function borrowUser(log: (msg: string) => void) { if (!PRIVILEGED) { - if (CUR_UID === null) { - throw new Error("unable to determine current UID"); - } else { - return { uid: CUR_UID, cleanup: async () => {} }; - } + return { uid: CUR_UID, cleanup: async () => {} }; } else { return await lock.acquire("key", async () => { if (availIds === null || nextId === null) { diff --git a/backend/src/util.ts b/backend/src/util.ts index 235252c..b1d7a64 100644 --- a/backend/src/util.ts +++ b/backend/src/util.ts @@ -1,17 +1,23 @@ import { spawn, SpawnOptions } from "child_process"; import * as process from "process"; +import * as appRoot from "app-root-path"; + interface Options extends SpawnOptions { input?: string; } +export const rijuSystemPrivileged = appRoot.resolve( + "system/out/riju-system-privileged" +); + export function getEnv(uuid: string) { const cwd = `/tmp/riju/${uuid}`; return { HOME: cwd, HOSTNAME: "riju", - LANG: "C.UTF-8", - LC_ALL: "C.UTF-8", + LANG: process.env.LANG || "", + LC_ALL: process.env.LC_ALL || "", PATH: "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/bin", PWD: cwd, SHELL: "/usr/bin/bash", @@ -59,11 +65,7 @@ export async function callPrivileged( log: (msg: string) => void, options?: Options ) { - await call( - ["/home/docker/src/system/out/riju-system-privileged"].concat(args), - log, - options - ); + await call([rijuSystemPrivileged].concat(args), log, options); } export async function spawnPrivileged( diff --git a/package.json b/package.json index c5a08b2..daf5eb5 100644 --- a/package.json +++ b/package.json @@ -49,9 +49,9 @@ "frontend": "webpack --production", "frontend-dev": "webpack --development --watch", "server": "scripts/setup.bash && node backend/out/server.js", - "server-dev": "watchexec -w backend/out -r 'scripts/setup.bash && node backend/out/server.js'", + "server-dev": "watchexec --no-vcs-ignore -w backend/out -r 'scripts/setup.bash && node backend/out/server.js'", "system": "scripts/compile-system.bash", - "system-dev": "watchexec -w system/src -n scripts/compile-system.bash", + "system-dev": "watchexec --no-vcs-ignore -w system/src -n scripts/compile-system.bash", "build": "run-s backend frontend system", "dev": "run-p backend-dev frontend-dev system-dev server-dev" } diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index 003017c..7359c57 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -70,7 +70,7 @@ chmod +x /opt/mspyls/Microsoft.Python.LanguageServer ln -s /opt/mspyls/Microsoft.Python.LanguageServer /usr/bin/Microsoft.Python.LanguageServer # SNOBOL -wget -nv ftp://ftp.snobol4.org/snobol/snobol4-2.0.tar.gz +wget -nv ftp://ftp.snobol4.org/snobol/old/snobol4-2.1.4.tar.gz tar -xf snobol4-*.tar.gz rm snobol4-*.tar.gz pushd snobol4-* >/dev/null diff --git a/scripts/setup.bash b/scripts/setup.bash index 08923fb..e9a597e 100755 --- a/scripts/setup.bash +++ b/scripts/setup.bash @@ -5,6 +5,6 @@ set -o pipefail mkdir -p /tmp/riju if [[ -x system/out/riju-system-privileged ]]; then - system/out/riju-system-privileged teardown "*" + system/out/riju-system-privileged teardown "*" || true fi chmod a=x,u=rwx /tmp/riju diff --git a/system/src/riju-system-privileged.c b/system/src/riju-system-privileged.c index 8ad72d1..20772d8 100644 --- a/system/src/riju-system-privileged.c +++ b/system/src/riju-system-privileged.c @@ -12,6 +12,8 @@ const int MIN_UID = 2000; const int MAX_UID = 65000; +int privileged; + void die(char *msg) { fprintf(stderr, "%s\n", msg); @@ -29,6 +31,8 @@ void die_with_usage() int parseUID(char *str) { + if (!privileged) + return -1; char *endptr; long uid = strtol(str, &endptr, 10); if (!*str || *endptr) @@ -50,6 +54,8 @@ char *parseUUID(char *uuid) void useradd(int uid) { + if (!privileged) + die("useradd not allowed without root privileges"); char *cmdline; if (asprintf(&cmdline, "groupadd -g %1$d riju%1$d", uid) < 0) die("asprintf failed"); @@ -70,12 +76,14 @@ void spawn(int uid, char *uuid, char **cmdline) die("asprintf failed"); if (chdir(cwd) < 0) die("chdir failed"); - if (setgid(uid) < 0) - die("setgid failed"); - if (setgroups(0, NULL) < 0) - die("setgroups failed"); - if (setuid(uid) < 0) - die("setuid failed"); + if (privileged) { + if (setgid(uid) < 0) + die("setgid failed"); + if (setgroups(0, NULL) < 0) + die("setgroups failed"); + if (setuid(uid) < 0) + die("setuid failed"); + } umask(077); execvp(cmdline[0], cmdline); die("execvp failed"); @@ -84,7 +92,9 @@ void spawn(int uid, char *uuid, char **cmdline) void setup(int uid, char *uuid) { char *cmdline; - if (asprintf(&cmdline, "install -d -o riju%1$d -g riju%1$d -m 700 /tmp/riju/%2$s", uid, uuid) < 0) + if (asprintf(&cmdline, privileged + ? "install -d -o riju%1$d -g riju%1$d -m 700 /tmp/riju/%2$s" + : "install -d -m 700 /tmp/riju/%2$s", uid, uuid) < 0) die("asprintf failed"); int status = system(cmdline); if (status) @@ -103,7 +113,10 @@ void teardown(char *uuid) int main(int argc, char **argv) { - setuid(0); + int code = setuid(0); + if (code != 0 && code != -EPERM) + die("setuid failed"); + privileged = code == 0; if (argc < 2) die_with_usage(); if (!strcmp(argv[1], "useradd")) { From 404aeef235fde8f7f04292bf31607285bd79a98c Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 5 Jul 2020 12:41:07 -0600 Subject: [PATCH 084/388] Debug info on frontend with #debug hash --- frontend/src/app.ts | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/frontend/src/app.ts b/frontend/src/app.ts index a5b9c1c..499885a 100644 --- a/frontend/src/app.ts +++ b/frontend/src/app.ts @@ -17,6 +17,8 @@ import { FitAddon } from "xterm-addon-fit"; import "xterm/css/xterm.css"; +const DEBUG = window.location.hash === "#debug"; + interface RijuConfig { id: string; monacoLang: string; @@ -61,6 +63,9 @@ class RijuMessageReader extends AbstractMessageReader { } switch (message?.event) { case "lspOutput": + if (DEBUG) { + console.log("RECEIVE LSP:", message?.output); + } this.callback!(message?.output); break; } @@ -77,6 +82,9 @@ class RijuMessageWriter extends AbstractMessageWriter { } write(msg: Message): void { + if (DEBUG) { + console.log("SEND LSP:", msg); + } this.socket.send(JSON.stringify({ event: "lspInput", input: msg })); } } @@ -99,6 +107,13 @@ async function main() { const initialRetryDelayMs = 200; let retryDelayMs = initialRetryDelayMs; + function sendMessage(message: any) { + if (DEBUG) { + console.log("SEND", message); + } + socket?.send(JSON.stringify(message)); + } + function tryConnect() { let clientDisposable: Disposable | null = null; console.log("Connecting to server..."); @@ -118,6 +133,9 @@ async function main() { console.error("Malformed message from server:", event.data); return; } + if (DEBUG && message?.event !== "lspOutput") { + console.log("RECEIVE:", message); + } if (message?.event && message?.event !== "error") { retryDelayMs = initialRetryDelayMs; } @@ -190,11 +208,7 @@ async function main() { let socket: WebSocket | null = null; tryConnect(); - term.onData( - (data) => - socket && - socket.send(JSON.stringify({ event: "terminalInput", input: data })) - ); + term.onData((data) => sendMessage({ event: "terminalInput", input: data })); const editor = monaco.editor.create(document.getElementById("editor")!, { minimap: { enabled: false }, @@ -205,7 +219,7 @@ async function main() { monaco.editor.setModelLanguage(editor.getModel()!, config.monacoLang); document.getElementById("runButton")!.addEventListener("click", () => { - socket?.send(JSON.stringify({ event: "runCode", code: editor.getValue() })); + sendMessage({ event: "runCode", code: editor.getValue() }); }); MonacoServices.install(editor); From 67cb37423c6a540dbce43424671c5f4b2481276e Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 5 Jul 2020 12:54:05 -0600 Subject: [PATCH 085/388] Get clangd working for C/C++/Objective-C --- backend/src/api.ts | 4 +++- backend/src/langs.ts | 1 + frontend/src/app.ts | 12 ++++++++++++ scripts/docker-install-phase3a.bash | 1 + 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/backend/src/api.ts b/backend/src/api.ts index a92d501..8f596c5 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -250,7 +250,9 @@ export class Session { this.lsp.reader.listen((data) => { this.ws.send(JSON.stringify({ event: "lspOutput", output: data })); }); - this.ws.send(JSON.stringify({ event: "lspStarted" })); + this.ws.send( + JSON.stringify({ event: "lspStarted", root: `/tmp/riju/${this.uuid}` }) + ); } }; cleanup = async () => { diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 0cd07d3..8cdaa63 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -147,6 +147,7 @@ implement main0 () = () main: "main.c", compile: "clang -Wall -Wextra main.c -o main", run: "./main", + lsp: "clangd", template: `#include int main() { diff --git a/frontend/src/app.ts b/frontend/src/app.ts index 499885a..29ef230 100644 --- a/frontend/src/app.ts +++ b/frontend/src/app.ts @@ -22,6 +22,7 @@ const DEBUG = window.location.hash === "#debug"; interface RijuConfig { id: string; monacoLang: string; + main: string; lspInit?: any; lspConfig?: any; template: string; @@ -151,6 +152,17 @@ async function main() { term.write(message.output); return; case "lspStarted": + if (typeof message.root !== "string") { + console.error("Unexpected message from server:", message); + return; + } + editor.setModel( + monaco.editor.createModel( + editor.getModel()!.getValue(), + undefined, + monaco.Uri.parse(`file://${message.root}/${config.main}`) + ) + ); const connection = createMessageConnection( new RijuMessageReader(socket!), new RijuMessageWriter(socket!) diff --git a/scripts/docker-install-phase3a.bash b/scripts/docker-install-phase3a.bash index ea98b4c..97044f3 100755 --- a/scripts/docker-install-phase3a.bash +++ b/scripts/docker-install-phase3a.bash @@ -30,6 +30,7 @@ beef # C/C++ clang +clangd # C# mono-mcs From eb66554ce489e005984fe629987fd3f454612a95 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 5 Jul 2020 14:29:45 -0600 Subject: [PATCH 086/388] Configure LSP for C, C++, Objective-C, Rust --- backend/src/api.ts | 13 +++++++++++-- backend/src/langs.ts | 7 +++++++ backend/src/util.ts | 5 ++++- frontend/src/app.ts | 13 +++++++++++-- scripts/docker-install-phase3c.bash | 3 --- scripts/docker-install-phase4.bash | 17 +++++++++++++++++ 6 files changed, 50 insertions(+), 8 deletions(-) diff --git a/backend/src/api.ts b/backend/src/api.ts index 8f596c5..951aec1 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -123,6 +123,7 @@ export class Session { alwaysCreate, compile, run, + lspSetup, lsp, hacks, } = this.config; @@ -230,6 +231,14 @@ export class Session { } }); if (lsp && this.lsp === null) { + if (lspSetup) { + await spawnPrivileged( + this.uid!, + this.uuid, + ["bash", "-c", lspSetup], + this.log + ); + } const lspArgs = [ rijuSystemPrivileged, "spawn", @@ -261,7 +270,7 @@ export class Session { await spawnPrivileged( this.uid!, this.uuid, - ["kill", "-9", `${this.term.pty.pid}`], + ["bash", "-c", `kill -9 ${this.term.pty.pid} 2>/dev/null || true`], this.log ); } @@ -269,7 +278,7 @@ export class Session { await spawnPrivileged( this.uid!, this.uuid, - ["kill", "-9", `${this.lsp.proc.pid}`], + ["bash", "-c", `kill -9 ${this.lsp.proc.pid} 2>/dev/null || true`], this.log ); } diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 8cdaa63..436a376 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -9,6 +9,7 @@ export interface LangConfig { alwaysCreate?: boolean; compile?: string; run: string; + lspSetup?: string; lsp?: string; lspInit?: any; lspConfig?: any; @@ -147,6 +148,7 @@ implement main0 () = () main: "main.c", compile: "clang -Wall -Wextra main.c -o main", run: "./main", + lspSetup: `echo '-Wall -Wextra' | sed -E 's/\\s+/\\n/g' > compile_flags.txt`, lsp: "clangd", template: `#include @@ -202,6 +204,8 @@ int main() { main: "main.cpp", compile: "clang++ -Wall -Wextra main.cpp -o main", run: "./main", + lspSetup: `echo '-Wall -Wextra' | sed -E 's/\\s+/\\n/g' > compile_flags.txt`, + lsp: "clangd", template: `#include int main() { @@ -640,6 +644,8 @@ require("repl").start() compile: "gcc $(gnustep-config --objc-flags) main.m $(gnustep-config --base-libs) -o main", run: "./main", + lspSetup: `(gnustep-config --objc-flags && gnustep-config --base-libs) | sed -E 's/\\s+/\\n/g' > compile_flags.txt`, + lsp: "clangd", template: `#import int main() { @@ -813,6 +819,7 @@ binding_irb.run(IRB.conf) main: "main.rs", compile: "rustc main.rs", run: "./main", + lsp: "rls", template: `fn main() { println!("Hello, world!"); } diff --git a/backend/src/util.ts b/backend/src/util.ts index b1d7a64..328f13a 100644 --- a/backend/src/util.ts +++ b/backend/src/util.ts @@ -5,6 +5,7 @@ import * as appRoot from "app-root-path"; interface Options extends SpawnOptions { input?: string; + check?: boolean; } export const rijuSystemPrivileged = appRoot.resolve( @@ -32,7 +33,9 @@ export async function call( ) { options = options || {}; const input = options.input; + const check = options.check === undefined ? true : options.check; delete options.input; + delete options.check; const proc = spawn(args[0], args.slice(1), options); if (input) { proc.stdin!.end(input); @@ -51,7 +54,7 @@ export async function call( if (output) { log(`Output from ${args[0]}:\n` + output); } - if (code === 0) { + if (code === 0 || !check) { resolve(); } else { reject(`command ${args[0]} failed with error code ${code}`); diff --git a/frontend/src/app.ts b/frontend/src/app.ts index 29ef230..045affa 100644 --- a/frontend/src/app.ts +++ b/frontend/src/app.ts @@ -3,6 +3,7 @@ import { createConnection, MonacoLanguageClient, MonacoServices, + Services, } from "monaco-languageclient"; import { Disposable } from "vscode"; import { createMessageConnection } from "vscode-jsonrpc"; @@ -117,6 +118,7 @@ async function main() { function tryConnect() { let clientDisposable: Disposable | null = null; + let servicesDisposable: Disposable | null = null; console.log("Connecting to server..."); socket = new WebSocket( (document.location.protocol === "http:" ? "ws://" : "wss://") + @@ -156,6 +158,10 @@ async function main() { console.error("Unexpected message from server:", message); return; } + const services = MonacoServices.create(editor, { + rootUri: `file://${message.root}`, + }); + servicesDisposable = Services.install(services); editor.setModel( monaco.editor.createModel( editor.getModel()!.getValue(), @@ -205,6 +211,11 @@ async function main() { } if (clientDisposable) { clientDisposable.dispose(); + clientDisposable = null; + } + if (servicesDisposable) { + servicesDisposable.dispose(); + servicesDisposable = null; } scheduleConnect(); }); @@ -233,8 +244,6 @@ async function main() { document.getElementById("runButton")!.addEventListener("click", () => { sendMessage({ event: "runCode", code: editor.getValue() }); }); - - MonacoServices.install(editor); } main().catch(console.error); diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index e14bf0c..e4271e4 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -58,9 +58,6 @@ qemu-user-static # Ruby ruby -# Rust -rustc - " export DEBIAN_FRONTEND=noninteractive diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 8274235..70e03ba 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -4,10 +4,24 @@ set -e set -o pipefail set -x +# Needed for project infrastructure npm config set unsafe-perm true PERL_MM_USE_DEFAULT=1 cpan App::cpanminus rm -rf /tmp/cpan_install_*.txt +export CARGO_HOME=/opt/rust +export RUSTUP_HOME=/opt/rust +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path + +tee /opt/rust/wrapper >/dev/null <<"EOF" +#!/usr/bin/env bash +RUSTUP_HOME=/opt/rust exec /opt/rust/bin/${0##*/} "$@" +EOF +chmod +x /opt/rust/wrapper +for file in /opt/rust/bin/*; do + ln -s /opt/rust/wrapper /usr/bin/${file##*/} +done + # Befunge npm install -g befunge93 prompt-sync @@ -26,6 +40,9 @@ cpanm -n Devel::REPL # ReasonML npm install -g bs-platform +# Rust +rustup component add rls rust-analysis rust-src + # Shakespeare pip3 install shakespearelang From 80cd12ec19f6c744bda591346a620ef91b7ece47 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 5 Jul 2020 14:37:17 -0600 Subject: [PATCH 087/388] Configure LSP for Clojure --- backend/src/langs.ts | 1 + scripts/docker-install-phase5.bash | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 436a376..28b9589 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -244,6 +244,7 @@ int main() { repl: "clojure", main: "main.clj", run: "clojure -i main.clj -r", + lsp: "clojure-lsp", template: `(println "Hello, world!") `, }, diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index 7359c57..76399e1 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -21,6 +21,12 @@ tar -xf linux-x86_64-static.tar.gz mv stack-*-linux-x86_64-static/stack /usr/bin/stack rm -rf stack-*-linux-x86_64-static linux-x86_64-static.tar.gz +# Clojure +cd /tmp +wget -nv https://github.com/snoe/clojure-lsp/releases/download/release-20200629T153107/clojure-lsp +chmod +x clojure-lsp +mv clojure-lsp /usr/bin/clojure-lsp + # D cd /tmp wget -nv http://downloads.dlang.org/releases/2.x/2.092.0/dmd_2.092.0-0_amd64.deb From 565379aaf37bac6fa26ead62733bb39bd29a0957 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 5 Jul 2020 15:32:46 -0600 Subject: [PATCH 088/388] Configure LSP for Go and FORTRAN --- backend/src/langs.ts | 2 ++ scripts/docker-install-phase4.bash | 3 +++ scripts/docker-install-phase5.bash | 7 +++++++ 3 files changed, 12 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 28b9589..bf5ac92 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -401,6 +401,7 @@ main() -> main: "main.f", compile: "flang main.f -o main", run: "./main", + lsp: "fortls", template: ` program hello print *, "Hello, world!" end program hello @@ -423,6 +424,7 @@ main() -> main: "main.go", compile: "go build main.go", run: "./main", + lsp: "gopls", template: `package main import "fmt" diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 70e03ba..024ed34 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -34,6 +34,9 @@ npm install -g coffeescript # Elm npm install -g @kachkaev/run-elm +# FORTRAN +pip3 install fortran-language-server + # Perl cpanm -n Devel::REPL diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index 76399e1..f31775a 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -40,6 +40,12 @@ gunzip binary-for-linux-64-bit.gz chmod +x binary-for-linux-64-bit mv binary-for-linux-64-bit /usr/bin/elm +# Go +export GO111MODULE=on +export GOPATH=/tmp/go +mv /tmp/go/bin/gopls /usr/bin/gopls +rm -rf /tmp/go + # Ink cd /tmp wget -nv https://github.com/thesephist/ink/releases/download/v0.1.7/ink-linux @@ -74,6 +80,7 @@ wget -nv "${nupkg}" unzip -d /opt/mspyls Python-Language-Server-linux-x64.*.nupkg chmod +x /opt/mspyls/Microsoft.Python.LanguageServer ln -s /opt/mspyls/Microsoft.Python.LanguageServer /usr/bin/Microsoft.Python.LanguageServer +rm Python-Language-Server-linux-x64.*.nupkg # SNOBOL wget -nv ftp://ftp.snobol4.org/snobol/old/snobol4-2.1.4.tar.gz From fac2a9acb592bb195be14338f26292c15249a749 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 6 Jul 2020 14:15:24 -0600 Subject: [PATCH 089/388] Additional LSP diagnostics on frontend --- backend/src/api.ts | 47 +++++++++++++++++++-------------------------- frontend/src/app.ts | 24 ++++++++++++++++++++++- 2 files changed, 43 insertions(+), 28 deletions(-) diff --git a/backend/src/api.ts b/backend/src/api.ts index 951aec1..130af6e 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -55,21 +55,22 @@ export class Session { this.run().catch((err) => { this.log(`Error while setting up environment for pty`); console.log(err); - try { - this.ws.send(JSON.stringify({ event: "terminalClear" })); - this.ws.send( - JSON.stringify({ - event: "terminalOutput", - output: `Riju encountered an unexpected error: ${err} + this.send({ event: "terminalClear" }); + this.send({ + event: "terminalOutput", + output: `Riju encountered an unexpected error: ${err} \rYou may want to save your code and refresh the page. `, - }) - ); - } catch (err) { - // - } + }); }); } + send = (msg: any) => { + try { + this.ws.send(JSON.stringify(msg)); + } catch (err) { + // + } + }; handleClientMessage = (event: string) => { let msg: any; try { @@ -131,11 +132,7 @@ export class Session { this.term.pty.kill(); this.term.live = false; } - try { - this.ws.send(JSON.stringify({ event: "terminalClear" })); - } catch (err) { - // - } + this.send({ event: "terminalClear" }); if (this.homedir == null) { this.homedir = `/tmp/riju/${this.uuid}`; await callPrivileged(["setup", `${this.uid}`, this.uuid], this.log); @@ -221,13 +218,7 @@ export class Session { // Capture term in closure so that we don't keep sending output // from the old pty even after it's been killed (see ghci). if (term.live) { - try { - this.ws.send( - JSON.stringify({ event: "terminalOutput", output: data }) - ); - } catch (err) { - // - } + this.send({ event: "terminalOutput", output: data }); } }); if (lsp && this.lsp === null) { @@ -251,17 +242,19 @@ export class Session { const proc = spawn(lspArgs[0], lspArgs.slice(1), { env: getEnv(this.uuid), }); + proc.on("exit", (code) => this.send({ event: "lspCrashed", code })); + proc.stderr.on("data", (data) => + this.send({ event: "lspLog", output: data.toString("utf8") }) + ); this.lsp = { proc, reader: new rpc.StreamMessageReader(proc.stdout), writer: new rpc.StreamMessageWriter(proc.stdin), }; this.lsp.reader.listen((data) => { - this.ws.send(JSON.stringify({ event: "lspOutput", output: data })); + this.send({ event: "lspOutput", output: data }); }); - this.ws.send( - JSON.stringify({ event: "lspStarted", root: `/tmp/riju/${this.uuid}` }) - ); + this.send({ event: "lspStarted", root: `/tmp/riju/${this.uuid}` }); } }; cleanup = async () => { diff --git a/frontend/src/app.ts b/frontend/src/app.ts index 045affa..c12ab85 100644 --- a/frontend/src/app.ts +++ b/frontend/src/app.ts @@ -119,6 +119,7 @@ async function main() { function tryConnect() { let clientDisposable: Disposable | null = null; let servicesDisposable: Disposable | null = null; + let lspLogBuffer = ""; console.log("Connecting to server..."); socket = new WebSocket( (document.location.protocol === "http:" ? "ws://" : "wss://") + @@ -136,7 +137,11 @@ async function main() { console.error("Malformed message from server:", event.data); return; } - if (DEBUG && message?.event !== "lspOutput") { + if ( + DEBUG && + message?.event !== "lspOutput" && + message?.event !== "lspLog" + ) { console.log("RECEIVE:", message); } if (message?.event && message?.event !== "error") { @@ -198,6 +203,23 @@ async function main() { case "lspOutput": // Should be handled by RijuMessageReader return; + case "lspLog": + if (typeof message.output !== "string") { + console.error("Unexpected message from server:", message); + return; + } + if (DEBUG) { + lspLogBuffer += message.output; + while (lspLogBuffer.includes("\n")) { + const idx = lspLogBuffer.indexOf("\n"); + const line = lspLogBuffer.slice(0, idx); + lspLogBuffer = lspLogBuffer.slice(idx + 1); + console.log(`LSP || ${line}`); + } + } + return; + case "lspCrashed": + return; default: console.error("Unexpected message from server:", message); return; From e28e10c05477279caf1f8eea73b2eaf50d85ec46 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 6 Jul 2020 14:52:14 -0600 Subject: [PATCH 090/388] LSP working for Julia oh my god that was terrible --- backend/src/langs.ts | 1 + frontend/src/app.ts | 10 ++++++++-- scripts/docker-install-phase4.bash | 7 +++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index bf5ac92..8bbe4e8 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -518,6 +518,7 @@ PLEASE GIVE UP repl: "julia", main: "main.jl", run: "julia -L main.jl", + lsp: `JULIA_DEPOT_PATH=:/opt/julia julia -e 'using LanguageServer; run(LanguageServerInstance(stdin, stdout))'`, template: `println("Hello, world!") `, }, diff --git a/frontend/src/app.ts b/frontend/src/app.ts index c12ab85..6642f8e 100644 --- a/frontend/src/app.ts +++ b/frontend/src/app.ts @@ -84,6 +84,9 @@ class RijuMessageWriter extends AbstractMessageWriter { } write(msg: Message): void { + if ((msg as any).method === "initialize") { + (msg as any).params.processId = null; + } if (DEBUG) { console.log("SEND LSP:", msg); } @@ -184,8 +187,11 @@ async function main() { documentSelector: [{ pattern: "**" }], middleware: { workspace: { - configuration: () => { - return [config.lspConfig || {}]; + configuration: (params, token, configuration) => { + (window as any).config = configuration; + return Array( + (configuration(params, token) as {}[]).length + ).fill(config.lspConfig || null); }, }, }, diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 024ed34..843e372 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -5,6 +5,10 @@ set -o pipefail set -x # Needed for project infrastructure +cd /tmp +mkdir /opt/julia +export JULIA_DEPOT_PATH=/opt/julia + npm config set unsafe-perm true PERL_MM_USE_DEFAULT=1 cpan App::cpanminus rm -rf /tmp/cpan_install_*.txt @@ -37,6 +41,9 @@ npm install -g @kachkaev/run-elm # FORTRAN pip3 install fortran-language-server +# Julia +julia -e 'using Pkg; Pkg.add("LanguageServer")' + # Perl cpanm -n Devel::REPL From e47e49e353ec1954c5ca2215cb1080034185cd16 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 6 Jul 2020 18:19:07 -0600 Subject: [PATCH 091/388] LSP working for Haskell And I even managed to dodge the absurd 30-minute compilation time that would normally be required in order to install HIE. --- backend/src/langs.ts | 6 ++++++ frontend/src/app.ts | 4 +++- scripts/docker-install-phase5.bash | 16 +++++++++++++++- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 8bbe4e8..d027af8 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -450,6 +450,11 @@ func main() { repl: "ghci", main: "Main.hs", run: "ghci", + lspSetup: "cp /opt/haskell/hie.yaml hie.yaml", + lsp: "HIE_HOOGLE_DATABASE=/opt/haskell/hoogle.hoo hie --lsp", + lspInit: { + languageServerHaskell: {}, + }, template: `module Main where main :: IO () @@ -519,6 +524,7 @@ PLEASE GIVE UP main: "main.jl", run: "julia -L main.jl", lsp: `JULIA_DEPOT_PATH=:/opt/julia julia -e 'using LanguageServer; run(LanguageServerInstance(stdin, stdout))'`, + lspConfig: null, template: `println("Hello, world!") `, }, diff --git a/frontend/src/app.ts b/frontend/src/app.ts index 6642f8e..857e4bd 100644 --- a/frontend/src/app.ts +++ b/frontend/src/app.ts @@ -191,7 +191,9 @@ async function main() { (window as any).config = configuration; return Array( (configuration(params, token) as {}[]).length - ).fill(config.lspConfig || null); + ).fill( + config.lspConfig !== undefined ? config.lspConfig : {} + ); }, }, }, diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index f31775a..f9f9499 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -100,9 +100,15 @@ tar -xf swift.tar.gz -C /opt/swift --strip-components=2 ln -s /opt/swift/bin/swiftc /usr/bin/swiftc rm swift.tar.gz +# Haskell +mkdir -p /opt/haskell +gdown "https://drive.google.com/uc?export=download&id=1GPoR_ja4ns16KCamRgwB-JVag4HK0igz" /usr/bin/hie +gdown "https://drive.google.com/uc?export=download&id=1qSxj8JjAeetAmNjUGayX0RBARgr5R4Ij" /opt/haskell/hoogle.hoo +chmod +x /usr/bin/hie + # Kalyn cd /tmp -git clone https://github.com/raxod502/kalyn +git clone https://github.com/raxod502/kalyn.git pushd kalyn >/dev/null stack build kalyn mv "$(stack exec which kalyn)" /usr/bin/kalyn @@ -217,6 +223,14 @@ tee /opt/elm/elm.json >/dev/null <<"EOF" } EOF +# Haskell +mkdir -p /opt/haskell +tee /opt/haskell/hie.yaml >/dev/null <<"EOF" +cradle: + direct: + arguments: [] +EOF + # Unlambda tee /usr/bin/unlambda-repl >/dev/null <<"EOF" #!/usr/bin/env python3 From f39f2ca58f5f526f7dc682c3b5039edf3b3f08d4 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 6 Jul 2020 18:25:39 -0600 Subject: [PATCH 092/388] LSP working for Ruby It is my dream that all language servers would be so easy --- backend/src/langs.ts | 1 + scripts/docker-install-phase3c.bash | 1 + scripts/docker-install-phase4.bash | 3 +++ 3 files changed, 5 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index d027af8..bce605c 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -819,6 +819,7 @@ binding_irb = IRB::Irb.new(workspace) binding_irb.run(IRB.conf) `, run: "ruby main.rb", + lsp: "solargraph stdio", template: `puts "Hello, world!" `, }, diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index e4271e4..e68abee 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -57,6 +57,7 @@ qemu-user-static # Ruby ruby +ruby-dev " diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 843e372..3bad91e 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -50,6 +50,9 @@ cpanm -n Devel::REPL # ReasonML npm install -g bs-platform +# Ruby +gem install solargraph + # Rust rustup component add rls rust-analysis rust-src From fd4a81a8d178e3ddcc1fc5525a07701b09a8589f Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 6 Jul 2020 18:27:26 -0600 Subject: [PATCH 093/388] LSP working for Bash Another easy one! --- backend/src/langs.ts | 1 + scripts/docker-install-phase4.bash | 3 +++ 2 files changed, 4 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index bce605c..387b253 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -82,6 +82,7 @@ implement main0 () = () repl: "bash --rcfile /dev/null", main: "main.bash", run: "bash --rcfile main.bash", + lsp: "bash-language-server start", template: `echo "Hello, world!" `, }, diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 3bad91e..985a13b 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -26,6 +26,9 @@ for file in /opt/rust/bin/*; do ln -s /opt/rust/wrapper /usr/bin/${file##*/} done +# Bash +npm install -g bash-language-server + # Befunge npm install -g befunge93 prompt-sync From 49586c095057fdbae1264025f74ae2aba4457cd0 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Tue, 7 Jul 2020 12:20:53 -0600 Subject: [PATCH 094/388] LSP working for Ada --- backend/src/langs.ts | 1 + scripts/docker-install-phase5.bash | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 387b253..82d7982 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -25,6 +25,7 @@ export const langs: { [key: string]: LangConfig } = { main: "main.adb", compile: "x86_64-linux-gnu-gnatmake-9 main.adb", run: "./main", + lsp: "ada_language_server", template: `with Ada.Text_IO; procedure Main is diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index f9f9499..0b5986f 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -21,6 +21,14 @@ tar -xf linux-x86_64-static.tar.gz mv stack-*-linux-x86_64-static/stack /usr/bin/stack rm -rf stack-*-linux-x86_64-static linux-x86_64-static.tar.gz +# Ada +cd /tmp +wget -nv https://dl.bintray.com/reznikmm/ada-language-server/linux-latest.tar.gz +tar -xf linux-latest.tar.gz +mv linux/ada_language_server /usr/bin/ada_language_server +mv linux/*.so* /usr/lib/x86_64-linux-gnu/ +rm linux-latest.tar.gz + # Clojure cd /tmp wget -nv https://github.com/snoe/clojure-lsp/releases/download/release-20200629T153107/clojure-lsp From eeb4d3af70c93a65cad9558368afadf2934af595 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Wed, 8 Jul 2020 18:42:31 -0600 Subject: [PATCH 095/388] Various hacks --- .gitignore | 1 + backend/src/api.ts | 56 +++++++------- backend/src/global.d.ts | 2 +- backend/src/langs.ts | 11 ++- backend/src/lsp-repl.ts | 116 +++++++++++++++++++++++++++++ backend/src/util.ts | 2 +- frontend/src/app.ts | 28 +++++-- package.json | 6 +- scripts/docker-install-phase2.bash | 1 + yarn.lock | 35 ++++++++- 10 files changed, 215 insertions(+), 43 deletions(-) create mode 100755 backend/src/lsp-repl.ts diff --git a/.gitignore b/.gitignore index 1a03776..9d1ea22 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.log .log +.lsp-repl-history node_modules out diff --git a/backend/src/api.ts b/backend/src/api.ts index 130af6e..922998c 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -19,7 +19,7 @@ import { export class Session { uuid: string; - code: string; + code: string | null; config: LangConfig; term: { pty: IPty | null; live: boolean }; lsp: { @@ -41,7 +41,7 @@ export class Session { this.config = langs[lang]; this.term = { pty: null, live: false }; this.lsp = null; - this.code = ""; + this.code = null; this.homedir = null; this.uid = null; this.uidCleanup = null; @@ -121,11 +121,12 @@ export class Session { repl, main, suffix, - alwaysCreate, + createEmpty, compile, run, lspSetup, lsp, + template, hacks, } = this.config; if (this.term.pty) { @@ -141,42 +142,37 @@ export class Session { if (!run) { cmdline = `echo 'Support for ${this.config.name} is not yet implemented.'`; } else if (this.code) { - let code = this.code; - if (suffix) { - code += suffix; - } - if (main.includes("/")) { - await spawnPrivileged( - this.uid, - this.uuid, - ["mkdir", "-p", path.dirname(path.resolve(this.homedir, main))], - this.log - ); - } - await spawnPrivileged( - this.uid, - this.uuid, - ["sh", "-c", `cat > ${path.resolve(this.homedir, main)}`], - this.log, - { input: code } - ); cmdline = run; if (compile) { cmdline = `( ${compile} ) && ( ${run} )`; } } else if (repl) { - if (alwaysCreate) { - await spawnPrivileged( - this.uid, - this.uuid, - ["touch", `${path.resolve(this.homedir, main)}`], - this.log - ); - } cmdline = repl; } else { cmdline = `echo '${name} has no REPL, press Run to see it in action'`; } + let code = this.code; + if (this.code === null) { + code = createEmpty ? "" : template; + } + if (code && suffix) { + code += suffix; + } + if (main.includes("/")) { + await spawnPrivileged( + this.uid, + this.uuid, + ["mkdir", "-p", path.dirname(path.resolve(this.homedir, main))], + this.log + ); + } + await spawnPrivileged( + this.uid, + this.uuid, + ["sh", "-c", `cat > ${path.resolve(this.homedir, main)}`], + this.log, + { input: code as string } + ); if (hacks && hacks.includes("ghci-config") && run) { if (this.code) { const contents = ":load Main\nmain\n"; diff --git a/backend/src/global.d.ts b/backend/src/global.d.ts index 3aad786..6a63761 100644 --- a/backend/src/global.d.ts +++ b/backend/src/global.d.ts @@ -1 +1 @@ -declare module "heroku-ssl-redirect"; +declare module "historic-readline"; diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 82d7982..6193c94 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -6,13 +6,15 @@ export interface LangConfig { main: string; prefix?: string; suffix?: string; - alwaysCreate?: boolean; + createEmpty?: boolean; compile?: string; run: string; lspSetup?: string; lsp?: string; + lspDisableDynamicRegistration?: boolean; lspInit?: any; lspConfig?: any; + lspLang?: string; template: string; hacks?: "ghci-config"[]; } @@ -340,6 +342,7 @@ output = "Hello, world!" monacoLang: "plaintext", repl: `SHELL=/usr/bin/elvish HOME="$PWD" elvish`, main: ".elvish/rc.elv", + createEmpty: true, run: `SHELL=/usr/bin/elvish HOME="$PWD" elvish`, template: `echo "Hello, world!" `, @@ -558,6 +561,7 @@ PLEASE GIVE UP monacoLang: "shell", repl: `SHELL=/usr/bin/ksh HOME="$PWD" ksh`, main: ".kshrc", + createEmpty: true, run: `SHELL=/usr/bin/ksh HOME="$PWD" ksh`, template: `echo "Hello, world!" `, @@ -865,6 +869,7 @@ binding_irb.run(IRB.conf) monacoLang: "shell", repl: `SHELL=/usr/bin/sh HOME="$PWD" posh -l`, main: ".profile", + createEmpty: true, run: `SHELL=/usr/bin/sh HOME="$PWD" posh -l`, template: `echo "Hello, world!" `, @@ -1025,6 +1030,7 @@ END monacoLang: "tcl", repl: "tclsh", main: ".tclshrc", + createEmpty: true, run: `HOME="$PWD" tclsh`, template: `puts {Hello, world!} `, @@ -1035,6 +1041,7 @@ END monacoLang: "shell", repl: `SHELL=/usr/bin/tcsh HOME="$PWD" tcsh`, main: ".tcshrc", + createEmpty: true, run: `SHELL=/usr/bin/tcsh HOME="$PWD" tcsh`, template: `echo "Hello, world!" `, @@ -1147,7 +1154,7 @@ message: monacoLang: "shell", repl: "SHELL=/usr/bin/zsh zsh", main: ".zshrc", - alwaysCreate: true, + createEmpty: true, run: `SHELL=/usr/bin/zsh ZDOTDIR="$PWD" zsh`, template: `echo "Hello, world!" `, diff --git a/backend/src/lsp-repl.ts b/backend/src/lsp-repl.ts new file mode 100755 index 0000000..fe2f4cc --- /dev/null +++ b/backend/src/lsp-repl.ts @@ -0,0 +1,116 @@ +import * as child_process from "child_process"; +import * as process from "process"; +import * as nodeReadline from "readline"; + +import * as appRoot from "app-root-path"; +import * as readline from "historic-readline"; +import { quote } from "shell-quote"; +import * as rpc from "vscode-jsonrpc"; + +import { langs } from "./langs"; + +const args = process.argv.slice(2); + +function printUsage() { + console.log(`usage: yarn lsp-repl (LANG | CMDLINE...)`); +} + +if (args.length === 0) { + printUsage(); + process.exit(1); +} + +if (["-h", "-help", "--help", "help"].includes(args[0])) { + printUsage(); + process.exit(0); +} + +let cmdline; +if ( + args.length === 1 && + langs[args[0]] && + typeof langs[args[0]].lsp === "string" +) { + cmdline = ["bash", "-c", langs[args[0]].lsp as string]; +} else { + cmdline = args; +} + +console.error(quote(cmdline)); +const proc = child_process.spawn(cmdline[0], cmdline.slice(1)); + +proc.stderr.on("data", (data) => process.stderr.write(data)); +proc.on("exit", (code, signal) => { + if (code) { + console.error(`Language server exited with code ${code}`); + process.exit(code); + } else { + console.error(`Language server exited due to signal ${signal}`); + process.exit(1); + } +}); +proc.on("error", (err) => { + console.error(`Failed to start language server: ${err}`); + process.exit(1); +}); + +const reader = new rpc.StreamMessageReader(proc.stdout); +const writer = new rpc.StreamMessageWriter(proc.stdin); + +reader.listen((data) => { + console.log("<<< " + JSON.stringify(data) + "\n"); +}); + +// https://stackoverflow.com/a/10608048/3538165 +function fixStdoutFor(cli: any) { + var oldStdout = process.stdout; + var newStdout = Object.create(oldStdout); + newStdout.write = function () { + cli.output.write("\x1b[2K\r"); + var result = oldStdout.write.apply( + this, + (Array.prototype.slice as any).call(arguments) + ); + cli._refreshLine(); + return result; + }; + (process as any).__defineGetter__("stdout", function () { + return newStdout; + }); +} + +readline.createInterface({ + input: process.stdin, + output: process.stdout, + path: appRoot.resolve(".lsp-repl-history"), + next: (cli: nodeReadline.Interface) => { + fixStdoutFor(cli); + cli.setPrompt(">>> "); + cli.on("line", (line: string) => { + if (line) { + let data; + try { + data = JSON.parse(line); + } catch (err) { + console.error(`Invalid JSON: ${err}`); + cli.prompt(); + return; + } + console.log(); + writer.write(data); + } + cli.prompt(); + }); + cli.on("SIGINT", () => { + console.error("^C"); + cli.write("", { ctrl: true, name: "u" }); + cli.prompt(); + }); + cli.on("close", () => { + console.error(); + process.exit(0); + }); + console.log(); + cli.prompt(); + }, +}); diff --git a/backend/src/util.ts b/backend/src/util.ts index 328f13a..eebe1d1 100644 --- a/backend/src/util.ts +++ b/backend/src/util.ts @@ -37,7 +37,7 @@ export async function call( delete options.input; delete options.check; const proc = spawn(args[0], args.slice(1), options); - if (input) { + if (typeof input === "string") { proc.stdin!.end(input); } let output = ""; diff --git a/frontend/src/app.ts b/frontend/src/app.ts index 857e4bd..8337c3c 100644 --- a/frontend/src/app.ts +++ b/frontend/src/app.ts @@ -19,13 +19,16 @@ import { FitAddon } from "xterm-addon-fit"; import "xterm/css/xterm.css"; const DEBUG = window.location.hash === "#debug"; +const config: RijuConfig = (window as any).rijuConfig; interface RijuConfig { id: string; monacoLang: string; main: string; + lspDisableDynamicRegistration?: boolean; lspInit?: any; lspConfig?: any; + lspLang?: string; template: string; } @@ -84,19 +87,35 @@ class RijuMessageWriter extends AbstractMessageWriter { } write(msg: Message): void { - if ((msg as any).method === "initialize") { - (msg as any).params.processId = null; + switch ((msg as any).method) { + case "initialize": + (msg as any).params.processId = null; + if (config.lspDisableDynamicRegistration) { + this.disableDynamicRegistration(msg); + } + break; + case "textDocument/didOpen": + if (config.lspLang) { + (msg as any).params.textDocument.languageId = config.lspLang; + } } if (DEBUG) { console.log("SEND LSP:", msg); } this.socket.send(JSON.stringify({ event: "lspInput", input: msg })); } + + disableDynamicRegistration(msg: any) { + if (!msg || typeof msg !== "object") return; + for (const [key, val] of Object.entries(msg)) { + if (key === "dynamicRegistration" && val === true) + msg.dynamicRegistration = false; + this.disableDynamicRegistration(val); + } + } } async function main() { - const config: RijuConfig = (window as any).rijuConfig; - const term = new Terminal(); const fitAddon = new FitAddon(); term.loadAddon(fitAddon); @@ -188,7 +207,6 @@ async function main() { middleware: { workspace: { configuration: (params, token, configuration) => { - (window as any).config = configuration; return Array( (configuration(params, token) as {}[]).length ).fill( diff --git a/package.json b/package.json index daf5eb5..02bd9dc 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "@types/mkdirp": "^1.0.1", "@types/parse-passwd": "^1.0.0", "@types/rimraf": "^3.0.0", + "@types/shell-quote": "^1.7.0", "@types/tmp": "^0.2.0", "@types/uuid": "^8.0.0", "app-root-path": "^3.0.0", @@ -24,6 +25,7 @@ "express": "^4.17.1", "express-ws": "^4.0.0", "file-loader": "^6.0.0", + "historic-readline": "^1.0.8", "lodash": "^4.17.15", "monaco-editor": "^0.20.0", "monaco-editor-webpack-plugin": "^1.9.0", @@ -32,6 +34,7 @@ "node-pty": "^0.9.0", "npm-run-all": "^4.1.5", "parse-passwd": "^1.0.0", + "shell-quote": "^1.7.2", "style-loader": "^1.2.1", "ts-loader": "^7.0.5", "typescript": "^3.9.5", @@ -53,6 +56,7 @@ "system": "scripts/compile-system.bash", "system-dev": "watchexec --no-vcs-ignore -w system/src -n scripts/compile-system.bash", "build": "run-s backend frontend system", - "dev": "run-p backend-dev frontend-dev system-dev server-dev" + "dev": "run-p backend-dev frontend-dev system-dev server-dev", + "lsp": "node backend/out/lsp-repl.js" } } diff --git a/scripts/docker-install-phase2.bash b/scripts/docker-install-phase2.bash index 37d96fd..14d6574 100755 --- a/scripts/docker-install-phase2.bash +++ b/scripts/docker-install-phase2.bash @@ -27,6 +27,7 @@ make man-db moreutils nano +iputils-ping sudo tmux vim diff --git a/yarn.lock b/yarn.lock index 2f3509f..387f7bf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -918,6 +918,11 @@ "@types/express-serve-static-core" "*" "@types/mime" "*" +"@types/shell-quote@^1.7.0": + version "1.7.0" + resolved "https://registry.yarnpkg.com/@types/shell-quote/-/shell-quote-1.7.0.tgz#0b6b930de00ad35128239b182c1fec8b8c40e876" + integrity sha512-0CJaSSayMigMKu/Egx1eVcFjgGYkP6T4dyPRs462BFrMB/OK2FAJFV/24+6R4cGIXw6ZQpZK8XEd2UCVKfkZRw== + "@types/tmp@^0.2.0": version "0.2.0" resolved "https://registry.yarnpkg.com/@types/tmp/-/tmp-0.2.0.tgz#e3f52b4d7397eaa9193592ef3fdd44dc0af4298c" @@ -2362,6 +2367,16 @@ from2@^2.1.0: inherits "^2.0.1" readable-stream "^2.0.0" +fs-extra@^0.24.0: + version "0.24.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.24.0.tgz#d4e4342a96675cb7846633a6099249332b539952" + integrity sha1-1OQ0KpZnXLeEZjOmCZJJMytTmVI= + dependencies: + graceful-fs "^4.1.2" + jsonfile "^2.1.0" + path-is-absolute "^1.0.0" + rimraf "^2.2.8" + fs-write-stream-atomic@^1.0.8: version "1.0.10" resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" @@ -2502,7 +2517,7 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2: +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6: version "4.2.4" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== @@ -2582,6 +2597,13 @@ he@1.1.1: resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0= +historic-readline@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/historic-readline/-/historic-readline-1.0.8.tgz#6f36e770769275113a57ae1a6007001af771cff6" + integrity sha1-bzbncHaSdRE6V64aYAcAGvdxz/Y= + dependencies: + fs-extra "^0.24.0" + hmac-drbg@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -2995,6 +3017,13 @@ json5@^2.1.2: dependencies: minimist "^1.2.5" +jsonfile@^2.1.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" + integrity sha1-NzaitCi4e72gzIO1P6PWM6NcKug= + optionalDependencies: + graceful-fs "^4.1.6" + kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -4133,7 +4162,7 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== -rimraf@^2.5.4, rimraf@^2.6.3: +rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.3: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== @@ -4291,7 +4320,7 @@ shebang-regex@^1.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= -shell-quote@^1.6.1: +shell-quote@^1.6.1, shell-quote@^1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== From 8b8c199c34a17c5c97ba453fc6dabe8a9f2dbf3c Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Wed, 8 Jul 2020 18:56:52 -0600 Subject: [PATCH 096/388] Refactor, LSP working for Elixir --- Dockerfile.dev | 6 + Dockerfile.prod | 6 + backend/src/langs.ts | 1 + scripts/docker-install-phase1.bash | 3 +- scripts/docker-install-phase4.bash | 5 +- scripts/docker-install-phase5.bash | 193 +++-------------------------- scripts/docker-install-phase6.bash | 134 ++++++++++++++++++-- scripts/docker-install-phase7.bash | 31 +++++ scripts/docker-install-phase8.bash | 24 ++++ 9 files changed, 213 insertions(+), 190 deletions(-) create mode 100755 scripts/docker-install-phase7.bash create mode 100755 scripts/docker-install-phase8.bash diff --git a/Dockerfile.dev b/Dockerfile.dev index efe6904..5c7df74 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -32,6 +32,12 @@ RUN /tmp/docker-install-phase5.bash COPY scripts/docker-install-phase6.bash /tmp/ RUN /tmp/docker-install-phase6.bash "$UID" +COPY scripts/docker-install-phase7.bash /tmp/ +RUN /tmp/docker-install-phase7.bash "$UID" + +COPY scripts/docker-install-phase8.bash /tmp/ +RUN /tmp/docker-install-phase8.bash "$UID" + USER docker WORKDIR /home/docker RUN chmod go-rwx /home/docker diff --git a/Dockerfile.prod b/Dockerfile.prod index a69919d..38f0854 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -34,6 +34,12 @@ RUN /tmp/docker-install-phase5.bash COPY scripts/docker-install-phase6.bash /tmp/ RUN /tmp/docker-install-phase6.bash +COPY scripts/docker-install-phase7.bash /tmp/ +RUN /tmp/docker-install-phase7.bash "$UID" + +COPY scripts/docker-install-phase8.bash /tmp/ +RUN /tmp/docker-install-phase8.bash "$UID" + USER docker WORKDIR /home/docker RUN chmod go-rwx /home/docker diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 6193c94..c6cb5c4 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -321,6 +321,7 @@ void main() { repl: "iex", main: "main.exs", run: "iex main.exs", + lsp: "/opt/elixir-ls/language_server.sh", template: `IO.puts("Hello, world!") `, }, diff --git a/scripts/docker-install-phase1.bash b/scripts/docker-install-phase1.bash index 5f47de2..61f4e24 100755 --- a/scripts/docker-install-phase1.bash +++ b/scripts/docker-install-phase1.bash @@ -3,6 +3,7 @@ set -e set -o pipefail set -x +pushd /tmp >/dev/null dpkg --add-architecture i386 @@ -17,7 +18,6 @@ curl -sSL https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - curl -sSL https://keybase.io/crystal/pgp_keys.asc | apt-key add - apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9 -cd /tmp wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb dpkg -i packages-microsoft-prod.deb rm packages-microsoft-prod.deb @@ -33,4 +33,5 @@ EOF add-apt-repository -y -n ppa:deadsnakes/ppa +popd >/dev/null rm "$0" diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 985a13b..21448f8 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -4,15 +4,16 @@ set -e set -o pipefail set -x -# Needed for project infrastructure -cd /tmp +# Package manager - Julia mkdir /opt/julia export JULIA_DEPOT_PATH=/opt/julia +# Package manager - Node.js npm config set unsafe-perm true PERL_MM_USE_DEFAULT=1 cpan App::cpanminus rm -rf /tmp/cpan_install_*.txt +# Package manager - Rust export CARGO_HOME=/opt/rust export RUSTUP_HOME=/opt/rust curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index 0b5986f..1716cda 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -3,26 +3,18 @@ set -e set -o pipefail set -x +pushd /tmp >/dev/null # Needed for project infrastructure -cd /tmp wget -nv https://github.com/watchexec/watchexec/releases/download/1.13.1/watchexec-1.13.1-x86_64-unknown-linux-gnu.deb dpkg -i watchexec-*.deb rm watchexec-*.deb -cd /tmp git clone https://github.com/circulosmeos/gdown.pl.git mv gdown.pl/gdown.pl /usr/bin/gdown rm -rf gdown.pl -cd /tmp -wget https://get.haskellstack.org/stable/linux-x86_64-static.tar.gz -tar -xf linux-x86_64-static.tar.gz -mv stack-*-linux-x86_64-static/stack /usr/bin/stack -rm -rf stack-*-linux-x86_64-static linux-x86_64-static.tar.gz - # Ada -cd /tmp wget -nv https://dl.bintray.com/reznikmm/ada-language-server/linux-latest.tar.gz tar -xf linux-latest.tar.gz mv linux/ada_language_server /usr/bin/ada_language_server @@ -30,19 +22,21 @@ mv linux/*.so* /usr/lib/x86_64-linux-gnu/ rm linux-latest.tar.gz # Clojure -cd /tmp wget -nv https://github.com/snoe/clojure-lsp/releases/download/release-20200629T153107/clojure-lsp chmod +x clojure-lsp mv clojure-lsp /usr/bin/clojure-lsp # D -cd /tmp wget -nv http://downloads.dlang.org/releases/2.x/2.092.0/dmd_2.092.0-0_amd64.deb dpkg -i dmd_*.deb rm dmd_*.deb +# Elixir +wget -nv https://github.com/elixir-lsp/elixir-ls/releases/download/v0.5.0/elixir-ls.zip +unzip -d /opt/elixir-ls elixir-ls.zip +ln -s /opt/elixir-ls/language_server.sh /usr/bin/elixir-ls + # Elm -cd /tmp wget -nv https://github.com/elm/compiler/releases/download/0.19.1/binary-for-linux-64-bit.gz gunzip binary-for-linux-64-bit.gz chmod +x binary-for-linux-64-bit @@ -54,8 +48,18 @@ export GOPATH=/tmp/go mv /tmp/go/bin/gopls /usr/bin/gopls rm -rf /tmp/go +# Haskell +wget https://get.haskellstack.org/stable/linux-x86_64-static.tar.gz +tar -xf linux-x86_64-static.tar.gz +mv stack-*-linux-x86_64-static/stack /usr/bin/stack +rm -rf stack-*-linux-x86_64-static linux-x86_64-static.tar.gz + +mkdir -p /opt/haskell +gdown "https://drive.google.com/uc?export=download&id=1GPoR_ja4ns16KCamRgwB-JVag4HK0igz" /usr/bin/hie +gdown "https://drive.google.com/uc?export=download&id=1qSxj8JjAeetAmNjUGayX0RBARgr5R4Ij" /opt/haskell/hoogle.hoo +chmod +x /usr/bin/hie + # Ink -cd /tmp wget -nv https://github.com/thesephist/ink/releases/download/v0.1.7/ink-linux wget -nv https://github.com/thesephist/ink/releases/download/v0.1.7/std.ink wget -nv https://github.com/thesephist/ink/releases/download/v0.1.7/str.ink @@ -65,7 +69,6 @@ mkdir /opt/ink mv std.ink str.ink /opt/ink/ # Kotlin -cd /tmp wget -nv https://github.com/JetBrains/kotlin/releases/download/v1.3.72/kotlin-compiler-1.3.72.zip unzip kotlin-*.zip cp kotlinc/bin/* /usr/bin/ @@ -73,7 +76,6 @@ cp kotlinc/lib/* /usr/lib/ rm -rf kotlin-*.zip kotlinc # PowerShell -cd /tmp wget -nv https://github.com/PowerShell/PowerShell/releases/download/v7.0.1/powershell-7.0.1-linux-x64.tar.gz mkdir /opt/powershell tar -xf powershell-*.tar.gz -C /opt/powershell @@ -81,7 +83,6 @@ ln -s /opt/powershell/pwsh /usr/bin/pwsh rm powershell-*.tar.gz # Python -cd /tmp xml="$(curl -sSL "https://pvsc.blob.core.windows.net/python-language-server-stable?restype=container&comp=list&prefix=Python-Language-Server-linux-x64")" nupkg="$(echo "$xml" | grep -Eo 'https://[^<]+\.nupkg' | tail -n1)" wget -nv "${nupkg}" @@ -101,171 +102,11 @@ popd >/dev/null rm -rf snobol4-* # Swift -cd /tmp gdown "https://drive.google.com/uc?export=download&id=1eE1-VuZz0gv-fITaGVT_r1UunCLjS-JT" swift.tar.gz mkdir /opt/swift tar -xf swift.tar.gz -C /opt/swift --strip-components=2 ln -s /opt/swift/bin/swiftc /usr/bin/swiftc rm swift.tar.gz -# Haskell -mkdir -p /opt/haskell -gdown "https://drive.google.com/uc?export=download&id=1GPoR_ja4ns16KCamRgwB-JVag4HK0igz" /usr/bin/hie -gdown "https://drive.google.com/uc?export=download&id=1qSxj8JjAeetAmNjUGayX0RBARgr5R4Ij" /opt/haskell/hoogle.hoo -chmod +x /usr/bin/hie - -# Kalyn -cd /tmp -git clone https://github.com/raxod502/kalyn.git -pushd kalyn >/dev/null -stack build kalyn -mv "$(stack exec which kalyn)" /usr/bin/kalyn -mkdir /opt/kalyn -cp -R src-kalyn/Stdlib src-kalyn/Stdlib.kalyn /opt/kalyn/ popd >/dev/null -rm -rf kalyn - -# LOLCODE -cd /tmp -git clone https://github.com/justinmeza/lci.git -pushd lci >/dev/null -python3 install.py --prefix=/usr -popd >/dev/null -rm -rf lci - -# Malbolge -cd /tmp -git clone https://github.com/bipinu/malbolge.git -clang malbolge/malbolge.c -o /usr/bin/malbolge -rm -rf malbolge - -# Befunge -tee /usr/bin/befunge-repl >/dev/null <<"EOF" -#!/usr/bin/env -S NODE_PATH=/usr/lib/node_modules node -const fs = require("fs"); - -const Befunge = require("befunge93"); -const prompt = require("prompt-sync")(); - -const befunge = new Befunge(); -befunge.onInput = prompt; -befunge.onOutput = (output) => { - if (typeof output === "string") { - process.stdout.write(output); - } else { - process.stdout.write(output + " "); - } -}; - -const args = process.argv.slice(2); -if (args.length !== 1) { - console.error("usage: befunge-repl FILE"); - process.exit(1); -} - -befunge.run(fs.readFileSync(args[0], { encoding: "utf-8" })).catch((err) => { - console.error(err); - process.exit(1); -}); -EOF -chmod +x /usr/bin/befunge-repl - -# BrainF -tee /usr/bin/brainf-repl >/dev/null <<"EOF" -#!/usr/bin/env python3 -import argparse -import readline -import subprocess -import tempfile - -parser = argparse.ArgumentParser() -parser.add_argument("file", nargs="?") -args = parser.parse_args() - -if args.file: - subprocess.run(["beef", args.file]) -while True: - try: - code = input("bf> ") - except KeyboardInterrupt: - print("^C") - continue - except EOFError: - print("^D") - break - if not code: - continue - with tempfile.NamedTemporaryFile(mode="w") as f: - f.write(code) - f.flush() - subprocess.run(["beef", f.name]) -EOF -chmod +x /usr/bin/brainf-repl - -# Elm -mkdir /opt/elm -tee /opt/elm/elm.json >/dev/null <<"EOF" -{ - "type": "application", - "source-directories": [ - "." - ], - "elm-version": "0.19.1", - "dependencies": { - "direct": { - "elm/browser": "1.0.2", - "elm/core": "1.0.5", - "elm/html": "1.0.0" - }, - "indirect": { - "elm/json": "1.1.3", - "elm/time": "1.0.0", - "elm/url": "1.0.0", - "elm/virtual-dom": "1.0.2" - } - }, - "test-dependencies": { - "direct": {}, - "indirect": {} - } -} -EOF - -# Haskell -mkdir -p /opt/haskell -tee /opt/haskell/hie.yaml >/dev/null <<"EOF" -cradle: - direct: - arguments: [] -EOF - -# Unlambda -tee /usr/bin/unlambda-repl >/dev/null <<"EOF" -#!/usr/bin/env python3 -import argparse -import readline -import subprocess - -parser = argparse.ArgumentParser() -parser.add_argument("file", nargs="?") -args = parser.parse_args() - -if args.file: - with open(args.file) as f: - subprocess.run(["unlambda"], input=f.read(), encoding="utf-8") -while True: - try: - code = input("λ> ") - except KeyboardInterrupt: - print("^C") - continue - except EOFError: - print("^D") - break - if not code: - continue - subprocess.run(["unlambda"], input=code, encoding="utf-8") -EOF -chmod +x /usr/bin/unlambda-repl - rm "$0" diff --git a/scripts/docker-install-phase6.bash b/scripts/docker-install-phase6.bash index eefee5a..4efcf57 100755 --- a/scripts/docker-install-phase6.bash +++ b/scripts/docker-install-phase6.bash @@ -4,21 +4,133 @@ set -e set -o pipefail set -x -uid="$1" +# Befunge +tee /usr/bin/befunge-repl >/dev/null <<"EOF" +#!/usr/bin/env -S NODE_PATH=/usr/lib/node_modules node +const fs = require("fs"); -rm -rf /tmp/hsperfdata_root +const Befunge = require("befunge93"); +const prompt = require("prompt-sync")(); -if [[ -n "$uid" ]] && (( "$uid" != 0 )); then - useradd --uid="$uid" --password "!" --create-home --groups sudo docker -else - useradd --password "!" --create-home --groups sudo docker -fi +const befunge = new Befunge(); +befunge.onInput = prompt; +befunge.onOutput = (output) => { + if (typeof output === "string") { + process.stdout.write(output); + } else { + process.stdout.write(output + " "); + } +}; -tee /etc/sudoers.d/99-passwordless >/dev/null <<"EOF" -%sudo ALL=(ALL:ALL) NOPASSWD: ALL +const args = process.argv.slice(2); +if (args.length !== 1) { + console.error("usage: befunge-repl FILE"); + process.exit(1); +} + +befunge.run(fs.readFileSync(args[0], { encoding: "utf-8" })).catch((err) => { + console.error(err); + process.exit(1); +}); +EOF +chmod +x /usr/bin/befunge-repl + +# BrainF +tee /usr/bin/brainf-repl >/dev/null <<"EOF" +#!/usr/bin/env python3 +import argparse +import readline +import subprocess +import tempfile + +parser = argparse.ArgumentParser() +parser.add_argument("file", nargs="?") +args = parser.parse_args() + +if args.file: + subprocess.run(["beef", args.file]) +while True: + try: + code = input("bf> ") + except KeyboardInterrupt: + print("^C") + continue + except EOFError: + print("^D") + break + if not code: + continue + with tempfile.NamedTemporaryFile(mode="w") as f: + f.write(code) + f.flush() + subprocess.run(["beef", f.name]) +EOF +chmod +x /usr/bin/brainf-repl + +# Elm +mkdir /opt/elm +tee /opt/elm/elm.json >/dev/null <<"EOF" +{ + "type": "application", + "source-directories": [ + "." + ], + "elm-version": "0.19.1", + "dependencies": { + "direct": { + "elm/browser": "1.0.2", + "elm/core": "1.0.5", + "elm/html": "1.0.0" + }, + "indirect": { + "elm/json": "1.1.3", + "elm/time": "1.0.0", + "elm/url": "1.0.0", + "elm/virtual-dom": "1.0.2" + } + }, + "test-dependencies": { + "direct": {}, + "indirect": {} + } +} EOF -touch /home/docker/.zshrc -chown docker:docker /home/docker/.zshrc +# Haskell +mkdir -p /opt/haskell +tee /opt/haskell/hie.yaml >/dev/null <<"EOF" +cradle: + direct: + arguments: [] +EOF + +# Unlambda +tee /usr/bin/unlambda-repl >/dev/null <<"EOF" +#!/usr/bin/env python3 +import argparse +import readline +import subprocess + +parser = argparse.ArgumentParser() +parser.add_argument("file", nargs="?") +args = parser.parse_args() + +if args.file: + with open(args.file) as f: + subprocess.run(["unlambda"], input=f.read(), encoding="utf-8") +while True: + try: + code = input("λ> ") + except KeyboardInterrupt: + print("^C") + continue + except EOFError: + print("^D") + break + if not code: + continue + subprocess.run(["unlambda"], input=code, encoding="utf-8") +EOF +chmod +x /usr/bin/unlambda-repl rm "$0" diff --git a/scripts/docker-install-phase7.bash b/scripts/docker-install-phase7.bash new file mode 100755 index 0000000..29e0075 --- /dev/null +++ b/scripts/docker-install-phase7.bash @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail +set -x +pushd /tmp >/dev/null + +# Kalyn +git clone https://github.com/raxod502/kalyn.git +pushd kalyn >/dev/null +stack build kalyn +mv "$(stack exec which kalyn)" /usr/bin/kalyn +mkdir /opt/kalyn +cp -R src-kalyn/Stdlib src-kalyn/Stdlib.kalyn /opt/kalyn/ +popd >/dev/null +rm -rf kalyn + +# LOLCODE +git clone https://github.com/justinmeza/lci.git +pushd lci >/dev/null +python3 install.py --prefix=/usr +popd >/dev/null +rm -rf lci + +# Malbolge +git clone https://github.com/bipinu/malbolge.git +clang malbolge/malbolge.c -o /usr/bin/malbolge +rm -rf malbolge + +popd >/dev/null +rm "$0" diff --git a/scripts/docker-install-phase8.bash b/scripts/docker-install-phase8.bash new file mode 100755 index 0000000..eefee5a --- /dev/null +++ b/scripts/docker-install-phase8.bash @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail +set -x + +uid="$1" + +rm -rf /tmp/hsperfdata_root + +if [[ -n "$uid" ]] && (( "$uid" != 0 )); then + useradd --uid="$uid" --password "!" --create-home --groups sudo docker +else + useradd --password "!" --create-home --groups sudo docker +fi + +tee /etc/sudoers.d/99-passwordless >/dev/null <<"EOF" +%sudo ALL=(ALL:ALL) NOPASSWD: ALL +EOF + +touch /home/docker/.zshrc +chown docker:docker /home/docker/.zshrc + +rm "$0" From d112226aa7d2861f3457d2f846807261dc2a8642 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Wed, 8 Jul 2020 19:01:08 -0600 Subject: [PATCH 097/388] LSP working for Elm --- backend/src/langs.ts | 2 ++ scripts/docker-install-phase4.bash | 1 + 2 files changed, 3 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index c6cb5c4..fac2624 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -331,6 +331,8 @@ void main() { repl: "elm repl", main: "Main.elm", run: "cp /opt/elm/elm.json elm.json && run-elm Main.elm; elm repl", + lsp: "elm-language-server --stdio", + lspSetup: "cp /opt/elm/elm.json elm.json", template: `module Main exposing (..) output : String diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 21448f8..809287f 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -41,6 +41,7 @@ npm install -g coffeescript # Elm npm install -g @kachkaev/run-elm +npm install -g @elm-tooling/elm-language-server # FORTRAN pip3 install fortran-language-server From b3fb71f50179ef51cf0224e72e4dd314b4fb8d73 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Wed, 8 Jul 2020 19:09:22 -0600 Subject: [PATCH 098/388] LSP working for Erlang --- backend/src/langs.ts | 1 + scripts/docker-install-phase3b.bash | 1 + scripts/docker-install-phase5.bash | 6 ++++++ scripts/docker-install-phase7.bash | 8 ++++++++ 4 files changed, 16 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index fac2624..0775412 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -368,6 +368,7 @@ output = "Hello, world!" main: "main.erl", compile: "erl -compile main", run: "erl -s main main", + lsp: "erlang_ls", template: `-module(main). -export([main/0]). diff --git a/scripts/docker-install-phase3b.bash b/scripts/docker-install-phase3b.bash index 60e9aad..0a6e4fa 100755 --- a/scripts/docker-install-phase3b.bash +++ b/scripts/docker-install-phase3b.bash @@ -17,6 +17,7 @@ emacs-nox # Erlang erlang +rebar # F# fsharp diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index 1716cda..ab0763b 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -35,6 +35,7 @@ rm dmd_*.deb wget -nv https://github.com/elixir-lsp/elixir-ls/releases/download/v0.5.0/elixir-ls.zip unzip -d /opt/elixir-ls elixir-ls.zip ln -s /opt/elixir-ls/language_server.sh /usr/bin/elixir-ls +rm elixir-ls.zip # Elm wget -nv https://github.com/elm/compiler/releases/download/0.19.1/binary-for-linux-64-bit.gz @@ -42,6 +43,11 @@ gunzip binary-for-linux-64-bit.gz chmod +x binary-for-linux-64-bit mv binary-for-linux-64-bit /usr/bin/elm +# Erlang +wget -nv https://s3.amazonaws.com/rebar3/rebar3 +chmod +x rebar3 +mv rebar3 /usr/bin/rebar3 + # Go export GO111MODULE=on export GOPATH=/tmp/go diff --git a/scripts/docker-install-phase7.bash b/scripts/docker-install-phase7.bash index 29e0075..ab215ad 100755 --- a/scripts/docker-install-phase7.bash +++ b/scripts/docker-install-phase7.bash @@ -5,6 +5,14 @@ set -o pipefail set -x pushd /tmp >/dev/null +# Erlang +git clone https://github.com/erlang-ls/erlang_ls.git +pushd erlang_ls >/dev/null +make +mv _build/default/bin/erlang_ls /usr/bin/erlang_ls +popd >/dev/null +rm -rf erlang_ls + # Kalyn git clone https://github.com/raxod502/kalyn.git pushd kalyn >/dev/null From 2f3f018ba3fead1fe2ebf2259b31902b5d07d672 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Wed, 8 Jul 2020 20:52:50 -0600 Subject: [PATCH 099/388] Reduce number of warnings for Groovy --- backend/src/langs.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 0775412..091e1a6 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -446,9 +446,9 @@ func main() { groovy: { name: "Groovy", monacoLang: "plaintext", - repl: "groovysh", + repl: `JAVA_OPTS="-Djava.util.prefs.systemRoot=$PWD/.java -Djava.util.prefs.userRoot=$PWD/.java/.userPrefs" groovysh`, main: "main.groovy", - run: "groovysh main.groovy", + run: `JAVA_OPTS="-Djava.util.prefs.systemRoot=$PWD/.java -Djava.util.prefs.userRoot=$PWD/.java/.userPrefs" groovysh main.groovy`, template: `print "Hello, world!"; `, }, From cd8682a8559abedad3891c29f7dc66a4af98625d Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Wed, 8 Jul 2020 20:55:14 -0600 Subject: [PATCH 100/388] LSP working for Lua --- backend/src/langs.ts | 1 + scripts/docker-install-phase5.bash | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 091e1a6..a612b52 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -587,6 +587,7 @@ KTHXBYE repl: "lua", main: "main.lua", run: "lua -i main.lua", + lsp: "java -cp /usr/lib/EmmyLua-LS.jar com.tang.vscode.MainKt", template: `print("Hello, world!") `, }, diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index ab0763b..58aee57 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -81,6 +81,10 @@ cp kotlinc/bin/* /usr/bin/ cp kotlinc/lib/* /usr/lib/ rm -rf kotlin-*.zip kotlinc +# Lua +wget -nv https://github.com/EmmyLua/EmmyLua-LanguageServer/releases/download/0.3.6/EmmyLua-LS-all.jar +mv EmmyLua-LS-all.jar /usr/lib/EmmyLua-LS.jar + # PowerShell wget -nv https://github.com/PowerShell/PowerShell/releases/download/v7.0.1/powershell-7.0.1-linux-x64.tar.gz mkdir /opt/powershell From cfc5aba9914cb9f647b6076cef8309bee8c24f41 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Thu, 9 Jul 2020 10:41:03 -0600 Subject: [PATCH 101/388] Add quoting --- scripts/docker-install-phase4.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 809287f..5c20191 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -24,7 +24,7 @@ RUSTUP_HOME=/opt/rust exec /opt/rust/bin/${0##*/} "$@" EOF chmod +x /opt/rust/wrapper for file in /opt/rust/bin/*; do - ln -s /opt/rust/wrapper /usr/bin/${file##*/} + ln -s /opt/rust/wrapper "/usr/bin/${file##*/}" done # Bash From 68dc99c77ffeebeacafb282bf35902d311304d78 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Thu, 9 Jul 2020 11:05:59 -0600 Subject: [PATCH 102/388] LSP working for PHP --- backend/src/langs.ts | 1 + scripts/docker-install-phase4.bash | 3 +++ 2 files changed, 4 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index a612b52..136adeb 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -717,6 +717,7 @@ end. repl: "php -a", main: "main.php", run: "php -d auto_prepend_file=main.php -a", + lsp: "intelephense --stdio", template: ` Date: Thu, 9 Jul 2020 11:34:42 -0600 Subject: [PATCH 103/388] LSP working for PowerShell --- backend/src/langs.ts | 1 + scripts/docker-install-phase5.bash | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 136adeb..7218030 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -730,6 +730,7 @@ echo "Hello, world!\\n"; repl: "SHELL=/usr/bin/pwsh pwsh", main: "main.ps1", run: "SHELL=/usr/bin/pwsh pwsh -NoExit main.ps1", + lsp: `pwsh -NoLogo -NoProfile -Command "/opt/powershell-editor-services/PowerShellEditorServices/Start-EditorServices.ps1 -BundledModulesPath /opt/powershell-editor-services -LogPath '$PWD/.powershell-editor-services/lsp.log' -SessionDetailsPath '$PWD/.powershell-editor-services/session.json' -FeatureFlags @() -AdditionalModules @() -HostName Riju -HostProfileId 'riju' -HostVersion 0.0 -Stdio -LogLevel Normal"`, template: `Write-Host "Hello, world!" `, }, diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index 58aee57..d017710 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -92,6 +92,10 @@ tar -xf powershell-*.tar.gz -C /opt/powershell ln -s /opt/powershell/pwsh /usr/bin/pwsh rm powershell-*.tar.gz +wget -nv https://github.com/PowerShell/PowerShellEditorServices/releases/download/v2.2.0/PowerShellEditorServices.zip +unzip PowerShellEditorServices.zip +mv PowerShellEditorServices /opt/powershell-editor-services + # Python xml="$(curl -sSL "https://pvsc.blob.core.windows.net/python-language-server-stable?restype=container&comp=list&prefix=Python-Language-Server-linux-x64")" nupkg="$(echo "$xml" | grep -Eo 'https://[^<]+\.nupkg' | tail -n1)" From e0a3fcffb66fe3807e13e8e895de4756a0abbc63 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Thu, 9 Jul 2020 12:45:34 -0600 Subject: [PATCH 104/388] LSP working for Scala, mostly --- scripts/docker-install-phase5.bash | 17 ++++++++--------- scripts/docker-install-phase7.bash | 10 ++++++++++ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index d017710..320c4e8 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -105,15 +105,14 @@ chmod +x /opt/mspyls/Microsoft.Python.LanguageServer ln -s /opt/mspyls/Microsoft.Python.LanguageServer /usr/bin/Microsoft.Python.LanguageServer rm Python-Language-Server-linux-x64.*.nupkg -# SNOBOL -wget -nv ftp://ftp.snobol4.org/snobol/old/snobol4-2.1.4.tar.gz -tar -xf snobol4-*.tar.gz -rm snobol4-*.tar.gz -pushd snobol4-* >/dev/null -make || true -mv snobol4 /usr/bin/snobol4 -popd >/dev/null -rm -rf snobol4-* +# Scala +wget -nv https://git.io/coursier-cli +chmod +x coursier-cli +mv coursier-cli /usr/bin/coursier +coursier bootstrap --java-opt -Xss4m --java-opt -Xms100m --java-opt -Dmetals.client=emacs org.scalameta:metals_2.12:0.9.1 -r bintray:scalacenter/releases -r sonatype:snapshots -o /usr/bin/metals +metals -version /dev/null +make || true +mv snobol4 /usr/bin/snobol4 +popd >/dev/null +rm -rf snobol4-* + popd >/dev/null rm "$0" From c93aa1d8c527fbd6248d266f1599e08d6b5d8645 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Thu, 9 Jul 2020 12:47:22 -0600 Subject: [PATCH 105/388] LSP working for Swift --- backend/src/langs.ts | 1 + scripts/docker-install-phase5.bash | 1 + 2 files changed, 2 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 7218030..da59d07 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1028,6 +1028,7 @@ END main: "main.swift", compile: "swiftc main.swift", run: "./main", + lsp: "sourcekit-lsp", template: `print("Hello, world!") `, }, diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index 320c4e8..36c432a 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -119,6 +119,7 @@ gdown "https://drive.google.com/uc?export=download&id=1eE1-VuZz0gv-fITaGVT_r1Uun mkdir /opt/swift tar -xf swift.tar.gz -C /opt/swift --strip-components=2 ln -s /opt/swift/bin/swiftc /usr/bin/swiftc +ln -s /opt/swift/bin/sourcekit-lsp /usr/bin/sourcekit-lsp rm swift.tar.gz popd >/dev/null From 240dead914ecc914023368ad0dcdd6bd83ba18b6 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Thu, 9 Jul 2020 12:51:50 -0600 Subject: [PATCH 106/388] LSP working for TeX --- backend/src/langs.ts | 2 ++ scripts/docker-install-phase3d.bash | 2 ++ scripts/docker-install-phase4.bash | 3 +++ 3 files changed, 7 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index da59d07..7006be5 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1061,6 +1061,8 @@ END repl: "tex", main: "main.tex", run: "tex main.tex", + lsp: "digestif", + lspLang: "tex", template: `\\message{Hello, world!} `, }, diff --git a/scripts/docker-install-phase3d.bash b/scripts/docker-install-phase3d.bash index 6ff69b4..7766f19 100755 --- a/scripts/docker-install-phase3d.bash +++ b/scripts/docker-install-phase3d.bash @@ -38,6 +38,8 @@ tcl tcsh # TeX +liblua5.3-dev +luarocks texlive-binaries # Unlambda diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 1821e21..5bc51cb 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -67,6 +67,9 @@ rustup component add rls rust-analysis rust-src # Shakespeare pip3 install shakespearelang +# TeX +luarocks install digestif + # TypeScript npm install -g ts-node typescript From 3ff89c5124c80a47ea0e2c0e30093518baf37128 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Thu, 9 Jul 2020 12:53:29 -0600 Subject: [PATCH 107/388] LSP working for Vimscript --- backend/src/langs.ts | 1 + scripts/docker-install-phase4.bash | 3 +++ 2 files changed, 4 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 7006be5..047d438 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1092,6 +1092,7 @@ END repl: "vim", main: "main.vim", run: `vim -c "$(< main.vim)"`, + lsp: "vim-language-server --stdio", template: `:echo "Hello, world!" `, }, diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 5bc51cb..f6dd297 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -73,6 +73,9 @@ luarocks install digestif # TypeScript npm install -g ts-node typescript +# Vim +npm install -g vim-language-server + # Whitespace pip3 install whitespace From 4a11be067927040cec681d43854ab4161dba3d11 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Thu, 9 Jul 2020 13:00:12 -0600 Subject: [PATCH 108/388] Add YAML, TOML, HCL --- backend/src/langs.ts | 30 +++++++++++++++++++++++++++++ scripts/docker-install-phase3d.bash | 3 +++ scripts/docker-install-phase5.bash | 5 +++++ 3 files changed, 38 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 047d438..be61c50 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -471,6 +471,16 @@ main = putStrLn "Hello, world!" `, hacks: ["ghci-config"], }, + hcl: { + aliases: ["tf", "terraform", "hashicorp", "hc"], + name: "HCL", + monacoLang: "plaintext", + main: "main.hcl", + compile: "cat main.hcl | yj -cj > main.json", + run: "cat main.json | jq .", + template: `output = "Hello, world!" +`, + }, ink: { name: "Ink", monacoLang: "plaintext", @@ -1064,6 +1074,16 @@ END lsp: "digestif", lspLang: "tex", template: `\\message{Hello, world!} +`, + }, + toml: { + aliases: ["tom"], + name: "TOML", + monacoLang: "plaintext", + main: "main.toml", + compile: "cat main.toml | yj -tj > main.json", + run: "cat main.json | jq .", + template: `output = "Hello, world!" `, }, typescript: { @@ -1157,6 +1177,16 @@ main: .data message: .string "Hello, world!\\n" +`, + }, + yaml: { + aliases: ["yml"], + name: "YAML", + monacoLang: "yaml", + main: "main.yaml", + compile: "cat main.yaml | yj -yj > main.json", + run: "cat main.json | jq .", + template: `output: "Hello, world!" `, }, zsh: { diff --git a/scripts/docker-install-phase3d.bash b/scripts/docker-install-phase3d.bash index 7766f19..5917be0 100755 --- a/scripts/docker-install-phase3d.bash +++ b/scripts/docker-install-phase3d.bash @@ -57,6 +57,9 @@ python3.7 # x86 clang +# YAML +jq + # Zsh zsh diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index 36c432a..329d5c6 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -65,6 +65,11 @@ gdown "https://drive.google.com/uc?export=download&id=1GPoR_ja4ns16KCamRgwB-JVag gdown "https://drive.google.com/uc?export=download&id=1qSxj8JjAeetAmNjUGayX0RBARgr5R4Ij" /opt/haskell/hoogle.hoo chmod +x /usr/bin/hie +# HCL/TOML/YAML +wget -nv https://github.com/sclevine/yj/releases/download/v4.0.0/yj-linux +chmod +x yj-linux +mv yj-linux /usr/bin/yj + # Ink wget -nv https://github.com/thesephist/ink/releases/download/v0.1.7/ink-linux wget -nv https://github.com/thesephist/ink/releases/download/v0.1.7/std.ink From f2cbd81498a154f9a820e82a5364c7828356cd61 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Thu, 9 Jul 2020 13:30:36 -0600 Subject: [PATCH 109/388] Add Dhall --- backend/src/langs.ts | 9 +++++++++ scripts/docker-install-phase3a.bash | 3 +++ scripts/docker-install-phase5.bash | 7 +++++++ 3 files changed, 19 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index be61c50..a684572 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -312,6 +312,15 @@ void main() { template: `void main() { print('Hello, world!'); } +`, + }, + dhall: { + name: "Dhall", + monacoLang: "plaintext", + main: "main.dhall", + compile: "cat main.dhall | dhall-to-json > main.json", + run: "cat main.json | jq .", + template: `{ output = "Hello, world!" } `, }, elixir: { diff --git a/scripts/docker-install-phase3a.bash b/scripts/docker-install-phase3a.bash index 97044f3..a0575c3 100755 --- a/scripts/docker-install-phase3a.bash +++ b/scripts/docker-install-phase3a.bash @@ -55,6 +55,9 @@ crystal # Dart dart +# Dhall +dhall + " export DEBIAN_FRONTEND=noninteractive diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index 329d5c6..0e7df14 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -31,6 +31,13 @@ wget -nv http://downloads.dlang.org/releases/2.x/2.092.0/dmd_2.092.0-0_amd64.deb dpkg -i dmd_*.deb rm dmd_*.deb +# Dhall +wget -nv https://github.com/dhall-lang/dhall-haskell/releases/download/1.33.1/dhall-json-1.7.0-x86_64-linux.tar.bz2 +mkdir dhall-json +tar -xf dhall-json-*-x86_64-linux.tar.bz2 -C dhall-json +mv dhall-json/bin/dhall-to-json dhall-json/bin/json-to-dhall /usr/bin/ +rm dhall-json dhall-json-*-x86_64-linux.tar.bz2 + # Elixir wget -nv https://github.com/elixir-lsp/elixir-ls/releases/download/v0.5.0/elixir-ls.zip unzip -d /opt/elixir-ls elixir-ls.zip From a7b1ba67f34918feb5e7bdc4a4e1a21240328fff Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 10 Jul 2020 09:57:35 -0600 Subject: [PATCH 110/388] Fix login shell for riju#### users --- system/src/riju-system-privileged.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/riju-system-privileged.c b/system/src/riju-system-privileged.c index 20772d8..312b2fa 100644 --- a/system/src/riju-system-privileged.c +++ b/system/src/riju-system-privileged.c @@ -62,7 +62,7 @@ void useradd(int uid) int status = system(cmdline); if (status) die("groupadd failed"); - if (asprintf(&cmdline, "useradd -M -N -l -r -u %1$d -g %1$d -p '!' riju%1$d", uid) < 0) + if (asprintf(&cmdline, "useradd -M -N -l -r -u %1$d -g %1$d -p '!' -s /usr/bin/bash riju%1$d", uid) < 0) die("asprintf failed"); status = system(cmdline); if (status) From bb14a6c9ab6a9ca60bfadd2acd344db4a5d4417a Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 10 Jul 2020 09:58:16 -0600 Subject: [PATCH 111/388] Add daemon support, sandbox script --- backend/src/api.ts | 16 +++++++++++++++- backend/src/langs.ts | 1 + backend/src/sandbox.ts | 35 +++++++++++++++++++++++++++++++++++ frontend/src/app.ts | 20 +++++++++++++++++++- package.json | 3 ++- 5 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 backend/src/sandbox.ts diff --git a/backend/src/api.ts b/backend/src/api.ts index 922998c..aad5e61 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -7,7 +7,6 @@ import { IPty } from "node-pty"; import * as rpc from "vscode-jsonrpc"; import { v4 as getUUID } from "uuid"; -import { PRIVILEGED } from "./config"; import { LangConfig, langs } from "./langs"; import { borrowUser } from "./users"; import { @@ -27,6 +26,7 @@ export class Session { reader: rpc.StreamMessageReader; writer: rpc.StreamMessageWriter; } | null; + daemon: ChildProcess | null; ws: WebSocket; homedir: string | null; uid: number | null; @@ -41,6 +41,7 @@ export class Session { this.config = langs[lang]; this.term = { pty: null, live: false }; this.lsp = null; + this.daemon = null; this.code = null; this.homedir = null; this.uid = null; @@ -118,6 +119,7 @@ export class Session { } const { name, + daemon, repl, main, suffix, @@ -217,6 +219,18 @@ export class Session { this.send({ event: "terminalOutput", output: data }); } }); + if (daemon && this.daemon === null) { + this.daemon = spawn("bash", ["-c", daemon], { env: getEnv(this.uuid) }); + this.daemon.on("exit", (code) => + this.send({ event: "daemonCrashed", code }) + ); + this.daemon.stdout!.on("data", (data) => + this.send({ event: "daemonLog", output: data.toString("utf8") }) + ); + this.daemon.stderr!.on("data", (data) => + this.send({ event: "daemonLog", output: data.toString("utf8") }) + ); + } if (lsp && this.lsp === null) { if (lspSetup) { await spawnPrivileged( diff --git a/backend/src/langs.ts b/backend/src/langs.ts index a684572..d4f8b2d 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2,6 +2,7 @@ export interface LangConfig { aliases?: string[]; name: string; monacoLang: string; + daemon?: string; repl?: string; main: string; prefix?: string; diff --git a/backend/src/sandbox.ts b/backend/src/sandbox.ts new file mode 100644 index 0000000..f9fd273 --- /dev/null +++ b/backend/src/sandbox.ts @@ -0,0 +1,35 @@ +import { spawn } from "child_process"; +import * as fs from "fs"; + +import { v4 as getUUID } from "uuid"; + +import { langs } from "./langs"; +import { borrowUser } from "./users"; +import { callPrivileged, getEnv, rijuSystemPrivileged } from "./util"; + +function die(msg: any) { + console.error(msg); + process.exit(1); +} + +function log(msg: any) { + console.log(msg); +} + +async function main() { + const uuid = getUUID(); + const { uid, cleanup } = await borrowUser(log); + await callPrivileged(["setup", `${uid}`, uuid], log); + const args = [rijuSystemPrivileged, "spawn", `${uid}`, `${uuid}`, "bash"]; + const proc = spawn(args[0], args.slice(1), { + env: getEnv(uuid), + stdio: "inherit", + }); + await new Promise((resolve, reject) => { + proc.on("error", reject); + proc.on("exit", resolve); + }); + await cleanup(); +} + +main().catch(die); diff --git a/frontend/src/app.ts b/frontend/src/app.ts index 8337c3c..bdbe5a0 100644 --- a/frontend/src/app.ts +++ b/frontend/src/app.ts @@ -142,6 +142,7 @@ async function main() { let clientDisposable: Disposable | null = null; let servicesDisposable: Disposable | null = null; let lspLogBuffer = ""; + let daemonLogBuffer = ""; console.log("Connecting to server..."); socket = new WebSocket( (document.location.protocol === "http:" ? "ws://" : "wss://") + @@ -162,7 +163,8 @@ async function main() { if ( DEBUG && message?.event !== "lspOutput" && - message?.event !== "lspLog" + message?.event !== "lspLog" && + message?.event !== "daemonLog" ) { console.log("RECEIVE:", message); } @@ -244,7 +246,23 @@ async function main() { } } return; + case "daemonLog": + if (typeof message.output !== "string") { + console.error("Unexpected message from server:", message); + return; + } + if (DEBUG) { + daemonLogBuffer += message.output; + while (daemonLogBuffer.includes("\n")) { + const idx = daemonLogBuffer.indexOf("\n"); + const line = daemonLogBuffer.slice(0, idx); + daemonLogBuffer = daemonLogBuffer.slice(idx + 1); + console.log(`DAEMON || ${line}`); + } + } + return; case "lspCrashed": + case "daemonCrashed": return; default: console.error("Unexpected message from server:", message); diff --git a/package.json b/package.json index 02bd9dc..db50a61 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,7 @@ "system-dev": "watchexec --no-vcs-ignore -w system/src -n scripts/compile-system.bash", "build": "run-s backend frontend system", "dev": "run-p backend-dev frontend-dev system-dev server-dev", - "lsp": "node backend/out/lsp-repl.js" + "lsp-repl": "node backend/out/lsp-repl.js", + "sandbox": "node backend/out/sandbox.js" } } From 0b8d5d244d3c126bdb8ed48ec4077e3b152ab219 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 11 Jul 2020 11:00:17 -0600 Subject: [PATCH 112/388] Refactor api.ts, plug resource leaks, fix build --- Dockerfile.dev | 4 +- Dockerfile.prod | 4 +- README.md | 5 +- backend/src/api.ts | 582 ++++++++++++++++------------ backend/src/sandbox.ts | 17 +- backend/src/server.ts | 4 +- backend/src/users.ts | 10 +- backend/src/util.ts | 45 +-- frontend/src/app.ts | 71 ++-- package.json | 2 +- scripts/docker-install-phase5.bash | 11 +- scripts/my_init | 424 ++++++++++++++++++++ scripts/setup.bash | 2 +- system/src/riju-system-privileged.c | 50 ++- tsconfig-webpack.json | 3 +- tsconfig.json | 3 +- yarn.lock | 10 +- 17 files changed, 888 insertions(+), 359 deletions(-) create mode 100755 scripts/my_init diff --git a/Dockerfile.dev b/Dockerfile.dev index 5c7df74..8210b26 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -2,6 +2,8 @@ FROM ubuntu:focal ARG UID +COPY scripts/my_init /usr/bin/my_init + COPY scripts/docker-install-phase0.bash /tmp/ RUN /tmp/docker-install-phase0.bash @@ -44,6 +46,6 @@ RUN chmod go-rwx /home/docker EXPOSE 6119 EXPOSE 6120 -ENTRYPOINT ["/usr/local/bin/pid1.bash"] +ENTRYPOINT ["/usr/bin/my_init", "/usr/local/bin/pid1.bash"] COPY scripts/pid1.bash /usr/local/bin/ CMD ["bash"] diff --git a/Dockerfile.prod b/Dockerfile.prod index 38f0854..83629f0 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -4,6 +4,8 @@ FROM ubuntu:focal # prod, it's not actually read by anything. ARG UID +COPY scripts/my_init /usr/bin/my_init + COPY scripts/docker-install-phase0.bash /tmp/ RUN /tmp/docker-install-phase0.bash @@ -46,7 +48,7 @@ RUN chmod go-rwx /home/docker EXPOSE 6119 EXPOSE 6120 -ENTRYPOINT ["/usr/local/bin/pid1.bash"] +ENTRYPOINT ["/usr/bin/my_init", "/usr/local/bin/pid1.bash"] COPY scripts/pid1.bash /usr/local/bin/ CMD ["yarn", "run", "server"] diff --git a/README.md b/README.md index c290c31..55f2e37 100644 --- a/README.md +++ b/README.md @@ -43,8 +43,9 @@ container first: $ make docker -Note that building the image takes about 30 minutes on high-end -hardware and ethernet, and it requires about 15 GB of disk space. +Note that building the image can take up to 45 minutes even on +high-end hardware and internet, and it requires about 15 GB of disk +space. ## Flag diff --git a/backend/src/api.ts b/backend/src/api.ts index aad5e61..946b838 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -9,288 +9,354 @@ import { v4 as getUUID } from "uuid"; import { LangConfig, langs } from "./langs"; import { borrowUser } from "./users"; -import { - callPrivileged, - getEnv, - rijuSystemPrivileged, - spawnPrivileged, -} from "./util"; +import * as util from "./util"; +import { Context, Options, bash } from "./util"; + +const allSessions: Set = new Set(); export class Session { + ws: WebSocket; uuid: string; - code: string | null; - config: LangConfig; - term: { pty: IPty | null; live: boolean }; + lang: string; + + tearingDown: boolean = false; + + // Initialized by setup() + uidInfo: { + uid: number; + returnUID: () => Promise; + } | null = null; + + // Initialized later or never + term: { pty: IPty; live: boolean } | null = null; lsp: { proc: ChildProcess; reader: rpc.StreamMessageReader; writer: rpc.StreamMessageWriter; - } | null; - daemon: ChildProcess | null; - ws: WebSocket; - homedir: string | null; - uid: number | null; - uidCleanup: (() => Promise) | null; + } | null = null; + daemon: { proc: ChildProcess } | null = null; + + get homedir() { + return `/tmp/riju/${this.uuid}`; + } + + get config() { + return langs[this.lang]; + } + + get uid() { + return this.uidInfo!.uid; + } + + returnUID = async () => { + this.uidInfo && (await this.uidInfo.returnUID()); + }; + + get context() { + return { uid: this.uid, uuid: this.uuid }; + } + + get env() { + return util.getEnv(this.uuid); + } log = (msg: string) => console.log(`[${this.uuid}] ${msg}`); constructor(ws: WebSocket, lang: string) { - this.uuid = getUUID(); - this.log(`Creating session, language ${lang}`); this.ws = ws; - this.config = langs[lang]; - this.term = { pty: null, live: false }; - this.lsp = null; - this.daemon = null; - this.code = null; - this.homedir = null; - this.uid = null; - this.uidCleanup = null; - ws.on("message", this.handleClientMessage); - ws.on("close", () => - this.cleanup().catch((err) => { - this.log(`Error during session cleanup`); - console.log(err); - }) - ); - this.run().catch((err) => { - this.log(`Error while setting up environment for pty`); - console.log(err); - this.send({ event: "terminalClear" }); - this.send({ - event: "terminalOutput", - output: `Riju encountered an unexpected error: ${err} -\rYou may want to save your code and refresh the page. -`, - }); - }); + this.uuid = getUUID(); + this.lang = lang; + this.log(`Creating session, language ${this.lang}`); + this.setup(); } - send = (msg: any) => { + + run = async (args: string[], options?: Options) => { + return await util.run(args, this.log, options); + }; + + privilegedSetup = () => util.privilegedSetup(this.context); + privilegedSpawn = (args: string[]) => + util.privilegedSpawn(this.context, args); + privilegedUseradd = () => util.privilegedUseradd(this.uid); + privilegedTeardown = () => util.privilegedTeardown(this.context); + + setup = async () => { try { + allSessions.add(this); + const { uid, returnUID } = await borrowUser(this.log); + this.uidInfo = { uid, returnUID }; + this.log(`Borrowed uid ${this.uid}`); + await this.run(this.privilegedSetup()); + await this.runCode(); + if (this.config.daemon) { + const daemonArgs = this.privilegedSpawn(bash(this.config.daemon)); + const daemonProc = spawn(daemonArgs[0], daemonArgs.slice(1), { + env: this.env, + }); + this.daemon = { + proc: daemonProc, + }; + for (const stream of [daemonProc.stdout, daemonProc.stderr]) { + stream.on("data", (data) => + this.send({ + event: "serviceLog", + service: "daemon", + output: data.toString("utf8"), + }) + ); + daemonProc.on("exit", (code, signal) => + this.send({ + event: "serviceFailed", + service: "daemon", + error: `Exited with status ${signal || code}`, + }) + ); + daemonProc.on("error", (err) => + this.send({ + event: "serviceFailed", + service: "daemon", + error: `${err}`, + }) + ); + } + } + if (this.config.lsp) { + if (this.config.lspSetup) { + await this.run(this.privilegedSpawn(bash(this.config.lspSetup))); + } + const lspArgs = this.privilegedSpawn(bash(this.config.lsp)); + const lspProc = spawn(lspArgs[0], lspArgs.slice(1), { env: this.env }); + this.lsp = { + proc: lspProc, + reader: new rpc.StreamMessageReader(lspProc.stdout), + writer: new rpc.StreamMessageWriter(lspProc.stdin), + }; + this.lsp.reader.listen((data: any) => { + this.send({ event: "lspOutput", output: data }); + }); + lspProc.stderr.on("data", (data) => + this.send({ + event: "serviceLog", + service: "lsp", + output: data.toString("utf8"), + }) + ); + lspProc.on("exit", (code, signal) => + this.send({ + event: "serviceFailed", + service: "lsp", + error: `Exited with status ${signal || code}`, + }) + ); + lspProc.on("error", (err) => + this.send({ event: "serviceFailed", service: "lsp", error: `${err}` }) + ); + this.send({ event: "lspStarted", root: this.homedir }); + } + this.ws.on("message", this.receive); + this.ws.on("close", async () => { + await this.teardown(); + }); + this.ws.on("error", async (err) => { + this.log(`Websocket error: ${err}`); + await this.teardown(); + }); + } catch (err) { + this.log(`Error while setting up environment`); + console.log(err); + this.sendError(err); + await this.teardown(); + } + }; + + send = async (msg: any) => { + try { + if (this.tearingDown) { + return; + } this.ws.send(JSON.stringify(msg)); } catch (err) { - // + this.log(`Failed to send websocket message: ${err}`); + await this.teardown(); } }; - handleClientMessage = (event: string) => { - let msg: any; - try { - msg = JSON.parse(event); - } catch (err) { - this.log(`Failed to parse client message: ${msg}`); - return; - } - switch (msg?.event) { - case "terminalInput": - if (!this.term) { - this.log(`Got terminal input before pty was started`); - } else if (typeof msg.input !== "string") { - this.log(`Got malformed terminal input message`); - } else { - this.term.pty!.write(msg.input); - } - break; - case "runCode": - if (typeof msg.code !== "string") { - this.log(`Got malformed run message`); - } else { - this.code = msg.code; - this.run(); - } - break; - case "lspInput": - if (!this.lsp) { - this.log(`Got LSP input before language server was started`); - } else { - this.lsp.writer.write(msg.input); - } - break; - default: - this.log(`Got unknown message type: ${msg.event}`); - break; - } - }; - run = async () => { - if (this.uid === null) { - ({ uid: this.uid, cleanup: this.uidCleanup } = await borrowUser( - this.log - )); - this.log(`Borrowed uid ${this.uid}`); - } - const { - name, - daemon, - repl, - main, - suffix, - createEmpty, - compile, - run, - lspSetup, - lsp, - template, - hacks, - } = this.config; - if (this.term.pty) { - this.term.pty.kill(); - this.term.live = false; - } - this.send({ event: "terminalClear" }); - if (this.homedir == null) { - this.homedir = `/tmp/riju/${this.uuid}`; - await callPrivileged(["setup", `${this.uid}`, this.uuid], this.log); - } - let cmdline: string; - if (!run) { - cmdline = `echo 'Support for ${this.config.name} is not yet implemented.'`; - } else if (this.code) { - cmdline = run; - if (compile) { - cmdline = `( ${compile} ) && ( ${run} )`; - } - } else if (repl) { - cmdline = repl; - } else { - cmdline = `echo '${name} has no REPL, press Run to see it in action'`; - } - let code = this.code; - if (this.code === null) { - code = createEmpty ? "" : template; - } - if (code && suffix) { - code += suffix; - } - if (main.includes("/")) { - await spawnPrivileged( - this.uid, - this.uuid, - ["mkdir", "-p", path.dirname(path.resolve(this.homedir, main))], - this.log - ); - } - await spawnPrivileged( - this.uid, - this.uuid, - ["sh", "-c", `cat > ${path.resolve(this.homedir, main)}`], - this.log, - { input: code as string } - ); - if (hacks && hacks.includes("ghci-config") && run) { - if (this.code) { - const contents = ":load Main\nmain\n"; - await spawnPrivileged( - this.uid, - this.uuid, - ["sh", "-c", `cat > ${path.resolve(this.homedir, ".ghci")}`], - this.log, - { input: contents } - ); - } else { - await spawnPrivileged( - this.uid, - this.uuid, - ["rm", "-f", path.resolve(this.homedir, ".ghci")], - this.log - ); - } - } - const args = [ - rijuSystemPrivileged, - "spawn", - `${this.uid}`, - `${this.uuid}`, - "bash", - "-c", - cmdline, - ]; - const env = getEnv(this.uuid); - const term = { - pty: pty.spawn(args[0], args.slice(1), { - name: "xterm-color", - env, - }), - live: true, - }; - this.term = term; - term.pty.on("data", (data) => { - // Capture term in closure so that we don't keep sending output - // from the old pty even after it's been killed (see ghci). - if (term.live) { - this.send({ event: "terminalOutput", output: data }); - } + + sendError = async (err: any) => { + await this.send({ event: "terminalClear" }); + await this.send({ + event: "terminalOutput", + output: `Riju encountered an unexpected error: ${err} +\r +\rYou may want to save your code and refresh the page. +`, }); - if (daemon && this.daemon === null) { - this.daemon = spawn("bash", ["-c", daemon], { env: getEnv(this.uuid) }); - this.daemon.on("exit", (code) => - this.send({ event: "daemonCrashed", code }) - ); - this.daemon.stdout!.on("data", (data) => - this.send({ event: "daemonLog", output: data.toString("utf8") }) - ); - this.daemon.stderr!.on("data", (data) => - this.send({ event: "daemonLog", output: data.toString("utf8") }) - ); - } - if (lsp && this.lsp === null) { - if (lspSetup) { - await spawnPrivileged( - this.uid!, - this.uuid, - ["bash", "-c", lspSetup], - this.log - ); + }; + + logBadMessage = (msg: any) => { + this.log(`Got malformed message from client: ${msg}`); + }; + + receive = async (event: string) => { + try { + if (this.tearingDown) { + return; } - const lspArgs = [ - rijuSystemPrivileged, - "spawn", - `${this.uid}`, - `${this.uuid}`, - "bash", - "-c", - lsp, - ]; - const proc = spawn(lspArgs[0], lspArgs.slice(1), { - env: getEnv(this.uuid), - }); - proc.on("exit", (code) => this.send({ event: "lspCrashed", code })); - proc.stderr.on("data", (data) => - this.send({ event: "lspLog", output: data.toString("utf8") }) - ); - this.lsp = { - proc, - reader: new rpc.StreamMessageReader(proc.stdout), - writer: new rpc.StreamMessageWriter(proc.stdin), - }; - this.lsp.reader.listen((data) => { - this.send({ event: "lspOutput", output: data }); - }); - this.send({ event: "lspStarted", root: `/tmp/riju/${this.uuid}` }); + let msg: any; + try { + msg = JSON.parse(event); + } catch (err) { + this.log(`Failed to parse message from client: ${msg}`); + return; + } + switch (msg && msg.event) { + case "terminalInput": + if (typeof msg.input !== "string") { + this.logBadMessage(msg); + break; + } + if (!this.term) { + this.log("terminalInput ignored because term is null"); + break; + } + this.term!.pty.write(msg.input); + break; + case "runCode": + if (typeof msg.code !== "string") { + this.logBadMessage(msg); + break; + } + await this.runCode(msg.code); + break; + case "lspInput": + if (typeof msg.input !== "object" || !msg) { + this.logBadMessage(msg); + break; + } + if (!this.lsp) { + this.log(`lspInput ignored because lsp is null`); + break; + } + this.lsp.writer.write(msg.input); + break; + default: + this.logBadMessage(msg); + break; + } + } catch (err) { + this.log(`Error while handling message from client`); + console.log(err); + this.sendError(err); } }; - cleanup = async () => { - this.log(`Cleaning up session`); - if (this.term.pty) { - await spawnPrivileged( - this.uid!, - this.uuid, - ["bash", "-c", `kill -9 ${this.term.pty.pid} 2>/dev/null || true`], - this.log + + runCode = async (code?: string) => { + try { + const { + name, + repl, + main, + suffix, + createEmpty, + compile, + run, + template, + hacks, + } = this.config; + if (this.term) { + const pid = this.term.pty.pid; + const args = this.privilegedSpawn( + bash(`kill -SIGTERM ${pid}; sleep 3; kill -SIGKILL ${pid}`) + ); + spawn(args[0], args.slice(1), { env: this.env }); + // Signal to terminalOutput message generator using closure. + this.term.live = false; + this.term = null; + } + this.send({ event: "terminalClear" }); + let cmdline: string; + if (code) { + cmdline = run; + if (compile) { + cmdline = `( ${compile} ) && ( ${run} )`; + } + } else if (repl) { + cmdline = repl; + } else { + cmdline = `echo '${name} has no REPL, press Run to see it in action'`; + } + if (code === undefined) { + code = createEmpty ? "" : template; + } + if (code && suffix) { + code += suffix; + } + if (main.includes("/")) { + await this.run( + this.privilegedSpawn([ + "mkdir", + "-p", + path.dirname(`${this.homedir}/${main}`), + ]) + ); + } + await this.run( + this.privilegedSpawn([ + "sh", + "-c", + `cat > ${path.resolve(this.homedir, main)}`, + ]), + { input: code } ); + if (hacks && hacks.includes("ghci-config") && run) { + if (code) { + await this.run( + this.privilegedSpawn(["sh", "-c", `cat > ${this.homedir}/.ghci`]), + { input: ":load Main\nmain\n" } + ); + } else { + await this.run( + this.privilegedSpawn(["rm", "-f", `${this.homedir}/.ghci`]) + ); + } + } + const termArgs = this.privilegedSpawn(bash(cmdline)); + const term = { + pty: pty.spawn(termArgs[0], termArgs.slice(1), { + name: "xterm-color", + env: this.env, + }), + live: true, + }; + this.term = term; + this.term.pty.on("data", (data) => { + // Capture term in closure so that we don't keep sending output + // from the old pty even after it's been killed (see ghci). + if (term.live) { + this.send({ event: "terminalOutput", output: data }); + } + }); + } catch (err) { + this.log(`Error while running user code`); + console.log(err); + this.sendError(err); } - if (this.lsp !== null) { - await spawnPrivileged( - this.uid!, - this.uuid, - ["bash", "-c", `kill -9 ${this.lsp.proc.pid} 2>/dev/null || true`], - this.log - ); - } - if (this.homedir) { - await callPrivileged(["teardown", this.uuid], this.log); - } - if (this.uidCleanup) { - await this.uidCleanup(); - this.log(`Returned uid ${this.uid}`); + }; + + teardown = async () => { + try { + if (this.tearingDown) { + return; + } + this.log(`Tearing down session`); + this.tearingDown = true; + allSessions.delete(this); + await new Promise((resolve) => setTimeout(resolve, 5000)); + await this.run(this.privilegedTeardown()); + await this.returnUID(); + this.ws.terminate(); + } catch (err) { + this.log(`Error during teardown`); + console.log(err); } }; } diff --git a/backend/src/sandbox.ts b/backend/src/sandbox.ts index f9fd273..f147a80 100644 --- a/backend/src/sandbox.ts +++ b/backend/src/sandbox.ts @@ -5,7 +5,13 @@ import { v4 as getUUID } from "uuid"; import { langs } from "./langs"; import { borrowUser } from "./users"; -import { callPrivileged, getEnv, rijuSystemPrivileged } from "./util"; +import { + getEnv, + privilegedSetup, + privilegedSpawn, + privilegedTeardown, + run, +} from "./util"; function die(msg: any) { console.error(msg); @@ -18,9 +24,9 @@ function log(msg: any) { async function main() { const uuid = getUUID(); - const { uid, cleanup } = await borrowUser(log); - await callPrivileged(["setup", `${uid}`, uuid], log); - const args = [rijuSystemPrivileged, "spawn", `${uid}`, `${uuid}`, "bash"]; + const { uid, returnUID } = await borrowUser(log); + await run(privilegedSetup({ uid, uuid }), log); + const args = privilegedSpawn({ uid, uuid }, ["bash"]); const proc = spawn(args[0], args.slice(1), { env: getEnv(uuid), stdio: "inherit", @@ -29,7 +35,8 @@ async function main() { proc.on("error", reject); proc.on("exit", resolve); }); - await cleanup(); + await run(privilegedTeardown({ uid, uuid }), log); + await returnUID(); } main().catch(die); diff --git a/backend/src/server.ts b/backend/src/server.ts index 9134449..862fd6f 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -100,7 +100,7 @@ if (useTLS) { httpsServer.listen(tlsPort, host, () => console.log(`Listening on https://${host}:${tlsPort}`) ); - http + const server = http .createServer((req, res) => { res.writeHead(301, { Location: "https://" + req.headers["host"] + req.url, @@ -112,7 +112,7 @@ if (useTLS) { ); } else { addWebsocket(app, undefined); - app.listen(port, host, () => + const server = app.listen(port, host, () => console.log(`Listening on http://${host}:${port}`) ); } diff --git a/backend/src/users.ts b/backend/src/users.ts index 89862b5..d41d07d 100644 --- a/backend/src/users.ts +++ b/backend/src/users.ts @@ -7,7 +7,7 @@ import * as _ from "lodash"; import * as parsePasswd from "parse-passwd"; import { PRIVILEGED } from "./config"; -import { callPrivileged } from "./util"; +import { privilegedUseradd, run } from "./util"; // Keep in sync with system/src/riju-system-privileged.c const MIN_UID = 2000; @@ -21,7 +21,7 @@ let lock = new AsyncLock(); async function readExistingUsers(log: (msg: string) => void) { availIds = parsePasswd( - await new Promise((resolve, reject) => + await new Promise((resolve: (result: string) => void, reject) => fs.readFile("/etc/passwd", "utf-8", (err, data) => { if (err) { reject(err); @@ -43,7 +43,7 @@ async function createUser(log: (msg: string) => void): Promise { throw new Error("too many users"); } const uid = nextId!; - await callPrivileged(["useradd", `${uid}`], log); + await run(privilegedUseradd(uid), log); log(`Created new user with ID ${uid}`); nextId! += 1; return uid; @@ -51,7 +51,7 @@ async function createUser(log: (msg: string) => void): Promise { export async function borrowUser(log: (msg: string) => void) { if (!PRIVILEGED) { - return { uid: CUR_UID, cleanup: async () => {} }; + return { uid: CUR_UID, returnUID: async () => {} }; } else { return await lock.acquire("key", async () => { if (availIds === null || nextId === null) { @@ -65,7 +65,7 @@ export async function borrowUser(log: (msg: string) => void) { } return { uid, - cleanup: async () => { + returnUID: async () => { await lock.acquire("key", () => { availIds!.push(uid); }); diff --git a/backend/src/util.ts b/backend/src/util.ts index eebe1d1..59cb89a 100644 --- a/backend/src/util.ts +++ b/backend/src/util.ts @@ -3,11 +3,16 @@ import * as process from "process"; import * as appRoot from "app-root-path"; -interface Options extends SpawnOptions { +export interface Options extends SpawnOptions { input?: string; check?: boolean; } +export interface Context { + uid: number; + uuid: string; +} + export const rijuSystemPrivileged = appRoot.resolve( "system/out/riju-system-privileged" ); @@ -26,7 +31,7 @@ export function getEnv(uuid: string) { }; } -export async function call( +export async function run( args: string[], log: (msg: string) => void, options?: Options @@ -63,26 +68,22 @@ export async function call( }); } -export async function callPrivileged( - args: string[], - log: (msg: string) => void, - options?: Options -) { - await call([rijuSystemPrivileged].concat(args), log, options); +export function privilegedUseradd(uid: number) { + return [rijuSystemPrivileged, "useradd", `${uid}`]; } -export async function spawnPrivileged( - uid: number, - uuid: string, - args: string[], - log: (msg: string) => void, - options?: Options -) { - options = options || {}; - options.env = getEnv(uuid); - await callPrivileged( - ["spawn", `${uid}`, `${uuid}`].concat(args), - log, - options - ); +export function privilegedSetup({ uid, uuid }: Context) { + return [rijuSystemPrivileged, "setup", `${uid}`, uuid]; +} + +export function privilegedSpawn({ uid, uuid }: Context, args: string[]) { + return [rijuSystemPrivileged, "spawn", `${uid}`, uuid].concat(args); +} + +export function privilegedTeardown({ uid, uuid }: Context) { + return [rijuSystemPrivileged, "teardown", `${uid}`, uuid]; +} + +export function bash(cmdline: string) { + return ["bash", "-c", cmdline]; } diff --git a/frontend/src/app.ts b/frontend/src/app.ts index bdbe5a0..0aa0dd8 100644 --- a/frontend/src/app.ts +++ b/frontend/src/app.ts @@ -66,12 +66,12 @@ class RijuMessageReader extends AbstractMessageReader { } catch (err) { return; } - switch (message?.event) { + switch (message && message.event) { case "lspOutput": if (DEBUG) { - console.log("RECEIVE LSP:", message?.output); + console.log("RECEIVE LSP:", message.output); } - this.callback!(message?.output); + this.callback!(message.output); break; } } @@ -135,14 +135,15 @@ async function main() { if (DEBUG) { console.log("SEND", message); } - socket?.send(JSON.stringify(message)); + if (socket) { + socket.send(JSON.stringify(message)); + } } function tryConnect() { let clientDisposable: Disposable | null = null; let servicesDisposable: Disposable | null = null; - let lspLogBuffer = ""; - let daemonLogBuffer = ""; + const serviceLogBuffers: { [index: string]: string } = {}; console.log("Connecting to server..."); socket = new WebSocket( (document.location.protocol === "http:" ? "ws://" : "wss://") + @@ -162,16 +163,17 @@ async function main() { } if ( DEBUG && - message?.event !== "lspOutput" && - message?.event !== "lspLog" && - message?.event !== "daemonLog" + message && + message.event !== "lspOutput" && + message.event !== "lspLog" && + message.event !== "daemonLog" ) { console.log("RECEIVE:", message); } - if (message?.event && message?.event !== "error") { + if (message && message.event && message.event !== "error") { retryDelayMs = initialRetryDelayMs; } - switch (message?.event) { + switch (message && message.event) { case "terminalClear": term.reset(); return; @@ -208,7 +210,11 @@ async function main() { documentSelector: [{ pattern: "**" }], middleware: { workspace: { - configuration: (params, token, configuration) => { + configuration: ( + params: any, + token: any, + configuration: any + ) => { return Array( (configuration(params, token) as {}[]).length ).fill( @@ -220,7 +226,7 @@ async function main() { initializationOptions: config.lspInit || {}, }, connectionProvider: { - get: (errorHandler, closeHandler) => + get: (errorHandler: any, closeHandler: any) => Promise.resolve( createConnection(connection, errorHandler, closeHandler) ), @@ -231,38 +237,27 @@ async function main() { case "lspOutput": // Should be handled by RijuMessageReader return; - case "lspLog": - if (typeof message.output !== "string") { + case "serviceLog": + if ( + typeof message.service !== "string" || + typeof message.output !== "string" + ) { console.error("Unexpected message from server:", message); return; } if (DEBUG) { - lspLogBuffer += message.output; - while (lspLogBuffer.includes("\n")) { - const idx = lspLogBuffer.indexOf("\n"); - const line = lspLogBuffer.slice(0, idx); - lspLogBuffer = lspLogBuffer.slice(idx + 1); - console.log(`LSP || ${line}`); + let buffer = serviceLogBuffers[message.service] || ""; + buffer += message.output; + while (buffer.includes("\n")) { + const idx = buffer.indexOf("\n"); + const line = buffer.slice(0, idx); + buffer = buffer.slice(idx + 1); + console.log(`${message.service.toUpperCase()} || ${line}`); } + serviceLogBuffers[message.service] = buffer; } return; - case "daemonLog": - if (typeof message.output !== "string") { - console.error("Unexpected message from server:", message); - return; - } - if (DEBUG) { - daemonLogBuffer += message.output; - while (daemonLogBuffer.includes("\n")) { - const idx = daemonLogBuffer.indexOf("\n"); - const line = daemonLogBuffer.slice(0, idx); - daemonLogBuffer = daemonLogBuffer.slice(idx + 1); - console.log(`DAEMON || ${line}`); - } - } - return; - case "lspCrashed": - case "daemonCrashed": + case "serviceCrashed": return; default: console.error("Unexpected message from server:", message); diff --git a/package.json b/package.json index db50a61..c75e371 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "@types/express-ws": "^3.0.0", "@types/lodash": "^4.14.155", "@types/mkdirp": "^1.0.1", + "@types/node-cleanup": "^2.1.1", "@types/parse-passwd": "^1.0.0", "@types/rimraf": "^3.0.0", "@types/shell-quote": "^1.7.0", @@ -30,7 +31,6 @@ "monaco-editor": "^0.20.0", "monaco-editor-webpack-plugin": "^1.9.0", "monaco-languageclient": "^0.13.0", - "node-cleanup": "^2.1.2", "node-pty": "^0.9.0", "npm-run-all": "^4.1.5", "parse-passwd": "^1.0.0", diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index 0e7df14..16c1bf5 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -36,7 +36,7 @@ wget -nv https://github.com/dhall-lang/dhall-haskell/releases/download/1.33.1/dh mkdir dhall-json tar -xf dhall-json-*-x86_64-linux.tar.bz2 -C dhall-json mv dhall-json/bin/dhall-to-json dhall-json/bin/json-to-dhall /usr/bin/ -rm dhall-json dhall-json-*-x86_64-linux.tar.bz2 +rm -rf dhall-json dhall-json-*-x86_64-linux.tar.bz2 # Elixir wget -nv https://github.com/elixir-lsp/elixir-ls/releases/download/v0.5.0/elixir-ls.zip @@ -57,12 +57,13 @@ mv rebar3 /usr/bin/rebar3 # Go export GO111MODULE=on -export GOPATH=/tmp/go -mv /tmp/go/bin/gopls /usr/bin/gopls -rm -rf /tmp/go +export GOPATH="$PWD/go" +go get golang.org/x/tools/gopls@latest +mv go/bin/gopls /usr/bin/gopls +rm -rf go # Haskell -wget https://get.haskellstack.org/stable/linux-x86_64-static.tar.gz +wget -nv https://get.haskellstack.org/stable/linux-x86_64-static.tar.gz tar -xf linux-x86_64-static.tar.gz mv stack-*-linux-x86_64-static/stack /usr/bin/stack rm -rf stack-*-linux-x86_64-static linux-x86_64-static.tar.gz diff --git a/scripts/my_init b/scripts/my_init new file mode 100755 index 0000000..9177e6d --- /dev/null +++ b/scripts/my_init @@ -0,0 +1,424 @@ +#!/usr/bin/python3 -u +# -*- coding: utf-8 -*- +# +# From https://github.com/phusion/baseimage-docker/blob/5078b027ba58cce8887acb5c1add0bb8d56f5d38/image/bin/my_init +# Copyright 2013-2015 Phusion Holding B.V. under MIT License +# See https://github.com/phusion/baseimage-docker/blob/5078b027ba58cce8887acb5c1add0bb8d56f5d38/LICENSE.txt + +import argparse +import errno +import json +import os +import os.path +import re +import signal +import stat +import sys +import time + +ENV_INIT_DIRECTORY = os.environ.get('ENV_INIT_DIRECTORY', '/etc/my_init.d') + +KILL_PROCESS_TIMEOUT = int(os.environ.get('KILL_PROCESS_TIMEOUT', 30)) +KILL_ALL_PROCESSES_TIMEOUT = int(os.environ.get('KILL_ALL_PROCESSES_TIMEOUT', 30)) + +LOG_LEVEL_ERROR = 1 +LOG_LEVEL_WARN = 1 +LOG_LEVEL_INFO = 2 +LOG_LEVEL_DEBUG = 3 + +SHENV_NAME_WHITELIST_REGEX = re.compile('\W') + +log_level = None + +terminated_child_processes = {} + +_find_unsafe = re.compile(r'[^\w@%+=:,./-]').search + + +class AlarmException(Exception): + pass + + +def error(message): + if log_level >= LOG_LEVEL_ERROR: + sys.stderr.write("*** %s\n" % message) + + +def warn(message): + if log_level >= LOG_LEVEL_WARN: + sys.stderr.write("*** %s\n" % message) + + +def info(message): + if log_level >= LOG_LEVEL_INFO: + sys.stderr.write("*** %s\n" % message) + + +def debug(message): + if log_level >= LOG_LEVEL_DEBUG: + sys.stderr.write("*** %s\n" % message) + + +def ignore_signals_and_raise_keyboard_interrupt(signame): + signal.signal(signal.SIGTERM, signal.SIG_IGN) + signal.signal(signal.SIGINT, signal.SIG_IGN) + raise KeyboardInterrupt(signame) + + +def raise_alarm_exception(): + raise AlarmException('Alarm') + + +def listdir(path): + try: + result = os.stat(path) + except OSError: + return [] + if stat.S_ISDIR(result.st_mode): + return sorted(os.listdir(path)) + else: + return [] + + +def is_exe(path): + try: + return os.path.isfile(path) and os.access(path, os.X_OK) + except OSError: + return False + + +def import_envvars(clear_existing_environment=True, override_existing_environment=True): + if not os.path.exists("/etc/container_environment"): + return + new_env = {} + for envfile in listdir("/etc/container_environment"): + name = os.path.basename(envfile) + with open("/etc/container_environment/" + envfile, "r") as f: + # Text files often end with a trailing newline, which we + # don't want to include in the env variable value. See + # https://github.com/phusion/baseimage-docker/pull/49 + value = re.sub('\n\Z', '', f.read()) + new_env[name] = value + if clear_existing_environment: + os.environ.clear() + for name, value in new_env.items(): + if override_existing_environment or name not in os.environ: + os.environ[name] = value + + +def export_envvars(to_dir=True): + if not os.path.exists("/etc/container_environment"): + return + shell_dump = "" + for name, value in os.environ.items(): + if name in ['HOME', 'USER', 'GROUP', 'UID', 'GID', 'SHELL']: + continue + if to_dir: + with open("/etc/container_environment/" + name, "w") as f: + f.write(value) + shell_dump += "export " + sanitize_shenvname(name) + "=" + shquote(value) + "\n" + with open("/etc/container_environment.sh", "w") as f: + f.write(shell_dump) + with open("/etc/container_environment.json", "w") as f: + f.write(json.dumps(dict(os.environ))) + + +def shquote(s): + """Return a shell-escaped version of the string *s*.""" + if not s: + return "''" + if _find_unsafe(s) is None: + return s + + # use single quotes, and put single quotes into double quotes + # the string $'b is then quoted as '$'"'"'b' + return "'" + s.replace("'", "'\"'\"'") + "'" + + +def sanitize_shenvname(s): + """Return string with [0-9a-zA-Z_] characters""" + return re.sub(SHENV_NAME_WHITELIST_REGEX, "_", s) + + +# Waits for the child process with the given PID, while at the same time +# reaping any other child processes that have exited (e.g. adopted child +# processes that have terminated). + +def waitpid_reap_other_children(pid): + global terminated_child_processes + + status = terminated_child_processes.get(pid) + if status: + # A previous call to waitpid_reap_other_children(), + # with an argument not equal to the current argument, + # already waited for this process. Return the status + # that was obtained back then. + del terminated_child_processes[pid] + return status + + done = False + status = None + while not done: + try: + # https://github.com/phusion/baseimage-docker/issues/151#issuecomment-92660569 + this_pid, status = os.waitpid(pid, os.WNOHANG) + if this_pid == 0: + this_pid, status = os.waitpid(-1, 0) + if this_pid == pid: + done = True + else: + # Save status for later. + terminated_child_processes[this_pid] = status + except OSError as e: + if e.errno == errno.ECHILD or e.errno == errno.ESRCH: + return None + else: + raise + return status + + +def stop_child_process(name, pid, signo=signal.SIGTERM, time_limit=KILL_PROCESS_TIMEOUT): + info("Shutting down %s (PID %d)..." % (name, pid)) + try: + os.kill(pid, signo) + except OSError: + pass + signal.alarm(time_limit) + try: + try: + waitpid_reap_other_children(pid) + except OSError: + pass + except AlarmException: + warn("%s (PID %d) did not shut down in time. Forcing it to exit." % (name, pid)) + try: + os.kill(pid, signal.SIGKILL) + except OSError: + pass + try: + waitpid_reap_other_children(pid) + except OSError: + pass + finally: + signal.alarm(0) + + +def run_command_killable(*argv): + filename = argv[0] + status = None + pid = os.spawnvp(os.P_NOWAIT, filename, argv) + try: + status = waitpid_reap_other_children(pid) + except BaseException: + warn("An error occurred. Aborting.") + stop_child_process(filename, pid) + raise + if status != 0: + if status is None: + error("%s exited with unknown status\n" % filename) + else: + error("%s failed with status %d\n" % (filename, os.WEXITSTATUS(status))) + sys.exit(1) + + +def run_command_killable_and_import_envvars(*argv): + run_command_killable(*argv) + import_envvars() + export_envvars(False) + + +def kill_all_processes(time_limit): + info("Killing all processes...") + try: + os.kill(-1, signal.SIGTERM) + except OSError: + pass + signal.alarm(time_limit) + try: + # Wait until no more child processes exist. + done = False + while not done: + try: + os.waitpid(-1, 0) + except OSError as e: + if e.errno == errno.ECHILD: + done = True + else: + raise + except AlarmException: + warn("Not all processes have exited in time. Forcing them to exit.") + try: + os.kill(-1, signal.SIGKILL) + except OSError: + pass + finally: + signal.alarm(0) + + +def run_startup_files(): + # Run ENV_INIT_DIRECTORY/* + for name in listdir(ENV_INIT_DIRECTORY): + filename = os.path.join(ENV_INIT_DIRECTORY, name) + if is_exe(filename): + info("Running %s..." % filename) + run_command_killable_and_import_envvars(filename) + + # Run /etc/rc.local. + if is_exe("/etc/rc.local"): + info("Running /etc/rc.local...") + run_command_killable_and_import_envvars("/etc/rc.local") + + +def run_pre_shutdown_scripts(): + debug("Running pre-shutdown scripts...") + + # Run /etc/my_init.pre_shutdown.d/* + for name in listdir("/etc/my_init.pre_shutdown.d"): + filename = "/etc/my_init.pre_shutdown.d/" + name + if is_exe(filename): + info("Running %s..." % filename) + run_command_killable(filename) + + +def run_post_shutdown_scripts(): + debug("Running post-shutdown scripts...") + + # Run /etc/my_init.post_shutdown.d/* + for name in listdir("/etc/my_init.post_shutdown.d"): + filename = "/etc/my_init.post_shutdown.d/" + name + if is_exe(filename): + info("Running %s..." % filename) + run_command_killable(filename) + + +def start_runit(): + info("Booting runit daemon...") + pid = os.spawnl(os.P_NOWAIT, "/usr/bin/runsvdir", "/usr/bin/runsvdir", + "-P", "/etc/service") + info("Runit started as PID %d" % pid) + return pid + + +def wait_for_runit_or_interrupt(pid): + status = waitpid_reap_other_children(pid) + return (True, status) + + +def shutdown_runit_services(quiet=False): + if not quiet: + debug("Begin shutting down runit services...") + os.system("/usr/bin/sv -w %d force-stop /etc/service/* > /dev/null" % KILL_PROCESS_TIMEOUT) + + +def wait_for_runit_services(): + debug("Waiting for runit services to exit...") + done = False + while not done: + done = os.system("/usr/bin/sv status /etc/service/* | grep -q '^run:'") != 0 + if not done: + time.sleep(0.1) + # According to https://github.com/phusion/baseimage-docker/issues/315 + # there is a bug or race condition in Runit, causing it + # not to shutdown services that are already being started. + # So during shutdown we repeatedly instruct Runit to shutdown + # services. + shutdown_runit_services(True) + + +def install_insecure_key(): + info("Installing insecure SSH key for user root") + run_command_killable("/usr/sbin/enable_insecure_key") + + +def main(args): + import_envvars(False, False) + export_envvars() + + if args.enable_insecure_key: + install_insecure_key() + + if not args.skip_startup_files: + run_startup_files() + + runit_exited = False + exit_code = None + + if not args.skip_runit: + runit_pid = start_runit() + try: + exit_status = None + if len(args.main_command) == 0: + runit_exited, exit_code = wait_for_runit_or_interrupt(runit_pid) + if runit_exited: + if exit_code is None: + info("Runit exited with unknown status") + exit_status = 1 + else: + exit_status = os.WEXITSTATUS(exit_code) + info("Runit exited with status %d" % exit_status) + else: + info("Running %s..." % " ".join(args.main_command)) + pid = os.spawnvp(os.P_NOWAIT, args.main_command[0], args.main_command) + try: + exit_code = waitpid_reap_other_children(pid) + if exit_code is None: + info("%s exited with unknown status." % args.main_command[0]) + exit_status = 1 + else: + exit_status = os.WEXITSTATUS(exit_code) + info("%s exited with status %d." % (args.main_command[0], exit_status)) + except KeyboardInterrupt: + stop_child_process(args.main_command[0], pid) + raise + except BaseException: + warn("An error occurred. Aborting.") + stop_child_process(args.main_command[0], pid) + raise + sys.exit(exit_status) + finally: + if not args.skip_runit: + run_pre_shutdown_scripts() + shutdown_runit_services() + if not runit_exited: + stop_child_process("runit daemon", runit_pid) + wait_for_runit_services() + run_post_shutdown_scripts() + +# Parse options. +parser = argparse.ArgumentParser(description='Initialize the system.') +parser.add_argument('main_command', metavar='MAIN_COMMAND', type=str, nargs='*', + help='The main command to run. (default: runit)') +parser.add_argument('--enable-insecure-key', dest='enable_insecure_key', + action='store_const', const=True, default=False, + help='Install the insecure SSH key') +parser.add_argument('--skip-startup-files', dest='skip_startup_files', + action='store_const', const=True, default=False, + help='Skip running /etc/my_init.d/* and /etc/rc.local') +parser.add_argument('--skip-runit', dest='skip_runit', + action='store_const', const=True, default=False, + help='Do not run runit services') +parser.add_argument('--no-kill-all-on-exit', dest='kill_all_on_exit', + action='store_const', const=False, default=True, + help='Don\'t kill all processes on the system upon exiting') +parser.add_argument('--quiet', dest='log_level', + action='store_const', const=LOG_LEVEL_WARN, default=LOG_LEVEL_INFO, + help='Only print warnings and errors') +args = parser.parse_args() +log_level = args.log_level + +if args.skip_runit and len(args.main_command) == 0: + error("When --skip-runit is given, you must also pass a main command.") + sys.exit(1) + +# Run main function. +signal.signal(signal.SIGTERM, lambda signum, frame: ignore_signals_and_raise_keyboard_interrupt('SIGTERM')) +signal.signal(signal.SIGINT, lambda signum, frame: ignore_signals_and_raise_keyboard_interrupt('SIGINT')) +signal.signal(signal.SIGALRM, lambda signum, frame: raise_alarm_exception()) +try: + main(args) +except KeyboardInterrupt: + warn("Init system aborted.") + exit(2) +finally: + if args.kill_all_on_exit: + kill_all_processes(KILL_ALL_PROCESSES_TIMEOUT) diff --git a/scripts/setup.bash b/scripts/setup.bash index e9a597e..af87aaa 100755 --- a/scripts/setup.bash +++ b/scripts/setup.bash @@ -5,6 +5,6 @@ set -o pipefail mkdir -p /tmp/riju if [[ -x system/out/riju-system-privileged ]]; then - system/out/riju-system-privileged teardown "*" || true + system/out/riju-system-privileged teardown "*" "*" || true fi chmod a=x,u=rwx /tmp/riju diff --git a/system/src/riju-system-privileged.c b/system/src/riju-system-privileged.c index 312b2fa..e9a774a 100644 --- a/system/src/riju-system-privileged.c +++ b/system/src/riju-system-privileged.c @@ -14,7 +14,7 @@ const int MAX_UID = 65000; int privileged; -void die(char *msg) +void __attribute__ ((noreturn)) die(char *msg) { fprintf(stderr, "%s\n", msg); exit(1); @@ -24,8 +24,8 @@ void die_with_usage() { die("usage:\n" " riju-system-privileged useradd UID\n" - " riju-system-privileged spawn UID CMDLINE...\n" " riju-system-privileged setup UID UUID\n" + " riju-system-privileged spawn UID UUID CMDLINE...\n" " riju-system-privileged teardown UUID"); } @@ -60,12 +60,12 @@ void useradd(int uid) if (asprintf(&cmdline, "groupadd -g %1$d riju%1$d", uid) < 0) die("asprintf failed"); int status = system(cmdline); - if (status) + if (status != 0) die("groupadd failed"); if (asprintf(&cmdline, "useradd -M -N -l -r -u %1$d -g %1$d -p '!' -s /usr/bin/bash riju%1$d", uid) < 0) die("asprintf failed"); status = system(cmdline); - if (status) + if (status != 0) die("useradd failed"); } @@ -97,17 +97,44 @@ void setup(int uid, char *uuid) : "install -d -m 700 /tmp/riju/%2$s", uid, uuid) < 0) die("asprintf failed"); int status = system(cmdline); - if (status) + if (status != 0) die("install failed"); } -void teardown(char *uuid) +void teardown(int uid, char *uuid) { char *cmdline; + int status; + char *users; + if (uid >= MIN_UID && uid < MAX_UID) { + if (asprintf(&users, "%d", uid) < 0) + die("asprintf failed"); + } else { + cmdline = "getent passwd | grep -Eo '^riju[0-9]{4}' | paste -s -d, - | tr -d '\n'"; + FILE *fp = popen(cmdline, "r"); + if (fp == NULL) + die("popen failed"); + static char buf[(MAX_UID - MIN_UID) * 9]; + if (fgets(buf, sizeof(buf), fp) == NULL) { + if (feof(fp)) + users = NULL; + else { + die("fgets failed"); + } + } else + users = buf; + } + if (users != NULL) { + if (asprintf(&cmdline, "pkill -SIGKILL --uid %s", users) < 0) + die("asprintf failed"); + status = system(cmdline); + if (status != 0 && status != 256) + die("pkill failed"); + } if (asprintf(&cmdline, "rm -rf /tmp/riju/%s", uuid) < 0) die("asprintf failed"); - int status = system(cmdline); - if (status) + status = system(cmdline); + if (status != 0) die("rm failed"); } @@ -140,10 +167,11 @@ int main(int argc, char **argv) return 0; } if (!strcmp(argv[1], "teardown")) { - if (argc != 3) + if (argc != 4) die_with_usage(); - char *uuid = strcmp(argv[2], "*") ? parseUUID(argv[2]) : "*"; - teardown(uuid); + int uid = strcmp(argv[2], "*") ? parseUID(argv[2]) : -1; + char *uuid = strcmp(argv[3], "*") ? parseUUID(argv[3]) : "*"; + teardown(uid, uuid); return 0; } die_with_usage(); diff --git a/tsconfig-webpack.json b/tsconfig-webpack.json index 358bebf..e27d0d9 100644 --- a/tsconfig-webpack.json +++ b/tsconfig-webpack.json @@ -1,7 +1,8 @@ { "compilerOptions": { "outDir": "./frontend/out", - "rootDir": "./frontend/src" + "rootDir": "./frontend/src", + "target": "ES3" }, "extends": "./tsconfig.json", "include": ["frontend/src"] diff --git a/tsconfig.json b/tsconfig.json index 9e16e58..c964b6b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,8 @@ "resolveJsonModule": true, "rootDir": "./backend/src", "sourceMap": true, - "strict": true + "strict": true, + "target": "ES5" }, "include": ["backend/src"] } diff --git a/yarn.lock b/yarn.lock index 387f7bf..de64bc2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -882,6 +882,11 @@ dependencies: "@types/node" "*" +"@types/node-cleanup@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@types/node-cleanup/-/node-cleanup-2.1.1.tgz#c8f78a648897d2a40ed10632268ce15d343cc191" + integrity sha512-Q1s5Sszz6YfhaGr1pbaZihr9IYaiQT0aOK/3c2qb9lOUbEBhcAb9ZEU7RBTtopnHSIJF80adLRcOGTay2W5QVQ== + "@types/node@*": version "14.0.11" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.11.tgz#61d4886e2424da73b7b25547f59fdcb534c165a3" @@ -3450,11 +3455,6 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== -node-cleanup@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/node-cleanup/-/node-cleanup-2.1.2.tgz#7ac19abd297e09a7f72a71545d951b517e4dde2c" - integrity sha1-esGavSl+Caf3KnFUXZUbUX5N3iw= - node-libs-browser@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" From 0f63d82389e737377186471a6ea2b21545cac054 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 11 Jul 2020 11:31:42 -0600 Subject: [PATCH 113/388] Misc cleanup --- scripts/docker-install-phase4.bash | 1 + scripts/docker-install-phase5.bash | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index f6dd297..5103fec 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -82,6 +82,7 @@ pip3 install whitespace # Wolfram Language python3.7 -m pip install mathics +rm -rf /root/.cache /root/.config /root/.cpan /root/.cpanm /root/.gem /root/.npm /root/.npmrc rm -f /tmp/core-js-banners rm "$0" diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index 16c1bf5..f437f93 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -19,7 +19,7 @@ wget -nv https://dl.bintray.com/reznikmm/ada-language-server/linux-latest.tar.gz tar -xf linux-latest.tar.gz mv linux/ada_language_server /usr/bin/ada_language_server mv linux/*.so* /usr/lib/x86_64-linux-gnu/ -rm linux-latest.tar.gz +rm -rf linux linux-latest.tar.gz # Clojure wget -nv https://github.com/snoe/clojure-lsp/releases/download/release-20200629T153107/clojure-lsp @@ -108,6 +108,7 @@ rm powershell-*.tar.gz wget -nv https://github.com/PowerShell/PowerShellEditorServices/releases/download/v2.2.0/PowerShellEditorServices.zip unzip PowerShellEditorServices.zip mv PowerShellEditorServices /opt/powershell-editor-services +rm PowerShellEditorServices.zip # Python xml="$(curl -sSL "https://pvsc.blob.core.windows.net/python-language-server-stable?restype=container&comp=list&prefix=Python-Language-Server-linux-x64")" From 7aadfaa421d616b529dc92fe11ad60918e5834bf Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 11 Jul 2020 11:31:49 -0600 Subject: [PATCH 114/388] New language: Factor --- backend/src/langs.ts | 13 +++++++++++++ scripts/docker-install-phase5.bash | 7 +++++++ 2 files changed, 20 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index d4f8b2d..ab421ea 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -384,6 +384,19 @@ output = "Hello, world!" main() -> io:fwrite("Hello, world!\\n"). +`, + }, + factor: { + aliases: ["fact"], + name: "Factor", + monacoLang: "plaintext", + repl: "factor-lang", + main: ".factor-rc", + createEmpty: true, + run: "factor-lang", + template: `USE: io + +"Hello, world!" print `, }, fish: { diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index f437f93..856cdf1 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -55,6 +55,13 @@ wget -nv https://s3.amazonaws.com/rebar3/rebar3 chmod +x rebar3 mv rebar3 /usr/bin/rebar3 +# Factor +wget -nv https://downloads.factorcode.org/releases/0.98/factor-linux-x86-64-0.98.tar.gz +tar -xf factor-linux-x86-64-*.tar.gz +mv -T factor /opt/factor +ln -s /opt/factor/factor /usr/bin/factor-lang +rm factor-linux-x86-64-*.tar.gz + # Go export GO111MODULE=on export GOPATH="$PWD/go" From 5d85e2036d7796fd83a1beee999123076f134c12 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 11 Jul 2020 11:39:52 -0600 Subject: [PATCH 115/388] New language: LLVM --- backend/src/langs.ts | 30 ++++++++++++++++++++++++++++- scripts/docker-install-phase3b.bash | 3 +++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index ab421ea..678741a 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -147,7 +147,7 @@ implement main0 () = () `, }, c: { - aliases: ["gcc", "llvm", "clang", "h", "cc", "c99", "c11", "c18"], + aliases: ["gcc", "clang", "h", "cc", "c99", "c11", "c18"], name: "C", monacoLang: "c", main: "main.c", @@ -601,6 +601,34 @@ PLEASE GIVE UP createEmpty: true, run: `SHELL=/usr/bin/ksh HOME="$PWD" ksh`, template: `echo "Hello, world!" +`, + }, + llvm: { + name: "LLVM", + monacoLang: "shell", + main: "main.ll", + compile: "clang -Wno-override-module main.ll -o main", + run: "./main", + template: `; Copied directly from the documentation +; Declare the string constant as a global constant. +@.str = private unnamed_addr constant [13 x i8] c"hello world\\0A\\00" + +; External declaration of the puts function +declare i32 @puts(i8* nocapture) nounwind + +; Definition of main function +define i32 @main() { ; i32()* + ; Convert [13 x i8]* to i8 *... + %cast210 = getelementptr [13 x i8],[13 x i8]* @.str, i64 0, i64 0 + + ; Call puts function to write out the string to stdout. + call i32 @puts(i8* %cast210) + ret i32 0 +} + +; Named metadata +!0 = !{i32 42, null, !"string"} +!foo = !{!0} `, }, lolcode: { diff --git a/scripts/docker-install-phase3b.bash b/scripts/docker-install-phase3b.bash index 0a6e4fa..b0cd0df 100755 --- a/scripts/docker-install-phase3b.bash +++ b/scripts/docker-install-phase3b.bash @@ -53,6 +53,9 @@ julia # Ksh ksh +# LLVM +llvm + # LOLCODE cmake From a66ed3ce21396b6214a0b7be77a971b05fa02f98 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 11 Jul 2020 11:44:17 -0600 Subject: [PATCH 116/388] New language: OCaml --- backend/src/langs.ts | 9 +++++++++ scripts/docker-install-phase3c.bash | 3 +++ 2 files changed, 12 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 678741a..9d72571 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -736,6 +736,15 @@ int main() { [pool drain]; return 0; } +`, + }, + ocaml: { + name: "OCaml", + monacoLang: "plaintext", + main: "main.ml", + repl: "ocaml", + run: "ocaml -init main.ml", + template: `print_string "Hello, world!\\n";; `, }, octave: { diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index e68abee..b91737b 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -24,6 +24,9 @@ yarn gcc gnustep-devel +# Ocaml +ocaml + # Octave octave From 8ef7581a9f446a3f66b1564a8e3ae668aa090f6e Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 11 Jul 2020 11:53:45 -0600 Subject: [PATCH 117/388] New language: Pug --- backend/src/langs.ts | 11 +++++++++++ scripts/docker-install-phase4.bash | 3 +++ 2 files changed, 14 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 9d72571..b912191 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -814,6 +814,17 @@ echo "Hello, world!\\n"; main :- write("Hello, world!"), nl. +`, + }, + pug: { + name: "Pug", + monacoLang: "pug", + main: "main.pug", + compile: "pug main.pug", + run: "prettier --no-config main.html", + template: `html + body + p Hello, world! `, }, python: { diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 5103fec..15f78bc 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -55,6 +55,9 @@ cpanm -n Devel::REPL # PHP npm install -g intelephense +# Pug +npm install -g prettier pug-cli + # ReasonML npm install -g bs-platform From 55311d852432348eb8defcf6e89e857d51ec0269 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 11 Jul 2020 12:07:40 -0600 Subject: [PATCH 118/388] New language: Markdown --- backend/src/langs.ts | 20 ++++++++++++++++++++ scripts/docker-install-phase3c.bash | 4 ++++ 2 files changed, 24 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index b912191..c527f3d 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -661,6 +661,26 @@ KTHXBYE template: " (=<`#9]~6ZY32Vx/4Rs+0No-&Jk)\"Fh}|Bcy?`=*z]Kw%oG4UUS0/@-ejc(:'8dc\n", }, + markdown: { + aliases: [ + "mdown", + "mkdn", + "md", + "mkd", + "mdwn", + "mdtxt", + "mdtext", + "text", + "rmd", + ], + name: "Markdown", + monacoLang: "markdown", + main: "main.md", + compile: "pandoc main.md -o main.html", + run: "prettier --no-config main.html", + template: `Hello, world! +`, + }, mips: { aliases: ["mips64"], name: "MIPS", diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index b91737b..9895b21 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -6,6 +6,10 @@ set -x packages=" +# Markdown +pandoc +prettier + # MIPS gcc-mips64-linux-gnuabi64 qemu-user-static From 5326223cf8a5ece45a4d05bd1f91aaf0dd63bd80 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 11 Jul 2020 12:07:45 -0600 Subject: [PATCH 119/388] New language: AsciiDoc --- backend/src/langs.ts | 10 ++++++++++ scripts/docker-install-phase3a.bash | 3 +++ 2 files changed, 13 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index c527f3d..c838715 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -66,6 +66,16 @@ main: .data message: .string "Hello, world!\\n" +`, + }, + asciidoc: { + aliases: ["adoc", "asc"], + monacoLang: "plaintext", + name: "AsciiDoc", + main: "main.adoc", + compile: "asciidoc -s main.adoc", + run: "prettier --no-config main.html", + template: `Hello, world! `, }, ats: { diff --git a/scripts/docker-install-phase3a.bash b/scripts/docker-install-phase3a.bash index a0575c3..c64d750 100755 --- a/scripts/docker-install-phase3a.bash +++ b/scripts/docker-install-phase3a.bash @@ -16,6 +16,9 @@ algol68g gcc-arm-linux-gnueabihf qemu-user-static +# AsciiDoc +asciidoc + # ATS ats2-lang From 2efd97adb654d79d1f6ccfb4e4eb7cdf947ab29f Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 11 Jul 2020 12:12:44 -0600 Subject: [PATCH 120/388] New language: Textile --- backend/src/langs.ts | 9 +++++++++ scripts/docker-install-phase3d.bash | 3 +++ 2 files changed, 12 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index c838715..a030f4c 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1175,6 +1175,15 @@ END lsp: "digestif", lspLang: "tex", template: `\\message{Hello, world!} +`, + }, + textile: { + name: "Textile", + monacoLang: "plaintext", + main: "main.textile", + compile: "pandoc main.textile -o main.html", + run: "prettier --no-config main.html", + template: `Hello, world! `, }, toml: { diff --git a/scripts/docker-install-phase3d.bash b/scripts/docker-install-phase3d.bash index 5917be0..fe75baf 100755 --- a/scripts/docker-install-phase3d.bash +++ b/scripts/docker-install-phase3d.bash @@ -42,6 +42,9 @@ liblua5.3-dev luarocks texlive-binaries +# Textile +pandoc + # Unlambda unlambda From ef7291da04675523a4a0a6c07c0c76491c4728ca Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 11 Jul 2020 12:12:48 -0600 Subject: [PATCH 121/388] New language: reStructuredText --- backend/src/langs.ts | 10 ++++++++++ scripts/docker-install-phase3c.bash | 3 +++ 2 files changed, 13 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index a030f4c..3b96675 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -904,6 +904,16 @@ main :- compile: "bsc main.re > main.js", run: "NODE_PATH=/usr/lib/node_modules node main.js", template: `print_string("Hello, world!\\n") +`, + }, + restructuredtext: { + aliases: ["rst"], + name: "reStructuredText", + monacoLang: "restructuredtext", + main: "main.rst", + compile: "pandoc main.rst -o main.html", + run: "prettier --no-config main.html", + template: `Hello, world! `, }, riscv: { diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index 9895b21..4cd5446 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -58,6 +58,9 @@ r-base # Racket racket +# reStructuredText +pandoc + # RISC-V gcc-riscv64-linux-gnu qemu-user-static From ffab644ea7ca7f21532f39c67d93def56ca04215 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 11 Jul 2020 12:14:51 -0600 Subject: [PATCH 122/388] New language: Org --- backend/src/langs.ts | 10 ++++++++++ scripts/docker-install-phase3c.bash | 3 +++ 2 files changed, 13 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 3b96675..105f355 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -785,6 +785,16 @@ int main() { main: "main.m", run: "octave --persist main.m", template: `disp("Hello, world!") +`, + }, + org: { + aliases: ["orgmode"], + name: "Org", + monacoLang: "plaintext", + main: "main.org", + compile: "pandoc main.org -o main.html", + run: "prettier --no-config main.html", + template: `Hello, world! `, }, pascal: { diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index 4cd5446..82bdcc5 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -34,6 +34,9 @@ ocaml # Octave octave +# Org +pandoc + # Pascal fpc From 83697c7de05fe9a2a57f1adade06721682f19528 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 11 Jul 2020 12:39:34 -0600 Subject: [PATCH 123/388] New language: roff --- backend/src/langs.ts | 26 ++++++++++++++++++++++++++ scripts/docker-install-phase3c.bash | 3 +++ 2 files changed, 29 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 105f355..0ce8574 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -947,6 +947,32 @@ main: .data message: .string "Hello, world!\\n" +`, + }, + roff: { + aliases: [ + "groff", + "nroff", + "troff", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "man", + "manual", + ], + name: "roff", + monacoLang: "plaintext", + main: "main.roff", + compile: "pandoc main.roff -f man -o main.html", + run: "prettier --no-config main.html", + template: `.PP +Hello, world! `, }, ruby: { diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index 82bdcc5..5efe927 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -68,6 +68,9 @@ pandoc gcc-riscv64-linux-gnu qemu-user-static +# roff +pandoc + # Ruby ruby ruby-dev From 972aee458314571bcfaf689655ea606788acbc3c Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 11 Jul 2020 13:08:22 -0600 Subject: [PATCH 124/388] New languages: wiki markup dialects --- backend/src/langs.ts | 58 +++++++++++++++++++++++++++++ frontend/styles/index.css | 2 +- scripts/docker-install-phase3c.bash | 13 ------- scripts/docker-install-phase3d.bash | 3 -- scripts/docker-install-phase4.bash | 5 ++- scripts/docker-install-phase5.bash | 5 +++ 6 files changed, 68 insertions(+), 18 deletions(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 0ce8574..a305623 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -191,6 +191,16 @@ int main() { main: "main.lisp", run: "rlwrap sbcl --userinit main.lisp", template: `(format t "Hello, world!") +`, + }, + confluence: { + aliases: ["jira", "atlassian"], + name: "Confluence", + monacoLang: "plaintext", + main: "main.txt", + compile: "pandoc main.txt -f jira -o main.html", + run: "prettier --no-config main.html", + template: `Hello, world! `, }, cpp: { @@ -332,6 +342,16 @@ void main() { compile: "cat main.dhall | dhall-to-json > main.json", run: "cat main.json | jq .", template: `{ output = "Hello, world!" } +`, + }, + dokuwiki: { + aliases: ["doku"], + name: "DokuWiki", + monacoLang: "plaintext", + main: "main.txt", + compile: "pandoc main.txt -f dokuwiki -o main.html", + run: "prettier --no-config main.html", + template: `Hello, world! `, }, elixir: { @@ -689,6 +709,16 @@ KTHXBYE compile: "pandoc main.md -o main.html", run: "prettier --no-config main.html", template: `Hello, world! +`, + }, + mediawiki: { + aliases: ["media"], + name: "MediaWiki", + monacoLang: "plaintext", + main: "main.txt", + compile: "pandoc main.txt -f mediawiki -o main.html", + run: "prettier --no-config main.html", + template: `Hello, world! `, }, mips: { @@ -1230,6 +1260,16 @@ END compile: "pandoc main.textile -o main.html", run: "prettier --no-config main.html", template: `Hello, world! +`, + }, + tikiwiki: { + aliases: ["tiki"], + name: "Tiki Wiki", + monacoLang: "plaintext", + main: "main.txt", + compile: "pandoc main.txt -f tikiwiki -o main.html", + run: "prettier --no-config main.html", + template: `Hello, world! `, }, toml: { @@ -1240,6 +1280,15 @@ END compile: "cat main.toml | yj -tj > main.json", run: "cat main.json | jq .", template: `output = "Hello, world!" +`, + }, + twiki: { + name: "TWiki", + monacoLang: "plaintext", + main: "main.txt", + compile: "pandoc main.txt -f twiki -o main.html", + run: "prettier --no-config main.html", + template: `Hello, world! `, }, typescript: { @@ -1270,6 +1319,15 @@ END run: `vim -c "$(< main.vim)"`, lsp: "vim-language-server --stdio", template: `:echo "Hello, world!" +`, + }, + vimwiki: { + name: "Vimwiki", + monacoLang: "plaintext", + main: "main.txt", + compile: "pandoc main.txt -f vimwiki -o main.html", + run: "prettier --no-config main.html", + template: `Hello, world! `, }, visualbasic: { diff --git a/frontend/styles/index.css b/frontend/styles/index.css index 0b2d9a1..f461a7a 100644 --- a/frontend/styles/index.css +++ b/frontend/styles/index.css @@ -15,7 +15,7 @@ body { } div.language { - width: 120px; + width: 140px; height: 60px; border: solid; margin: 5px; diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index 5efe927..b91737b 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -6,10 +6,6 @@ set -x packages=" -# Markdown -pandoc -prettier - # MIPS gcc-mips64-linux-gnuabi64 qemu-user-static @@ -34,9 +30,6 @@ ocaml # Octave octave -# Org -pandoc - # Pascal fpc @@ -61,16 +54,10 @@ r-base # Racket racket -# reStructuredText -pandoc - # RISC-V gcc-riscv64-linux-gnu qemu-user-static -# roff -pandoc - # Ruby ruby ruby-dev diff --git a/scripts/docker-install-phase3d.bash b/scripts/docker-install-phase3d.bash index fe75baf..5917be0 100755 --- a/scripts/docker-install-phase3d.bash +++ b/scripts/docker-install-phase3d.bash @@ -42,9 +42,6 @@ liblua5.3-dev luarocks texlive-binaries -# Textile -pandoc - # Unlambda unlambda diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 15f78bc..41dded7 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -27,6 +27,9 @@ for file in /opt/rust/bin/*; do ln -s /opt/rust/wrapper "/usr/bin/${file##*/}" done +# Shared +npm install -g prettier + # Bash npm install -g bash-language-server @@ -56,7 +59,7 @@ cpanm -n Devel::REPL npm install -g intelephense # Pug -npm install -g prettier pug-cli +npm install -g pug-cli # ReasonML npm install -g bs-platform diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index 856cdf1..7a19dbb 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -14,6 +14,11 @@ git clone https://github.com/circulosmeos/gdown.pl.git mv gdown.pl/gdown.pl /usr/bin/gdown rm -rf gdown.pl +# Shared +wget -nv https://github.com/jgm/pandoc/releases/download/2.10/pandoc-2.10-linux-amd64.tar.gz +tar -xf pandoc-*-linux-amd64.tar.gz -C /usr --strip-components=1 +rm pandoc-*-linux-amd64.tar.gz + # Ada wget -nv https://dl.bintray.com/reznikmm/ada-language-server/linux-latest.tar.gz tar -xf linux-latest.tar.gz From 95fa0df9bbff05562e55a731ba91eab66ce44fb4 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 11 Jul 2020 13:20:23 -0600 Subject: [PATCH 125/388] New languages: CSS preprocessors --- backend/src/langs.ts | 30 ++++++++++++++++++++++++++++++ scripts/docker-install-phase4.bash | 6 ++++++ 2 files changed, 36 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index a305623..c700e06 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -631,6 +631,17 @@ PLEASE GIVE UP createEmpty: true, run: `SHELL=/usr/bin/ksh HOME="$PWD" ksh`, template: `echo "Hello, world!" +`, + }, + less: { + aliases: ["lessc"], + name: "Less", + monacoLang: "less", + main: "main.less", + run: "lessc main.less", + template: `body:before { + content: "Hello, world!"; +} `, }, llvm: { @@ -1034,6 +1045,15 @@ binding_irb.run(IRB.conf) template: `fn main() { println!("Hello, world!"); } +`, + }, + sass: { + name: "Sass", + monacoLang: "plaintext", + main: "main.sass", + run: "sass main.sass", + template: `body:before + content: "Hello, world!" `, }, scala: { @@ -1055,6 +1075,16 @@ binding_irb.run(IRB.conf) template: `(begin (display "Hello, world!") (newline)) +`, + }, + scss: { + name: "SCSS", + monacoLang: "scss", + main: "main.scss", + run: "sass main.scss", + template: `body:before { + content: "Hello, world!"; +} `, }, sh: { diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 41dded7..e02aca1 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -52,6 +52,9 @@ pip3 install fortran-language-server # Julia julia -e 'using Pkg; Pkg.add("LanguageServer")' +# Less +npm install -g less + # Perl cpanm -n Devel::REPL @@ -70,6 +73,9 @@ gem install solargraph # Rust rustup component add rls rust-analysis rust-src +# Sass/SCSS +npm install -g sass + # Shakespeare pip3 install shakespearelang From febaef077084a0794a077e95dc7b31c2062615cf Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 11 Jul 2020 13:31:37 -0600 Subject: [PATCH 126/388] New language: LiveScript --- backend/src/langs.ts | 10 ++++++++++ scripts/docker-install-phase4.bash | 3 +++ 2 files changed, 13 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index c700e06..5cd2419 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -642,6 +642,16 @@ PLEASE GIVE UP template: `body:before { content: "Hello, world!"; } +`, + }, + livescript: { + aliases: ["lsc", "ls"], + name: "LiveScript", + monacoLang: "plaintext", + repl: "lsc", + main: "main.ls", + run: "lsc -r ./main.ls; lsc", + template: `console.log "Hello, world!" `, }, llvm: { diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index e02aca1..6bbc359 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -55,6 +55,9 @@ julia -e 'using Pkg; Pkg.add("LanguageServer")' # Less npm install -g less +# LiveScript +npm install -g livescript + # Perl cpanm -n Devel::REPL From 03117016cd7d29f497cf94163cf66dfb12fcc03b Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 12 Jul 2020 12:35:51 -0600 Subject: [PATCH 127/388] Fix conflicts between sandboxes --- backend/src/sandbox.ts | 18 +++++++++++++++++- backend/src/users.ts | 28 ++++++++++++++++++++++++---- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/backend/src/sandbox.ts b/backend/src/sandbox.ts index f147a80..a2774f4 100644 --- a/backend/src/sandbox.ts +++ b/backend/src/sandbox.ts @@ -4,7 +4,7 @@ import * as fs from "fs"; import { v4 as getUUID } from "uuid"; import { langs } from "./langs"; -import { borrowUser } from "./users"; +import { MIN_UID, MAX_UID, borrowUser, ignoreUsers } from "./users"; import { getEnv, privilegedSetup, @@ -23,6 +23,22 @@ function log(msg: any) { } async function main() { + const dirs = await new Promise((resolve, reject) => + fs.readdir("/tmp/riju", (err, dirs) => (err ? reject(err) : resolve(dirs))) + ); + const uids = ( + await Promise.all( + dirs.map( + (dir) => + new Promise((resolve, reject) => + fs.stat(`/tmp/riju/${dir}`, (err, stat) => + err ? reject(err) : resolve(stat.uid) + ) + ) + ) + ) + ).filter((uid) => uid >= MIN_UID && uid < MAX_UID); + await ignoreUsers(uids, log); const uuid = getUUID(); const { uid, returnUID } = await borrowUser(log); await run(privilegedSetup({ uid, uuid }), log); diff --git a/backend/src/users.ts b/backend/src/users.ts index d41d07d..aecbc5a 100644 --- a/backend/src/users.ts +++ b/backend/src/users.ts @@ -10,8 +10,8 @@ import { PRIVILEGED } from "./config"; import { privilegedUseradd, run } from "./util"; // Keep in sync with system/src/riju-system-privileged.c -const MIN_UID = 2000; -const MAX_UID = 65000; +export const MIN_UID = 2000; +export const MAX_UID = 65000; const CUR_UID = os.userInfo().uid; @@ -33,9 +33,10 @@ async function readExistingUsers(log: (msg: string) => void) { ) .filter(({ username }) => username.startsWith("riju")) .map(({ uid }) => parseInt(uid)) - .filter((uid) => !isNaN(uid) && uid >= MIN_UID && uid < MAX_UID); + .filter((uid) => !isNaN(uid) && uid >= MIN_UID && uid < MAX_UID) + .reverse(); nextId = (_.max(availIds) || MIN_UID - 1) + 1; - log(`Found ${availIds.length} existing users, next ID is ${nextId}`); + log(`Found ${availIds.length} existing users, next is riju${nextId}`); } async function createUser(log: (msg: string) => void): Promise { @@ -49,6 +50,25 @@ async function createUser(log: (msg: string) => void): Promise { return uid; } +export async function ignoreUsers(uids: number[], log: (msg: string) => void) { + await lock.acquire("key", async () => { + if (availIds === null || nextId === null) { + await readExistingUsers(log); + } + const uidSet = new Set(uids); + if (uidSet.size > 0) { + const plural = uidSet.size !== 1 ? "s" : ""; + log( + `Ignoring user${plural} from open session${plural}: ${Array.from(uidSet) + .sort() + .map((uid) => `riju${uid}`) + .join(", ")}` + ); + } + availIds = availIds!.filter((uid) => !uidSet.has(uid)); + }); +} + export async function borrowUser(log: (msg: string) => void) { if (!PRIVILEGED) { return { uid: CUR_UID, returnUID: async () => {} }; From 3fafd3422fa71aae9a0d4cc238046d971b9c2d4a Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 12 Jul 2020 14:18:07 -0600 Subject: [PATCH 128/388] Improve createEmpty, add setup --- backend/src/api.ts | 5 ++++- backend/src/langs.ts | 17 +++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/backend/src/api.ts b/backend/src/api.ts index 946b838..845fffe 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -87,6 +87,9 @@ export class Session { this.uidInfo = { uid, returnUID }; this.log(`Borrowed uid ${this.uid}`); await this.run(this.privilegedSetup()); + if (this.config.setup) { + await this.run(this.privilegedSpawn(bash(this.config.setup))); + } await this.runCode(); if (this.config.daemon) { const daemonArgs = this.privilegedSpawn(bash(this.config.daemon)); @@ -285,7 +288,7 @@ export class Session { cmdline = `echo '${name} has no REPL, press Run to see it in action'`; } if (code === undefined) { - code = createEmpty ? "" : template; + code = createEmpty !== undefined ? createEmpty : template; } if (code && suffix) { code += suffix; diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 5cd2419..7d13e57 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -3,11 +3,12 @@ export interface LangConfig { name: string; monacoLang: string; daemon?: string; + setup?: string; repl?: string; main: string; prefix?: string; suffix?: string; - createEmpty?: boolean; + createEmpty?: string; compile?: string; run: string; lspSetup?: string; @@ -385,7 +386,7 @@ output = "Hello, world!" monacoLang: "plaintext", repl: `SHELL=/usr/bin/elvish HOME="$PWD" elvish`, main: ".elvish/rc.elv", - createEmpty: true, + createEmpty: ``, run: `SHELL=/usr/bin/elvish HOME="$PWD" elvish`, template: `echo "Hello, world!" `, @@ -422,7 +423,7 @@ main() -> monacoLang: "plaintext", repl: "factor-lang", main: ".factor-rc", - createEmpty: true, + createEmpty: ``, run: "factor-lang", template: `USE: io @@ -628,7 +629,7 @@ PLEASE GIVE UP monacoLang: "shell", repl: `SHELL=/usr/bin/ksh HOME="$PWD" ksh`, main: ".kshrc", - createEmpty: true, + createEmpty: ``, run: `SHELL=/usr/bin/ksh HOME="$PWD" ksh`, template: `echo "Hello, world!" `, @@ -1103,7 +1104,7 @@ binding_irb.run(IRB.conf) monacoLang: "shell", repl: `SHELL=/usr/bin/sh HOME="$PWD" posh -l`, main: ".profile", - createEmpty: true, + createEmpty: ``, run: `SHELL=/usr/bin/sh HOME="$PWD" posh -l`, template: `echo "Hello, world!" `, @@ -1265,7 +1266,7 @@ END monacoLang: "tcl", repl: "tclsh", main: ".tclshrc", - createEmpty: true, + createEmpty: ``, run: `HOME="$PWD" tclsh`, template: `puts {Hello, world!} `, @@ -1276,7 +1277,7 @@ END monacoLang: "shell", repl: `SHELL=/usr/bin/tcsh HOME="$PWD" tcsh`, main: ".tcshrc", - createEmpty: true, + createEmpty: ``, run: `SHELL=/usr/bin/tcsh HOME="$PWD" tcsh`, template: `echo "Hello, world!" `, @@ -1449,7 +1450,7 @@ message: monacoLang: "shell", repl: "SHELL=/usr/bin/zsh zsh", main: ".zshrc", - createEmpty: true, + createEmpty: ``, run: `SHELL=/usr/bin/zsh ZDOTDIR="$PWD" zsh`, template: `echo "Hello, world!" `, From afc2fff6d800cabb8ba3a71bda8e197c15c6ad40 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 12 Jul 2020 14:18:23 -0600 Subject: [PATCH 129/388] New language: Spago (good lord that took forever) --- backend/src/langs.ts | 20 ++++++++++++++++++++ scripts/docker-install-phase2.bash | 1 + scripts/docker-install-phase3c.bash | 3 +++ scripts/docker-install-phase4.bash | 3 +++ scripts/docker-install-phase6.bash | 22 ++++++++++++++++++++++ 5 files changed, 49 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 7d13e57..e9262d7 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -917,6 +917,26 @@ main :- template: `html body p Hello, world! +`, + }, + purescript: { + aliases: ["purs", "pure", "ps"], + name: "PureScript", + monacoLang: "plaintext", + setup: `shopt -s dotglob; cp -R /opt/purescript/project-template/* "$PWD/"`, + repl: "spago repl", + main: "src/Main.purs", + run: `if spago build -n; then spago run -n; (echo 'import Prelude'; echo 'import Main') > .purs-repl; spago repl; else echo 'import Prelude' > .purs-repl; spago repl -d; fi`, + template: `module Main where + +import Prelude + +import Effect (Effect) +import Effect.Console (log) + +main :: Effect Unit +main = do + log "Hello, world!" `, }, python: { diff --git a/scripts/docker-install-phase2.bash b/scripts/docker-install-phase2.bash index 14d6574..ae92977 100755 --- a/scripts/docker-install-phase2.bash +++ b/scripts/docker-install-phase2.bash @@ -30,6 +30,7 @@ nano iputils-ping sudo tmux +tree vim wget diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index b91737b..10e16cb 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -43,6 +43,9 @@ php # Prolog swi-prolog +# PureScript +libtinfo5 + # Python python3 python3-pip diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 6bbc359..3e489d9 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -67,6 +67,9 @@ npm install -g intelephense # Pug npm install -g pug-cli +# PureScript +npm install -g purescript spago + # ReasonML npm install -g bs-platform diff --git a/scripts/docker-install-phase6.bash b/scripts/docker-install-phase6.bash index 4efcf57..4e0a0cb 100755 --- a/scripts/docker-install-phase6.bash +++ b/scripts/docker-install-phase6.bash @@ -3,6 +3,27 @@ set -e set -o pipefail set -x +pushd /tmp >/dev/null + +mkdir project-template +pushd project-template >/dev/null +spago init -C +rm -rf .gitignore test +sed -i 's#, "test/\*\*/\*\.purs"##' spago.dhall +cat <<"EOF" > src/Main.spago +import Prelude + +import Effect (Effect) + +main :: Effect Unit +main = pure unit +EOF +spago build +spago repl < /dev/null +rm -rf src +popd >/dev/null +mkdir /opt/purescript +mv project-template /opt/purescript/ # Befunge tee /usr/bin/befunge-repl >/dev/null <<"EOF" @@ -133,4 +154,5 @@ while True: EOF chmod +x /usr/bin/unlambda-repl +popd >/dev/null rm "$0" From 8a1465b924ece6c6036e59c155e70bc9a6e03890 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 12 Jul 2020 15:07:17 -0600 Subject: [PATCH 130/388] Prune before build --- scripts/deploy-phase2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/deploy-phase2.py b/scripts/deploy-phase2.py index adbf088..c3ffcb2 100755 --- a/scripts/deploy-phase2.py +++ b/scripts/deploy-phase2.py @@ -10,8 +10,8 @@ import sys import tempfile import time -subprocess.run(["make", "image-prod"], check=True) subprocess.run(["docker", "system", "prune", "-f"], check=True) +subprocess.run(["make", "image-prod"], check=True) existing_containers = subprocess.run( ["docker", "ps", "-q"], check=True, stdout=subprocess.PIPE ).stdout.splitlines() From a641af75102ca8f148633e870a036afa9c1c82ce Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 12 Jul 2020 20:52:14 -0600 Subject: [PATCH 131/388] Starting to thing about package management --- backend/src/langs.ts | 37 ++++++++++++++++++++++++++++-- backend/src/util.ts | 12 +++++++++- scripts/docker-install-phase2.bash | 1 + 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index e9262d7..d1b148c 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -11,6 +11,12 @@ export interface LangConfig { createEmpty?: string; compile?: string; run: string; + pkg?: { + install: string; + uninstall?: string; + all?: string; + search?: string; + }; lspSetup?: string; lsp?: string; lspDisableDynamicRegistration?: boolean; @@ -19,6 +25,9 @@ export interface LangConfig { lspLang?: string; template: string; hacks?: "ghci-config"[]; + test?: { + ensure?: string; + }; } export const langs: { [key: string]: LangConfig } = { @@ -395,9 +404,14 @@ output = "Hello, world!" aliases: ["emacslisp", "elisp", "gnuemacs", "xemacs", "ielm"], name: "Emacs Lisp", monacoLang: "plaintext", - repl: "emacs --eval '(ielm)'", + repl: `emacs --eval "(progn (require 'package) (push '(\"melpa\" . \"https://melpa.org/packages/\") package-archives) (package-initialize) (ielm))"`, main: "main.el", - run: "emacs --load main.el --eval '(ielm)'", + run: `emacs --load main.el --eval "(progn (require 'package) (push '(\"melpa\" . \"https://melpa.org/packages/\") package-archives) (package-initialize) (ielm))"`, + pkg: { + install: `emacs -Q --batch --eval "(progn (require 'package) (push '(\"melpa\" . \"https://melpa.org/packages/\") package-archives) (package-initialize) (unless (ignore-errors (>= (length (directory-files \"~/.emacs.d/elpa/archives\")) 4)) (package-refresh-contents)) (package-install 'NAME))"`, + uninstall: `ls ~/.emacs.d/elpa | grep -- - | grep '^NAME-[0-9]' | while read pkg; do emacs -Q --batch --eval "(progn (require 'package) (push '(\"melpa\" . \"https://melpa.org/packages/\") package-archives) (package-initialize) (unless (ignore-errors (>= (length (directory-files \"~/.emacs.d/elpa/archives\")) 4)) (package-refresh-contents)) (call-interactively 'package-delete))" <<< "$pkg"; done`, + all: `set -o pipefail; (curl -sS https://elpa.gnu.org/packages/ | grep '' | grep -Eo '[^>]+' | grep -Eo '^[^<]+' && curl -sS https://melpa.org/archive.json | jq -r 'keys | .[]') | sort | uniq`, + }, template: `(message "Hello, world!") `, }, @@ -797,6 +811,12 @@ message: eval.apply(this, [require("fs").readFileSync("main.js", {encoding: "utf-8"})]) require("repl").start() '`, + pkg: { + install: "yarn add NAME", + uninstall: "yarn remove NAME", + search: + "curl -sS 'https://registry.npmjs.org/-/v1/search?text=NAME' | jq -r '.objects | map(.package.name) | .[]'", + }, template: `console.log("Hello, world!") `, }, @@ -946,6 +966,11 @@ main = do repl: "python3 -u", main: "main.py", run: "python3 -u -i main.py", + pkg: { + install: "pip3 install --user NAME", + uninstall: "pip3 uninstall NAME", + search: `python3 -c 'import json; from xmlrpc import client; print(json.dumps(client.ServerProxy("https://pypi.org/pypi").search({"name": "NAME"})))' | jq -r 'map(.name) | .[]'`, + }, lsp: "Microsoft.Python.LanguageServer", lspInit: { interpreter: { @@ -1061,9 +1086,17 @@ binding_irb = IRB::Irb.new(workspace) binding_irb.run(IRB.conf) `, run: "ruby main.rb", + pkg: { + install: "gem install --user-install NAME", + uninstall: "gem uninstall --user-install NAME", + search: `curl -sS 'https://rubygems.org/api/v1/search.json?query=NAME' | jq -r 'map(.name) | .[]'`, + }, lsp: "solargraph stdio", template: `puts "Hello, world!" `, + test: { + ensure: `ruby -e 'raise "version mismatch, expected #{RUBY_VERSION}" unless ENV["PATH"].include? ".gem/ruby/#{RUBY_VERSION}/bin"'`, + }, }, rust: { aliases: ["rs", "rustc"], diff --git a/backend/src/util.ts b/backend/src/util.ts index 59cb89a..808ca8c 100644 --- a/backend/src/util.ts +++ b/backend/src/util.ts @@ -19,12 +19,22 @@ export const rijuSystemPrivileged = appRoot.resolve( export function getEnv(uuid: string) { const cwd = `/tmp/riju/${uuid}`; + const path = [ + `${cwd}/.gem/ruby/2.7.0/bin`, + `${cwd}/.local/bin`, + `${cwd}/node_modules/.bin`, + `/usr/local/sbin`, + `/usr/local/bin`, + `/usr/sbin`, + `/usr/bin`, + `/bin`, + ]; return { HOME: cwd, HOSTNAME: "riju", LANG: process.env.LANG || "", LC_ALL: process.env.LC_ALL || "", - PATH: "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/bin", + PATH: path.join(":"), PWD: cwd, SHELL: "/usr/bin/bash", TERM: "xterm-color", diff --git a/scripts/docker-install-phase2.bash b/scripts/docker-install-phase2.bash index ae92977..cc6b4fe 100755 --- a/scripts/docker-install-phase2.bash +++ b/scripts/docker-install-phase2.bash @@ -20,6 +20,7 @@ bsdmainutils curl emacs-nox git +httpie htop jq lsof From ce9c968d7651c8a0d787180f66c869b0ffbd85ec Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 17 Jul 2020 17:34:50 -0600 Subject: [PATCH 132/388] New language: Beatnik --- backend/src/langs.ts | 96 ++++++++++++++++++++++++++++++ scripts/docker-install-phase7.bash | 6 ++ 2 files changed, 102 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index d1b148c..d836aa3 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -118,6 +118,102 @@ implement main0 () = () main: "main.bas", run: "bwbasic main.bas", template: `PRINT "Hello, world!" +`, + }, + beatnik: { + name: "Beatnik", + monacoLang: "plaintext", + main: "main.beatnik", + run: "beatnik main.beatnik", + template: `Soars, larkspurs, rains. +Indistinctness. +Mario snarl (nurses, natures, rules...) sensuously retries goal. +Agribusinesses' costs par lain ropes (mopes) autos' cores. +Tuner ambitiousness. +Flit. +Dour entombment. +Legals' saner kinking lapse. +Nests glint. +Dread, tied futures, dourer usual tumor grunts alter atonal + garb tries shouldered coins. +Taste a vast lustiness. +Stile stuns gad subgroup gram lanes. +Draftee insurer road: cuckold blunt, strut sunnier. +Rely enure pantheism: arty gain groups (genies, pan) titters, tattles, nears. +Bluffer tapes? Idle diatom stooge! +Feted antes anklets ague? Remit goiter gout! +Doubtless teared toed alohas will dull gangs' aerials' tails' sluices; +Gusset ends! Gawkier halo! + +Enter abstruse rested loser beer guy louts. +Curtain roams lasso weir lupus stunt. +Truant bears animate talon. Entire torte originally timer. +Redo stilt gobs. + +Utter centaurs; +Urgent stars; +Usurers (dilute); +Noses; +Bones; +Brig sonar graders; +Utensil silts; +Lazies. +Fret arson veterinary rows. + +Atlas grunted: "Pates, slues, sulfuric manor liaising tines, + trailers, rep... unfair! Instant snots!" + +Sled rested until eatery fail. +Ergs fortitude + Indent spotter +Euros enter egg. +Curious tenures. +Torus cutlasses. +Sarong torso earns cruel lags it reeled. + +Engineer: "Erase handbag -- unite ratification!" + +oaring oaten donkeys unsold, surer rapid saltest tags +BUTTERED TIBIA LUGS REWIRING TOILETS +anion festers raring edit epilogues. +DIRGE ROTOR. +linnet oaring. +GORE BOOTIES. +Ironed goon lists tallest sublets -- +Riots, +Raucous onset. + +Ignobly, runners' diet anguishes sunrise loner. +Erode mob, slier switcher! +Loaners stilt drudge pearl atoll, risking hats' ends. + +Rebind sitters. + +Toga epistles -- crud lard. (Pager purse dons souls.) + +glob title a curio hired rites shed suds lade grease strut arctic revs toad +unless idlers rind stilt region land GERMICIDES SULTANA GUTS gill siting leans +nice spurs +tests gloves +roused asp + +Holes! Moles! (Sores!) +Hygienists! Scars! (Asses!) +Smells spell rares. + +Cubs instant sing in parse goodies. +Rosin. Unhelpful sisal acres. Slope told. +MALENESS PASTA LAB. "Infirmary vine," rang illiterates (beans). +Rosin sours, insults truss abalones, nailed rules, helical atlases. +Dear remodeling stings mar rents. +Sunless shiner orb (silly idol.) +Clarity disses senna. +Vagabonds sauted; sloes performed gelds. +Alter post radial lip sectioning gums. +Saint Towellings. +Larger aeons telephone stolid char, pal! +Boats Dean forsook, rosters, tunas, terrariums -- united, traced. +Nude pagoda careens. `, }, befunge: { diff --git a/scripts/docker-install-phase7.bash b/scripts/docker-install-phase7.bash index a7c44e7..ec8f3f2 100755 --- a/scripts/docker-install-phase7.bash +++ b/scripts/docker-install-phase7.bash @@ -5,6 +5,12 @@ set -o pipefail set -x pushd /tmp >/dev/null +# Beatnik +git clone https://github.com/catseye/Beatnik.git +sed -i 's#env python#env python2#' Beatnik/script/beatnik.py +mv Beatnik/script/beatnik.py /usr/bin/beatnik +rm -rf Beatnik + # Erlang git clone https://github.com/erlang-ls/erlang_ls.git pushd erlang_ls >/dev/null From 720acc50bbf7318f3c86ef9d8df041324c177fc5 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 17 Jul 2020 18:12:45 -0600 Subject: [PATCH 133/388] New language: Binary Lambda Calculus --- backend/src/langs.ts | 16 ++++++++++++++++ scripts/docker-install-phase6.bash | 17 +++++++++++++++++ scripts/docker-install-phase7.bash | 5 +++++ 3 files changed, 38 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index d836aa3..d63e096 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -223,6 +223,22 @@ Nude pagoda careens. main: "main.be", run: "befunge-repl main.be", template: `64+"!dlrow ,olleH">:#,_@ +`, + }, + blc: { + aliases: [ + "binarylambdacalculus", + "lc", + "binary", + "lambdacalculus", + "lambda", + ], + name: "Binary Lambda Calculus", + monacoLang: "plaintext", + main: "main.blc", + run: "cat main.blc | binary-to-text | tromp", + template: `001010100100100001100101011011000110110001101111001011000010 +000001110111011011110111001001101100011001000010000100001010 `, }, brainf: { diff --git a/scripts/docker-install-phase6.bash b/scripts/docker-install-phase6.bash index 4e0a0cb..f928069 100755 --- a/scripts/docker-install-phase6.bash +++ b/scripts/docker-install-phase6.bash @@ -56,6 +56,23 @@ befunge.run(fs.readFileSync(args[0], { encoding: "utf-8" })).catch((err) => { EOF chmod +x /usr/bin/befunge-repl +# Binary Lambda Calculus +tee /usr/bin/binary-to-text >/dev/null <<"EOF" +#!/usr/bin/env python3 + +import re +import sys + +text = re.sub(r"[^01]", "", sys.stdin.read()) +out = [] + +for m in re.finditer(r"([01]{8})", text): + out += chr(int(m.group(0), 2)) + +print("".join(out), end="") +EOF +chmod +x /usr/bin/binary-to-text + # BrainF tee /usr/bin/brainf-repl >/dev/null <<"EOF" #!/usr/bin/env python3 diff --git a/scripts/docker-install-phase7.bash b/scripts/docker-install-phase7.bash index ec8f3f2..b9d5696 100755 --- a/scripts/docker-install-phase7.bash +++ b/scripts/docker-install-phase7.bash @@ -11,6 +11,11 @@ sed -i 's#env python#env python2#' Beatnik/script/beatnik.py mv Beatnik/script/beatnik.py /usr/bin/beatnik rm -rf Beatnik +# Binary Lambda Calculus +wget -nv https://www.ioccc.org/2012/tromp/tromp.c +clang tromp.c -Wno-everything -DInt=long -DX=8 -DA=500000 -o /usr/bin/tromp +rm tromp.c + # Erlang git clone https://github.com/erlang-ls/erlang_ls.git pushd erlang_ls >/dev/null From 4ca01a6fdd5aec053e93d92c6236e92ba3a67274 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 17 Jul 2020 18:20:56 -0600 Subject: [PATCH 134/388] New language: Chef --- backend/src/langs.ts | 64 ++++++++++++++++++++++++++++++ scripts/docker-install-phase4.bash | 3 ++ 2 files changed, 67 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index d63e096..e24a840 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -293,6 +293,70 @@ int main() { printf("Hello, world!\\n"); return 0; } +`, + }, + chef: { + name: "Chef", + monacoLang: "plaintext", + main: "main.chef", + run: "chef main.chef", + template: `Hello World Cake with Chocolate Sauce. + +Ingredients. +33 g chocolate chips +100 g butter +54 ml double cream +2 pinches baking powder +114 g sugar +111 ml beaten eggs +119 g flour +32 g cocoa powder +0 g cake mixture + +Cooking time: 25 minutes. + +Pre-heat oven to 180 degrees Celsius. + +Method. +Put chocolate chips into the mixing bowl. +Put butter into the mixing bowl. +Put sugar into the mixing bowl. +Put beaten eggs into the mixing bowl. +Put flour into the mixing bowl. +Put baking powder into the mixing bowl. +Put cocoa powder into the mixing bowl. +Stir the mixing bowl for 1 minute. +Combine double cream into the mixing bowl. +Stir the mixing bowl for 4 minutes. +Liquefy the contents of the mixing bowl. +Pour contents of the mixing bowl into the baking dish. +bake the cake mixture. +Wait until baked. +Serve with chocolate sauce. + +Chocolate Sauce. + +Ingredients. +111 g sugar +108 ml hot water +108 ml heated double cream +101 g dark chocolate +72 g milk chocolate + +Method. +Clean the mixing bowl. +Put sugar into the mixing bowl. +Put hot water into the mixing bowl. +Put heated double cream into the mixing bowl. +dissolve the sugar. +agitate the sugar until dissolved. +Liquefy the dark chocolate. +Put dark chocolate into the mixing bowl. +Liquefy the milk chocolate. +Put milk chocolate into the mixing bowl. +Liquefy contents of the mixing bowl. +Pour contents of the mixing bowl into the baking dish. +Refrigerate for 1 hour. `, }, cmd: { diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 3e489d9..6649580 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -36,6 +36,9 @@ npm install -g bash-language-server # Befunge npm install -g befunge93 prompt-sync +# Chef +cpanm -n Acme::Chef + # ClojureScript npm install -g lumo-cljs From 5006521982167c19954e60e86886c1b1dcc39337 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 17 Jul 2020 18:24:22 -0600 Subject: [PATCH 135/388] New language: Dogescript --- backend/src/langs.ts | 10 ++++++++++ scripts/docker-install-phase4.bash | 3 +++ 2 files changed, 13 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index e24a840..4fd8cea 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -519,6 +519,16 @@ void main() { template: `void main() { print('Hello, world!'); } +`, + }, + dogescript: { + aliases: ["doge", "ds", "wow"], + name: "Dogescript", + monacoLang: "plaintext", + repl: "dogescript", + main: "main.djs", + run: "dogescript main.djs | node; dogescript", + template: `plz console.loge with "Hello, world!" `, }, dhall: { diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 6649580..25f82fa 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -45,6 +45,9 @@ npm install -g lumo-cljs # CoffeeScript npm install -g coffeescript +# Dogescript +npm install -g dogescript + # Elm npm install -g @kachkaev/run-elm npm install -g @elm-tooling/elm-language-server From 9b87d850b008320d2b892bd6f3592c811efa1c5f Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 17 Jul 2020 18:49:18 -0600 Subject: [PATCH 136/388] New language: Entropy --- backend/src/langs.ts | 12 ++++++++++++ scripts/docker-install-phase5.bash | 5 +++++ 2 files changed, 17 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 4fd8cea..4773af6 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -599,6 +599,18 @@ output = "Hello, world!" all: `set -o pipefail; (curl -sS https://elpa.gnu.org/packages/ | grep '' | grep -Eo '[^>]+' | grep -Eo '^[^<]+' && curl -sS https://melpa.org/archive.json | jq -r 'keys | .[]') | sort | uniq`, }, template: `(message "Hello, world!") +`, + }, + entropy: { + aliases: ["ent", "entc", "vge"], + name: "Entropy", + monacoLang: "plaintext", + main: "main.vge", + compile: `mono /opt/entropy/entc.exe main.vge | grep -Ev 'WARNING:|Using default' > main.cs && mcs -lib:/opt/entropy -r:Rottytooth.Esolang.Entropy main.cs`, + run: "MONO_PATH=/opt/entropy mono main.exe", + template: `Program MyNamespace MyProgram [ + print "Hello, world!"; +] `, }, erlang: { diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index 7a19dbb..df1d9f0 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -55,6 +55,11 @@ gunzip binary-for-linux-64-bit.gz chmod +x binary-for-linux-64-bit mv binary-for-linux-64-bit /usr/bin/elm +# Entropy +wget -nv http://danieltemkin.com/Content/Entropy/Entropy.zip +unzip -d /opt/entropy Entropy.zip +rm Entropy.zip + # Erlang wget -nv https://s3.amazonaws.com/rebar3/rebar3 chmod +x rebar3 From f3cb91cbb90dbda7748be18c48331ff117c8a152 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 17 Jul 2020 18:50:54 -0600 Subject: [PATCH 137/388] Cleanup --- scripts/docker-install-phase1.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/docker-install-phase1.bash b/scripts/docker-install-phase1.bash index 61f4e24..f3a13e7 100755 --- a/scripts/docker-install-phase1.bash +++ b/scripts/docker-install-phase1.bash @@ -18,7 +18,7 @@ curl -sSL https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - curl -sSL https://keybase.io/crystal/pgp_keys.asc | apt-key add - apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9 -wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb +wget -nv https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb dpkg -i packages-microsoft-prod.deb rm packages-microsoft-prod.deb From fd16801ab0e045080894b14f2922aa4d588121f9 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 17 Jul 2020 19:04:48 -0600 Subject: [PATCH 138/388] README.WHYYYYYYY The contents of ftp://ftp.snobol4.org/snobol/old/snobol4-2.1.4.tar.gz are now a tarball containing a single file entitled 'README.WHY' with the following contents... July 13th, 2020 Just curious why I'm seeing repeated downloads of ftp://ftp.snobol4.org/snobol4/old/snobol4-2.1.4.tar.gz (on July 11th and 12th). 2.1.4 was an intermediate release for Windows 10 support. The currently available Windows 10 binary release is 2.1.5, available since July 2nd 2020. Please let me know by emailing phil(at)snobol4.org ... So rather than deal with this I decided to just grab the latest release and stick it on Google Drive. --- scripts/docker-install-phase5.bash | 4 ++++ scripts/docker-install-phase7.bash | 10 ---------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index df1d9f0..c7ad8db 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -145,6 +145,10 @@ metals -version /dev/null -make || true -mv snobol4 /usr/bin/snobol4 -popd >/dev/null -rm -rf snobol4-* - popd >/dev/null rm "$0" From f35865a1ca66aef6a56c2abdb06183bc16b00876 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 17 Jul 2020 19:06:33 -0600 Subject: [PATCH 139/388] New language: GolfScript --- backend/src/langs.ts | 9 +++++++++ scripts/docker-install-phase5.bash | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 4773af6..be62d51 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -707,6 +707,15 @@ import "fmt" func main() { fmt.Println("Hello, world!") } +`, + }, + golfscript: { + aliases: ["gs", "golf"], + name: "GolfScript", + monacoLang: "plaintext", + main: "main.gs", + run: "golfscript main.gs", + template: `'Hello, world!' `, }, groovy: { diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index c7ad8db..251b903 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -79,6 +79,10 @@ go get golang.org/x/tools/gopls@latest mv go/bin/gopls /usr/bin/gopls rm -rf go +# GolfScript +wget -nv http://www.golfscript.com/golfscript/golfscript.rb -O /usr/bin/golfscript +chmod +x /usr/bin/golfscript + # Haskell wget -nv https://get.haskellstack.org/stable/linux-x86_64-static.tar.gz tar -xf linux-x86_64-static.tar.gz From eac2f311383f0bcb21f2308f40e02df419756736 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 17 Jul 2020 19:14:28 -0600 Subject: [PATCH 140/388] Make monacoLang optional --- backend/src/langs.ts | 70 +------------------------------------------- frontend/src/app.ts | 7 +++-- 2 files changed, 6 insertions(+), 71 deletions(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index be62d51..46ec41a 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1,7 +1,7 @@ export interface LangConfig { aliases?: string[]; name: string; - monacoLang: string; + monacoLang?: string; daemon?: string; setup?: string; repl?: string; @@ -34,7 +34,6 @@ export const langs: { [key: string]: LangConfig } = { ada: { aliases: ["adb"], name: "Ada", - monacoLang: "plaintext", main: "main.adb", compile: "x86_64-linux-gnu-gnatmake-9 main.adb", run: "./main", @@ -50,7 +49,6 @@ end Main; algol: { aliases: ["alg"], name: "ALGOL 68", - monacoLang: "plaintext", main: "main.alg", run: "a68g main.alg", template: `print(("Hello, world!",new line)) @@ -58,7 +56,6 @@ end Main; }, arm: { name: "ARM", - monacoLang: "plaintext", main: "main.S", compile: "arm-linux-gnueabihf-gcc main.S -o main -static", run: "qemu-arm-static main", @@ -80,7 +77,6 @@ message: }, asciidoc: { aliases: ["adoc", "asc"], - monacoLang: "plaintext", name: "AsciiDoc", main: "main.adoc", compile: "asciidoc -s main.adoc", @@ -113,7 +109,6 @@ implement main0 () = () basic: { aliases: ["bas", "qbasic"], name: "BASIC", - monacoLang: "plaintext", repl: "bwbasic", main: "main.bas", run: "bwbasic main.bas", @@ -122,7 +117,6 @@ implement main0 () = () }, beatnik: { name: "Beatnik", - monacoLang: "plaintext", main: "main.beatnik", run: "beatnik main.beatnik", template: `Soars, larkspurs, rains. @@ -219,7 +213,6 @@ Nude pagoda careens. befunge: { aliases: ["be"], name: "Befunge", - monacoLang: "plaintext", main: "main.be", run: "befunge-repl main.be", template: `64+"!dlrow ,olleH">:#,_@ @@ -234,7 +227,6 @@ Nude pagoda careens. "lambda", ], name: "Binary Lambda Calculus", - monacoLang: "plaintext", main: "main.blc", run: "cat main.blc | binary-to-text | tromp", template: `001010100100100001100101011011000110110001101111001011000010 @@ -244,7 +236,6 @@ Nude pagoda careens. brainf: { aliases: ["brainfuck", "bf"], name: "Brainf***", - monacoLang: "plaintext", repl: "brainf-repl", main: "main.bf", run: "brainf-repl main.bf", @@ -297,7 +288,6 @@ int main() { }, chef: { name: "Chef", - monacoLang: "plaintext", main: "main.chef", run: "chef main.chef", template: `Hello World Cake with Chocolate Sauce. @@ -372,7 +362,6 @@ Refrigerate for 1 hour. commonlisp: { aliases: ["lisp", "sbcl"], name: "Common Lisp", - monacoLang: "plaintext", repl: "rlwrap sbcl", main: "main.lisp", run: "rlwrap sbcl --userinit main.lisp", @@ -382,7 +371,6 @@ Refrigerate for 1 hour. confluence: { aliases: ["jira", "atlassian"], name: "Confluence", - monacoLang: "plaintext", main: "main.txt", compile: "pandoc main.txt -f jira -o main.html", run: "prettier --no-config main.html", @@ -428,7 +416,6 @@ int main() { crystal: { aliases: ["cr"], name: "Crystal", - monacoLang: "plaintext", main: "main.cr", run: "crystal main.cr", template: `puts "Hello, world!" @@ -472,7 +459,6 @@ int main() { cobol: { aliases: ["cbl", "cobc"], name: "COBOL", - monacoLang: "plaintext", main: "main.cbl", compile: "cobc -free -x main.cbl -o main", run: "./main", @@ -500,7 +486,6 @@ require("/usr/lib/node_modules/coffeescript/repl").start() d: { aliases: ["dmd"], name: "D", - monacoLang: "plaintext", main: "main.d", compile: "dmd main.d", run: "./main", @@ -524,7 +509,6 @@ void main() { dogescript: { aliases: ["doge", "ds", "wow"], name: "Dogescript", - monacoLang: "plaintext", repl: "dogescript", main: "main.djs", run: "dogescript main.djs | node; dogescript", @@ -533,7 +517,6 @@ void main() { }, dhall: { name: "Dhall", - monacoLang: "plaintext", main: "main.dhall", compile: "cat main.dhall | dhall-to-json > main.json", run: "cat main.json | jq .", @@ -543,7 +526,6 @@ void main() { dokuwiki: { aliases: ["doku"], name: "DokuWiki", - monacoLang: "plaintext", main: "main.txt", compile: "pandoc main.txt -f dokuwiki -o main.html", run: "prettier --no-config main.html", @@ -553,7 +535,6 @@ void main() { elixir: { aliases: ["iex", "exs"], name: "Elixir", - monacoLang: "plaintext", repl: "iex", main: "main.exs", run: "iex main.exs", @@ -563,7 +544,6 @@ void main() { }, elm: { name: "Elm", - monacoLang: "plaintext", repl: "elm repl", main: "Main.elm", run: "cp /opt/elm/elm.json elm.json && run-elm Main.elm; elm repl", @@ -578,7 +558,6 @@ output = "Hello, world!" elvish: { aliases: ["elv"], name: "Elvish", - monacoLang: "plaintext", repl: `SHELL=/usr/bin/elvish HOME="$PWD" elvish`, main: ".elvish/rc.elv", createEmpty: ``, @@ -589,7 +568,6 @@ output = "Hello, world!" emacs: { aliases: ["emacslisp", "elisp", "gnuemacs", "xemacs", "ielm"], name: "Emacs Lisp", - monacoLang: "plaintext", repl: `emacs --eval "(progn (require 'package) (push '(\"melpa\" . \"https://melpa.org/packages/\") package-archives) (package-initialize) (ielm))"`, main: "main.el", run: `emacs --load main.el --eval "(progn (require 'package) (push '(\"melpa\" . \"https://melpa.org/packages/\") package-archives) (package-initialize) (ielm))"`, @@ -604,7 +582,6 @@ output = "Hello, world!" entropy: { aliases: ["ent", "entc", "vge"], name: "Entropy", - monacoLang: "plaintext", main: "main.vge", compile: `mono /opt/entropy/entc.exe main.vge | grep -Ev 'WARNING:|Using default' > main.cs && mcs -lib:/opt/entropy -r:Rottytooth.Esolang.Entropy main.cs`, run: "MONO_PATH=/opt/entropy mono main.exe", @@ -616,7 +593,6 @@ output = "Hello, world!" erlang: { aliases: ["erl"], name: "Erlang", - monacoLang: "plaintext", repl: "erl", main: "main.erl", compile: "erl -compile main", @@ -632,7 +608,6 @@ main() -> factor: { aliases: ["fact"], name: "Factor", - monacoLang: "plaintext", repl: "factor-lang", main: ".factor-rc", createEmpty: ``, @@ -644,7 +619,6 @@ main() -> }, fish: { name: "Fish", - monacoLang: "plaintext", repl: "SHELL=/usr/bin/fish fish", main: "main.fish", run: 'SHELL=/usr/bin/fish fish -C "$(< main.fish)"', @@ -654,7 +628,6 @@ main() -> forth: { aliases: ["fs", "gforth"], name: "Forth", - monacoLang: "plaintext", repl: "gforth", main: "main.fs", run: "gforth main.fs", @@ -672,7 +645,6 @@ main() -> "fortran2008", ], name: "FORTRAN", - monacoLang: "plaintext", main: "main.f", compile: "flang main.f -o main", run: "./main", @@ -712,7 +684,6 @@ func main() { golfscript: { aliases: ["gs", "golf"], name: "GolfScript", - monacoLang: "plaintext", main: "main.gs", run: "golfscript main.gs", template: `'Hello, world!' @@ -720,7 +691,6 @@ func main() { }, groovy: { name: "Groovy", - monacoLang: "plaintext", repl: `JAVA_OPTS="-Djava.util.prefs.systemRoot=$PWD/.java -Djava.util.prefs.userRoot=$PWD/.java/.userPrefs" groovysh`, main: "main.groovy", run: `JAVA_OPTS="-Djava.util.prefs.systemRoot=$PWD/.java -Djava.util.prefs.userRoot=$PWD/.java/.userPrefs" groovysh main.groovy`, @@ -730,7 +700,6 @@ func main() { haskell: { aliases: ["ghc", "ghci", "hs"], name: "Haskell", - monacoLang: "plaintext", repl: "ghci", main: "Main.hs", run: "ghci", @@ -749,7 +718,6 @@ main = putStrLn "Hello, world!" hcl: { aliases: ["tf", "terraform", "hashicorp", "hc"], name: "HCL", - monacoLang: "plaintext", main: "main.hcl", compile: "cat main.hcl | yj -cj > main.json", run: "cat main.json | jq .", @@ -758,7 +726,6 @@ main = putStrLn "Hello, world!" }, ink: { name: "Ink", - monacoLang: "plaintext", repl: "ink", main: "main.ink", run: "ink main.ink; ink", @@ -773,7 +740,6 @@ log('Hello, world!') intercal: { aliases: ["i", "ick"], name: "INTERCAL", - monacoLang: "plaintext", main: "main.i", compile: "ick main.i", run: "./main", @@ -813,7 +779,6 @@ PLEASE GIVE UP julia: { aliases: ["jl"], name: "Julia", - monacoLang: "plaintext", repl: "julia", main: "main.jl", run: "julia -L main.jl", @@ -824,7 +789,6 @@ PLEASE GIVE UP }, kalyn: { name: "Kalyn", - monacoLang: "plaintext", main: "src-kalyn/Main.kalyn", compile: "kalyn", run: "out-kalyn/Main", @@ -869,7 +833,6 @@ PLEASE GIVE UP livescript: { aliases: ["lsc", "ls"], name: "LiveScript", - monacoLang: "plaintext", repl: "lsc", main: "main.ls", run: "lsc -r ./main.ls; lsc", @@ -907,7 +870,6 @@ define i32 @main() { ; i32()* lolcode: { aliases: ["lol", "lci"], name: "LOLCODE", - monacoLang: "plaintext", main: "main.lol", run: "lci main.lol", template: `HAI 1.2 @@ -928,7 +890,6 @@ KTHXBYE malbolge: { aliases: ["mb"], name: "Malbolge", - monacoLang: "plaintext", main: "main.mb", run: "malbolge main.mb", template: @@ -957,7 +918,6 @@ KTHXBYE mediawiki: { aliases: ["media"], name: "MediaWiki", - monacoLang: "plaintext", main: "main.txt", compile: "pandoc main.txt -f mediawiki -o main.html", run: "prettier --no-config main.html", @@ -990,7 +950,6 @@ message: mumps: { aliases: ["mlang", "gtm", "fisgtm"], name: "MUMPS", - monacoLang: "plaintext", main: "main.m", run: "gtm_dist=/usr/lib/x86_64-linux-gnu/fis-gtm/V6.3-007_x86_64 /usr/lib/x86_64-linux-gnu/fis-gtm/V6.3-007_x86_64/utf8/mumps -r main main.m", @@ -1001,7 +960,6 @@ message: }, nim: { name: "Nim", - monacoLang: "plaintext", main: "main.nim", compile: "nim compile main.nim", run: "./main", @@ -1049,7 +1007,6 @@ int main() { }, ocaml: { name: "OCaml", - monacoLang: "plaintext", main: "main.ml", repl: "ocaml", run: "ocaml -init main.ml", @@ -1059,7 +1016,6 @@ int main() { octave: { aliases: ["matlab", "m", "mathworks"], name: "Octave", - monacoLang: "plaintext", repl: "octave", main: "main.m", run: "octave --persist main.m", @@ -1069,7 +1025,6 @@ int main() { org: { aliases: ["orgmode"], name: "Org", - monacoLang: "plaintext", main: "main.org", compile: "pandoc main.org -o main.html", run: "prettier --no-config main.html", @@ -1125,7 +1080,6 @@ echo "Hello, world!\\n"; }, prolog: { name: "Prolog", - monacoLang: "plaintext", repl: "prolog", main: "main.pl", run: "prolog main.pl", @@ -1149,7 +1103,6 @@ main :- purescript: { aliases: ["purs", "pure", "ps"], name: "PureScript", - monacoLang: "plaintext", setup: `shopt -s dotglob; cp -R /opt/purescript/project-template/* "$PWD/"`, repl: "spago repl", main: "src/Main.purs", @@ -1202,7 +1155,6 @@ main = do racket: { aliases: ["rkt"], name: "Racket", - monacoLang: "plaintext", repl: "racket", main: "main.rkt", run: `racket -i -e '(enter! "main.rkt") (display "[ type (enter! \\"main.rkt\\") to access local variables ]\\n")'`, @@ -1213,7 +1165,6 @@ main = do reasonml: { aliases: ["re", "reason", "bsc", "buckle", "bucklescript"], name: "ReasonML", - monacoLang: "plaintext", main: "main.re", compile: "bsc main.re > main.js", run: "NODE_PATH=/usr/lib/node_modules node main.js", @@ -1233,7 +1184,6 @@ main = do riscv: { aliases: ["risc"], name: "RISC-V", - monacoLang: "plaintext", main: "main.S", compile: "riscv64-linux-gnu-gcc main.S -o main -static", run: "qemu-riscv64-static main", @@ -1271,7 +1221,6 @@ message: "manual", ], name: "roff", - monacoLang: "plaintext", main: "main.roff", compile: "pandoc main.roff -f man -o main.html", run: "prettier --no-config main.html", @@ -1320,7 +1269,6 @@ binding_irb.run(IRB.conf) }, sass: { name: "Sass", - monacoLang: "plaintext", main: "main.sass", run: "sass main.sass", template: `body:before @@ -1329,7 +1277,6 @@ binding_irb.run(IRB.conf) }, scala: { name: "Scala", - monacoLang: "plaintext", repl: "scala", main: "main.scala", run: "scala -i main.scala", @@ -1372,7 +1319,6 @@ binding_irb.run(IRB.conf) shakespeare: { aliases: ["spl"], name: "Shakespeare", - monacoLang: "plaintext", repl: "shakespeare console", main: "main.spl", suffix: "\n[A pause]", @@ -1471,7 +1417,6 @@ Ophelia: smalltalk: { aliases: ["gst", "st"], name: "Smalltalk", - monacoLang: "plaintext", repl: "gst", main: "main.st", run: "gst main.st; gst", @@ -1481,7 +1426,6 @@ Ophelia: snobol: { aliases: ["snobol4", "spitbol", "sno"], name: "SNOBOL", - monacoLang: "plaintext", repl: "snobol4", main: "main.sno", run: "snobol4 main.sno; snobol4", @@ -1502,7 +1446,6 @@ END standardml: { aliases: ["sml", "ml"], name: "Standard ML", - monacoLang: "plaintext", repl: "rlwrap sml", main: "main.sml", run: "rlwrap sml main.sml", @@ -1545,7 +1488,6 @@ END tex: { aliases: ["latex", "xetex", "plaintex"], name: "TeX", - monacoLang: "plaintext", repl: "tex", main: "main.tex", run: "tex main.tex", @@ -1556,7 +1498,6 @@ END }, textile: { name: "Textile", - monacoLang: "plaintext", main: "main.textile", compile: "pandoc main.textile -o main.html", run: "prettier --no-config main.html", @@ -1566,7 +1507,6 @@ END tikiwiki: { aliases: ["tiki"], name: "Tiki Wiki", - monacoLang: "plaintext", main: "main.txt", compile: "pandoc main.txt -f tikiwiki -o main.html", run: "prettier --no-config main.html", @@ -1576,7 +1516,6 @@ END toml: { aliases: ["tom"], name: "TOML", - monacoLang: "plaintext", main: "main.toml", compile: "cat main.toml | yj -tj > main.json", run: "cat main.json | jq .", @@ -1585,7 +1524,6 @@ END }, twiki: { name: "TWiki", - monacoLang: "plaintext", main: "main.txt", compile: "pandoc main.txt -f twiki -o main.html", run: "prettier --no-config main.html", @@ -1605,7 +1543,6 @@ END unlambda: { aliases: ["unl"], name: "Unlambda", - monacoLang: "plaintext", repl: "unlambda-repl", main: "main.unl", run: "unlambda-repl main.unl", @@ -1614,7 +1551,6 @@ END vim: { aliases: ["viml", "vimscript"], name: "Vimscript", - monacoLang: "plaintext", repl: "vim", main: "main.vim", run: `vim -c "$(< main.vim)"`, @@ -1624,7 +1560,6 @@ END }, vimwiki: { name: "Vimwiki", - monacoLang: "plaintext", main: "main.txt", compile: "pandoc main.txt -f vimwiki -o main.html", run: "prettier --no-config main.html", @@ -1648,7 +1583,6 @@ End Module whitespace: { aliases: ["ws"], name: "Whitespace", - monacoLang: "plaintext", main: "main.ws", run: "whitespace main.ws", template: `Hello, world! \t \t \n\t\n \t\t \t \t\n\t\n \t\t \t\t \n\t\n \t\t \t\t \n\t\n \t\t \t\t\t\t\n\t\n \t \t\t \n\t\n \t \n\t\n \t\t\t \t\t\t\n\t\n \t\t \t\t\t\t\n\t\n \t\t\t \t \n\t\n \t\t \t\t \n\t\n \t\t \t \n\t\n \n\n\n`, @@ -1664,7 +1598,6 @@ End Module "symja", ], name: "Wolfram Language", - monacoLang: "plaintext", repl: "mathics", main: "main.wls", run: "mathics --persist main.wls", @@ -1674,7 +1607,6 @@ End Module x86: { aliases: ["s", "asm", "assembly", "x86-64"], name: "x86", - monacoLang: "plaintext", main: "main.S", compile: "clang main.S -o main", run: "./main", diff --git a/frontend/src/app.ts b/frontend/src/app.ts index 0aa0dd8..6cb71bd 100644 --- a/frontend/src/app.ts +++ b/frontend/src/app.ts @@ -23,7 +23,7 @@ const config: RijuConfig = (window as any).rijuConfig; interface RijuConfig { id: string; - monacoLang: string; + monacoLang?: string; main: string; lspDisableDynamicRegistration?: boolean; lspInit?: any; @@ -300,7 +300,10 @@ async function main() { }); window.addEventListener("resize", () => editor.layout()); editor.getModel()!.setValue(config.template); - monaco.editor.setModelLanguage(editor.getModel()!, config.monacoLang); + monaco.editor.setModelLanguage( + editor.getModel()!, + config.monacoLang || "plaintext" + ); document.getElementById("runButton")!.addEventListener("click", () => { sendMessage({ event: "runCode", code: editor.getValue() }); From bf61acbf68d2fd3d1f06617c0277810cd00b9fc4 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 17 Jul 2020 19:14:36 -0600 Subject: [PATCH 141/388] New language: Omgrofl --- backend/src/langs.ts | 32 ++++++++++++++++++++++++++++++ scripts/docker-install-phase5.bash | 4 ++++ 2 files changed, 36 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 46ec41a..1598ed6 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1020,6 +1020,38 @@ int main() { main: "main.m", run: "octave --persist main.m", template: `disp("Hello, world!") +`, + }, + omgrofl: { + aliases: ["omg", "rofl"], + name: "Omgrofl", + main: "main.omgrofl", + run: "java -jar /opt/omgrofl/Omgrofl.jar main.omgrofl", + template: `lol iz 72 +rofl lol +lol iz 101 +rofl lol +lol iz 108 +rofl lol +rofl lol +lool iz 111 +rofl lool +loool iz 44 +rofl loool +loool iz 32 +rofl loool +loool iz 119 +rofl loool +rofl lool +lool iz 114 +rofl lool +rofl lol +lol iz 100 +rofl lol +lol iz 33 +rofl lol +lol iz 10 +rofl lol `, }, org: { diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index 251b903..ee2c836 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -119,6 +119,10 @@ rm -rf kotlin-*.zip kotlinc wget -nv https://github.com/EmmyLua/EmmyLua-LanguageServer/releases/download/0.3.6/EmmyLua-LS-all.jar mv EmmyLua-LS-all.jar /usr/lib/EmmyLua-LS.jar +# Omgrofl +mkdir /opt/omgrofl +wget -nv https://github.com/OlegSmelov/omgrofl-interpreter/releases/download/v0.1/Omgrofl.jar -O /opt/omgrofl/Omgrofl.jar + # PowerShell wget -nv https://github.com/PowerShell/PowerShell/releases/download/v7.0.1/powershell-7.0.1-linux-x64.tar.gz mkdir /opt/powershell From 2402e736d3dc4dfc994199702d03562452d0abaa Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 17 Jul 2020 19:45:30 -0600 Subject: [PATCH 142/388] New language: Pikachu --- backend/src/langs.ts | 25 +++++++++++++++++++++++++ scripts/docker-install-phase4.bash | 3 +++ 2 files changed, 28 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 1598ed6..cd41f8c 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1097,6 +1097,31 @@ end. template: ` Date: Fri, 17 Jul 2020 19:45:39 -0600 Subject: [PATCH 143/388] New language: Thue --- backend/src/langs.ts | 9 +++++++++ scripts/docker-install-phase7.bash | 10 ++++++++++ 2 files changed, 19 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index cd41f8c..bd94de1 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1559,6 +1559,15 @@ END compile: "pandoc main.textile -o main.html", run: "prettier --no-config main.html", template: `Hello, world! +`, + }, + thue: { + name: "Thue", + main: "main.thue", + run: "thue main.thue", + template: `a::=~Hello, world! +::= +a `, }, tikiwiki: { diff --git a/scripts/docker-install-phase7.bash b/scripts/docker-install-phase7.bash index d54ef74..ab57fa9 100755 --- a/scripts/docker-install-phase7.bash +++ b/scripts/docker-install-phase7.bash @@ -46,5 +46,15 @@ git clone https://github.com/bipinu/malbolge.git clang malbolge/malbolge.c -o /usr/bin/malbolge rm -rf malbolge +# Thue +wget -nv https://catseye.tc/distfiles/thue-1.5-2015.0827.zip +unzip thue-*.zip +rm thue-*.zip +pushd thue-* >/dev/null +./build.sh +mv bin/thue /usr/bin/thue +popd >/dev/null +rm -rf thue-* + popd >/dev/null rm "$0" From 82197aa2de496f05bb44b19fd4adb664bb3492a9 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 17 Jul 2020 19:45:43 -0600 Subject: [PATCH 144/388] Add ripgrep to image --- scripts/docker-install-phase2.bash | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/docker-install-phase2.bash b/scripts/docker-install-phase2.bash index cc6b4fe..9b8106e 100755 --- a/scripts/docker-install-phase2.bash +++ b/scripts/docker-install-phase2.bash @@ -29,6 +29,7 @@ man-db moreutils nano iputils-ping +ripgrep sudo tmux tree From 2abfbf7bc80363363ee5a66ce9958204b63e5aed Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 17 Jul 2020 20:03:33 -0600 Subject: [PATCH 145/388] New language: Zot --- backend/src/langs.ts | 28 ++++++++++++++++++++++++++++ scripts/docker-install-phase3d.bash | 4 ++++ scripts/docker-install-phase7.bash | 8 ++++++++ 3 files changed, 40 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index bd94de1..384089c 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1700,6 +1700,34 @@ message: compile: "cat main.yaml | yj -yj > main.json", run: "cat main.json | jq .", template: `output: "Hello, world!" +`, + }, + zot: { + name: "Zot", + main: "main.zot", + run: "zot --file main.zot", + template: `111101010100111010101001001101010010010011101010100111010101 +001101010010101010011101010100110101001101010100110101001010 +101001110101010011101010100110101001010101001110101010011010 +100110101010011010100101010100111010101001101010011010101001 +101010011010101001110101010011101010100111010101001110101010 +010011010100100110101001001101010010011010100101010011101010 +100110101001101010100110101001101010100110101001010100111010 +101001110101010011010100101010100111010101001101010011010101 +001101010010101010011101010100110101001101010100111010101001 +101010010101010010101001110101010011010100101010011101010100 +111010101001101010010101010011101010100110101001010100111010 +101001101010010101010010101001101010011101010100110101001101 +010100100101010011010100101010011101010100110101001101010100 +110101001101010100110101001010100111010101001110101010011010 +100101010100111010101001101010011010101001101010010101010011 +101010100110101001101010100111010101001101010010101010010101 +001110101010011010100101010011101010100111010101001101010010 +101010011101010100110101001010100111010101001101010010101010 +010101001101010011101010100110101001101010100100101010011010 +100101010011101010100110101001010100101010001010000100001000 +010011000110110010011101111011011101110000001000011010011110 +11000110110001101101010011000010010 `, }, zsh: { diff --git a/scripts/docker-install-phase3d.bash b/scripts/docker-install-phase3d.bash index 5917be0..1f4a4d2 100755 --- a/scripts/docker-install-phase3d.bash +++ b/scripts/docker-install-phase3d.bash @@ -60,6 +60,10 @@ clang # YAML jq +# Zot +qt5-qmake +qtscript5-dev + # Zsh zsh diff --git a/scripts/docker-install-phase7.bash b/scripts/docker-install-phase7.bash index ab57fa9..eba233c 100755 --- a/scripts/docker-install-phase7.bash +++ b/scripts/docker-install-phase7.bash @@ -56,5 +56,13 @@ mv bin/thue /usr/bin/thue popd >/dev/null rm -rf thue-* +# Zot +git clone https://github.com/manyoso/zot.git +pushd zot >/dev/null +./build.sh +mv build/bin/zot /usr/bin/zot +popd >/dev/null +rm -rf zot + popd >/dev/null rm "$0" From 84b45388a1a66103d36ef6400aaf630ff09cf7ad Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 17 Jul 2020 20:08:32 -0600 Subject: [PATCH 146/388] New language: Hexagony --- backend/src/langs.ts | 14 ++++++++++++++ scripts/docker-install-phase7.bash | 3 +++ 2 files changed, 17 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 384089c..8db7526 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -722,6 +722,20 @@ main = putStrLn "Hello, world!" compile: "cat main.hcl | yj -cj > main.json", run: "cat main.json | jq .", template: `output = "Hello, world!" +`, + }, + hexagony: { + aliases: ["hxg", "hex"], + name: "Hexagony", + main: "main.hxg", + run: "/opt/hexagony/interpreter.rb main.hxg", + template: ` H ; e ; + l ; d ; * + ; r ; o ; w +l ; ; o ; * 4 + 3 3 ; @ . > + ; 2 3 < \\ + 4 ; * / `, }, ink: { diff --git a/scripts/docker-install-phase7.bash b/scripts/docker-install-phase7.bash index eba233c..a6afaff 100755 --- a/scripts/docker-install-phase7.bash +++ b/scripts/docker-install-phase7.bash @@ -24,6 +24,9 @@ mv _build/default/bin/erlang_ls /usr/bin/erlang_ls popd >/dev/null rm -rf erlang_ls +# Hexagony +git clone https://github.com/m-ender/hexagony.git /opt/hexagony + # Kalyn git clone https://github.com/raxod502/kalyn.git pushd kalyn >/dev/null From 3ff5954bd10da9b5f1e6c3239171f58021f694ed Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 17 Jul 2020 21:05:06 -0600 Subject: [PATCH 147/388] New language: ><> --- backend/src/langs.ts | 9 +++++++++ scripts/docker-install-phase5.bash | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 8db7526..ba3f894 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -31,6 +31,15 @@ export interface LangConfig { } export const langs: { [key: string]: LangConfig } = { + "><>": { + aliases: ["esofish"], + name: "><>", + main: "main.fish", + run: "esofish main.fish", + template: `"Hello, world!"r\\ + o;!?l< +`, + }, ada: { aliases: ["adb"], name: "Ada", diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index ee2c836..a933ed7 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -19,6 +19,11 @@ wget -nv https://github.com/jgm/pandoc/releases/download/2.10/pandoc-2.10-linux- tar -xf pandoc-*-linux-amd64.tar.gz -C /usr --strip-components=1 rm pandoc-*-linux-amd64.tar.gz +# ><> +wget -nv https://gist.githubusercontent.com/anonymous/6392418/raw/3b16018cb47f2f9ad1fa085c155cc5c0dc448b2d/fish.py -O /usr/bin/esofish +sed -i 's:^#!.*:#!/usr/bin/env python3:' /usr/bin/esofish +chmod +x /usr/bin/esofish + # Ada wget -nv https://dl.bintray.com/reznikmm/ada-language-server/linux-latest.tar.gz tar -xf linux-latest.tar.gz From fdd08d96f2d7f1f514f260ca60975c2e21b488de Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 17 Jul 2020 21:06:03 -0600 Subject: [PATCH 148/388] Sort languages by display name on index page --- frontend/pages/index.ejs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/pages/index.ejs b/frontend/pages/index.ejs index e32c189..4c4d579 100644 --- a/frontend/pages/index.ejs +++ b/frontend/pages/index.ejs @@ -9,7 +9,8 @@

Riju: fast online playground for every programming language

Pick your favorite language to get started:
- <% for (const [id, {name}] of Object.entries(langs)) { %> + <% for (const [id, {name}] of Object.entries(langs).sort( + ([id1, {name: name1}], [id2, {name: name2}]) => name1.localeCompare(name2))) { %> class="language">
<%= name %> From 5d52dbf122c1105b32a3ed4d551dc40ad5891f09 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 18 Jul 2020 09:41:45 -0600 Subject: [PATCH 149/388] Rename cpp to c++ --- backend/src/langs.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index ba3f894..931d502 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -386,9 +386,9 @@ Refrigerate for 1 hour. template: `Hello, world! `, }, - cpp: { + "c++": { aliases: [ - "c++", + "cpp", "g++", "clang++", "c++98", From e0112a2876e9fcea5918d5ac61fe9c4c50733aa4 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 18 Jul 2020 09:58:30 -0600 Subject: [PATCH 150/388] New language: Redis --- backend/src/langs.ts | 11 +++++++++++ scripts/docker-install-phase3c.bash | 3 +++ 2 files changed, 14 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 931d502..09370e1 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1249,6 +1249,17 @@ main = do compile: "bsc main.re > main.js", run: "NODE_PATH=/usr/lib/node_modules node main.js", template: `print_string("Hello, world!\\n") +`, + }, + redis: { + name: "Redis", + monacoLang: "redis", + repl: + "rm -f socket; (redis-server --port 0 --unixsocket socket &); while [[ ! -e socket ]]; do sleep 0.01; done; redis-cli -s socket", + main: "main.redis", + run: + "rm -f socket; (redis-server --port 0 --unixsocket socket &); while [[ ! -e socket ]]; do sleep 0.01; done; redis-cli -s socket < main.redis; redis-cli -s socket", + template: `ECHO "Hello, world!" `, }, restructuredtext: { diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index 10e16cb..59a5dfd 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -57,6 +57,9 @@ r-base # Racket racket +# Redis +redis + # RISC-V gcc-riscv64-linux-gnu qemu-user-static From 7fba53317af60c6ae1fcf9334040221b54efe5f6 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 18 Jul 2020 10:18:14 -0600 Subject: [PATCH 151/388] Add missing comment --- scripts/docker-install-phase6.bash | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/docker-install-phase6.bash b/scripts/docker-install-phase6.bash index f928069..4efb86b 100755 --- a/scripts/docker-install-phase6.bash +++ b/scripts/docker-install-phase6.bash @@ -5,6 +5,7 @@ set -o pipefail set -x pushd /tmp >/dev/null +# PureScript mkdir project-template pushd project-template >/dev/null spago init -C From 04ec9d11bd3b3875251e8fe68d08339718b104d6 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 18 Jul 2020 11:31:36 -0600 Subject: [PATCH 152/388] Add ncdu, change sudoers config filename --- scripts/docker-install-phase2.bash | 1 + scripts/docker-install-phase8.bash | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/docker-install-phase2.bash b/scripts/docker-install-phase2.bash index 9b8106e..e8fb232 100755 --- a/scripts/docker-install-phase2.bash +++ b/scripts/docker-install-phase2.bash @@ -28,6 +28,7 @@ make man-db moreutils nano +ncdu iputils-ping ripgrep sudo diff --git a/scripts/docker-install-phase8.bash b/scripts/docker-install-phase8.bash index eefee5a..ded5284 100755 --- a/scripts/docker-install-phase8.bash +++ b/scripts/docker-install-phase8.bash @@ -14,8 +14,8 @@ else useradd --password "!" --create-home --groups sudo docker fi -tee /etc/sudoers.d/99-passwordless >/dev/null <<"EOF" -%sudo ALL=(ALL:ALL) NOPASSWD: ALL +tee /etc/sudoers.d/90-passwordless >/dev/null <<"EOF" +%sudo ALL=(ALL:ALL) NOPASSWD: ALL EOF touch /home/docker/.zshrc From 0dd8fbeee26fe8fb5ac84254be4534c17787f0e0 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 18 Jul 2020 11:31:44 -0600 Subject: [PATCH 153/388] Change to single quotes for SQLite --- backend/src/langs.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 09370e1..fb807d9 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1531,7 +1531,7 @@ END repl: "sqlite3", main: "main.sql", run: `sqlite3 -cmd "$(< main.sql)"`, - template: `SELECT "Hello, world!" + template: `SELECT 'Hello, world!'; `, }, standardml: { From db1553b9f99b306a04242c9449983eb43dc52661 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 18 Jul 2020 11:32:01 -0600 Subject: [PATCH 154/388] New language: PostgreSQL --- backend/src/langs.ts | 10 ++++++++++ scripts/docker-install-phase3c.bash | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index fb807d9..935cd51 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1145,6 +1145,16 @@ pikachu pi pi pi pikachu pipi pi pi pikachu pichu pichu pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pikachu pipi pikachu pi pi pi pikachu ka ka ka ka ka ka pikachu ka ka ka ka ka ka ka ka pikachu pipi pi pikachu pipi pikachu +`, + }, + postgresql: { + aliases: ["psql", "postgres", "pgsql", "postgre"], + name: "PostgreSQL", + monacoLang: "pgsql", + repl: `rm -rf data && /usr/lib/postgresql/*/bin/initdb -D data && (echo "listen_addresses = ''" && echo "unix_socket_directories = '.'") >> data/postgresql.conf && /usr/lib/postgresql/*/bin/pg_ctl -D data -w start && psql -h "$PWD/data" postgres`, + main: "main.sql", + run: `rm -rf data && /usr/lib/postgresql/*/bin/initdb -D data && (echo "listen_addresses = ''" && echo "unix_socket_directories = '.'") >> data/postgresql.conf && /usr/lib/postgresql/*/bin/pg_ctl -D data -w start && (psql -h "$PWD/data" postgres -f main.sql; psql -h "$PWD/data" postgres)`, + template: `SELECT 'Hello, world!'; `, }, powershell: { diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index 59a5dfd..63b0347 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -40,6 +40,10 @@ perlconsole # PHP php +# PostgreSQL +postgresql +postgresql-client + # Prolog swi-prolog From fc671226e0633bf980b74a9014e3311a7466f7cf Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 18 Jul 2020 12:31:55 -0600 Subject: [PATCH 155/388] New language: MySQL Good god why do these people make it so hard for me --- backend/src/langs.ts | 9 +++++++++ scripts/docker-install-phase3c.bash | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 935cd51..cea4731 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -979,6 +979,15 @@ message: template: `main() write "Hello, world!",! quit +`, + }, + mysql: { + aliases: ["my"], + name: "MySQL", + repl: `rm -rf data && mysqld -h "$PWD/data" --initialize-insecure && (mysqld -h "$PWD/data" --socket="$PWD/socket" --pid-file="$PWD/pid-file" --mysqlx=OFF --skip-networking &) && while [[ ! -e socket ]]; do sleep 0.01; done && mysql --socket="$PWD/socket" -u root`, + main: "main.sql", + run: `rm -rf data && mysqld -h "$PWD/data" --initialize-insecure && (mysqld -h "$PWD/data" --socket="$PWD/socket" --pid-file="$PWD/pid-file" --mysqlx=OFF --skip-networking &) && while [[ ! -e socket ]]; do sleep 0.01; done && (mysql --socket="$PWD/socket" -u root < main.sql; mysql --socket="$PWD/socket" -u root)`, + template: `SELECT 'Hello, world!' `, }, nim: { diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index 63b0347..cb9e91b 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -13,6 +13,9 @@ qemu-user-static # MUMPS fis-gtm +# MySQL +mysql-server + # Nim nim @@ -79,4 +82,6 @@ apt-get update apt-get install -y $(grep -v "^#" <<< "$packages") rm -rf /var/lib/apt/lists/* +rm /etc/mysql/mysql.conf.d/mysqld.cnf + rm "$0" From 6f7e28c9a4aad302072c4817b404e0911f26403b Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 18 Jul 2020 20:51:22 -0600 Subject: [PATCH 156/388] New language: MariaDB --- backend/src/langs.ts | 9 +++++++++ scripts/docker-install-phase3c.bash | 3 +++ scripts/docker-install-phase5.bash | 8 ++++++++ 3 files changed, 20 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index cea4731..45f3993 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -918,6 +918,15 @@ KTHXBYE template: " (=<`#9]~6ZY32Vx/4Rs+0No-&Jk)\"Fh}|Bcy?`=*z]Kw%oG4UUS0/@-ejc(:'8dc\n", }, + mariadb: { + aliases: ["maria"], + name: "MariaDB", + repl: `rm -rf data && /opt/mariadb/scripts/mariadb-install-db --user="$(id -un)" && (/opt/mariadb/bin/mysqld --datadir="$PWD/data" --socket="$PWD/socket" --skip-networking &) && while [[ ! -e socket ]]; do sleep 0.01; done && mysql --socket="$PWD/socket"`, + main: "main.sql", + run: `rm -rf data && /opt/mariadb/scripts/mariadb-install-db --user="$(id -un)" && (/opt/mariadb/bin/mysqld --datadir="$PWD/data" --socket="$PWD/socket" --skip-networking &) && while [[ ! -e socket ]]; do sleep 0.01; done && (mysql --socket="$PWD/socket" < main.sql; mysql --socket="$PWD/socket")`, + template: `SELECT 'Hello, world!' +`, + }, markdown: { aliases: [ "mdown", diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index cb9e91b..77e6fef 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -6,6 +6,9 @@ set -x packages=" +# MariaDB +libtinfo5 + # MIPS gcc-mips64-linux-gnuabi64 qemu-user-static diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index a933ed7..0d002bf 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -124,6 +124,14 @@ rm -rf kotlin-*.zip kotlinc wget -nv https://github.com/EmmyLua/EmmyLua-LanguageServer/releases/download/0.3.6/EmmyLua-LS-all.jar mv EmmyLua-LS-all.jar /usr/lib/EmmyLua-LS.jar +# MariaDB +wget -nv "https://downloads.mariadb.org/f/mariadb-10.5.4/bintar-linux-x86_64/mariadb-10.5.4-linux-x86_64.tar.gz/from/http%3A//mirror.vpsfree.cz/mariadb/?serve" -O mariadb.tar.gz +tar -xf mariadb.tar.gz +mkdir /opt/mariadb +mv mariadb-*-linux-x86_64/* /opt/mariadb/ +chmod a=rx,u=rwx /opt/mariadb/lib/plugin/auth_pam_tool_dir +chmod a=rx,u=rwxs /opt/mariadb/lib/plugin/auth_pam_tool_dir/auth_pam_tool + # Omgrofl mkdir /opt/omgrofl wget -nv https://github.com/OlegSmelov/omgrofl-interpreter/releases/download/v0.1/Omgrofl.jar -O /opt/omgrofl/Omgrofl.jar From 4befef14137cbdd33f7ea72026eeb92e37a80e96 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 18 Jul 2020 20:54:59 -0600 Subject: [PATCH 157/388] New language: Hy --- backend/src/langs.ts | 8 ++++++++ scripts/docker-install-phase4.bash | 3 +++ 2 files changed, 11 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 45f3993..e8bd032 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -745,6 +745,14 @@ l ; ; o ; * 4 3 3 ; @ . > ; 2 3 < \\ 4 ; * / +`, + }, + hy: { + name: "Hy", + repl: "hy", + main: "main.hy", + run: "hy -i main.hy", + template: `(print "Hello, world!") `, }, ink: { diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index d3c35b9..852b92e 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -55,6 +55,9 @@ npm install -g @elm-tooling/elm-language-server # FORTRAN pip3 install fortran-language-server +# Hy +pip3 install hy + # Julia julia -e 'using Pkg; Pkg.add("LanguageServer")' From e6d625e1ebc7841450c70c7fbe3ceb2972b29784 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 19 Jul 2020 08:49:42 -0600 Subject: [PATCH 158/388] Add 'make docker-nobuild' target --- Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 5ee1504..46715d1 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,10 @@ image-prod: ## Build Docker image for production scripts/docker.bash build . -f Dockerfile.prod -t riju:prod --build-arg "UID=$(UID)" .PHONY: docker -docker: image-dev ## Run shell with source code and deps inside Docker +docker: image-dev docker-nobuild ## Run shell with source code and deps inside Docker + +.PHONY: docker +docker-nobuild: ## Same as 'make docker', but don't rebuild image scripts/docker.bash run -it --rm -v "$(PWD):/home/docker/src" -p 6119:6119 -p 6120:6120 -h riju riju bash .PHONY: deploy From 221f09bb2d3d27ecbc79ea22f5c045a146e5a0be Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 19 Jul 2020 08:49:56 -0600 Subject: [PATCH 159/388] New language: Rapira --- backend/src/langs.ts | 8 ++++++++ scripts/docker-install-phase3c.bash | 3 +++ scripts/docker-install-phase7.bash | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index e8bd032..3723a5d 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1276,6 +1276,14 @@ main = do run: `racket -i -e '(enter! "main.rkt") (display "[ type (enter! \\"main.rkt\\") to access local variables ]\\n")'`, template: `#lang racket/base (display "Hello, world!\\n") +`, + }, + рапира: { + aliases: ["rap", "rerap", "rerap2", "rapira"], + name: "Рапира", + main: "main.rap", + run: "rapira main.rap", + template: `вывод: "Hello, world!" `, }, reasonml: { diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index 77e6fef..aeb3677 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -67,6 +67,9 @@ r-base # Racket racket +# Rapira +clang + # Redis redis diff --git a/scripts/docker-install-phase7.bash b/scripts/docker-install-phase7.bash index a6afaff..a6e21cc 100755 --- a/scripts/docker-install-phase7.bash +++ b/scripts/docker-install-phase7.bash @@ -49,6 +49,14 @@ git clone https://github.com/bipinu/malbolge.git clang malbolge/malbolge.c -o /usr/bin/malbolge rm -rf malbolge +# Rapira +git clone https://github.com/freeduke33/rerap2.git +pushd rerap2 >/dev/null +make +mv rapira /usr/bin/rapira +popd >/dev/null +rm -rf rerap2 + # Thue wget -nv https://catseye.tc/distfiles/thue-1.5-2015.0827.zip unzip thue-*.zip From 76eab72b8105a4d07fa5e411d37f4bf4efabb21b Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 19 Jul 2020 09:39:25 -0600 Subject: [PATCH 160/388] New language: Qalb (and swap phases 6&7) --- backend/src/langs.ts | 9 ++ scripts/docker-install-phase6.bash | 221 ++++++++------------------ scripts/docker-install-phase7.bash | 242 ++++++++++++++++++++++------- 3 files changed, 258 insertions(+), 214 deletions(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 3723a5d..3dde5b7 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1256,6 +1256,15 @@ main = do }, }, template: `print("Hello, world!") +`, + }, + قلب: { + aliases: ["qalb"], + name: "قلب", + repl: "node /opt/qalb/repl.js", + main: "main.qalb", + run: "node /opt/qalb/repl.js main.qalb", + template: `(قول "مرحبا يا عالم") `, }, r: { diff --git a/scripts/docker-install-phase6.bash b/scripts/docker-install-phase6.bash index 4efb86b..765d58d 100755 --- a/scripts/docker-install-phase6.bash +++ b/scripts/docker-install-phase6.bash @@ -5,172 +5,83 @@ set -o pipefail set -x pushd /tmp >/dev/null -# PureScript -mkdir project-template -pushd project-template >/dev/null -spago init -C -rm -rf .gitignore test -sed -i 's#, "test/\*\*/\*\.purs"##' spago.dhall -cat <<"EOF" > src/Main.spago -import Prelude - -import Effect (Effect) - -main :: Effect Unit -main = pure unit -EOF -spago build -spago repl < /dev/null -rm -rf src -popd >/dev/null -mkdir /opt/purescript -mv project-template /opt/purescript/ - -# Befunge -tee /usr/bin/befunge-repl >/dev/null <<"EOF" -#!/usr/bin/env -S NODE_PATH=/usr/lib/node_modules node -const fs = require("fs"); - -const Befunge = require("befunge93"); -const prompt = require("prompt-sync")(); - -const befunge = new Befunge(); -befunge.onInput = prompt; -befunge.onOutput = (output) => { - if (typeof output === "string") { - process.stdout.write(output); - } else { - process.stdout.write(output + " "); - } -}; - -const args = process.argv.slice(2); -if (args.length !== 1) { - console.error("usage: befunge-repl FILE"); - process.exit(1); -} - -befunge.run(fs.readFileSync(args[0], { encoding: "utf-8" })).catch((err) => { - console.error(err); - process.exit(1); -}); -EOF -chmod +x /usr/bin/befunge-repl +# Beatnik +git clone https://github.com/catseye/Beatnik.git +sed -i 's#env python#env python2#' Beatnik/script/beatnik.py +mv Beatnik/script/beatnik.py /usr/bin/beatnik +rm -rf Beatnik # Binary Lambda Calculus -tee /usr/bin/binary-to-text >/dev/null <<"EOF" -#!/usr/bin/env python3 +wget -nv https://www.ioccc.org/2012/tromp/tromp.c +clang tromp.c -Wno-everything -DInt=long -DX=8 -DA=500000 -o /usr/bin/tromp +rm tromp.c -import re -import sys +# Erlang +git clone https://github.com/erlang-ls/erlang_ls.git +pushd erlang_ls >/dev/null +make +mv _build/default/bin/erlang_ls /usr/bin/erlang_ls +popd >/dev/null +rm -rf erlang_ls -text = re.sub(r"[^01]", "", sys.stdin.read()) -out = [] +# Hexagony +git clone https://github.com/m-ender/hexagony.git /opt/hexagony -for m in re.finditer(r"([01]{8})", text): - out += chr(int(m.group(0), 2)) +# Kalyn +git clone https://github.com/raxod502/kalyn.git +pushd kalyn >/dev/null +stack build kalyn +mv "$(stack exec which kalyn)" /usr/bin/kalyn +mkdir /opt/kalyn +cp -R src-kalyn/Stdlib src-kalyn/Stdlib.kalyn /opt/kalyn/ +popd >/dev/null +rm -rf kalyn -print("".join(out), end="") -EOF -chmod +x /usr/bin/binary-to-text +# LOLCODE +git clone https://github.com/justinmeza/lci.git +pushd lci >/dev/null +python3 install.py --prefix=/usr +popd >/dev/null +rm -rf lci -# BrainF -tee /usr/bin/brainf-repl >/dev/null <<"EOF" -#!/usr/bin/env python3 -import argparse -import readline -import subprocess -import tempfile +# Malbolge +git clone https://github.com/bipinu/malbolge.git +clang malbolge/malbolge.c -o /usr/bin/malbolge +rm -rf malbolge -parser = argparse.ArgumentParser() -parser.add_argument("file", nargs="?") -args = parser.parse_args() +# Rapira +git clone https://github.com/freeduke33/rerap2.git +pushd rerap2 >/dev/null +make +mv rapira /usr/bin/rapira +popd >/dev/null +rm -rf rerap2 -if args.file: - subprocess.run(["beef", args.file]) -while True: - try: - code = input("bf> ") - except KeyboardInterrupt: - print("^C") - continue - except EOFError: - print("^D") - break - if not code: - continue - with tempfile.NamedTemporaryFile(mode="w") as f: - f.write(code) - f.flush() - subprocess.run(["beef", f.name]) -EOF -chmod +x /usr/bin/brainf-repl +# Qalb +git clone https://github.com/nasser/---.git qalb +pushd qalb >/dev/null +mkdir -p /opt/qalb +mv public/qlb/*.js /opt/qalb/ +popd >/dev/null +rm -rf qalb -# Elm -mkdir /opt/elm -tee /opt/elm/elm.json >/dev/null <<"EOF" -{ - "type": "application", - "source-directories": [ - "." - ], - "elm-version": "0.19.1", - "dependencies": { - "direct": { - "elm/browser": "1.0.2", - "elm/core": "1.0.5", - "elm/html": "1.0.0" - }, - "indirect": { - "elm/json": "1.1.3", - "elm/time": "1.0.0", - "elm/url": "1.0.0", - "elm/virtual-dom": "1.0.2" - } - }, - "test-dependencies": { - "direct": {}, - "indirect": {} - } -} -EOF +# Thue +wget -nv https://catseye.tc/distfiles/thue-1.5-2015.0827.zip +unzip thue-*.zip +rm thue-*.zip +pushd thue-* >/dev/null +./build.sh +mv bin/thue /usr/bin/thue +popd >/dev/null +rm -rf thue-* -# Haskell -mkdir -p /opt/haskell -tee /opt/haskell/hie.yaml >/dev/null <<"EOF" -cradle: - direct: - arguments: [] -EOF - -# Unlambda -tee /usr/bin/unlambda-repl >/dev/null <<"EOF" -#!/usr/bin/env python3 -import argparse -import readline -import subprocess - -parser = argparse.ArgumentParser() -parser.add_argument("file", nargs="?") -args = parser.parse_args() - -if args.file: - with open(args.file) as f: - subprocess.run(["unlambda"], input=f.read(), encoding="utf-8") -while True: - try: - code = input("λ> ") - except KeyboardInterrupt: - print("^C") - continue - except EOFError: - print("^D") - break - if not code: - continue - subprocess.run(["unlambda"], input=code, encoding="utf-8") -EOF -chmod +x /usr/bin/unlambda-repl +# Zot +git clone https://github.com/manyoso/zot.git +pushd zot >/dev/null +./build.sh +mv build/bin/zot /usr/bin/zot +popd >/dev/null +rm -rf zot popd >/dev/null rm "$0" diff --git a/scripts/docker-install-phase7.bash b/scripts/docker-install-phase7.bash index a6e21cc..ce49026 100755 --- a/scripts/docker-install-phase7.bash +++ b/scripts/docker-install-phase7.bash @@ -5,75 +5,199 @@ set -o pipefail set -x pushd /tmp >/dev/null -# Beatnik -git clone https://github.com/catseye/Beatnik.git -sed -i 's#env python#env python2#' Beatnik/script/beatnik.py -mv Beatnik/script/beatnik.py /usr/bin/beatnik -rm -rf Beatnik +# PureScript +mkdir project-template +pushd project-template >/dev/null +spago init -C +rm -rf .gitignore test +sed -i 's#, "test/\*\*/\*\.purs"##' spago.dhall +cat <<"EOF" > src/Main.spago +import Prelude + +import Effect (Effect) + +main :: Effect Unit +main = pure unit +EOF +spago build +spago repl < /dev/null +rm -rf src +popd >/dev/null +mkdir /opt/purescript +mv project-template /opt/purescript/ + +# Befunge +tee /usr/bin/befunge-repl >/dev/null <<"EOF" +#!/usr/bin/env -S NODE_PATH=/usr/lib/node_modules node +const fs = require("fs"); + +const Befunge = require("befunge93"); +const prompt = require("prompt-sync")(); + +const befunge = new Befunge(); +befunge.onInput = prompt; +befunge.onOutput = (output) => { + if (typeof output === "string") { + process.stdout.write(output); + } else { + process.stdout.write(output + " "); + } +}; + +const args = process.argv.slice(2); +if (args.length !== 1) { + console.error("usage: befunge-repl FILE"); + process.exit(1); +} + +befunge.run(fs.readFileSync(args[0], { encoding: "utf-8" })).catch((err) => { + console.error(err); + process.exit(1); +}); +EOF +chmod +x /usr/bin/befunge-repl # Binary Lambda Calculus -wget -nv https://www.ioccc.org/2012/tromp/tromp.c -clang tromp.c -Wno-everything -DInt=long -DX=8 -DA=500000 -o /usr/bin/tromp -rm tromp.c +tee /usr/bin/binary-to-text >/dev/null <<"EOF" +#!/usr/bin/env python3 -# Erlang -git clone https://github.com/erlang-ls/erlang_ls.git -pushd erlang_ls >/dev/null -make -mv _build/default/bin/erlang_ls /usr/bin/erlang_ls -popd >/dev/null -rm -rf erlang_ls +import re +import sys -# Hexagony -git clone https://github.com/m-ender/hexagony.git /opt/hexagony +text = re.sub(r"[^01]", "", sys.stdin.read()) +out = [] -# Kalyn -git clone https://github.com/raxod502/kalyn.git -pushd kalyn >/dev/null -stack build kalyn -mv "$(stack exec which kalyn)" /usr/bin/kalyn -mkdir /opt/kalyn -cp -R src-kalyn/Stdlib src-kalyn/Stdlib.kalyn /opt/kalyn/ -popd >/dev/null -rm -rf kalyn +for m in re.finditer(r"([01]{8})", text): + out += chr(int(m.group(0), 2)) -# LOLCODE -git clone https://github.com/justinmeza/lci.git -pushd lci >/dev/null -python3 install.py --prefix=/usr -popd >/dev/null -rm -rf lci +print("".join(out), end="") +EOF +chmod +x /usr/bin/binary-to-text -# Malbolge -git clone https://github.com/bipinu/malbolge.git -clang malbolge/malbolge.c -o /usr/bin/malbolge -rm -rf malbolge +# BrainF +tee /usr/bin/brainf-repl >/dev/null <<"EOF" +#!/usr/bin/env python3 +import argparse +import readline +import subprocess +import tempfile -# Rapira -git clone https://github.com/freeduke33/rerap2.git -pushd rerap2 >/dev/null -make -mv rapira /usr/bin/rapira -popd >/dev/null -rm -rf rerap2 +parser = argparse.ArgumentParser() +parser.add_argument("file", nargs="?") +args = parser.parse_args() -# Thue -wget -nv https://catseye.tc/distfiles/thue-1.5-2015.0827.zip -unzip thue-*.zip -rm thue-*.zip -pushd thue-* >/dev/null -./build.sh -mv bin/thue /usr/bin/thue -popd >/dev/null -rm -rf thue-* +if args.file: + subprocess.run(["beef", args.file]) +while True: + try: + code = input("bf> ") + except KeyboardInterrupt: + print("^C") + continue + except EOFError: + print("^D") + break + if not code: + continue + with tempfile.NamedTemporaryFile(mode="w") as f: + f.write(code) + f.flush() + subprocess.run(["beef", f.name]) +EOF +chmod +x /usr/bin/brainf-repl -# Zot -git clone https://github.com/manyoso/zot.git -pushd zot >/dev/null -./build.sh -mv build/bin/zot /usr/bin/zot -popd >/dev/null -rm -rf zot +# Elm +mkdir /opt/elm +tee /opt/elm/elm.json >/dev/null <<"EOF" +{ + "type": "application", + "source-directories": [ + "." + ], + "elm-version": "0.19.1", + "dependencies": { + "direct": { + "elm/browser": "1.0.2", + "elm/core": "1.0.5", + "elm/html": "1.0.0" + }, + "indirect": { + "elm/json": "1.1.3", + "elm/time": "1.0.0", + "elm/url": "1.0.0", + "elm/virtual-dom": "1.0.2" + } + }, + "test-dependencies": { + "direct": {}, + "indirect": {} + } +} +EOF + +# Haskell +mkdir -p /opt/haskell +tee /opt/haskell/hie.yaml >/dev/null <<"EOF" +cradle: + direct: + arguments: [] +EOF + +# Qalb +mkdir -p /opt/qalb +tee /opt/qalb/repl.js >/dev/null <<"EOF" +const fs = require("fs"); +const repl = require("repl"); + +const args = process.argv.slice(2); +if (args.length > 1) { + console.error("usage: repl.js [FILE]"); + process.exit(1); +} + +const program = args.length === 1 ? fs.readFileSync(args[0]) : null; + +eval(fs.readFileSync("public/qlb/qlb.js", "utf-8")); +eval(fs.readFileSync("public/qlb/parser.js", "utf-8")); +eval(fs.readFileSync("public/qlb/primitives.js", "utf-8")); + +Qlb.init({console}); + +if (program !== null) { + Qlb.execute(program); +} + +repl.start({prompt: "قلب> ", eval: (cmd, context, filename, callback) => callback(null, Qlb.execute(cmd))}); +EOF + +# Unlambda +tee /usr/bin/unlambda-repl >/dev/null <<"EOF" +#!/usr/bin/env python3 +import argparse +import readline +import subprocess + +parser = argparse.ArgumentParser() +parser.add_argument("file", nargs="?") +args = parser.parse_args() + +if args.file: + with open(args.file) as f: + subprocess.run(["unlambda"], input=f.read(), encoding="utf-8") +while True: + try: + code = input("λ> ") + except KeyboardInterrupt: + print("^C") + continue + except EOFError: + print("^D") + break + if not code: + continue + subprocess.run(["unlambda"], input=code, encoding="utf-8") +EOF +chmod +x /usr/bin/unlambda-repl popd >/dev/null rm "$0" From 2987af3c33b7f6ff8b050cd0b0e1c9223a7fad40 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 19 Jul 2020 09:53:20 -0600 Subject: [PATCH 161/388] New language: Hack --- backend/src/langs.ts | 11 +++++++++++ scripts/docker-install-phase1.bash | 2 ++ scripts/docker-install-phase3b.bash | 3 +++ 3 files changed, 16 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 3dde5b7..b9df877 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -704,6 +704,17 @@ func main() { main: "main.groovy", run: `JAVA_OPTS="-Djava.util.prefs.systemRoot=$PWD/.java -Djava.util.prefs.userRoot=$PWD/.java/.userPrefs" groovysh main.groovy`, template: `print "Hello, world!"; +`, + }, + hack: { + name: "Hack", + repl: "hhvm -a", + main: "main.hack", + run: "hhvm -a main.hack", + template: `<<__EntryPoint>> +function main(): void { + echo "Hello, world!\\n"; +} `, }, haskell: { diff --git a/scripts/docker-install-phase1.bash b/scripts/docker-install-phase1.bash index f3a13e7..27f8701 100755 --- a/scripts/docker-install-phase1.bash +++ b/scripts/docker-install-phase1.bash @@ -17,6 +17,7 @@ curl -sSL https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - curl -sSL https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - curl -sSL https://keybase.io/crystal/pgp_keys.asc | apt-key add - apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9 +apt-key adv --keyserver keyserver.ubuntu.com --recv-keys B4112585D386EB94 wget -nv https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb dpkg -i packages-microsoft-prod.deb @@ -27,6 +28,7 @@ deb [arch=amd64] https://storage.googleapis.com/download.dartlang.org/linux/debi deb https://cloud.r-project.org/bin/linux/ubuntu focal-cran40/ deb https://deb.nodesource.com/node_14.x focal main deb https://dist.crystal-lang.org/apt crystal main +deb https://dl.hhvm.com/ubuntu focal main deb https://dl.yarnpkg.com/debian/ stable main deb-src https://deb.nodesource.com/node_14.x focal main EOF diff --git a/scripts/docker-install-phase3b.bash b/scripts/docker-install-phase3b.bash index b0cd0df..a9b4e5a 100755 --- a/scripts/docker-install-phase3b.bash +++ b/scripts/docker-install-phase3b.bash @@ -37,6 +37,9 @@ golang # Groovy groovy +# Hack +hhvm + # Haskell cabal-install ghc From e89e530c89da1f3d30153fc533423f09f42092f7 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 19 Jul 2020 10:04:22 -0600 Subject: [PATCH 162/388] New language: Euphoria --- backend/src/langs.ts | 8 ++++++++ scripts/docker-install-phase5.bash | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index b9df877..454b16d 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -612,6 +612,14 @@ output = "Hello, world!" main() -> io:fwrite("Hello, world!\\n"). +`, + }, + euphoria: { + aliases: ["ex", "exw", "exu", "euc", "eui", "eub"], + name: "Euphoria", + main: "main.exu", + run: "eui main.exu", + template: `puts(1, "Hello, world!\\n") `, }, factor: { diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index 0d002bf..482817d 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -70,6 +70,11 @@ wget -nv https://s3.amazonaws.com/rebar3/rebar3 chmod +x rebar3 mv rebar3 /usr/bin/rebar3 +# Euphoria +wget -nv https://sourceforge.net/projects/rapideuphoria/files/Euphoria/4.0.5/euphoria_4.0.5_amd64.deb/download -O euphoria.deb +dpkg -i euphoria.deb +rm euphoria.deb + # Factor wget -nv https://downloads.factorcode.org/releases/0.98/factor-linux-x86-64-0.98.tar.gz tar -xf factor-linux-x86-64-*.tar.gz From c2adccae3b61c0c0221b8c4c16ebb159a42852b4 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 19 Jul 2020 10:13:46 -0600 Subject: [PATCH 163/388] New language: APL --- backend/src/langs.ts | 8 ++++++++ scripts/docker-install-phase3a.bash | 3 +++ scripts/docker-install-phase5.bash | 5 +++++ 3 files changed, 16 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 454b16d..b5a68ec 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -61,6 +61,14 @@ end Main; main: "main.alg", run: "a68g main.alg", template: `print(("Hello, world!",new line)) +`, + }, + apl: { + name: "APL", + repl: "apl", + main: "main.apl", + run: "apl -f main.apl", + template: `'Hello, world!' `, }, arm: { diff --git a/scripts/docker-install-phase3a.bash b/scripts/docker-install-phase3a.bash index c64d750..07a9dfe 100755 --- a/scripts/docker-install-phase3a.bash +++ b/scripts/docker-install-phase3a.bash @@ -12,6 +12,9 @@ gnat # Algol algol68g +# APL +libtinfo5 + # ARM gcc-arm-linux-gnueabihf qemu-user-static diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index 482817d..0c03f2d 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -31,6 +31,11 @@ mv linux/ada_language_server /usr/bin/ada_language_server mv linux/*.so* /usr/lib/x86_64-linux-gnu/ rm -rf linux linux-latest.tar.gz +# APL +wget -nv ftp://ftp.gnu.org/gnu/apl/apl_1.8-1_amd64.deb +dpkg -i apl_*_amd64.deb +rm apl_*_amd64.deb + # Clojure wget -nv https://github.com/snoe/clojure-lsp/releases/download/release-20200629T153107/clojure-lsp chmod +x clojure-lsp From d58c9841a68cc30e29a4cbffe29b24e331f91050 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 19 Jul 2020 10:27:41 -0600 Subject: [PATCH 164/388] New language: Awk --- backend/src/langs.ts | 8 ++++++++ scripts/docker-install-phase3a.bash | 3 +++ 2 files changed, 11 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index b5a68ec..ff52c65 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -110,6 +110,14 @@ message: run: "./main", template: `val _ = print ("Hello, world!\\n") implement main0 () = () +`, + }, + awk: { + aliases: ["gawk", "mawk"], + name: "Awk", + main: "main.awk", + run: `awk -f main.awk`, + template: `BEGIN { print "Hello, world!" } `, }, bash: { diff --git a/scripts/docker-install-phase3a.bash b/scripts/docker-install-phase3a.bash index 07a9dfe..8a46343 100755 --- a/scripts/docker-install-phase3a.bash +++ b/scripts/docker-install-phase3a.bash @@ -25,6 +25,9 @@ asciidoc # ATS ats2-lang +# Awk +mawk + # BASIC bwbasic From db40d25d0c9a5a963c35b67abc443f60f1f23bd5 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 19 Jul 2020 10:44:14 -0600 Subject: [PATCH 165/388] New language: Sed --- backend/src/langs.ts | 8 ++++++++ scripts/docker-install-phase3d.bash | 3 +++ 2 files changed, 11 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index ff52c65..ee75ce5 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1482,6 +1482,14 @@ binding_irb.run(IRB.conf) template: `body:before { content: "Hello, world!"; } +`, + }, + sed: { + aliases: ["gsed"], + name: "Sed", + main: "main.sed", + run: "echo 'Reading from stdin...' >&2; sed -f main.sed", + template: `s/.*/Hello, world!/ `, }, sh: { diff --git a/scripts/docker-install-phase3d.bash b/scripts/docker-install-phase3d.bash index 1f4a4d2..6aa1983 100755 --- a/scripts/docker-install-phase3d.bash +++ b/scripts/docker-install-phase3d.bash @@ -12,6 +12,9 @@ scala # Scheme mit-scheme +# Sed +sed + # Sh posh From 35bd5253ef9b6bf4062a540b5d1316a569187742 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 19 Jul 2020 11:34:44 -0600 Subject: [PATCH 166/388] Sort case insensitively on index page --- frontend/pages/index.ejs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/pages/index.ejs b/frontend/pages/index.ejs index 4c4d579..2c75c0f 100644 --- a/frontend/pages/index.ejs +++ b/frontend/pages/index.ejs @@ -10,7 +10,7 @@ Pick your favorite language to get started:
<% for (const [id, {name}] of Object.entries(langs).sort( - ([id1, {name: name1}], [id2, {name: name2}]) => name1.localeCompare(name2))) { %> + ([id1, {name: name1}], [id2, {name: name2}]) => name1.toLowerCase().localeCompare(name2.toLowerCase()))) { %> class="language">
<%= name %> From 2c66e8b58f19802c1cb4e4928154d61f9a0fd716 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 19 Jul 2020 11:34:55 -0600 Subject: [PATCH 167/388] Take advantage of 'until' --- backend/src/langs.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index ee75ce5..1ece6fe 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -964,9 +964,9 @@ KTHXBYE mariadb: { aliases: ["maria"], name: "MariaDB", - repl: `rm -rf data && /opt/mariadb/scripts/mariadb-install-db --user="$(id -un)" && (/opt/mariadb/bin/mysqld --datadir="$PWD/data" --socket="$PWD/socket" --skip-networking &) && while [[ ! -e socket ]]; do sleep 0.01; done && mysql --socket="$PWD/socket"`, + repl: `rm -rf data && /opt/mariadb/scripts/mariadb-install-db --user="$(id -un)" && (/opt/mariadb/bin/mysqld --datadir="$PWD/data" --socket="$PWD/socket" --skip-networking &) && until [[ -e socket ]]; do sleep 0.01; done && mysql --socket="$PWD/socket"`, main: "main.sql", - run: `rm -rf data && /opt/mariadb/scripts/mariadb-install-db --user="$(id -un)" && (/opt/mariadb/bin/mysqld --datadir="$PWD/data" --socket="$PWD/socket" --skip-networking &) && while [[ ! -e socket ]]; do sleep 0.01; done && (mysql --socket="$PWD/socket" < main.sql; mysql --socket="$PWD/socket")`, + run: `rm -rf data && /opt/mariadb/scripts/mariadb-install-db --user="$(id -un)" && (/opt/mariadb/bin/mysqld --datadir="$PWD/data" --socket="$PWD/socket" --skip-networking &) && until [[ -e socket ]]; do sleep 0.01; done && (mysql --socket="$PWD/socket" < main.sql; mysql --socket="$PWD/socket")`, template: `SELECT 'Hello, world!' `, }, @@ -1036,9 +1036,9 @@ message: mysql: { aliases: ["my"], name: "MySQL", - repl: `rm -rf data && mysqld -h "$PWD/data" --initialize-insecure && (mysqld -h "$PWD/data" --socket="$PWD/socket" --pid-file="$PWD/pid-file" --mysqlx=OFF --skip-networking &) && while [[ ! -e socket ]]; do sleep 0.01; done && mysql --socket="$PWD/socket" -u root`, + repl: `rm -rf data && mysqld -h "$PWD/data" --initialize-insecure && (mysqld -h "$PWD/data" --socket="$PWD/socket" --pid-file="$PWD/pid-file" --mysqlx=OFF --skip-networking &) && until [[ -e socket ]]; do sleep 0.01; done && mysql --socket="$PWD/socket" -u root`, main: "main.sql", - run: `rm -rf data && mysqld -h "$PWD/data" --initialize-insecure && (mysqld -h "$PWD/data" --socket="$PWD/socket" --pid-file="$PWD/pid-file" --mysqlx=OFF --skip-networking &) && while [[ ! -e socket ]]; do sleep 0.01; done && (mysql --socket="$PWD/socket" -u root < main.sql; mysql --socket="$PWD/socket" -u root)`, + run: `rm -rf data && mysqld -h "$PWD/data" --initialize-insecure && (mysqld -h "$PWD/data" --socket="$PWD/socket" --pid-file="$PWD/pid-file" --mysqlx=OFF --skip-networking &) && until [[ -e socket ]]; do sleep 0.01; done && (mysql --socket="$PWD/socket" -u root < main.sql; mysql --socket="$PWD/socket" -u root)`, template: `SELECT 'Hello, world!' `, }, @@ -1343,10 +1343,10 @@ main = do name: "Redis", monacoLang: "redis", repl: - "rm -f socket; (redis-server --port 0 --unixsocket socket &); while [[ ! -e socket ]]; do sleep 0.01; done; redis-cli -s socket", + "rm -f socket; (redis-server --port 0 --unixsocket socket &); until [[ -e socket ]]; do sleep 0.01; done; redis-cli -s socket", main: "main.redis", run: - "rm -f socket; (redis-server --port 0 --unixsocket socket &); while [[ ! -e socket ]]; do sleep 0.01; done; redis-cli -s socket < main.redis; redis-cli -s socket", + "rm -f socket; (redis-server --port 0 --unixsocket socket &); until [[ -e socket ]]; do sleep 0.01; done; redis-cli -s socket < main.redis; redis-cli -s socket", template: `ECHO "Hello, world!" `, }, From fd298cbba7b0dea479f1df68ee108601af7b324c Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 19 Jul 2020 11:35:40 -0600 Subject: [PATCH 168/388] New language: mongoDB --- backend/src/langs.ts | 9 +++++++++ scripts/docker-install-phase3c.bash | 3 +++ 2 files changed, 12 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 1ece6fe..3c2999a 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1020,6 +1020,15 @@ main: .data message: .string "Hello, world!\\n" +`, + }, + mongodb: { + aliases: ["mongo", "mongod"], + name: "MongoDB", + repl: `while ps -u "$(id -un)" -o comm | grep -q mongod; do sleep 0.01; done && rm -rf data && mkdir data && (mongod --dbpath=data --unixSocketPrefix="$PWD" --bind_ip=, &) && until mongo --host "$PWD/mongodb-27017.sock" --eval ' ' &>/dev/null; do sleep 0.01; done && mongo --host "$PWD/mongodb-27017.sock"`, + main: "main.js", + run: `while ps -u "$(id -un)" -o comm | grep -q mongod; do sleep 0.01; done && rm -rf data && mkdir data && (mongod --dbpath=data --unixSocketPrefix="$PWD" --bind_ip=, &) && until mongo --host "$PWD/mongodb-27017.sock" --eval ' ' &>/dev/null; do sleep 0.01; done && mongo --host "$PWD/mongodb-27017.sock" --shell main.js`, + template: `print("Hello, world!") `, }, mumps: { diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index aeb3677..0633966 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -13,6 +13,9 @@ libtinfo5 gcc-mips64-linux-gnuabi64 qemu-user-static +# MongoDB +mongodb + # MUMPS fis-gtm From 382abe9f6d50fdea277db888d273ba1366d18bde Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 19 Jul 2020 11:46:34 -0600 Subject: [PATCH 169/388] Add some more environment variables --- backend/src/api.ts | 2 +- backend/src/sandbox.ts | 2 +- backend/src/util.ts | 12 ++++++++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/backend/src/api.ts b/backend/src/api.ts index 845fffe..292b9b4 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -57,7 +57,7 @@ export class Session { } get env() { - return util.getEnv(this.uuid); + return util.getEnv(this.context); } log = (msg: string) => console.log(`[${this.uuid}] ${msg}`); diff --git a/backend/src/sandbox.ts b/backend/src/sandbox.ts index a2774f4..f987a52 100644 --- a/backend/src/sandbox.ts +++ b/backend/src/sandbox.ts @@ -44,7 +44,7 @@ async function main() { await run(privilegedSetup({ uid, uuid }), log); const args = privilegedSpawn({ uid, uuid }, ["bash"]); const proc = spawn(args[0], args.slice(1), { - env: getEnv(uuid), + env: getEnv({ uid, uuid }), stdio: "inherit", }); await new Promise((resolve, reject) => { diff --git a/backend/src/util.ts b/backend/src/util.ts index 808ca8c..8178696 100644 --- a/backend/src/util.ts +++ b/backend/src/util.ts @@ -1,8 +1,11 @@ import { spawn, SpawnOptions } from "child_process"; +import * as os from "os"; import * as process from "process"; import * as appRoot from "app-root-path"; +import { MIN_UID, MAX_UID } from "./users"; + export interface Options extends SpawnOptions { input?: string; check?: boolean; @@ -17,7 +20,7 @@ export const rijuSystemPrivileged = appRoot.resolve( "system/out/riju-system-privileged" ); -export function getEnv(uuid: string) { +export function getEnv({ uid, uuid }: Context) { const cwd = `/tmp/riju/${uuid}`; const path = [ `${cwd}/.gem/ruby/2.7.0/bin`, @@ -29,15 +32,20 @@ export function getEnv(uuid: string) { `/usr/bin`, `/bin`, ]; + const username = + uid >= MIN_UID && uid < MAX_UID ? `riju${uid}` : os.userInfo().username; return { HOME: cwd, HOSTNAME: "riju", LANG: process.env.LANG || "", LC_ALL: process.env.LC_ALL || "", + LOGNAME: username, PATH: path.join(":"), PWD: cwd, SHELL: "/usr/bin/bash", - TERM: "xterm-color", + TERM: "xterm-256color", + USER: username, + USERNAME: username, }; } From f0102d89fd322680df39e2e1706e83ae9ee75d74 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 19 Jul 2020 12:29:42 -0600 Subject: [PATCH 170/388] Set TMPDIR as well --- backend/src/api.ts | 13 +++---------- backend/src/sandbox.ts | 2 -- backend/src/util.ts | 24 +++++++++++++++++++++--- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/backend/src/api.ts b/backend/src/api.ts index 292b9b4..bde47ef 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -56,10 +56,6 @@ export class Session { return { uid: this.uid, uuid: this.uuid }; } - get env() { - return util.getEnv(this.context); - } - log = (msg: string) => console.log(`[${this.uuid}] ${msg}`); constructor(ws: WebSocket, lang: string) { @@ -93,9 +89,7 @@ export class Session { await this.runCode(); if (this.config.daemon) { const daemonArgs = this.privilegedSpawn(bash(this.config.daemon)); - const daemonProc = spawn(daemonArgs[0], daemonArgs.slice(1), { - env: this.env, - }); + const daemonProc = spawn(daemonArgs[0], daemonArgs.slice(1)); this.daemon = { proc: daemonProc, }; @@ -128,7 +122,7 @@ export class Session { await this.run(this.privilegedSpawn(bash(this.config.lspSetup))); } const lspArgs = this.privilegedSpawn(bash(this.config.lsp)); - const lspProc = spawn(lspArgs[0], lspArgs.slice(1), { env: this.env }); + const lspProc = spawn(lspArgs[0], lspArgs.slice(1)); this.lsp = { proc: lspProc, reader: new rpc.StreamMessageReader(lspProc.stdout), @@ -270,7 +264,7 @@ export class Session { const args = this.privilegedSpawn( bash(`kill -SIGTERM ${pid}; sleep 3; kill -SIGKILL ${pid}`) ); - spawn(args[0], args.slice(1), { env: this.env }); + spawn(args[0], args.slice(1)); // Signal to terminalOutput message generator using closure. this.term.live = false; this.term = null; @@ -326,7 +320,6 @@ export class Session { const term = { pty: pty.spawn(termArgs[0], termArgs.slice(1), { name: "xterm-color", - env: this.env, }), live: true, }; diff --git a/backend/src/sandbox.ts b/backend/src/sandbox.ts index f987a52..f47ecf7 100644 --- a/backend/src/sandbox.ts +++ b/backend/src/sandbox.ts @@ -6,7 +6,6 @@ import { v4 as getUUID } from "uuid"; import { langs } from "./langs"; import { MIN_UID, MAX_UID, borrowUser, ignoreUsers } from "./users"; import { - getEnv, privilegedSetup, privilegedSpawn, privilegedTeardown, @@ -44,7 +43,6 @@ async function main() { await run(privilegedSetup({ uid, uuid }), log); const args = privilegedSpawn({ uid, uuid }, ["bash"]); const proc = spawn(args[0], args.slice(1), { - env: getEnv({ uid, uuid }), stdio: "inherit", }); await new Promise((resolve, reject) => { diff --git a/backend/src/util.ts b/backend/src/util.ts index 8178696..cdefaf1 100644 --- a/backend/src/util.ts +++ b/backend/src/util.ts @@ -3,6 +3,7 @@ import * as os from "os"; import * as process from "process"; import * as appRoot from "app-root-path"; +import { quote } from "shell-quote"; import { MIN_UID, MAX_UID } from "./users"; @@ -20,7 +21,7 @@ export const rijuSystemPrivileged = appRoot.resolve( "system/out/riju-system-privileged" ); -export function getEnv({ uid, uuid }: Context) { +function getEnv({ uid, uuid }: Context) { const cwd = `/tmp/riju/${uuid}`; const path = [ `${cwd}/.gem/ruby/2.7.0/bin`, @@ -44,11 +45,18 @@ export function getEnv({ uid, uuid }: Context) { PWD: cwd, SHELL: "/usr/bin/bash", TERM: "xterm-256color", + TMPDIR: `${cwd}`, USER: username, USERNAME: username, }; } +function getEnvString(ctx: Context) { + return Object.entries(getEnv(ctx)) + .map(([key, val]) => `${key}=${quote([val])}`) + .join(" "); +} + export async function run( args: string[], log: (msg: string) => void, @@ -94,8 +102,18 @@ export function privilegedSetup({ uid, uuid }: Context) { return [rijuSystemPrivileged, "setup", `${uid}`, uuid]; } -export function privilegedSpawn({ uid, uuid }: Context, args: string[]) { - return [rijuSystemPrivileged, "spawn", `${uid}`, uuid].concat(args); +export function privilegedSpawn(ctx: Context, args: string[]) { + const { uid, uuid } = ctx; + return [ + rijuSystemPrivileged, + "spawn", + `${uid}`, + uuid, + "bash", + "-c", + `exec env -i ${getEnvString(ctx)} "$@"`, + "--", + ].concat(args); } export function privilegedTeardown({ uid, uuid }: Context) { From 964e143964dfcb5f6f4b305e776fc3f84b5f2a79 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 19 Jul 2020 12:57:09 -0600 Subject: [PATCH 171/388] New language: Emojicode --- backend/src/langs.ts | 11 +++++++++++ scripts/docker-install-phase5.bash | 12 ++++++++++++ 2 files changed, 23 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 3c2999a..da4936c 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -602,6 +602,17 @@ output = "Hello, world!" all: `set -o pipefail; (curl -sS https://elpa.gnu.org/packages/ | grep '' | grep -Eo '[^>]+' | grep -Eo '^[^<]+' && curl -sS https://melpa.org/archive.json | jq -r 'keys | .[]') | sort | uniq`, }, template: `(message "Hello, world!") +`, + }, + emojicode: { + aliases: ["emoji", "emojic", "emojicodec"], + name: "Emojicode", + main: "main.emojic", + compile: "emojicodec main.emojic", + run: "./main", + template: `🏁 🍇 + 😀 🔤Hello, world!🔤❗️ +🍉 `, }, entropy: { diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index 0c03f2d..5eead77 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -65,6 +65,18 @@ gunzip binary-for-linux-64-bit.gz chmod +x binary-for-linux-64-bit mv binary-for-linux-64-bit /usr/bin/elm +# Emojicode +wget -nv https://github.com/emojicode/emojicode/releases/download/v1.0-beta.2/Emojicode-1.0-beta.2-Linux-x86_64.tar.gz +tar -xf Emojicode-*-Linux-x86_64.tar.gz +pushd Emojicode-*-Linux-x86_64 >/dev/null +mv emojicodec /usr/local/bin/ +mkdir -p /usr/local/include/emojicode +mv include/* /usr/local/include/emojicode/ +mkdir -p /usr/local/EmojicodePackages +mv packages/* /usr/local/EmojicodePackages/ +popd >/dev/null +rm -rf Emojicode-*-Linux-x86_64 Emojicode-*-Linux-x86_64.tar.gz + # Entropy wget -nv http://danieltemkin.com/Content/Entropy/Entropy.zip unzip -d /opt/entropy Entropy.zip From 7716ea6af842cd1fa7a63e21a0b2817bda13133f Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 19 Jul 2020 13:01:57 -0600 Subject: [PATCH 172/388] New language: Haxe --- backend/src/langs.ts | 13 +++++++++++++ scripts/docker-install-phase3b.bash | 3 +++ 2 files changed, 16 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index da4936c..09e5d60 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -770,6 +770,19 @@ main = putStrLn "Hello, world!" `, hacks: ["ghci-config"], }, + haxe: { + aliases: ["hx"], + name: "Haxe", + main: "Main.hx", + compile: "haxe --main Main --js Main.js", + run: "node Main.js", + template: `class Main { + static public function main() { + trace("Hello, world!"); + } +} +`, + }, hcl: { aliases: ["tf", "terraform", "hashicorp", "hc"], name: "HCL", diff --git a/scripts/docker-install-phase3b.bash b/scripts/docker-install-phase3b.bash index a9b4e5a..e795213 100755 --- a/scripts/docker-install-phase3b.bash +++ b/scripts/docker-install-phase3b.bash @@ -44,6 +44,9 @@ hhvm cabal-install ghc +# Haxe +haxe + # INTERCAL intercal From a6756f240a1562e95644f2383b79536d5996b9cc Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 19 Jul 2020 13:10:03 -0600 Subject: [PATCH 173/388] New language: Ioke --- backend/src/langs.ts | 9 +++++++++ scripts/docker-install-phase5.bash | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 09e5d60..ee71b81 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -850,6 +850,15 @@ PLEASE DO ,1 SUB #13 <- #162 DO ,1 SUB #14 <- #52 PLEASE READ OUT ,1 PLEASE GIVE UP +`, + }, + ioke: { + aliases: ["ik"], + name: "Ioke", + repl: "ioke", + main: "main.ik", + run: "ioke main.ik; ioke", + template: `"Hello, world!" println `, }, java: { diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index 5eead77..c1eaca2 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -135,6 +135,12 @@ mv ink-linux /usr/bin/ink mkdir /opt/ink mv std.ink str.ink /opt/ink/ +# Ioke +wget -nv https://ioke.org/dist/ioke-P-ikj-0.4.0.tar.gz +tar -xf ioke-P-ikj-*.tar.gz -C /opt +rm ioke-P-ikj-*.tar.gz +ln -s /opt/ioke/bin/ioke /usr/bin/ioke + # Kotlin wget -nv https://github.com/JetBrains/kotlin/releases/download/v1.3.72/kotlin-compiler-1.3.72.zip unzip kotlin-*.zip From c33ab4996e98f9ad61da4b1a774087e91434afb4 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 19 Jul 2020 13:39:18 -0600 Subject: [PATCH 174/388] New language: Kitten --- backend/src/langs.ts | 9 +++++++++ scripts/docker-install-phase5.bash | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index ee71b81..919b4c9 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -895,6 +895,15 @@ PLEASE GIVE UP (public def main (IO Empty) (print "Hello, world!\\n")) +`, + }, + kitten: { + aliases: ["ktn"], + name: "Kitten", + repl: "kitten", + main: "main.ktn", + run: "kitten main.ktn; kitten", + template: `"Hello, world!" say `, }, kotlin: { diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index c1eaca2..be690bd 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -141,6 +141,11 @@ tar -xf ioke-P-ikj-*.tar.gz -C /opt rm ioke-P-ikj-*.tar.gz ln -s /opt/ioke/bin/ioke /usr/bin/ioke +# Kitten +wget -nv "https://drive.google.com/uc?export=download&id=11u0G2I8i0u4ez27zvEjAT6E9xF4RwuFZ" -O /usr/local/bin/kitten +wget -nv "https://drive.google.com/uc?export=download&id=1h-U1iURWax8h18kTD1AyGS21UblEIT9K" -O /usr/local/bin/common.ktn +chmod +x /usr/local/bin/kitten + # Kotlin wget -nv https://github.com/JetBrains/kotlin/releases/download/v1.3.72/kotlin-compiler-1.3.72.zip unzip kotlin-*.zip From 26ef2dd9ff26a845d982e73e79b77349b1a22439 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 19 Jul 2020 13:43:53 -0600 Subject: [PATCH 175/388] New language: SETL --- backend/src/langs.ts | 7 +++++++ scripts/docker-install-phase5.bash | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 919b4c9..e70451e 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1541,6 +1541,13 @@ binding_irb.run(IRB.conf) main: "main.sed", run: "echo 'Reading from stdin...' >&2; sed -f main.sed", template: `s/.*/Hello, world!/ +`, + }, + setl: { + name: "SETL", + main: "main.setl", + run: "setl main.setl", + template: `print("Hello, world!"); `, }, sh: { diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index be690bd..4d2c780 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -199,6 +199,10 @@ metals -version Date: Sun, 19 Jul 2020 14:15:53 -0600 Subject: [PATCH 176/388] New language: Ceylon --- backend/src/langs.ts | 9 +++++++++ scripts/docker-install-phase3a.bash | 3 +++ scripts/docker-install-phase5.bash | 5 +++++ 3 files changed, 17 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index e70451e..8d92728 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -309,6 +309,15 @@ int main() { printf("Hello, world!\\n"); return 0; } +`, + }, + ceylon: { + name: "Ceylon", + main: "source/main.ceylon", + run: `PATH="/usr/lib/jvm/java-8-openjdk-amd64/bin:$PATH" ceylon run --compile=force default`, + template: `shared void run() { + print("Hello, world!"); +} `, }, chef: { diff --git a/scripts/docker-install-phase3a.bash b/scripts/docker-install-phase3a.bash index 8a46343..03d0e47 100755 --- a/scripts/docker-install-phase3a.bash +++ b/scripts/docker-install-phase3a.bash @@ -44,6 +44,9 @@ clangd # C# mono-mcs +# Ceylon +openjdk-8-jdk-headless + # Clojure clojure diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index 4d2c780..5baf9ad 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -36,6 +36,11 @@ wget -nv ftp://ftp.gnu.org/gnu/apl/apl_1.8-1_amd64.deb dpkg -i apl_*_amd64.deb rm apl_*_amd64.deb +# Ceylon +wget -nv https://ceylon-lang.org/download/dist/1_3_3_deb -O ceylon.deb +dpkg -i ceylon.deb +rm ceylon.deb + # Clojure wget -nv https://github.com/snoe/clojure-lsp/releases/download/release-20200629T153107/clojure-lsp chmod +x clojure-lsp From 55932fb28a58de00f00519c906fb477ad00ffc7a Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 19 Jul 2020 14:21:38 -0600 Subject: [PATCH 177/388] Reduce CPU usage from TypeScript compiler --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c75e371..cbe3bd9 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ }, "scripts": { "backend": "tsc", - "backend-dev": "tsc --watch --preserveWatchOutput", + "backend-dev": "TSC_NONPOLLING_WATCHER=1 tsc --watch --preserveWatchOutput", "frontend": "webpack --production", "frontend-dev": "webpack --development --watch", "server": "scripts/setup.bash && node backend/out/server.js", From 87ef0c56ee7c49dc4b180fd71ce236480444ae51 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 19 Jul 2020 17:08:08 -0600 Subject: [PATCH 178/388] Fix API error logging --- backend/src/api.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/api.ts b/backend/src/api.ts index bde47ef..c0fcf50 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -190,7 +190,7 @@ export class Session { }; logBadMessage = (msg: any) => { - this.log(`Got malformed message from client: ${msg}`); + this.log(`Got malformed message from client: ${JSON.stringify(msg)}`); }; receive = async (event: string) => { @@ -202,7 +202,7 @@ export class Session { try { msg = JSON.parse(event); } catch (err) { - this.log(`Failed to parse message from client: ${msg}`); + this.log(`Failed to parse message from client: ${event}`); return; } switch (msg && msg.event) { From 3fd5bd32d862cc715a9e0c3ae893425263f36868 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 19 Jul 2020 17:35:05 -0600 Subject: [PATCH 179/388] Remove needless arguments from Docker scripts --- Dockerfile.dev | 4 ++-- Dockerfile.prod | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile.dev b/Dockerfile.dev index 8210b26..5b9583b 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -32,10 +32,10 @@ COPY scripts/docker-install-phase5.bash /tmp/ RUN /tmp/docker-install-phase5.bash COPY scripts/docker-install-phase6.bash /tmp/ -RUN /tmp/docker-install-phase6.bash "$UID" +RUN /tmp/docker-install-phase6.bash COPY scripts/docker-install-phase7.bash /tmp/ -RUN /tmp/docker-install-phase7.bash "$UID" +RUN /tmp/docker-install-phase7.bash COPY scripts/docker-install-phase8.bash /tmp/ RUN /tmp/docker-install-phase8.bash "$UID" diff --git a/Dockerfile.prod b/Dockerfile.prod index 83629f0..e8dd95d 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -37,7 +37,7 @@ COPY scripts/docker-install-phase6.bash /tmp/ RUN /tmp/docker-install-phase6.bash COPY scripts/docker-install-phase7.bash /tmp/ -RUN /tmp/docker-install-phase7.bash "$UID" +RUN /tmp/docker-install-phase7.bash COPY scripts/docker-install-phase8.bash /tmp/ RUN /tmp/docker-install-phase8.bash "$UID" From 68bb853fa043090d5d35c4c336cbb526f28603e4 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 19 Jul 2020 17:40:54 -0600 Subject: [PATCH 180/388] Add code formatting button, Python/Haskell support --- backend/src/api.ts | 88 +++++++++++++++++++++++++----- backend/src/langs.ts | 10 ++-- frontend/pages/app.ejs | 1 + frontend/src/app.ts | 24 +++++++- frontend/styles/app.css | 11 ++++ scripts/docker-install-phase4.bash | 3 + scripts/docker-install-phase5.bash | 3 + 7 files changed, 119 insertions(+), 21 deletions(-) diff --git a/backend/src/api.ts b/backend/src/api.ts index c0fcf50..9131634 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -35,6 +35,12 @@ export class Session { writer: rpc.StreamMessageWriter; } | null = null; daemon: { proc: ChildProcess } | null = null; + formatter: { + proc: ChildProcess; + live: boolean; + input: string; + output: string; + } | null = null; get homedir() { return `/tmp/riju/${this.uuid}`; @@ -224,6 +230,13 @@ export class Session { } await this.runCode(msg.code); break; + case "formatCode": + if (typeof msg.code !== "string") { + this.logBadMessage(msg); + break; + } + await this.formatCode(msg.code); + break; case "lspInput": if (typeof msg.input !== "object" || !msg) { this.logBadMessage(msg); @@ -257,12 +270,11 @@ export class Session { compile, run, template, - hacks, } = this.config; if (this.term) { const pid = this.term.pty.pid; const args = this.privilegedSpawn( - bash(`kill -SIGTERM ${pid}; sleep 3; kill -SIGKILL ${pid}`) + bash(`kill -SIGTERM ${pid}; sleep 1; kill -SIGKILL ${pid}`) ); spawn(args[0], args.slice(1)); // Signal to terminalOutput message generator using closure. @@ -304,18 +316,6 @@ export class Session { ]), { input: code } ); - if (hacks && hacks.includes("ghci-config") && run) { - if (code) { - await this.run( - this.privilegedSpawn(["sh", "-c", `cat > ${this.homedir}/.ghci`]), - { input: ":load Main\nmain\n" } - ); - } else { - await this.run( - this.privilegedSpawn(["rm", "-f", `${this.homedir}/.ghci`]) - ); - } - } const termArgs = this.privilegedSpawn(bash(cmdline)); const term = { pty: pty.spawn(termArgs[0], termArgs.slice(1), { @@ -338,6 +338,66 @@ export class Session { } }; + formatCode = async (code: string) => { + if (!this.config.format) { + this.log("formatCode ignored because format is null"); + return; + } + if (this.formatter) { + const pid = this.formatter.proc.pid; + const args = this.privilegedSpawn( + bash(`kill -SIGTERM ${pid}; sleep 1; kill -SIGKILL ${pid}`) + ); + spawn(args[0], args.slice(1)); + this.formatter.live = false; + this.formatter = null; + } + const args = this.privilegedSpawn(bash(this.config.format)); + const formatter = { + proc: spawn(args[0], args.slice(1)), + live: true, + input: code, + output: "", + }; + formatter.proc.stdout!.on("data", (data) => { + if (formatter.live) { + formatter.output += data.toString("utf8"); + } + }); + formatter.proc.stderr!.on("data", (data) => { + if (formatter.live) { + this.send({ + event: "serviceLog", + service: "formatter", + output: data.toString("utf8"), + }); + } + }); + formatter.proc.on("exit", (code, signal) => { + if (code === 0) { + this.send({ + event: "formattedCode", + code: formatter.output, + originalCode: formatter.input, + }); + } else { + this.send({ + event: "serviceFailed", + service: "formatter", + error: `Exited with status ${signal || code}`, + }); + } + }); + formatter.proc.on("error", (err) => + this.send({ + event: "serviceFailed", + service: "formatter", + error: `${err}`, + }) + ); + this.formatter = formatter; + }; + teardown = async () => { try { if (this.tearingDown) { diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 8d92728..e2a41c6 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -11,6 +11,7 @@ export interface LangConfig { createEmpty?: string; compile?: string; run: string; + format?: string; pkg?: { install: string; uninstall?: string; @@ -24,7 +25,6 @@ export interface LangConfig { lspConfig?: any; lspLang?: string; template: string; - hacks?: "ghci-config"[]; test?: { ensure?: string; }; @@ -764,9 +764,10 @@ function main(): void { haskell: { aliases: ["ghc", "ghci", "hs"], name: "Haskell", - repl: "ghci", + repl: "rm -f .ghci && ghci", main: "Main.hs", - run: "ghci", + run: "(echo ':load Main' && echo 'main') > .ghci && ghci", + format: "brittany Main.hs", lspSetup: "cp /opt/haskell/hie.yaml hie.yaml", lsp: "HIE_HOOGLE_DATABASE=/opt/haskell/hoogle.hoo hie --lsp", lspInit: { @@ -1337,6 +1338,7 @@ main = do repl: "python3 -u", main: "main.py", run: "python3 -u -i main.py", + format: "cat main.py | black -", pkg: { install: "pip3 install --user NAME", uninstall: "pip3 uninstall NAME", @@ -1350,7 +1352,7 @@ main = do }, }, }, - template: `print("Hello, world!") + template: `print('Hello, world!') `, }, قلب: { diff --git a/frontend/pages/app.ejs b/frontend/pages/app.ejs index bc2e09a..c6b046e 100644 --- a/frontend/pages/app.ejs +++ b/frontend/pages/app.ejs @@ -16,6 +16,7 @@
+ Switch to a different language
+ <% if (analyticsEnabled) { %> + + <% } %> diff --git a/frontend/pages/index.ejs b/frontend/pages/index.ejs index 2c75c0f..59d2ff2 100644 --- a/frontend/pages/index.ejs +++ b/frontend/pages/index.ejs @@ -26,5 +26,8 @@ on GitHub.

+ <% if (analyticsEnabled) { %> + + <% } %> diff --git a/scripts/riju-serve.bash b/scripts/riju-serve.bash index 123fbbf..2c45189 100755 --- a/scripts/riju-serve.bash +++ b/scripts/riju-serve.bash @@ -6,10 +6,11 @@ set -o pipefail TLS=1 TLS_PRIVATE_KEY="$(base64 /etc/letsencrypt/live/riju.codes/privkey.pem)" TLS_CERTIFICATE="$(base64 /etc/letsencrypt/live/riju.codes/fullchain.pem)" +ANALYTICS=1 # Do this separately so that errors in command substitution will crash # the script. -export TLS TLS_PRIVATE_KEY TLS_CERTIFICATE +export TLS TLS_PRIVATE_KEY TLS_CERTIFICATE ANALYTICS if [[ -t 1 ]]; then it=-it @@ -17,5 +18,5 @@ else it= fi -docker run ${it} -e TLS -e TLS_PRIVATE_KEY -e TLS_CERTIFICATE \ +docker run ${it} -e TLS -e TLS_PRIVATE_KEY -e TLS_CERTIFICATE -e ANALYTICS \ --rm -p 0.0.0.0:80:6119 -p 0.0.0.0:443:6120 -h riju riju:prod From df9fb8b86a9ea9bf57e19d092d776e4ce7409297 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 12:03:11 -0600 Subject: [PATCH 225/388] Pull latest ubuntu:rolling in CI --- scripts/deploy-phase2.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/deploy-phase2.py b/scripts/deploy-phase2.py index c3ffcb2..8489fbb 100755 --- a/scripts/deploy-phase2.py +++ b/scripts/deploy-phase2.py @@ -10,6 +10,7 @@ import sys import tempfile import time +subprocess.run(["docker", "pull", "ubuntu:rolling"], check=True) subprocess.run(["docker", "system", "prune", "-f"], check=True) subprocess.run(["make", "image-prod"], check=True) existing_containers = subprocess.run( From deb2c9b320bae540dfe475f229fe6cac6641478f Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 12:07:15 -0600 Subject: [PATCH 226/388] Workaround really obnoxious APT bug --- scripts/docker-install-phase3b.bash | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/docker-install-phase3b.bash b/scripts/docker-install-phase3b.bash index 97191f8..123e5ec 100755 --- a/scripts/docker-install-phase3b.bash +++ b/scripts/docker-install-phase3b.bash @@ -23,6 +23,7 @@ emacs-nox # Erlang erlang +libodbc1 # workaround bug in APT rebar # F# @@ -77,7 +78,7 @@ ${lua_name} " -apt-get install -y $(grep -v "^#" <<< "$packages") +apt-get install -y $(sed 's/#.*//' <<< "$packages") rm -rf /var/lib/apt/lists/* rm "$0" From 67fe68c6d2aa39ab06dda1e358a8b32b2a593542 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 22 Aug 2020 18:08:06 +0000 Subject: [PATCH 227/388] Bump elliptic from 6.5.2 to 6.5.3 Bumps [elliptic](https://github.com/indutny/elliptic) from 6.5.2 to 6.5.3. - [Release notes](https://github.com/indutny/elliptic/releases) - [Commits](https://github.com/indutny/elliptic/compare/v6.5.2...v6.5.3) Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 4d74e64..045d049 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1969,9 +1969,9 @@ electron-to-chromium@^1.3.413: integrity sha512-q2PeCP2PQXSYadDo9uNY+uHXjdB9PcsUpCVoGlY8TZOPHGlXdevlqW9PkKeqCxn2QBkGB8b6AcMO++gh8X82bA== elliptic@^6.0.0, elliptic@^6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" - integrity sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw== + version "6.5.3" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6" + integrity sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw== dependencies: bn.js "^4.4.0" brorand "^1.0.1" From f1fb3e3f1aae94f7fda205f9d68a76bcddd3ac71 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 12:17:46 -0600 Subject: [PATCH 228/388] Fix liblua name computation --- scripts/docker-install-phase3d.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/docker-install-phase3d.bash b/scripts/docker-install-phase3d.bash index 01f3dec..5e3fa91 100755 --- a/scripts/docker-install-phase3d.bash +++ b/scripts/docker-install-phase3d.bash @@ -8,7 +8,7 @@ export DEBIAN_FRONTEND=noninteractive apt-get update lua_ver="$(grep-aptavail -XF Provides lua -s Version -n | sort -Vr | head -n1)" -liblua_name="$(grep-aptavail -eF Package "liblua[0-9.]+-dev" -a -XF Version "${lua_ver}" -s Package | head -n1)" +liblua_name="$(grep-aptavail -eF Package "liblua[0-9.]+-dev" -a -XF Version "${lua_ver}" -s Package -n | head -n1)" packages=" From cb3682c2fc3531c8bd4557b7fd823694a8a0291c Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 12:19:56 -0600 Subject: [PATCH 229/388] Fix variable substitution in watchexec download --- scripts/docker-install-phase4.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index a1def92..330ddfd 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -11,7 +11,7 @@ latest_release() { # Needed for project infrastructure ver="$(latest_release watchexec/watchexec)" -wget -nv "https://github.com/watchexec/watchexec/releases/download/${rel}/watchexec-${ver}-x86_64-unknown-linux-gnu.deb" +wget -nv "https://github.com/watchexec/watchexec/releases/download/${ver}/watchexec-${ver}-x86_64-unknown-linux-gnu.deb" dpkg -i watchexec-*.deb rm watchexec-*.deb From 81f69f074813a30ba901dafcbb86ff8dade3321d Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 12:27:29 -0600 Subject: [PATCH 230/388] Un-rolling-release Euphoria --- scripts/docker-install-phase4.bash | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 330ddfd..c23f2d8 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -101,7 +101,10 @@ chmod +x rebar3 mv rebar3 /usr/local/bin/rebar3 # Euphoria -wget -nv "$(curl -sSL https://sourceforge.net/projects/rapideuphoria/best_release.json | jq -r '.platform_releases.linux.url')" -O euphoria.deb +# It's not possible to rolling-release because they don't upload a +# consistent set of files for every version. In particular there's no +# .deb file for 4.1.0. Besides, the latest release was in 2014. +wget -nv https://sourceforge.net/projects/rapideuphoria/files/Euphoria/4.0.5/euphoria_4.0.5_amd64.deb/download -O euphoria.deb dpkg -i euphoria.deb rm euphoria.deb From d5713ff08927dbb1c29a0145f0a30a1342b86a72 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 12:32:20 -0600 Subject: [PATCH 231/388] Fix broken Stack install --- scripts/docker-install-phase4.bash | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index c23f2d8..e5768cc 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -128,10 +128,7 @@ wget -nv http://www.golfscript.com/golfscript/golfscript.rb -O /usr/local/bin/go chmod +x /usr/local/bin/golfscript # Haskell -wget -nv https://get.haskellstack.org/stable/linux-x86_64-static.tar.gz -tar -xf linux-x86_64-static.tar.gz -mv stack-*-linux-x86_64-static/stack /usr/local/bin/stack -rm -rf stack-*-linux-x86_64-static linux-x86_64-static.tar.gz +curl -sSL https://get.haskellstack.org/ | sh wget "https://drive.google.com/uc?export=download&id=1MpozlNLmWeUaQuT-5t6gyE3Yv56gUbea" -O /usr/local/bin/brittany chmod +x /usr/local/bin/brittany From 9636d28d2a828ba1f594dcf8d0da374057ccce01 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 12:34:22 -0600 Subject: [PATCH 232/388] Fix Ioke download URL --- scripts/docker-install-phase4.bash | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index e5768cc..e141a4b 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -155,9 +155,9 @@ mkdir /opt/ink mv std.ink str.ink /opt/ink/ # Ioke -wget -nv https://ioke.org/dist/ioke-P-ikj-latest.tar.gz -tar -xf ioke-P-ikj-*.tar.gz -C /opt -rm ioke-P-ikj-*.tar.gz +wget -nv https://ioke.org/dist/ioke-ikj-latest.tar.gz +tar -xf ioke-ikj-*.tar.gz -C /opt +rm ioke-ikj-*.tar.gz ln -s /opt/ioke/bin/ioke /usr/local/bin/ioke # Kitten From 9bda3dc94334cbe81970ebc4250cfa2b0bc27c9a Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 12:44:20 -0600 Subject: [PATCH 233/388] Skip remaining LSP tests --- backend/src/langs.ts | 28 +++++++++++++++++++++++----- backend/src/test-runner.ts | 20 ++++++++++++++------ 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index ae70733..07e8c6f 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -43,9 +43,9 @@ export interface LangConfig { init?: any; config?: any; lang?: string; - code?: string; // FIXME + code?: string; // required unless test is skipped after?: string; - item?: string; // FIXME + item?: string; // required unless test is skipped }; template: string; timeout?: number; @@ -370,6 +370,7 @@ int main() { return 0; } `, + skip: ["lsp"], }, ceylon: { name: "Ceylon", @@ -532,6 +533,7 @@ int main() { return 0; } `, + skip: ["lsp"], }, crystal: { aliases: ["cr"], @@ -581,6 +583,7 @@ int main() { lsp: { start: "clojure-lsp" }, template: `(println "Hello, world!") `, + skip: ["lsp"], }, clojurescript: { aliases: ["cljs", "lumo"], @@ -702,7 +705,7 @@ end`, lsp: { start: "/opt/elixir-ls/language_server.sh" }, template: `IO.puts("Hello, world!") `, - skip: ["repl", "runrepl", "scope"], + skip: ["repl", "runrepl", "scope", "lsp"], }, elm: { name: "Elm", @@ -723,6 +726,7 @@ Main.x`, output : String output = "Hello, world!" `, + skip: ["lsp"], }, elvish: { aliases: ["elv"], @@ -803,6 +807,7 @@ x() -> 123 * 234. main() -> io:fwrite("Hello, world!\\n"). `, + skip: ["lsp"], }, euphoria: { aliases: ["ex", "exw", "exu", "euc", "eui", "eub"], @@ -879,6 +884,7 @@ USE: io print *, "Hello, world!" end program hello `, + skip: ["lsp"], }, fsharp: { aliases: ["fsharpi", "fsx", "fs"], @@ -923,6 +929,7 @@ func main() { fmt.Println("Hello, world!") } `, + skip: ["lsp"], }, golfscript: { aliases: ["gs", "golf"], @@ -995,6 +1002,7 @@ main = main :: IO () main = putStrLn "Hello, world!" `, + skip: ["lsp"], }, haxe: { aliases: ["hx"], @@ -1156,6 +1164,7 @@ PLEASE GIVE UP }, template: `println("Hello, world!") `, + skip: ["lsp"], }, kalyn: { name: "Kalyn", @@ -1273,6 +1282,7 @@ KTHXBYE lsp: { start: "java -cp /usr/lib/EmmyLua-LS.jar com.tang.vscode.MainKt" }, template: `print("Hello, world!") `, + skip: ["lsp"], }, malbolge: { aliases: ["mb"], @@ -1423,6 +1433,7 @@ int main() { return 0; } `, + skip: ["lsp"], }, ocaml: { name: "OCaml", @@ -1444,6 +1455,7 @@ let x = 123 * 234`, template: `;; print_string "Hello, world!\\n" `, + skip: ["lsp"], }, octave: { aliases: ["matlab", "m", "mathworks"], @@ -1547,6 +1559,7 @@ end. echo "Hello, world!\\n"; `, + skip: ["lsp"], }, pikachu: { aliases: [ @@ -1603,7 +1616,7 @@ pipi pikachu }, template: `Write-Host "Hello, world!" `, - skip: ["repl", "runrepl", "scope"], + skip: ["repl", "runrepl", "scope", "lsp"], }, prolog: { name: "Prolog", @@ -1757,6 +1770,7 @@ x`, }, template: `print_string("Hello, world!\\n"); `, + skip: ["lsp"], }, redis: { name: "Redis", @@ -1858,7 +1872,7 @@ binding_irb.run(IRB.conf) lsp: { start: "solargraph stdio" }, template: `puts "Hello, world!" `, - skip: ["repl", "runrepl", "scope"], + skip: ["repl", "runrepl", "scope", "lsp"], }, rust: { aliases: ["rs", "rustc"], @@ -1872,6 +1886,7 @@ binding_irb.run(IRB.conf) println!("Hello, world!"); } `, + skip: ["lsp"], }, sass: { name: "Sass", @@ -2118,6 +2133,7 @@ END lsp: { start: "sourcekit-lsp" }, template: `print("Hello, world!") `, + skip: ["lsp"], }, tcl: { aliases: ["tclsh", "tclshrc"], @@ -2170,6 +2186,7 @@ END lsp: { start: "digestif", lang: "tex" }, template: `\\message{Hello, world!} `, + skip: ["lsp"], }, textile: { name: "Textile", @@ -2256,6 +2273,7 @@ a lsp: { start: "vim-language-server --stdio" }, template: `:echo "Hello, world!" `, + skip: ["lsp"], }, vimwiki: { name: "Vimwiki", diff --git a/backend/src/test-runner.ts b/backend/src/test-runner.ts index 0b91f6a..649cb49 100644 --- a/backend/src/test-runner.ts +++ b/backend/src/test-runner.ts @@ -242,9 +242,9 @@ class Test { } }; testLsp = async () => { - const insertedCode = this.config.lsp!.code!; // FIXME + const insertedCode = this.config.lsp!.code!; const after = this.config.lsp!.after; - const item = this.config.lsp!.item!; // FIXME + const item = this.config.lsp!.item!; const idx = after ? this.config.template.indexOf(after) + after.length : this.config.template.length; @@ -542,12 +542,20 @@ function lint(lang: string) { } // These can be removed when the types are adjusted to make these // situations impossible. - if (config.format && !config.format.input) { + if ( + config.format && + !config.format.input && + !(config.skip || []).includes("format") + ) { throw new Error("formatter is missing test"); } - // if (config.lsp && !(config.lsp.code && config.lsp.item)) { - // throw new Error("LSP is missing test"); - // } + if ( + config.lsp && + !(config.lsp.code && config.lsp.item) && + !(config.skip || []).includes("lsp") + ) { + throw new Error("LSP is missing test"); + } } const testTypes: { From 32acc77eec47ce75cbb495816eadb16259411233 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 12:44:25 -0600 Subject: [PATCH 234/388] Use faster mirror for MariaDB --- scripts/docker-install-phase4.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index e141a4b..8846594 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -180,7 +180,7 @@ mv EmmyLua-LS-all.jar /usr/lib/EmmyLua-LS.jar # MariaDB ver="$(curl -sSL https://downloads.mariadb.org/ | grep 'href="/mariadb/[0-9]' | grep -Eo '[0-9][^/]+' | sort -rV | head -n1)" -wget -nv "https://downloads.mariadb.org/f/mariadb-${ver}/bintar-linux-x86_64/mariadb-${ver}-linux-x86_64.tar.gz/from/http%3A//mirror.vpsfree.cz/mariadb/?serve" -O mariadb.tar.gz +wget -nv "https://downloads.mariadb.org/f/mariadb-${ver}/bintar-linux-x86_64/mariadb-${ver}-linux-x86_64.tar.gz/from/http%3A//mirror.dal.ca/mariadb/?serve" -O mariadb.tar.gz tar -xf mariadb.tar.gz mkdir /opt/mariadb mv mariadb-*-linux-x86_64/* /opt/mariadb/ From d805b3efc00e755be0d43214835b645592b6ce6c Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 14:24:09 -0600 Subject: [PATCH 235/388] Stop using Sourceforge (prevent hung downloads) --- backend/src/langs.ts | 2 +- scripts/docker-install-phase4.bash | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 07e8c6f..76371f5 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -813,7 +813,7 @@ main() -> aliases: ["ex", "exw", "exu", "euc", "eui", "eub"], name: "Euphoria", main: "main.exu", - run: "eui main.exu", + run: "exu main.exu", template: `puts(1, "Hello, world!\\n") `, }, diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 8846594..330c756 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -101,12 +101,11 @@ chmod +x rebar3 mv rebar3 /usr/local/bin/rebar3 # Euphoria -# It's not possible to rolling-release because they don't upload a -# consistent set of files for every version. In particular there's no -# .deb file for 4.1.0. Besides, the latest release was in 2014. -wget -nv https://sourceforge.net/projects/rapideuphoria/files/Euphoria/4.0.5/euphoria_4.0.5_amd64.deb/download -O euphoria.deb -dpkg -i euphoria.deb -rm euphoria.deb +wget -nv http://www.rapideuphoria.com/31/euphor31.tar +mkdir /opt/euphoria +tar -xf euphor*.tar -C /opt/euphoria --strip-components=1 +ln -s /opt/euphoria/bin/exu /usr/bin/ +rm euphor*.tar # Factor ver="$(curl -sSL https://factorcode.org/ | grep -Eo 'release\?os=linux[^>]+>[^<]+' | sed -E 's/[^>]+>//' | head -n1)" From 810540799970a4034fae85d1ad25d1e8d706a684 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 14:25:14 -0600 Subject: [PATCH 236/388] Fix Snobol download --- scripts/docker-install-phase4.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 330c756..9f766fe 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -250,7 +250,7 @@ wget -nv https://setl.org/setl/bin/Linux-x86-64bit/setlbin.tgz tar -xf setlbin.tgz -C /usr/local/bin # Snobol -file="$(curl -sSL ftp://ftp.snobol4.org/snobol/ | grep -Eo 'snobol4-.*\.tar\.gz')" +file="$(curl -sSL ftp://ftp.snobol4.org/snobol/ | grep -Eo 'snobol4-.*\.tar\.gz' | sort -rV | head -n1)" wget -nv "ftp://ftp.snobol4.org/snobol/${file}" tar -xf snobol4-*.tar.gz rm snobol4-*.tar.gz From 2a2ab3336fe3fab5f3bf41ec3885911d3a16e43b Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 15:10:19 -0600 Subject: [PATCH 237/388] Migrate from Google Drive to GitHub Releases --- scripts/docker-install-phase4.bash | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 9f766fe..00b8560 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -15,10 +15,6 @@ wget -nv "https://github.com/watchexec/watchexec/releases/download/${ver}/watche dpkg -i watchexec-*.deb rm watchexec-*.deb -git clone https://github.com/circulosmeos/gdown.pl.git -mv gdown.pl/gdown.pl /usr/local/bin/gdown -rm -rf gdown.pl - # Shared ver="$(latest_release jgm/pandoc)" wget -nv "https://github.com/jgm/pandoc/releases/download/${ver}/pandoc-${ver}-linux-amd64.tar.gz" @@ -128,13 +124,12 @@ chmod +x /usr/local/bin/golfscript # Haskell curl -sSL https://get.haskellstack.org/ | sh - -wget "https://drive.google.com/uc?export=download&id=1MpozlNLmWeUaQuT-5t6gyE3Yv56gUbea" -O /usr/local/bin/brittany +wget -nv https://github.com/raxod502/riju-cdn/releases/download/brittany-0.12.1.1/brittany -O /usr/local/bin/brittany chmod +x /usr/local/bin/brittany mkdir -p /opt/haskell -gdown "https://drive.google.com/uc?export=download&id=1GPoR_ja4ns16KCamRgwB-JVag4HK0igz" /usr/local/bin/hie -gdown "https://drive.google.com/uc?export=download&id=1qSxj8JjAeetAmNjUGayX0RBARgr5R4Ij" /opt/haskell/hoogle.hoo +wget -nv https://github.com/raxod502/riju-cdn/releases/download/hie-1.4-a9005b2ba2050bdfdd4438f1d471a3f7985492cd-ghc8.6.5/hie -O /usr/local/bin/hie +wget -nv https://github.com/raxod502/riju-cdn/releases/download/hie-1.4-a9005b2ba2050bdfdd4438f1d471a3f7985492cd-ghc8.6.5/hoogle.hoo -O /opt/haskell/hoogle.hoo chmod +x /usr/local/bin/hie # HCL/TOML/YAML @@ -160,8 +155,8 @@ rm ioke-ikj-*.tar.gz ln -s /opt/ioke/bin/ioke /usr/local/bin/ioke # Kitten -wget -nv "https://drive.google.com/uc?export=download&id=11u0G2I8i0u4ez27zvEjAT6E9xF4RwuFZ" -O /usr/local/bin/kitten -wget -nv "https://drive.google.com/uc?export=download&id=1h-U1iURWax8h18kTD1AyGS21UblEIT9K" -O /usr/local/bin/common.ktn +wget -nv https://github.com/raxod502/riju-cdn/releases/download/kitten-0.1-bcaffa109c7f93959b3c2e9e7ae74462f840088d.ktn/kitten -O /usr/local/bin/kitten +wget -nv https://github.com/raxod502/riju-cdn/releases/download/kitten-0.1-bcaffa109c7f93959b3c2e9e7ae74462f840088d.ktn/common.ktn -O /usr/local/bin/common.ktn chmod +x /usr/local/bin/kitten # Kotlin @@ -261,7 +256,7 @@ popd >/dev/null rm -rf snobol4-* # Swift -gdown "https://drive.google.com/uc?export=download&id=1eE1-VuZz0gv-fITaGVT_r1UunCLjS-JT" swift.tar.gz +wget -nv https://github.com/raxod502/riju-cdn/releases/download/swift-5.2.4-20.04/swift.tar.gz -O swift.tar.gz mkdir /opt/swift tar -xf swift.tar.gz -C /opt/swift --strip-components=2 ln -s /opt/swift/bin/swiftc /usr/local/bin/swiftc From 39aa3a29da83f73ed78f8a399b40788cdf1dc7e9 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 15:19:32 -0600 Subject: [PATCH 238/388] Move Snobol from phase 4 to phase 6 --- scripts/docker-install-phase4.bash | 11 ----------- scripts/docker-install-phase6.bash | 11 +++++++++++ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 00b8560..2c9f416 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -244,17 +244,6 @@ mv "$HOME/.cache/coursier" /opt/coursier/cache wget -nv https://setl.org/setl/bin/Linux-x86-64bit/setlbin.tgz tar -xf setlbin.tgz -C /usr/local/bin -# Snobol -file="$(curl -sSL ftp://ftp.snobol4.org/snobol/ | grep -Eo 'snobol4-.*\.tar\.gz' | sort -rV | head -n1)" -wget -nv "ftp://ftp.snobol4.org/snobol/${file}" -tar -xf snobol4-*.tar.gz -rm snobol4-*.tar.gz -pushd snobol4-* >/dev/null -make || true -mv snobol4 /usr/local/bin/snobol4 -popd >/dev/null -rm -rf snobol4-* - # Swift wget -nv https://github.com/raxod502/riju-cdn/releases/download/swift-5.2.4-20.04/swift.tar.gz -O swift.tar.gz mkdir /opt/swift diff --git a/scripts/docker-install-phase6.bash b/scripts/docker-install-phase6.bash index 0da0891..bcbaf40 100755 --- a/scripts/docker-install-phase6.bash +++ b/scripts/docker-install-phase6.bash @@ -65,6 +65,17 @@ mv public/qlb/*.js /opt/qalb/ popd >/dev/null rm -rf qalb +# Snobol +file="$(curl -sSL ftp://ftp.snobol4.org/snobol/ | grep -Eo 'snobol4-.*\.tar\.gz' | sort -rV | head -n1)" +wget -nv "ftp://ftp.snobol4.org/snobol/${file}" +tar -xf snobol4-*.tar.gz +rm snobol4-*.tar.gz +pushd snobol4-* >/dev/null +make || true +mv snobol4 /usr/local/bin/snobol4 +popd >/dev/null +rm -rf snobol4-* + # Thue wget -nv "$(curl -sSL https://catseye.tc/distribution/Thue_distribution | grep -Eo 'https://catseye.tc/distfiles/thue-[^"]+\.zip' | head -n1)" unzip thue-*.zip From 3fe27089d96f0224041e9a2fa653f21d2601a20e Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 15:35:21 -0600 Subject: [PATCH 239/388] Work around set -o pipefail --- scripts/docker-install-phase7.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/docker-install-phase7.bash b/scripts/docker-install-phase7.bash index 68249e9..092c6ee 100755 --- a/scripts/docker-install-phase7.bash +++ b/scripts/docker-install-phase7.bash @@ -16,7 +16,7 @@ chmod -R a=u,go-w /opt/cmd/home-template mkdir -p /opt/elm mkdir elm-project pushd elm-project >/dev/null -yes | elm init +(yes || true) | elm init cat elm.json | jq '."source-directories" = ["."]' > /opt/elm/elm.json popd >/dev/null rm -rf elm-project From b6b62a792e2081b237e13bd245d6abb102c4fa94 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 15:47:27 -0600 Subject: [PATCH 240/388] Update README --- README.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/README.md b/README.md index 7968954..7246404 100644 --- a/README.md +++ b/README.md @@ -46,12 +46,7 @@ container first: Note that building the image typically requires over an hour and 20 GB of disk space. -## Maintainer guide -### Updating brittany - -Install latest version of Cabal v3, then use it with `--installdir` to -create a binary linked to `/usr/lib/ghc` and slap this on Google -Drive. +See also [riju-cdn](https://github.com/raxod502/riju-cdn). ## Flag From 85a5b33180463517359d346bd216373c6065ff99 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 16:14:30 -0600 Subject: [PATCH 241/388] Enable systemd service automatically --- scripts/deploy-phase2.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/deploy-phase2.py b/scripts/deploy-phase2.py index 8489fbb..afd2bba 100755 --- a/scripts/deploy-phase2.py +++ b/scripts/deploy-phase2.py @@ -19,6 +19,7 @@ existing_containers = subprocess.run( subprocess.run(["scripts/install-scripts.bash"], check=True) if existing_containers: subprocess.run(["docker", "kill", *existing_containers], check=True) +subprocess.run(["systemctl", "enable", "riju"], check=True) subprocess.run(["systemctl", "restart", "riju"], check=True) print("==> Successfully deployed Riju! <==", file=sys.stderr) From 4c0cab2572e0f85dcfb44d093294a53d1fc6012e Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 16:14:39 -0600 Subject: [PATCH 242/388] Add hint for Hack repl --- backend/src/langs.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 76371f5..5d04a6c 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -957,7 +957,7 @@ func main() { repl: "hhvm -a", input: "print 123 * 234", main: "main.hack", - run: "hhvm -a main.hack", + run: `echo "Type 'r' at the debugger prompt to run the code" && hhvm -a main.hack`, helloInput: "r", scope: { code: `function x() : int { From e5ba8b722e885860d0a94be5377befab19d766b8 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 16:24:15 -0600 Subject: [PATCH 243/388] Reduce number of subshells generated --- backend/src/util.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/backend/src/util.ts b/backend/src/util.ts index ba4e588..bffbce4 100644 --- a/backend/src/util.ts +++ b/backend/src/util.ts @@ -131,5 +131,10 @@ export function privilegedTeardown({ uid, uuid }: Context) { } export function bash(cmdline: string) { + if (!cmdline.match(/[;|&(){}=]/)) { + // Reduce number of subshells we generate, if we're just running a + // single command (no shell logic). + cmdline = "exec " + cmdline; + } return ["bash", "-c", cmdline]; } From b1fd9aee6b5c8c4291110b4f3d080eea96769369 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 16:34:32 -0600 Subject: [PATCH 244/388] Use 'mv' instead of 'cp' where possible --- scripts/docker-install-phase4.bash | 7 ++++--- scripts/docker-install-phase6.bash | 2 +- scripts/docker-install-phase7.bash | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 2c9f416..7c50313 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -163,9 +163,10 @@ chmod +x /usr/local/bin/kitten ver="$(latest_release JetBrains/kotlin)" wget -nv "https://github.com/JetBrains/kotlin/releases/download/${ver}/kotlin-compiler-$(sed 's/^v//' <<< "$ver").zip" unzip kotlin-*.zip -cp kotlinc/bin/* /usr/local/bin/ -cp kotlinc/lib/* /usr/local/lib/ -rm -rf kotlin-*.zip kotlinc +mv kotlinc /opt/kotlin +ln -s /opt/kotlin/bin/* /usr/local/bin/ +ln -s /opt/kotlin/lib/* /usr/local/lib/ +rm kotlin-*.zip # Lua ver="$(latest_release EmmyLua/EmmyLua-LanguageServer)" diff --git a/scripts/docker-install-phase6.bash b/scripts/docker-install-phase6.bash index bcbaf40..cf2c190 100755 --- a/scripts/docker-install-phase6.bash +++ b/scripts/docker-install-phase6.bash @@ -33,7 +33,7 @@ pushd kalyn >/dev/null stack build kalyn mv "$(stack exec which kalyn)" /usr/local/bin/kalyn mkdir /opt/kalyn -cp -R src-kalyn/Stdlib src-kalyn/Stdlib.kalyn /opt/kalyn/ +mv src-kalyn/Stdlib src-kalyn/Stdlib.kalyn /opt/kalyn/ popd >/dev/null rm -rf kalyn diff --git a/scripts/docker-install-phase7.bash b/scripts/docker-install-phase7.bash index 092c6ee..420214e 100755 --- a/scripts/docker-install-phase7.bash +++ b/scripts/docker-install-phase7.bash @@ -9,7 +9,7 @@ useradd -m -N -l -r -p '!' build # Cmd sudo -u build wine cmd < /dev/null mkdir -p /opt/cmd/home-template -cp -R /home/build/.wine /opt/cmd/home-template/ +mv /home/build/.wine /opt/cmd/home-template/ chmod -R a=u,go-w /opt/cmd/home-template # Elm From d9b6254bd144fc7b92c0951ab775722ebe73b233 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 16:52:50 -0600 Subject: [PATCH 245/388] LSP working for Java --- backend/src/langs.ts | 139 +++++++++++++++++++++++++++++ scripts/docker-install-phase4.bash | 6 ++ 2 files changed, 145 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 5d04a6c..dc16b32 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1118,12 +1118,151 @@ PLEASE GIVE UP } `, }, + lsp: { + setup: "rm -rf jdt && cp -RT /opt/jdt/config_linux jdt", + start: `java -Declipse.application=org.eclipse.jdt.ls.core.id1 -Dosgi.bundles.defaultStartLevel=4 -Declipse.product=org.eclipse.jdt.ls.core.product -Dlog.level=ALL -noverify -Xmx1G -jar /opt/jdt/plugins/org.eclipse.equinox.launcher_*.jar -configuration "$PWD/jdt" -data "$PWD" --add-modules=ALL-SYSTEM --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED`, + init: { + settings: { + java: { + codeGeneration: { + toString: { + limitElements: 0, + listArrayContents: true, + skipNullValues: false, + codeStyle: "STRING_CONCATENATION", + template: + "${object.className} [${member.name()}=${member.value}, ${otherMembers}]", + }, + generateComments: false, + useBlocks: false, + hashCodeEquals: { + useInstanceof: false, + useJava7Objects: false, + }, + }, + format: { + onType: { + enabled: true, + }, + comments: { + enabled: true, + }, + enabled: true, + }, + progressReports: { + enabled: true, + }, + foldingRange: { + enabled: true, + }, + completion: { + importOrder: ["java", "javax", "com", "org"], + favoriteStaticMembers: [ + "org.junit.Assert.*", + "org.junit.Assume.*", + "org.junit.jupiter.api.Assertions.*", + "org.junit.jupiter.api.Assumptions.*", + "org.junit.jupiter.api.DynamicContainer.*", + "org.junit.jupiter.api.DynamicTest.*", + "org.mockito.Mockito.*", + "org.mockito.ArgumentMatchers.*", + "org.mockito.Answers.*", + ], + guessMethodArguments: true, + overwrite: true, + enabled: true, + filteredTypes: ["java.awt.*", "com.sun.*"], + }, + maxConcurrentBuilds: 1, + autobuild: { + enabled: true, + }, + selection: { + enabled: true, + }, + import: { + exclusions: [ + "**/node_modules/**", + "**/.metadata/**", + "**/archetype-resources/**", + "**/META-INF/maven/**", + ], + maven: { + enabled: true, + }, + gradle: { + enabled: true, + wrapper: { + enabled: true, + }, + }, + }, + saveActions: { + organizeImports: false, + }, + implementationsCodeLens: { + enabled: false, + }, + signatureHelp: { + enabled: true, + }, + referencesCodeLens: { + enabled: false, + }, + maven: { + downloadSources: false, + }, + trace: { + server: "off", + }, + configuration: { + updateBuildConfiguration: "automatic", + checkProjectSettingsExclusions: true, + }, + errors: { + incompleteClasspath: { + severity: "warning", + }, + }, + dependency: { + packagePresentation: "flat", + }, + }, + }, + extendedClientCapabilities: { + progressReportProvider: true, + classFileContentsSupport: true, + overrideMethodsPromptSupport: true, + hashCodeEqualsPromptSupport: true, + advancedOrganizeImportsSupport: true, + generateConstructorsPromptSupport: true, + generateToStringPromptSupport: true, + advancedGenerateAccessorsSupport: true, + advancedExtractRefactoringSupport: true, + moveRefactoringSupport: true, + }, + bundles: [ + "/opt/jdt/bundles/com.microsoft.java.test.plugin-0.19.0.jar", + "/opt/jdt/bundles/com.microsoft.jdtls.ext.core-0.5.1.jar", + "/opt/jdt/bundles/dg.jdt.ls.decompiler.cfr-0.0.2-201802221740.jar", + "/opt/jdt/bundles/dg.jdt.ls.decompiler.common-0.0.2-201802221740.jar", + "/opt/jdt/bundles/dg.jdt.ls.decompiler.fernflower-0.0.2-201802221740.jar", + "/opt/jdt/bundles/dg.jdt.ls.decompiler.procyon-0.0.2-201802221740.jar", + "/opt/jdt/bundles/io.projectreactor.reactor-core.jar", + "/opt/jdt/bundles/java.debug.plugin.jar", + "/opt/jdt/bundles/jdt-ls-commons.jar", + "/opt/jdt/bundles/jdt-ls-extension.jar", + "/opt/jdt/bundles/org.reactivestreams.reactive-streams.jar", + ], + }, + }, template: `public class Main { public static void main(String[] args) { System.out.println("Hello, world!"); } } `, + skip: ["lsp"], }, javascript: { aliases: ["node", "js", "web", "jsx", "v8", "closure", "nodejs"], diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 7c50313..bfed8f2 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -154,6 +154,12 @@ tar -xf ioke-ikj-*.tar.gz -C /opt rm ioke-ikj-*.tar.gz ln -s /opt/ioke/bin/ioke /usr/local/bin/ioke +# Java +wget -nv https://download.eclipse.org/jdtls/snapshots/jdt-language-server-latest.tar.gz +mkdir /opt/jdt +tar -C /opt/jdt -xf jdt-language-server-latest.tar.gz +rm jdt-language-server-latest.tar.gz + # Kitten wget -nv https://github.com/raxod502/riju-cdn/releases/download/kitten-0.1-bcaffa109c7f93959b3c2e9e7ae74462f840088d.ktn/kitten -O /usr/local/bin/kitten wget -nv https://github.com/raxod502/riju-cdn/releases/download/kitten-0.1-bcaffa109c7f93959b3c2e9e7ae74462f840088d.ktn/common.ktn -O /usr/local/bin/common.ktn From ebed873b5ce78ad6f839875e73a9fa0f4cd89b7f Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 17:23:35 -0600 Subject: [PATCH 246/388] LSP working for Dart --- backend/src/langs.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index dc16b32..385fcc6 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -657,10 +657,17 @@ void main() monacoLang: "dart", main: "main.dart", run: "dart main.dart", + lsp: { + start: + "dart /usr/lib/dart/bin/snapshots/analysis_server.dart.snapshot --lsp", + disableDynamicRegistration: true, + lang: "dart", + }, template: `void main() { print('Hello, world!'); } `, + skip: ["lsp"], }, dogescript: { aliases: ["doge", "ds", "wow"], From 728ec07f9d9a2c8356dc062d1f7c7c7e7b2d40b6 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 18:38:59 -0600 Subject: [PATCH 247/388] [#18] Fix link in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7246404..3697238 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Riju is a very fast online playground for every programming language. In less than a second, you can start playing with a Python interpreter or compiling INTERCAL code. -Check out the [live application](https://riju-sandbox.herokuapp.com/)! +Check out the [live application](https://riju.codes/)! **You should not write any sensitive code on Riju, as NO GUARANTEES are made about the security or privacy of your data. (No warranty etc From 3fa097dfc6cc2e945fbcff060aa36e43d365efee Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 18:41:02 -0600 Subject: [PATCH 248/388] Reduce concurrency for CI --- backend/src/test-runner.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/test-runner.ts b/backend/src/test-runner.ts index 649cb49..36ab925 100644 --- a/backend/src/test-runner.ts +++ b/backend/src/test-runner.ts @@ -11,7 +11,7 @@ import * as api from "./api"; import { LangConfig, langs } from "./langs"; const TIMEOUT_SECS = 5; -const CONCURRENCY = 2; +const CONCURRENCY = 1; function findPosition(str: string, idx: number) { const lines = str.substring(0, idx).split("\n"); From d5503db3748ddfcef2f00e68ac451beefca1c932 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 19:10:22 -0600 Subject: [PATCH 249/388] Alphabetize --- scripts/docker-install-phase5.bash | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index 0295931..42dc84f 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -8,16 +8,16 @@ set -x mkdir /opt/julia export JULIA_DEPOT_PATH=/opt/julia -# Package manager - OCaml -export OPAMROOT=/opt/opam -export OPAMROOTISOK=1 -opam init -n --disable-sandboxing - # Package manager - Node.js npm config set unsafe-perm true PERL_MM_USE_DEFAULT=1 cpan App::cpanminus rm -rf /tmp/cpan_install_*.txt +# Package manager - OCaml +export OPAMROOT=/opt/opam +export OPAMROOTISOK=1 +opam init -n --disable-sandboxing + # Shared npm install -g prettier From 3a2bc56f7dc450664c5bbf0c45050c153c3b6e70 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 19:43:34 -0600 Subject: [PATCH 250/388] LSP working for all SQL databases --- backend/src/langs.ts | 16 ++++++++++++++++ scripts/docker-install-phase4.bash | 7 +++++++ 2 files changed, 23 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 385fcc6..30a9d2e 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1446,8 +1446,12 @@ KTHXBYE input: "SELECT 123 * 234;", main: "main.sql", run: `rm -rf data && /opt/mariadb/scripts/mariadb-install-db --user="$(id -un)" && (/opt/mariadb/bin/mysqld --datadir="$PWD/data" --socket="$PWD/socket" --skip-networking &) && until [[ -e socket ]]; do sleep 0.01; done && (mysql --socket="$PWD/socket" < main.sql; mysql --socket="$PWD/socket")`, + lsp: { + start: "sqls", + }, template: `SELECT 'Hello, world!'; `, + skip: ["lsp"], }, markdown: { aliases: [ @@ -1534,9 +1538,13 @@ message: input: "SELECT 123 * 234;", main: "main.sql", run: `rm -rf data && mysqld -h "$PWD/data" --initialize-insecure && (mysqld -h "$PWD/data" --socket="$PWD/socket" --pid-file="$PWD/pid-file" --mysqlx=OFF --skip-networking &) && until [[ -e socket ]]; do sleep 0.01; done && (mysql --socket="$PWD/socket" -u root < main.sql; mysql --socket="$PWD/socket" -u root)`, + lsp: { + start: "sqls", + }, template: `SELECT 'Hello, world!'; `, timeout: 15, + skip: ["lsp"], }, nim: { name: "Nim", @@ -1741,9 +1749,13 @@ pipi pikachu input: "SELECT 123 * 234;", main: "main.sql", run: `rm -rf data && /usr/lib/postgresql/*/bin/initdb -D data && (echo "listen_addresses = ''" && echo "unix_socket_directories = '.'") >> data/postgresql.conf && /usr/lib/postgresql/*/bin/pg_ctl -D data -w start && (psql -h "$PWD/data" postgres -f main.sql; psql -h "$PWD/data" postgres)`, + lsp: { + start: "sqls", + }, template: `SELECT 'Hello, world!'; `, timeout: 15, + skip: ["lsp"], }, powershell: { aliases: ["pwsh", "ps1"], @@ -2252,8 +2264,12 @@ END input: "SELECT 123 * 234;", main: "main.sql", run: `sqlite3 -cmd "$(< main.sql)"`, + lsp: { + start: "sqls", + }, template: `SELECT 'Hello, world!'; `, + skip: ["lsp"], }, standardml: { aliases: ["sml", "ml"], diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index bfed8f2..cce5482 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -251,6 +251,13 @@ mv "$HOME/.cache/coursier" /opt/coursier/cache wget -nv https://setl.org/setl/bin/Linux-x86-64bit/setlbin.tgz tar -xf setlbin.tgz -C /usr/local/bin +# SQL +ver="$(latest_release lighttiger2505/sqls)" +wget -nv "https://github.com/lighttiger2505/sqls/releases/download/${ver}/sqls-${ver}-linux-amd64.tar.gz" +tar -xf sqls-*-linux-amd64.tar.gz +mv linux-amd64/sqls /usr/local/bin/ +rm -rf linux-amd64 sqls-*-linux-amd64.tar.gz + # Swift wget -nv https://github.com/raxod502/riju-cdn/releases/download/swift-5.2.4-20.04/swift.tar.gz -O swift.tar.gz mkdir /opt/swift From 5610772c15677859651ebb2035f03aa328e1bbff Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 19:47:13 -0600 Subject: [PATCH 251/388] Remove Metals installation --- scripts/docker-install-phase4.bash | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index cce5482..45c58ce 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -237,16 +237,6 @@ for file in /opt/rust/bin/*; do ln -s /opt/rust/wrapper "/usr/local/bin/${file##*/}" done -# Scala -file="$(curl -sSL https://scalameta.org/metals/docs/editors/emacs.html | grep -Eo 'org.scalameta[^ ]+')" -wget -nv https://git.io/coursier-cli -chmod +x coursier-cli -mv coursier-cli /usr/local/bin/coursier -coursier bootstrap --java-opt -Xss4m --java-opt -Xms100m --java-opt -Dmetals.client=emacs "${file}" -r bintray:scalacenter/releases -r sonatype:snapshots -o /usr/local/bin/metals -metals -version Date: Sat, 22 Aug 2020 19:54:01 -0600 Subject: [PATCH 252/388] Reduce concurrency only when building prod image --- Dockerfile.prod | 2 +- backend/src/test-runner.ts | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Dockerfile.prod b/Dockerfile.prod index 8de085f..a2fb906 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -68,4 +68,4 @@ RUN sudo cp -a /tmp/riju/* /home/docker/src/ && rm -rf /tmp/riju WORKDIR /home/docker/src RUN sudo deluser docker sudo -RUN RIJU_PRIVILEGED=1 yarn test +RUN RIJU_PRIVILEGED=1 TIMEOUT_SECS=20 yarn test diff --git a/backend/src/test-runner.ts b/backend/src/test-runner.ts index 36ab925..3010692 100644 --- a/backend/src/test-runner.ts +++ b/backend/src/test-runner.ts @@ -10,8 +10,13 @@ import { v4 as getUUID } from "uuid"; import * as api from "./api"; import { LangConfig, langs } from "./langs"; -const TIMEOUT_SECS = 5; -const CONCURRENCY = 1; +function parseIntOr(thing: any, def: number) { + const num = parseInt(thing); + return Number.isNaN(num) ? def : num; +} + +const TIMEOUT_SECS = parseIntOr(process.env.TIMEOUT, 5); +const CONCURRENCY = parseIntOr(process.env.CONCURRENCY, 2); function findPosition(str: string, idx: number) { const lines = str.substring(0, idx).split("\n"); From 016d3c8209565fa068482331f4556f9340887f34 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 20:32:36 -0600 Subject: [PATCH 253/388] Bump timeout to be ridiculously long --- Dockerfile.prod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile.prod b/Dockerfile.prod index a2fb906..c00dc6a 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -68,4 +68,4 @@ RUN sudo cp -a /tmp/riju/* /home/docker/src/ && rm -rf /tmp/riju WORKDIR /home/docker/src RUN sudo deluser docker sudo -RUN RIJU_PRIVILEGED=1 TIMEOUT_SECS=20 yarn test +RUN RIJU_PRIVILEGED=1 TIMEOUT_SECS=60 yarn test From 37a4be8a0a88aa985fc11c26a6c68d7fc9aae1ae Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 21:18:39 -0600 Subject: [PATCH 254/388] Decrease concurrency also --- Dockerfile.prod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile.prod b/Dockerfile.prod index c00dc6a..27f2ad4 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -68,4 +68,4 @@ RUN sudo cp -a /tmp/riju/* /home/docker/src/ && rm -rf /tmp/riju WORKDIR /home/docker/src RUN sudo deluser docker sudo -RUN RIJU_PRIVILEGED=1 TIMEOUT_SECS=60 yarn test +RUN RIJU_PRIVILEGED=1 CONCURRENCY=1 TIMEOUT_SECS=60 yarn test From aee2a82abc6aa635ddfd6035fc742e4b81d27824 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 21:28:48 -0600 Subject: [PATCH 255/388] Update README --- README.md | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3697238..ac6c4ad 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,34 @@ container first: $ make docker Note that building the image typically requires over an hour and 20 GB -of disk space. +of disk space, and it is only growing. + +The above command generates the development image as a subroutine. You +can skip this and use the last tagged development image: + + $ make docker-nobuild + +Or you can explicitly build the image without running it: + + $ make image-dev + +The production image is based on the development one, with some +additional layers. You can build it as follows: + + $ make image-prod + +Lastly I should mention the tests. There are integration tests for +every language, and they can be run as follows: + + $ [CONCURRENCY=2] [TIMEOUT=5] yarn test [...] + +Filters can be for language (`python`, `java`) or test type (`hello`, +`lsp`). You can comma-delimit multiple filters to do a disjunction, +and space-delimit them to do a conjunction (`hello python,java`) for +the `hello` tests for `python` and `java`. + +The tests are run automatically when building the production image, +and fail the build if they fail. See also [riju-cdn](https://github.com/raxod502/riju-cdn). From 5592a92c1b28ebbea508858d3e88eeb58c2d02ba Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 21:38:48 -0600 Subject: [PATCH 256/388] Make better use of Docker cache on failed builds --- scripts/deploy-phase2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/deploy-phase2.py b/scripts/deploy-phase2.py index afd2bba..4881234 100755 --- a/scripts/deploy-phase2.py +++ b/scripts/deploy-phase2.py @@ -11,7 +11,6 @@ import tempfile import time subprocess.run(["docker", "pull", "ubuntu:rolling"], check=True) -subprocess.run(["docker", "system", "prune", "-f"], check=True) subprocess.run(["make", "image-prod"], check=True) existing_containers = subprocess.run( ["docker", "ps", "-q"], check=True, stdout=subprocess.PIPE @@ -21,5 +20,6 @@ if existing_containers: subprocess.run(["docker", "kill", *existing_containers], check=True) subprocess.run(["systemctl", "enable", "riju"], check=True) subprocess.run(["systemctl", "restart", "riju"], check=True) +subprocess.run(["docker", "system", "prune", "-f"], check=True) print("==> Successfully deployed Riju! <==", file=sys.stderr) From e5dd562e87060714024b34e7e5bae2210f212743 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 22:13:52 -0600 Subject: [PATCH 257/388] New language: Battlestar --- backend/src/langs.ts | 12 ++++++++++++ scripts/docker-install-phase3a.bash | 4 ++++ scripts/docker-install-phase6.bash | 9 +++++++++ 3 files changed, 25 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 30a9d2e..9c3afb4 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -181,6 +181,18 @@ implement main0 () = () input: `PRINT x`, }, template: `PRINT "Hello, world!" +`, + }, + battlestar: { + aliases: ["battlestarc", "bts"], + name: "Battlestar", + main: "main.bts", + run: "bts main.bts", + template: `const message = "Hello, world!\n" + +fun main + syscall(1, 1, message, len(message)) +end `, }, beatnik: { diff --git a/scripts/docker-install-phase3a.bash b/scripts/docker-install-phase3a.bash index 93b9ded..2379a6e 100755 --- a/scripts/docker-install-phase3a.bash +++ b/scripts/docker-install-phase3a.bash @@ -39,6 +39,10 @@ bwbasic # Bash bash +# Battlestar +golang +yasm + # BrainF beef diff --git a/scripts/docker-install-phase6.bash b/scripts/docker-install-phase6.bash index cf2c190..eac280c 100755 --- a/scripts/docker-install-phase6.bash +++ b/scripts/docker-install-phase6.bash @@ -5,6 +5,15 @@ set -o pipefail set -x pushd /tmp >/dev/null +# Battlestar +git clone https://github.com/xyproto/battlestar.git +pushd battlestar >/dev/null +make +mv cmd/battlestarc/battlestarc /usr/local/bin/ +mv scripts/bts.sh /usr/local/bin/bts +popd >/dev/null +rm -rf battlestar + # Beatnik git clone https://github.com/catseye/Beatnik.git sed -i 's#env python#env python2#' Beatnik/script/beatnik.py From b8188be56046ceade60f938a9211c33d6f4df84a Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 22:25:50 -0600 Subject: [PATCH 258/388] New language: Boo --- backend/src/langs.ts | 11 +++++++++++ scripts/docker-install-phase4.bash | 7 +++++++ 2 files changed, 18 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 9c3afb4..fd1afe1 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -311,6 +311,17 @@ Nude pagoda careens. run: "cat main.blc | binary-to-text | tromp", template: `001010100100100001100101011011000110110001101111001011000010 000001110111011011110111001001101100011001000010000100001010 +`, + }, + boo: { + aliases: ["booc"], + name: "Boo", + setup: `mkdir -p "$HOME/.local/share" && touch "$HOME/.local/share/booish_history"`, + main: "main.boo", + repl: "booish", + compile: "booc main.boo", + run: "mono main.exe; booish", + template: `print "Hello, world!" `, }, brainf: { diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 45c58ce..ef22563 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -39,6 +39,13 @@ wget -nv "ftp://ftp.gnu.org/gnu/apl/${file}" dpkg -i apl_*_amd64.deb rm apl_*_amd64.deb +# Boo +wget -nv https://github.com/boo-lang/boo/releases/download/unstable/boo-latest.zip +unzip boo-latest.zip +mv boo-latest /usr/local/lib/boo +chmod +x /usr/local/lib/boo/booc /usr/local/lib/boo/booish +ln -s /usr/local/lib/boo/booc /usr/local/lib/boo/booish /usr/local/bin/ + # Clojure ver="$(latest_release snoe/clojure-lsp)" wget -nv "https://github.com/snoe/clojure-lsp/releases/download/${ver}/clojure-lsp" From af8f0a09abb315a09713351e095efa2c41d20a4c Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 22:51:54 -0600 Subject: [PATCH 259/388] Make timeout *absurdly* long --- Dockerfile.prod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile.prod b/Dockerfile.prod index 27f2ad4..95b88e7 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -68,4 +68,4 @@ RUN sudo cp -a /tmp/riju/* /home/docker/src/ && rm -rf /tmp/riju WORKDIR /home/docker/src RUN sudo deluser docker sudo -RUN RIJU_PRIVILEGED=1 CONCURRENCY=1 TIMEOUT_SECS=60 yarn test +RUN RIJU_PRIVILEGED=1 CONCURRENCY=1 TIMEOUT_SECS=240 yarn test From a17c80ae8c6f6fa08a65a7ba1e228a1fc457623a Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 23:03:14 -0600 Subject: [PATCH 260/388] Add trash-cli package as handy utility --- scripts/docker-install-phase2.bash | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/docker-install-phase2.bash b/scripts/docker-install-phase2.bash index e841838..7c0ac19 100755 --- a/scripts/docker-install-phase2.bash +++ b/scripts/docker-install-phase2.bash @@ -35,6 +35,7 @@ iputils-ping ripgrep sudo tmux +trash-cli tree vim wget From 55186a016f936d270d21c5268df6ba0af147d24b Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 22 Aug 2020 23:03:27 -0600 Subject: [PATCH 261/388] New language: Cat --- backend/src/langs.ts | 11 +++++++++++ scripts/docker-install-phase6.bash | 6 ++++++ scripts/docker-install-phase7.bash | 23 +++++++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index fd1afe1..3b76f32 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -395,6 +395,17 @@ int main() { `, skip: ["lsp"], }, + cat: { + aliases: ["cat-language"], + name: "Cat", + repl: "NODE_PATH=/opt/cat node /opt/cat/repl.js", + input: "123 234 mul", + main: "main.cat", + run: "NODE_PATH=/opt/cat node /opt/cat/repl.js main.cat", + hello: "72,101,108,108,111,44,32,119,111,114,108,100,33,10", + template: `72 101 108 108 111 44 32 119 111 114 108 100 33 10 +`, + }, ceylon: { name: "Ceylon", main: "source/main.ceylon", diff --git a/scripts/docker-install-phase6.bash b/scripts/docker-install-phase6.bash index eac280c..4c30a43 100755 --- a/scripts/docker-install-phase6.bash +++ b/scripts/docker-install-phase6.bash @@ -25,6 +25,12 @@ wget -nv https://www.ioccc.org/2012/tromp/tromp.c clang tromp.c -Wno-everything -DInt=long -DX=8 -DA=500000 -o /usr/local/bin/tromp rm tromp.c +# Cat +git clone https://github.com/cdiggins/cat-language.git /opt/cat +pushd /opt/cat >/dev/null +npm install +popd >/dev/null + # Erlang git clone https://github.com/erlang-ls/erlang_ls.git pushd erlang_ls >/dev/null diff --git a/scripts/docker-install-phase7.bash b/scripts/docker-install-phase7.bash index 420214e..6a58887 100755 --- a/scripts/docker-install-phase7.bash +++ b/scripts/docker-install-phase7.bash @@ -130,6 +130,29 @@ while True: EOF chmod +x /usr/local/bin/brainf-repl +# Cat +tee /opt/cat/repl.js >/dev/null <<"EOF" +const fs = require("fs"); +const repl = require("repl"); + +const args = process.argv.slice(2); +if (args.length > 1) { + console.error("usage: repl.js [FILE]"); + process.exit(1); +} + +const program = args.length === 1 ? fs.readFileSync(args[0], "utf-8") : null; + +const cat = require("cat"); +const ce = new cat.CatLanguage.CatEvaluator(); + +if (program !== null) { + ce.eval(program); +} + +repl.start({prompt: "cat> ", eval: (cmd, context, filename, callback) => callback(null, ce.eval(cmd))}); +EOF + # Haskell mkdir -p /opt/haskell tee /opt/haskell/hie.yaml >/dev/null <<"EOF" From ccdff2ec5d0f2b59f356d3fd5a58424ac055c3c8 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 23 Aug 2020 08:56:34 -0600 Subject: [PATCH 262/388] Prevent .git from being added to Docker image --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5b77209..cc99f2c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.git *.log .log .lsp-repl-history From a7af89cf04a12074644b5c16f93d683ce9d0b093 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 23 Aug 2020 09:16:08 -0600 Subject: [PATCH 263/388] Fix name of environment variable O_o --- Dockerfile.prod | 2 +- backend/src/test-runner.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile.prod b/Dockerfile.prod index 95b88e7..4e05025 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -68,4 +68,4 @@ RUN sudo cp -a /tmp/riju/* /home/docker/src/ && rm -rf /tmp/riju WORKDIR /home/docker/src RUN sudo deluser docker sudo -RUN RIJU_PRIVILEGED=1 CONCURRENCY=1 TIMEOUT_SECS=240 yarn test +RUN RIJU_PRIVILEGED=1 CONCURRENCY=1 TIMEOUT_SECS=30 yarn test diff --git a/backend/src/test-runner.ts b/backend/src/test-runner.ts index 3010692..09149fd 100644 --- a/backend/src/test-runner.ts +++ b/backend/src/test-runner.ts @@ -15,7 +15,7 @@ function parseIntOr(thing: any, def: number) { return Number.isNaN(num) ? def : num; } -const TIMEOUT_SECS = parseIntOr(process.env.TIMEOUT, 5); +const TIMEOUT_SECS = parseIntOr(process.env.TIMEOUT_SECS, 5); const CONCURRENCY = parseIntOr(process.env.CONCURRENCY, 2); function findPosition(str: string, idx: number) { From fb2334750c1406a8c1c3cdbbb527cc8e24f9bb91 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 23 Aug 2020 09:47:17 -0600 Subject: [PATCH 264/388] New language: Ezhil --- backend/src/langs.ts | 10 ++++++++++ scripts/docker-install-phase4.bash | 8 ++++++++ 2 files changed, 18 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 3b76f32..08bf40f 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -856,6 +856,16 @@ main() -> main: "main.exu", run: "exu main.exu", template: `puts(1, "Hello, world!\\n") +`, + }, + எழில்: { + aliases: ["ezhil", "ezhili", "ezhuthi", "tamil"], + name: "எழில்", + repl: "ezhili", + main: "main.n", + run: "ezhili main.n; ezhili", + hello: "வணக்கம், உலகமே!", + template: `பதிப்பி "வணக்கம், உலகமே!" `, }, factor: { diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index ef22563..d0444aa 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -110,6 +110,14 @@ tar -xf euphor*.tar -C /opt/euphoria --strip-components=1 ln -s /opt/euphoria/bin/exu /usr/bin/ rm euphor*.tar +# Ezhil +wget -nv https://github.com/raxod502/riju-cdn/releases/download/ezhil-2017.08.19/ezhil.tar.gz +tar -xf ezhil.tar.gz +mv ezhil-* /opt/ezhil +cp /opt/ezhil/ezhili /opt/ezhil/ezhuthi/ +ln -s /opt/ezhil/ezhuthi/ezhili /usr/local/bin/ +rm ezhil.tar.gz + # Factor ver="$(curl -sSL https://factorcode.org/ | grep -Eo 'release\?os=linux[^>]+>[^<]+' | sed -E 's/[^>]+>//' | head -n1)" wget -nv "https://downloads.factorcode.org/releases/${ver}/factor-linux-x86-64-${ver}.tar.gz" From 109079ed3eb6adab961509bc3d9ef98356203a4e Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 23 Aug 2020 10:20:00 -0600 Subject: [PATCH 265/388] New language: Dylan --- backend/src/langs.ts | 18 ++++++++++++++++++ scripts/docker-install-phase3a.bash | 3 +++ scripts/docker-install-phase4.bash | 8 ++++++++ scripts/docker-install-phase7.bash | 21 +++++++++++++++++++++ 4 files changed, 50 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 08bf40f..0f07bd2 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -727,6 +727,24 @@ void main() compile: "pandoc main.txt -f dokuwiki -o main.html", run: "prettier --no-config main.html", template: `Hello, world! +`, + }, + dylan: { + aliases: ["opendylan"], + name: "Dylan", + setup: "cp -R /opt/dylan/project-template/* ./", + main: "main.dylan", + compile: "dylan-compiler -build main.lid", + run: "_build/bin/main", + template: `Module: main + +define function main + (name :: , arguments :: ) + format-out("Hello, world!\\n"); + exit-application(0); +end function main; + +main(application-name(), application-arguments()); `, }, elixir: { diff --git a/scripts/docker-install-phase3a.bash b/scripts/docker-install-phase3a.bash index 2379a6e..f65951d 100755 --- a/scripts/docker-install-phase3a.bash +++ b/scripts/docker-install-phase3a.bash @@ -82,6 +82,9 @@ dart # Dhall dhall +# Dylan +libunwind-dev + " apt-get install -y $(grep -v "^#" <<< "$packages") diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index d0444aa..c8b5ad6 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -66,6 +66,14 @@ tar -xf dhall-json-*-x86_64-linux.tar.bz2 -C dhall-json mv dhall-json/bin/dhall-to-json dhall-json/bin/json-to-dhall /usr/local/bin/ rm -rf dhall-json dhall-json-*-x86_64-linux.tar.bz2 +# Dylan +ver="$(latest_release dylan-lang/opendylan)" +wget -nv "https://github.com/dylan-lang/opendylan/releases/download/${ver}/opendylan-$(grep -Eo '[0-9]+\.[0-9]+' <<< "$ver")-x86_64-linux.tar.bz2" +tar -xf opendylan-*-x86_64-linux.tar.bz2 +rm opendylan-*-x86_64-linux.tar.bz2 +mv opendylan-* /opt/dylan +ln -s /opt/dylan/bin/dylan-compiler /opt/dylan/bin/make-dylan-app /usr/local/bin/ + # Elixir ver="$(latest_release elixir-lsp/elixir-ls)" wget -nv "https://github.com/elixir-lsp/elixir-ls/releases/download/${ver}/elixir-ls.zip" diff --git a/scripts/docker-install-phase7.bash b/scripts/docker-install-phase7.bash index 6a58887..5482ddb 100755 --- a/scripts/docker-install-phase7.bash +++ b/scripts/docker-install-phase7.bash @@ -12,6 +12,27 @@ mkdir -p /opt/cmd/home-template mv /home/build/.wine /opt/cmd/home-template/ chmod -R a=u,go-w /opt/cmd/home-template +# Dylan +pushd /opt/dylan +make-dylan-app main +mv main project-template +pushd project-template >/dev/null +cat <<"EOF" > main.dylan +Module: main + +define function main + (name :: , arguments :: ) + format-out("Hello, world!\n"); + exit-application(0); +end function main; + +main(application-name(), application-arguments()); +EOF +dylan-compiler -build main.lid +rm main.dylan +popd >/dev/null +popd >/dev/null + # Elm mkdir -p /opt/elm mkdir elm-project From 0dc85743d6ae41285c81152f547a540d411085c4 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 23 Aug 2020 10:22:09 -0600 Subject: [PATCH 266/388] Switch to DigitalOcean mirror for MariaDB --- scripts/docker-install-phase4.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index c8b5ad6..f7606af 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -204,7 +204,7 @@ mv EmmyLua-LS-all.jar /usr/lib/EmmyLua-LS.jar # MariaDB ver="$(curl -sSL https://downloads.mariadb.org/ | grep 'href="/mariadb/[0-9]' | grep -Eo '[0-9][^/]+' | sort -rV | head -n1)" -wget -nv "https://downloads.mariadb.org/f/mariadb-${ver}/bintar-linux-x86_64/mariadb-${ver}-linux-x86_64.tar.gz/from/http%3A//mirror.dal.ca/mariadb/?serve" -O mariadb.tar.gz +wget -nv "https://downloads.mariadb.org/f/mariadb-${ver}/bintar-linux-x86_64/mariadb-${ver}-linux-x86_64.tar.gz/from/http%3A//sfo1.mirrors.digitalocean.com/mariadb/?serve" -O mariadb.tar.gz tar -xf mariadb.tar.gz mkdir /opt/mariadb mv mariadb-*-linux-x86_64/* /opt/mariadb/ From 7321737cd431dba18accb75c395825f593bca028 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 23 Aug 2020 10:37:34 -0600 Subject: [PATCH 267/388] Print number of tests run --- backend/src/test-runner.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/src/test-runner.ts b/backend/src/test-runner.ts index 09149fd..0ab8b06 100644 --- a/backend/src/test-runner.ts +++ b/backend/src/test-runner.ts @@ -637,6 +637,7 @@ async function main() { console.error("no tests selected"); process.exit(1); } + console.error(`Running ${tests.length} test${tests.length !== 1 ? "s" : ""}`); const lintSeen = new Set(); let lintPassed = new Set(); let lintFailed = new Map(); From a354f02ab4c92ba7fec3926f254d392adda26d2c Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 23 Aug 2020 10:47:22 -0600 Subject: [PATCH 268/388] New language: J --- backend/src/langs.ts | 9 +++++++++ scripts/docker-install-phase4.bash | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 0f07bd2..44d6791 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1169,6 +1169,15 @@ PLEASE GIVE UP `, timeout: 15, }, + j: { + aliases: ["jconsole", "ijconsole"], + name: "J", + repl: "echo 'ijconsole:' && ijconsole", + main: "main.ijs", + run: "ijconsole main.ijs", + template: `echo 'Hello, world!' +`, + }, java: { aliases: ["javac"], name: "Java", diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index f7606af..57d73f0 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -177,6 +177,11 @@ tar -xf ioke-ikj-*.tar.gz -C /opt rm ioke-ikj-*.tar.gz ln -s /opt/ioke/bin/ioke /usr/local/bin/ioke +# J +wget -nv "$(curl -sSL https://code.jsoftware.com/wiki/System/Installation/J901/Debian | grep -F ' Date: Sun, 23 Aug 2020 11:17:29 -0600 Subject: [PATCH 269/388] Alphabetize --- backend/src/langs.ts | 220 +++++++++++++++++++++---------------------- 1 file changed, 110 insertions(+), 110 deletions(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 44d6791..b56c0ab 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -392,6 +392,56 @@ int main() { printf("Hello, world!\\n"); return 0; } +`, + skip: ["lsp"], + }, + "c++": { + aliases: [ + "cpp", + "g++", + "clang++", + "c++98", + "c++03", + "c++11", + "c++14", + "c++17", + "c++20", + "cpp98", + "cpp03", + "cpp11", + "cpp14", + "cpp17", + "cpp20", + "hpp", + "cxx", + "hxx", + ], + name: "C++", + monacoLang: "cpp", + main: "main.cpp", + compile: "clang++ -Wall -Wextra main.cpp -o main", + run: "./main", + format: { + run: "clang-format --assume-filename=format.cpp", + input: `#include + +int main() +{ + std::cout << "Hello, world!" << std::endl; + return 0; +} +`, + }, + lsp: { + setup: `echo '-Wall -Wextra' | sed -E 's/\\s+/\\n/g' > compile_flags.txt`, + start: "clangd", + }, + template: `#include + +int main() { + std::cout << "Hello, world!" << std::endl; + return 0; +} `, skip: ["lsp"], }, @@ -478,6 +528,36 @@ Put milk chocolate into the mixing bowl. Liquefy contents of the mixing bowl. Pour contents of the mixing bowl into the baking dish. Refrigerate for 1 hour. +`, + }, + clojure: { + aliases: ["clj"], + name: "Clojure", + monacoLang: "clojure", + repl: "clojure", + input: "(* 123 234)", + main: "main.clj", + run: "clojure -i main.clj -r", + scope: { + code: `(def x (* 123 234))`, + }, + lsp: { start: "clojure-lsp" }, + template: `(println "Hello, world!") +`, + skip: ["lsp"], + }, + clojurescript: { + aliases: ["cljs", "lumo"], + name: "ClojureScript", + monacoLang: "clojure", + repl: "lumo -r", + input: "(* 123 234)", + main: "main.cljs", + run: "lumo -i main.cljs -r", + scope: { + code: `(def x (* 123 234))`, + }, + template: `(println "Hello, world!") `, }, cmd: { @@ -497,6 +577,36 @@ Refrigerate for 1 hour. `, timeout: 15, }, + cobol: { + aliases: ["cbl", "cobc"], + name: "COBOL", + main: "main.cbl", + compile: "cobc -free -x main.cbl -o main", + run: "./main", + template: `IDENTIFICATION DIVISION. +PROGRAM-ID. MAIN. +PROCEDURE DIVISION. + DISPLAY "Hello, world!". + STOP RUN. +`, + }, + coffeescript: { + aliases: ["coffee"], + name: "CoffeeScript", + monacoLang: "coffee", + repl: "coffee", + main: "main.coffee", + compile: "coffee -b -c main.coffee", + run: `node -e ' +eval.apply(this, [require("fs").readFileSync("main.js", {encoding: "utf-8"})]) +require("/usr/lib/node_modules/coffeescript/repl").start() +'`, + scope: { + code: `x = 123 * 234`, + }, + template: `console.log "Hello, world!" +`, + }, commonlisp: { aliases: ["lisp", "sbcl"], name: "Common Lisp", @@ -519,56 +629,6 @@ Refrigerate for 1 hour. template: `Hello, world! `, }, - "c++": { - aliases: [ - "cpp", - "g++", - "clang++", - "c++98", - "c++03", - "c++11", - "c++14", - "c++17", - "c++20", - "cpp98", - "cpp03", - "cpp11", - "cpp14", - "cpp17", - "cpp20", - "hpp", - "cxx", - "hxx", - ], - name: "C++", - monacoLang: "cpp", - main: "main.cpp", - compile: "clang++ -Wall -Wextra main.cpp -o main", - run: "./main", - format: { - run: "clang-format --assume-filename=format.cpp", - input: `#include - -int main() -{ - std::cout << "Hello, world!" << std::endl; - return 0; -} -`, - }, - lsp: { - setup: `echo '-Wall -Wextra' | sed -E 's/\\s+/\\n/g' > compile_flags.txt`, - start: "clangd", - }, - template: `#include - -int main() { - std::cout << "Hello, world!" << std::endl; - return 0; -} -`, - skip: ["lsp"], - }, crystal: { aliases: ["cr"], name: "Crystal", @@ -601,66 +661,6 @@ int main() { System.Console.WriteLine("Hello, world!"); } } -`, - }, - clojure: { - aliases: ["clj"], - name: "Clojure", - monacoLang: "clojure", - repl: "clojure", - input: "(* 123 234)", - main: "main.clj", - run: "clojure -i main.clj -r", - scope: { - code: `(def x (* 123 234))`, - }, - lsp: { start: "clojure-lsp" }, - template: `(println "Hello, world!") -`, - skip: ["lsp"], - }, - clojurescript: { - aliases: ["cljs", "lumo"], - name: "ClojureScript", - monacoLang: "clojure", - repl: "lumo -r", - input: "(* 123 234)", - main: "main.cljs", - run: "lumo -i main.cljs -r", - scope: { - code: `(def x (* 123 234))`, - }, - template: `(println "Hello, world!") -`, - }, - cobol: { - aliases: ["cbl", "cobc"], - name: "COBOL", - main: "main.cbl", - compile: "cobc -free -x main.cbl -o main", - run: "./main", - template: `IDENTIFICATION DIVISION. -PROGRAM-ID. MAIN. -PROCEDURE DIVISION. - DISPLAY "Hello, world!". - STOP RUN. -`, - }, - coffeescript: { - aliases: ["coffee"], - name: "CoffeeScript", - monacoLang: "coffee", - repl: "coffee", - main: "main.coffee", - compile: "coffee -b -c main.coffee", - run: `node -e ' -eval.apply(this, [require("fs").readFileSync("main.js", {encoding: "utf-8"})]) -require("/usr/lib/node_modules/coffeescript/repl").start() -'`, - scope: { - code: `x = 123 * 234`, - }, - template: `console.log "Hello, world!" `, }, d: { From cb6e2f84f868aeeb77c2c6bf8703de9d7578b438 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 23 Aug 2020 11:23:27 -0600 Subject: [PATCH 270/388] New language: Clean --- backend/src/langs.ts | 17 +++++++++++++++++ scripts/docker-install-phase6.bash | 10 ++++++++++ 2 files changed, 27 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index b56c0ab..b64d98f 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -528,6 +528,23 @@ Put milk chocolate into the mixing bowl. Liquefy contents of the mixing bowl. Pour contents of the mixing bowl into the baking dish. Refrigerate for 1 hour. +`, + }, + clean: { + aliases: ["icl", "clm"], + name: "Clean", + main: "main.icl", + compile: "clm main -o main", + run: "./main", + template: `module main + +import StdEnv + +Start world + #(console, world) = stdio world + #console = fwrites "Hello, world!\\n" console + #(ok, world) = fclose console world + = world `, }, clojure: { diff --git a/scripts/docker-install-phase6.bash b/scripts/docker-install-phase6.bash index 4c30a43..24a4ff6 100755 --- a/scripts/docker-install-phase6.bash +++ b/scripts/docker-install-phase6.bash @@ -31,6 +31,16 @@ pushd /opt/cat >/dev/null npm install popd >/dev/null +# Clean +wget -nv "$(curl -sSL https://clean.cs.ru.nl/Download_Clean | grep linux/clean | grep -F 64.tar.gz | grep -Eo "https://[^>]+\.tar\.gz")" +mkdir /opt/clean +tar -xf clean*_64.tar.gz -C /opt/clean --strip-components=1 +pushd /opt/clean >/dev/null +make +popd >/dev/null +ln -s /opt/clean/bin/clm /usr/local/bin/ +rm clean*_64.tar.gz + # Erlang git clone https://github.com/erlang-ls/erlang_ls.git pushd erlang_ls >/dev/null From 13904c38c74be7311c21f1207f9b2b19ff07afb5 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 23 Aug 2020 11:26:43 -0600 Subject: [PATCH 271/388] Use less disk space Turns out that I had it the way I did for a reason. This reverts commit 5592a92c1b28ebbea508858d3e88eeb58c2d02ba. --- scripts/deploy-phase2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/deploy-phase2.py b/scripts/deploy-phase2.py index 4881234..afd2bba 100755 --- a/scripts/deploy-phase2.py +++ b/scripts/deploy-phase2.py @@ -11,6 +11,7 @@ import tempfile import time subprocess.run(["docker", "pull", "ubuntu:rolling"], check=True) +subprocess.run(["docker", "system", "prune", "-f"], check=True) subprocess.run(["make", "image-prod"], check=True) existing_containers = subprocess.run( ["docker", "ps", "-q"], check=True, stdout=subprocess.PIPE @@ -20,6 +21,5 @@ if existing_containers: subprocess.run(["docker", "kill", *existing_containers], check=True) subprocess.run(["systemctl", "enable", "riju"], check=True) subprocess.run(["systemctl", "restart", "riju"], check=True) -subprocess.run(["docker", "system", "prune", "-f"], check=True) print("==> Successfully deployed Riju! <==", file=sys.stderr) From 72c99b00c6fe5f5c9e1e49fa15b4390cac1396b9 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 23 Aug 2020 13:26:44 -0600 Subject: [PATCH 272/388] New language: Koka --- backend/src/langs.ts | 13 +++++++++++++ scripts/docker-install-phase3b.bash | 3 +++ scripts/docker-install-phase6.bash | 10 ++++++++++ 3 files changed, 26 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index b64d98f..3b67e26 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1422,6 +1422,19 @@ PLEASE GIVE UP `, timeout: 15, }, + koka: { + aliases: ["kk"], + name: "Koka", + repl: "NODE_PATH=/opt/koka/node_modules rlwrap koka -i/opt/koka/lib", + main: "main.kk", + run: + "NODE_PATH=/opt/koka/node_modules rlwrap koka -i/opt/koka/lib main.kk; NODE_PATH=/opt/koka/node_modules rlwrap koka -i/opt/koka/lib", + template: `public fun main() : () +{ + println("Hello, world!") +} +`, + }, kotlin: { aliases: ["kts", "kotlinc"], name: "Kotlin", diff --git a/scripts/docker-install-phase3b.bash b/scripts/docker-install-phase3b.bash index 123e5ec..6413d3d 100755 --- a/scripts/docker-install-phase3b.bash +++ b/scripts/docker-install-phase3b.bash @@ -64,6 +64,9 @@ default-jdk # Julia julia +# Koka +rlwrap + # Ksh ksh diff --git a/scripts/docker-install-phase6.bash b/scripts/docker-install-phase6.bash index 24a4ff6..9ba51f2 100755 --- a/scripts/docker-install-phase6.bash +++ b/scripts/docker-install-phase6.bash @@ -62,6 +62,16 @@ mv src-kalyn/Stdlib src-kalyn/Stdlib.kalyn /opt/kalyn/ popd >/dev/null rm -rf kalyn +# Koka +git clone https://github.com/koka-lang/koka.git /opt/koka +pushd /opt/koka >/dev/null +npm install +npm install jake +npx jake compiler +popd >/dev/null +ln -s /opt/koka/out/debug/koka-* /usr/local/bin/koka +rm -rf koka + # LOLCODE git clone https://github.com/justinmeza/lci.git pushd lci >/dev/null From dd67746972e4aed5afba5355014ca7cd693ebd9c Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 23 Aug 2020 13:31:50 -0600 Subject: [PATCH 273/388] Yet another commit trying to fix CI timeouts --- Dockerfile.prod | 2 +- README.md | 2 +- backend/src/test-runner.ts | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Dockerfile.prod b/Dockerfile.prod index 4e05025..d70e973 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -68,4 +68,4 @@ RUN sudo cp -a /tmp/riju/* /home/docker/src/ && rm -rf /tmp/riju WORKDIR /home/docker/src RUN sudo deluser docker sudo -RUN RIJU_PRIVILEGED=1 CONCURRENCY=1 TIMEOUT_SECS=30 yarn test +RUN RIJU_PRIVILEGED=1 CONCURRENCY=1 TIMEOUT_FACTOR=5 yarn test diff --git a/README.md b/README.md index ac6c4ad..5c437bf 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ additional layers. You can build it as follows: Lastly I should mention the tests. There are integration tests for every language, and they can be run as follows: - $ [CONCURRENCY=2] [TIMEOUT=5] yarn test [...] + $ [CONCURRENCY=2] [TIMEOUT_FACTOR=1] yarn test [...] Filters can be for language (`python`, `java`) or test type (`hello`, `lsp`). You can comma-delimit multiple filters to do a disjunction, diff --git a/backend/src/test-runner.ts b/backend/src/test-runner.ts index 0ab8b06..025667a 100644 --- a/backend/src/test-runner.ts +++ b/backend/src/test-runner.ts @@ -15,8 +15,9 @@ function parseIntOr(thing: any, def: number) { return Number.isNaN(num) ? def : num; } -const TIMEOUT_SECS = parseIntOr(process.env.TIMEOUT_SECS, 5); +const TIMEOUT_FACTOR = parseIntOr(process.env.TIMEOUT_FACTOR, 1); const CONCURRENCY = parseIntOr(process.env.CONCURRENCY, 2); +const BASE_TIMEOUT_SECS = 5; function findPosition(str: string, idx: number) { const lines = str.substring(0, idx).split("\n"); @@ -103,7 +104,7 @@ class Test { timeout = setTimeout(() => { this.timedOut = true; this.handleUpdate(); - }, (this.config.timeout || TIMEOUT_SECS) * 1000); + }, (this.config.timeout || BASE_TIMEOUT_SECS) * 1000 * TIMEOUT_FACTOR); await session.setup(); switch (this.type) { case "ensure": From 46dd3711c39785359a2ad035635c3c9a381c6e01 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 23 Aug 2020 13:42:04 -0600 Subject: [PATCH 274/388] Install strace --- scripts/docker-install-phase2.bash | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/docker-install-phase2.bash b/scripts/docker-install-phase2.bash index 7c0ac19..9b6a2a6 100755 --- a/scripts/docker-install-phase2.bash +++ b/scripts/docker-install-phase2.bash @@ -33,6 +33,7 @@ nano ncdu iputils-ping ripgrep +strace sudo tmux trash-cli From d3c269ea667aa9354ad26c2413772e74186b7c71 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 23 Aug 2020 13:57:34 -0600 Subject: [PATCH 275/388] You *really* don't want to know --- scripts/docker-install-phase6.bash | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/docker-install-phase6.bash b/scripts/docker-install-phase6.bash index 9ba51f2..30b4ec4 100755 --- a/scripts/docker-install-phase6.bash +++ b/scripts/docker-install-phase6.bash @@ -41,6 +41,9 @@ popd >/dev/null ln -s /opt/clean/bin/clm /usr/local/bin/ rm clean*_64.tar.gz +sleep 2 +find /opt/clean -name '*.o' -exec touch '{}' ';' + # Erlang git clone https://github.com/erlang-ls/erlang_ls.git pushd erlang_ls >/dev/null From d5b1459410c9ba8800a33bb4c8054dfadc2db4e3 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 23 Aug 2020 17:11:24 -0600 Subject: [PATCH 276/388] Remove support for Koka Unfortunately, it is unusable due to excessive memory consumption. See https://github.com/koka-lang/koka/issues/34. This reverts commit 72c99b00c6fe5f5c9e1e49fa15b4390cac1396b9. --- backend/src/langs.ts | 13 ------------- scripts/docker-install-phase3b.bash | 3 --- scripts/docker-install-phase6.bash | 10 ---------- 3 files changed, 26 deletions(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 3b67e26..b64d98f 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1422,19 +1422,6 @@ PLEASE GIVE UP `, timeout: 15, }, - koka: { - aliases: ["kk"], - name: "Koka", - repl: "NODE_PATH=/opt/koka/node_modules rlwrap koka -i/opt/koka/lib", - main: "main.kk", - run: - "NODE_PATH=/opt/koka/node_modules rlwrap koka -i/opt/koka/lib main.kk; NODE_PATH=/opt/koka/node_modules rlwrap koka -i/opt/koka/lib", - template: `public fun main() : () -{ - println("Hello, world!") -} -`, - }, kotlin: { aliases: ["kts", "kotlinc"], name: "Kotlin", diff --git a/scripts/docker-install-phase3b.bash b/scripts/docker-install-phase3b.bash index 6413d3d..123e5ec 100755 --- a/scripts/docker-install-phase3b.bash +++ b/scripts/docker-install-phase3b.bash @@ -64,9 +64,6 @@ default-jdk # Julia julia -# Koka -rlwrap - # Ksh ksh diff --git a/scripts/docker-install-phase6.bash b/scripts/docker-install-phase6.bash index 30b4ec4..318d7f0 100755 --- a/scripts/docker-install-phase6.bash +++ b/scripts/docker-install-phase6.bash @@ -65,16 +65,6 @@ mv src-kalyn/Stdlib src-kalyn/Stdlib.kalyn /opt/kalyn/ popd >/dev/null rm -rf kalyn -# Koka -git clone https://github.com/koka-lang/koka.git /opt/koka -pushd /opt/koka >/dev/null -npm install -npm install jake -npx jake compiler -popd >/dev/null -ln -s /opt/koka/out/debug/koka-* /usr/local/bin/koka -rm -rf koka - # LOLCODE git clone https://github.com/justinmeza/lci.git pushd lci >/dev/null From d93d4382ef06173e97fc960aed02b0b32fd0c3b9 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 23 Aug 2020 17:49:47 -0600 Subject: [PATCH 277/388] New language: Unison --- backend/src/langs.ts | 24 ++++++++++++++++++++++++ backend/src/test-runner.ts | 25 ++++++++++++++++--------- scripts/docker-install-phase4.bash | 4 ++++ scripts/docker-install-phase7.bash | 7 +++++++ 4 files changed, 51 insertions(+), 9 deletions(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index b64d98f..8a77480 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2500,6 +2500,30 @@ a `, timeout: 15, }, + unison: { + aliases: ["ucm"], + name: "Unison", + setup: "shopt -s dotglob && cp -R /opt/unison/project-template/* ./", + repl: "unison -codebase .", + input: "find : [a] -> [a]", + output: "base.List.reverse", + main: "main.u", + run: `echo "Type 'run main' to run the code." && unison -codebase .`, + helloInput: "run main", + scope: { + code: `x = 123 * 234`, + input: `DELAY: 1 +add x +DELAY: 0.5 +display x`, + }, + template: `use io + +main : '{IO} () +main = 'let + printLine "Hello, world!" +`, + }, unlambda: { aliases: ["unl"], name: "Unlambda", diff --git a/backend/src/test-runner.ts b/backend/src/test-runner.ts index 025667a..fad3ba9 100644 --- a/backend/src/test-runner.ts +++ b/backend/src/test-runner.ts @@ -26,8 +26,18 @@ function findPosition(str: string, idx: number) { return { line, character }; } -function forTTY(input: string) { - return input.replace(/\n/g, "\r") + "\r"; +async function sendInput(send: (msg: any) => any, input: string) { + for (const line of input.split("\n")) { + if (line.startsWith("DELAY:")) { + const delay = parseFloat(line.replace(/DELAY: */, "")); + if (Number.isNaN(delay)) continue; + await new Promise((resolve) => + setTimeout(resolve, delay * 1000 * TIMEOUT_FACTOR) + ); + } else { + send({ event: "terminalInput", input: line + "\r" }); + } + } } class Test { @@ -196,24 +206,21 @@ class Test { const pattern = this.config.hello || "Hello, world!"; this.send({ event: "runCode", code: this.config.template }); if (this.config.helloInput !== undefined) { - this.send({ - event: "terminalInput", - input: forTTY(this.config.helloInput), - }); + sendInput(this.send, this.config.helloInput); } await this.waitForOutput(pattern, this.config.helloMaxLength); }; testRepl = async () => { const input = this.config.input || "123 * 234"; const output = this.config.output || "28782"; - this.send({ event: "terminalInput", input: forTTY(input) }); + sendInput(this.send, input); await this.waitForOutput(output); }; testRunRepl = async () => { const input = this.config.runReplInput || this.config.input || "123 * 234"; const output = this.config.runReplOutput || this.config.output || "28782"; this.send({ event: "runCode", code: this.config.template }); - this.send({ event: "terminalInput", input: forTTY(input) }); + sendInput(this.send, input); await this.waitForOutput(output); }; testScope = async () => { @@ -231,7 +238,7 @@ class Test { allCode = allCode + code + "\n"; } this.send({ event: "runCode", code: allCode }); - this.send({ event: "terminalInput", input: forTTY(input) }); + sendInput(this.send, input); await this.waitForOutput(output); }; testFormat = async () => { diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 57d73f0..74f1cf1 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -284,5 +284,9 @@ ln -s /opt/swift/bin/swiftc /usr/local/bin/swiftc ln -s /opt/swift/bin/sourcekit-lsp /usr/local/bin/sourcekit-lsp rm swift.tar.gz +# Unison +wget -nv https://github.com/raxod502/riju-cdn/releases/download/unison-M1l-232-519cbeb58704c1b9410c9386e492be59fd5a5334/unison -O /usr/local/bin/unison +chmod +x /usr/local/bin/unison + popd >/dev/null rm "$0" diff --git a/scripts/docker-install-phase7.bash b/scripts/docker-install-phase7.bash index 5482ddb..3067935 100755 --- a/scripts/docker-install-phase7.bash +++ b/scripts/docker-install-phase7.bash @@ -71,6 +71,13 @@ cat bsconfig.json | jq '.name = "riju-project"' | sponge bsconfig.json yarn install popd >/dev/null +# Unison +mkdir -p /opt/unison/project-template +pushd /opt/unison/project-template >/dev/null +unison -codebase . init +LESS="+q" unison -codebase . <<< 'pull https://github.com/unisonweb/base:.trunk .base' +popd >/dev/null + # Befunge tee /usr/local/bin/befunge-repl >/dev/null <<"EOF" #!/usr/bin/env -S NODE_PATH=/usr/lib/node_modules node From bb4c3f22eecdcf65c396daaed9c6c9df2a85bb5f Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 23 Aug 2020 17:51:00 -0600 Subject: [PATCH 278/388] Report timing information during Docker build --- Dockerfile.dev | 24 ++++++++++++------------ Dockerfile.prod | 32 ++++++++++++++++---------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/Dockerfile.dev b/Dockerfile.dev index cb94943..5e547d8 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -5,40 +5,40 @@ ARG UID COPY scripts/my_init /usr/bin/my_init COPY scripts/docker-install-phase0.bash /tmp/ -RUN /tmp/docker-install-phase0.bash +RUN time /tmp/docker-install-phase0.bash COPY scripts/docker-install-phase1.bash /tmp/ -RUN /tmp/docker-install-phase1.bash +RUN time /tmp/docker-install-phase1.bash COPY scripts/docker-install-phase2.bash /tmp/ -RUN /tmp/docker-install-phase2.bash +RUN time /tmp/docker-install-phase2.bash COPY scripts/docker-install-phase3a.bash /tmp/ -RUN /tmp/docker-install-phase3a.bash +RUN time /tmp/docker-install-phase3a.bash COPY scripts/docker-install-phase3b.bash /tmp/ -RUN /tmp/docker-install-phase3b.bash +RUN time /tmp/docker-install-phase3b.bash COPY scripts/docker-install-phase3c.bash /tmp/ -RUN /tmp/docker-install-phase3c.bash +RUN time /tmp/docker-install-phase3c.bash COPY scripts/docker-install-phase3d.bash /tmp/ -RUN /tmp/docker-install-phase3d.bash +RUN time /tmp/docker-install-phase3d.bash COPY scripts/docker-install-phase4.bash /tmp/ -RUN /tmp/docker-install-phase4.bash +RUN time /tmp/docker-install-phase4.bash COPY scripts/docker-install-phase5.bash /tmp/ -RUN /tmp/docker-install-phase5.bash +RUN time /tmp/docker-install-phase5.bash COPY scripts/docker-install-phase6.bash /tmp/ -RUN /tmp/docker-install-phase6.bash +RUN time /tmp/docker-install-phase6.bash COPY scripts/docker-install-phase7.bash /tmp/ -RUN /tmp/docker-install-phase7.bash +RUN time /tmp/docker-install-phase7.bash COPY scripts/docker-install-phase8.bash /tmp/ -RUN /tmp/docker-install-phase8.bash "$UID" +RUN time /tmp/docker-install-phase8.bash "$UID" USER docker WORKDIR /home/docker diff --git a/Dockerfile.prod b/Dockerfile.prod index d70e973..8f411eb 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -7,40 +7,40 @@ ARG UID COPY scripts/my_init /usr/bin/my_init COPY scripts/docker-install-phase0.bash /tmp/ -RUN /tmp/docker-install-phase0.bash +RUN time /tmp/docker-install-phase0.bash COPY scripts/docker-install-phase1.bash /tmp/ -RUN /tmp/docker-install-phase1.bash +RUN time /tmp/docker-install-phase1.bash COPY scripts/docker-install-phase2.bash /tmp/ -RUN /tmp/docker-install-phase2.bash +RUN time /tmp/docker-install-phase2.bash COPY scripts/docker-install-phase3a.bash /tmp/ -RUN /tmp/docker-install-phase3a.bash +RUN time /tmp/docker-install-phase3a.bash COPY scripts/docker-install-phase3b.bash /tmp/ -RUN /tmp/docker-install-phase3b.bash +RUN time /tmp/docker-install-phase3b.bash COPY scripts/docker-install-phase3c.bash /tmp/ -RUN /tmp/docker-install-phase3c.bash +RUN time /tmp/docker-install-phase3c.bash COPY scripts/docker-install-phase3d.bash /tmp/ -RUN /tmp/docker-install-phase3d.bash +RUN time /tmp/docker-install-phase3d.bash COPY scripts/docker-install-phase4.bash /tmp/ -RUN /tmp/docker-install-phase4.bash +RUN time /tmp/docker-install-phase4.bash COPY scripts/docker-install-phase5.bash /tmp/ -RUN /tmp/docker-install-phase5.bash +RUN time /tmp/docker-install-phase5.bash COPY scripts/docker-install-phase6.bash /tmp/ -RUN /tmp/docker-install-phase6.bash +RUN time /tmp/docker-install-phase6.bash COPY scripts/docker-install-phase7.bash /tmp/ -RUN /tmp/docker-install-phase7.bash +RUN time /tmp/docker-install-phase7.bash COPY scripts/docker-install-phase8.bash /tmp/ -RUN /tmp/docker-install-phase8.bash "$UID" +RUN time /tmp/docker-install-phase8.bash "$UID" USER docker WORKDIR /home/docker @@ -54,15 +54,15 @@ CMD ["yarn", "run", "server"] RUN mkdir /tmp/riju /tmp/riju/scripts COPY --chown=docker:docker package.json yarn.lock /tmp/riju/ -RUN cd /tmp/riju && yarn install +RUN time cd /tmp/riju && yarn install COPY --chown=docker:docker webpack.config.js tsconfig.json tsconfig-webpack.json /tmp/riju/ COPY --chown=docker:docker frontend /tmp/riju/frontend -RUN cd /tmp/riju && yarn run frontend +RUN time cd /tmp/riju && yarn run frontend COPY --chown=docker:docker backend /tmp/riju/backend -RUN cd /tmp/riju && yarn run backend +RUN time cd /tmp/riju && yarn run backend COPY --chown=docker:docker scripts/compile-system.bash /tmp/riju/scripts COPY --chown=docker:docker system /tmp/riju/system -RUN cd /tmp/riju && RIJU_PRIVILEGED=1 yarn run system +RUN time cd /tmp/riju && RIJU_PRIVILEGED=1 yarn run system COPY --chown=docker:docker . /home/docker/src RUN sudo cp -a /tmp/riju/* /home/docker/src/ && rm -rf /tmp/riju From a16ee4b2baa1052ed206a7cb496979cd1b215409 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 23 Aug 2020 19:55:24 -0600 Subject: [PATCH 279/388] Fix last error for production image build --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7550eb2..fd1b757 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,6 @@ "dev": "run-p backend-dev frontend-dev system-dev server-dev", "lsp-repl": "node backend/out/lsp-repl.js", "sandbox": "node backend/out/sandbox.js", - "test": "bash -c 'time node backend/out/test-runner.js \"$@\"' --" + "test": "bash -c 'scripts/setup.bash && time node backend/out/test-runner.js \"$@\"' --" } } From 0db55ffbcb8a592ddbd0272709f5a54e6bea053f Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 23 Aug 2020 20:12:13 -0600 Subject: [PATCH 280/388] Adjust syntax properly for time commands --- Dockerfile.dev | 24 ++++++++++++------------ Dockerfile.prod | 32 ++++++++++++++++---------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/Dockerfile.dev b/Dockerfile.dev index 5e547d8..8031b5c 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -5,40 +5,40 @@ ARG UID COPY scripts/my_init /usr/bin/my_init COPY scripts/docker-install-phase0.bash /tmp/ -RUN time /tmp/docker-install-phase0.bash +RUN bash -c "time /tmp/docker-install-phase0.bash" COPY scripts/docker-install-phase1.bash /tmp/ -RUN time /tmp/docker-install-phase1.bash +RUN bash -c "time /tmp/docker-install-phase1.bash" COPY scripts/docker-install-phase2.bash /tmp/ -RUN time /tmp/docker-install-phase2.bash +RUN bash -c "time /tmp/docker-install-phase2.bash" COPY scripts/docker-install-phase3a.bash /tmp/ -RUN time /tmp/docker-install-phase3a.bash +RUN bash -c "time /tmp/docker-install-phase3a.bash" COPY scripts/docker-install-phase3b.bash /tmp/ -RUN time /tmp/docker-install-phase3b.bash +RUN bash -c "time /tmp/docker-install-phase3b.bash" COPY scripts/docker-install-phase3c.bash /tmp/ -RUN time /tmp/docker-install-phase3c.bash +RUN bash -c "time /tmp/docker-install-phase3c.bash" COPY scripts/docker-install-phase3d.bash /tmp/ -RUN time /tmp/docker-install-phase3d.bash +RUN bash -c "time /tmp/docker-install-phase3d.bash" COPY scripts/docker-install-phase4.bash /tmp/ -RUN time /tmp/docker-install-phase4.bash +RUN bash -c "time /tmp/docker-install-phase4.bash" COPY scripts/docker-install-phase5.bash /tmp/ -RUN time /tmp/docker-install-phase5.bash +RUN bash -c "time /tmp/docker-install-phase5.bash" COPY scripts/docker-install-phase6.bash /tmp/ -RUN time /tmp/docker-install-phase6.bash +RUN bash -c "time /tmp/docker-install-phase6.bash" COPY scripts/docker-install-phase7.bash /tmp/ -RUN time /tmp/docker-install-phase7.bash +RUN bash -c "time /tmp/docker-install-phase7.bash" COPY scripts/docker-install-phase8.bash /tmp/ -RUN time /tmp/docker-install-phase8.bash "$UID" +RUN bash -c "time /tmp/docker-install-phase8.bash '$UID'" USER docker WORKDIR /home/docker diff --git a/Dockerfile.prod b/Dockerfile.prod index 8f411eb..9e364dd 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -7,40 +7,40 @@ ARG UID COPY scripts/my_init /usr/bin/my_init COPY scripts/docker-install-phase0.bash /tmp/ -RUN time /tmp/docker-install-phase0.bash +RUN bash -c "time /tmp/docker-install-phase0.bash" COPY scripts/docker-install-phase1.bash /tmp/ -RUN time /tmp/docker-install-phase1.bash +RUN bash -c "time /tmp/docker-install-phase1.bash" COPY scripts/docker-install-phase2.bash /tmp/ -RUN time /tmp/docker-install-phase2.bash +RUN bash -c "time /tmp/docker-install-phase2.bash" COPY scripts/docker-install-phase3a.bash /tmp/ -RUN time /tmp/docker-install-phase3a.bash +RUN bash -c "time /tmp/docker-install-phase3a.bash" COPY scripts/docker-install-phase3b.bash /tmp/ -RUN time /tmp/docker-install-phase3b.bash +RUN bash -c "time /tmp/docker-install-phase3b.bash" COPY scripts/docker-install-phase3c.bash /tmp/ -RUN time /tmp/docker-install-phase3c.bash +RUN bash -c "time /tmp/docker-install-phase3c.bash" COPY scripts/docker-install-phase3d.bash /tmp/ -RUN time /tmp/docker-install-phase3d.bash +RUN bash -c "time /tmp/docker-install-phase3d.bash" COPY scripts/docker-install-phase4.bash /tmp/ -RUN time /tmp/docker-install-phase4.bash +RUN bash -c "time /tmp/docker-install-phase4.bash" COPY scripts/docker-install-phase5.bash /tmp/ -RUN time /tmp/docker-install-phase5.bash +RUN bash -c "time /tmp/docker-install-phase5.bash" COPY scripts/docker-install-phase6.bash /tmp/ -RUN time /tmp/docker-install-phase6.bash +RUN bash -c "time /tmp/docker-install-phase6.bash" COPY scripts/docker-install-phase7.bash /tmp/ -RUN time /tmp/docker-install-phase7.bash +RUN bash -c "time /tmp/docker-install-phase7.bash" COPY scripts/docker-install-phase8.bash /tmp/ -RUN time /tmp/docker-install-phase8.bash "$UID" +RUN bash -c "time /tmp/docker-install-phase8.bash '$UID'" USER docker WORKDIR /home/docker @@ -54,15 +54,15 @@ CMD ["yarn", "run", "server"] RUN mkdir /tmp/riju /tmp/riju/scripts COPY --chown=docker:docker package.json yarn.lock /tmp/riju/ -RUN time cd /tmp/riju && yarn install +RUN bash -c "cd /tmp/riju && time yarn install" COPY --chown=docker:docker webpack.config.js tsconfig.json tsconfig-webpack.json /tmp/riju/ COPY --chown=docker:docker frontend /tmp/riju/frontend -RUN time cd /tmp/riju && yarn run frontend +RUN bash -c "cd /tmp/riju && time yarn run frontend" COPY --chown=docker:docker backend /tmp/riju/backend -RUN time cd /tmp/riju && yarn run backend +RUN bash -c "cd /tmp/riju && time yarn run backend" COPY --chown=docker:docker scripts/compile-system.bash /tmp/riju/scripts COPY --chown=docker:docker system /tmp/riju/system -RUN time cd /tmp/riju && RIJU_PRIVILEGED=1 yarn run system +RUN bash -c "cd /tmp/riju && time RIJU_PRIVILEGED=1 yarn run system" COPY --chown=docker:docker . /home/docker/src RUN sudo cp -a /tmp/riju/* /home/docker/src/ && rm -rf /tmp/riju From 68ee3469a16c52687099ca0675bb560b4659a264 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 23 Aug 2020 20:14:36 -0600 Subject: [PATCH 281/388] Fix typo --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5c437bf..ffe9919 100644 --- a/README.md +++ b/README.md @@ -67,8 +67,8 @@ every language, and they can be run as follows: Filters can be for language (`python`, `java`) or test type (`hello`, `lsp`). You can comma-delimit multiple filters to do a disjunction, -and space-delimit them to do a conjunction (`hello python,java`) for -the `hello` tests for `python` and `java`. +and space-delimit them to do a conjunction (`yarn test hello +python,java` for the `hello` tests for `python` and `java`). The tests are run automatically when building the production image, and fail the build if they fail. From a02b4a08d3dda53d14bd56c95c7f22549f70a527 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Tue, 25 Aug 2020 07:17:49 -0600 Subject: [PATCH 282/388] [#29] Add criteria for language inclusion --- README.md | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/README.md b/README.md index ffe9919..eb29e21 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,77 @@ etc.)** This project is a work in progress, and I don't intend on thoroughly documenting it until it has reached feature-completeness. +## Criteria for language inclusion + +I aspire for Riju to support more languages than any reasonable person +could conceivably think is reasonable. That said, there are some +requirements: + +* **Language must have a clear notion of execution.** This is because + a core part of Riju is the ability to execute code. Languages like + [YAML](https://yaml.org/), [SCSS](https://sass-lang.com/), and + Markdown are fine because they have a canonical transformation (into + [JSON](https://www.json.org/json-en.html), + [CSS](https://developer.mozilla.org/en-US/docs/Web/CSS), and + [HTML](https://developer.mozilla.org/en-US/docs/Web/HTML) + respectively) that can be performed on execution. However, languages + like JSON, CSS, and HTML are not acceptable, because there's nothing + reasonable to do when they are run. +* **Language must not require input or configuration.** This is + because, in order to avoid bloating the interface, Riju provides a + way to supply code but not any other data. Of course, it's possible + to supply input interactively, so reading stdin is allowed, but if a + language can only reasonably be programmed with additional input, + it's not a candidate for inclusion. Thus, many templating languages + are excluded, since they don't do anything unless you are + substituting a value. However, some languages such as + [Pug](https://pugjs.org/) are allowed, because they implement a + significant syntax transformation outside of template substitution. + Also, languages like [Sed](https://www.gnu.org/software/sed/) and + [Awk](https://www.gnu.org/software/gawk/) are allowed, because it's + straightforward to test code written in them even without a + pre-prepared input file. +* **Language must not require a graphical environment.** This is + because we use a pty to run code, and there is no X forwarding. As + such, we can't use languages like + [Scratch](https://scratch.mit.edu/), + [Alice](https://www.alice.org/), and + [Linotte](http://langagelinotte.free.fr/wordpress/). +* **Language must be available for free under a permissive license.** + This is because we must download and install all languages + noninteractively in the Docker image build, so anything that + requires license registration is unlikely to work (or be legal). We + can't use [Mathematica](https://www.wolfram.com/mathematica/) or + [MATLAB](https://www.mathworks.com/products/matlab.html), for + example, but we can use [Mathics](https://mathics.github.io/) and + [Octave](https://www.gnu.org/software/octave/), which provide + compatible open-source implementations of the underlying languages. +* **Language must be runnable under Docker on Linux.** This is because + that's the execution environment we have access to. + [AppleScript](https://en.wikipedia.org/wiki/AppleScript) is out + because it only runs on macOS, and [Docker](https://www.docker.com/) + is out because it can't be run inside Docker (without the + `--privileged` flag, which has unacceptable security drawbacks; see + [#29](https://github.com/raxod502/riju/issues/29)). Note, however, + that many Windows-based languages can be used successfully via + [Mono](https://www.mono-project.com/) or + [Wine](https://www.winehq.org/), such as + [Cmd](https://en.wikipedia.org/wiki/Cmd.exe), + [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)), + and [Visual Basic](https://en.wikipedia.org/wiki/Visual_Basic). + +Here are some explicit *non-requirements*: + +* *Language must be well-known.* Nope, I'll be happy to add your pet + project; after all, [Kalyn](https://github.com/raxod502/kalyn) and + [Ink](https://github.com/thesephist/ink) are already supported. +* *Language must be useful.* I would have no objection to adding + everything on the esolangs wiki, if there are interpreters/compilers + available. +* *Language must be easy to install and run.* Well, it would be nice, + but I've seen some s\*\*\* when adding languages to Riju so it will + take a lot to surprise me at this point. + ## Project setup To run the webserver, all you need is Yarn. Just run `yarn install` as From 2835716541909419a6fc04f71b4bbe8af5fdecef Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Tue, 25 Aug 2020 07:19:38 -0600 Subject: [PATCH 283/388] [#29] Add pointer to language support meta-issue --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index eb29e21..01ff7e4 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,11 @@ Here are some explicit *non-requirements*: but I've seen some s\*\*\* when adding languages to Riju so it will take a lot to surprise me at this point. +If you'd like to request a new language, head to the [language support +meta-issue](https://github.com/raxod502/riju/issues/24) and add a +comment. Of course, if you actually want it to be added anytime soon, +you should submit a pull request :) + ## Project setup To run the webserver, all you need is Yarn. Just run `yarn install` as From 01f3d3648b85542f14f5fe0b657403f0286204e8 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Wed, 26 Aug 2020 17:43:05 -0600 Subject: [PATCH 284/388] Try to fix Unison tests --- backend/src/langs.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 8a77480..fcd16f7 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2505,16 +2505,18 @@ a name: "Unison", setup: "shopt -s dotglob && cp -R /opt/unison/project-template/* ./", repl: "unison -codebase .", - input: "find : [a] -> [a]", + input: `DELAY: 3 +find : [a] -> [a]`, output: "base.List.reverse", main: "main.u", run: `echo "Type 'run main' to run the code." && unison -codebase .`, - helloInput: "run main", + helloInput: `DELAY: 3 +run main`, scope: { code: `x = 123 * 234`, - input: `DELAY: 1 + input: `DELAY: 3 add x -DELAY: 0.5 +DELAY: 3 display x`, }, template: `use io @@ -2523,6 +2525,7 @@ main : '{IO} () main = 'let printLine "Hello, world!" `, + timeout: 15, }, unlambda: { aliases: ["unl"], From 84707457fc991618e0306dfe594ec80dee38233f Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Thu, 27 Aug 2020 07:02:38 -0600 Subject: [PATCH 285/388] Workaround bug in Unison --- Dockerfile.prod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile.prod b/Dockerfile.prod index 9e364dd..5fa7241 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -68,4 +68,4 @@ RUN sudo cp -a /tmp/riju/* /home/docker/src/ && rm -rf /tmp/riju WORKDIR /home/docker/src RUN sudo deluser docker sudo -RUN RIJU_PRIVILEGED=1 CONCURRENCY=1 TIMEOUT_FACTOR=5 yarn test +RUN RIJU_PRIVILEGED=1 CONCURRENCY=1 TIMEOUT_FACTOR=5 LANG=C.UTF-8 LC_ALL=C.UTF-8 yarn test From 8222937a0627d8b6d2276cf89fbbcf2936f9956d Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Wed, 2 Sep 2020 08:26:38 -0600 Subject: [PATCH 286/388] [#34] Show timing info for tests, bump Cmd timeout --- backend/src/langs.ts | 2 +- backend/src/test-runner.ts | 15 ++++++++++++--- package.json | 1 + yarn.lock | 5 +++++ 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index fcd16f7..d419488 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -592,7 +592,7 @@ Start world }, template: `echo "Hello, world!" `, - timeout: 15, + timeout: 30, }, cobol: { aliases: ["cbl", "cobc"], diff --git a/backend/src/test-runner.ts b/backend/src/test-runner.ts index fad3ba9..999ee83 100644 --- a/backend/src/test-runner.ts +++ b/backend/src/test-runner.ts @@ -3,6 +3,8 @@ import * as process from "process"; import { promisify } from "util"; import * as _ from "lodash"; +import { Moment } from "moment"; +import * as moment from "moment"; import PQueue from "p-queue"; import * as rimraf from "rimraf"; import { v4 as getUUID } from "uuid"; @@ -47,6 +49,7 @@ class Test { timedOut: boolean = false; handledMessages: number = 0; handleUpdate: () => void = () => {}; + startTime: Moment | null = null; get config() { return langs[this.lang]; @@ -54,9 +57,14 @@ class Test { ws: any = null; + record = (msg: any) => { + const dur = moment.duration(moment().diff(this.startTime!)); + this.messages.push({ time: dur.asSeconds(), ...msg }); + }; + send = (msg: any) => { this.ws.onMessage(JSON.stringify(msg)); - this.messages.push(msg); + this.record(msg); this.handledMessages += 1; }; @@ -76,6 +84,7 @@ class Test { if ((this.config.skip || []).includes(this.type)) { return "skipped"; } + this.startTime = moment(); let session = null; let timeout = null; try { @@ -103,13 +112,13 @@ class Test { }, messageQueue: [] as any[], send: function (data: string) { - that.messages.push(JSON.parse(data)); + that.record(JSON.parse(data)); that.handleUpdate(); }, terminate: function () {}, }; session = new api.Session(this.ws, this.lang, (msg: string) => { - this.messages.push({ event: "serverLog", message: msg }); + this.record({ event: "serverLog", message: msg }); }); timeout = setTimeout(() => { this.timedOut = true; diff --git a/package.json b/package.json index fd1b757..c58174e 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "file-loader": "^6.0.0", "historic-readline": "^1.0.8", "lodash": "^4.17.15", + "moment": "^2.27.0", "monaco-editor": "^0.20.0", "monaco-editor-webpack-plugin": "^1.9.0", "monaco-languageclient": "^0.13.0", diff --git a/yarn.lock b/yarn.lock index 045d049..27ba20a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3374,6 +3374,11 @@ mocha@^5.2.0: mkdirp "0.5.1" supports-color "5.4.0" +moment@^2.27.0: + version "2.27.0" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.27.0.tgz#8bff4e3e26a236220dfe3e36de756b6ebaa0105d" + integrity sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ== + monaco-editor-webpack-plugin@^1.9.0: version "1.9.0" resolved "https://registry.yarnpkg.com/monaco-editor-webpack-plugin/-/monaco-editor-webpack-plugin-1.9.0.tgz#5b547281b9f404057dc5d8c5722390df9ac90be6" From 28029e045de08e3ea1fcb4c90008a8b1f66d7950 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 26 Sep 2020 07:19:07 -0700 Subject: [PATCH 287/388] [#24] New language: Tabloid --- backend/src/langs.ts | 9 +++++++++ scripts/docker-install-phase6.bash | 9 +++++++++ scripts/docker-install-phase7.bash | 21 +++++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index d419488..dfdb03f 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2385,6 +2385,15 @@ END `, skip: ["lsp"], }, + tabloid: { + name: "Tabloid", + main: "main.tabloid", + run: "node /opt/tabloid/run.js main.tabloid", + hello: "HELLO, WORLD!", + template: `YOU WON'T WANT TO MISS "Hello, world" +PLEASE LIKE AND SUBSCRIBE +`, + }, tcl: { aliases: ["tclsh", "tclshrc"], name: "Tcl", diff --git a/scripts/docker-install-phase6.bash b/scripts/docker-install-phase6.bash index 318d7f0..d415d08 100755 --- a/scripts/docker-install-phase6.bash +++ b/scripts/docker-install-phase6.bash @@ -104,6 +104,15 @@ mv snobol4 /usr/local/bin/snobol4 popd >/dev/null rm -rf snobol4-* +# Tabloid +mkdir /opt/tabloid +pushd /opt/tabloid >/dev/null +wget -nv https://github.com/thesephist/tabloid/raw/master/static/js/lang.js +cat <<"EOF" >> lang.js +module.exports = { tokenize, Parser, Environment }; +EOF +popd >/dev/null + # Thue wget -nv "$(curl -sSL https://catseye.tc/distribution/Thue_distribution | grep -Eo 'https://catseye.tc/distfiles/thue-[^"]+\.zip' | head -n1)" unzip thue-*.zip diff --git a/scripts/docker-install-phase7.bash b/scripts/docker-install-phase7.bash index 3067935..742e467 100755 --- a/scripts/docker-install-phase7.bash +++ b/scripts/docker-install-phase7.bash @@ -216,6 +216,27 @@ if (program !== null) { repl.start({prompt: "قلب> ", eval: (cmd, context, filename, callback) => callback(null, Qlb.execute(cmd))}); EOF +# Tabloid +tee /opt/tabloid/run.js >/dev/null <<"EOF" +const fs = require("fs"); + +const args = process.argv.slice(2); +if (args.length !== 1) { + console.error("usage: run.js FILE"); + process.exit(1); +} + +const lang = require("./lang"); + +const program = fs.readFileSync(args[0], "utf-8"); +const tokens = lang.tokenize(program); +const parser = new lang.Parser(tokens); +const ast = parser.parse(); +const runtime = { print: (s) => console.log(s.toString().toUpperCase() + "!") }; +const env = new lang.Environment(runtime); +env.run(ast); +EOF + # Unlambda tee /usr/local/bin/unlambda-repl >/dev/null <<"EOF" #!/usr/bin/env python3 From 4ded0f1380c20204aa2fa00f910a0bd7d7136562 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 26 Sep 2020 07:33:00 -0700 Subject: [PATCH 288/388] [#24] New language: HMMM --- backend/src/langs.ts | 50 ++++++++++++++++++++++++++++++ backend/src/test-runner.ts | 1 + scripts/docker-install-phase4.bash | 4 +++ 3 files changed, 55 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index dfdb03f..475c68d 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1124,6 +1124,56 @@ l ; ; o ; * 4 3 3 ; @ . > ; 2 3 < \\ 4 ; * / +`, + }, + hmmm: { + name: "HMMM", + main: "main.hmmm", + run: "hmmm main.hmmm", + hello: `72 +101 +108 +108 +111 +44 +32 +119 +111 +114 +108 +100 +33 +10 +`, + template: ` 0 setn r1, 72 + 1 write r1 + 2 setn r1, 101 + 3 write r1 + 4 setn r1, 108 + 5 write r1 + 6 setn r1, 108 + 7 write r1 + 8 setn r1, 111 + 9 write r1 +10 setn r1, 44 +11 write r1 +12 setn r1, 32 +13 write r1 +14 setn r1, 119 +15 write r1 +16 setn r1, 111 +17 write r1 +18 setn r1, 114 +19 write r1 +20 setn r1, 108 +21 write r1 +22 setn r1, 100 +23 write r1 +24 setn r1, 33 +25 write r1 +26 setn r1, 10 +27 write r1 +28 halt `, }, hy: { diff --git a/backend/src/test-runner.ts b/backend/src/test-runner.ts index 999ee83..9de15c5 100644 --- a/backend/src/test-runner.ts +++ b/backend/src/test-runner.ts @@ -182,6 +182,7 @@ class Test { }; waitForOutput = async (pattern: string, maxLength?: number) => { + pattern = pattern.replace(/\n/g, "\r\n"); let output = ""; return await this.wait(`output ${JSON.stringify(pattern)}`, (msg: any) => { const prevLength = output.length; diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 74f1cf1..1e7127c 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -161,6 +161,10 @@ wget -nv "https://github.com/sclevine/yj/releases/download/${ver}/yj-linux" chmod +x yj-linux mv yj-linux /usr/local/bin/yj +# HMMM +wget -nv https://www.cs.hmc.edu/~cs5grad/cs5/hmmm/code/hmmm -O /usr/local/bin/hmmm +chmod +x /usr/local/bin/hmmm + # Ink ver="$(latest_release thesephist/ink)" wget -nv "https://github.com/thesephist/ink/releases/download/${ver}/ink-linux" From 64d25f55108d9059bf1c4b8c21d835ea07e24218 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 26 Sep 2020 07:46:50 -0700 Subject: [PATCH 289/388] [#24] New language: Scilab --- backend/src/langs.ts | 10 ++++++++++ scripts/docker-install-phase3d.bash | 3 +++ 2 files changed, 13 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 475c68d..5629988 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2219,6 +2219,16 @@ binding_irb.run(IRB.conf) (newline) `, }, + scilab: { + aliases: ["sci"], + name: "Scilab", + repl: "scilab-cli", + main: "main.sci", + run: "scilab-cli -f main.sci", + template: `disp("Hello, world!") +`, + skip: ["repl", "runrepl"], + }, scss: { name: "SCSS", monacoLang: "scss", diff --git a/scripts/docker-install-phase3d.bash b/scripts/docker-install-phase3d.bash index 5e3fa91..63a8332 100755 --- a/scripts/docker-install-phase3d.bash +++ b/scripts/docker-install-phase3d.bash @@ -18,6 +18,9 @@ scala # Scheme mit-scheme +# Scilab +scilab + # Sed sed From da9606394e0d485a101f2bb60d336ead9ac25f7f Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 26 Sep 2020 07:59:09 -0700 Subject: [PATCH 290/388] [#24] New language: S-Lang --- backend/src/langs.ts | 16 ++++++++++++++++ scripts/docker-install-phase3d.bash | 3 +++ 2 files changed, 19 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 5629988..bae6bbb 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2225,6 +2225,9 @@ binding_irb.run(IRB.conf) repl: "scilab-cli", main: "main.sci", run: "scilab-cli -f main.sci", + scope: { + code: `x = 123 * 234`, + }, template: `disp("Hello, world!") `, skip: ["repl", "runrepl"], @@ -2383,6 +2386,19 @@ Ophelia: `, timeout: 15, }, + slang: { + aliases: ["s", "sl"], + name: "S-Lang", + repl: "slsh", + input: "123 * 234;", + main: "main.sl", + run: "slsh -i main.sl", + scope: { + code: "x = 123 * 234;", + }, + template: `message("Hello, world!"); +` + }, smalltalk: { aliases: ["gst", "st"], name: "Smalltalk", diff --git a/scripts/docker-install-phase3d.bash b/scripts/docker-install-phase3d.bash index 63a8332..151d24f 100755 --- a/scripts/docker-install-phase3d.bash +++ b/scripts/docker-install-phase3d.bash @@ -12,6 +12,9 @@ liblua_name="$(grep-aptavail -eF Package "liblua[0-9.]+-dev" -a -XF Version "${l packages=" +# S-Lang +slsh + # Scala scala From d70c916190d53e9f89ae50333d7118e5b7231e55 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 26 Sep 2020 10:23:29 -0700 Subject: [PATCH 291/388] [#24] New language: Squirrel --- backend/src/langs.ts | 10 ++++++++++ scripts/docker-install-phase3d.bash | 3 +++ 2 files changed, 13 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index bae6bbb..46377d1 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2435,6 +2435,16 @@ END `, skip: ["lsp"], }, + squirrel: { + aliases: ["nut", "cnut"], + name: "Squirrel", + repl: "squirrel", + input: `print(123 * 234)`, + main: "main.nut", + run: "squirrel main.nut; squirrel", + template: `print("Hello, world!\\n") +` + }, standardml: { aliases: ["sml", "ml"], name: "Standard ML", diff --git a/scripts/docker-install-phase3d.bash b/scripts/docker-install-phase3d.bash index 151d24f..7023673 100755 --- a/scripts/docker-install-phase3d.bash +++ b/scripts/docker-install-phase3d.bash @@ -39,6 +39,9 @@ m4 # SQLite sqlite +# Squirrel +squirrel3 + # Standard ML rlwrap smlnj From f730ac67921448775bf1542e732d11469d55e0f7 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 26 Sep 2020 10:35:41 -0700 Subject: [PATCH 292/388] [#24] New language: Subleq --- backend/src/langs.ts | 25 +++++++++++++++++++++++++ scripts/docker-install-phase6.bash | 7 +++++++ 2 files changed, 32 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 46377d1..f990e25 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2458,6 +2458,31 @@ END }, template: `print "Hello, world!\\n"; `, + }, + subleq: { + aliases: ["sq", "asq"], + name: "Subleq", + main: "main.sq", + run: "sq main.sq", + template: `12 12 3 +36 37 6 +37 12 9 +37 37 12 +0 -1 15 +38 36 18 +12 12 21 +53 37 24 +37 12 27 +37 37 30 +36 12 -1 +37 37 0 +39 0 -1 +72 101 108 +108 111 44 +32 119 111 +114 108 100 +33 10 53 +` }, swift: { aliases: ["swiftc"], diff --git a/scripts/docker-install-phase6.bash b/scripts/docker-install-phase6.bash index d415d08..180f19f 100755 --- a/scripts/docker-install-phase6.bash +++ b/scripts/docker-install-phase6.bash @@ -104,6 +104,13 @@ mv snobol4 /usr/local/bin/snobol4 popd >/dev/null rm -rf snobol4-* +# Subleq +git clone https://github.com/davidar/subleq.git +pushd subleq/src >/dev/null +make sq +mv sq /usr/local/bin/ +popd >/dev/null + # Tabloid mkdir /opt/tabloid pushd /opt/tabloid >/dev/null From 277e5bfda879b8b6e572b7d05d1816ea4f936f14 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 26 Sep 2020 10:38:37 -0700 Subject: [PATCH 293/388] [#24] New language: Vala --- backend/src/langs.ts | 11 +++++++++++ scripts/docker-install-phase3d.bash | 3 +++ 2 files changed, 14 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index f990e25..16ae43e 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2656,6 +2656,17 @@ main = 'let run: "unlambda-repl main.unl", template: "`.\n`.!`.d`.l`.r`.o`.w`. `.,`.o`.l`.l`.e`.Hi\n", }, + vala: { + aliases: ["valac"], + name: "Vala", + main: "main.vala", + compile: "valac main.vala", + run: "./main", + template: `void main () { + print("Hello, world!\\n"); +} +` + }, vim: { aliases: ["viml", "vimscript"], name: "Vimscript", diff --git a/scripts/docker-install-phase3d.bash b/scripts/docker-install-phase3d.bash index 7023673..ee251a8 100755 --- a/scripts/docker-install-phase3d.bash +++ b/scripts/docker-install-phase3d.bash @@ -63,6 +63,9 @@ texlive-binaries # Unlambda unlambda +# Vala +valac + # Vimscript vim From 82a61e69c2814e1d0bdec613e14877c0ae453da8 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 26 Sep 2020 19:29:56 -0700 Subject: [PATCH 294/388] Skip scope test for Scilab --- backend/src/langs.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 16ae43e..2a04977 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2230,7 +2230,7 @@ binding_irb.run(IRB.conf) }, template: `disp("Hello, world!") `, - skip: ["repl", "runrepl"], + skip: ["repl", "runrepl", "scope"], }, scss: { name: "SCSS", From f3af583d1c6073f9d1b73117e3e98e8374613de6 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 26 Sep 2020 19:34:21 -0700 Subject: [PATCH 295/388] [#24] New language: Velato --- backend/src/langs.ts | 225 +++++++++++++++++++++++++++++ scripts/docker-install-phase4.bash | 10 ++ 2 files changed, 235 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 2a04977..f52df7a 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2665,6 +2665,231 @@ main = 'let template: `void main () { print("Hello, world!\\n"); } +` + }, + velato: { + aliases: ["vlt"], + name: "Velato", + main: "main.asc", + compile: "asc2mid main.asc > main.mid && mono /opt/velato/Vlt.exe /s main.mid", + run: "mono main.exe", + hello: "Hello, World!", + template: `format=1 tracks=2 division=2880 + +BA 1 CR 0 TR 0 CH 16 Tempo 100 +BA 1 CR 0 TR 1 CH 1 NT C-- 4/5 von=101 voff=0 +BA 1 CR 0 TR 1 CH 1 NT A 4/5 voff=0 +BA 1 CR 0 TR 1 CH 1 NT G- 4/5 voff=0 +BA 1 CR 0 TR 1 CH 1 NT E- 4/5 voff=0 + +BA 2 CR 0 TR 1 CH 1 NT F- 4/5 voff=0 +BA 2 CR 0 TR 1 CH 1 NT A- 4/5 voff=0 +BA 2 CR 0 TR 1 CH 1 NT Eb 4/5 voff=0 + +BA 3 CR 1/2 TR 1 CH 1 NT G- 3+7/20 voff=0 +BA 3 CR 1/2 TR 1 CH 1 NT C 3+7/20 voff=0 + +BA 5 CR 0 TR 1 CH 1 NT C- 1/5 voff=0 +BA 5 CR 1/4 TR 1 CH 1 NT D 1/5 voff=0 +BA 5 CR 1/2 TR 1 CH 1 NT F 1/5 voff=0 +BA 5 CR 3/4 TR 1 CH 1 NT F-- 2/5 voff=0 +BA 5 CR 3/4 TR 1 CH 1 NT D 2/5 voff=0 +BA 5 CR 3/4 TR 1 CH 1 NT C- 2/5 voff=0 +BA 5 CR 3/4 TR 1 CH 1 NT A- 2/5 voff=0 + +BA 6 CR 1/4 TR 1 CH 1 NT Bb 4/5 voff=0 +BA 6 CR 1/4 TR 1 CH 1 NT G-- 4/5 voff=0 +BA 6 CR 1/4 TR 1 CH 1 NT F#- 4/5 voff=0 + +BA 7 CR 3/4 TR 1 CH 1 NT G- 3+7/20 voff=0 +BA 7 CR 3/4 TR 1 CH 1 NT C 3+7/20 voff=0 + +BA 9 CR 1/4 TR 1 CH 1 NT F- 1/5 voff=0 +BA 9 CR 1/2 TR 1 CH 1 NT G 1/5 voff=0 +BA 9 CR 3/4 TR 1 CH 1 NT Bb 1/5 voff=0 + +BA 10 CR 0 TR 1 CH 1 NT Bb-- 2/5 voff=0 +BA 10 CR 0 TR 1 CH 1 NT G 2/5 voff=0 +BA 10 CR 0 TR 1 CH 1 NT F- 2/5 voff=0 +BA 10 CR 0 TR 1 CH 1 NT D- 2/5 voff=0 +BA 10 CR 1/2 TR 1 CH 1 NT Eb 4/5 voff=0 +BA 10 CR 1/2 TR 1 CH 1 NT C- 4/5 voff=0 +BA 10 CR 1/2 TR 1 CH 1 NT B- 4/5 voff=0 + +BA 11 CR 1/2 TR 1 CH 1 NT G# 2/5 voff=0 + +BA 12 CR 0 TR 1 CH 1 NT F 4/5 voff=0 +BA 12 CR 0 TR 1 CH 1 NT Bb 4/5 voff=0 + +BA 13 CR 0 TR 1 CH 1 NT Bb- 2/5 voff=0 +BA 13 CR 1/2 TR 1 CH 1 NT Bb-- 1/5 voff=0 +BA 13 CR 3/4 TR 1 CH 1 NT G 1/5 voff=0 + +BA 14 CR 0 TR 1 CH 1 NT F- 1/5 voff=0 +BA 14 CR 1/4 TR 1 CH 1 NT D- 1/5 voff=0 +BA 14 CR 1/2 TR 1 CH 1 NT Eb 4/5 voff=0 +BA 14 CR 1/2 TR 1 CH 1 NT C- 4/5 voff=0 +BA 14 CR 1/2 TR 1 CH 1 NT B- 4/5 voff=0 + +BA 15 CR 1/2 TR 1 CH 1 NT G# 2/5 voff=0 + +BA 16 CR 0 TR 1 CH 1 NT F 4/5 voff=0 +BA 16 CR 0 TR 1 CH 1 NT Bb 4/5 voff=0 + +BA 17 CR 0 TR 1 CH 1 NT Bb- 4/5 voff=0 + +BA 18 CR 0 TR 1 CH 1 NT Bb- 2/5 voff=0 +BA 18 CR 1/2 TR 1 CH 1 NT C- 4/5 voff=0 +BA 18 CR 1/2 TR 1 CH 1 NT C 4/5 voff=0 + +BA 19 CR 1/2 TR 1 CH 1 NT C-- 3+2/5 voff=0 +BA 19 CR 1/2 TR 1 CH 1 NT A 3+2/5 voff=0 +BA 19 CR 1/2 TR 1 CH 1 NT G- 3+2/5 voff=0 +BA 19 CR 1/2 TR 1 CH 1 NT E- 3+2/5 voff=0 + +BA 21 CR 0 TR 1 CH 1 NT F- 4/5 voff=0 +BA 21 CR 0 TR 1 CH 1 NT D 4/5 voff=0 + +BA 22 CR 0 TR 1 CH 1 NT D 2/5 voff=0 +BA 22 CR 1/2 TR 1 CH 1 NT D 2/5 voff=0 +BA 22 CR 1/2 TR 1 CH 1 NT G- 2/5 voff=0 +BA 22 CR 1/2 TR 1 CH 1 NT C 2/5 voff=0 + +BA 23 CR 0 TR 1 CH 1 NT C-- 2/5 voff=0 +BA 23 CR 1/2 TR 1 CH 1 NT A 1+3/5 voff=0 +BA 23 CR 1/2 TR 1 CH 1 NT G- 1+3/5 voff=0 + +BA 25 CR 1/2 TR 1 CH 1 NT E 2/5 voff=0 +BA 25 CR 1/2 TR 1 CH 1 NT F- 2+7/10 voff=0 +BA 25 CR 1/2 TR 1 CH 1 NT F-- 2+7/10 voff=0 + +BA 27 CR 0 TR 1 CH 1 NT F 3+7/10 voff=0 +BA 27 CR 0 TR 1 CH 1 NT G- 5+9/20 voff=0 +BA 27 CR 0 TR 1 CH 1 NT C 5+9/20 voff=0 + +BA 30 CR 0 TR 1 CH 1 NT C- 1/5 voff=0 +BA 30 CR 1/4 TR 1 CH 1 NT D 1/5 voff=0 +BA 30 CR 1/2 TR 1 CH 1 NT F 1/5 voff=0 +BA 30 CR 3/4 TR 1 CH 1 NT F 4/5 voff=0 + +BA 31 CR 3/4 TR 1 CH 1 NT F- 2/5 voff=0 + +BA 32 CR 1/4 TR 1 CH 1 NT F-- 2/5 voff=0 +BA 32 CR 1/4 TR 1 CH 1 NT D 2/5 voff=0 +BA 32 CR 1/4 TR 1 CH 1 NT C- 2/5 voff=0 +BA 32 CR 1/4 TR 1 CH 1 NT A- 2/5 voff=0 +BA 32 CR 3/4 TR 1 CH 1 NT Bb 4/5 voff=0 + +BA 33 CR 3/4 TR 1 CH 1 NT A 2/5 voff=0 + +BA 34 CR 1/4 TR 1 CH 1 NT G#- 3+7/20 voff=0 +BA 34 CR 1/4 TR 1 CH 1 NT C 3+7/20 voff=0 + +BA 35 CR 3/4 TR 1 CH 1 NT F- 1/5 voff=0 + +BA 36 CR 0 TR 1 CH 1 NT G 1/5 voff=0 +BA 36 CR 1/4 TR 1 CH 1 NT Bb 1/5 voff=0 +BA 36 CR 1/2 TR 1 CH 1 NT Bb-- 2/5 voff=0 +BA 36 CR 1/2 TR 1 CH 1 NT G 2/5 voff=0 +BA 36 CR 1/2 TR 1 CH 1 NT F- 2/5 voff=0 +BA 36 CR 1/2 TR 1 CH 1 NT D- 2/5 voff=0 + +BA 37 CR 0 TR 1 CH 1 NT Eb 4/5 voff=0 +BA 37 CR 0 TR 1 CH 1 NT G# 4/5 voff=0 + +BA 38 CR 0 TR 1 CH 1 NT G 2/5 voff=0 +BA 38 CR 1/2 TR 1 CH 1 NT F 4/5 voff=0 +BA 38 CR 1/2 TR 1 CH 1 NT Bb 4/5 voff=0 + +BA 39 CR 1/2 TR 1 CH 1 NT Bb- 2/5 voff=0 + +BA 40 CR 0 TR 1 CH 1 NT Bb- 2/5 voff=0 +BA 40 CR 1/2 TR 1 CH 1 NT C- 4/5 voff=0 +BA 40 CR 1/2 TR 1 CH 1 NT C 4/5 voff=0 + +BA 41 CR 1/2 TR 1 CH 1 NT C-- 3+2/5 voff=0 +BA 41 CR 1/2 TR 1 CH 1 NT A 3+2/5 voff=0 +BA 41 CR 1/2 TR 1 CH 1 NT G- 3+2/5 voff=0 +BA 41 CR 1/2 TR 1 CH 1 NT E- 3+2/5 voff=0 + +BA 43 CR 0 TR 1 CH 1 NT F- 4/5 voff=0 +BA 43 CR 0 TR 1 CH 1 NT D 4/5 voff=0 + +BA 44 CR 0 TR 1 CH 1 NT D 2/5 voff=0 +BA 44 CR 1/2 TR 1 CH 1 NT D 4/5 voff=0 +BA 44 CR 1/2 TR 1 CH 1 NT G- 2/5 voff=0 +BA 44 CR 1/2 TR 1 CH 1 NT C 4/5 voff=0 + +BA 45 CR 1/2 TR 1 CH 1 NT C-- 3+2/5 voff=0 +BA 45 CR 1/2 TR 1 CH 1 NT A 3+2/5 voff=0 +BA 45 CR 1/2 TR 1 CH 1 NT G- 3+2/5 voff=0 +BA 45 CR 1/2 TR 1 CH 1 NT E- 3+2/5 voff=0 + +BA 47 CR 0 TR 1 CH 1 NT F- 4/5 voff=0 +BA 47 CR 0 TR 1 CH 1 NT D 4/5 voff=0 + +BA 48 CR 0 TR 1 CH 1 NT D 2/5 voff=0 +BA 48 CR 1/2 TR 1 CH 1 NT F 4/5 voff=0 +BA 48 CR 1/2 TR 1 CH 1 NT G 4/5 voff=0 +BA 48 CR 1/2 TR 1 CH 1 NT C- 4/5 voff=0 + +BA 49 CR 1/2 TR 1 CH 1 NT C- 1/5 voff=0 +BA 49 CR 3/4 TR 1 CH 1 NT D 1/5 voff=0 + +BA 50 CR 0 TR 1 CH 1 NT Bb 1/5 voff=0 +BA 50 CR 1/4 TR 1 CH 1 NT Bb 2/5 voff=0 +BA 50 CR 3/4 TR 1 CH 1 NT Bb- 4/5 voff=0 + +BA 51 CR 3/4 TR 1 CH 1 NT Bb 4/5 voff=0 + +BA 52 CR 3/4 TR 1 CH 1 NT Bb-- 2/5 voff=0 +BA 52 CR 3/4 TR 1 CH 1 NT G 2/5 voff=0 +BA 52 CR 3/4 TR 1 CH 1 NT F- 2/5 voff=0 +BA 52 CR 3/4 TR 1 CH 1 NT D- 2/5 voff=0 + +BA 53 CR 1/4 TR 1 CH 1 NT Eb 2/5 voff=0 +BA 53 CR 1/4 TR 1 CH 1 NT C- 2/5 voff=0 +BA 53 CR 1/4 TR 1 CH 1 NT B 2/5 voff=0 +BA 53 CR 3/4 TR 1 CH 1 NT G#- 4/5 voff=0 + +BA 54 CR 3/4 TR 1 CH 1 NT F- 4/5 voff=0 +BA 54 CR 3/4 TR 1 CH 1 NT Bb- 4/5 voff=0 + +BA 55 CR 3/4 TR 1 CH 1 NT Bb- 2/5 voff=0 + +BA 56 CR 1/4 TR 1 CH 1 NT Bb- 4/5 voff=0 + +BA 57 CR 1/4 TR 1 CH 1 NT Bb-- 2/5 voff=0 +BA 57 CR 1/4 TR 1 CH 1 NT G 2/5 voff=0 +BA 57 CR 1/4 TR 1 CH 1 NT F- 2/5 voff=0 +BA 57 CR 1/4 TR 1 CH 1 NT D- 2/5 voff=0 +BA 57 CR 3/4 TR 1 CH 1 NT Eb 2/5 voff=0 +BA 57 CR 3/4 TR 1 CH 1 NT C- 2/5 voff=0 +BA 57 CR 3/4 TR 1 CH 1 NT B- 2/5 voff=0 + +BA 58 CR 1/4 TR 1 CH 1 NT B 2/5 voff=0 +BA 58 CR 3/4 TR 1 CH 1 NT F 4/5 voff=0 +BA 58 CR 3/4 TR 1 CH 1 NT Bb 4/5 voff=0 + +BA 59 CR 3/4 TR 1 CH 1 NT Bb- 2/5 voff=0 + +BA 60 CR 1/4 TR 1 CH 1 NT Bb- 2/5 voff=0 +BA 60 CR 3/4 TR 1 CH 1 NT C- 4/5 voff=0 +BA 60 CR 3/4 TR 1 CH 1 NT C 4/5 voff=0 + +BA 61 CR 3/4 TR 1 CH 1 NT C-- 3+19/20 voff=0 +BA 61 CR 3/4 TR 1 CH 1 NT A 3+19/20 voff=0 +BA 61 CR 3/4 TR 1 CH 1 NT G- 3+19/20 voff=0 + +BA 63 CR 1/4 TR 1 CH 1 NT E- 1/5 voff=0 +BA 63 CR 1/2 TR 1 CH 1 NT F- 1/5 voff=0 +BA 63 CR 3/4 TR 1 CH 1 NT E- 1+11/20 voff=0 + +BA 64 CR 1/2 TR 1 CH 1 NT E 3+1/5 voff=0 +BA 64 CR 1/2 TR 1 CH 1 NT G- 1+1/5 voff=0 +BA 64 CR 1/2 TR 1 CH 1 NT C 3+1/5 voff=0 + +BA 67 CR 7/10 TR 1 CH 16 End of track ` }, vim: { diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 1e7127c..e8104b7 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -292,5 +292,15 @@ rm swift.tar.gz wget -nv https://github.com/raxod502/riju-cdn/releases/download/unison-M1l-232-519cbeb58704c1b9410c9386e492be59fd5a5334/unison -O /usr/local/bin/unison chmod +x /usr/local/bin/unison +# Velato +wget -nv http://www.archduke.org/midi/asc2mid.c +clang asc2mid.c -o /usr/local/bin/asc2mid +rm asc2mid.c + +file="$(curl -fsSL http://velato.net/ | grep -Eo 'Velato[0-9_]+.zip')" +wget -nv "http://velato.net/Content/Velato/${file}" +unzip -d /opt/velato Velato*.zip +rm Velato*.zip + popd >/dev/null rm "$0" From b9eb65bc007eb0bb9b8ca14a537951b942d13499 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 26 Sep 2020 19:40:14 -0700 Subject: [PATCH 296/388] [#24] New language: Verilog --- backend/src/langs.ts | 15 +++++++++++++++ scripts/docker-install-phase3d.bash | 3 +++ 2 files changed, 18 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index f52df7a..c146b50 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2891,6 +2891,21 @@ BA 64 CR 1/2 TR 1 CH 1 NT C 3+1/5 voff=0 BA 67 CR 7/10 TR 1 CH 16 End of track ` + }, + verilog: { + aliases: ["systemverilog", "iverilog", "v"], + name: "Verilog", + main: "main.v", + compile: "iverilog main.v -o main", + run: "./main", + template: `module main; + +initial begin + $display("Hello, world!"); +end + +endmodule +`, }, vim: { aliases: ["viml", "vimscript"], diff --git a/scripts/docker-install-phase3d.bash b/scripts/docker-install-phase3d.bash index ee251a8..376269a 100755 --- a/scripts/docker-install-phase3d.bash +++ b/scripts/docker-install-phase3d.bash @@ -66,6 +66,9 @@ unlambda # Vala valac +# Verilog +iverilog + # Vimscript vim From 647366a8ae18f6720b2825b66b1fcec404ce6226 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 26 Sep 2020 20:23:42 -0700 Subject: [PATCH 297/388] [#24] New language: XSLT God, the horror of putting together this example. It boggles the mind how hard XSLT is to use. --- backend/src/langs.ts | 19 +++++++++++++++++++ scripts/docker-install-phase3d.bash | 3 +++ 2 files changed, 22 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index c146b50..8869578 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2996,6 +2996,25 @@ main: message: .string "Hello, world!\\n" `, + }, + xslt: { + aliases: ["xsltproc", "xsl"], + name: "XSLT", + main: "main.xsl", + compile: "xsltproc main.xsl -o main", + run: "cat main", + template: ` +
+ + + + + + Hello, world! +
+` }, yaml: { aliases: ["yml"], diff --git a/scripts/docker-install-phase3d.bash b/scripts/docker-install-phase3d.bash index 376269a..b1e08a1 100755 --- a/scripts/docker-install-phase3d.bash +++ b/scripts/docker-install-phase3d.bash @@ -81,6 +81,9 @@ python3.7 # x86 clang +# XSLT +xsltproc + # YAML jq From f6de928cf3acde2865ba9a84be2240e860182a1c Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 26 Sep 2020 20:33:36 -0700 Subject: [PATCH 298/388] [#24] New language: Yorick --- backend/src/langs.ts | 14 ++++++++++++++ scripts/docker-install-phase3d.bash | 4 ++++ 2 files changed, 18 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 8869578..5c98828 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -3029,6 +3029,20 @@ message: `, }, template: `output: "Hello, world!" +`, + }, + yorick: { + name: "Yorick", + repl: "rlwrap yorick", + main: "main.i", + run: `echo "Type '#include \\"main.i\\"' to run the code." && rlwrap yorick`, + helloInput: `#include "main.i"`, + scope: { + code: `x = 123 * 234`, + input: `#include "main.i" +x`, + }, + template: `write, "Hello, world!" `, }, zot: { diff --git a/scripts/docker-install-phase3d.bash b/scripts/docker-install-phase3d.bash index b1e08a1..d77fd49 100755 --- a/scripts/docker-install-phase3d.bash +++ b/scripts/docker-install-phase3d.bash @@ -87,6 +87,10 @@ xsltproc # YAML jq +# Yorick +rlwrap +yorick + # Zot qt5-qmake qtscript5-dev From f1452ae9bca4f93f169d54f048ea980911277166 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 26 Sep 2020 20:54:28 -0700 Subject: [PATCH 299/388] [#24] New language: Zoem --- backend/src/langs.ts | 11 +++++++++++ scripts/docker-install-phase3d.bash | 3 +++ 2 files changed, 14 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 5c98828..9b451c5 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -3043,6 +3043,17 @@ message: x`, }, template: `write, "Hello, world!" +`, + }, + zoem: { + aliases: ["azm"], + name: "Zoem", + repl: "zoem", + input: `\\let{123 * 234} +.`, + main: "main.azm", + run: "zoem -I main.azm; zoem", + template: `\\inform{Hello, world!} `, }, zot: { diff --git a/scripts/docker-install-phase3d.bash b/scripts/docker-install-phase3d.bash index d77fd49..7e45a72 100755 --- a/scripts/docker-install-phase3d.bash +++ b/scripts/docker-install-phase3d.bash @@ -91,6 +91,9 @@ jq rlwrap yorick +# Zoem +zoem + # Zot qt5-qmake qtscript5-dev From 07b219d1193e1fa44c4843b30560d294ad5282f1 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 27 Sep 2020 08:45:19 -0700 Subject: [PATCH 300/388] [#24] New language: A+ --- backend/src/langs.ts | 12 ++++++++++++ scripts/docker-install-phase3a.bash | 5 +++++ 2 files changed, 17 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 9b451c5..70b3856 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -62,6 +62,18 @@ export const langs: { [key: string]: LangConfig } = { o;!?l< `, }, + "a+": { + aliases: ["aplus"], + name: "A+", + repl: "rlwrap a+", + input: "2 * 16", + output: "65536", + main: "main.a+", + run: "rlwrap a+ main.a+", + template: `'Hello, world!' +`, + skip: ["scope"], + }, ada: { aliases: ["adb"], name: "Ada", diff --git a/scripts/docker-install-phase3a.bash b/scripts/docker-install-phase3a.bash index f65951d..1a2a09c 100755 --- a/scripts/docker-install-phase3a.bash +++ b/scripts/docker-install-phase3a.bash @@ -11,6 +11,11 @@ ceylon="$(grep-aptavail -F Package ceylon -s Package -n | sort -rV | head -n1)" packages=" +# A+ +aplus-fsf +aplus-fsf-doc +rlwrap + # Ada gnat From 53b3abda6e5011af5f082f5bdfc95b13d0f807f7 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 27 Sep 2020 08:55:36 -0700 Subject: [PATCH 301/388] [#24] New language: Afnix --- backend/src/langs.ts | 11 +++++++++++ scripts/docker-install-phase3a.bash | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 70b3856..8cf4148 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -93,6 +93,17 @@ procedure Main is begin Ada.Text_IO.Put_Line("Hello, world!"); end Main; +`, + }, + afnix: { + aliases: ["als", "axc", "axi"], + name: "Afnix", + repl: "LD_LIBRARY_PATH=/usr/lib/afnix axi", + input: `DELAY: 1 +println (* 123 234)`, + main: "main.als", + run: "LD_LIBRARY_PATH=/usr/lib/afnix axi main.als; LD_LIBRARY_PATH=/usr/lib/afnix axi", + template: `println "Hello, world!" `, }, algol: { diff --git a/scripts/docker-install-phase3a.bash b/scripts/docker-install-phase3a.bash index 1a2a09c..dccc00a 100755 --- a/scripts/docker-install-phase3a.bash +++ b/scripts/docker-install-phase3a.bash @@ -19,6 +19,10 @@ rlwrap # Ada gnat +# Afnix +afnix +afnix-doc + # Algol algol68g From 73b17c81104c799333d3c16d1b3cde83aa8e8032 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 27 Sep 2020 09:04:51 -0700 Subject: [PATCH 302/388] [#25] Improve test coverage by adding delays --- backend/src/langs.ts | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 8cf4148..4fbfc31 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -791,6 +791,8 @@ main(application-name(), application-arguments()); aliases: ["iex", "exs"], name: "Elixir", repl: "iex", + input: `DELAY: 1 +123 * 234`, main: "main.exs", run: "iex main.exs", scope: { @@ -799,12 +801,13 @@ main(application-name(), application-arguments()); 123 * 234 end end`, - input: `Scope.x`, + input: `DELAY: 1 +Scope.x`, }, lsp: { start: "/opt/elixir-ls/language_server.sh" }, template: `IO.puts("Hello, world!") `, - skip: ["repl", "runrepl", "scope", "lsp"], + skip: ["lsp"], }, elm: { name: "Elm", @@ -1544,11 +1547,12 @@ PLEASE GIVE UP aliases: ["lsc", "ls"], name: "LiveScript", repl: "lsc", + input: `DELAY: 1 +123 * 234`, main: "main.ls", run: "lsc -r ./main.ls", template: `console.log "Hello, world!" `, - skip: ["repl", "runrepl"], }, llvm: { name: "LLVM", @@ -2096,13 +2100,13 @@ x`, monacoLang: "redis", repl: "rm -f socket; (redis-server --port 0 --unixsocket socket &); until [[ -e socket ]]; do sleep 0.01; done; redis-cli -s socket", - input: `EVAL "return 123 * 234" 0`, + input: `DELAY: 3 +EVAL "return 123 * 234" 0`, main: "main.redis", run: "rm -f socket; (redis-server --port 0 --unixsocket socket &); until [[ -e socket ]]; do sleep 0.01; done; redis-cli -s socket < main.redis; redis-cli -s socket", template: `ECHO "Hello, world!" `, - skip: ["repl", "runrepl"], }, restructuredtext: { aliases: ["rst"], @@ -2246,14 +2250,17 @@ binding_irb.run(IRB.conf) aliases: ["sci"], name: "Scilab", repl: "scilab-cli", + input: `DELAY: 1 +123 * 234`, main: "main.sci", run: "scilab-cli -f main.sci", scope: { code: `x = 123 * 234`, + input: `DELAY: 1 +x`, }, template: `disp("Hello, world!") `, - skip: ["repl", "runrepl", "scope"], }, scss: { name: "SCSS", From caef35a0e00c95660cf3bdc19636578fa0017e7a Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 27 Sep 2020 09:39:46 -0700 Subject: [PATCH 303/388] [#24] New language: Aheui --- backend/src/langs.ts | 27 +++++++++++++++++++++++++++ scripts/docker-install-phase6.bash | 8 ++++++++ 2 files changed, 35 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 4fbfc31..2f876ae 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -104,6 +104,33 @@ println (* 123 234)`, main: "main.als", run: "LD_LIBRARY_PATH=/usr/lib/afnix axi main.als; LD_LIBRARY_PATH=/usr/lib/afnix axi", template: `println "Hello, world!" +`, + }, + 아희: { + aliases: [ + "aheui", + "aheuis", + "rpaheui", + "caheui", + "naheui", + "goaheui", + "jsaheui", + "pyaheui", + "rsaheui", + "as3aheui", + "raheui", + ], + name: "아희", + main: "main.aheui", + run: "aheui main.aheui", + template: `밤밣따빠밣밟따뿌 +빠맣파빨받밤뚜뭏 +돋밬탕빠맣붏두붇 +볻뫃박발뚷투뭏붖 +뫃도뫃희멓뭏뭏붘 +뫃봌토범더벌뿌뚜 +뽑뽀멓멓더벓뻐뚠 +뽀덩벐멓뻐덕더벅 `, }, algol: { diff --git a/scripts/docker-install-phase6.bash b/scripts/docker-install-phase6.bash index 180f19f..35babb6 100755 --- a/scripts/docker-install-phase6.bash +++ b/scripts/docker-install-phase6.bash @@ -5,6 +5,14 @@ set -o pipefail set -x pushd /tmp >/dev/null +# Aheui +git clone https://github.com/aheui/caheui.git +pushd caheui >/dev/null +make +mv aheui /usr/local/bin/ +popd >/dev/null +rm -rf cahuei + # Battlestar git clone https://github.com/xyproto/battlestar.git pushd battlestar >/dev/null From 431a8d1c4b216dc2713aa26666ee1012a835e07b Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 27 Sep 2020 09:51:01 -0700 Subject: [PATCH 304/388] Relocate Velato --- scripts/docker-install-phase4.bash | 5 ----- scripts/docker-install-phase6.bash | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index e8104b7..0e169d3 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -292,11 +292,6 @@ rm swift.tar.gz wget -nv https://github.com/raxod502/riju-cdn/releases/download/unison-M1l-232-519cbeb58704c1b9410c9386e492be59fd5a5334/unison -O /usr/local/bin/unison chmod +x /usr/local/bin/unison -# Velato -wget -nv http://www.archduke.org/midi/asc2mid.c -clang asc2mid.c -o /usr/local/bin/asc2mid -rm asc2mid.c - file="$(curl -fsSL http://velato.net/ | grep -Eo 'Velato[0-9_]+.zip')" wget -nv "http://velato.net/Content/Velato/${file}" unzip -d /opt/velato Velato*.zip diff --git a/scripts/docker-install-phase6.bash b/scripts/docker-install-phase6.bash index 35babb6..b7c476a 100755 --- a/scripts/docker-install-phase6.bash +++ b/scripts/docker-install-phase6.bash @@ -138,6 +138,11 @@ mv bin/thue /usr/local/bin/thue popd >/dev/null rm -rf thue-* +# Velato +wget -nv http://www.archduke.org/midi/asc2mid.c +clang asc2mid.c -o /usr/local/bin/asc2mid +rm asc2mid.c + # Zot git clone https://github.com/manyoso/zot.git pushd zot >/dev/null From a56ec90f15c6820324c7134c4027f54da22912fb Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 27 Sep 2020 09:51:09 -0700 Subject: [PATCH 305/388] Rename esofish -> fish-lang --- backend/src/langs.ts | 4 ++-- scripts/docker-install-phase4.bash | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 2f876ae..acabfb2 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -54,10 +54,10 @@ export interface LangConfig { export const langs: { [key: string]: LangConfig } = { "><>": { - aliases: ["esofish"], + aliases: ["fishlang"], name: "><>", main: "main.fish", - run: "esofish main.fish", + run: "fish-lang main.fish", template: `"Hello, world!"r\\ o;!?l< `, diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 0e169d3..988e441 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -22,9 +22,9 @@ tar -xf pandoc-*-linux-amd64.tar.gz -C /usr --strip-components=1 rm pandoc-*-linux-amd64.tar.gz # ><> -wget -nv https://gist.githubusercontent.com/anonymous/6392418/raw/fish.py -O /usr/local/bin/esofish -sed -i 's:^#!.*:#!/usr/bin/env python3:' /usr/local/bin/esofish -chmod +x /usr/local/bin/esofish +wget -nv https://gist.githubusercontent.com/anonymous/6392418/raw/fish.py -O /usr/local/bin/fish-lang +sed -i 's:^#!.*:#!/usr/bin/env python3:' /usr/local/bin/fish-lang +chmod +x /usr/local/bin/fish-lang # Ada wget -nv https://dl.bintray.com/reznikmm/ada-language-server/linux-latest.tar.gz From 16b62fe34097b5ee57e21d6bec87d91f931304fa Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 27 Sep 2020 09:51:23 -0700 Subject: [PATCH 306/388] [#24] New language: Ante (the esolang) --- backend/src/langs.ts | 7 +++++++ scripts/docker-install-phase4.bash | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index acabfb2..1321971 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -139,6 +139,13 @@ println (* 123 234)`, main: "main.alg", run: "a68g main.alg", template: `print(("Hello, world!",new line)) +`, + }, + antecards: { + name: "Ante (Cards)", + main: "main.ante", + run: `RUBYOPT="-W0" ante-cards main.ante`, + template: `9♦8♥J♦A♦2♣3♥7♠J♦A♦7♦J♦J♦A♦3♦J♦5♥6♦4♥J♥A♥6♠6♠J♥A♦8♦J♦A♦8♠J♦A♦3♦J♦A♦6♠J♦A♦8♠J♦A♥3♦2♠J♥A♥2♣6♠J♥ `, }, apl: { diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 988e441..752d6c9 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -33,6 +33,10 @@ mv linux/ada_language_server /usr/local/bin/ada_language_server mv linux/*.so* /usr/lib/x86_64-linux-gnu/ rm -rf linux linux-latest.tar.gz +# Ante (Cards) +wget -nv https://github.com/michaeldv/ante/raw/master/ante.rb -O /usr/local/bin/ante-cards +chmod +x /usr/local/bin/ante-cards + # APL file="$(curl -sS ftp://ftp.gnu.org/gnu/apl/ | grep -Eo 'apl_[-0-9.]+_amd64.deb$' | sort -rV | head -n1)" wget -nv "ftp://ftp.gnu.org/gnu/apl/${file}" From dc33328746bc213916a50e70d8d1e6fa51d22cd5 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 27 Sep 2020 14:40:02 -0700 Subject: [PATCH 307/388] [#24] New language: Ante (the systems language) --- backend/src/langs.ts | 9 +++++++++ scripts/docker-install-phase4.bash | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 1321971..6c4b6c0 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -139,6 +139,15 @@ println (* 123 234)`, main: "main.alg", run: "a68g main.alg", template: `print(("Hello, world!",new line)) +`, + }, + ante: { + aliases: ["an"], + name: "Ante", + main: "main.an", + compile: "ante main.an", + run: "./main", + template: `puts("Hello, world!".cStr) `, }, antecards: { diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 752d6c9..18e3f9f 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -33,6 +33,10 @@ mv linux/ada_language_server /usr/local/bin/ada_language_server mv linux/*.so* /usr/lib/x86_64-linux-gnu/ rm -rf linux linux-latest.tar.gz +# Ante +wget -nv https://github.com/raxod502/riju-cdn/releases/download/ante-0.8.0-d2c43992e0c7a4c1942d5c097233f4f7638a1ee6/ante -O /usr/local/bin/ante +chmod +x /usr/local/bin/ante + # Ante (Cards) wget -nv https://github.com/michaeldv/ante/raw/master/ante.rb -O /usr/local/bin/ante-cards chmod +x /usr/local/bin/ante-cards From cd29dd30d51230f90ae8d97fb3fc70b4f5c9e07b Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 27 Sep 2020 14:46:59 -0700 Subject: [PATCH 308/388] [#24] New language: AspectC++ --- backend/src/langs.ts | 14 ++++++++++++++ scripts/docker-install-phase3a.bash | 3 +++ 2 files changed, 17 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 6c4b6c0..dfee7cb 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -197,6 +197,20 @@ message: compile: "asciidoc -s main.adoc", run: "prettier --no-config main.html", template: `Hello, world! +`, + }, + "aspectc++":{ + aliases: ["aspectcpp"], + name: "AspectC++", + main: "main.cpp", + compile: `ag++ main.cpp -o main | (grep -v "TO BE FIXED" || true)`, + run: "./main", + template: `#include + +int main() { + std::cout << "Hello, world!" << std::endl; + return 0; +} `, }, ats: { diff --git a/scripts/docker-install-phase3a.bash b/scripts/docker-install-phase3a.bash index dccc00a..0ff192a 100755 --- a/scripts/docker-install-phase3a.bash +++ b/scripts/docker-install-phase3a.bash @@ -36,6 +36,9 @@ qemu-user-static # AsciiDoc asciidoc +# AspectC++ +aspectc++ + # ATS ats2-lang From ee157193a9664b3ab5ab2370b4dce7b20fa0c802 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 27 Sep 2020 14:52:52 -0700 Subject: [PATCH 309/388] [#24] New language: AspectJ --- backend/src/langs.ts | 13 +++++++++++++ scripts/docker-install-phase3a.bash | 3 +++ 2 files changed, 16 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index dfee7cb..2e3246a 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -212,6 +212,19 @@ int main() { return 0; } `, + }, + aspectj: { + aliases: ["aj"], + name: "AspectJ", + main: "Main.aj", + compile: "ajc Main.aj", + run: "java Main", + template: `public class Main { + public static void main(String[] args) { + System.out.println("Hello, world!"); + } +} +` }, ats: { aliases: ["dats"], diff --git a/scripts/docker-install-phase3a.bash b/scripts/docker-install-phase3a.bash index 0ff192a..29e5508 100755 --- a/scripts/docker-install-phase3a.bash +++ b/scripts/docker-install-phase3a.bash @@ -39,6 +39,9 @@ asciidoc # AspectC++ aspectc++ +# AspectJ +aspectj + # ATS ats2-lang From aa4ff4d4cf84a046d1314a3ccc9634f97b7e79c2 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 27 Sep 2020 15:04:31 -0700 Subject: [PATCH 310/388] [#24] New language: Asymptote --- backend/src/langs.ts | 9 +++++++++ scripts/docker-install-phase3a.bash | 3 +++ 2 files changed, 12 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 2e3246a..5b96372 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -225,6 +225,15 @@ int main() { } } ` + }, + asymptote: { + aliases: ["asy"], + name: "Asymptote", + repl: "asy", + main: "main.asy", + run: "asy main.asy; asy", + template: `write("Hello, world!"); +`, }, ats: { aliases: ["dats"], diff --git a/scripts/docker-install-phase3a.bash b/scripts/docker-install-phase3a.bash index 29e5508..6a173a7 100755 --- a/scripts/docker-install-phase3a.bash +++ b/scripts/docker-install-phase3a.bash @@ -42,6 +42,9 @@ aspectc++ # AspectJ aspectj +# Asymptote +asymptote + # ATS ats2-lang From 49ba98c8fc954787eab1b61f0374ac134ae8fba7 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 27 Sep 2020 17:08:11 -0700 Subject: [PATCH 311/388] [#24] New language: bc --- backend/src/langs.ts | 9 +++++++++ scripts/docker-install-phase3a.bash | 3 +++ 2 files changed, 12 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 5b96372..9081b2a 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -295,6 +295,15 @@ implement main0 () = () fun main syscall(1, 1, message, len(message)) end +`, + }, + bc: { + name: "bc", + repl: "bc", + main: "main.bc", + run: "bc main.bc", + template: `"Hello, world! +" `, }, beatnik: { diff --git a/scripts/docker-install-phase3a.bash b/scripts/docker-install-phase3a.bash index 6a173a7..b7cf64c 100755 --- a/scripts/docker-install-phase3a.bash +++ b/scripts/docker-install-phase3a.bash @@ -61,6 +61,9 @@ bash golang yasm +# bc +bc + # BrainF beef From 69723f203ab4b4baabdebae2470d5fa724e0bfe2 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 27 Sep 2020 19:33:00 -0700 Subject: [PATCH 312/388] Fixes for Ante Turns out it's quite poorly designed. --- backend/src/langs.ts | 3 ++- scripts/docker-install-phase4.bash | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 9081b2a..4afa77b 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -144,9 +144,10 @@ println (* 123 234)`, ante: { aliases: ["an"], name: "Ante", + repl: "ante", main: "main.an", compile: "ante main.an", - run: "./main", + run: "./main; ante", template: `puts("Hello, world!".cStr) `, }, diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 18e3f9f..75e6352 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -34,8 +34,10 @@ mv linux/*.so* /usr/lib/x86_64-linux-gnu/ rm -rf linux linux-latest.tar.gz # Ante -wget -nv https://github.com/raxod502/riju-cdn/releases/download/ante-0.8.0-d2c43992e0c7a4c1942d5c097233f4f7638a1ee6/ante -O /usr/local/bin/ante -chmod +x /usr/local/bin/ante +wget -nv https://github.com/raxod502/riju-cdn/releases/download/ante-0.8.0-d2c43992e0c7a4c1942d5c097233f4f7638a1ee6/ante -O /opt/ante/ante +chmod +x /opt/ante/ante +wget -nv https://github.com/raxod502/riju-cdn/releases/download/ante-0.8.0-d2c43992e0c7a4c1942d5c097233f4f7638a1ee6/libantecommon.so -O /opt/ante/libantecommon.so +ln -s /opt/ante/ante /usr/local/bin/ # Ante (Cards) wget -nv https://github.com/michaeldv/ante/raw/master/ante.rb -O /usr/local/bin/ante-cards From 8d50ff12347c0a98eceac5be8265fa02be60eb8f Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 27 Sep 2020 19:45:20 -0700 Subject: [PATCH 313/388] [#24] New language: Beanshell --- backend/src/langs.ts | 15 +++++++++++++++ scripts/docker-install-phase3a.bash | 3 +++ 2 files changed, 18 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 4afa77b..4a18e82 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -305,6 +305,21 @@ end run: "bc main.bc", template: `"Hello, world! " +`, + }, + beanshell: { + aliases: ["bsh"], + name: "Beanshell", + repl: `CLASSPATH=/usr/share/java/jline.jar:/usr/share/java/bsh.jar java -Duser.home="$PWD" jline.ConsoleRunner bsh.Interpreter`, + input: `print(123 * 234);`, + main: ".bshrc", + createEmpty: ``, + run: `CLASSPATH=/usr/share/java/jline.jar:/usr/share/java/bsh.jar java -Duser.home="$PWD" jline.ConsoleRunner bsh.Interpreter`, + scope: { + code: `x = 123 * 234;`, + input: `print(x);`, + }, + template: `print("Hello, world!"); `, }, beatnik: { diff --git a/scripts/docker-install-phase3a.bash b/scripts/docker-install-phase3a.bash index b7cf64c..3110ff4 100755 --- a/scripts/docker-install-phase3a.bash +++ b/scripts/docker-install-phase3a.bash @@ -64,6 +64,9 @@ yasm # bc bc +# Beanshell +bsh + # BrainF beef From d6f4777ed1fdb976531d4a74ac9b53f0c71b83f2 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 27 Sep 2020 19:49:59 -0700 Subject: [PATCH 314/388] [#24] New language: CMake --- backend/src/langs.ts | 8 ++++++++ scripts/docker-install-phase3a.bash | 3 +++ 2 files changed, 11 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 4a18e82..860bf2a 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -702,6 +702,14 @@ Start world code: `(def x (* 123 234))`, }, template: `(println "Hello, world!") +`, + }, + cmake: { + aliases: ["cmakelists"], + name: "CMake", + main: "main.cmake", + run: "cmake -P main.cmake", + template: `message("Hello, world!") `, }, cmd: { diff --git a/scripts/docker-install-phase3a.bash b/scripts/docker-install-phase3a.bash index 3110ff4..3d0311e 100755 --- a/scripts/docker-install-phase3a.bash +++ b/scripts/docker-install-phase3a.bash @@ -86,6 +86,9 @@ openjdk-8-jdk-headless # Clojure clojure +# CMake +cmake + # Cmd wine wine32 From 8e7ea4d540f15876c0ae01359a184a556e32fc2f Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 27 Sep 2020 19:52:02 -0700 Subject: [PATCH 315/388] [#24] New language: Make --- backend/src/langs.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 860bf2a..c8d880b 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1707,6 +1707,23 @@ KTHXBYE `, skip: ["lsp"], }, + make: { + aliases: [ + "gmake", + "makefile", + "gmakefile", + "gnumakefile", + "gnumake", + "bsdmake", + ], + name: "Make", + main: "Makefile", + run: "make", + template: `.PHONY: all +all: + @echo "Hello, world!" +`, + }, malbolge: { aliases: ["mb"], name: "Malbolge", From 0acb6ed87174326ff227eb37199261df2a125c47 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 27 Sep 2020 20:10:51 -0700 Subject: [PATCH 316/388] [#24] New language: Curry --- backend/src/langs.ts | 13 +++++++++++++ scripts/docker-install-phase3a.bash | 3 +++ 2 files changed, 16 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index c8d880b..f7fbee7 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -813,6 +813,19 @@ require("/usr/lib/node_modules/coffeescript/repl").start() System.Console.WriteLine("Hello, world!"); } } +`, + }, + curry: { + aliases: ["curry2prolog", "pakcs"], + name: "Curry", + repl: "pakcs", + main: "main.curry", + run: "pakcs :load main.curry :eval main", + scope: { + code: `x = 123 * 234`, + }, + template: `main :: IO () +main = putStrLn "Hello, world!" `, }, d: { diff --git a/scripts/docker-install-phase3a.bash b/scripts/docker-install-phase3a.bash index 3d0311e..01f6c3f 100755 --- a/scripts/docker-install-phase3a.bash +++ b/scripts/docker-install-phase3a.bash @@ -103,6 +103,9 @@ sbcl # Crystal crystal +# Curry +pakcs + # Dart dart From 6a89992c8d78eefcbd68c31e0d2db732928f4aff Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 27 Sep 2020 20:29:00 -0700 Subject: [PATCH 317/388] [#24] New language: Dafny --- backend/src/langs.ts | 11 +++++++++++ scripts/docker-install-phase3a.bash | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index f7fbee7..5742b96 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -849,6 +849,17 @@ void main() { writeln("Hello, world!"); } +`, + }, + dafny: { + aliases: ["dfy"], + name: "Dafny", + main: "main.dfy", + compile: "dafny main.dfy", + run: "mono main.exe", + template: `method Main() { + print "Hello, world!\\n"; +} `, }, dart: { diff --git a/scripts/docker-install-phase3a.bash b/scripts/docker-install-phase3a.bash index 01f6c3f..bd3396f 100755 --- a/scripts/docker-install-phase3a.bash +++ b/scripts/docker-install-phase3a.bash @@ -106,6 +106,10 @@ crystal # Curry pakcs +# Dafny +dafny +mono-runtime + # Dart dart From 31f01eb6f20e77dbc0e4729b3d87a3ca45ca9a5a Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 27 Sep 2020 20:36:36 -0700 Subject: [PATCH 318/388] [#24] New language: dc --- backend/src/langs.ts | 13 +++++++++++++ scripts/docker-install-phase3a.bash | 3 +++ 2 files changed, 16 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 5742b96..72f120d 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -879,6 +879,19 @@ void main() `, skip: ["lsp"], }, + dc: { + name: "dc", + repl: "echo 'Reading from stdin...' >&2; dc", + input: `123 234 * p`, + main: "main.dc", + run: "echo 'Reading from stdin...' >&2; dc main.dc -", + scope: { + code: `123 234 *`, + input: `p`, + }, + template: `[Hello, world!] p +`, + }, dogescript: { aliases: ["doge", "ds", "wow"], name: "Dogescript", diff --git a/scripts/docker-install-phase3a.bash b/scripts/docker-install-phase3a.bash index bd3396f..28d5ec6 100755 --- a/scripts/docker-install-phase3a.bash +++ b/scripts/docker-install-phase3a.bash @@ -113,6 +113,9 @@ mono-runtime # Dart dart +# dc +dc + # Dhall dhall From 0f76de5910445511c2682a2b1cb3b9a8543cfe6c Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 28 Sep 2020 08:27:46 -0700 Subject: [PATCH 319/388] Fix for Ante --- scripts/docker-install-phase4.bash | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 75e6352..d6bca4e 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -34,6 +34,7 @@ mv linux/*.so* /usr/lib/x86_64-linux-gnu/ rm -rf linux linux-latest.tar.gz # Ante +mkdir /opt/ante wget -nv https://github.com/raxod502/riju-cdn/releases/download/ante-0.8.0-d2c43992e0c7a4c1942d5c097233f4f7638a1ee6/ante -O /opt/ante/ante chmod +x /opt/ante/ante wget -nv https://github.com/raxod502/riju-cdn/releases/download/ante-0.8.0-d2c43992e0c7a4c1942d5c097233f4f7638a1ee6/libantecommon.so -O /opt/ante/libantecommon.so From 0741393ee00e14923a18c671e9284535f0e5b1cb Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 28 Sep 2020 18:42:20 -0700 Subject: [PATCH 320/388] Another fix for Ante --- scripts/docker-install-phase4.bash | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index d6bca4e..94d2a2c 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -39,6 +39,9 @@ wget -nv https://github.com/raxod502/riju-cdn/releases/download/ante-0.8.0-d2c43 chmod +x /opt/ante/ante wget -nv https://github.com/raxod502/riju-cdn/releases/download/ante-0.8.0-d2c43992e0c7a4c1942d5c097233f4f7638a1ee6/libantecommon.so -O /opt/ante/libantecommon.so ln -s /opt/ante/ante /usr/local/bin/ +wget -nv https://github.com/raxod502/riju-cdn/releases/download/ante-0.8.0-d2c43992e0c7a4c1942d5c097233f4f7638a1ee6/stdlib.tar.gz +tar -xf stdlib.tar.gz -C /opt/ante +rm stdlib.tar.gz # Ante (Cards) wget -nv https://github.com/michaeldv/ante/raw/master/ante.rb -O /usr/local/bin/ante-cards From f6f8ec6847ffb56c7cffbb8a9b58144cae2128f1 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 28 Sep 2020 18:45:53 -0700 Subject: [PATCH 321/388] [#24] New language: eC --- backend/src/langs.ts | 15 +++++++++++++++ scripts/docker-install-phase3b.bash | 3 +++ 2 files changed, 18 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 72f120d..3e2ad1a 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -934,6 +934,21 @@ define function main end function main; main(application-name(), application-arguments()); +`, + }, + ec: { + aliases: ["ecere", "ecp", "ecs", "ecc"], + name: "eC", + main: "main.ec", + compile: "ecp -c main.ec -o main.sym && ecc -c main.ec -o main.c && ecs -console main.sym main.imp -o main.main.ec && ecp -c main.main.ec -o main.main.sym && ecc -c main.main.ec -o main.main.c && clang main.c main.main.c -lecereCOM -o main", + run: "./main", + template: `class Main : Application +{ + void Main() + { + PrintLn("Hello, world!"); + } +} `, }, elixir: { diff --git a/scripts/docker-install-phase3b.bash b/scripts/docker-install-phase3b.bash index 123e5ec..72c57d7 100755 --- a/scripts/docker-install-phase3b.bash +++ b/scripts/docker-install-phase3b.bash @@ -12,6 +12,9 @@ lua_name="$(grep-aptavail -XF Provides lua -a -XF Version "${lua_ver}" -s Packag packages=" +# eC +ecere-dev + # Elixir elixir From d96c1dad2e87aa01f6ed20f20cacc88ed93313f3 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 28 Sep 2020 19:02:03 -0700 Subject: [PATCH 322/388] [#24] New language: FALSE --- backend/src/langs.ts | 8 ++++++++ scripts/docker-install-phase4.bash | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 3e2ad1a..488171b 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1111,6 +1111,14 @@ x`, USE: io "Hello, world!" print +`, + }, + "false": { + aliases: ["falselang"], + name: "FALSE", + main: "main.false", + run: "false-lang main.false", + template: `"Hello, world!" `, }, fish: { diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 94d2a2c..b1f6a59 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -148,6 +148,12 @@ mv -T factor /opt/factor ln -s /opt/factor/factor /usr/local/bin/factor-lang rm factor-linux-x86-64-*.tar.gz +# False +wget https://github.com/mame/quine-relay/raw/master/vendor/false.rb +cat <(echo '#!/usr/bin/env ruby') false.rb > /usr/local/bin/false-lang +chmod +x /usr/local/bin/false-lang +rm false.rb + # Go export GO111MODULE=on export GOPATH="$PWD/go" From 014a97fd2a5f833633fe45e9c3b3acaade527ac2 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 28 Sep 2020 19:17:47 -0700 Subject: [PATCH 323/388] [#24] New language: jq --- backend/src/langs.ts | 15 +++++++++++++++ backend/src/test-runner.ts | 5 ++++- package.json | 1 + scripts/docker-install-phase3b.bash | 3 +++ yarn.lock | 12 ++++++++++++ 5 files changed, 35 insertions(+), 1 deletion(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 488171b..69c7283 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1629,6 +1629,21 @@ PLEASE GIVE UP "curl -sS 'https://registry.npmjs.org/-/v1/search?text=NAME' | jq -r '.objects | map(.package.name) | .[]'", }, template: `console.log("Hello, world!"); +`, + }, + jq: { + name: "jq", + repl: "echo 'Reading from stdin...' >&2 && while true; do jq .; done", + input: `{"foo":"bar"}`, + output: `"foo": "bar"`, + main: "main.jq", + run: `echo 'Reading from stdin...' >&2 && while true; do jq "$(< main.jq)"; done`, + helloInput: `{}`, + // This test doesn't actually test anything, because "Hello, + // world" is already printed before anything is sent to the repl, + // but we can't do any better. + runReplOutput: `"Hello, world!"`, + template: `"Hello, world!" `, }, julia: { diff --git a/backend/src/test-runner.ts b/backend/src/test-runner.ts index 9de15c5..4cfb26c 100644 --- a/backend/src/test-runner.ts +++ b/backend/src/test-runner.ts @@ -7,6 +7,7 @@ import { Moment } from "moment"; import * as moment from "moment"; import PQueue from "p-queue"; import * as rimraf from "rimraf"; +import stripAnsi = require("strip-ansi"); import { v4 as getUUID } from "uuid"; import * as api from "./api"; @@ -187,7 +188,9 @@ class Test { return await this.wait(`output ${JSON.stringify(pattern)}`, (msg: any) => { const prevLength = output.length; if (msg.event === "terminalOutput") { - output += msg.output; + // Applying stripAnsi here is wrong because escape sequences + // could be split across multiple messages. Who cares? + output += stripAnsi(msg.output); } if (typeof maxLength === "number") { return ( diff --git a/package.json b/package.json index c58174e..e19f307 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "parse-passwd": "^1.0.0", "rimraf": "^3.0.2", "shell-quote": "^1.7.2", + "strip-ansi": "^6.0.0", "style-loader": "^1.2.1", "ts-loader": "^7.0.5", "typescript": "^3.9.5", diff --git a/scripts/docker-install-phase3b.bash b/scripts/docker-install-phase3b.bash index 72c57d7..9e46d98 100755 --- a/scripts/docker-install-phase3b.bash +++ b/scripts/docker-install-phase3b.bash @@ -64,6 +64,9 @@ intercal clang-format default-jdk +# jq +jq + # Julia julia diff --git a/yarn.lock b/yarn.lock index 27ba20a..6e944d5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1152,6 +1152,11 @@ ansi-regex@^4.1.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== +ansi-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -4570,6 +4575,13 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" +strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== + dependencies: + ansi-regex "^5.0.0" + strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" From 810673ee2ef3547480ed21e7af5d6ce96e133278 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 28 Sep 2020 19:36:27 -0700 Subject: [PATCH 324/388] [#24] New language: Flex --- backend/src/langs.ts | 25 +++++++++++++++++++++++++ backend/src/test-runner.ts | 4 +++- scripts/docker-install-phase3b.bash | 4 ++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 69c7283..2c5ede8 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1132,6 +1132,31 @@ USE: io input: `echo $x`, }, template: `echo "Hello, world!" +`, + }, + flex: { + aliases: ["lex"], + name: "Flex", + main: "main.lex", + compile: "lex -o main.c main.lex && clang main.c -o main", + run: "echo 'Reading from stdin, ctrl+D to end input...' >&2 && ./main", + helloInput: "EOF", + template: `%{ +#include +%} + +%% +%% + +int yywrap() { + printf("Hello, world!\\n"); + return 1; +} + +int main() { + yylex(); + return 0; +} `, }, forth: { diff --git a/backend/src/test-runner.ts b/backend/src/test-runner.ts index 4cfb26c..95417cd 100644 --- a/backend/src/test-runner.ts +++ b/backend/src/test-runner.ts @@ -31,7 +31,9 @@ function findPosition(str: string, idx: number) { async function sendInput(send: (msg: any) => any, input: string) { for (const line of input.split("\n")) { - if (line.startsWith("DELAY:")) { + if (line === "EOF") { + send({ event: "terminalInput", input: "\u0004" }); + } else if (line.startsWith("DELAY:")) { const delay = parseFloat(line.replace(/DELAY: */, "")); if (Number.isNaN(delay)) continue; await new Promise((resolve) => diff --git a/scripts/docker-install-phase3b.bash b/scripts/docker-install-phase3b.bash index 9e46d98..f01ff5a 100755 --- a/scripts/docker-install-phase3b.bash +++ b/scripts/docker-install-phase3b.bash @@ -35,6 +35,10 @@ fsharp # Fish fish +# Flex +flex +flex-doc + # FORTRAN flang From b873667c34cb94e9c1dfd1ba090bd78a3e00c669 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 28 Sep 2020 19:43:53 -0700 Subject: [PATCH 325/388] [#24] New language: Gambas --- backend/src/langs.ts | 8 ++++++++ scripts/docker-install-phase3b.bash | 3 +++ 2 files changed, 11 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 2c5ede8..e53b6a5 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1211,6 +1211,14 @@ int main() { `, timeout: 15, }, + gambas: { + aliases: ["gambasscript", "gbs"], + name: "Gambas", + main: "main.gbs", + run: "gbs3 main.gbs", + template: `Print "Hello, world!" +`, + }, go: { aliases: ["golang"], name: "Go", diff --git a/scripts/docker-install-phase3b.bash b/scripts/docker-install-phase3b.bash index f01ff5a..5c19d8e 100755 --- a/scripts/docker-install-phase3b.bash +++ b/scripts/docker-install-phase3b.bash @@ -45,6 +45,9 @@ flang # Forth gforth +# Gambas +gambas3-script + # Go golang From f52d795a12dd701c03ed10e9a86fef1a2f68bfb5 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 28 Sep 2020 19:52:29 -0700 Subject: [PATCH 326/388] [#24] New language: GAP --- backend/src/langs.ts | 13 +++++++++++++ scripts/docker-install-phase3b.bash | 3 +++ 2 files changed, 16 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index e53b6a5..8b096f3 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1217,6 +1217,19 @@ int main() { main: "main.gbs", run: "gbs3 main.gbs", template: `Print "Hello, world!" +`, + }, + gap: { + name: "GAP", + repl: "gap", + input: `123 * 234;`, + main: "main.gap", + run: "gap main.gap", + scope: { + code: `x := 123 * 234;`, + input: `123 * 234;`, + }, + template: `Print("Hello, world!\\n"); `, }, go: { diff --git a/scripts/docker-install-phase3b.bash b/scripts/docker-install-phase3b.bash index 5c19d8e..e5870f5 100755 --- a/scripts/docker-install-phase3b.bash +++ b/scripts/docker-install-phase3b.bash @@ -48,6 +48,9 @@ gforth # Gambas gambas3-script +# GAP +gap + # Go golang From 779de3a0176205c98440cf53676ba8eea6bf0050 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 28 Sep 2020 19:56:43 -0700 Subject: [PATCH 327/388] [#24] New language: GDB --- backend/src/langs.ts | 13 +++++++++++++ scripts/docker-install-phase3b.bash | 3 +++ 2 files changed, 16 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 8b096f3..98703dd 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1230,6 +1230,19 @@ int main() { input: `123 * 234;`, }, template: `Print("Hello, world!\\n"); +`, + }, + gdb: { + name: "GDB", + repl: "gdb", + input: "p 123 * 234", + main: "main.gdb", + run: "gdb -x main.gdb", + scope: { + code: `set $x = 123 * 234`, + input: `p $x`, + }, + template: `p "Hello, world!" `, }, go: { diff --git a/scripts/docker-install-phase3b.bash b/scripts/docker-install-phase3b.bash index e5870f5..5dc5822 100755 --- a/scripts/docker-install-phase3b.bash +++ b/scripts/docker-install-phase3b.bash @@ -51,6 +51,9 @@ gambas3-script # GAP gap +# GDB +gdb + # Go golang From cc78f49a1306b3440e94a383cf382023a852c7d3 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 28 Sep 2020 20:03:31 -0700 Subject: [PATCH 328/388] [#24] New language: GEL --- backend/src/langs.ts | 13 +++++++++++++ scripts/docker-install-phase3b.bash | 3 +++ 2 files changed, 16 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 98703dd..bb68fc9 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1243,6 +1243,19 @@ int main() { input: `p $x`, }, template: `p "Hello, world!" +`, + }, + gel: { + aliases: ["genius"], + name: "GEL", + repl: "genius", + main: ".geniusinit", + createEmpty: ``, + run: "genius", + scope: { + code: `x = 123 * 234`, + }, + template: `print("Hello, world!") `, }, go: { diff --git a/scripts/docker-install-phase3b.bash b/scripts/docker-install-phase3b.bash index 5dc5822..319b897 100755 --- a/scripts/docker-install-phase3b.bash +++ b/scripts/docker-install-phase3b.bash @@ -54,6 +54,9 @@ gap # GDB gdb +# GEL +genius + # Go golang From 6d230c2e114cf791c2503cabe7ed737f214fb8b2 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 28 Sep 2020 20:11:53 -0700 Subject: [PATCH 329/388] [#24] New language: Gnuplot --- backend/src/langs.ts | 13 +++++++++++++ scripts/docker-install-phase3b.bash | 3 +++ 2 files changed, 16 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index bb68fc9..181e021 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1256,6 +1256,19 @@ int main() { code: `x = 123 * 234`, }, template: `print("Hello, world!") +`, + }, + gnuplot: { + name: "Gnuplot", + repl: "gnuplot", + input: `print 123 * 234`, + main: "main.gnuplot", + run: "gnuplot main.gnuplot -", + scope: { + code: `x = 123 * 234`, + input: `print x`, + }, + template: `print "Hello, world!" `, }, go: { diff --git a/scripts/docker-install-phase3b.bash b/scripts/docker-install-phase3b.bash index 319b897..a27cac8 100755 --- a/scripts/docker-install-phase3b.bash +++ b/scripts/docker-install-phase3b.bash @@ -63,6 +63,9 @@ golang # Groovy groovy +# Gnuplot +gnuplot + # Hack hhvm From d3a991a13267098e4870b286fbd18c4ee7b1ddc6 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Tue, 29 Sep 2020 12:27:57 -0700 Subject: [PATCH 330/388] "Fix" Ante tests --- backend/src/langs.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 181e021..07e03d4 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -145,11 +145,13 @@ println (* 123 234)`, aliases: ["an"], name: "Ante", repl: "ante", + output: "i32", main: "main.an", compile: "ante main.an", run: "./main; ante", template: `puts("Hello, world!".cStr) `, + timeout: 10, }, antecards: { name: "Ante (Cards)", From 46f8716f46d751c287e071d3d46b7c5b99249486 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Tue, 29 Sep 2020 12:28:04 -0700 Subject: [PATCH 331/388] [#24] New language: Grass --- backend/src/langs.ts | 8 ++++++++ scripts/docker-install-phase4.bash | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 07e03d4..9a54cf1 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1308,6 +1308,14 @@ func main() { main: "main.gs", run: "golfscript main.gs", template: `'Hello, world!' +`, + }, + grass: { + name: "Grass", + main: "main.grass", + run: "grass < main.grass", + hello: `w`, + template: `wWWwwww `, }, groovy: { diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index b1f6a59..dfbd79a 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -165,6 +165,10 @@ rm -rf go wget -nv http://www.golfscript.com/golfscript/golfscript.rb -O /usr/local/bin/golfscript chmod +x /usr/local/bin/golfscript +# Grass +wget -nv http://www.blue.sky.or.jp/grass/grass.rb -O /usr/local/bin/grass +chmod +x /usr/local/bin/grass + # Haskell curl -sSL https://get.haskellstack.org/ | sh wget -nv https://github.com/raxod502/riju-cdn/releases/download/brittany-0.12.1.1/brittany -O /usr/local/bin/brittany From 51bcd5c69b6fd55998dcd654c6f4be03c8a4ee07 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Tue, 29 Sep 2020 12:34:16 -0700 Subject: [PATCH 332/388] [#24] New language: Icon --- backend/src/langs.ts | 11 +++++++++++ scripts/docker-install-phase3b.bash | 3 +++ 2 files changed, 14 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 9a54cf1..3f5e745 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1479,6 +1479,17 @@ l ; ; o ; * 4 code: `(setv x (* 123 234))`, }, template: `(print "Hello, world!") +`, + }, + icon: { + aliases: ["icn", "icont", "iconx"], + name: "Icon", + main: "main.icn", + compile: "icont main.icn", + run: "./main", + template: `procedure main () + write("Hello, world!") +end `, }, ink: { diff --git a/scripts/docker-install-phase3b.bash b/scripts/docker-install-phase3b.bash index a27cac8..399ce36 100755 --- a/scripts/docker-install-phase3b.bash +++ b/scripts/docker-install-phase3b.bash @@ -76,6 +76,9 @@ ghc # Haxe haxe +# Icon +icont + # INTERCAL intercal From cfd2d977e01e8a416caad903d4a3f07365db2251 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Tue, 29 Sep 2020 12:39:37 -0700 Subject: [PATCH 333/388] [#24] New language: Jasmin --- backend/src/langs.ts | 23 +++++++++++++++++++++++ scripts/docker-install-phase3b.bash | 3 +++ 2 files changed, 26 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 3f5e745..3ac9766 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1547,6 +1547,29 @@ PLEASE GIVE UP main: "main.ijs", run: "ijconsole main.ijs", template: `echo 'Hello, world!' +`, + }, + jasmin: { + name: "Jasmin", + main: "Main.j", + compile: "jasmin Main.j", + run: "java Main", + template: `.class public Main +.super java/lang/Object + +.method public ()V + aload_0 + invokenonvirtual java/lang/Object/()V + return +.end method + +.method public static main([Ljava/lang/String;)V + .limit stack 2 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc "Hello, world!" + invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V + return +.end method `, }, java: { diff --git a/scripts/docker-install-phase3b.bash b/scripts/docker-install-phase3b.bash index 399ce36..07e4f9e 100755 --- a/scripts/docker-install-phase3b.bash +++ b/scripts/docker-install-phase3b.bash @@ -82,6 +82,9 @@ icont # INTERCAL intercal +# Jasmin +jasmin-sable + # Java clang-format default-jdk From 4652760bf15c1526b4c9012bfeebe82acb73aac9 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Tue, 29 Sep 2020 12:45:26 -0700 Subject: [PATCH 334/388] [#24] New language: JSF*** --- backend/src/langs.ts | 139 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 3ac9766..61b41e6 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1773,6 +1773,145 @@ PLEASE GIVE UP // but we can't do any better. runReplOutput: `"Hello, world!"`, template: `"Hello, world!" +`, + }, + jsf: { + name: "JSF***", + main: "main.js", + run: `sed 's/[^[]()!+]//g' main.js | node`, + template: `[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]][([]+[][(![] ++[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+!![]]+( +!![]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![] ++[+[]]]+([][[]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!! +[]]+([][[]]+[])[+[]]+([]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(! +![]+[])[+[]]])[!![]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!! +[]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+(!![]+[])[+!![]]]((!![]+[ +])[+!![]]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+! +![]]+([][[]]+[])[+!![]]+(![]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![] +]+(!![]+[])[+[]]])[!![]+!![]+[+[]]]+([]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![ +]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+!![]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!! +[]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+([][[]]+[])[+!![]]+(![]+[ +])[!![]+!![]+!![]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(! +![]+[])[+[]]])[+!![]+[+[]]]+(![]+[])[!![]+!![]]+(!![]+[])[!![]+!![]+!![]])()[(![ +]+[])[!![]+!![]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![ +]+[])[+[]]])[+!![]+[+[]]]+(+[]+[![]]+([]+[])[([]+[][(![]+[])[+[]]+(![]+[])[!![]+ +!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+!![]]+(!![]+[][(![]+[])[+[]]+(! +[]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+([][[]]+[])[+!![ +]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([] ++[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![] ++!![]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]] ++(!![]+[])[+[]]])[+!![]+[+[]]]+(!![]+[])[+!![]]])[!![]+!![]+[+[]]]]([][(![]+[])[ ++[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]][([]+[][(![]+[])[+[]]+(! +[]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+!![]]+(!![]+[][(![] ++[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+([][ +[]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+ +[])[+[]]+([]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]] +])[!![]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![ +]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+(! +![]+[])[!![]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]] ++[])[+!![]]+([]+[])[(![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![ +]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+([][[]]+[])[+!![]]+(!![]+[])[+[]]+([] ++[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![] ++!![]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]] +])[+!![]+[+[]]]+(![]+[])[!![]+!![]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+( +![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+(!![]+[])[+!![]]]()[+!![]+[!![]+!![ +]]]+(![]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]][([ +]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![ +]+!![]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[] +]])[+!![]+[+[]]]+([][[]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+[]]+(!![ +]+[])[+!![]]+([][[]]+[])[+[]]+([]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[ ++!![]]+(!![]+[])[+[]]])[!![]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(! +[]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+(!![]+[])[+!![]] +]((!![]+[])[+!![]]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!! +[]+[])[+!![]]+([][[]]+[])[+!![]]+(!![]+[])[(![]+[])[!![]+!![]+!![]]+([][[]]+[])[ ++[]]+([][(!![]+[])[!![]+!![]+!![]]+([][[]]+[])[+!![]]+(!![]+[])[+[]]+(!![]+[])[+ +!![]]+([![]]+[][[]])[+!![]+[+[]]]+(!![]+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+! +![]]]()+[])[!![]+!![]]]()[+!![]+[+[]]]+![]+(!![]+[])[(![]+[])[!![]+!![]+!![]]+([ +][[]]+[])[+[]]+([][(!![]+[])[!![]+!![]+!![]]+([][[]]+[])[+!![]]+(!![]+[])[+[]]+( +!![]+[])[+!![]]+([![]]+[][[]])[+!![]+[+[]]]+(!![]+[])[!![]+!![]+!![]]+(![]+[])[! +![]+!![]+!![]]]()+[])[!![]+!![]]]()[+!![]+[+[]]])()[([]+[][(![]+[])[+[]]+(![]+[] +)[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+!![]]+(!![]+[][(![]+[])[ ++[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+([][[]]+[ +])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+ +[]]+([]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[!! +[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[]) +[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+(!![]+[])[+!![]]](([]+[])[([![]]+[][[]])[+ +!![]+[+[]]]+(!![]+[])[+[]]+(![]+[])[+!![]]+(![]+[])[!![]+!![]]+([![]]+[][[]])[+! +![]+[+[]]]+([]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[ +]]])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]]()))[+!![]+[+[]]]+(+!![])+(+!![])+ +(+[])+([]+[])[(![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[ ++!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+([][[]]+[])[+!![]]+(!![]+[])[+[]]+([]+[][(! +[]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+!![]] ++(!![]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[+!! +[]+[+[]]]+(![]+[])[!![]+!![]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[] +)[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+(!![]+[])[+!![]]]()[+!![]+[!![]+!![]]])() ++(!![]+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]]+(![]+[])[!![]+!![]]+(!![]+[][(![] ++[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+([][ +(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]][([]+[][(![]+[] +)[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+!![]]+(![] ++[])[+!![]]+(![]+[])[!![]+!![]]+(![]+[])[!![]+!![]]](![]+[])+[])[+!![]]+(![]+[][ +(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+[+[ +]]]+(+(+!![]+[+!![]]+(+!![])+(!![]+!![])))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]] ++(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+([]+[])[([]+[ +][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+! +![]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]]) +[+!![]+[+[]]]+([][[]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[ +])[+!![]]+([][[]]+[])[+[]]+([]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!! +[]]+(!![]+[])[+[]]])[!![]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+ +[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+(!![]+[])[+!![]]][( +[][[]]+[])[+!![]]+(![]+[])[+!![]]+([]+(+[])[([]+[][(![]+[])[+[]]+(![]+[])[!![]+! +![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+!![]]+(!![]+[][(![]+[])[+[]]+(![ +]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+([][[]]+[])[+!![] +]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+ +[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+ +!![]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+ +(!![]+[])[+[]]])[+!![]+[+[]]]+(!![]+[])[+!![]]])[+!![]+[+!![]]]+(!![]+[])[!![]+! +![]+!![]]]](!![]+!![]+!![]+[!![]+!![]+!![]+!![]])+(!![]+[])[+!![]]+(![]+[])[!![] ++!![]]+([][[]]+[])[!![]+!![]]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![ +]]+(!![]+[])[+[]]][([]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![ +]+[])[+[]]])[!![]+!![]+!![]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[]) +[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+([][[]]+[])[+!![]]+(![]+[])[!![]+!![]+!![] +]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+[][(![]+[])[+[]]+(![]+[]) +[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+!![]]+(!![]+[])[+[]]+(!![ +]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+ +[]]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+[]] ++([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+[])[(![]+[])[+[]]+(!![ +]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+ +[]]]+([][[]]+[])[+!![]]+(!![]+[])[+[]]+([]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+ +(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+!![]]+(!![]+[][(![]+[])[+[]]+(![]+[]) +[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+(![]+[])[!![]+!![]]+(! +![]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+ +[+[]]]+(!![]+[])[+!![]]]()[+!![]+[!![]+!![]]]+(![]+[][(![]+[])[+[]]+(![]+[])[!![ +]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]][([]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]] ++(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+!![]]+(!![]+[][(![]+[])[+[]]+(![]+[] +)[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+([][[]]+[])[+!![]]+(! +[]+[])[!![]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+[][( +![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+!![] +]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![ +]+[])[+[]]])[+!![]+[+[]]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+(!![]+[])[!![]+!![] ++!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+(!![] ++[])[(![]+[])[!![]+!![]+!![]]+([][[]]+[])[+[]]+([][(!![]+[])[!![]+!![]+!![]]+([] +[[]]+[])[+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([![]]+[][[]])[+!![]+[+[]]]+(!![ +]+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]]()+[])[!![]+!![]]]()[+!![]+[+[]]] ++![]+(!![]+[])[(![]+[])[!![]+!![]+!![]]+([][[]]+[])[+[]]+([][(!![]+[])[!![]+!![] ++!![]]+([][[]]+[])[+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([![]]+[][[]])[+!![]+[ ++[]]]+(!![]+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]]()+[])[!![]+!![]]]()[+! +![]+[+[]]])()[([]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[]) +[+[]]])[!![]+!![]+!![]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![ +]]+(!![]+[])[+[]]])[+!![]+[+[]]]+([][[]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!! +[]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+[][(![]+[])[+[]]+(![]+[])[!![] ++!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[][ +(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+ +(!![]+[])[+!![]]](([]+[])[([![]]+[][[]])[+!![]+[+[]]]+(!![]+[])[+[]]+(![]+[])[+! +![]]+(![]+[])[!![]+!![]]+([![]]+[][[]])[+!![]+[+[]]]+([]+[][(![]+[])[+[]]+(![]+[ +])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+!![]]+(![]+[])[!![]+!![ +]+!![]]]()))[+!![]+[+[]]]+(!![]+!![]+!![]+!![])+(+!![])+([]+[])[(![]+[])[+[]]+(! +![]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+ +[+[]]]+([][[]]+[])[+!![]]+(!![]+[])[+[]]+([]+[][(![]+[])[+[]]+(![]+[])[!![]+!![] +]+(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+!![]]+(!![]+[][(![]+[])[+[]]+(![]+[ +])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+(![]+[])[!![]+!![]]+ +(!![]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![ +]+[+[]]]+(!![]+[])[+!![]]]()[+!![]+[!![]+!![]]])()) `, }, julia: { From 9243f1b6cbdb574c63b38492d59309b39d6e7766 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Tue, 29 Sep 2020 12:57:46 -0700 Subject: [PATCH 335/388] [#24] New language: Lazy K --- backend/src/langs.ts | 6 ++++++ scripts/docker-install-phase6.bash | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 61b41e6..858054b 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1980,6 +1980,12 @@ PLEASE GIVE UP template: `echo "Hello, world!" `, }, + lazyk: { + name: "Lazy K", + main: "main.lazy", + run: "lazyk -u main.lazy", + template: "K(S(S(S(S(S(S(SI`S`K(S(S`KS(S`KK(S`KS(S(S`KS(S`K`S(SI`KK)(S`KKK)))`K`K(SI`K0))))\n)`K(S`K`S(S`KS(S`K`SI(S`KK(S`K(S(S(SSS)(SS(SSI(SS0))))S(S`KSK))(SI`K(S`KSK))))))\n(S`KKK)))(SII)`K(SII(SII(S(S`KSK)I))))(S`K`S(S(S(SSS)(SS0))S)(SSSS))(SS(SS0))(S(\nSI(SS0))(SS(SS(SS(SS`S(SSS)(SS0))))))(SS(SS(SS(SSSSSS(SS0))))))`S(S(S(SS(SS0))(S\nS0))S))`K(SS0))`K(SS(SS(S(SSS)(SS(SS0))))))I(SSSSSS(SS0)))I(S(SI(SS0))(SS(SS(SS(\nSS`S(SSS)(SS0))))))(SS(S(S(S(SSS)(SS0))S)(SSSS(SS(SS0)))))(S(SSS)(S(SSS)(SS0)))`\nK0)\n", + }, less: { aliases: ["lessc"], name: "Less", diff --git a/scripts/docker-install-phase6.bash b/scripts/docker-install-phase6.bash index b7c476a..005bb11 100755 --- a/scripts/docker-install-phase6.bash +++ b/scripts/docker-install-phase6.bash @@ -73,6 +73,14 @@ mv src-kalyn/Stdlib src-kalyn/Stdlib.kalyn /opt/kalyn/ popd >/dev/null rm -rf kalyn +# Lazy K +git clone https://github.com/irori/lazyk.git +pushd lazyk >/dev/null +make +mv lazyk /usr/local/bin/ +popd >/dev/null +rm -rf lazyk + # LOLCODE git clone https://github.com/justinmeza/lci.git pushd lci >/dev/null From 37e1d46a9a625b515afc58cd8fc183217a83b32c Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Tue, 29 Sep 2020 13:07:26 -0700 Subject: [PATCH 336/388] [#24] New language: Lisaac --- backend/src/langs.ts | 15 +++++++++++++++ scripts/docker-install-phase3b.bash | 3 +++ 2 files changed, 18 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 858054b..814ca72 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2002,6 +2002,21 @@ PLEASE GIVE UP template: `body:before { content: "Hello, world!"; } +`, + }, + lisaac: { + name: "Lisaac", + main: "main.li", + compile: "lisaac -gcc -Wno-implicit-function-declaration main.li", + run: "./main", + template: `Section Header + + name := MAIN; + +Section Public + - main <- + ( + "Hello, world!\\n".print; + ); `, }, livescript: { diff --git a/scripts/docker-install-phase3b.bash b/scripts/docker-install-phase3b.bash index 07e4f9e..1cd0b59 100755 --- a/scripts/docker-install-phase3b.bash +++ b/scripts/docker-install-phase3b.bash @@ -98,6 +98,9 @@ julia # Ksh ksh +# Lisaac +lisaac + # LLVM llvm From 59a4a4e91b22492cd7b6c13fc7c8795125917f48 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Tue, 29 Sep 2020 13:20:28 -0700 Subject: [PATCH 337/388] [#24] New language: m4 --- backend/src/langs.ts | 11 +++++++++++ scripts/docker-install-phase3c.bash | 3 +++ 2 files changed, 14 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 814ca72..29bb602 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2071,6 +2071,17 @@ KTHXBYE `, skip: ["lsp"], }, + m4: { + name: "m4", + repl: "echo 'Reading from stdin...' >&2; m4", + input: `eval(123 * 234)`, + main: "main.m4", + run: "echo 'Reading from stdin...' >&2; m4 main.m4 -", + scope: { + code: "define(`x', eval(123 * 234))", + }, + template: "errprint(`Hello, world!')\n", + }, make: { aliases: [ "gmake", diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index b02aa5e..5b7201a 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -6,6 +6,9 @@ set -x packages=" +# m4 +m4 + # MariaDB libtinfo5 From 283afa1859965b57e91fc281c427b0675b044f81 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Tue, 29 Sep 2020 16:18:48 -0700 Subject: [PATCH 338/388] [#24] New language: MiniZinc --- backend/src/langs.ts | 10 ++++++++++ scripts/docker-install-phase3c.bash | 3 +++ 2 files changed, 13 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 29bb602..1494c67 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2155,6 +2155,16 @@ all: compile: "pandoc main.txt -f mediawiki -o main.html", run: "prettier --no-config main.html", template: `Hello, world! +`, + }, + minizinc: { + aliases: ["mzn"], + name: "MiniZinc", + main: "main.mzn", + run: "minizinc --solver Gecode main.mzn", + template: `solve satisfy; + +output ["Hello, world!\\n"]; `, }, mips: { diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index 5b7201a..7876b65 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -12,6 +12,9 @@ m4 # MariaDB libtinfo5 +# MiniZinc +minizinc + # MIPS gcc-mips64-linux-gnuabi64 qemu-user-static From f3c15a0a676dff0d8230f0c92a43e324dc61c3b3 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Tue, 29 Sep 2020 21:08:59 -0700 Subject: [PATCH 339/388] [#24] New language: CIL (MSIL) --- backend/src/langs.ts | 19 +++++++++++++++++++ scripts/docker-install-phase3a.bash | 3 +++ 2 files changed, 22 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 1494c67..a180e39 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -657,6 +657,25 @@ Put milk chocolate into the mixing bowl. Liquefy contents of the mixing bowl. Pour contents of the mixing bowl into the baking dish. Refrigerate for 1 hour. +`, + }, + cil: { + aliases: ["msil", "il", "ilasm"], + name: "CIL", + main: "main.il", + compile: "ilasm main.il", + run: "mono main.exe", + template: `.assembly main {} +.class Main +{ + .method static void Main() cil managed + { + .entrypoint + ldstr "Hello, world!" + call void [mscorlib]System.Console::WriteLine(string) + ret + } +} `, }, clean: { diff --git a/scripts/docker-install-phase3a.bash b/scripts/docker-install-phase3a.bash index 28d5ec6..a1734e2 100755 --- a/scripts/docker-install-phase3a.bash +++ b/scripts/docker-install-phase3a.bash @@ -83,6 +83,9 @@ mono-mcs ${ceylon} openjdk-8-jdk-headless +# CIL +mono-devel + # Clojure clojure From 681db59d4453af8961bf2bde7432899a43c546f9 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 2 Oct 2020 16:40:59 -0700 Subject: [PATCH 340/388] [#24] New language: Neko --- backend/src/langs.ts | 9 +++++++++ scripts/docker-install-phase3c.bash | 3 +++ 2 files changed, 12 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index a180e39..8318400 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2244,6 +2244,15 @@ message: timeout: 15, skip: ["lsp"], }, + neko: { + aliases: ["nekoc"], + name: "Neko", + main: "main.neko", + compile: "nekoc main.neko", + run: "neko main", + template: `$print("Hello, world!\\n"); +`, + }, nim: { name: "Nim", main: "main.nim", diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index 7876b65..0324a7f 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -28,6 +28,9 @@ fis-gtm # MySQL mysql-server +# Neko +neko + # Nim nim From 038334f239ab80d3f637a6dcd6e90f7014b0e884 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 2 Oct 2020 16:51:12 -0700 Subject: [PATCH 341/388] [#24] New language: Nickle --- backend/src/langs.ts | 13 +++++++++++++ scripts/docker-install-phase3c.bash | 3 +++ 2 files changed, 16 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 8318400..d6df18d 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2251,6 +2251,19 @@ message: compile: "nekoc main.neko", run: "neko main", template: `$print("Hello, world!\\n"); +`, + }, + nickle: { + name: "Nickle", + repl: "nickle", + main: "main.nickle", + run: `nickle main.nickle; echo "Type 'load \\"main.nickle\\"' at the repl prompt to bring variables into scope" >&2; nickle`, + scope: { + code: `x = 123 * 234;`, + input: `load "main.nickle" +x`, + }, + template: `printf("Hello, world!\\n"); `, }, nim: { diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index 0324a7f..8dd8ff0 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -31,6 +31,9 @@ mysql-server # Neko neko +# Nickle +nickle + # Nim nim From 9a9f2d086d970e6c4960464dc679120d484676ab Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 2 Oct 2020 17:08:56 -0700 Subject: [PATCH 342/388] [#24] New language: Ook --- backend/src/langs.ts | 25 +++++++++++++++++++++++++ scripts/docker-install-phase3c.bash | 3 +++ scripts/docker-install-phase6.bash | 11 +++++++++++ 3 files changed, 39 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index d6df18d..2b7dfac 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2341,6 +2341,31 @@ print_string "Hello, world!\\n" code: `x = 123 * 234`, }, template: `disp("Hello, world!") +`, + }, + ook: { + name: "Ook", + main: "main.ook", + run: "esco -q main.ook", + hello: "Hello World!", + template: `Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. +Ook. Ook. Ook. Ook. Ook! Ook? Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. +Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook! Ook! Ook? Ook! Ook? Ook. +Ook! Ook. Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. +Ook. Ook. Ook! Ook? Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? +Ook! Ook! Ook? Ook! Ook? Ook. Ook. Ook. Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. +Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook! Ook. Ook. Ook. Ook. Ook. +Ook. Ook. Ook! Ook. Ook. Ook? Ook. Ook? Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. +Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook? Ook. Ook. Ook. +Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook! Ook! Ook? Ook! Ook? Ook. Ook! Ook. +Ook. Ook? Ook. Ook? Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. +Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook? Ook. Ook. Ook. +Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. +Ook. Ook? Ook! Ook! Ook? Ook! Ook? Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. +Ook? Ook. Ook? Ook. Ook? Ook. Ook? Ook. Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. +Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. +Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! +Ook! Ook. Ook. Ook? Ook. Ook? Ook. Ook. Ook! Ook. `, }, omgrofl: { diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index 8dd8ff0..9da3d91 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -52,6 +52,9 @@ opam # Octave octave +# Ook +autoconf + # Pascal fpc diff --git a/scripts/docker-install-phase6.bash b/scripts/docker-install-phase6.bash index 005bb11..da190bf 100755 --- a/scripts/docker-install-phase6.bash +++ b/scripts/docker-install-phase6.bash @@ -93,6 +93,17 @@ git clone https://github.com/bipinu/malbolge.git clang malbolge/malbolge.c -o /usr/local/bin/malbolge rm -rf malbolge +# Ook +git clone https://git.code.sf.net/p/esco/code esco +pushd esco >/dev/null +autoreconf -fi +./configure --prefix="$PWD" +make +make install +mv bin/esco /usr/local/bin/ +popd >/dev/null +rm -rf esco + # Rapira git clone https://github.com/freeduke33/rerap2.git pushd rerap2 >/dev/null From 89fed8b5eea3d9541ffbcddda0b0cbde2750e1d4 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 2 Oct 2020 17:11:34 -0700 Subject: [PATCH 343/388] [#24] New language: PARI/GP --- backend/src/langs.ts | 12 ++++++++++++ scripts/docker-install-phase3c.bash | 3 +++ 2 files changed, 15 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 2b7dfac..02112ba 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2407,6 +2407,18 @@ rofl lol compile: "pandoc main.org -o main.html", run: "prettier --no-config main.html", template: `Hello, world! +`, + }, + parigp: { + aliases: ["gp"], + name: "PARI/GP", + repl: "gp", + main: "main.gp", + run: "gp main.gp", + scope: { + code: `x = 123 * 234`, + }, + template: `print("Hello, world!") `, }, pascal: { diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index 9da3d91..39174d3 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -55,6 +55,9 @@ octave # Ook autoconf +# PARI/GP +pari-gp + # Pascal fpc From f0ccf33ffa1a6f18e45d9c18eedb667e8c450340 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 3 Oct 2020 10:43:27 -0700 Subject: [PATCH 344/388] [#24] New language: Parser3 --- backend/src/langs.ts | 8 ++++++++ scripts/docker-install-phase3c.bash | 3 +++ 2 files changed, 11 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 02112ba..ae54015 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2419,6 +2419,14 @@ rofl lol code: `x = 123 * 234`, }, template: `print("Hello, world!") +`, + }, + parser3: { + aliases: ["parser", "p"], + name: "Parser3", + main: "main.p", + run: "parser3 main.p", + template: `$console:line[Hello, world!] `, }, pascal: { diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index 39174d3..dce1f23 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -58,6 +58,9 @@ autoconf # PARI/GP pari-gp +# Parser3 +parser3-cgi + # Pascal fpc From ee3bd8494369ec49191f40867fe113d9a425f8eb Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 3 Oct 2020 10:54:44 -0700 Subject: [PATCH 345/388] [#24] New language: Pike --- backend/src/langs.ts | 13 +++++++++++++ scripts/docker-install-phase3c.bash | 6 ++++++ 2 files changed, 19 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index ae54015..290ee8d 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2504,6 +2504,19 @@ pikachu pi pi pi pikachu pipi pi pi pikachu pichu pichu pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pikachu pipi pikachu pi pi pi pikachu ka ka ka ka ka ka pikachu ka ka ka ka ka ka ka ka pikachu pipi pi pikachu pipi pikachu +`, + }, + pike: { + name: "Pike", + repl: "pike", + input: `123 * 234;`, + main: "main.pike", + run: "pike main.pike; pike", + template: `int main() +{ + write("Hello, world!\\n"); + return 0; +} `, }, postgresql: { diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index dce1f23..184822b 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -4,6 +4,8 @@ set -e set -o pipefail set -x +pike_name="$(grep-aptavail -eF Package "^pike[0-9.]+$" -s Package -n | sort -Vr | head -n1)" + packages=" # m4 @@ -71,6 +73,10 @@ perlconsole # PHP php +# Pike +${pike_name} +${pike_name}-doc + # PostgreSQL postgresql postgresql-client From a3e15b67baed35664a6f3c4089d06ecd8dd5a943 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 3 Oct 2020 11:02:36 -0700 Subject: [PATCH 346/388] [#24] New language: PostScript --- backend/src/langs.ts | 18 ++++++++++++++++-- scripts/docker-install-phase3c.bash | 4 ++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 290ee8d..87ea76c 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1322,7 +1322,7 @@ func main() { skip: ["lsp"], }, golfscript: { - aliases: ["gs", "golf"], + aliases: ["golf"], name: "GolfScript", main: "main.gs", run: "golfscript main.gs", @@ -2535,6 +2535,20 @@ pipi pikachu timeout: 15, skip: ["lsp"], }, + postscript: { + aliases: ["ps", "gs", "ghostscript"], + name: "PostScript", + repl: "rlwrap gs", + input: `123 234 mul =`, + main: "main.ps", + run: "rlwrap gs main.ps", + scope: { + code: `123 234 mul`, + input: `=`, + }, + template: `(Hello, world!) = +`, + }, powershell: { aliases: ["pwsh", "ps1"], name: "PowerShell", @@ -2582,7 +2596,7 @@ main :- `, }, purescript: { - aliases: ["purs", "pure", "ps"], + aliases: ["purs", "pure"], name: "PureScript", setup: `shopt -s dotglob; cp -R /opt/purescript/project-template/* "$PWD/"`, repl: "spago repl", diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index 184822b..164259a 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -81,6 +81,10 @@ ${pike_name}-doc postgresql postgresql-client +# PostScript +ghostscript +rlwrap + # Prolog swi-prolog From 6cfbc5bc959bd01171a08c48bb434457cc8d77cc Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 3 Oct 2020 11:08:31 -0700 Subject: [PATCH 347/388] [#24] New language: PROMELA --- backend/src/langs.ts | 10 ++++++++++ scripts/docker-install-phase3c.bash | 3 +++ 2 files changed, 13 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 87ea76c..f43aad7 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2582,6 +2582,16 @@ pipi pikachu main :- write("Hello, world!"), nl. +`, + }, + promela: { + aliases: ["spin", "pml"], + name: "PROMELA", + main: "main.pml", + run: "spin main.pml", + template: `active proctype main() { + printf("Hello, world!\\n"); +} `, }, pug: { diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index 164259a..18469ae 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -88,6 +88,9 @@ rlwrap # Prolog swi-prolog +# Promela +spin + # PureScript libtinfo5 From f79d3ef75f2d9271b2714fc231e0ad47b5e6d23f Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 3 Oct 2020 11:16:12 -0700 Subject: [PATCH 348/388] [#24] New language: Ratfor --- backend/src/langs.ts | 10 ++++++++++ scripts/docker-install-phase3c.bash | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index f43aad7..1a9565e 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2711,6 +2711,16 @@ x`, main: "main.rap", run: "rapira main.rap", template: `вывод: "Hello, world!" +`, + }, + ratfor: { + aliases: ["rationalfortran"], + name: "Ratfor", + main: "main.r", + compile: "ratfor main.r -o main.f && flang main.f -o main", + run: "./main", + template: `print *, 'Hello, world!' +end `, }, reasonml: { diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index 18469ae..6736c3a 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -108,6 +108,10 @@ racket # Rapira clang +# Ratfor +flang +ratfor + # Redis redis From fdf15882ba594a4e748d8676f2d50eda87d8d8be Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 3 Oct 2020 11:24:36 -0700 Subject: [PATCH 349/388] [#24] New language: rc --- backend/src/langs.ts | 10 ++++++++++ scripts/docker-install-phase3c.bash | 3 +++ 2 files changed, 13 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 1a9565e..e038672 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2721,6 +2721,16 @@ x`, run: "./main", template: `print *, 'Hello, world!' end +`, + }, + rc: { + aliases: ["runcommands"], + name: "rc", + repl: "rc", + input: `expr 123 '*' 234`, + main: "main.rc", + run: "rc main.rc; rc", + template: `echo Hello, world! `, }, reasonml: { diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index 6736c3a..634b82a 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -112,6 +112,9 @@ clang flang ratfor +# rc +rc + # Redis redis From 101b71a6473673737242e2270d10039ae87ce0ff Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 3 Oct 2020 11:27:10 -0700 Subject: [PATCH 350/388] [#24] New language: REXX --- backend/src/langs.ts | 8 ++++++++ scripts/docker-install-phase3c.bash | 3 +++ 2 files changed, 11 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index e038672..18927a5 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2773,6 +2773,14 @@ EVAL "return 123 * 234" 0`, compile: "pandoc main.rst -o main.html", run: "prettier --no-config main.html", template: `Hello, world! +`, + }, + rexx: { + aliases: ["regina", "reginarexx"], + name: "REXX", + main: "main.rexx", + run: "rexx main.rexx", + template: `say "Hello, world!" `, }, riscv: { diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index 634b82a..96faa06 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -118,6 +118,9 @@ rc # Redis redis +# REXX +regina-rexx + # RISC-V gcc-riscv64-linux-gnu qemu-user-static From 967ea0f22e7314d35c0c2c85f0c77756135b7884 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 3 Oct 2020 11:33:27 -0700 Subject: [PATCH 351/388] [#24] New language: Bython --- backend/src/langs.ts | 8 ++++++++ scripts/docker-install-phase5.bash | 3 +++ 2 files changed, 11 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 18927a5..5722564 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -491,6 +491,14 @@ Nude pagoda careens. +++.------.--------. >>+. >++. +`, + }, + bython: { + aliases: ["by"], + name: "Bython", + main: "main.by", + run: "bython main.by", + template: `print("Hello, world!") `, }, c: { diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index 42dc84f..95eecba 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -27,6 +27,9 @@ npm install -g bash-language-server # Befunge npm install -g befunge93 prompt-sync +# Bython +pip3 install bython + # Chef cpanm -n Acme::Chef From d0919686d599c91bb08364460a4c710d0b7d2c85 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 3 Oct 2020 13:21:40 -0700 Subject: [PATCH 352/388] [#24] New language: TECO --- backend/src/langs.ts | 16 ++++++++++++++++ scripts/docker-install-phase6.bash | 10 ++++++++++ scripts/docker-install-phase7.bash | 14 ++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 5722564..f0a73ed 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -3238,6 +3238,22 @@ PLEASE LIKE AND SUBSCRIBE input: `echo "$x"`, }, template: `echo "Hello, world!" +`, + }, + teco: { + aliases: ["mung"], + name: "TECO", + repl: "teco", + input: `123*234=\x1b\x1b`, + main: "main.txt", + compile: "cat main.txt | teco-encode > main.teco", + run: "mung main.teco", + scope: { + code: `123*234UX$$`, + input: `QX=\x1b\x1b`, + }, + template: `IHello, world! +$HT$$ `, }, tex: { diff --git a/scripts/docker-install-phase6.bash b/scripts/docker-install-phase6.bash index da190bf..95d3fb4 100755 --- a/scripts/docker-install-phase6.bash +++ b/scripts/docker-install-phase6.bash @@ -147,6 +147,16 @@ module.exports = { tokenize, Parser, Environment }; EOF popd >/dev/null +# TECO +git clone https://github.com/blakemcbride/TECOC.git +pushd TECOC/src >/dev/null +make -f makefile.linux +mv tecoc /usr/local/bin/tecoc +ln -s /usr/local/bin/tecoc /usr/local/bin/teco +ln -s /usr/local/bin/tecoc /usr/local/bin/mung +popd >/dev/null +rm -rf TECOC + # Thue wget -nv "$(curl -sSL https://catseye.tc/distribution/Thue_distribution | grep -Eo 'https://catseye.tc/distfiles/thue-[^"]+\.zip' | head -n1)" unzip thue-*.zip diff --git a/scripts/docker-install-phase7.bash b/scripts/docker-install-phase7.bash index 742e467..9c10d0e 100755 --- a/scripts/docker-install-phase7.bash +++ b/scripts/docker-install-phase7.bash @@ -237,6 +237,20 @@ const env = new lang.Environment(runtime); env.run(ast); EOF +# TECO +tee /usr/local/bin/teco-encode >/dev/null <<"EOF" +#!/usr/bin/env -S python3 -u + +import re +import sys + +for line in sys.stdin: + line = re.sub(r"\^(.)", lambda m: chr(ord(m.group(1)) ^ 0b1000000), line) + line = line.replace("$", chr(27)) + print(line, end="") +EOF +chmod +x /usr/local/bin/teco-encode + # Unlambda tee /usr/local/bin/unlambda-repl >/dev/null <<"EOF" #!/usr/bin/env python3 From 8f6cee1276dae67ba8bdd10b1270536854c9ec49 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 3 Oct 2020 13:26:55 -0700 Subject: [PATCH 353/388] Fix Pike version auto-detection --- scripts/docker-install-phase3c.bash | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index 96faa06..b0b80d4 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -4,6 +4,9 @@ set -e set -o pipefail set -x +export DEBIAN_FRONTEND=noninteractive +apt-get update + pike_name="$(grep-aptavail -eF Package "^pike[0-9.]+$" -s Package -n | sort -Vr | head -n1)" packages=" @@ -131,8 +134,6 @@ ruby-dev " -export DEBIAN_FRONTEND=noninteractive -apt-get update apt-get install -y $(grep -v "^#" <<< "$packages") rm -rf /var/lib/apt/lists/* From bb8bcc96a70c8dd33f60948ca60bc8418eaef93b Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 3 Oct 2020 19:32:48 -0700 Subject: [PATCH 354/388] [#24] New language: SageMath --- backend/src/langs.ts | 14 ++++++++++++++ scripts/docker-install-phase3d.bash | 3 +++ 2 files changed, 17 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index f0a73ed..bce8e50 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2884,6 +2884,20 @@ binding_irb.run(IRB.conf) `, skip: ["lsp"], }, + sagemath: { + aliases: ["sage"], + name: "SageMath", + repl: "sage", + main: ".sage/init.sage", + createEmpty: ``, + run: "sage", + scope: { + code: `x = 123 * 234`, + }, + template: `print("Hello, world!") +`, + timeout: 10, + }, sass: { name: "Sass", main: "main.sass", diff --git a/scripts/docker-install-phase3d.bash b/scripts/docker-install-phase3d.bash index 7e45a72..ae7e6c3 100755 --- a/scripts/docker-install-phase3d.bash +++ b/scripts/docker-install-phase3d.bash @@ -15,6 +15,9 @@ packages=" # S-Lang slsh +# SageMath +sagemath + # Scala scala From 2fa58a9683e9b38fb2f30f3832f955cc6b99ca28 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 3 Oct 2020 19:56:29 -0700 Subject: [PATCH 355/388] [#24] New language: ABC --- backend/src/langs.ts | 13 +++++++++++++ scripts/docker-install-phase3a.bash | 3 +++ scripts/docker-install-phase4.bash | 13 +++++++++++++ 3 files changed, 29 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index bce8e50..27ff866 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -74,6 +74,19 @@ export const langs: { [key: string]: LangConfig } = { `, skip: ["scope"], }, + abc: { + name: "ABC", + repl: "abc", + input: `WRITE 123 * 234`, + main: "main.abc", + run: `abc "$PWD/main.abc" -`, + scope: { + code: `PUT 123 * 234 IN x`, + input: `WRITE x`, + }, + template: `WRITE "Hello, world!" / +`, + }, ada: { aliases: ["adb"], name: "Ada", diff --git a/scripts/docker-install-phase3a.bash b/scripts/docker-install-phase3a.bash index a1734e2..c2ba6e9 100755 --- a/scripts/docker-install-phase3a.bash +++ b/scripts/docker-install-phase3a.bash @@ -16,6 +16,9 @@ aplus-fsf aplus-fsf-doc rlwrap +# ABC +libtinfo5:i386 + # Ada gnat diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index dfbd79a..6bfda4d 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -26,6 +26,19 @@ wget -nv https://gist.githubusercontent.com/anonymous/6392418/raw/fish.py -O /us sed -i 's:^#!.*:#!/usr/bin/env python3:' /usr/local/bin/fish-lang chmod +x /usr/local/bin/fish-lang +# ABC +wget -nv https://homepages.cwi.nl/~steven/abc/implementations/abc.tar.gz +mkdir /opt/abc +tar -xf abc.tar.gz -C /opt/abc --strip-components=1 +chmod +x /opt/abc/abc /opt/abc/abckeys +tee /usr/local/bin/abc >/dev/null <<"EOF" +#!/usr/bin/env bash +cd /opt/abc +exec ./abc "$@" +EOF +chmod +x /usr/local/bin/abc +rm abc.tar.gz + # Ada wget -nv https://dl.bintray.com/reznikmm/ada-language-server/linux-latest.tar.gz tar -xf linux-latest.tar.gz From 08a7dbdaee2c118d8fb2af76e1b2b478bed5eb85 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 3 Oct 2020 20:57:39 -0700 Subject: [PATCH 356/388] [#24] New language: Oberon --- backend/src/langs.ts | 16 ++++++++++++++++ scripts/docker-install-phase3c.bash | 4 ++++ scripts/docker-install-phase6.bash | 10 ++++++++++ 3 files changed, 30 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 27ff866..a182ed2 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2293,6 +2293,22 @@ x`, compile: "nim compile main.nim", run: "./main", template: `echo "Hello, world!" +`, + }, + oberon: { + aliases: ["obn"], + name: "Oberon", + main: "Main.obn", + compile: "obnc Main.obn -o main", + run: "./main", + template: `MODULE Main; + +IMPORT Out; + +BEGIN + Out.String("Hello, world!"); + Out.Ln; +END Main. `, }, objectivec: { diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index b0b80d4..4f8fb39 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -46,6 +46,10 @@ nim nodejs yarn +# Oberon +clang +make + # Objective-C gcc gnustep-devel diff --git a/scripts/docker-install-phase6.bash b/scripts/docker-install-phase6.bash index 95d3fb4..c2d553a 100755 --- a/scripts/docker-install-phase6.bash +++ b/scripts/docker-install-phase6.bash @@ -93,6 +93,16 @@ git clone https://github.com/bipinu/malbolge.git clang malbolge/malbolge.c -o /usr/local/bin/malbolge rm -rf malbolge +# Oberon +file="$(curl -sSL https://miasap.se/obnc/ | grep -F obnc_ | grep -Eo 'obnc_[^"]+' | grep -v win | head -n1)" +wget -nv "https://miasap.se/obnc/downloads/${file}" +tar -xf obnc_*.tar.gz +pushd obnc-* >/dev/null +./build +./install +popd >/dev/null +rm -rf obnc_*.tar.gz obnc-* + # Ook git clone https://git.code.sf.net/p/esco/code esco pushd esco >/dev/null From d9f9d3817a35a072c60d525feafce5bad58432bb Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 3 Oct 2020 21:07:38 -0700 Subject: [PATCH 357/388] [#24] New language: REBOL --- backend/src/langs.ts | 11 +++++++++++ scripts/docker-install-phase4.bash | 7 +++++++ 2 files changed, 18 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index a182ed2..9cede8b 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2789,6 +2789,17 @@ end `, skip: ["lsp"], }, + rebol: { + name: "REBOL", + repl: "rebol", + main: "main.r", + run: "rebol main.r; rebol", + runReplInput: `DELAY: 1 +123 * 234`, + template: `REBOL [Title: "Main"] +print "Hello, world!" +`, + }, redis: { name: "Redis", monacoLang: "redis", diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 6bfda4d..ebdf8d7 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -292,6 +292,13 @@ unzip rls-linux.zip mv rls-linux/reason-language-server /usr/local/bin/ rm rls-linux.zip +# Rebol +file="$(curl -sSL http://www.rebol.com/downloads.html | sed '0,/x86-64/d' | head -n10 | grep -Eo 'downloads/[^"]+')" +wget -nv "http://www.rebol.com/${file}" +tar -xf rebol-core-*.tar.gz +mv rebol-core/rebol /usr/local/bin/ +rm -rf rebol-core rebol-core-*.tar.gz + # Rust export CARGO_HOME=/opt/rust export RUSTUP_HOME=/opt/rust From fce9b88136b18c8c59883c2eeb4bccce99da0ab0 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 3 Oct 2020 21:26:57 -0700 Subject: [PATCH 358/388] [#24] New language: Oz --- backend/src/langs.ts | 16 ++++++++++++++++ scripts/docker-install-phase4.bash | 6 ++++++ 2 files changed, 22 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 9cede8b..8cb7be9 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2444,6 +2444,22 @@ rofl lol compile: "pandoc main.org -o main.html", run: "prettier --no-config main.html", template: `Hello, world! +`, + }, + oz: { + aliases: ["mozart", "mozart2"], + name: "Oz", + main: "main.oz", + compile: "ozc -c main.oz", + run: "ozengine main.ozf", + template: `functor +import + Application + System +define + {System.showInfo 'Hello, world!'} + {Application.exit 0} +end `, }, parigp: { diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index ebdf8d7..58ae543 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -262,6 +262,12 @@ ver="$(latest_release OlegSmelov/omgrofl-interpreter)" mkdir /opt/omgrofl wget -nv "https://github.com/OlegSmelov/omgrofl-interpreter/releases/download/${ver}/Omgrofl.jar" -O /opt/omgrofl/Omgrofl.jar +# Oz +ver="$(latest_release mozart/mozart2)" +wget -nv "https://github.com/mozart/mozart2/releases/download/${ver}/mozart2-$(sed 's/^v//' <<< "$ver")-x86_64-linux.deb" +dpkg -i mozart2-*-x86_64-linux.deb +rm mozart2-*-x86_64-linux.deb + # PowerShell ver="$(latest_release PowerShell/PowerShell)" wget -nv "https://github.com/PowerShell/PowerShell/releases/download/${ver}/powershell-$(sed 's/^v//' <<< "$ver")-linux-x64.tar.gz" From c1f493b976b0225260517c9e988b69b456aa1eb5 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 4 Oct 2020 09:23:51 -0700 Subject: [PATCH 359/388] [#24] New language: Red --- backend/src/langs.ts | 13 +++++++++++++ scripts/docker-install-phase3c.bash | 3 +++ scripts/docker-install-phase4.bash | 6 ++++++ scripts/docker-install-phase7.bash | 5 +++++ 4 files changed, 27 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 8cb7be9..6743fd6 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2814,6 +2814,19 @@ end 123 * 234`, template: `REBOL [Title: "Main"] print "Hello, world!" +`, + }, + red: { + name: "Red", + setup: "cp -R /opt/red/template .red", + repl: "/usr/local/bin/red", + input: `DELAY: 1 +123 * 234`, + main: "main.red", + run: "/usr/local/bin/red main.red; /usr/local/bin/red", + template: `Red [Title: "Main"] + +print "Hello, world!" `, }, redis: { diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index 4f8fb39..ade3586 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -122,6 +122,9 @@ ratfor # rc rc +# Red +libcurl4:i386 + # Redis redis diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 58ae543..f3f083b 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -305,6 +305,12 @@ tar -xf rebol-core-*.tar.gz mv rebol-core/rebol /usr/local/bin/ rm -rf rebol-core rebol-core-*.tar.gz +# Red +path="$(curl -sSL https://static.red-lang.org/download.html | grep -Eo '/dl/linux/[^"]+' | head -n1)" +wget -nv "https://static.red-lang.org/${path}" -O /usr/local/bin/red +chmod +x /usr/local/bin/red +rm red-latest.zip + # Rust export CARGO_HOME=/opt/rust export RUSTUP_HOME=/opt/rust diff --git a/scripts/docker-install-phase7.bash b/scripts/docker-install-phase7.bash index 9c10d0e..4ad6b3f 100755 --- a/scripts/docker-install-phase7.bash +++ b/scripts/docker-install-phase7.bash @@ -71,6 +71,11 @@ cat bsconfig.json | jq '.name = "riju-project"' | sponge bsconfig.json yarn install popd >/dev/null +# Red +sudo -u build /usr/local/bin/red <<< quit +mkdir /opt/red +mv /home/build/.red /opt/red/template + # Unison mkdir -p /opt/unison/project-template pushd /opt/unison/project-template >/dev/null From 3603c93eecc3d436e513442c708393c75b32d406 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 4 Oct 2020 10:47:48 -0700 Subject: [PATCH 360/388] [#24] New language: Limbo Hooooo boy that was a wild one. --- backend/src/langs.ts | 23 +++++++++++++++++++++++ scripts/docker-install-phase3b.bash | 6 ++++++ scripts/docker-install-phase6.bash | 11 +++++++++++ 3 files changed, 40 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 6743fd6..3d5526c 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2042,6 +2042,29 @@ PLEASE GIVE UP template: `body:before { content: "Hello, world!"; } +`, + }, + limbo: { + aliases: ["inferno"], + name: "Limbo", + setup: "ln -s /usr/local/inferno/* ./", + main: "riju/main.b", + compile: "limbo -o riju/main.dis riju/main.b", + run: `emu -r . riju/main.dis`, + template: `implement Cmd; + +include "sys.m"; +include "draw.m"; + +Cmd : module { + init : fn (ctxt : ref Draw->Context, args : list of string); +}; + +init(nil : ref Draw->Context, nil : list of string) +{ + sys := load Sys Sys->PATH; + sys->print("Hello, world!\\n"); +} `, }, lisaac: { diff --git a/scripts/docker-install-phase3b.bash b/scripts/docker-install-phase3b.bash index 1cd0b59..6913e4a 100755 --- a/scripts/docker-install-phase3b.bash +++ b/scripts/docker-install-phase3b.bash @@ -98,6 +98,12 @@ julia # Ksh ksh +# Limbo +gcc +libc6-dev-i386 +libx11-dev:i386 +libxext-dev:i386 + # Lisaac lisaac diff --git a/scripts/docker-install-phase6.bash b/scripts/docker-install-phase6.bash index c2d553a..f0859ce 100755 --- a/scripts/docker-install-phase6.bash +++ b/scripts/docker-install-phase6.bash @@ -81,6 +81,17 @@ mv lazyk /usr/local/bin/ popd >/dev/null rm -rf lazyk +# Limbo +wget -nv "$(curl -sSL http://www.vitanuova.com/inferno/downloads.html | grep -E 'inferno-[0-9]+\.tgz' | grep -Eo 'http://[^"]+')" +tar -xf inferno-*.tgz -C /usr/local +pushd /usr/local/inferno >/dev/null +sed -i 's/gcc/gcc -m32/g' makemk.sh +./makemk.sh +PATH="$PWD/Linux/386/bin:$PATH" mk install +ln -s "$PWD/Linux/386/bin/emu" "$PWD/Linux/386/bin/limbo" /usr/local/bin/ +popd >/dev/null +rm inferno-*.tgz + # LOLCODE git clone https://github.com/justinmeza/lci.git pushd lci >/dev/null From 9fa26e05691d6c7f85fb737838b791d32d67aa5e Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 4 Oct 2020 10:53:02 -0700 Subject: [PATCH 361/388] Fix tragic SIGPIPE from sed --- scripts/docker-install-phase4.bash | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index f3f083b..5b45cd7 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -298,8 +298,8 @@ unzip rls-linux.zip mv rls-linux/reason-language-server /usr/local/bin/ rm rls-linux.zip -# Rebol -file="$(curl -sSL http://www.rebol.com/downloads.html | sed '0,/x86-64/d' | head -n10 | grep -Eo 'downloads/[^"]+')" +# REBOL +file="$(curl -sSL http://www.rebol.com/downloads.html | sed '0,/x86-64/d' | grep -Eo 'downloads/[^"]+' | head -n1)" wget -nv "http://www.rebol.com/${file}" tar -xf rebol-core-*.tar.gz mv rebol-core/rebol /usr/local/bin/ From 40785b8ac25c96b02647c1445fb1261aac7692d1 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 4 Oct 2020 10:53:36 -0700 Subject: [PATCH 362/388] Add alias for Limbo --- backend/src/langs.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 3d5526c..8f425b3 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2045,7 +2045,7 @@ PLEASE GIVE UP `, }, limbo: { - aliases: ["inferno"], + aliases: ["inferno", "b"], name: "Limbo", setup: "ln -s /usr/local/inferno/* ./", main: "riju/main.b", From 15628f0e0d362f1900984a687aec73228fd9cfba Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 4 Oct 2020 11:31:53 -0700 Subject: [PATCH 363/388] [#24] New language: Pawn --- backend/src/langs.ts | 13 +++++++++++++ scripts/docker-install-phase6.bash | 11 +++++++++++ 2 files changed, 24 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 8f425b3..428bd13 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2516,6 +2516,19 @@ end begin writeln('Hello, world!'); end. +`, + }, + pawn: { + aliases: ["pawncc", "pawnrun"], + name: "PAWN", + main: "main.pawn", + compile: "pawncc main.pawn -i/opt/pawn/include", + run: "pawnrun main.amx", + template: `#include + +main() { + print("Hello, world!\\n"); +} `, }, perl: { diff --git a/scripts/docker-install-phase6.bash b/scripts/docker-install-phase6.bash index f0859ce..5344257 100755 --- a/scripts/docker-install-phase6.bash +++ b/scripts/docker-install-phase6.bash @@ -125,6 +125,17 @@ mv bin/esco /usr/local/bin/ popd >/dev/null rm -rf esco +# PAWN +git clone https://github.com/compuphase/pawn.git +pushd pawn >/dev/null +cmake . +make +mv pawncc pawnrun /usr/local/bin/ +mkdir /opt/pawn +mv include /opt/pawn/ +popd >/dev/null +rm -rf pawn + # Rapira git clone https://github.com/freeduke33/rerap2.git pushd rerap2 >/dev/null From 06b12efbac898ad708c93a08c1e52f8dfd3e7238 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 4 Oct 2020 12:13:36 -0700 Subject: [PATCH 364/388] Fix erroneous reference to red-latest.zip --- scripts/docker-install-phase4.bash | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 5b45cd7..8b65dca 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -309,7 +309,6 @@ rm -rf rebol-core rebol-core-*.tar.gz path="$(curl -sSL https://static.red-lang.org/download.html | grep -Eo '/dl/linux/[^"]+' | head -n1)" wget -nv "https://static.red-lang.org/${path}" -O /usr/local/bin/red chmod +x /usr/local/bin/red -rm red-latest.zip # Rust export CARGO_HOME=/opt/rust From ec84d426d07f91379efcac5d1171f421ad1f789b Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 4 Oct 2020 14:26:07 -0700 Subject: [PATCH 365/388] Install python3.7-dev for Mathics install --- scripts/docker-install-phase3c.bash | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index ade3586..414b316 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -17,6 +17,10 @@ m4 # MariaDB libtinfo5 +# Mathics +python3.7 +python3.7-dev + # MiniZinc minizinc From aea38776d1d5032f04fdbe6f6dbe7a8ad96b6905 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 4 Oct 2020 15:14:24 -0700 Subject: [PATCH 366/388] [#24] New language: Idris --- backend/src/langs.ts | 16 ++++++++++++++++ scripts/docker-install-phase3b.bash | 4 ++++ scripts/docker-install-phase6.bash | 8 ++++++++ 3 files changed, 28 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 428bd13..4c85a18 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1530,6 +1530,22 @@ l ; ; o ; * 4 template: `procedure main () write("Hello, world!") end +`, + }, + idris: { + aliases: ["idr", "idris2"], + name: "Idris", + repl: "rm -f .idris/repl/init; idris2", + main: "Main.idr", + run: "mkdir -p .idris/repl; echo ':exec main' > .idris/repl/init; idris2 Main.idr -x main; idris2 Main.idr", + scope: { + code: `x : Int +x = 123 * 234`, + }, + template: `module Main + +main : IO () +main = putStrLn "Hello, world!" `, }, ink: { diff --git a/scripts/docker-install-phase3b.bash b/scripts/docker-install-phase3b.bash index 6913e4a..1157763 100755 --- a/scripts/docker-install-phase3b.bash +++ b/scripts/docker-install-phase3b.bash @@ -79,6 +79,10 @@ haxe # Icon icont +# Idris +chezscheme +gcc + # INTERCAL intercal diff --git a/scripts/docker-install-phase6.bash b/scripts/docker-install-phase6.bash index 5344257..f017b03 100755 --- a/scripts/docker-install-phase6.bash +++ b/scripts/docker-install-phase6.bash @@ -63,6 +63,14 @@ rm -rf erlang_ls # Hexagony git clone https://github.com/m-ender/hexagony.git /opt/hexagony +# Idris +wget -nv https://www.idris-lang.org/idris2-src/idris2-latest.tgz +tar -xf idris2-latest.tgz +make bootstrap-build SCHEME=chezscheme PREFIX=/usr/local +make install PREFIX=/usr/local +chmod -R a=u,go-w /usr/local/idris2-* +rm -rf Idris2-* idris2-latest.tgz + # Kalyn git clone https://github.com/raxod502/kalyn.git pushd kalyn >/dev/null From a88089cbd06147cf617e1ed232e7a4d101ddba8c Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 4 Oct 2020 15:16:49 -0700 Subject: [PATCH 367/388] [#24] New language: PSeInt --- backend/src/langs.ts | 11 +++++++++++ scripts/docker-install-phase4.bash | 6 ++++++ 2 files changed, 17 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 4c85a18..2a95179 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2697,6 +2697,17 @@ main :- template: `active proctype main() { printf("Hello, world!\\n"); } +`, + }, + pseint: { + aliases: ["psc"], + name: "PSeInt", + main: "main.psc", + run: "pseint --nouser main.psc", + hello: "¡Hola, mundo!", + template: `Proceso Main + Escribir "¡Hola, mundo!"; +FinProceso `, }, pug: { diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 8b65dca..36c2e54 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -282,6 +282,12 @@ unzip PowerShellEditorServices.zip mv PowerShellEditorServices /opt/powershell-editor-services rm PowerShellEditorServices.zip +# PSeInt +wget -nv "$(curl -sSL "http://pseint.sourceforge.net/index.php?page=descargas.php&os=lnx" | grep -Eo 'http://[^"]+l64[^"]+\.tgz\?download')" -O pseint.tgz +tar -xf pseint.tgz +mv pseint/bin/pseint /usr/local/bin/ +rm -rf pseint pseint.tgz + # Python xml="$(curl -sSL "https://pvsc.blob.core.windows.net/python-language-server-stable?restype=container&comp=list&prefix=Python-Language-Server-linux-x64")" nupkg="$(echo "$xml" | grep -Eo 'https://[^<]+\.nupkg' | tail -n1)" From 3b5dd79799d03c4f34d23cd9e28f859df455a15a Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 4 Oct 2020 15:26:07 -0700 Subject: [PATCH 368/388] [#24] New language: Slick --- backend/src/langs.ts | 11 +++++++++++ scripts/docker-install-phase5.bash | 4 ++++ scripts/docker-install-phase6.bash | 14 ++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 2a95179..74ced3b 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -3247,6 +3247,17 @@ Ophelia: }, template: `message("Hello, world!"); ` + }, + slick: { + name: "Slick", + repl: "slick", + input: `DELAY: 1 +123 * 234`, + main: "main.sl", + run: "slick main.sl; slick", + template: `def main: + print "Hello, world!" +`, }, smalltalk: { aliases: ["gst", "st"], diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index 95eecba..a16d73d 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -109,6 +109,10 @@ npm install -g sass # Shakespeare pip3 install shakespearelang +# Slick +opam install -y dune +ln -s /opt/opam/default/bin/dune /usr/local/bin/dune + # TeX luarocks install digestif diff --git a/scripts/docker-install-phase6.bash b/scripts/docker-install-phase6.bash index f017b03..9ba5f81 100755 --- a/scripts/docker-install-phase6.bash +++ b/scripts/docker-install-phase6.bash @@ -5,6 +5,9 @@ set -o pipefail set -x pushd /tmp >/dev/null +export OPAMROOT=/opt/opam +export OPAMROOTISOK=1 + # Aheui git clone https://github.com/aheui/caheui.git pushd caheui >/dev/null @@ -160,6 +163,17 @@ mv public/qlb/*.js /opt/qalb/ popd >/dev/null rm -rf qalb +# Slick +git clone https://github.com/kwshi/slick.git +pushd slick >/dev/null +opam switch create . +opam install --switch . $(dune external-lib-deps src --display=quiet | grep -F - | sed 's/- //; s/\..*//') -y +opam install --switch . menhir -y +opam exec --switch . dune build +mv _build/default/src/exe/main.exe /usr/local/bin/slick +popd >/dev/null +rm -rf slick + # Snobol file="$(curl -sSL ftp://ftp.snobol4.org/snobol/ | grep -Eo 'snobol4-.*\.tar\.gz' | sort -rV | head -n1)" wget -nv "ftp://ftp.snobol4.org/snobol/${file}" From ecbb9caa0d6016cda40c387a803af98f239d60f7 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 4 Oct 2020 18:09:15 -0700 Subject: [PATCH 369/388] Install 32-bit Linux headers for Limbo --- scripts/docker-install-phase3b.bash | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/docker-install-phase3b.bash b/scripts/docker-install-phase3b.bash index 1157763..9dfe57a 100755 --- a/scripts/docker-install-phase3b.bash +++ b/scripts/docker-install-phase3b.bash @@ -107,6 +107,7 @@ gcc libc6-dev-i386 libx11-dev:i386 libxext-dev:i386 +linux-libc-dev:i386 # Lisaac lisaac From 01f93522bb5b1f2f2b337a39f8d75a29b282957d Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 4 Oct 2020 18:15:15 -0700 Subject: [PATCH 370/388] [#24] New language: OpenSCAD --- backend/src/langs.ts | 8 ++++++++ scripts/docker-install-phase3c.bash | 3 +++ 2 files changed, 11 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 74ced3b..9ccacf7 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2474,6 +2474,14 @@ lol iz 33 rofl lol lol iz 10 rofl lol +`, + }, + openscad: { + name: "OpenSCAD", + main: "main.scad", + compile: "openscad main.scad -o main.stl", + run: "cat main.stl", + template: `echo("Hello, world!"); `, }, org: { diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index 414b316..e019d87 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -68,6 +68,9 @@ octave # Ook autoconf +# OpenSCAD +openscad + # PARI/GP pari-gp From 08ff7edaa40267d7bd67466321be6c830d588c70 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 5 Oct 2020 07:33:15 -0700 Subject: [PATCH 371/388] Correctly chdir into Idris2 source dir --- scripts/docker-install-phase6.bash | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/docker-install-phase6.bash b/scripts/docker-install-phase6.bash index 9ba5f81..c10573c 100755 --- a/scripts/docker-install-phase6.bash +++ b/scripts/docker-install-phase6.bash @@ -69,9 +69,11 @@ git clone https://github.com/m-ender/hexagony.git /opt/hexagony # Idris wget -nv https://www.idris-lang.org/idris2-src/idris2-latest.tgz tar -xf idris2-latest.tgz +pushd Idris2-* >/dev/null make bootstrap-build SCHEME=chezscheme PREFIX=/usr/local make install PREFIX=/usr/local chmod -R a=u,go-w /usr/local/idris2-* +popd >/dev/null rm -rf Idris2-* idris2-latest.tgz # Kalyn From d87455995bbc21c394c6671b36846de8b5aef19b Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 5 Oct 2020 18:45:52 -0700 Subject: [PATCH 372/388] [#24] New language: Objective-C++ --- backend/src/langs.ts | 33 +++++++++++++++++++++++++++++ scripts/docker-install-phase3c.bash | 5 +++++ 2 files changed, 38 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 9ccacf7..a5d3883 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2376,6 +2376,39 @@ int main() { }, template: `#import +int main() { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSLog(@"Hello, world!"); + [pool drain]; + return 0; +} +`, + skip: ["lsp"], + }, + "objectivec++": { + aliases: ["objc++", "objcpp", "objectivecpp"], + name: "Objective-C++", + main: "main.mm", + compile: "gcc $(gnustep-config --objc-flags) main.mm $(gnustep-config --base-libs) -o main", + run: "./main", + format: { + run: "clang-format --assume-filename=format.m", + input: `#import + +int main() { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSLog(@"Hello, world!"); + [pool drain]; + return 0; +} +`, + }, + lsp: { + setup: `(gnustep-config --objc-flags && gnustep-config --base-libs) | sed -E 's/\\s+/\\n/g' > compile_flags.txt`, + start: "clangd", + }, + template: `#import + int main() { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSLog(@"Hello, world!"); diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index e019d87..7ac9f09 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -58,6 +58,11 @@ make gcc gnustep-devel +Objective-C++ +gcc +gnustep-devel +gobjc++ + # OCaml ocaml opam From a2714f2eb64bcdc4596ec961f8d54f3dd28e6a56 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 5 Oct 2020 20:06:58 -0700 Subject: [PATCH 373/388] [#24] New language: Q# --- backend/src/langs.ts | 19 +++++++++++++++++++ scripts/docker-install-phase3d.bash | 5 +++++ scripts/docker-install-phase7.bash | 9 +++++++++ 3 files changed, 33 insertions(+) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index a5d3883..4bde826 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2818,6 +2818,25 @@ main = do `, timeout: 15, }, + qsharp: { + aliases: ["q", "qs"], + name: "Q#", + setup: "cp -R /opt/qsharp/dotnet ./.dotnet && cp -R /opt/qsharp/project-template/* ./", + main: "Main.qs", + run: "dotnet run", + template: `namespace main { + + open Microsoft.Quantum.Canon; + open Microsoft.Quantum.Intrinsic; + + @EntryPoint() + operation Main() : Unit { + Message("Hello, world!"); + } +} +`, + timeout: 60, + }, قلب: { aliases: ["qalb"], name: "قلب", diff --git a/scripts/docker-install-phase3d.bash b/scripts/docker-install-phase3d.bash index ae7e6c3..ec2a290 100755 --- a/scripts/docker-install-phase3d.bash +++ b/scripts/docker-install-phase3d.bash @@ -10,8 +10,13 @@ apt-get update lua_ver="$(grep-aptavail -XF Provides lua -s Version -n | sort -Vr | head -n1)" liblua_name="$(grep-aptavail -eF Package "liblua[0-9.]+-dev" -a -XF Version "${lua_ver}" -s Package -n | head -n1)" +dotnet_name="$(grep-aptavail -eF Package "^dotnet-sdk-[0-9.]+$" -s Package -n | sort -Vr | head -n1)" + packages=" +# Q# +${dotnet_name} + # S-Lang slsh diff --git a/scripts/docker-install-phase7.bash b/scripts/docker-install-phase7.bash index 4ad6b3f..df9eaf9 100755 --- a/scripts/docker-install-phase7.bash +++ b/scripts/docker-install-phase7.bash @@ -63,6 +63,15 @@ popd >/dev/null mkdir /opt/purescript mv project-template /opt/purescript/ +# Q# +dotnet new -i Microsoft.Quantum.ProjectTemplates +dotnet new console -lang Q# -o main +rm main/Program.qs +mkdir /opt/qsharp +mv main /opt/qsharp/project-template +mv "$HOME/.dotnet" /opt/qsharp/dotnet +chmod -R a=u,go-w /opt/qsharp/dotnet + # ReasonML mkdir -p /opt/reasonml/project-template pushd /opt/reasonml/project-template >/dev/null From b97775abd1da81d76260b3a9dcc5711129f2eac1 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Wed, 7 Oct 2020 06:37:19 -0700 Subject: [PATCH 374/388] Fix comment formatting --- scripts/docker-install-phase3c.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index 7ac9f09..f8b7e0e 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -58,7 +58,7 @@ make gcc gnustep-devel -Objective-C++ +# Objective-C++ gcc gnustep-devel gobjc++ From e466a94d18803718c96197d9a0d1f1da8483be13 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Wed, 7 Oct 2020 18:22:13 -0700 Subject: [PATCH 375/388] Migrate to Packer --- .circleci/config.yml | 8 +- .gitignore | 2 + Makefile | 4 +- packer/config-certbot.json | 22 +++++ packer/config.json | 55 ++++++++++++ packer/provision-certbot.bash | 11 +++ packer/provision.bash | 89 +++++++++++++++++++ .../resources}/certbot-post.bash | 0 .../resources}/certbot-pre.bash | 0 packer/resources/riju.bash | 31 +++++++ {scripts => packer/resources}/riju.service | 2 +- packer/resources/rijuctl.bash | 49 ++++++++++ scripts/deploy-phase1.py | 41 --------- scripts/deploy-phase2.py | 25 ------ scripts/deploy.bash | 53 ++++++++--- scripts/install-scripts.bash | 12 --- scripts/riju-serve.bash | 22 ----- 17 files changed, 309 insertions(+), 117 deletions(-) create mode 100644 packer/config-certbot.json create mode 100644 packer/config.json create mode 100755 packer/provision-certbot.bash create mode 100755 packer/provision.bash rename {scripts => packer/resources}/certbot-post.bash (100%) rename {scripts => packer/resources}/certbot-pre.bash (100%) create mode 100755 packer/resources/riju.bash rename {scripts => packer/resources}/riju.service (88%) create mode 100755 packer/resources/rijuctl.bash delete mode 100755 scripts/deploy-phase1.py delete mode 100755 scripts/deploy-phase2.py delete mode 100755 scripts/install-scripts.bash delete mode 100755 scripts/riju-serve.bash diff --git a/.circleci/config.yml b/.circleci/config.yml index c4e90f3..915887a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -5,7 +5,13 @@ jobs: - image: alpine steps: - checkout - - run: apk add --no-cache --no-progress bash openssh + - setup_remote_docker + - run: >- + apk add --no-cache --no-progress + bash docker make openssh + - run: >- + echo "${DOCKER_PASSWORD}" | + docker login --username "${DOCKER_USERNAME}" --password-stdin - run: scripts/deploy.bash workflows: version: 2 diff --git a/.gitignore b/.gitignore index cc99f2c..808bf7f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,9 @@ *.log .log .lsp-repl-history +do_digitalocean.pem node_modules out +secrets.json tests tests-* diff --git a/Makefile b/Makefile index 46715d1..2ca3d2e 100644 --- a/Makefile +++ b/Makefile @@ -19,10 +19,10 @@ image-prod: ## Build Docker image for production .PHONY: docker docker: image-dev docker-nobuild ## Run shell with source code and deps inside Docker -.PHONY: docker +.PHONY: docker-nobuild docker-nobuild: ## Same as 'make docker', but don't rebuild image scripts/docker.bash run -it --rm -v "$(PWD):/home/docker/src" -p 6119:6119 -p 6120:6120 -h riju riju bash .PHONY: deploy -deploy: ## Deploy current master from GitHub to production +deploy: image-prod ## Build, publish, and deploy production image scripts/deploy.bash diff --git a/packer/config-certbot.json b/packer/config-certbot.json new file mode 100644 index 0000000..da7bc53 --- /dev/null +++ b/packer/config-certbot.json @@ -0,0 +1,22 @@ +{ + "variables": { + "api_token": "" + }, + "sensitive-variables": ["api_token"], + "builders": [ + { + "type": "digitalocean", + "api_token": "{{user `api_token`}}", + "image": "ubuntu-20-04-x64", + "region": "sfo3", + "size": "s-1vcpu-1gb", + "ssh_username": "root" + } + ], + "provisioners": [ + { + "type": "shell", + "script": "provision-certbot.bash" + } + ] +} diff --git a/packer/config.json b/packer/config.json new file mode 100644 index 0000000..8e86a28 --- /dev/null +++ b/packer/config.json @@ -0,0 +1,55 @@ +{ + "variables": { + "api_token": "", + "admin_password": "", + "admin_ssh_public_key_file": "", + "deploy_ssh_public_key_file": "", + "docker_repo": "raxod502/riju" + }, + "sensitive-variables": ["api_token", "admin_password"], + "builders": [ + { + "type": "digitalocean", + "api_token": "{{user `api_token`}}", + "image": "ubuntu-20-04-x64", + "region": "sfo3", + "size": "s-1vcpu-1gb", + "ssh_username": "root" + } + ], + "provisioners": [ + { + "type": "file", + "source": "{{user `admin_ssh_public_key_file`}}", + "destination": "/tmp/id_admin.pub" + }, + { + "type": "file", + "source": "{{user `deploy_ssh_public_key_file`}}", + "destination": "/tmp/id_deploy.pub" + }, + { + "type": "file", + "source": "resources/riju.bash", + "destination": "/tmp/riju.bash" + }, + { + "type": "file", + "source": "resources/riju.service", + "destination": "/tmp/riju.service" + }, + { + "type": "file", + "source": "resources/rijuctl.bash", + "destination": "/tmp/rijuctl.bash" + }, + { + "type": "shell", + "script": "provision.bash", + "environment_vars": [ + "ADMIN_PASSWORD={{user `admin_password`}}", + "DOCKER_REPO={{user `docker_repo`}}" + ] + } + ] +} diff --git a/packer/provision-certbot.bash b/packer/provision-certbot.bash new file mode 100755 index 0000000..992665d --- /dev/null +++ b/packer/provision-certbot.bash @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +set -euxo pipefail + +export DEBIAN_FRONTEND=noninteractive +apt-get update +apt-get dist-upgrade -y + +apt-get install -y certbot + +rm -rf /var/lib/apt/lists/* diff --git a/packer/provision.bash b/packer/provision.bash new file mode 100755 index 0000000..12ebaa3 --- /dev/null +++ b/packer/provision.bash @@ -0,0 +1,89 @@ +#!/usr/bin/env bash + +set -euxo pipefail + +if [[ -z "${ADMIN_PASSWORD}" ]]; then + echo "you need to set admin_password in secrets.json" >&2 + exit 1 +fi + +if [[ -z "${DOCKER_REPO}" ]]; then + echo "internal error: somehow DOCKER_REPO was not set" >&2 + exit 1 +fi + +for user in admin deploy; do + if [[ ! -s "/tmp/id_${user}.pub" ]]; then + echo "you need to set ${user}_ssh_public_key_file in secrets.json" >&2 + exit 1 + fi + + if ! grep -vq "PRIVATE KEY" "/tmp/id_${user}.pub"; then + echo "you accidentally set ${user}_ssh_public_key_file to a private key" >&2 + exit 1 + fi + + IFS=" " read contents < "/tmp/id_${user}.pub" + echo "${contents}" > "/tmp/id_${user}.pub" +done + +export DEBIAN_FRONTEND=noninteractive +apt-get update +apt-get dist-upgrade -y + +apt-get install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common +curl -sSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - +add-apt-repository -n universe +add-apt-repository -n "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" + +packages=" + +bsdmainutils +certbot +containerd.io +docker-ce +docker-ce-cli +git +make +members +python3 +tmux +vim +whois + +" + +apt-get update +apt-get install -y ${packages} + +sed -Ei 's/^#?PermitRootLogin .*/PermitRootLogin no/' /etc/ssh/sshd_config +sed -Ei 's/^#?PasswordAuthentication .*/PasswordAuthentication no/' /etc/ssh/sshd_config +sed -Ei 's/^#?PermitEmptyPasswords .*/PermitEmptyPasswords no/' /etc/ssh/sshd_config + +passwd -l root +useradd admin -g admin -G sudo -s /usr/bin/bash -p "$(echo "${ADMIN_PASSWORD}" | mkpasswd -s)" -m +useradd deploy -s /usr/bin/bash -p "!" + +for user in admin deploy; do + mkdir -p "/home/${user}/.ssh" + mv "/tmp/id_${user}.pub" "/home/${user}/.ssh/authorized_keys" + chown -R "${user}:${user}" "/home/${user}/.ssh" + chmod -R go-rwx "/home/${user}/.ssh" +done + +sed -i 's/^/command="sudo rijuctl",restrict/' /home/deploy/.ssh/authorized_keys + +cat <<"EOF" > /etc/sudoers.d/riju +deploy ALL=(root) NOPASSWD: /usr/local/bin/rijuctl +EOF + +sed -i "s#DOCKER_REPO_REPLACED_BY_PACKER#${DOCKER_REPO}#" /tmp/rijuctl.bash + +mv /tmp/riju.bash /usr/local/bin/riju +mv /tmp/riju.service /etc/systemd/system/riju.service +mv /tmp/rijuctl.bash /usr/local/bin/rijuctl + +chmod +x /usr/local/bin/riju +chmod +x /usr/local/bin/rijuctl + +rm -rf /var/lib/apt/lists/* diff --git a/scripts/certbot-post.bash b/packer/resources/certbot-post.bash similarity index 100% rename from scripts/certbot-post.bash rename to packer/resources/certbot-post.bash diff --git a/scripts/certbot-pre.bash b/packer/resources/certbot-pre.bash similarity index 100% rename from scripts/certbot-pre.bash rename to packer/resources/certbot-pre.bash diff --git a/packer/resources/riju.bash b/packer/resources/riju.bash new file mode 100755 index 0000000..c350863 --- /dev/null +++ b/packer/resources/riju.bash @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +domain="$(ls /etc/letsencrypt/live | grep -v README | head -n1)" + +if [[ -n "${domain}" ]]; then + echo "Detected cert for domain: ${domain}, enabling TLS" >&2 + export TLS=1 + TLS_PRIVATE_KEY="$(base64 "/etc/letsencrypt/live/${domain}/privkey.pem")" + TLS_CERTIFICATE="$(base64 "/etc/letsencrypt/live/${domain}/fullchain.pem")" + export TLS_PRIVATE_KEY TLS_CERTIFICATE + if [[ "${domain}" == riju.codes ]]; then + echo "Domain is riju.codes, enabling analytics" >&2 + export ANALYTICS=1 + else + echo "Domain is not riju.codes, disabling analytics" >&2 + fi +else + echo "No certs installed in /etc/letsencrypt/live, disabling TLS" >&2 +fi + +if [[ -t 1 ]]; then + it=-it +else + it= +fi + +docker run ${it} -e TLS -e TLS_PRIVATE_KEY -e TLS_CERTIFICATE -e ANALYTICS \ + --rm -p 0.0.0.0:80:6119 -p 0.0.0.0:443:6120 -h riju riju:live diff --git a/scripts/riju.service b/packer/resources/riju.service similarity index 88% rename from scripts/riju.service rename to packer/resources/riju.service index 2854d1f..6ea3ac0 100644 --- a/scripts/riju.service +++ b/packer/resources/riju.service @@ -5,7 +5,7 @@ After=docker.service [Service] Type=exec -ExecStart=riju-serve +ExecStart=riju Restart=always [Install] diff --git a/packer/resources/rijuctl.bash b/packer/resources/rijuctl.bash new file mode 100755 index 0000000..9add265 --- /dev/null +++ b/packer/resources/rijuctl.bash @@ -0,0 +1,49 @@ +#!/usr/bin/env bash + +set -euxo pipefail + +DOCKER_REPO="${DOCKER_REPO:-DOCKER_REPO_REPLACED_BY_PACKER}" + +if [[ -n "${SSH_ORIGINAL_COMMAND}" ]]; then + set -- ${SSH_ORIGINAL_COMMAND} +fi + +function usage { + echo "usage: rijuctl deploy TAG" >&2 + exit 1 +} + +function main { + if (( $# == 0 )); then + usage + fi + + subcmd="$1" + shift + case "${subcmd}" in + deploy) + deploy "$@" + ;; + *) + usage + ;; + esac +} + +function deploy { + if (( $# != 1 )); then + usage + fi + tag="$1" + if [[ -z "${tag}" ]]; then + usage + fi + + docker pull "${DOCKER_REPO}:${tag}" + docker tag riju:live riju:prev + docker tag "${DOCKER_REPO}:${tag}" riju:live + docker system prune -f + systemctl restart riju +} + +main "$@" diff --git a/scripts/deploy-phase1.py b/scripts/deploy-phase1.py deleted file mode 100755 index be09219..0000000 --- a/scripts/deploy-phase1.py +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env python3 - -import argparse -import errno -import os -import re -import signal -import subprocess -import sys -import tempfile -import time - -result = subprocess.run(["pgrep", "-x", "riju-deploy"], stdout=subprocess.PIPE) -assert result.returncode in {0, 1} -for pid in result.stdout.decode().splitlines(): - print(f"Found existing process {pid}, trying to kill ...", file=sys.stderr) - pid = int(pid) - os.kill(pid, signal.SIGTERM) - while True: - time.sleep(0.01) - try: - os.kill(pid, 0) - except OSError as e: - if e.errno == errno.ESRCH: - break - -with tempfile.TemporaryDirectory() as tmpdir: - os.chdir(tmpdir) - subprocess.run( - [ - "git", - "clone", - "https://github.com/raxod502/riju.git", - "--single-branch", - "--depth=1", - "--no-tags", - ], - check=True, - ) - os.chdir("riju") - subprocess.run(["scripts/deploy-phase2.py"], check=True) diff --git a/scripts/deploy-phase2.py b/scripts/deploy-phase2.py deleted file mode 100755 index afd2bba..0000000 --- a/scripts/deploy-phase2.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python3 - -import argparse -import errno -import os -import re -import signal -import subprocess -import sys -import tempfile -import time - -subprocess.run(["docker", "pull", "ubuntu:rolling"], check=True) -subprocess.run(["docker", "system", "prune", "-f"], check=True) -subprocess.run(["make", "image-prod"], check=True) -existing_containers = subprocess.run( - ["docker", "ps", "-q"], check=True, stdout=subprocess.PIPE -).stdout.splitlines() -subprocess.run(["scripts/install-scripts.bash"], check=True) -if existing_containers: - subprocess.run(["docker", "kill", *existing_containers], check=True) -subprocess.run(["systemctl", "enable", "riju"], check=True) -subprocess.run(["systemctl", "restart", "riju"], check=True) - -print("==> Successfully deployed Riju! <==", file=sys.stderr) diff --git a/scripts/deploy.bash b/scripts/deploy.bash index c70c13b..b03b810 100755 --- a/scripts/deploy.bash +++ b/scripts/deploy.bash @@ -1,23 +1,50 @@ #!/usr/bin/env bash -set -e -set -o pipefail +set -euxo pipefail -tmpdir="$(mktemp -d)" -keyfile="${tmpdir}/id" - -if [[ -n "$DEPLOY_KEY" ]]; then - printf '%s\n' "$DEPLOY_KEY" | base64 -d > "$keyfile" -elif [[ -f "$HOME/.ssh/id_rsa_riju_deploy" ]]; then - cp "$HOME/.ssh/id_rsa_riju_deploy" "$keyfile" -else - echo 'deploy.bash: you must set $DEPLOY_KEY' >&2 +if [[ -z "${DOCKER_REPO}" ]]; then + echo "environment variable not set: DOCKER_REPO" >&2 exit 1 fi -chmod go-rw "$keyfile" +if [[ -z "${DOMAIN}" ]]; then + echo "environment variable not set: DOMAIN" >&2 + exit 1 +fi + +if [[ -z "${DEPLOY_SSH_PRIVATE_KEY}" ]]; then + if [[ -f "$HOME/.ssh/id_rsa_riju_deploy" ]]; then + DEPLOY_SSH_PRIVATE_KEY="$(< "$HOME/.ssh/id_rsa_riju_deploy")" + else + echo "environment variable not set: DEPLOY_SSH_PRIVATE_KEY" + fi +else + DEPLOY_SSH_PRIVATE_KEY="$(printf '%s\n' "${DEPLOY_SSH_PRIVATE_KEY}" | base64 -d)" +fi + +tag="$(date +%s%3N)-$(git branch --show-current)-$(git rev-parse @)" + +if [[ -n "$(git status --porcelain)" ]]; then + tag="${tag}-dirty" +fi + +scripts/docker.bash tag riju:prod "${DOCKER_REPO}:${tag}" +scripts/docker.bash push "${DOCKER_REPO}:${tag}" + +tmpdir="$(mktemp -d)" + +function cleanup { + rm -rf "${tmpdir}" +} + +trap cleanup EXIT + +printf '%s' "${DEPLOY_SSH_PRIVATE_KEY}" > "${tmpdir}/id" + +chmod go-rw "${tmpdir}/id" ssh -o IdentitiesOnly=yes \ -o StrictHostKeyChecking=no \ -o UserKnownHostsFile=/dev/null \ -o LogLevel=QUIET \ - -i "${keyfile}" deploy@riju.codes + -i "${tmpdir}/id" "deploy@${DOMAIN}" \ + deploy "${tag}" diff --git a/scripts/install-scripts.bash b/scripts/install-scripts.bash deleted file mode 100755 index 494a92e..0000000 --- a/scripts/install-scripts.bash +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -o pipefail - -cp scripts/riju.service /etc/systemd/system/riju.service -cp scripts/riju-serve.bash /usr/local/bin/riju-serve -cp scripts/certbot-pre.bash /etc/letsencrypt/renewal-hooks/pre/riju -cp scripts/certbot-post.bash /etc/letsencrypt/renewal-hooks/post/riju -cp scripts/deploy-phase1.py /usr/local/bin/riju-deploy - -systemctl daemon-reload diff --git a/scripts/riju-serve.bash b/scripts/riju-serve.bash deleted file mode 100755 index 2c45189..0000000 --- a/scripts/riju-serve.bash +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -o pipefail - -TLS=1 -TLS_PRIVATE_KEY="$(base64 /etc/letsencrypt/live/riju.codes/privkey.pem)" -TLS_CERTIFICATE="$(base64 /etc/letsencrypt/live/riju.codes/fullchain.pem)" -ANALYTICS=1 - -# Do this separately so that errors in command substitution will crash -# the script. -export TLS TLS_PRIVATE_KEY TLS_CERTIFICATE ANALYTICS - -if [[ -t 1 ]]; then - it=-it -else - it= -fi - -docker run ${it} -e TLS -e TLS_PRIVATE_KEY -e TLS_CERTIFICATE -e ANALYTICS \ - --rm -p 0.0.0.0:80:6119 -p 0.0.0.0:443:6120 -h riju riju:prod From 1407e2330b34b3be2f392f1c46c5905e3d692d7e Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Wed, 7 Oct 2020 18:39:20 -0700 Subject: [PATCH 376/388] Update CircleCI, fix libc6:i386 install error --- .circleci/config.yml | 16 ++++++++++++++++ scripts/docker-install-phase1.bash | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 915887a..c3cc57e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,5 +1,15 @@ version: 2 jobs: + build: + docker: + - image: alpine + steps: + - checkout + - setup_remote_docker + - run: >- + apk add --no-cache --no-progress + bash docker make + - run: make image-prod build_and_deploy: docker: - image: alpine @@ -17,6 +27,12 @@ workflows: version: 2 ci: jobs: + - build: + filters: + branches: + ignore: master + tags: + ignore: /.*/ - build_and_deploy: filters: branches: diff --git a/scripts/docker-install-phase1.bash b/scripts/docker-install-phase1.bash index 285758a..7f090ca 100755 --- a/scripts/docker-install-phase1.bash +++ b/scripts/docker-install-phase1.bash @@ -9,7 +9,7 @@ dpkg --add-architecture i386 export DEBIAN_FRONTEND=noninteractive apt-get update -apt-get install -y apt-transport-https curl gnupg lsb-release software-properties-common wget +apt-get install -y apt-transport-https curl gnupg libc6 libc6:i386 lsb-release software-properties-common wget rm -rf /var/lib/apt/lists/* ubuntu_ver="$(lsb_release -rs)" From 444a8be81215c7f128ec5f276f8c39e758ee7ba1 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Wed, 7 Oct 2020 18:46:01 -0700 Subject: [PATCH 377/388] Fix multiline yaml --- .circleci/config.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c3cc57e..4a4323b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -6,8 +6,8 @@ jobs: steps: - checkout - setup_remote_docker - - run: >- - apk add --no-cache --no-progress + - run: | + apk add --no-cache --no-progress \ bash docker make - run: make image-prod build_and_deploy: @@ -16,11 +16,11 @@ jobs: steps: - checkout - setup_remote_docker - - run: >- - apk add --no-cache --no-progress + - run: | + apk add --no-cache --no-progress \ bash docker make openssh - - run: >- - echo "${DOCKER_PASSWORD}" | + - run: | + echo "${DOCKER_PASSWORD}" | \ docker login --username "${DOCKER_USERNAME}" --password-stdin - run: scripts/deploy.bash workflows: From 418ddf3743d40f682fff0ad48d1cfd51a368fd06 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Wed, 7 Oct 2020 21:14:39 -0700 Subject: [PATCH 378/388] wget -v, .env, readme, -i386, env vars --- Makefile | 3 + README.md | 225 +++++++++++++++++++++++++++- backend/src/test-runner.ts | 2 +- packer/config-certbot.json | 22 --- packer/config.json | 6 +- packer/provision-certbot.bash | 11 -- packer/resources/certbot-post.bash | 3 - packer/resources/certbot-pre.bash | 3 - scripts/deploy.bash | 15 +- scripts/docker-install-phase1.bash | 2 +- scripts/docker-install-phase3b.bash | 2 +- scripts/docker-install-phase4.bash | 110 +++++++------- scripts/docker-install-phase6.bash | 18 +-- 13 files changed, 304 insertions(+), 118 deletions(-) delete mode 100644 packer/config-certbot.json delete mode 100755 packer/provision-certbot.bash diff --git a/Makefile b/Makefile index 2ca3d2e..09b9bfb 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,6 @@ +-include .env +export + UID := $(shell id -u) .PHONY: help diff --git a/README.md b/README.md index 01ff7e4..0c78a73 100644 --- a/README.md +++ b/README.md @@ -151,6 +151,227 @@ and fail the build if they fail. See also [riju-cdn](https://github.com/raxod502/riju-cdn). -## Flag +## Adding a language -[![Flag](flag.png)](https://www.reddit.com/r/Breath_of_the_Wild/comments/947ewf/flag_of_the_gerudo_based_on_the_flag_of_kazakhstan/) +The workflow for adding a language is more streamlined than you might +expect, given that building Riju's Docker image takes over an hour. +This is because there is no need to rebuild the image when a change is +made. Instead, you can manually apply the changes to a running +container in parallel with adding those changes to the Dockerfile +scripts. + +### Install + +The first step in adding a language is figuring out how to install it. +There are a number of considerations here: + +* If it's available from Ubuntu, that's the best option. +* Language-specific package managers are a second-best choice. +* Downloading precompiled binaries is also not the worst. It's best if + upstream offers a .deb download, but manual installation is fine + too. +* Compiling from source is the worst option, but sometimes it's the + only way. + +Typically, I `sudo su` and change directory to `/tmp` in order to test +out installation. Once I've identified a way to install such that the +software appears to function, I transcribe the commands from my shell +back into the relevant Dockerfile script. + +#### Dockerfile scripts + +These are as follows: + +* `docker-install-phase0.bash`: perform initial upgrade of all Ubuntu + packages, unminimize system +* `docker-install-phase1.bash`: configure APT repositories and + additional architectures +* `docker-install-phase2.bash`: install tools that are used for Riju + itself (build and development tools) +* `docker-install-phase3a.bash`: install APT packages for languages + A-D +* `docker-install-phase3b.bash`: install APT packages for languages + E-L +* `docker-install-phase3c.bash`: install APT packages for languages + M-R +* `docker-install-phase3d.bash`: install APT packages for languages + S-Z +* `docker-install-phase4.bash`: install precompiled binaries and + tarballs +* `docker-install-phase5.bash`: set up language-specific package + managers and install packages from them +* `docker-install-phase6.bash`: install things from source +* `docker-install-phase7.bash`: set up project templates for languages + that require you start by running a "create new project" command, + and install custom wrapper scripts +* `docker-install-phase8.bash`: set up access control and do final + cleanup + +#### Rolling-release policy + +You'll notice in these scripts a distinct lack of any version numbers. +This is because Riju uses rolling-release for everything that can +conceivably be rolling-released (even things that look like they're +probably never *going* to get a new release, since the last one was in +2004). + +For APT and language-specific packages, this is typically simple. A +small number of APT packages include a version number as part of their +name for some reason, and I work around this using various +`grep-aptavail` incantations at the top of the `phase-3[ad].bash` +scripts. I suggest checking those examples and referring to the +`grep-aptavail` man page to understand what is going on. + +For binaries and tarballs in `phase4.bash`, a version number is +typically encoded in the download URL. For projects available via +GitHub Releases (preferred), there is a `latest_release` shell +function to fetch the latest tag. For things hosted elsewhere, I +resort to using `curl` and `grep` on the download homepage to identify +the latest version number or download URL. Crafting an appropriate +pipeline for these cases is as much an art as a science. We simply +hope that the relevant webpages will not have their layout changed too +frequently. + +#### Conventions + +* We do all work from `/tmp` and clean up our files when done. (The + current code doesn't always do a great job of this; see + [#27](https://github.com/raxod502/riju/issues/27).) +* When changing directory, we use `pushd` and `popd` in pairs. +* We prefer putting files where they're supposed to be in the first + place, rather than moving (or worse, copying) them. This can be + accomplished by means of `wget -O`, `unzip -d`, `tar -C + [--strip-components]`, and similar. +* We like to keep things as minimal as possible in terms of shell + scripting, but try to follow the standard installation procedure + where reasonable. + +### Running + +There are three categories of languages: non-interactive, interactive, +and interactive+scoped. The capabilities are as follows: + +* *Non-interactive:* You can run a file. +* FIXME + +## Debugging tools + +Add `#debug` to the end of a Riju URL and reload the page to output +all messages in JSON format in the JavaScript console. You can copy +the LSP messages as JSON for direct use in the LSP REPL (see below). + +To get a sandboxed shell session, the same as is used to run languages +on Riju, run: + + $ yarn sandbox + +To start up a JSON REPL for interacting with LSP servers, run: + + $ yarn lsp-repl (LANGUAGE | CMD...) + +## Self-hosting + +Riju is hosted on [DigitalOcean](https://www.digitalocean.com/). Sign +up for an account and obtain a personal access token with read/write +access. + +You will need some credentials. Start by selecting an admin password +to use for the DigitalOcean instance. Then generate two SSH key-pairs +(or you can use pre-existing ones). One is for the admin account on +DigitalOcean, while the other is to deploy from CI. + +Install [Packer](https://www.packer.io/). Riju uses Packer to generate +DigitalOcean AMIs to ensure a consistent setup for the production +instance. Navigate to the `packer` subdirectory of this repository and +create a file `secrets.json`, changing the values as appropriate for +your setup: + +```json +{ + "digitalocean_api_token": "28114a9f0ed5637c576794138c71bf03d01946288a6922ea083f923ec883c431", + "admin_password": "R3iIhqs856N1sT5Mg6QFAsB5VPJrXS", + "admin_ssh_public_key_file": "/home/raxod502/.ssh/id_rsa.pub", + "deploy_ssh_public_key_file": "/home/raxod502/.ssh/id_rsa_riju_deploy.pub" +} +``` + +We'll start by setting up Riju without TLS. Run: + + $ packer build -var-file secrets.json config.json + +This will take about five minutes to generate a DigitalOcean AMI. Log +in to your DigitalOcean and launch an instance based on that AMI +(called an "Image" in the interface). The hosted version of Riju uses +the $10/month instance with 1 vCPU and 2GB memory / 50GB disk. + +Root login is disabled on the AMI generated by Packer, but +DigitalOcean unfortunately doesn't give you any option to leave login +settings unchanged. I suggest setting the root password to a random +string. Make a note of the IP address of the droplet and SSH into it +under the admin user, using the key that you specified in +`secrets.json`. Now perform the following setup: + + $ sudo passwd -l root + +This completes the first DigitalOcean portion of deployment. + +Now you'll need an account on [Docker Hub](https://hub.docker.com/), +which is where built images will be stored before they are pulled down +to DigitalOcean. Create a repository; the name will be +`your-docker-id/whatever-you-name-the-repo`. You'll need this below. + +You're now ready to deploy. You can do this manually to begin with. In +the repository root on your local checkout of Riju, create a file +`.env`, changing the values as appropriate for your setup: + + DOCKER_REPO=raxod502/riju + DOMAIN=riju.codes + DEPLOY_SSH_PRIVATE_KEY=/home/raxod502/.ssh/id_rsa_riju_deploy + +Run: + + $ docker login + $ make deploy + +Riju should now be available online at your instance's public IP +address. + +Next, let's configure TLS. You'll need to configure DNS for your +domain with a CNAME to point at your DigitalOcean instance. Once DNS +has propagated, SSH into your DigitalOcean instance and run: + + $ sudo systemctl stop riju + $ sudo certbot certonly --standalone + $ sudo systemctl start riju + +You'll also want to set up automatic renewal. This can be done by +installing the two Certbot hook scripts from Riju in the +`packer/resources` subdirectory. Here is one approach: + + $ sudo wget https://github.com/raxod502/riju/raw/master/packer/resources/certbot-pre.bash + -O /etc/letsencrypt/renewal-hooks/pre/riju + $ sudo wget https://github.com/raxod502/riju/raw/master/packer/resources/certbot-post.bash + -O /etc/letsencrypt/renewal-hooks/post/riju + $ sudo chmod +x /etc/letsencrypt/renewal-hooks/pre/riju + $ sudo chmod +x /etc/letsencrypt/renewal-hooks/post/riju + +At this point you should be able to visit Riju at your custom browser +with TLS enabled. + +We can now set up CI. Sign up at [CircleCI](https://circleci.com/) and +enable automatic builds for your fork of Riju. You'll need to set the +following environment variables for the Riju project on CircleCI, +adjusting as appropriate for your own setup: + + DOCKER_USERNAME=raxod502 + DOCKER_PASSWORD=MIMvzS1bKPunDDSX4AJu + DOCKER_REPO=raxod502/riju + DOMAIN=riju.codes + DEPLOY_SSH_PRIVATE_KEY=b2Rs......lots more......SFAK + +To obtain the base64-encoded deploy key, run: + + $ cat ~/.ssh/id_rsa_riju_deploy | base64 | tr -d '\n'; echo + +New pushes to master should trigger deploys, while pushes to other +branches should trigger just builds. diff --git a/backend/src/test-runner.ts b/backend/src/test-runner.ts index 95417cd..4a44de5 100644 --- a/backend/src/test-runner.ts +++ b/backend/src/test-runner.ts @@ -607,7 +607,7 @@ const testTypes: { format: { pred: ({ format }) => (format ? true : false), }, - lsp: { pred: ({ lsp }) => (lsp && lsp.code ? true : false) }, + lsp: { pred: ({ lsp }) => (lsp ? true : false) }, }; function getTestList() { diff --git a/packer/config-certbot.json b/packer/config-certbot.json deleted file mode 100644 index da7bc53..0000000 --- a/packer/config-certbot.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "variables": { - "api_token": "" - }, - "sensitive-variables": ["api_token"], - "builders": [ - { - "type": "digitalocean", - "api_token": "{{user `api_token`}}", - "image": "ubuntu-20-04-x64", - "region": "sfo3", - "size": "s-1vcpu-1gb", - "ssh_username": "root" - } - ], - "provisioners": [ - { - "type": "shell", - "script": "provision-certbot.bash" - } - ] -} diff --git a/packer/config.json b/packer/config.json index 8e86a28..768ccac 100644 --- a/packer/config.json +++ b/packer/config.json @@ -1,16 +1,16 @@ { "variables": { - "api_token": "", + "digitalocean_api_token": "", "admin_password": "", "admin_ssh_public_key_file": "", "deploy_ssh_public_key_file": "", "docker_repo": "raxod502/riju" }, - "sensitive-variables": ["api_token", "admin_password"], + "sensitive-variables": ["digitalocean_api_token", "admin_password"], "builders": [ { "type": "digitalocean", - "api_token": "{{user `api_token`}}", + "api_token": "{{user `digitalocean_api_token`}}", "image": "ubuntu-20-04-x64", "region": "sfo3", "size": "s-1vcpu-1gb", diff --git a/packer/provision-certbot.bash b/packer/provision-certbot.bash deleted file mode 100755 index 992665d..0000000 --- a/packer/provision-certbot.bash +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash - -set -euxo pipefail - -export DEBIAN_FRONTEND=noninteractive -apt-get update -apt-get dist-upgrade -y - -apt-get install -y certbot - -rm -rf /var/lib/apt/lists/* diff --git a/packer/resources/certbot-post.bash b/packer/resources/certbot-post.bash index a151447..ed18ab4 100755 --- a/packer/resources/certbot-post.bash +++ b/packer/resources/certbot-post.bash @@ -1,6 +1,3 @@ #!/usr/bin/env bash -set -e -set -o pipefail - systemctl start riju diff --git a/packer/resources/certbot-pre.bash b/packer/resources/certbot-pre.bash index 5bd2098..ae175ae 100755 --- a/packer/resources/certbot-pre.bash +++ b/packer/resources/certbot-pre.bash @@ -1,6 +1,3 @@ #!/usr/bin/env bash -set -e -set -o pipefail - systemctl stop riju diff --git a/scripts/deploy.bash b/scripts/deploy.bash index b03b810..b9351c8 100755 --- a/scripts/deploy.bash +++ b/scripts/deploy.bash @@ -13,15 +13,16 @@ if [[ -z "${DOMAIN}" ]]; then fi if [[ -z "${DEPLOY_SSH_PRIVATE_KEY}" ]]; then - if [[ -f "$HOME/.ssh/id_rsa_riju_deploy" ]]; then - DEPLOY_SSH_PRIVATE_KEY="$(< "$HOME/.ssh/id_rsa_riju_deploy")" - else - echo "environment variable not set: DEPLOY_SSH_PRIVATE_KEY" - fi -else - DEPLOY_SSH_PRIVATE_KEY="$(printf '%s\n' "${DEPLOY_SSH_PRIVATE_KEY}" | base64 -d)" + echo "environment variable not set: DEPLOY_SSH_PRIVATE_KEY" >&2 + exit 1 fi +if [[ -f "${DEPLOY_SSH_PRIVATE_KEY}" ]]; then + DEPLOY_SSH_PRIVATE_KEY="$(< "${DEPLOY_SSH_PRIVATE_KEY}")" +fi + +DEPLOY_SSH_PRIVATE_KEY="$(printf '%s\n' "${DEPLOY_SSH_PRIVATE_KEY}" | base64 -d)" + tag="$(date +%s%3N)-$(git branch --show-current)-$(git rev-parse @)" if [[ -n "$(git status --porcelain)" ]]; then diff --git a/scripts/docker-install-phase1.bash b/scripts/docker-install-phase1.bash index 7f090ca..08a3745 100755 --- a/scripts/docker-install-phase1.bash +++ b/scripts/docker-install-phase1.bash @@ -23,7 +23,7 @@ curl -sSL https://keybase.io/crystal/pgp_keys.asc | apt-key add - apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9 apt-key adv --keyserver keyserver.ubuntu.com --recv-keys B4112585D386EB94 -wget -nv "https://packages.microsoft.com/config/ubuntu/${ubuntu_ver}/packages-microsoft-prod.deb" +wget "https://packages.microsoft.com/config/ubuntu/${ubuntu_ver}/packages-microsoft-prod.deb" dpkg -i packages-microsoft-prod.deb rm packages-microsoft-prod.deb diff --git a/scripts/docker-install-phase3b.bash b/scripts/docker-install-phase3b.bash index 9dfe57a..7e408f6 100755 --- a/scripts/docker-install-phase3b.bash +++ b/scripts/docker-install-phase3b.bash @@ -104,7 +104,7 @@ ksh # Limbo gcc -libc6-dev-i386 +libc6-dev:i386 libx11-dev:i386 libxext-dev:i386 linux-libc-dev:i386 diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 36c2e54..49d0217 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -11,23 +11,23 @@ latest_release() { # Needed for project infrastructure ver="$(latest_release watchexec/watchexec)" -wget -nv "https://github.com/watchexec/watchexec/releases/download/${ver}/watchexec-${ver}-x86_64-unknown-linux-gnu.deb" +wget "https://github.com/watchexec/watchexec/releases/download/${ver}/watchexec-${ver}-x86_64-unknown-linux-gnu.deb" dpkg -i watchexec-*.deb rm watchexec-*.deb # Shared ver="$(latest_release jgm/pandoc)" -wget -nv "https://github.com/jgm/pandoc/releases/download/${ver}/pandoc-${ver}-linux-amd64.tar.gz" +wget "https://github.com/jgm/pandoc/releases/download/${ver}/pandoc-${ver}-linux-amd64.tar.gz" tar -xf pandoc-*-linux-amd64.tar.gz -C /usr --strip-components=1 rm pandoc-*-linux-amd64.tar.gz # ><> -wget -nv https://gist.githubusercontent.com/anonymous/6392418/raw/fish.py -O /usr/local/bin/fish-lang +wget https://gist.githubusercontent.com/anonymous/6392418/raw/fish.py -O /usr/local/bin/fish-lang sed -i 's:^#!.*:#!/usr/bin/env python3:' /usr/local/bin/fish-lang chmod +x /usr/local/bin/fish-lang # ABC -wget -nv https://homepages.cwi.nl/~steven/abc/implementations/abc.tar.gz +wget https://homepages.cwi.nl/~steven/abc/implementations/abc.tar.gz mkdir /opt/abc tar -xf abc.tar.gz -C /opt/abc --strip-components=1 chmod +x /opt/abc/abc /opt/abc/abckeys @@ -40,7 +40,7 @@ chmod +x /usr/local/bin/abc rm abc.tar.gz # Ada -wget -nv https://dl.bintray.com/reznikmm/ada-language-server/linux-latest.tar.gz +wget https://dl.bintray.com/reznikmm/ada-language-server/linux-latest.tar.gz tar -xf linux-latest.tar.gz mv linux/ada_language_server /usr/local/bin/ada_language_server mv linux/*.so* /usr/lib/x86_64-linux-gnu/ @@ -48,26 +48,26 @@ rm -rf linux linux-latest.tar.gz # Ante mkdir /opt/ante -wget -nv https://github.com/raxod502/riju-cdn/releases/download/ante-0.8.0-d2c43992e0c7a4c1942d5c097233f4f7638a1ee6/ante -O /opt/ante/ante +wget https://github.com/raxod502/riju-cdn/releases/download/ante-0.8.0-d2c43992e0c7a4c1942d5c097233f4f7638a1ee6/ante -O /opt/ante/ante chmod +x /opt/ante/ante -wget -nv https://github.com/raxod502/riju-cdn/releases/download/ante-0.8.0-d2c43992e0c7a4c1942d5c097233f4f7638a1ee6/libantecommon.so -O /opt/ante/libantecommon.so +wget https://github.com/raxod502/riju-cdn/releases/download/ante-0.8.0-d2c43992e0c7a4c1942d5c097233f4f7638a1ee6/libantecommon.so -O /opt/ante/libantecommon.so ln -s /opt/ante/ante /usr/local/bin/ -wget -nv https://github.com/raxod502/riju-cdn/releases/download/ante-0.8.0-d2c43992e0c7a4c1942d5c097233f4f7638a1ee6/stdlib.tar.gz +wget https://github.com/raxod502/riju-cdn/releases/download/ante-0.8.0-d2c43992e0c7a4c1942d5c097233f4f7638a1ee6/stdlib.tar.gz tar -xf stdlib.tar.gz -C /opt/ante rm stdlib.tar.gz # Ante (Cards) -wget -nv https://github.com/michaeldv/ante/raw/master/ante.rb -O /usr/local/bin/ante-cards +wget https://github.com/michaeldv/ante/raw/master/ante.rb -O /usr/local/bin/ante-cards chmod +x /usr/local/bin/ante-cards # APL file="$(curl -sS ftp://ftp.gnu.org/gnu/apl/ | grep -Eo 'apl_[-0-9.]+_amd64.deb$' | sort -rV | head -n1)" -wget -nv "ftp://ftp.gnu.org/gnu/apl/${file}" +wget "ftp://ftp.gnu.org/gnu/apl/${file}" dpkg -i apl_*_amd64.deb rm apl_*_amd64.deb # Boo -wget -nv https://github.com/boo-lang/boo/releases/download/unstable/boo-latest.zip +wget https://github.com/boo-lang/boo/releases/download/unstable/boo-latest.zip unzip boo-latest.zip mv boo-latest /usr/local/lib/boo chmod +x /usr/local/lib/boo/booc /usr/local/lib/boo/booish @@ -75,19 +75,19 @@ ln -s /usr/local/lib/boo/booc /usr/local/lib/boo/booish /usr/local/bin/ # Clojure ver="$(latest_release snoe/clojure-lsp)" -wget -nv "https://github.com/snoe/clojure-lsp/releases/download/${ver}/clojure-lsp" +wget "https://github.com/snoe/clojure-lsp/releases/download/${ver}/clojure-lsp" chmod +x clojure-lsp mv clojure-lsp /usr/local/bin/clojure-lsp # D -wget -nv "$(curl -sSL https://dlang.org/download.html | grep -Eo '"http://[^"]+amd64.deb"' | tr -d '"')" +wget "$(curl -sSL https://dlang.org/download.html | grep -Eo '"http://[^"]+amd64.deb"' | tr -d '"')" dpkg -i dmd_*.deb rm dmd_*.deb # Dhall ver="$(latest_release dhall-lang/dhall-haskell)" file="$(curl -sSL "https://api.github.com/repos/dhall-lang/dhall-haskell/releases/tags/${ver}" | jq -r '.assets | map(select(.name | (contains("dhall-json") and contains("x86_64-linux.tar.bz2")))) | .[0].name')" -wget -nv "https://github.com/dhall-lang/dhall-haskell/releases/download/${ver}/${file}" +wget "https://github.com/dhall-lang/dhall-haskell/releases/download/${ver}/${file}" mkdir dhall-json tar -xf dhall-json-*-x86_64-linux.tar.bz2 -C dhall-json mv dhall-json/bin/dhall-to-json dhall-json/bin/json-to-dhall /usr/local/bin/ @@ -95,7 +95,7 @@ rm -rf dhall-json dhall-json-*-x86_64-linux.tar.bz2 # Dylan ver="$(latest_release dylan-lang/opendylan)" -wget -nv "https://github.com/dylan-lang/opendylan/releases/download/${ver}/opendylan-$(grep -Eo '[0-9]+\.[0-9]+' <<< "$ver")-x86_64-linux.tar.bz2" +wget "https://github.com/dylan-lang/opendylan/releases/download/${ver}/opendylan-$(grep -Eo '[0-9]+\.[0-9]+' <<< "$ver")-x86_64-linux.tar.bz2" tar -xf opendylan-*-x86_64-linux.tar.bz2 rm opendylan-*-x86_64-linux.tar.bz2 mv opendylan-* /opt/dylan @@ -103,21 +103,21 @@ ln -s /opt/dylan/bin/dylan-compiler /opt/dylan/bin/make-dylan-app /usr/local/bin # Elixir ver="$(latest_release elixir-lsp/elixir-ls)" -wget -nv "https://github.com/elixir-lsp/elixir-ls/releases/download/${ver}/elixir-ls.zip" +wget "https://github.com/elixir-lsp/elixir-ls/releases/download/${ver}/elixir-ls.zip" unzip -d /opt/elixir-ls elixir-ls.zip ln -s /opt/elixir-ls/language_server.sh /usr/local/bin/elixir-ls rm elixir-ls.zip # Elm ver="$(latest_release elm/compiler)" -wget -nv "https://github.com/elm/compiler/releases/download/${ver}/binary-for-linux-64-bit.gz" +wget "https://github.com/elm/compiler/releases/download/${ver}/binary-for-linux-64-bit.gz" gunzip binary-for-linux-64-bit.gz chmod +x binary-for-linux-64-bit mv binary-for-linux-64-bit /usr/local/bin/elm # Emojicode ver="$(latest_release emojicode/emojicode)" -wget -nv "https://github.com/emojicode/emojicode/releases/download/${ver}/Emojicode-$(sed 's/^v//' <<< "$ver")-Linux-x86_64.tar.gz" +wget "https://github.com/emojicode/emojicode/releases/download/${ver}/Emojicode-$(sed 's/^v//' <<< "$ver")-Linux-x86_64.tar.gz" tar -xf Emojicode-*-Linux-x86_64.tar.gz pushd Emojicode-*-Linux-x86_64 >/dev/null mv emojicodec /usr/local/bin/ @@ -129,24 +129,24 @@ popd >/dev/null rm -rf Emojicode-*-Linux-x86_64 Emojicode-*-Linux-x86_64.tar.gz # Entropy -wget -nv http://danieltemkin.com/Content/Entropy/Entropy.zip +wget http://danieltemkin.com/Content/Entropy/Entropy.zip unzip -d /opt/entropy Entropy.zip rm Entropy.zip # Erlang -wget -nv https://s3.amazonaws.com/rebar3/rebar3 +wget https://s3.amazonaws.com/rebar3/rebar3 chmod +x rebar3 mv rebar3 /usr/local/bin/rebar3 # Euphoria -wget -nv http://www.rapideuphoria.com/31/euphor31.tar +wget http://www.rapideuphoria.com/31/euphor31.tar mkdir /opt/euphoria tar -xf euphor*.tar -C /opt/euphoria --strip-components=1 ln -s /opt/euphoria/bin/exu /usr/bin/ rm euphor*.tar # Ezhil -wget -nv https://github.com/raxod502/riju-cdn/releases/download/ezhil-2017.08.19/ezhil.tar.gz +wget https://github.com/raxod502/riju-cdn/releases/download/ezhil-2017.08.19/ezhil.tar.gz tar -xf ezhil.tar.gz mv ezhil-* /opt/ezhil cp /opt/ezhil/ezhili /opt/ezhil/ezhuthi/ @@ -155,7 +155,7 @@ rm ezhil.tar.gz # Factor ver="$(curl -sSL https://factorcode.org/ | grep -Eo 'release\?os=linux[^>]+>[^<]+' | sed -E 's/[^>]+>//' | head -n1)" -wget -nv "https://downloads.factorcode.org/releases/${ver}/factor-linux-x86-64-${ver}.tar.gz" +wget "https://downloads.factorcode.org/releases/${ver}/factor-linux-x86-64-${ver}.tar.gz" tar -xf factor-linux-x86-64-*.tar.gz mv -T factor /opt/factor ln -s /opt/factor/factor /usr/local/bin/factor-lang @@ -175,68 +175,68 @@ mv go/bin/gopls /usr/local/bin/gopls rm -rf go # GolfScript -wget -nv http://www.golfscript.com/golfscript/golfscript.rb -O /usr/local/bin/golfscript +wget http://www.golfscript.com/golfscript/golfscript.rb -O /usr/local/bin/golfscript chmod +x /usr/local/bin/golfscript # Grass -wget -nv http://www.blue.sky.or.jp/grass/grass.rb -O /usr/local/bin/grass +wget http://www.blue.sky.or.jp/grass/grass.rb -O /usr/local/bin/grass chmod +x /usr/local/bin/grass # Haskell curl -sSL https://get.haskellstack.org/ | sh -wget -nv https://github.com/raxod502/riju-cdn/releases/download/brittany-0.12.1.1/brittany -O /usr/local/bin/brittany +wget https://github.com/raxod502/riju-cdn/releases/download/brittany-0.12.1.1/brittany -O /usr/local/bin/brittany chmod +x /usr/local/bin/brittany mkdir -p /opt/haskell -wget -nv https://github.com/raxod502/riju-cdn/releases/download/hie-1.4-a9005b2ba2050bdfdd4438f1d471a3f7985492cd-ghc8.6.5/hie -O /usr/local/bin/hie -wget -nv https://github.com/raxod502/riju-cdn/releases/download/hie-1.4-a9005b2ba2050bdfdd4438f1d471a3f7985492cd-ghc8.6.5/hoogle.hoo -O /opt/haskell/hoogle.hoo +wget https://github.com/raxod502/riju-cdn/releases/download/hie-1.4-a9005b2ba2050bdfdd4438f1d471a3f7985492cd-ghc8.6.5/hie -O /usr/local/bin/hie +wget https://github.com/raxod502/riju-cdn/releases/download/hie-1.4-a9005b2ba2050bdfdd4438f1d471a3f7985492cd-ghc8.6.5/hoogle.hoo -O /opt/haskell/hoogle.hoo chmod +x /usr/local/bin/hie # HCL/TOML/YAML ver="$(latest_release sclevine/yj)" -wget -nv "https://github.com/sclevine/yj/releases/download/${ver}/yj-linux" +wget "https://github.com/sclevine/yj/releases/download/${ver}/yj-linux" chmod +x yj-linux mv yj-linux /usr/local/bin/yj # HMMM -wget -nv https://www.cs.hmc.edu/~cs5grad/cs5/hmmm/code/hmmm -O /usr/local/bin/hmmm +wget https://www.cs.hmc.edu/~cs5grad/cs5/hmmm/code/hmmm -O /usr/local/bin/hmmm chmod +x /usr/local/bin/hmmm # Ink ver="$(latest_release thesephist/ink)" -wget -nv "https://github.com/thesephist/ink/releases/download/${ver}/ink-linux" -wget -nv "https://github.com/thesephist/ink/releases/download/${ver}/std.ink" -wget -nv "https://github.com/thesephist/ink/releases/download/${ver}/str.ink" +wget "https://github.com/thesephist/ink/releases/download/${ver}/ink-linux" +wget "https://github.com/thesephist/ink/releases/download/${ver}/std.ink" +wget "https://github.com/thesephist/ink/releases/download/${ver}/str.ink" chmod +x ink-linux mv ink-linux /usr/local/bin/ink mkdir /opt/ink mv std.ink str.ink /opt/ink/ # Ioke -wget -nv https://ioke.org/dist/ioke-ikj-latest.tar.gz +wget https://ioke.org/dist/ioke-ikj-latest.tar.gz tar -xf ioke-ikj-*.tar.gz -C /opt rm ioke-ikj-*.tar.gz ln -s /opt/ioke/bin/ioke /usr/local/bin/ioke # J -wget -nv "$(curl -sSL https://code.jsoftware.com/wiki/System/Installation/J901/Debian | grep -F '/dev/null # Clean -wget -nv "$(curl -sSL https://clean.cs.ru.nl/Download_Clean | grep linux/clean | grep -F 64.tar.gz | grep -Eo "https://[^>]+\.tar\.gz")" +wget "$(curl -sSL https://clean.cs.ru.nl/Download_Clean | grep linux/clean | grep -F 64.tar.gz | grep -Eo "https://[^>]+\.tar\.gz")" mkdir /opt/clean tar -xf clean*_64.tar.gz -C /opt/clean --strip-components=1 pushd /opt/clean >/dev/null @@ -67,7 +67,7 @@ rm -rf erlang_ls git clone https://github.com/m-ender/hexagony.git /opt/hexagony # Idris -wget -nv https://www.idris-lang.org/idris2-src/idris2-latest.tgz +wget https://www.idris-lang.org/idris2-src/idris2-latest.tgz tar -xf idris2-latest.tgz pushd Idris2-* >/dev/null make bootstrap-build SCHEME=chezscheme PREFIX=/usr/local @@ -95,7 +95,7 @@ popd >/dev/null rm -rf lazyk # Limbo -wget -nv "$(curl -sSL http://www.vitanuova.com/inferno/downloads.html | grep -E 'inferno-[0-9]+\.tgz' | grep -Eo 'http://[^"]+')" +wget "$(curl -sSL http://www.vitanuova.com/inferno/downloads.html | grep -E 'inferno-[0-9]+\.tgz' | grep -Eo 'http://[^"]+')" tar -xf inferno-*.tgz -C /usr/local pushd /usr/local/inferno >/dev/null sed -i 's/gcc/gcc -m32/g' makemk.sh @@ -119,7 +119,7 @@ rm -rf malbolge # Oberon file="$(curl -sSL https://miasap.se/obnc/ | grep -F obnc_ | grep -Eo 'obnc_[^"]+' | grep -v win | head -n1)" -wget -nv "https://miasap.se/obnc/downloads/${file}" +wget "https://miasap.se/obnc/downloads/${file}" tar -xf obnc_*.tar.gz pushd obnc-* >/dev/null ./build @@ -178,7 +178,7 @@ rm -rf slick # Snobol file="$(curl -sSL ftp://ftp.snobol4.org/snobol/ | grep -Eo 'snobol4-.*\.tar\.gz' | sort -rV | head -n1)" -wget -nv "ftp://ftp.snobol4.org/snobol/${file}" +wget "ftp://ftp.snobol4.org/snobol/${file}" tar -xf snobol4-*.tar.gz rm snobol4-*.tar.gz pushd snobol4-* >/dev/null @@ -197,7 +197,7 @@ popd >/dev/null # Tabloid mkdir /opt/tabloid pushd /opt/tabloid >/dev/null -wget -nv https://github.com/thesephist/tabloid/raw/master/static/js/lang.js +wget https://github.com/thesephist/tabloid/raw/master/static/js/lang.js cat <<"EOF" >> lang.js module.exports = { tokenize, Parser, Environment }; EOF @@ -214,7 +214,7 @@ popd >/dev/null rm -rf TECOC # Thue -wget -nv "$(curl -sSL https://catseye.tc/distribution/Thue_distribution | grep -Eo 'https://catseye.tc/distfiles/thue-[^"]+\.zip' | head -n1)" +wget "$(curl -sSL https://catseye.tc/distribution/Thue_distribution | grep -Eo 'https://catseye.tc/distfiles/thue-[^"]+\.zip' | head -n1)" unzip thue-*.zip rm thue-*.zip pushd thue-* >/dev/null @@ -224,7 +224,7 @@ popd >/dev/null rm -rf thue-* # Velato -wget -nv http://www.archduke.org/midi/asc2mid.c +wget http://www.archduke.org/midi/asc2mid.c clang asc2mid.c -o /usr/local/bin/asc2mid rm asc2mid.c From d681f04efc6181000c40912955f2cdb67ac82828 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 12 Dec 2020 21:01:20 +0000 Subject: [PATCH 379/388] Bump ini from 1.3.5 to 1.3.8 Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.8. - [Release notes](https://github.com/isaacs/ini/releases) - [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.8) Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 6e944d5..2ee7efc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2771,9 +2771,9 @@ inherits@2.0.3: integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= ini@^1.3.4, ini@^1.3.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== interpret@1.2.0: version "1.2.0" From f0940ce3307010234deec52581889fecd25b919d Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Wed, 7 Oct 2020 21:20:06 -0700 Subject: [PATCH 380/388] Remove secrets from deploy log --- scripts/deploy.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/deploy.bash b/scripts/deploy.bash index b9351c8..e4ede18 100755 --- a/scripts/deploy.bash +++ b/scripts/deploy.bash @@ -1,6 +1,6 @@ #!/usr/bin/env bash -set -euxo pipefail +set -euo pipefail if [[ -z "${DOCKER_REPO}" ]]; then echo "environment variable not set: DOCKER_REPO" >&2 From 7d17745db1fb0437366407b8d8822a5a005874ad Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Wed, 7 Oct 2020 21:20:46 -0700 Subject: [PATCH 381/388] Fix typo in CircleCI config --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4a4323b..625d26f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -22,7 +22,7 @@ jobs: - run: | echo "${DOCKER_PASSWORD}" | \ docker login --username "${DOCKER_USERNAME}" --password-stdin - - run: scripts/deploy.bash + - run: make deploy workflows: version: 2 ci: From 28283c76eedea4d605c2d3fda1cb511bf93563a6 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Wed, 14 Oct 2020 19:28:05 -0700 Subject: [PATCH 382/388] Add .env to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 808bf7f..519aca8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.env .git *.log .log From 0852ea241c5b5d85198d02303f1001abc0af2aaf Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 17 Oct 2020 08:39:35 -0700 Subject: [PATCH 383/388] Fix PATH in non-privileged mode --- backend/src/util.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/src/util.ts b/backend/src/util.ts index bffbce4..31280df 100644 --- a/backend/src/util.ts +++ b/backend/src/util.ts @@ -5,6 +5,7 @@ import * as process from "process"; import * as appRoot from "app-root-path"; import { quote } from "shell-quote"; +import { PRIVILEGED } from "./config"; import { MIN_UID, MAX_UID } from "./users"; export interface Options extends SpawnOptions { @@ -51,7 +52,7 @@ function getEnv({ uid, uuid }: Context) { LANG: process.env.LANG || "", LC_ALL: process.env.LC_ALL || "", LOGNAME: username, - PATH: path.join(":"), + PATH: PRIVILEGED ? path.join(":") : process.env.PATH || "", PWD: cwd, SHELL: "/usr/bin/bash", TERM: "xterm-256color", From e4813d3c6c31d14be419e62749b9aeecbec73b16 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 17 Oct 2020 08:39:42 -0700 Subject: [PATCH 384/388] Fix D installation --- scripts/docker-install-phase4.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 49d0217..90981ed 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -80,7 +80,7 @@ chmod +x clojure-lsp mv clojure-lsp /usr/local/bin/clojure-lsp # D -wget "$(curl -sSL https://dlang.org/download.html | grep -Eo '"http://[^"]+amd64.deb"' | tr -d '"')" +wget "$(curl -sSL https://dlang.org/download.html | grep -Eo '"http://[^"]+amd64.deb"' | grep -v pre-release | tr -d '"')" dpkg -i dmd_*.deb rm dmd_*.deb From 23b3afe282659e520ba34e2d78e0f2c4d4ae36fd Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 17 Oct 2020 08:39:46 -0700 Subject: [PATCH 385/388] Clean up Zsh run command --- backend/src/langs.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 4bde826..6885704 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -4030,7 +4030,7 @@ x`, input: `expr 123 \\* 234`, main: ".zshrc", createEmpty: ``, - run: `SHELL=/usr/bin/zsh ZDOTDIR="$PWD" zsh`, + run: `SHELL=/usr/bin/zsh zsh`, scope: { code: `x="$(expr 123 \\* 234)"`, input: `echo "$x"`, From 207646653a5c5d5da96e7abbb4ef39a75de5adad Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 17 Oct 2020 08:40:07 -0700 Subject: [PATCH 386/388] Write a bunch of documentation --- README.md | 218 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 211 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 0c78a73..c6640bd 100644 --- a/README.md +++ b/README.md @@ -91,8 +91,8 @@ you should submit a pull request :) ## Project setup -To run the webserver, all you need is Yarn. Just run `yarn install` as -usual to install dependencies. For production, it's: +To run the webserver, all you need is Yarn and LLVM. Just run `yarn +install` as usual to install dependencies. For production, it's: $ yarn backend |- or run all three with 'yarn build' $ yarn frontend | @@ -246,13 +246,217 @@ frequently. scripting, but try to follow the standard installation procedure where reasonable. -### Running +### Language configuration -There are three categories of languages: non-interactive, interactive, -and interactive+scoped. The capabilities are as follows: +After installing the language, you'll need to configure it. This is +done by adding an entry to +[`backend/src/langs.ts`](backend/src/langs.ts). -* *Non-interactive:* You can run a file. -* FIXME +#### Required keys + +Here is an example of a minimal language configuration, with only the +required keys: + +```ts + befunge: { + name: "Befunge", + main: "main.be", + run: "befunge-repl main.be", + template: `64+"!dlrow ,olleH">:#,_@ +`, + }, +``` + +We have five things here: + +* The language ID `befunge`, which appears in the URL + () and is used internally to track the + language. This can contain Unicode characters, but it must be safe + for URLs, so for example `+` is fine but `#` is not. +* The language display name `Befunge`, which is shown on the language + homepage and in some UI messages. The homepage is sorted by this + key. +* The name `main.be` of the file where a program is stored to be run. + When the user clicks the Run button, whatever is in the code editor + will be saved to this filename before the run command is executed. + We try to use a file extension that is actually appropriate for the + language, but if there's no standard one it's okay to pick something + that seems reasonable. The "Hello, world" resources on the [Riju + wiki](https://github.com/raxod502/riju/wiki) can be a helpful source + of plausible file extensions for obscure languages. +* The shell command `befunge-repl main.be` (executed in Bash) to run + the main file. +* The code `64+"!dlrow ,olleH">:#,_@` to prepopulate in the code + editor on page load. This should print "Hello, world!" exactly with + a trailing newline. Some languages are extremely difficult to write + in, so for those cases it's okay to copy a "Hello, world" program + from online even if it doesn't have the formatting quite right. The + `template` key should use a backtick-delimited string literal with a + trailing newline. + +After you add these four keys, you should be able to test your +language at . You shouldn't have +to manually restart anything if you're running `yarn dev` already. + +#### Interactive languages + +Some languages provide an interactive REPL facility. Such languages +should be configured to expose that functionality on Riju. That's done +by adding a `repl` key, like so: + +```ts + python: { + name: "Python", + repl: "python3 -u", + main: "main.py", + run: "python3 -u -i main.py", + template: `print("Hello, world!") +`, + }, +``` + +The `repl` key has another shell command to be executed with Bash, +which should launch a REPL independently of whatever may be in the +main file (in this case `main.py`). Also, for interactive languages, +the `run` command is different. It should not only run the code in +`main.py`, but then subsequently start the REPL. Many languages +provide a way to do this conveniently; for Python, the `-i` flag +forces the REPL to launch after `main.py` has finished executing. + +One thing you will want to test is whether variables from your code +are accessible in the REPL. If it's possible to make this happen, do +it. Some languages require that you use a specific command-line +argument to get this behavior, while others may not support it at all. + +For languages that do not have a convenient `-i` flag like Python, it +is okay to explicitly launch the REPL after running the code: + +```ts + kitten: { + name: "Kitten", + repl: "kitten", + main: "main.ktn", + run: "kitten main.ktn; kitten", + template: `"Hello, world!" say +`, + }, +``` + +##### Hacking startup files + +Many languages *appear* to have no way to start a REPL with your +code's variables in scope, but nevertheless have a secret backdoor. +Check to see if the language supports a "startup file" or "profile +file" or "REPL configuration file" or "rc file" or anything like that. +If it does, we can often put the user's code in there and it will be +read in a special way when the REPL starts up. This is especially +useful for shells: + +```ts + zsh: { + name: "Zsh", + repl: "SHELL=/usr/bin/zsh zsh", + main: ".zshrc", + createEmpty: ``, + run: `SHELL=/usr/bin/zsh zsh`, + template: `echo "Hello, world!" +`, + }, +``` + +When this hack is used, the `repl` and `run` commands are often the +same, with the different behavior of running the user's code or not +being caused by whether or not the code has been put into the profile +file (in this case `.zshrc`). + +Note the use of the `createEmpty` key here. To make LSP work properly +(more on that later), the main file (here `.zshrc`) is actually +created even before the user clicks the Run button. This causes +problems for languages that use a startup file hack, since when +executing the `repl` shell command, the "Hello, world" code from the +template will get executed, which is undesired. To work around this, +the `createEmpty` key allows you to provide a special value to write +into the main file (here `.zshrc`) before executing the `repl` shell +command. Providing the empty string ensures no user code gets executed +when we just want to launch a REPL. + +Check out Beanshell, Elvish, Factor, GEL, Ksh, R, SageMath, Sh, Tcl, +Tcsh, and Zsh for examples of this hack. + +#### Compiled languages + +For languages that have a compilation step, it's nice to split out +that step into a separate shell command under the `compile` key, like +so: + +```ts + c: { + name: "C", + main: "main.c", + compile: "clang -Wall -Wextra main.c -o main", + run: "./main", + template: `#include + +int main() { + printf("Hello, world!\\n"); + return 0; +} +`, + }, +``` + +It's not treated any differently by Riju at present than just cramming +both steps into the `run` key with a `&&`, but we could implement +optimizations later such as only re-running the compile step if the +code actually changed. + +#### Integration tests + +Riju has a suite of over 500 integration tests covering all supported +languages. This is to ensure that our aggressive rolling-release +policy does not lead to breakage. + +My design philosophy of tests is that if they require any effort to +write, nobody is going to write them, least of all me. For this +reason, Riju uses a +[convention-over-configuration](https://en.wikipedia.org/wiki/Convention_over_configuration) +scheme to automatically synthesize the majority of the integration +tests without the need for any code to be written. + +There are seven possible tests each language can have, and each +language has some subset of them: + +* `run`: Verify that running the language with the default code causes + `Hello, world!` to be printed. +* `repl`: Verify that typing in an expression at the REPL (by default + `123 * 234`) causes a result to be output (by default `28782`). +* `runrepl`: Same as `repl`, but after the Run button is clicked. This + proves that a REPL is being started after the code finishes running. +* `scope`: Verify that a variable defined in the code is accessible in + the REPL after the code is run. +* `format`: Verify that a code formatter correctly reformats a piece + of sample code. +* `lsp`: Verify that an LSP server produces a particular completion. +* `ensure`: Run an arbitrary shell command and verify that it exits + successfully. This test is currently not used by any language. + +The `run`, `repl`, and `runrepl` tests are configured automatically +with default values for every language. The other test types are not +configured automatically, because there is no way to pick a reasonable +default for the behavior they are testing. Use the following list to +identify which tests you should make sure are configured for your +language: + +* `run`: all languages +* `repl`, `runrepl`: interactive languages (ones with a `repl` key) +* `scope`: interactive languages where you can access code variables + from the REPL +* `format`: languages with code formatters (see below) +* `lsp`: languages with LSP support (see below) + +##### Test configuration + +FIXME ## Debugging tools From 0e80fba7a60cb71cefce03f39e0822c85c23e75f Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Wed, 16 Dec 2020 21:43:44 -0800 Subject: [PATCH 387/388] [#44] Upgrade Mathics, remove deadsnakes dependency The deadsnakes PPA has apparently not been updated for compatibility with Ubuntu Groovy, so the build was failing. I think we only needed deadsnakes (which provides older Python versions) for Mathics, which (until the recent new release) had a bug that prevented using it with Python 3.8. By upgrading Mathics, we remove the need for the old Python version, which means we don't have to figure out how to work around the deadsnakes compatibility problem. --- scripts/docker-install-phase1.bash | 2 -- scripts/docker-install-phase3c.bash | 4 ---- scripts/docker-install-phase3d.bash | 3 ++- scripts/docker-install-phase5.bash | 2 +- 4 files changed, 3 insertions(+), 8 deletions(-) diff --git a/scripts/docker-install-phase1.bash b/scripts/docker-install-phase1.bash index 08a3745..e7e5bdd 100755 --- a/scripts/docker-install-phase1.bash +++ b/scripts/docker-install-phase1.bash @@ -40,7 +40,5 @@ deb https://dl.yarnpkg.com/debian/ stable main deb https://downloads.ceylon-lang.org/apt/ unstable main EOF -add-apt-repository -y -n ppa:deadsnakes/ppa - popd >/dev/null rm "$0" diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index f8b7e0e..361a208 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -17,10 +17,6 @@ m4 # MariaDB libtinfo5 -# Mathics -python3.7 -python3.7-dev - # MiniZinc minizinc diff --git a/scripts/docker-install-phase3d.bash b/scripts/docker-install-phase3d.bash index ec2a290..5d91cac 100755 --- a/scripts/docker-install-phase3d.bash +++ b/scripts/docker-install-phase3d.bash @@ -84,7 +84,8 @@ vim mono-vbnc # Wolfram Language -python3.7 +python3 +python3-dev # x86 clang diff --git a/scripts/docker-install-phase5.bash b/scripts/docker-install-phase5.bash index a16d73d..7ebecdd 100755 --- a/scripts/docker-install-phase5.bash +++ b/scripts/docker-install-phase5.bash @@ -126,7 +126,7 @@ npm install -g vim-language-server pip3 install whitespace # Wolfram Language -python3.7 -m pip install mathics +pip3 install Mathics3 rm -rf /root/.cache /root/.config /root/.cpan /root/.cpanm /root/.dub /root/.gem /root/.npm /root/.npmrc rm -f /tmp/core-js-banners From a2b34fa9db07d78b04025cb97ba09f24ed2c9945 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Tue, 22 Dec 2020 14:55:25 -0800 Subject: [PATCH 388/388] [#23] Start adding language metadata --- backend/src/langs.ts | 633 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 623 insertions(+), 10 deletions(-) diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 6885704..6764477 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -1,6 +1,37 @@ +type Category = "assembly" | "config" | "data" | "database" | "editor" | "esoteric" | "general" | "markup" | "pure" | "shell" | "tool" +type Mode = "compiled" | "interpreted" +type Platform = "bf" | "clr" | "js" | "jvm" | "python" | "windows" +type Syntax = "assembly" | "basic" | "c" | "golf" | "haskell" | "lisp" | "pascal" | "python" | "text" | "tokens" | "2d" | "column" | "extensible" | "foreign" | "symbol" | "whitespace" +type Typing = "static" | "dynamic" | "theorem" | "float" | "integer" | "lambda" | "string" | "weak" +type Paradigm = "array" | "declarative" | "functional" | "imperative" | "oo" | "stack" | "turing" +type Usage = "abandoned" | "personal" | "popular" + +type Some = T | T[]; + export interface LangConfig { aliases?: string[]; name: string; + info?: { + impl?: string; + version?: string; + year: number; + desc: string; + ext: Some; + web: { + wiki?: string; + esolang?: string; + home?: string; + impl?: string; + source: string | null; + }; + category: Some; + mode: Some; + platform: Some; + syntax: Some; + typing: Some; + paradigm: Some; + usage: Some; + } monacoLang?: string; daemon?: string; setup?: string; @@ -52,10 +83,31 @@ export interface LangConfig { skip?: string[]; } +// Popular languages: https://pypl.github.io/PYPL.html +// +// (All 28 languages listed are on Riju, except Object Pascal and VBA.) + +// TODO: validate that links have not broken export const langs: { [key: string]: LangConfig } = { "><>": { aliases: ["fishlang"], name: "><>", + info: { + year: 2009, + desc: "Stack-based, reflective, two-dimensional esoteric programming language", + ext: "fish", + web: { + esolang: "https://esolangs.org/wiki/Fish", + source: "https://gist.github.com/anonymous/6392418", + }, + category: "esoteric", + mode: "interpreted", + platform: [], + syntax: ["golf", "2d"], + typing: "float", + paradigm: "stack", + usage: [], + }, main: "main.fish", run: "fish-lang main.fish", template: `"Hello, world!"r\\ @@ -88,8 +140,27 @@ export const langs: { [key: string]: LangConfig } = { `, }, ada: { - aliases: ["adb"], + aliases: ["adb", "gnat"], name: "Ada", + info: { + impl: "GNAT", + year: 1980, + desc: "Structured, statically typed, imperative, and object-oriented high-level programming language, extended from Pascal and other languages", + ext: ["adb", "ads"], + web: { + wiki: "https://en.wikipedia.org/wiki/Ada_(programming_language)", + home: "https://www.adaic.org/", + impl: "https://www.gnu.org/software/gnat/", + source: "https://gcc.gnu.org/git.html", + }, + category: "general", + mode: "compiled", + platform: [], + syntax: "pascal", + typing: "static", + paradigm: ["imperative", "oo"], + usage: "popular", + }, main: "main.adb", compile: "x86_64-linux-gnu-gnatmake-9 main.adb", run: "./main", @@ -147,8 +218,27 @@ println (* 123 234)`, `, }, algol: { - aliases: ["alg"], + aliases: ["alg", "a68g", "genie", "a68genie"], name: "ALGOL 68", + info: { + impl: "ALGOL 68 Genie", + version: "ALGOL 68", + year: 1958, + desc: "Seminal imperative programming language which introduced lexical scope and formal grammar specification", + ext: "alg", + web: { + wiki: "https://en.wikipedia.org/wiki/ALGOL", + home: "http://algol68.sourceforge.net/", + source: "https://jmvdveer.home.xs4all.nl/en.algol-68-genie.html", + }, + category: "general", + mode: ["interpreted", "compiled"], + platform: [], + syntax: "pascal", + typing: "static", + paradigm: "imperative", + usage: [], + }, main: "main.alg", run: "a68g main.alg", template: `print(("Hello, world!",new line)) @@ -175,6 +265,24 @@ println (* 123 234)`, }, apl: { name: "APL", + info: { + impl: "GNU APL", + year: 1966, + desc: "Array-based programming language using large range of special symbols for concision", + ext: "apl", + web: { + wiki: "https://en.wikipedia.org/wiki/APL_(programming_language)", + impl: "https://www.gnu.org/software/apl/", + source: "https://savannah.gnu.org/svn/?group=apl", + }, + category: ["general"], + mode: "interpreted", + platform: [], + syntax: ["golf", "symbol"], + typing: "dynamic", + paradigm: ["array", "functional", "imperative"], + usage: [], + }, repl: "apl", input: "123 × 234", main: "main.apl", @@ -187,6 +295,25 @@ println (* 123 234)`, }, arm: { name: "ARM", + info: { + impl: "GCC", + year: 1985, + desc: "Popular RISC architecture used in mobile devices", + ext: "S", + web: { + wiki: "https://en.wikipedia.org/wiki/ARM_architecture", + home: "https://developer.arm.com/architectures/cpu-architecture", + impl: "https://gcc.gnu.org/", + source: "https://gcc.gnu.org/git.html", + }, + category: "assembly", + mode: "compiled", + platform: [], + syntax: "assembly", + typing: "weak", + paradigm: "imperative", + usage: [], + }, main: "main.S", compile: "arm-linux-gnueabihf-gcc main.S -o main -static", run: "qemu-arm-static main", @@ -209,6 +336,23 @@ message: asciidoc: { aliases: ["adoc", "asc"], name: "AsciiDoc", + info: { + year: 2002, + desc: "Human-readable document format, semantically equivalent to DocBook XML, but using plain-text mark-up conventions", + ext: "adoc", + web: { + wiki: "https://en.wikipedia.org/wiki/AsciiDoc", + home: "https://asciidoc.org/", + source: "https://github.com/asciidoc/asciidoc", + }, + category: "markup", + mode: [], + platform: [], + syntax: "text", + typing: [], + paradigm: [], + usage: [], + }, main: "main.adoc", compile: "asciidoc -s main.adoc", run: "prettier --no-config main.html", @@ -252,8 +396,26 @@ int main() { `, }, ats: { - aliases: ["dats"], + aliases: ["dats", "sats", "cats", "hats"], name: "ATS", + info: { + impl: "ATS2/Postiats", + year: 2007, + desc: "Programming language designed to unify programming with formal specification", + ext: ["sats", "dats", "cats", "hats"], + web: { + wiki: "https://en.wikipedia.org/wiki/ATS_(programming_language)", + home: "http://www.ats-lang.org/", + source: "https://github.com/githwxi/ATS-Postiats", + }, + category: "general", + mode: "compiled", + platform: [], + syntax: ["c", "haskell"], + typing: ["static", "theorem"], + paradigm: ["imperative", "declarative"], + usage: [], + }, monacoLang: "postiats", main: "main.dats", compile: "patscc main.dats -o main", @@ -263,8 +425,26 @@ implement main0 () = () `, }, awk: { - aliases: ["gawk", "mawk"], + aliases: ["gawk", "mawk", "nawk"], name: "Awk", + info: { + impl: "GNU Awk", + year: 1977, + desc: "Domain-specific language designed for text processing and typically used as a data extraction and reporting tool", + ext: "awk", + web: { + wiki: "https://en.wikipedia.org/wiki/AWK", + impl: "https://www.gnu.org/software/gawk/manual/gawk.html", + source: "https://savannah.gnu.org/git/?group=gawk", + }, + category: "tool", + mode: "interpreted", + platform: [], + syntax: "c", + typing: "weak", + paradigm: "imperative", + usage: [], + }, main: "main.awk", run: `awk -f main.awk`, template: `BEGIN { print "Hello, world!" } @@ -273,6 +453,24 @@ implement main0 () = () bash: { aliases: ["bashrc", "bourneshell"], name: "Bash", + info: { + impl: "GNU Bash", + year: 1989, + desc: "Unix shell and command language written by Brian Fox for the GNU Project as a free software replacement for the Bourne shell", + ext: ["bash", "sh"], + web: { + wiki: "https://en.wikipedia.org/wiki/Bash_(Unix_shell)", + impl: "https://www.gnu.org/software/bash/", + source: "https://savannah.gnu.org/projects/bash/", + }, + category: "shell", + mode: "interpreted", + platform: [], + syntax: "pascal", + typing: "weak", + paradigm: "imperative", + usage: [], + }, monacoLang: "shell", repl: "bash --rcfile /dev/null", input: `expr 123 \\* 234`, @@ -290,6 +488,24 @@ implement main0 () = () basic: { aliases: ["bas", "qbasic"], name: "BASIC", + info: { + impl: "Bywater BASIC", + year: 1964, + desc: "General-purpose, high-level programming language whose design philosophy emphasizes ease of use", + ext: "bas", + web: { + wiki: "https://en.wikipedia.org/wiki/BASIC", + impl: "https://sourceforge.net/projects/bwbasic/", + source: "https://sourceforge.net/projects/bwbasic/files/bwbasic/", + }, + category: "general", + mode: "interpreted", + platform: [], + syntax: ["basic", "column", "whitespace"], + typing: "static", + paradigm: "imperative", + usage: [], + }, repl: "bwbasic", input: "PRINT 123 * 234", main: "main.bas", @@ -304,6 +520,21 @@ implement main0 () = () battlestar: { aliases: ["battlestarc", "bts"], name: "Battlestar", + info: { + year: 2014, + desc: "A different take on assembly, with the goal of creating tiny executables", + ext: "bts", + web: { + source: "https://github.com/xyproto/battlestar", + }, + category: "assembly", + mode: "compiled", + platform: [], + syntax: "assembly", + typing: "weak", + paradigm: "imperative", + usage: "personal", + }, main: "main.bts", run: "bts main.bts", template: `const message = "Hello, world!\n" @@ -339,6 +570,25 @@ end }, beatnik: { name: "Beatnik", + info: { + impl: "Cat's Eye Beatnik", + year: 2001, + desc: "Stack-based esoteric programming language created by Cliff L. Biffle", + ext: "beatnik", + web: { + wiki: "https://en.wikipedia.org/wiki/Beatnik_(programming_language)", + esolang: "https://esolangs.org/wiki/Beatnik", + home: "https://cliffle.com/esoterica/beatnik/", + source: "https://github.com/catseye/Beatnik", + }, + category: "esoteric", + mode: "interpreted", + platform: [], + syntax: [], + typing: "integer", + paradigm: "stack", + usage: [], + }, main: "main.beatnik", run: "beatnik main.beatnik", template: `Soars, larkspurs, rains. @@ -435,6 +685,26 @@ Nude pagoda careens. befunge: { aliases: ["be"], name: "Befunge", + info: { + impl: "amicloud Befunge-93", + version: "Befunge-93", + year: 1993, + desc: "Two-dimensional esoteric programming language invented in 1993 by Chris Pressey with the goal of being as difficult to compile as possible", + ext: ["be", "bf", "b93", "b98", "befunge"], + web: { + wiki: "https://en.wikipedia.org/wiki/Befunge", + esolang: "https://esolangs.org/wiki/Befunge", + home: "https://catseye.tc/article/Languages.md#befunge-93", + source: "https://github.com/amicloud/befunge93", + }, + category: "esoteric", + mode: "interpreted", + platform: [], + syntax: ["golf", "2d"], + typing: "integer", + paradigm: "stack", + usage: [], + }, main: "main.be", run: "befunge-repl main.be", template: `64+"!dlrow ,olleH">:#,_@ @@ -449,6 +719,25 @@ Nude pagoda careens. "lambda", ], name: "Binary Lambda Calculus", + info: { + year: 2004, + desc: "Minimal, pure functional programming language invented by John Tromp in 2004, based on a binary encoding of the untyped lambda calculus in De Bruijn index notation", + ext: "blc", + web: { + wiki: "https://en.wikipedia.org/wiki/Binary_combinatory_logic", + esolang: "https://esolangs.org/wiki/Binary_lambda_calculus", + home: "https://tromp.github.io/cl/Binary_lambda_calculus.html", + impl: "https://www.ioccc.org/2012/tromp/hint.html", + source: "https://www.ioccc.org/2012/tromp/tromp.c", + }, + category: "esoteric", + mode: "interpreted", + platform: [], + syntax: [], + typing: "lambda", + paradigm: "functional", + usage: [], + }, main: "main.blc", run: "cat main.blc | binary-to-text | tromp", template: `001010100100100001100101011011000110110001101111001011000010 @@ -458,6 +747,23 @@ Nude pagoda careens. boo: { aliases: ["booc"], name: "Boo", + info: { + year: 2003, + desc: "Object-oriented, statically typed, general-purpose programming language on Microsoft's Common Language Infrastructure", + ext: "boo", + web: { + wiki: "https://en.wikipedia.org/wiki/Boo_(programming_language)", + home: "https://boo-language.github.io/", + source: "https://github.com/boo-lang/boo", + }, + category: "general", + mode: "compiled", + platform: "clr", + syntax: ["python", "extensible", "whitespace"], + typing: ["static", "dynamic"], + paradigm: ["imperative", "oo"], + usage: [], + }, setup: `mkdir -p "$HOME/.local/share" && touch "$HOME/.local/share/booish_history"`, main: "main.boo", repl: "booish", @@ -469,6 +775,25 @@ Nude pagoda careens. brainf: { aliases: ["brainfuck", "bf"], name: "Brainf***", + info: { + impl: "Beef", + year: 1993, + desc: "Famous esoteric programming language created in 1993 by Urban Müller", + ext: ["b", "bf"], + web: { + wiki: "https://en.wikipedia.org/wiki/Brainfuck", + esolang: "https://esolangs.org/wiki/Brainfuck", + impl: "https://kiyuko.org/software/beef", + source: "https://github.com/andreabolognani/beef", + }, + category: "esoteric", + mode: "interpreted", + platform: "bf", + syntax: "golf", + typing: "integer", + paradigm: "turing", + usage: [], + }, repl: "brainf-repl", input: ">++>+[>++++[-<++++>]<<]> [>>+>+<<<-]>>>[<<<+>>>-]<<+>[<->[>++++++++++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>[-]++++++++[<++++++>-]>[<<+>>-]>[<<+>>-]<<]>]<[->>++++++++[<++++++>-]]<[.[-]<]<", @@ -517,9 +842,28 @@ Nude pagoda careens. c: { aliases: ["gcc", "clang", "h", "cc", "c99", "c11", "c18"], name: "C", + info: { + impl: "LLVM", + version: "C18", + year: 1972, + desc: "General-purpose, procedural computer programming language supporting structured programming, lexical variable scope, and recursion, with a static type system", + ext: ["c", "h"], + web: { + wiki: "https://en.wikipedia.org/wiki/C_(programming_language)", + impl: "https://llvm.org/", + source: "https://github.com/llvm/llvm-project", + }, + category: "general", + mode: "compiled", + platform: [], + syntax: "c", + typing: "static", + paradigm: "imperative", + usage: "popular", + }, monacoLang: "c", main: "main.c", - compile: "clang -Wall -Wextra main.c -o main", + compile: "clang -std=c17 -pedantic -Wall -Wextra main.c -o main", run: "./main", format: { run: "clang-format --assume-filename=format.c", @@ -567,9 +911,28 @@ int main() { "hxx", ], name: "C++", + info: { + impl: "LLVM", + version: "C++20", + year: 1985, + desc: "General-purpose programming language created by Bjarne Stroustrup as an extension of the C programming language", + ext: ["C", "cc", "cpp", "cxx", "c++", "h", "hh", "hpp", "hxx", "h++"], + web: { + wiki: "https://en.wikipedia.org/wiki/C%2B%2B", + impl: "https://llvm.org/", + source: "https://github.com/llvm/llvm-project", + }, + category: "general", + mode: "compiled", + platform: [], + syntax: "c", + typing: "static", + paradigm: ["functional", "imperative", "oo"], + usage: "popular", + }, monacoLang: "cpp", main: "main.cpp", - compile: "clang++ -Wall -Wextra main.cpp -o main", + compile: "clang++ -std=c++17 -pedantic -Wall -Wextra main.cpp -o main", run: "./main", format: { run: "clang-format --assume-filename=format.cpp", @@ -598,6 +961,21 @@ int main() { cat: { aliases: ["cat-language"], name: "Cat", + info: { + year: 2006, + desc: "Statically typed stack-based programming language in C#", + ext: "cat", + web: { + source: "https://github.com/cdiggins/cat-language", + }, + category: "pure", + mode: "interpreted", + platform: [], + syntax: "tokens", + typing: "static", + paradigm: "stack", + usage: [], + }, repl: "NODE_PATH=/opt/cat node /opt/cat/repl.js", input: "123 234 mul", main: "main.cat", @@ -608,6 +986,23 @@ int main() { }, ceylon: { name: "Ceylon", + info: { + year: 2011, + desc: "Object-oriented, strongly statically typed programming language with an emphasis on immutability, created by Red Hat", + ext: "ceylon", + web: { + wiki: "https://en.wikipedia.org/wiki/Ceylon_(programming_language)", + home: "https://ceylon-lang.org/", + source: "https://ceylon-lang.org/code/source/", + }, + category: "general", + mode: "compiled", + platform: "jvm", + syntax: "c", + typing: "static", + paradigm: ["imperative", "oo"], + usage: [], + }, main: "source/main.ceylon", run: `PATH="/usr/lib/jvm/java-8-openjdk-amd64/bin:$PATH" ceylon run --compile=force default`, template: `shared void run() { @@ -618,6 +1013,24 @@ int main() { }, chef: { name: "Chef", + info: { + impl: "Acme::Chef", + year: 2002, + desc: "Stack-based language where programs look like cooking recipes", + ext: "chef", + web: { + esolang: "https://esolangs.org/wiki/Chef", + home: "https://www.dangermouse.net/esoteric/chef.html", + source: "http://search.cpan.org/author/SMUELLER/Acme-Chef/", + }, + category: "esoteric", + mode: ["compiled", "interpreted"], + platform: [], + syntax: "text", + typing: "integer", + paradigm: "imperative", + usage: [], + }, main: "main.chef", run: "chef main.chef", hello: "Hello world!", @@ -700,8 +1113,25 @@ Refrigerate for 1 hour. `, }, clean: { - aliases: ["icl", "clm"], + aliases: ["icl", "clm", "dcl"], name: "Clean", + info: { + year: 1987, + desc: "General-purpose purely functional computer programming language", + ext: ["icl", "dcl", "abc"], + web: { + wiki: "https://en.wikipedia.org/wiki/Clean_(programming_language)", + home: "https://clean.cs.ru.nl/Clean", + source: "https://gitlab.science.ru.nl/clean-compiler-and-rts/compiler", + }, + category: "general", + mode: "compiled", + platform: [], + syntax: "haskell", + typing: "static", + paradigm: ["declarative", "functional"], + usage: [], + }, main: "main.icl", compile: "clm main -o main", run: "./main", @@ -719,6 +1149,24 @@ Start world clojure: { aliases: ["clj"], name: "Clojure", + info: { + impl: "Java Clojure", + year: 2007, + desc: "Modern, dynamic, and functional dialect of the Lisp programming language on the Java platform", + ext: ["clj", "cljc", "edn"], + web: { + wiki: "https://en.wikipedia.org/wiki/Clojure", + home: "https://clojure.org/", + source: "https://github.com/clojure/clojure", + }, + category: "general", + mode: "interpreted", + platform: "jvm", + syntax: ["lisp", "extensible"], + typing: "dynamic", + paradigm: ["declarative", "functional", "imperative", "oo"], + usage: [], + }, monacoLang: "clojure", repl: "clojure", input: "(* 123 234)", @@ -735,6 +1183,23 @@ Start world clojurescript: { aliases: ["cljs", "lumo"], name: "ClojureScript", + info: { + year: 2011, + desc: "Compiler for Clojure that targets JavaScript", + ext: "cljs", + web: { + wiki: "https://en.wikipedia.org/wiki/Clojure#Platforms", + home: "https://clojurescript.org/", + source: "https://github.com/clojure/clojurescript", + }, + category: "general", + mode: ["compiled", "interpreted"], + platform: "js", + syntax: ["lisp", "extensible"], + typing: ["dynamic", "weak"], + paradigm: ["declarative", "functional", "imperative", "oo"], + usage: [], + }, monacoLang: "clojure", repl: "lumo -r", input: "(* 123 234)", @@ -757,6 +1222,23 @@ Start world cmd: { aliases: ["bat", "batch", "wine"], name: "Cmd", + info: { + year: 1987, + desc: "Obsolete (but still default) command-line interpreter for Microsoft Windows", + ext: "bat", + web: { + wiki: "https://en.wikipedia.org/wiki/Cmd.exe", + home: "https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/windows-commands", + source: null, + }, + category: "shell", + mode: "interpreted", + platform: "windows", + syntax: "basic", + typing: "weak", + paradigm: "imperative", + usage: [], + }, monacoLang: "bat", setup: "shopt -s dotglob; cp -R /opt/cmd/home-template/* ./", repl: "wine cmd", @@ -772,8 +1254,27 @@ Start world timeout: 30, }, cobol: { - aliases: ["cbl", "cobc"], + aliases: ["cbl", "cob", "cobc", "cpy"], name: "COBOL", + info: { + impl: "GnuCOBOL", + version: "COBOL 2014", + year: 1959, + desc: "Compiled English-like computer programming language designed for business use", + ext: ["cbl", "cob", "cpy"], + web: { + wiki: "https://en.wikipedia.org/wiki/COBOL", + impl: "https://sourceforge.net/projects/gnucobol/", + source: "https://sourceforge.net/p/gnucobol/_list/svn", + }, + category: "general", + mode: "compiled", + platform: [], + syntax: "basic", + typing: "weak", + paradigm: ["imperative", "oo"], + usage: "popular", + }, main: "main.cbl", compile: "cobc -free -x main.cbl -o main", run: "./main", @@ -785,8 +1286,25 @@ PROCEDURE DIVISION. `, }, coffeescript: { - aliases: ["coffee"], + aliases: ["coffee", "litcoffee"], name: "CoffeeScript", + info: { + year: 2009, + desc: "Compile-to-JavaScript programming language adding syntactic sugar inspired by Ruby, Python and Haskell in an effort to enhance JavaScript's brevity and readability", + ext: ["coffee", "litcoffee"], + web: { + wiki: "https://en.wikipedia.org/wiki/CoffeeScript", + home: "https://coffeescript.org/", + source: "https://github.com/jashkenas/coffeescript", + }, + category: "general", + mode: ["interpreted", "compiled"], + platform: "js", + syntax: ["c", "haskell"], + typing: "weak", + paradigm: ["declarative", "functional", "imperative"], + usage: [], + }, monacoLang: "coffee", repl: "coffee", main: "main.coffee", @@ -804,6 +1322,25 @@ require("/usr/lib/node_modules/coffeescript/repl").start() commonlisp: { aliases: ["lisp", "sbcl"], name: "Common Lisp", + info: { + impl: "SBCL", + year: 1984, + desc: "Modern, multi-paradigm, high-performance, compiled, ANSI-standardized, most prominent (along with Scheme) descendant of the Lisp family", + ext: ["lisp", "lsp", "l", "cl", "fasl"], + web: { + wiki: "https://en.wikipedia.org/wiki/Common_Lisp", + home: "https://common-lisp.net/", + impl: "http://www.sbcl.org/", + source: "https://sourceforge.net/p/sbcl/sbcl/ci/master/tree/", + }, + category: "general", + mode: ["compiled", "interpreted"], + platform: [], + syntax: ["lisp", "extensible"], + typing: ["static", "dynamic"], + paradigm: ["declarative", "functional", "imperative", "oo"], + usage: [], + }, repl: "rlwrap sbcl", input: "(* 123 234)", main: "main.lisp", @@ -817,6 +1354,25 @@ require("/usr/lib/node_modules/coffeescript/repl").start() confluence: { aliases: ["jira", "atlassian"], name: "Confluence", + info: { + impl: "Pandoc", + year: 2004, + desc: "Markup format for a popular web-based corporate wiki developed by Atlassian", + ext: [], + web: { + wiki: "https://en.wikipedia.org/wiki/Confluence_(software)", + home: "https://confluence.atlassian.com/doc/confluence-wiki-markup-251003035.html", + impl: "https://pandoc.org/", + source: "https://github.com/jgm/pandoc", + }, + category: "markup", + mode: [], + platform: [], + syntax: "text", + typing: [], + paradigm: [], + usage: [], + }, main: "main.txt", compile: "pandoc main.txt -f jira -o main.html", run: "prettier --no-config main.html", @@ -826,6 +1382,23 @@ require("/usr/lib/node_modules/coffeescript/repl").start() crystal: { aliases: ["cr"], name: "Crystal", + info: { + year: 2014, + desc: "General-purpose, object-oriented programming language with syntax inspired by the language Ruby", + ext: "cr", + web: { + wiki: "https://en.wikipedia.org/wiki/Crystal_(programming_language)", + home: "https://crystal-lang.org/", + source: "https://github.com/crystal-lang/crystal", + }, + category: "general", + mode: "compiled", + platform: [], + syntax: "pascal", + typing: "static", + paradigm: "oo", + usage: [], + }, main: "main.cr", run: "crystal main.cr", template: `puts "Hello, world!" @@ -835,6 +1408,7 @@ require("/usr/lib/node_modules/coffeescript/repl").start() csharp: { aliases: ["cs", "mcs"], name: "C#", + // popular monacoLang: "csharp", main: "main.cs", compile: "mcs main.cs", @@ -906,6 +1480,7 @@ void main() }, dart: { name: "Dart", + // popular monacoLang: "dart", main: "main.dart", run: "dart main.dart", @@ -1316,6 +1891,7 @@ int main() { go: { aliases: ["golang"], name: "Go", + // popular monacoLang: "go", main: "main.go", compile: "go build main.go", @@ -1360,6 +1936,7 @@ func main() { }, groovy: { name: "Groovy", + // popular repl: `JAVA_OPTS="-Djava.util.prefs.systemRoot=$PWD/.java -Djava.util.prefs.userRoot=$PWD/.java/.userPrefs" groovysh`, main: "main.groovy", run: `JAVA_OPTS="-Djava.util.prefs.systemRoot=$PWD/.java -Djava.util.prefs.userRoot=$PWD/.java/.userPrefs" groovysh main.groovy`, @@ -1394,6 +1971,7 @@ function main(): void { haskell: { aliases: ["ghc", "ghci", "hs"], name: "Haskell", + // popular repl: "rm -f .ghci && ghci", main: "Main.hs", run: "(echo ':load Main' && echo 'main') > .ghci && ghci", @@ -1631,6 +2209,7 @@ PLEASE GIVE UP java: { aliases: ["javac"], name: "Java", + // popular monacoLang: "java", main: "Main.java", compile: "javac Main.java", @@ -1795,6 +2374,7 @@ PLEASE GIVE UP javascript: { aliases: ["node", "js", "web", "jsx", "v8", "closure", "nodejs"], name: "Node.js", + // popular monacoLang: "javascript", repl: "node", main: "main.js", @@ -1973,6 +2553,7 @@ PLEASE GIVE UP julia: { aliases: ["jl"], name: "Julia", + // popular repl: "julia", main: "main.jl", run: "julia -L main.jl", @@ -2012,6 +2593,7 @@ PLEASE GIVE UP kotlin: { aliases: ["kts", "kotlinc"], name: "Kotlin", + // popular monacoLang: "kotlin", repl: `JAVA_OPTS="-Duser.home=$PWD" kotlinc`, main: "main.kts", @@ -2138,6 +2720,7 @@ KTHXBYE }, lua: { name: "Lua", + // popular monacoLang: "lua", repl: "lua", main: "main.lua", @@ -2353,6 +2936,7 @@ END Main. objectivec: { aliases: ["objc", "gnustep"], name: "Objective-C", + // popular monacoLang: "objective-c", main: "main.m", compile: @@ -2443,6 +3027,7 @@ print_string "Hello, world!\\n" octave: { aliases: ["matlab", "m", "mathworks"], name: "Octave", + // popular repl: "octave", main: "main.m", run: "octave --persist main.m", @@ -2591,6 +3176,7 @@ main() { perl: { aliases: ["pl", "repl"], name: "Perl", + // popular monacoLang: "perl", repl: "re.pl", main: "main.pl", @@ -2610,6 +3196,7 @@ main() { php: { aliases: ["phpcli"], name: "PHP", + // popular monacoLang: "php", repl: "php -a", input: "print 123 * 234;", @@ -2785,6 +3372,25 @@ main = do python: { aliases: ["python3", "python2", "py"], name: "Python", + info: { + impl: "CPython", + version: "Python 3", + year: 1990, + desc: "Interpreted, high-level, general-purpose programming language", + ext: ["py", "pyi", "pyc", "pyd", "pyo", "pyw", "pyz"], + web: { + wiki: "https://en.wikipedia.org/wiki/Python_(programming_language)", + source: "https://github.com/python/cpython", + home: "https://www.python.org/", + }, + category: "general", + mode: "interpreted", + platform: "python", + syntax: ["python", "whitespace"], + typing: "dynamic", + paradigm: ["functional", "imperative", "oo"], + usage: "popular", + }, monacoLang: "python", repl: "python3 -u", main: "main.py", @@ -2855,6 +3461,7 @@ main = do r: { aliases: ["rlang"], name: "R", + // popular monacoLang: "r", repl: "R", main: ".Rprofile", @@ -3033,6 +3640,7 @@ Hello, world! ruby: { aliases: ["irb", "rb"], name: "Ruby", + // popular monacoLang: "ruby", repl: "irb", main: "main.rb", @@ -3065,6 +3673,7 @@ binding_irb.run(IRB.conf) rust: { aliases: ["rs", "rustc"], name: "Rust", + // popular monacoLang: "rust", main: "main.rs", compile: "rustc main.rs", @@ -3100,6 +3709,7 @@ binding_irb.run(IRB.conf) }, scala: { name: "Scala", + // popular repl: "scala", main: "main.scala", run: "scala -i main.scala", @@ -3407,6 +4017,7 @@ END swift: { aliases: ["swiftc"], name: "Swift", + // popular monacoLang: "swift", main: "main.swift", compile: "swiftc main.swift", @@ -3540,6 +4151,7 @@ a typescript: { aliases: ["ts", "tsnode", "tsc"], name: "TypeScript", + // popular monacoLang: "typescript", repl: "ts-node", main: "main.ts", @@ -3868,8 +4480,9 @@ endmodule `, }, visualbasic: { - aliases: ["vbasic", "vb", "vbnc"], + aliases: ["vbasic", "vb", "vbnc", "vba"], name: "Visual Basic", + // popular monacoLang: "vb", main: "main.vb", compile: "vbnc main.vb",