From 7afcfa727b5ca1fef26eb25d8b6e017b049e8b42 Mon Sep 17 00:00:00 2001
From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com>
Date: Sun, 5 Mar 2023 11:56:46 +0100
Subject: [PATCH] implement more
---
assets/index.html | 101 +++++++++++++++++++++++++++++++++++-----------
src/bootstrap.rs | 24 +++++++++++
src/main.rs | 47 +++++++++++++++++----
3 files changed, 142 insertions(+), 30 deletions(-)
diff --git a/assets/index.html b/assets/index.html
index 285196f..445c173 100644
--- a/assets/index.html
+++ b/assets/index.html
@@ -28,6 +28,21 @@
display: flex;
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);
+ }
@@ -36,7 +51,14 @@
-
+
+
+
+
@@ -45,33 +67,66 @@
diff --git a/src/bootstrap.rs b/src/bootstrap.rs
index aadcb56..294199b 100644
--- a/src/bootstrap.rs
+++ b/src/bootstrap.rs
@@ -3,6 +3,7 @@ use std::{path::Path, pin::Pin, process::Stdio};
use axum::extract::ws::{self, WebSocket};
use color_eyre::{eyre::Context, Result};
use futures::{stream::SplitSink, SinkExt};
+use serde::Serialize;
use tokio::{
io::{AsyncRead, AsyncReadExt},
process::{Child, Command},
@@ -36,6 +37,29 @@ pub async fn build_a_compiler(
Ok(())
}
+#[derive(Debug, Clone, Serialize)]
+pub enum Compiler {
+ Bootstrap,
+ Dev,
+ Dist,
+}
+
+pub async fn list_compilers(entrypoint: &Path) -> Vec {
+ 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(
mut stdout: Pin>,
mut stderr: Pin>,
diff --git a/src/main.rs b/src/main.rs
index ebe1bfa..1d3172e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -5,15 +5,16 @@ use std::{net::SocketAddr, path::PathBuf};
use axum::{
extract::{
- ws::{Message, WebSocket},
+ ws::{CloseFrame, Message, WebSocket},
ConnectInfo, TypedHeader, WebSocketUpgrade,
},
response::IntoResponse,
routing::get,
Router,
};
-use futures::stream::StreamExt;
-use serde::Serialize;
+use bootstrap::Compiler;
+use futures::{stream::StreamExt, SinkExt};
+use serde::{Deserialize, Serialize};
use tower_http::{
services::ServeDir,
trace::{DefaultMakeSpan, TraceLayer},
@@ -94,6 +95,13 @@ async fn ws_handler(
enum ServerMessage<'a> {
Stdout(&'a str),
Stderr(&'a str),
+ AvailableCompilers(Vec),
+}
+
+#[derive(Debug, Clone, Deserialize)]
+enum ClientMessage {
+ Compile,
+ ListCompilers,
}
impl<'a> From> for Message {
@@ -136,10 +144,35 @@ async fn handle_socket(mut socket: WebSocket, who: SocketAddr, entrypoint: PathB
while let Some(Ok(msg)) = receiver.next().await {
info!(?msg);
- if let Message::Text(msg) = msg {
- if msg == "bootstrap me" {
- if let Err(err) = bootstrap::build_a_compiler(&mut sender, &entrypoint).await {
- error!(%err);
+ if let Message::Text(msg_str) = msg {
+ let msg = serde_json::from_str::(&msg_str);
+
+ match msg {
+ Ok(ClientMessage::Compile) => {
+ if let Err(err) = bootstrap::build_a_compiler(&mut sender, &entrypoint).await {
+ 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);
+ }
}
}
}