implement more

This commit is contained in:
nora 2023-03-05 11:56:46 +01:00
parent c5c87feef2
commit 7afcfa727b
3 changed files with 142 additions and 30 deletions

View file

@ -28,6 +28,21 @@
display: flex; display: flex;
margin-bottom: 10px; margin-bottom: 10px;
} }
#compilers-wrapper {
display: flex;
height: 100px;
}
.compiler {
height: 70px;
width: 150px;
display: flex;
align-items: center;
justify-content: center;
border: 1px black solid;
background: rgb(185, 210, 181);
}
</style> </style>
</head> </head>
<body> <body>
@ -36,7 +51,14 @@
<div class="source-box"><div class="source-box-text">LIBRARY</div></div> <div class="source-box"><div class="source-box-text">LIBRARY</div></div>
</div> </div>
<button onclick="startWs()">build me a compiler</button> <div id="compilers-wrapper"></div>
<button class="compile-action" disabled onclick="compile()">
build me a compiler
</button>
<button class="compile-action" disabled onclick="updateCompilers()">
update compilers
</button>
<br /> <br />
<br /> <br />
@ -45,18 +67,21 @@
<textarea id="stderr" rows="30" cols="80"></textarea> <textarea id="stderr" rows="30" cols="80"></textarea>
<script> <script>
function startWs() {
console.log("starting ws");
const stdout = document.getElementById("stdout"); const stdout = document.getElementById("stdout");
const stderr = document.getElementById("stderr"); const stderr = document.getElementById("stderr");
stdout.value = ""; const compilersWrapper = document.getElementById("compilers-wrapper");
stderr.value = "";
const compileActions = document.querySelectorAll(".compile-action");
const ws = new WebSocket("ws://localhost:3000/ws"); const ws = new WebSocket("ws://localhost:3000/ws");
ws.addEventListener("open", () => { ws.addEventListener("open", () => {
ws.send("bootstrap me"); for (elem of compileActions) {
elem.disabled = false;
}
ws.send(JSON.stringify("ListCompilers"));
}); });
ws.addEventListener("message", (event) => { ws.addEventListener("message", (event) => {
@ -71,7 +96,37 @@
if ("Stderr" in msg) { if ("Stderr" in msg) {
stdout.value += msg.Stderr; stdout.value += msg.Stderr;
} }
if ("AvailableCompilers" in msg) {
console.log("compilers");
const compilers = msg.AvailableCompilers;
compilersWrapper.innerHTML = "";
for (const compiler of compilers) {
const inner = document.createElement("div");
inner.innerText = compiler;
inner.classList.add("source-box-text");
const elem = document.createElement("div");
elem.classList.add("compiler");
elem.appendChild(inner);
compilersWrapper.appendChild(elem);
}
}
}); });
function compile() {
console.log("compiling");
ws.send(JSON.stringify("Compile"));
stdout.value = "";
stderr.value = "";
}
function updateCompilers() {
console.log("list compilers");
ws.send(JSON.stringify("ListCompilers"));
} }
</script> </script>
</body> </body>

View file

@ -3,6 +3,7 @@ use std::{path::Path, pin::Pin, process::Stdio};
use axum::extract::ws::{self, WebSocket}; use axum::extract::ws::{self, WebSocket};
use color_eyre::{eyre::Context, Result}; use color_eyre::{eyre::Context, Result};
use futures::{stream::SplitSink, SinkExt}; use futures::{stream::SplitSink, SinkExt};
use serde::Serialize;
use tokio::{ use tokio::{
io::{AsyncRead, AsyncReadExt}, io::{AsyncRead, AsyncReadExt},
process::{Child, Command}, process::{Child, Command},
@ -36,6 +37,29 @@ pub async fn build_a_compiler(
Ok(()) Ok(())
} }
#[derive(Debug, Clone, Serialize)]
pub enum Compiler {
Bootstrap,
Dev,
Dist,
}
pub async fn list_compilers(entrypoint: &Path) -> Vec<Compiler> {
let mut compilers = vec![Compiler::Bootstrap];
let build = entrypoint.parent().unwrap().join("build/host");
if let Ok(true) = tokio::fs::try_exists(build.join("stage1").join("bin").join("rustc")).await {
compilers.push(Compiler::Dev);
}
if let Ok(true) = tokio::fs::try_exists(build.join("stage2").join("bin").join("rustc")).await {
compilers.push(Compiler::Dist);
}
compilers
}
async fn handle_stdouts( async fn handle_stdouts(
mut stdout: Pin<Box<impl AsyncRead>>, mut stdout: Pin<Box<impl AsyncRead>>,
mut stderr: Pin<Box<impl AsyncRead>>, mut stderr: Pin<Box<impl AsyncRead>>,

View file

@ -5,15 +5,16 @@ use std::{net::SocketAddr, path::PathBuf};
use axum::{ use axum::{
extract::{ extract::{
ws::{Message, WebSocket}, ws::{CloseFrame, Message, WebSocket},
ConnectInfo, TypedHeader, WebSocketUpgrade, ConnectInfo, TypedHeader, WebSocketUpgrade,
}, },
response::IntoResponse, response::IntoResponse,
routing::get, routing::get,
Router, Router,
}; };
use futures::stream::StreamExt; use bootstrap::Compiler;
use serde::Serialize; use futures::{stream::StreamExt, SinkExt};
use serde::{Deserialize, Serialize};
use tower_http::{ use tower_http::{
services::ServeDir, services::ServeDir,
trace::{DefaultMakeSpan, TraceLayer}, trace::{DefaultMakeSpan, TraceLayer},
@ -94,6 +95,13 @@ async fn ws_handler(
enum ServerMessage<'a> { enum ServerMessage<'a> {
Stdout(&'a str), Stdout(&'a str),
Stderr(&'a str), Stderr(&'a str),
AvailableCompilers(Vec<Compiler>),
}
#[derive(Debug, Clone, Deserialize)]
enum ClientMessage {
Compile,
ListCompilers,
} }
impl<'a> From<ServerMessage<'a>> for Message { impl<'a> From<ServerMessage<'a>> for Message {
@ -136,12 +144,37 @@ async fn handle_socket(mut socket: WebSocket, who: SocketAddr, entrypoint: PathB
while let Some(Ok(msg)) = receiver.next().await { while let Some(Ok(msg)) = receiver.next().await {
info!(?msg); info!(?msg);
if let Message::Text(msg) = msg { if let Message::Text(msg_str) = msg {
if msg == "bootstrap me" { let msg = serde_json::from_str::<ClientMessage>(&msg_str);
match msg {
Ok(ClientMessage::Compile) => {
if let Err(err) = bootstrap::build_a_compiler(&mut sender, &entrypoint).await { if let Err(err) = bootstrap::build_a_compiler(&mut sender, &entrypoint).await {
error!(%err); error!(%err);
} }
} }
Ok(ClientMessage::ListCompilers) => {
let compilers = bootstrap::list_compilers(&entrypoint).await;
if let Err(err) = sender
.send(ServerMessage::AvailableCompilers(compilers).into())
.await
{
error!(%err);
}
}
Err(err) => {
error!(?err, ?msg_str, "invalid client message");
if let Err(err) = sender
.send(Message::Close(Some(CloseFrame {
code: 0,
reason: "invalid message, you naughty".into(),
})))
.await
{
error!(%err);
}
}
}
} }
} }