Compare commits

..

9 commits

5 changed files with 112 additions and 5 deletions

View file

@ -17,9 +17,17 @@ tracing-subscriber = "0.3"
# fs # fs
tempfile = "3.10" tempfile = "3.10"
# TOML parsing
serde = { version = "1.0", features = ["derive"] }
toml = "0.8"
# error handling
terrors = "0.3"
[dev-dependencies] [dev-dependencies]
# Testing # Testing
test-log = "0.2" test-log = "0.2"
anyhow = "1.0"
[package.metadata.bin] [package.metadata.bin]
# Conventional commits githook # Conventional commits githook

View file

@ -0,0 +1,9 @@
[forge.default]
type = "forgejo"
url = "https://git.example.net"
user = "git-next" # the user to perform actions as
# API token for user?
# path to private SSH key for user?
[forge.default.repos]
hello = "user/hello" # maps to https://git.example.net/user/hello and git@git.example.net:user/hello.git

View file

@ -7,7 +7,7 @@ use std::{
}; };
use tempfile::{tempdir, TempDir}; use tempfile::{tempdir, TempDir};
use tracing::{event, Level}; use tracing::info;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum FileSystem { pub enum FileSystem {
@ -46,7 +46,7 @@ pub trait FileSystemEnv: Sync + Send + std::fmt::Debug {
use std::io::{LineWriter, Write}; use std::io::{LineWriter, Write};
let path = self.in_cwd(file_name); let path = self.in_cwd(file_name);
event!(Level::INFO, "writing to {:?}", path); info!("writing to {:?}", path);
let file = File::create(path.clone())?; let file = File::create(path.clone())?;
let mut file = LineWriter::new(file); let mut file = LineWriter::new(file);
file.write_all(content.as_bytes())?; file.write_all(content.as_bytes())?;
@ -57,6 +57,18 @@ pub trait FileSystemEnv: Sync + Send + std::fmt::Debug {
use std::fs::File; use std::fs::File;
File::open(name).is_ok() File::open(name).is_ok()
} }
fn read_file(&self, file_name: &str) -> std::io::Result<String> {
use std::fs::File;
use std::io::Read;
let path = self.in_cwd(file_name);
info!("reading from {:?}", path);
let mut file = File::open(path)?;
let mut content = String::new();
file.read_to_string(&mut content)?;
Ok(content)
}
} }
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
@ -91,7 +103,7 @@ impl RealFileSystemEnv {
impl TempFileSystemEnv { impl TempFileSystemEnv {
fn new() -> std::io::Result<Self> { fn new() -> std::io::Result<Self> {
let temp_dir = tempdir()?; let temp_dir = tempdir()?;
event!(Level::INFO, "temp dir: {:?}", temp_dir.path()); info!("temp dir: {:?}", temp_dir.path());
let cwd = temp_dir.path().to_path_buf(); let cwd = temp_dir.path().to_path_buf();
let temp_dir = Arc::new(Mutex::new(temp_dir)); let temp_dir = Arc::new(Mutex::new(temp_dir));
Ok(Self { cwd, temp_dir }) Ok(Self { cwd, temp_dir })
@ -125,4 +137,15 @@ mod tests {
let env = RealFileSystemEnv::new(cwd.clone()); let env = RealFileSystemEnv::new(cwd.clone());
assert_eq!(env.cwd(), &cwd); assert_eq!(env.cwd(), &cwd);
} }
#[test_log::test]
fn test_write_and_read_file() -> std::io::Result<()> {
let env = TempFileSystemEnv::new()?;
let file_name = "test.txt";
let content = "Hello, World!";
let path = env.write_file(file_name, content)?;
assert_eq!(env.read_file(file_name)?, content);
assert!(path.exists());
Ok(())
}
} }

64
src/server/config.rs Normal file
View file

@ -0,0 +1,64 @@
use serde::Deserialize;
use terrors::OneOf;
use crate::filesystem::FileSystem;
#[derive(Debug, PartialEq, Deserialize)]
pub(crate) struct Config {
r#type: ForgeType,
url: String,
user: String,
// API Token
// Private SSH Key Path
}
#[derive(Debug, PartialEq, Deserialize)]
pub(crate) enum ForgeType {
ForgeJo,
// Gitea,
// GitHub,
// GitLab,
// BitBucket,
}
impl Config {
pub(crate) fn load(fs: &FileSystem) -> Result<Self, OneOf<(std::io::Error, toml::de::Error)>> {
let str = fs.read_file("git-next-server.toml").map_err(OneOf::new)?;
toml::from_str(&str).map_err(OneOf::new)
}
pub const fn r#type(&self) -> &ForgeType {
&self.r#type
}
pub fn url(&self) -> &str {
self.url.as_str()
}
pub fn user(&self) -> &str {
self.user.as_str()
}
}
#[cfg(test)]
mod tests {
use crate::filesystem::FileSystem;
use super::*;
#[test]
fn test_config_load() -> Result<(), OneOf<(std::io::Error, toml::de::Error)>> {
let fs = FileSystem::new_temp().map_err(OneOf::new)?;
fs.write_file(
"git-next-server.toml",
r#"
type = "ForgeJo"
url = "https://forge.jo"
user = "Bob"
"#,
)
.map_err(OneOf::new)?;
let config = Config::load(&fs)?;
assert_eq!(config.r#type(), &ForgeType::ForgeJo);
assert_eq!(config.url(), "https://forge.jo".to_string());
assert_eq!(config.user(), "Bob".to_string());
Ok(())
}
}

View file

@ -1,3 +1,5 @@
mod config;
use std::path::PathBuf; use std::path::PathBuf;
use tracing::info; use tracing::info;
@ -13,7 +15,7 @@ pub(crate) fn init(fs: FileSystem) {
file_name file_name
); );
} else { } else {
match fs.write_file(file_name, include_str!("../server-default.toml")) { match fs.write_file(file_name, include_str!("../../server-default.toml")) {
Ok(_) => println!("Created a default configuration file at {}", file_name), Ok(_) => println!("Created a default configuration file at {}", file_name),
Err(e) => { Err(e) => {
eprintln!("Failed to write to the configuration file: {}", e) eprintln!("Failed to write to the configuration file: {}", e)
@ -22,12 +24,13 @@ pub(crate) fn init(fs: FileSystem) {
} }
} }
pub(crate) fn start(_fs: FileSystem) { pub(crate) fn start(fs: FileSystem) {
let Ok(_) = init_logging() else { let Ok(_) = init_logging() else {
eprintln!("Failed to initialize logging."); eprintln!("Failed to initialize logging.");
return; return;
}; };
info!("Starting Server..."); info!("Starting Server...");
let _config = config::Config::load(&fs);
// todo!() // todo!()
} }