forked from kemitix/git-next
refactor: merge file-watcher-crate into cli crate
This commit is contained in:
parent
a679abeafc
commit
9ca532a2b4
11 changed files with 84 additions and 109 deletions
|
@ -37,6 +37,7 @@ actix-rt = { workspace = true }
|
|||
# boilerplate
|
||||
derive_more = { workspace = true }
|
||||
derive-with = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
|
||||
# Webhooks
|
||||
serde = { workspace = true }
|
||||
|
@ -46,6 +47,9 @@ time = { workspace = true }
|
|||
secrecy = { workspace = true }
|
||||
standardwebhooks = { workspace = true }
|
||||
|
||||
# file watcher (linux)
|
||||
inotify = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
# Testing
|
||||
assert2 = { workspace = true }
|
||||
|
|
|
@ -523,7 +523,6 @@ stateDiagram-v2
|
|||
cli --> forge
|
||||
cli --> repo_actor
|
||||
cli --> webhook_actor
|
||||
cli --> file_watcher_actor
|
||||
|
||||
forge --> core
|
||||
forge --> forge_forgejo
|
||||
|
|
70
crates/cli/src/file_watcher.rs
Normal file
70
crates/cli/src/file_watcher.rs
Normal file
|
@ -0,0 +1,70 @@
|
|||
//
|
||||
use actix::prelude::*;
|
||||
|
||||
use actix::Recipient;
|
||||
use inotify::{EventMask, Inotify, WatchMask};
|
||||
|
||||
use std::{path::PathBuf, time::Duration};
|
||||
|
||||
const CHECK_INTERVAL: Duration = Duration::from_secs(1);
|
||||
|
||||
#[derive(Debug, Clone, Message)]
|
||||
#[rtype(result = "()")]
|
||||
pub struct WatchFile;
|
||||
|
||||
#[derive(Debug, Message)]
|
||||
#[rtype(result = "()")]
|
||||
pub struct FileUpdated;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum Error {
|
||||
#[error("io")]
|
||||
Io(#[from] std::io::Error),
|
||||
}
|
||||
|
||||
pub struct FileWatcher {
|
||||
inotify: Inotify,
|
||||
recipient: Recipient<FileUpdated>,
|
||||
run_interval: Option<SpawnHandle>,
|
||||
}
|
||||
impl FileWatcher {
|
||||
pub fn new(path: PathBuf, recipient: Recipient<FileUpdated>) -> Result<Self, Error> {
|
||||
let inotify = Inotify::init()?;
|
||||
inotify.watches().add(
|
||||
path,
|
||||
WatchMask::MODIFY | WatchMask::CREATE | WatchMask::DELETE | WatchMask::ATTRIB,
|
||||
)?;
|
||||
Ok(Self {
|
||||
inotify,
|
||||
recipient,
|
||||
run_interval: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl Actor for FileWatcher {
|
||||
type Context = Context<Self>;
|
||||
|
||||
fn started(&mut self, ctx: &mut Self::Context) {
|
||||
tracing::info!("Starting file watcher actor");
|
||||
self.run_interval
|
||||
.replace(ctx.run_interval(CHECK_INTERVAL, |_act, ctx| {
|
||||
ctx.notify(WatchFile);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
impl Handler<WatchFile> for FileWatcher {
|
||||
type Result = ();
|
||||
|
||||
fn handle(&mut self, _msg: WatchFile, _ctx: &mut Self::Context) -> Self::Result {
|
||||
let mut buffer = [0u8; 4096];
|
||||
if let Ok(mut events) = self.inotify.read_events(&mut buffer) {
|
||||
if events.any(|event| {
|
||||
event.mask.contains(EventMask::MODIFY) || event.mask.contains(EventMask::ATTRIB)
|
||||
}) {
|
||||
tracing::info!("File modified");
|
||||
self.recipient.do_send(FileUpdated);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
//
|
||||
mod file_watcher;
|
||||
mod init;
|
||||
mod server;
|
||||
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
//-
|
||||
//
|
||||
use actix::prelude::*;
|
||||
|
||||
use git_next_core::server::ServerConfig;
|
||||
use git_next_file_watcher_actor::FileUpdated;
|
||||
|
||||
use crate::server::actor::{messages::ReceiveServerConfig, ServerActor};
|
||||
use crate::{
|
||||
file_watcher::FileUpdated,
|
||||
server::actor::{messages::ReceiveServerConfig, ServerActor},
|
||||
};
|
||||
|
||||
impl Handler<FileUpdated> for ServerActor {
|
||||
type Result = ();
|
||||
|
|
|
@ -6,9 +6,9 @@ mod tests;
|
|||
|
||||
use actix::prelude::*;
|
||||
|
||||
use crate::file_watcher::{FileUpdated, FileWatcher};
|
||||
use actor::ServerActor;
|
||||
use git_next_core::git::RepositoryFactory;
|
||||
use git_next_file_watcher_actor::{FileUpdated, FileWatcher};
|
||||
|
||||
use kxio::{fs::FileSystem, network::Network};
|
||||
use tracing::{error, info, level_filters::LevelFilter};
|
||||
|
|
|
@ -5,31 +5,3 @@ edition = { workspace = true }
|
|||
license = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
description = "Config file watcher for git-next, the trunk-based development manager"
|
||||
|
||||
[dependencies]
|
||||
# logging
|
||||
tracing = { workspace = true }
|
||||
|
||||
# file watcher
|
||||
inotify = { workspace = true }
|
||||
|
||||
# Webhooks
|
||||
# bytes = { workspace = true }
|
||||
# warp = { workspace = true }
|
||||
|
||||
# boilerplate
|
||||
# derive_more = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
|
||||
# Actors
|
||||
actix = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
# Testing
|
||||
# assert2 = { workspace = true }
|
||||
|
||||
[lints.clippy]
|
||||
nursery = { level = "warn", priority = -1 }
|
||||
# pedantic = "warn"
|
||||
unwrap_used = "warn"
|
||||
expect_used = "warn"
|
||||
|
|
|
@ -7,3 +7,5 @@ development workflows where each commit must pass CI before being included in
|
|||
the main branch.
|
||||
|
||||
See [git-next](https://crates.io/crates/git-next) for more information.
|
||||
|
||||
N.B. this crate has been merged into [git-next](https://crates.io/git-next).
|
||||
|
|
|
@ -1,68 +1 @@
|
|||
use actix::prelude::*;
|
||||
|
||||
use actix::Recipient;
|
||||
use inotify::{EventMask, Inotify, WatchMask};
|
||||
use std::{path::PathBuf, time::Duration};
|
||||
|
||||
const CHECK_INTERVAL: Duration = Duration::from_secs(1);
|
||||
|
||||
#[derive(Debug, Clone, Message)]
|
||||
#[rtype(result = "()")]
|
||||
pub struct WatchFile;
|
||||
|
||||
#[derive(Debug, Message)]
|
||||
#[rtype(result = "()")]
|
||||
pub struct FileUpdated;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum Error {
|
||||
#[error("io")]
|
||||
Io(#[from] std::io::Error),
|
||||
}
|
||||
|
||||
pub struct FileWatcher {
|
||||
inotify: Inotify,
|
||||
recipient: Recipient<FileUpdated>,
|
||||
run_interval: Option<SpawnHandle>,
|
||||
}
|
||||
impl FileWatcher {
|
||||
pub fn new(path: PathBuf, recipient: Recipient<FileUpdated>) -> Result<Self, Error> {
|
||||
let inotify = Inotify::init()?;
|
||||
inotify.watches().add(
|
||||
path,
|
||||
WatchMask::MODIFY | WatchMask::CREATE | WatchMask::DELETE | WatchMask::ATTRIB,
|
||||
)?;
|
||||
Ok(Self {
|
||||
inotify,
|
||||
recipient,
|
||||
run_interval: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl Actor for FileWatcher {
|
||||
type Context = Context<Self>;
|
||||
|
||||
fn started(&mut self, ctx: &mut Self::Context) {
|
||||
tracing::info!("Starting file watcher actor");
|
||||
self.run_interval
|
||||
.replace(ctx.run_interval(CHECK_INTERVAL, |_act, ctx| {
|
||||
ctx.notify(WatchFile);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
impl Handler<WatchFile> for FileWatcher {
|
||||
type Result = ();
|
||||
|
||||
fn handle(&mut self, _msg: WatchFile, _ctx: &mut Self::Context) -> Self::Result {
|
||||
let mut buffer = [0u8; 4096];
|
||||
if let Ok(mut events) = self.inotify.read_events(&mut buffer) {
|
||||
if events.any(|event| {
|
||||
event.mask.contains(EventMask::MODIFY) || event.mask.contains(EventMask::ATTRIB)
|
||||
}) {
|
||||
tracing::info!("File modified");
|
||||
self.recipient.do_send(FileUpdated);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
// moved to /crates/cli/src/file_watcher
|
||||
|
|
|
@ -5,11 +5,3 @@ edition = { workspace = true }
|
|||
license = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
description = "[deprecated crate] server for git-next, the trunk-based development manager"
|
||||
|
||||
|
||||
|
||||
[lints.clippy]
|
||||
nursery = { level = "warn", priority = -1 }
|
||||
# pedantic = "warn"
|
||||
unwrap_used = "warn"
|
||||
expect_used = "warn"
|
||||
|
|
Loading…
Reference in a new issue