1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
//
#[cfg(test)]
mod tests;

use actix::prelude::*;

use git_next_core::git::RepositoryFactory;
use git_next_file_watcher_actor::{FileUpdated, FileWatcher};
use git_next_server_actor::ServerActor;

use kxio::{fs::FileSystem, network::Network};
use tracing::{error, info, level_filters::LevelFilter};

use std::path::PathBuf;

pub fn init(fs: FileSystem) {
    let file_name = "git-next-server.toml";
    let pathbuf = PathBuf::from(file_name);
    let Ok(exists) = fs.path_exists(&pathbuf) else {
        eprintln!("Could not check if file exist: {}", file_name);
        return;
    };
    if exists {
        eprintln!(
            "The configuration file already exists at {} - not overwritting it.",
            file_name
        );
    } else {
        match fs.file_write(&pathbuf, include_str!("../server-default.toml")) {
            Ok(_) => println!("Created a default configuration file at {}", file_name),
            Err(e) => {
                eprintln!("Failed to write to the configuration file: {}", e)
            }
        }
    }
}

pub fn start(
    fs: FileSystem,
    net: Network,
    repo: Box<dyn RepositoryFactory>,
    sleep_duration: std::time::Duration,
) {
    init_logging();

    info!("Starting Server...");
    let execution = async move {
        let server = ServerActor::new(fs.clone(), net.clone(), repo, sleep_duration).start();
        server.do_send(FileUpdated);

        info!("Starting File Watcher...");
        let fw = match FileWatcher::new("git-next-server.toml".into(), server.clone().recipient()) {
            Ok(fw) => fw,
            Err(err) => {
                error!(?err, "Failed to start file watcher");
                return;
            }
        };
        fw.start();

        info!("Server running - Press Ctrl-C to stop...");
        let _ = actix_rt::signal::ctrl_c().await;
        info!("Ctrl-C received, shutting down...");
        server.do_send(git_next_server_actor::messages::Shutdown);
        actix_rt::time::sleep(std::time::Duration::from_millis(200)).await;
        System::current().stop();
    };
    let system = System::new();
    Arbiter::current().spawn(execution);
    if let Err(err) = system.run() {
        tracing::error!(?err, "")
    };
}

pub fn init_logging() {
    use tracing_subscriber::prelude::*;
    use tracing_subscriber::EnvFilter;

    let subscriber = tracing_subscriber::fmt::layer()
        .with_target(false)
        .with_file(true)
        .with_line_number(true)
        .with_filter(
            EnvFilter::builder()
                .with_default_directive(LevelFilter::INFO.into())
                .from_env_lossy(),
        );
    tracing_subscriber::registry()
        .with(console_subscriber::ConsoleLayer::builder().spawn())
        .with(subscriber)
        .init();
}