Compare commits

...

3 commits

Author SHA1 Message Date
12ecc308d5 refactor: merge webhook-actor crate into cli crate
All checks were successful
Rust / build (push) Successful in 2m40s
ci/woodpecker/push/cron-docker-builder Pipeline was successful
ci/woodpecker/push/tag-created Pipeline was successful
ci/woodpecker/push/push-next Pipeline was successful
ci/woodpecker/cron/push-next Pipeline was successful
ci/woodpecker/cron/tag-created Pipeline was successful
ci/woodpecker/cron/cron-docker-builder Pipeline was successful
2024-07-27 19:06:20 +01:00
366930bcfc refactor: merge file-watcher-crate into cli crate
All checks were successful
Rust / build (push) Successful in 1m55s
ci/woodpecker/push/push-next Pipeline was successful
ci/woodpecker/push/tag-created Pipeline was successful
ci/woodpecker/push/cron-docker-builder Pipeline was successful
2024-07-27 19:06:20 +01:00
9ca532a2b4 refactor: merge file-watcher-crate into cli crate
All checks were successful
Rust / build (push) Successful in 2m4s
ci/woodpecker/push/cron-docker-builder Pipeline was successful
ci/woodpecker/push/tag-created Pipeline was successful
ci/woodpecker/push/push-next Pipeline was successful
2024-07-27 18:51:05 +01:00
23 changed files with 156 additions and 199 deletions

View file

@ -13,11 +13,9 @@ categories = { workspace = true }
[dependencies]
git-next-core = { workspace = true }
git-next-file-watcher-actor = { workspace = true }
git-next-server-actor = { workspace = true }
git-next-forge = { workspace = true }
git-next-repo-actor = { workspace = true }
git-next-webhook-actor = { workspace = true }
# CLI parsing
clap = { workspace = true }
@ -37,6 +35,7 @@ actix-rt = { workspace = true }
# boilerplate
derive_more = { workspace = true }
derive-with = { workspace = true }
thiserror = { workspace = true }
# Webhooks
serde = { workspace = true }
@ -45,6 +44,11 @@ ulid = { workspace = true }
time = { workspace = true }
secrecy = { workspace = true }
standardwebhooks = { workspace = true }
bytes = { workspace = true }
warp = { workspace = true }
# file watcher (linux)
inotify = { workspace = true }
[dev-dependencies]
# Testing

View file

@ -522,8 +522,6 @@ stateDiagram-v2
cli --> core
cli --> forge
cli --> repo_actor
cli --> webhook_actor
cli --> file_watcher_actor
forge --> core
forge --> forge_forgejo
@ -535,9 +533,6 @@ stateDiagram-v2
repo_actor --> core
repo_actor --> forge
webhook_actor --> core
webhook_actor --> repo_actor
```
## License

View 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);
};
}
}
}

View file

@ -1,6 +1,8 @@
//
mod file_watcher;
mod init;
mod server;
mod webhook;
#[cfg(test)]
mod tests;

View file

@ -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 = ();

View file

@ -1,9 +1,16 @@
//
use actix::prelude::*;
use git_next_webhook_actor::{AddWebhookRecipient, ShutdownWebhook, WebhookActor, WebhookRouter};
use crate::server::actor::{
messages::{ReceiveValidServerConfig, ValidServerConfig},
ServerActor,
use crate::{
server::actor::{
messages::{ReceiveValidServerConfig, ValidServerConfig},
ServerActor,
},
webhook::{
messages::ShutdownWebhook,
router::{AddWebhookRecipient, WebhookRouter},
WebhookActor,
},
};
impl Handler<ReceiveValidServerConfig> for ServerActor {

View file

@ -1,8 +1,11 @@
//-
use actix::prelude::*;
use git_next_webhook_actor::ShutdownWebhook;
use crate::server::actor::{messages::Shutdown, ServerActor};
use actix::prelude::*;
use crate::{
server::actor::{messages::Shutdown, ServerActor},
webhook::messages::ShutdownWebhook,
};
impl Handler<Shutdown> for ServerActor {
type Result = ();

View file

@ -7,14 +7,16 @@ mod tests;
mod handlers;
pub mod messages;
use crate::webhook::WebhookActor;
use git_next_core::{
git::{repository::factory::RepositoryFactory, Generation, RepoDetails},
server::{self, InboundWebhook, ServerConfig, ServerStorage},
ForgeAlias, ForgeConfig, GitDir, RepoAlias, ServerRepoConfig, StoragePathType,
};
use git_next_repo_actor::messages::NotifyUser;
use git_next_repo_actor::{messages::CloneRepo, RepoActor};
use git_next_webhook_actor::WebhookActor;
use git_next_repo_actor::{
messages::{CloneRepo, NotifyUser},
RepoActor,
};
use kxio::{fs::FileSystem, network::Network};

View file

@ -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};

View file

@ -1,7 +1,7 @@
//
use actix::prelude::*;
use crate::{ShutdownWebhook, WebhookActor};
use crate::webhook::{messages::ShutdownWebhook, WebhookActor};
impl Handler<ShutdownWebhook> for WebhookActor {
type Result = ();

View file

@ -0,0 +1,42 @@
//
use actix::prelude::*;
mod handlers;
pub mod messages;
pub mod router;
mod server;
use git_next_repo_actor::messages::WebhookNotification;
use std::net::SocketAddr;
use tracing::Instrument;
#[derive(Debug)]
pub struct WebhookActor {
socket_addr: SocketAddr,
span: tracing::Span,
spawn_handle: Option<actix::SpawnHandle>,
message_receiver: Recipient<WebhookNotification>,
}
impl WebhookActor {
pub fn new(socket_addr: SocketAddr, message_receiver: Recipient<WebhookNotification>) -> Self {
let span = tracing::info_span!("WebhookActor");
Self {
socket_addr,
span,
message_receiver,
spawn_handle: None,
}
}
}
impl Actor for WebhookActor {
type Context = actix::Context<Self>;
fn started(&mut self, ctx: &mut Self::Context) {
let _gaurd = self.span.enter();
let address: Recipient<WebhookNotification> = self.message_receiver.clone();
let server = server::start(self.socket_addr, address);
let spawn_handle = ctx.spawn(server.in_current_span().into_actor(self));
self.spawn_handle.replace(spawn_handle);
}
}

View file

@ -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"

View file

@ -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).

View file

@ -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

View file

@ -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"

View file

@ -4,31 +4,4 @@ version = { workspace = true }
edition = { workspace = true }
license = { workspace = true }
repository = { workspace = true }
description = "webhook actor for git-next, the trunk-based development manager"
[dependencies]
git-next-core = { workspace = true }
git-next-repo-actor = { workspace = true }
# logging
tracing = { workspace = true }
# Webhooks
bytes = { workspace = true }
warp = { workspace = true }
# boilerplate
derive_more = { 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"
description = "[deprecated crate] webhook actor for git-next, the trunk-based development manager"

View file

@ -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).

View file

@ -1,45 +1 @@
//
use actix::prelude::*;
mod handlers;
pub mod messages;
mod router;
mod server;
use git_next_repo_actor::messages::WebhookNotification;
pub use messages::ShutdownWebhook;
use std::net::SocketAddr;
pub use router::AddWebhookRecipient;
pub use router::WebhookRouter;
use tracing::Instrument;
#[derive(Debug)]
pub struct WebhookActor {
socket_addr: SocketAddr,
span: tracing::Span,
spawn_handle: Option<actix::SpawnHandle>,
message_receiver: Recipient<WebhookNotification>,
}
impl WebhookActor {
pub fn new(socket_addr: SocketAddr, message_receiver: Recipient<WebhookNotification>) -> Self {
let span = tracing::info_span!("WebhookActor");
Self {
socket_addr,
span,
message_receiver,
spawn_handle: None,
}
}
}
impl Actor for WebhookActor {
type Context = actix::Context<Self>;
fn started(&mut self, ctx: &mut Self::Context) {
let _gaurd = self.span.enter();
let address: Recipient<WebhookNotification> = self.message_receiver.clone();
let server = server::start(self.socket_addr, address);
let spawn_handle = ctx.spawn(server.in_current_span().into_actor(self));
self.spawn_handle.replace(spawn_handle);
}
}
// moved to /crates/cli/src/webhook