async deploy
This commit is contained in:
Generated
+36
@@ -1153,6 +1153,7 @@ dependencies = [
|
|||||||
"clipboard-rs",
|
"clipboard-rs",
|
||||||
"eframe",
|
"eframe",
|
||||||
"egui_ltreeview",
|
"egui_ltreeview",
|
||||||
|
"futures",
|
||||||
"markdown",
|
"markdown",
|
||||||
"rfd",
|
"rfd",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -1211,6 +1212,21 @@ dependencies = [
|
|||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures"
|
||||||
|
version = "0.3.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
|
||||||
|
dependencies = [
|
||||||
|
"futures-channel",
|
||||||
|
"futures-core",
|
||||||
|
"futures-executor",
|
||||||
|
"futures-io",
|
||||||
|
"futures-sink",
|
||||||
|
"futures-task",
|
||||||
|
"futures-util",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-channel"
|
name = "futures-channel"
|
||||||
version = "0.3.31"
|
version = "0.3.31"
|
||||||
@@ -1218,6 +1234,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
|
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
"futures-sink",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1226,6 +1243,17 @@ version = "0.3.31"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
|
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-executor"
|
||||||
|
version = "0.3.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"futures-task",
|
||||||
|
"futures-util",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-io"
|
name = "futures-io"
|
||||||
version = "0.3.31"
|
version = "0.3.31"
|
||||||
@@ -1256,6 +1284,12 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-sink"
|
||||||
|
version = "0.3.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-task"
|
name = "futures-task"
|
||||||
version = "0.3.31"
|
version = "0.3.31"
|
||||||
@@ -1268,9 +1302,11 @@ version = "0.3.31"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
|
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-io",
|
"futures-io",
|
||||||
"futures-macro",
|
"futures-macro",
|
||||||
|
"futures-sink",
|
||||||
"futures-task",
|
"futures-task",
|
||||||
"memchr",
|
"memchr",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ tokio = { version = "1.47.1", features = ["full"] }
|
|||||||
tinyrand = "0.5.0"
|
tinyrand = "0.5.0"
|
||||||
clipboard-rs = "0.3.0"
|
clipboard-rs = "0.3.0"
|
||||||
tempfile = "3.23.0"
|
tempfile = "3.23.0"
|
||||||
|
futures = "0.3.31"
|
||||||
|
|
||||||
[package.metadata.bundle]
|
[package.metadata.bundle]
|
||||||
identifier = "org.geekfu.fleen"
|
identifier = "org.geekfu.fleen"
|
||||||
|
|||||||
+16
-4
@@ -4,8 +4,10 @@ use std::path::{Path, PathBuf};
|
|||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use clipboard_rs::Clipboard;
|
use clipboard_rs::Clipboard;
|
||||||
use clipboard_rs::common::RustImage;
|
use clipboard_rs::common::RustImage;
|
||||||
|
use tempfile::TempDir;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use tinyrand::{Rand, Seeded};
|
use tinyrand::{Rand, Seeded};
|
||||||
|
use tokio::task::JoinHandle;
|
||||||
use crate::fleen_app::FleenError::{RootDirNonexistence, RootDirPopulated, TargetDir};
|
use crate::fleen_app::FleenError::{RootDirNonexistence, RootDirPopulated, TargetDir};
|
||||||
use crate::fleen_app::TreeEntry::{CloseDir, Dir};
|
use crate::fleen_app::TreeEntry::{CloseDir, Dir};
|
||||||
use crate::renderer;
|
use crate::renderer;
|
||||||
@@ -284,7 +286,7 @@ impl FleenApp {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_and_deploy(&self) -> Result<String, FleenError> {
|
pub fn build_and_deploy(&self) -> Result<JoinHandle<Result<String, FleenError>>, FleenError> {
|
||||||
let output_dir = tempfile::tempdir().map_err(|_| TargetDir)?;
|
let output_dir = tempfile::tempdir().map_err(|_| TargetDir)?;
|
||||||
self.build_site(&output_dir.path())?; // Attempt to build the site somewhere
|
self.build_site(&output_dir.path())?; // Attempt to build the site somewhere
|
||||||
|
|
||||||
@@ -294,10 +296,20 @@ impl FleenApp {
|
|||||||
} else {
|
} else {
|
||||||
let mut command = Command::new(deploy_script_path);
|
let mut command = Command::new(deploy_script_path);
|
||||||
command.current_dir(output_dir.path()); // don't consume dir!
|
command.current_dir(output_dir.path()); // don't consume dir!
|
||||||
match command.output() {
|
Ok(self.build_and_deploy_inner(output_dir, command))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_and_deploy_inner(&self, output_dir: TempDir, mut command: Command) -> JoinHandle<Result<String, FleenError>> {
|
||||||
|
tokio::spawn(async move {
|
||||||
|
let output = command.output();
|
||||||
|
let status = command.status().unwrap();
|
||||||
|
output_dir.close().map_err(|e| FleenError::Io(e))?;
|
||||||
|
|
||||||
|
match output {
|
||||||
Ok(output) => {
|
Ok(output) => {
|
||||||
let output = String::from_utf8(output.stdout).unwrap_or("Error reading deploy script output".to_string());
|
let output = String::from_utf8(output.stdout).unwrap_or("Error reading deploy script output".to_string());
|
||||||
if command.status().unwrap().success() {
|
if status.success() {
|
||||||
Ok(output)
|
Ok(output)
|
||||||
} else {
|
} else {
|
||||||
Err(FleenError::DeployError(output))
|
Err(FleenError::DeployError(output))
|
||||||
@@ -307,7 +319,7 @@ impl FleenApp {
|
|||||||
Err(FleenError::DeployError(e.to_string()))
|
Err(FleenError::DeployError(e.to_string()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+35
-12
@@ -4,6 +4,8 @@ mod server;
|
|||||||
mod ui_ext;
|
mod ui_ext;
|
||||||
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::task::Waker;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use eframe::egui::{Button, Context, Id, RichText};
|
use eframe::egui::{Button, Context, Id, RichText};
|
||||||
use eframe::{egui, Frame};
|
use eframe::{egui, Frame};
|
||||||
@@ -37,25 +39,27 @@ struct TempMessage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct FleenUi {
|
struct FleenUi {
|
||||||
app: Option<FleenApp>,
|
app: Option<Arc<FleenApp>>,
|
||||||
error: Option<FleenError>,
|
error: Option<FleenError>,
|
||||||
message: Option<String>,
|
message: Option<String>,
|
||||||
selected_file: Option<String>,
|
selected_file: Option<String>,
|
||||||
dialog_mode: Option<DialogMode>,
|
dialog_mode: Option<DialogMode>,
|
||||||
server_handle: Option<JoinHandle<()>>,
|
server_handle: Option<JoinHandle<()>>,
|
||||||
server_port: String,
|
server_port: String,
|
||||||
image_message: Option<TempMessage>
|
deploy_handle: Option<JoinHandle<Result<String, FleenError>>>,
|
||||||
|
image_message: Option<TempMessage>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for FleenUi {
|
impl Default for FleenUi {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
app: None,
|
app: None.into(),
|
||||||
error: None,
|
error: None,
|
||||||
message: None,
|
message: None,
|
||||||
selected_file: None,
|
selected_file: None,
|
||||||
dialog_mode: None,
|
dialog_mode: None,
|
||||||
server_handle: None,
|
server_handle: None,
|
||||||
|
deploy_handle: None,
|
||||||
image_message: None,
|
image_message: None,
|
||||||
server_port: "3000".to_string(),
|
server_port: "3000".to_string(),
|
||||||
}
|
}
|
||||||
@@ -71,7 +75,7 @@ impl FleenUi {
|
|||||||
if ui.add_fill_width(Button::blue("Open site...")).clicked() && let Some(path) = rfd::FileDialog::new().pick_folder() {
|
if ui.add_fill_width(Button::blue("Open site...")).clicked() && let Some(path) = rfd::FileDialog::new().pick_folder() {
|
||||||
match FleenApp::open(path.clone()) {
|
match FleenApp::open(path.clone()) {
|
||||||
Ok(app) => {
|
Ok(app) => {
|
||||||
self.app = Some(app);
|
self.app = Some(app.into());
|
||||||
}
|
}
|
||||||
Err(err) => { self.error = Some(err) }
|
Err(err) => { self.error = Some(err) }
|
||||||
}
|
}
|
||||||
@@ -80,7 +84,7 @@ impl FleenUi {
|
|||||||
if ui.add_fill_width(Button::green("New site...")).clicked() && let Some(path) = rfd::FileDialog::new().pick_folder() {
|
if ui.add_fill_width(Button::green("New site...")).clicked() && let Some(path) = rfd::FileDialog::new().pick_folder() {
|
||||||
match FleenApp::create(path.clone()) {
|
match FleenApp::create(path.clone()) {
|
||||||
Ok(app) => {
|
Ok(app) => {
|
||||||
self.app = Some(app);
|
self.app = Some(app.into());
|
||||||
self.server_handle = Some(tokio::spawn(start_server(path, 3000)))
|
self.server_handle = Some(tokio::spawn(start_server(path, 3000)))
|
||||||
}
|
}
|
||||||
Err(err) => { self.error = Some(err) }
|
Err(err) => { self.error = Some(err) }
|
||||||
@@ -105,16 +109,15 @@ impl FleenUi {
|
|||||||
});
|
});
|
||||||
ui.column(width, |ui| self.server_controls(ui));
|
ui.column(width, |ui| self.server_controls(ui));
|
||||||
ui.column(width, |ui| {
|
ui.column(width, |ui| {
|
||||||
if ui.add_fill_width(Button::green("Build and deploy")).clicked() {
|
ui.add_enabled_ui(self.deploy_handle.is_none(), |ui| {
|
||||||
match self.app.as_ref().unwrap().build_and_deploy() {
|
if ui.add_fill_width(Button::green("Build and deploy")).clicked() {
|
||||||
Ok(output) => { self.message = Some(format!("Site built and deployed:\n\n{}", output)) }
|
self.build_and_deploy();
|
||||||
Err(err) => { self.error = Some(err) }
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
if ui.add_fill_width(Button::blue("Build site...")).clicked() &&
|
if ui.add_fill_width(Button::blue("Build site...")).clicked() &&
|
||||||
let Some(path) = rfd::FileDialog::new().pick_folder() {
|
let Some(path) = rfd::FileDialog::new().pick_folder() {
|
||||||
match self.app.as_ref().unwrap().build_site(&path) {
|
match self.app.as_ref().as_ref().unwrap().build_site(&path) {
|
||||||
Ok(()) => { self.message = Some("Site built successfully".to_string()) }
|
Ok(()) => { self.message = Some("Site built successfully".to_string()) }
|
||||||
Err(err) => { self.error = Some(err) }
|
Err(err) => { self.error = Some(err) }
|
||||||
}
|
}
|
||||||
@@ -131,12 +134,19 @@ impl FleenUi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn build_and_deploy(&mut self) {
|
||||||
|
match self.app.as_ref().unwrap().build_and_deploy() {
|
||||||
|
Ok(handle) => { self.deploy_handle = Some(handle) },
|
||||||
|
Err(err) => { self.error = Some(err) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn tree_view(&mut self, ui: &mut egui::Ui) {
|
fn tree_view(&mut self, ui: &mut egui::Ui) {
|
||||||
let tv = egui_ltreeview::TreeView::new(Id::from("tree"))
|
let tv = egui_ltreeview::TreeView::new(Id::from("tree"))
|
||||||
.allow_multi_selection(false)
|
.allow_multi_selection(false)
|
||||||
.allow_drag_and_drop(false);
|
.allow_drag_and_drop(false);
|
||||||
let (_, actions) = tv.show(ui, |builder| {
|
let (_, actions) = tv.show(ui, |builder| {
|
||||||
for entry in self.app.as_mut().unwrap().file_tree_entries().into_iter() {
|
for entry in self.app.clone().as_mut().unwrap().file_tree_entries().into_iter() {
|
||||||
match entry {
|
match entry {
|
||||||
TreeEntry::File(p) => builder.leaf(id_for_path(&p), label_for_path(&p)),
|
TreeEntry::File(p) => builder.leaf(id_for_path(&p), label_for_path(&p)),
|
||||||
TreeEntry::Dir(p) => { builder.dir(id_for_path(&p), label_for_path(&p)); },
|
TreeEntry::Dir(p) => { builder.dir(id_for_path(&p), label_for_path(&p)); },
|
||||||
@@ -351,6 +361,19 @@ impl FleenUi {
|
|||||||
|
|
||||||
impl eframe::App for FleenUi {
|
impl eframe::App for FleenUi {
|
||||||
fn update(&mut self, ctx: &Context, _frame: &mut Frame) {
|
fn update(&mut self, ctx: &Context, _frame: &mut Frame) {
|
||||||
|
if let Some(handle) = self.deploy_handle.as_ref() {
|
||||||
|
if handle.is_finished() {
|
||||||
|
let handle = self.deploy_handle.take().unwrap();
|
||||||
|
let result = futures::executor::block_on(async move { handle.await });
|
||||||
|
match result {
|
||||||
|
Err(e) => { self.error = Some(FleenError::DeployError(e.to_string())) }
|
||||||
|
Ok(Err(e)) => { self.error = Some(e) }
|
||||||
|
Ok(Ok(s)) => { self.message = Some(s) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.request_repaint_after(Duration::from_millis(100));
|
||||||
|
}
|
||||||
|
|
||||||
match &mut self.app {
|
match &mut self.app {
|
||||||
None => self.site_chooser(ctx),
|
None => self.site_chooser(ctx),
|
||||||
Some(_) => self.display(ctx)
|
Some(_) => self.display(ctx)
|
||||||
|
|||||||
Reference in New Issue
Block a user