Skip to content

Commit

Permalink
Merge pull request #42 from kraktus/changes
Browse files Browse the repository at this point in the history
Changes
  • Loading branch information
fitztrev authored Dec 7, 2023
2 parents b47ba06 + 97256b2 commit 7ae3bea
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 118 deletions.
39 changes: 0 additions & 39 deletions command/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion command/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,4 @@ edition = "2021"
cliclack = "0.1.6"
local-ip-address = "0.5.6"
serde = { version = "1.0.193", features = ["derive"] }
struct_iterable = "0.1.1"
toml = "0.8.8"
154 changes: 76 additions & 78 deletions command/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![warn(clippy::pedantic)]

use cliclack::{
confirm, input, intro,
log::{self, info},
Expand All @@ -6,11 +8,10 @@ use cliclack::{
use local_ip_address::local_ip;
use serde::{Deserialize, Serialize};
use std::{
collections::HashMap,
format,
io::Error,
path::{Path, PathBuf},
};
use struct_iterable::Iterable;

const BANNER: &str = r"
|\_ _ _ _
Expand All @@ -21,7 +22,7 @@ const BANNER: &str = r"
|___/
";

#[derive(Serialize, Deserialize, Iterable, Debug)]
#[derive(Serialize, Deserialize, Debug, Default)]
struct Config {
compose_profiles: Option<Vec<String>>,
setup_database: Option<bool>,
Expand All @@ -36,78 +37,70 @@ struct Config {
pairing_port: Option<u16>,
}

macro_rules! to_env {
($name_opt:ident) => {
$name_opt
.clone()
.map(|v| format!("{}={}", stringify!($name_opt).to_uppercase(), v.to_string()))
.unwrap_or_default()
};
($key:ident, $value:expr) => {
format!("{}={}", stringify!($key).to_uppercase(), $value)
};
}

impl Config {
const SETTINGS_TOML: &'static str = "settings.toml";
const SETTINGS_ENV: &'static str = "settings.env";

fn default() -> Self {
Self {
compose_profiles: None,
setup_database: None,
enable_monitoring: None,
su_password: None,
password: None,
lila_domain: None,
lila_url: None,
phone_ip: None,
connection_port: None,
pairing_code: None,
pairing_port: None,
}
}

fn load() -> Self {
if !Path::new(Self::SETTINGS_TOML).exists() {
return Self::default();
}

let toml = std::fs::read_to_string(Self::SETTINGS_TOML).unwrap();
toml::from_str(&toml).unwrap()
std::fs::read_to_string(Self::SETTINGS_TOML).map_or_else(
|_| Self::default(),
|contents| toml::from_str(&contents).unwrap(),
)
}

fn save(&self) {
std::fs::write(Self::SETTINGS_TOML, self.to_toml()).unwrap();
std::fs::write(Self::SETTINGS_ENV, self.to_env()).unwrap();
fn save(&self) -> std::io::Result<()> {
std::fs::write(Self::SETTINGS_TOML, self.to_toml())?;
std::fs::write(Self::SETTINGS_ENV, self.to_env())
}

fn to_toml(&self) -> String {
toml::to_string(&self).unwrap()
}

fn to_env(&self) -> String {
let mut contents: HashMap<&str, String> = HashMap::new();

for (key, value) in self.iter() {
if let Some(string_opt) = value.downcast_ref::<Option<String>>() {
if let Some(string_opt) = string_opt {
contents.insert(key, string_opt.to_string());
}
} else if let Some(bool_opt) = value.downcast_ref::<Option<bool>>() {
if let Some(bool_opt) = bool_opt {
contents.insert(key, bool_opt.to_string());
}
} else if let Some(u16_opt) = value.downcast_ref::<Option<u16>>() {
if let Some(u16_opt) = u16_opt {
contents.insert(key, u16_opt.to_string());
}
} else if let Some(u32_opt) = value.downcast_ref::<Option<u32>>() {
if let Some(u32_opt) = u32_opt {
contents.insert(key, u32_opt.to_string());
}
} else if let Some(vec_string) = value.downcast_ref::<Option<Vec<String>>>() {
if let Some(vec_string) = vec_string {
contents.insert(key, vec_string.join(","));
}
} else {
panic!("Unsupported type: Could not write [{key}] to env");
}
}

contents
.iter()
.map(|(k, v)| format!("{}={}", k.to_uppercase(), v))
.collect::<Vec<String>>()
.join("\n")
let Self {
compose_profiles,
setup_database,
enable_monitoring,
su_password,
password,
lila_domain,
lila_url,
phone_ip,
connection_port,
pairing_code,
pairing_port,
} = self;
let compose_profiles_string = compose_profiles
.clone()
.map(|v| v.join(","))
.unwrap_or_default();
format!(
"{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n",
to_env!(compose_profiles, compose_profiles_string),
to_env!(setup_database),
to_env!(enable_monitoring),
to_env!(su_password),
to_env!(password),
to_env!(lila_domain),
to_env!(lila_url),
to_env!(phone_ip),
to_env!(connection_port),
to_env!(pairing_code),
to_env!(pairing_port)
)
}
}

Expand Down Expand Up @@ -179,6 +172,16 @@ fn main() -> std::io::Result<()> {
}
}

fn pwd_input(user_type: &str) -> std::io::Result<String> {
input(format!(
"Choose a password for {user_type} users (blank for 'password')"
))
.placeholder("password")
.default_input("password")
.required(false)
.interact()
}

fn setup(mut config: Config) -> std::io::Result<()> {
intro(BANNER)?;

Expand All @@ -190,18 +193,7 @@ fn setup(mut config: Config) -> std::io::Result<()> {
.interact()?;

let (su_password, password) = if setup_database {
(
input("Choose a password for admin users (blank for 'password')")
.placeholder("password")
.default_input("password")
.required(false)
.interact()?,
input("Choose a password for regular users (blank for 'password')")
.placeholder("password")
.default_input("password")
.required(false)
.interact()?,
)
(pwd_input("admin")?, pwd_input("regular")?)
} else {
(String::new(), String::new())
};
Expand Down Expand Up @@ -229,7 +221,7 @@ fn setup(mut config: Config) -> std::io::Result<()> {
config.lila_url = Some(gitpod.url);
}

config.save();
config.save()?;

create_placeholder_dirs();

Expand Down Expand Up @@ -481,7 +473,7 @@ fn hostname(mut config: Config) -> std::io::Result<()> {

config.lila_domain = Some(format!("{hostname}:8080"));
config.lila_url = Some(format!("http://{hostname}:8080"));
config.save();
config.save()?;

outro(format!("✔ Local Lichess URL set to http://{hostname}:8080"))
}
Expand Down Expand Up @@ -515,7 +507,7 @@ fn mobile_setup(mut config: Config) -> std::io::Result<()> {
config.connection_port = Some(connection_port);
config.pairing_code = Some(pairing_code);
config.pairing_port = Some(pairing_port);
config.save();
config.save()?;

outro("Pairing and connecting to phone...")
}
Expand Down Expand Up @@ -547,6 +539,7 @@ fn welcome() -> std::io::Result<()> {
#[cfg(test)]
mod tests {
use super::*;
use std::collections::HashMap;

#[test]
fn test_repository() {
Expand All @@ -558,6 +551,12 @@ mod tests {
assert_eq!(repo.clone_path(), Path::new("repos/lila"));
}

#[test]
fn test_to_env_proc() {
let foo = Some("test");
assert_eq!(to_env!(foo), "FOO=test");
}

#[test]
fn test_set_env_vars_from_struct() {
let contents = Config {
Expand All @@ -577,8 +576,7 @@ mod tests {

let vars = contents
.split("\n")
.map(|line| line.split("="))
.map(|mut parts| (parts.next().unwrap(), parts.next().unwrap()))
.flat_map(|line| line.split_once("="))
.collect::<HashMap<&str, &str>>();

assert_eq!(vars["COMPOSE_PROFILES"], "foo,bar");
Expand Down

0 comments on commit 7ae3bea

Please sign in to comment.