1
Fork 0

Extract methods to separate files

This commit is contained in:
Jake Howard 2023-09-03 16:20:41 +01:00
parent 38fe58ea9b
commit 1d7b09f92a
Signed by: jake
GPG key ID: 57AFB45680EDD477
3 changed files with 74 additions and 66 deletions

58
src/dokku.rs Normal file
View file

@ -0,0 +1,58 @@
use async_std::fs::read_to_string;
use async_std::path::PathBuf;
use serde::Serialize;
use std::collections::HashSet;
#[derive(Debug, Serialize)]
pub struct DokkuApp {
name: String,
hosts: HashSet<String>,
}
impl DokkuApp {
pub async fn try_from_path(path: PathBuf) -> Option<Self> {
let vhost_path = path.join("VHOST");
if !vhost_path.is_file().await {
return None;
}
let current_vhosts = read_to_string(&vhost_path).await.ok()?;
if current_vhosts.is_empty() {
return None;
}
Some(DokkuApp {
name: String::from(path.file_name()?.to_str()?),
hosts: current_vhosts.lines().map(String::from).collect(),
})
}
}
pub fn get_dokku_root() -> Option<std::path::PathBuf> {
// First, check if we have a custom directory
if let Some(dokku_root) = std::env::var_os("DOKKU_ROOT") {
return Some(std::path::PathBuf::from(dokku_root));
}
// Next, check for a dokku user and its home directory
match nix::unistd::User::from_name("dokku") {
Ok(Some(user)) => return Some(user.dir),
// If the user doesn't exist, do nothing
Ok(None) => return None,
// If there was an error, give up
_ => {}
}
// Finally, try a hard-coded path
let dokku_home_guess = std::path::PathBuf::from("/home/dokku");
if dokku_home_guess.is_dir() {
return Some(dokku_home_guess);
}
// If there's nothing else, give up
None
}

View file

@ -1,79 +1,20 @@
use async_std::fs::read_to_string;
use async_std::path::PathBuf; use async_std::path::PathBuf;
use async_std::stream::StreamExt; use async_std::stream::StreamExt;
use axum::extract::State; use axum::extract::State;
use axum::{routing::get, Router}; use axum::{routing::get, Router};
use serde::Serialize;
use std::collections::HashSet;
use std::net::{IpAddr, Ipv6Addr, SocketAddr}; use std::net::{IpAddr, Ipv6Addr, SocketAddr};
use tokio::task::JoinSet; use tokio::task::JoinSet;
mod dokku;
mod utils;
use dokku::DokkuApp;
#[derive(Clone)] #[derive(Clone)]
struct AppState { struct AppState {
dokku_root: PathBuf, dokku_root: PathBuf,
} }
#[derive(Debug, Serialize)]
struct DokkuApp {
name: String,
hosts: HashSet<String>,
}
impl DokkuApp {
async fn try_from_path(path: PathBuf) -> Option<Self> {
let vhost_path = path.join("VHOST");
if !vhost_path.is_file().await {
return None;
}
let current_vhosts = read_to_string(&vhost_path).await.ok()?;
if current_vhosts.is_empty() {
return None;
}
Some(DokkuApp {
name: String::from(path.file_name()?.to_str()?),
hosts: current_vhosts.lines().map(String::from).collect(),
})
}
}
fn get_dokku_root() -> Option<std::path::PathBuf> {
// First, check if we have a custom directory
if let Some(dokku_root) = std::env::var_os("DOKKU_ROOT") {
return Some(std::path::PathBuf::from(dokku_root));
}
// Next, check for a dokku user and its home directory
match nix::unistd::User::from_name("dokku") {
Ok(Some(user)) => return Some(user.dir),
// If the user doesn't exist, do nothing
Ok(None) => return None,
// If there was an error, give up
_ => {}
}
// Finally, try a hard-coded path
let dokku_home_guess = std::path::PathBuf::from("/home/dokku");
if dokku_home_guess.is_dir() {
return Some(dokku_home_guess);
}
// If there's nothing else, give up
None
}
fn osstring_starts_with(data: std::ffi::OsString, prefix: char) -> bool {
match data.into_string() {
Ok(s) => matches!(s.chars().next(), Some(c) if c == prefix),
Err(_) => false,
}
}
async fn hosts(State(state): State<AppState>) -> axum::Json<Vec<DokkuApp>> { async fn hosts(State(state): State<AppState>) -> axum::Json<Vec<DokkuApp>> {
let mut dir_entries = state.dokku_root.read_dir().await.unwrap(); let mut dir_entries = state.dokku_root.read_dir().await.unwrap();
@ -81,7 +22,7 @@ async fn hosts(State(state): State<AppState>) -> axum::Json<Vec<DokkuApp>> {
while let Some(Ok(dir_entry)) = dir_entries.next().await { while let Some(Ok(dir_entry)) = dir_entries.next().await {
// Skip hidden folders / files // Skip hidden folders / files
if osstring_starts_with(dir_entry.file_name(), '.') { if utils::osstring_starts_with(dir_entry.file_name(), '.') {
continue; continue;
} }
@ -107,7 +48,7 @@ async fn hosts(State(state): State<AppState>) -> axum::Json<Vec<DokkuApp>> {
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
let dokku_root = match get_dokku_root() { let dokku_root = match dokku::get_dokku_root() {
Some(path) => path, Some(path) => path,
None => { None => {
println!("Failed to find dokku root"); println!("Failed to find dokku root");

9
src/utils.rs Normal file
View file

@ -0,0 +1,9 @@
use std::ffi::OsString;
#[inline]
pub fn osstring_starts_with(data: OsString, prefix: char) -> bool {
match data.into_string() {
Ok(s) => matches!(s.chars().next(), Some(c) if c == prefix),
Err(_) => false,
}
}