Compare commits
2 commits
4d19f9e98f
...
76b6eb3903
Author | SHA1 | Date | |
---|---|---|---|
76b6eb3903 | |||
c965586537 |
14 changed files with 133 additions and 27 deletions
|
@ -18,21 +18,21 @@ jobs:
|
|||
uses: actions/checkout@v4
|
||||
|
||||
- name: Format
|
||||
uses: https://git.kemitix.net/kemitix/rust@v1.80.0-2
|
||||
uses: https://git.kemitix.net/kemitix/rust@v1.80.1-1
|
||||
with:
|
||||
args: cargo fmt --all -- --check
|
||||
args: cargo hack fmt --feature-powerset --all -- --check
|
||||
|
||||
- name: Clippy
|
||||
uses: https://git.kemitix.net/kemitix/rust@v1.80.0-2
|
||||
uses: https://git.kemitix.net/kemitix/rust@v1.80.1-1
|
||||
with:
|
||||
args: cargo clippy
|
||||
args: cargo hack clippy --feature-powerset
|
||||
|
||||
- name: Build
|
||||
uses: https://git.kemitix.net/kemitix/rust@v1.80.0-2
|
||||
uses: https://git.kemitix.net/kemitix/rust@v1.80.1-1
|
||||
with:
|
||||
args: cargo build
|
||||
args: cargo hack build --feature-powerset
|
||||
|
||||
- name: Test
|
||||
uses: https://git.kemitix.net/kemitix/rust@v1.80.0-2
|
||||
uses: https://git.kemitix.net/kemitix/rust@v1.80.1-1
|
||||
with:
|
||||
args: cargo test
|
||||
args: cargo hack test --feature-powerset
|
||||
|
|
|
@ -12,7 +12,7 @@ keywords = { workspace = true }
|
|||
categories = { workspace = true }
|
||||
|
||||
[features]
|
||||
default = ["forgejo", "github", "tui"]
|
||||
default = ["forgejo", "github"]
|
||||
forgejo = ["git-next-forge-forgejo"]
|
||||
github = ["git-next-forge-github"]
|
||||
tui = ["ratatui"]
|
||||
|
|
|
@ -38,6 +38,7 @@ enum Server {
|
|||
Init,
|
||||
Start {
|
||||
/// Display a UI (experimental)
|
||||
#[cfg(feature = "tui")]
|
||||
#[arg(long, required = false)]
|
||||
ui: bool,
|
||||
},
|
||||
|
@ -57,6 +58,12 @@ fn main() -> Result<()> {
|
|||
Server::Init => {
|
||||
server::init(&fs)?;
|
||||
}
|
||||
#[cfg(not(feature = "tui"))]
|
||||
Server::Start {} => {
|
||||
let sleep_duration = std::time::Duration::from_secs(10);
|
||||
server::start(false, fs, net, repository_factory, sleep_duration)?;
|
||||
}
|
||||
#[cfg(feature = "tui")]
|
||||
Server::Start { ui } => {
|
||||
let sleep_duration = std::time::Duration::from_secs(10);
|
||||
server::start(ui, fs, net, repository_factory, sleep_duration)?;
|
||||
|
|
|
@ -2,3 +2,4 @@ mod file_updated;
|
|||
mod receive_app_config;
|
||||
mod receive_valid_app_config;
|
||||
mod shutdown;
|
||||
mod subscribe_updates;
|
||||
|
|
|
@ -71,6 +71,7 @@ impl Handler<ReceiveValidAppConfig> for ServerActor {
|
|||
let shout = app_config.shout().clone();
|
||||
self.app_config.replace(app_config);
|
||||
self.alerts.do_send(UpdateShout::new(shout));
|
||||
self.send_server_updates();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
10
crates/cli/src/server/actor/handlers/subscribe_updates.rs
Normal file
10
crates/cli/src/server/actor/handlers/subscribe_updates.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
use crate::server::actor::{messages::SubscribeToUpdates, ServerActor};
|
||||
|
||||
//
|
||||
impl actix::Handler<SubscribeToUpdates> for ServerActor {
|
||||
type Result = ();
|
||||
|
||||
fn handle(&mut self, msg: SubscribeToUpdates, _ctx: &mut Self::Context) -> Self::Result {
|
||||
self.subscribers.push(msg.unwrap());
|
||||
}
|
||||
}
|
|
@ -1,9 +1,12 @@
|
|||
use actix::{Message, Recipient};
|
||||
//-
|
||||
use derive_more::Constructor;
|
||||
|
||||
use git_next_core::{
|
||||
git::graph::Log,
|
||||
message,
|
||||
server::{AppConfig, Storage},
|
||||
ForgeAlias, RepoAlias, RepoBranches,
|
||||
};
|
||||
|
||||
use std::net::SocketAddr;
|
||||
|
@ -33,3 +36,28 @@ message!(
|
|||
);
|
||||
|
||||
message!(Shutdown, "Notification to shutdown the server actor");
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Message)]
|
||||
#[rtype(result = "()")]
|
||||
pub enum ServerUpdate {
|
||||
/// Status of a repo
|
||||
UpdateRepoSummary {
|
||||
forge_alias: ForgeAlias,
|
||||
repo_alias: RepoAlias,
|
||||
branches: RepoBranches,
|
||||
log: Log,
|
||||
},
|
||||
/// remove a repo
|
||||
RemoveRepo {
|
||||
forge_alias: ForgeAlias,
|
||||
repo_alias: RepoAlias,
|
||||
},
|
||||
/// test message
|
||||
Ping,
|
||||
}
|
||||
|
||||
message!(
|
||||
SubscribeToUpdates,
|
||||
Recipient<ServerUpdate>,
|
||||
"Subscribe to receive updates from the server"
|
||||
);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
use actix::prelude::*;
|
||||
use messages::ReceiveAppConfig;
|
||||
use messages::{ReceiveAppConfig, ServerUpdate};
|
||||
use tracing::error;
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -58,6 +58,8 @@ pub struct ServerActor {
|
|||
sleep_duration: std::time::Duration,
|
||||
repo_actors: BTreeMap<(ForgeAlias, RepoAlias), Addr<RepoActor>>,
|
||||
|
||||
subscribers: Vec<Recipient<ServerUpdate>>,
|
||||
|
||||
// testing
|
||||
message_log: Option<Arc<RwLock<Vec<String>>>>,
|
||||
}
|
||||
|
@ -82,6 +84,7 @@ impl ServerActor {
|
|||
net,
|
||||
alerts,
|
||||
repository_factory: repo,
|
||||
subscribers: Vec::default(),
|
||||
sleep_duration,
|
||||
repo_actors: BTreeMap::new(),
|
||||
message_log: None,
|
||||
|
@ -239,4 +242,10 @@ impl ServerActor {
|
|||
ctx.address().do_send(msg);
|
||||
}
|
||||
}
|
||||
|
||||
fn send_server_updates(&self) {
|
||||
self.subscribers.iter().for_each(|subscriber| {
|
||||
subscriber.do_send(ServerUpdate::Ping);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,12 +5,16 @@ pub mod actor;
|
|||
mod tests;
|
||||
|
||||
use actix::prelude::*;
|
||||
use actix_rt::signal;
|
||||
|
||||
use crate::{
|
||||
alerts::{AlertsActor, History},
|
||||
file_watcher::{watch_file, FileUpdated},
|
||||
};
|
||||
|
||||
#[allow(clippy::module_name_repetitions)]
|
||||
pub use actor::ServerActor;
|
||||
|
||||
use git_next_core::git::RepositoryFactory;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
|
@ -63,17 +67,28 @@ pub fn start(
|
|||
.expect("file watcher");
|
||||
|
||||
if ui {
|
||||
let (tx, rx) = std::sync::mpsc::channel::<()>();
|
||||
actix_rt::task::spawn_blocking(|| {
|
||||
println!("Start Terminal...");
|
||||
// TODO: how does server send messages to Tui?
|
||||
crate::tui::Tui::new(tx).start().do_send(crate::tui::Tick);
|
||||
});
|
||||
println!("Waiting for shutdown...");
|
||||
let _ = rx.recv(); // block until shutdown is signaled
|
||||
#[cfg(feature = "tui")]
|
||||
{
|
||||
use crate::server::actor::messages::SubscribeToUpdates;
|
||||
use crate::tui;
|
||||
use std::sync::mpsc::channel;
|
||||
|
||||
let (tx_shutdown, rx_shutdown) = channel::<()>();
|
||||
let tui_addr = tui::Tui::new(tx_shutdown).start();
|
||||
// tui_addr.do_send(tui::Tick);
|
||||
let _ = tui_addr.send(tui::Tick).await;
|
||||
server.do_send(SubscribeToUpdates::new(tui_addr.clone().recipient()));
|
||||
loop {
|
||||
let _ = tui_addr.send(tui::Tick).await;
|
||||
if rx_shutdown.try_recv().is_ok() {
|
||||
break;
|
||||
}
|
||||
// actix_rt::task::yield_now().await;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
info!("Server running - Press Ctrl-C to stop...");
|
||||
let _ = actix_rt::signal::ctrl_c().await;
|
||||
let _ = signal::ctrl_c().await;
|
||||
info!("Ctrl-C received, shutting down...");
|
||||
}
|
||||
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
//
|
||||
mod server_update;
|
||||
mod tick;
|
||||
|
||||
|
|
28
crates/cli/src/tui/actor/handlers/server_update.rs
Normal file
28
crates/cli/src/tui/actor/handlers/server_update.rs
Normal file
|
@ -0,0 +1,28 @@
|
|||
use std::time::Instant;
|
||||
|
||||
use actix::Handler;
|
||||
|
||||
use crate::{server::actor::messages::ServerUpdate, tui::Tui};
|
||||
|
||||
//
|
||||
impl Handler<ServerUpdate> for Tui {
|
||||
type Result = ();
|
||||
|
||||
fn handle(&mut self, msg: ServerUpdate, _ctx: &mut Self::Context) -> Self::Result {
|
||||
match msg {
|
||||
ServerUpdate::UpdateRepoSummary {
|
||||
forge_alias,
|
||||
repo_alias,
|
||||
branches,
|
||||
log,
|
||||
} => todo!(),
|
||||
ServerUpdate::RemoveRepo {
|
||||
forge_alias,
|
||||
repo_alias,
|
||||
} => todo!(),
|
||||
ServerUpdate::Ping => {
|
||||
self.last_ping = Instant::now();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
//
|
||||
use std::borrow::BorrowMut;
|
||||
use std::{borrow::BorrowMut, time::Instant};
|
||||
|
||||
use actix::{ActorContext, AsyncContext, Handler};
|
||||
use actix::{ActorContext, Handler};
|
||||
use ratatui::{
|
||||
crossterm::event::{self, KeyCode, KeyEventKind},
|
||||
style::Stylize as _,
|
||||
|
@ -14,14 +14,17 @@ impl Handler<Tick> for Tui {
|
|||
type Result = std::io::Result<()>;
|
||||
|
||||
fn handle(&mut self, _msg: Tick, ctx: &mut Self::Context) -> Self::Result {
|
||||
ctx.notify_later(Tick, std::time::Duration::from_millis(16));
|
||||
if let Some(terminal) = self.terminal.borrow_mut() {
|
||||
terminal.draw(|frame| {
|
||||
let area = frame.area();
|
||||
frame.render_widget(
|
||||
Paragraph::new("Hello Ratatui! (press 'q' to quit)")
|
||||
.white()
|
||||
.on_blue(),
|
||||
Paragraph::new(format!(
|
||||
"(press 'q' to quit) Ping:[{:?}] UI:[{:?}]",
|
||||
self.last_ping,
|
||||
Instant::now()
|
||||
))
|
||||
.white()
|
||||
.on_blue(),
|
||||
area,
|
||||
);
|
||||
})?;
|
||||
|
|
|
@ -5,6 +5,7 @@ pub mod messages;
|
|||
use std::{
|
||||
io::{stderr, Stderr},
|
||||
sync::mpsc::Sender,
|
||||
time::Instant,
|
||||
};
|
||||
|
||||
use actix::{Actor, Context};
|
||||
|
@ -22,6 +23,7 @@ use ratatui::{
|
|||
pub struct Tui {
|
||||
terminal: Option<Terminal<CrosstermBackend<Stderr>>>,
|
||||
signal_shutdown: Sender<()>,
|
||||
last_ping: Instant,
|
||||
}
|
||||
impl Actor for Tui {
|
||||
type Context = Context<Self>;
|
||||
|
@ -52,10 +54,11 @@ impl Actor for Tui {
|
|||
}
|
||||
}
|
||||
impl Tui {
|
||||
pub const fn new(signal_shutdown: Sender<()>) -> Self {
|
||||
pub fn new(signal_shutdown: Sender<()>) -> Self {
|
||||
Self {
|
||||
terminal: None,
|
||||
signal_shutdown,
|
||||
last_ping: Instant::now(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -99,7 +99,6 @@ impl git::repository::OpenRepositoryLike for TestOpenRepository {
|
|||
.fetch_counter
|
||||
.read()
|
||||
.map_err(|_| git::fetch::Error::Lock)?;
|
||||
println!("Fetch: {i}");
|
||||
self.fetch_counter
|
||||
.write()
|
||||
.map_err(|_| git::fetch::Error::Lock)
|
||||
|
|
Loading…
Reference in a new issue