Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
780 changes: 367 additions & 413 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions crates/kftray-commons/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ path = "src/lib.rs"

[dependencies]
anyhow = { workspace = true }
chrono = { workspace = true }
dirs = { workspace = true }
futures = { workspace = true }
git2 = { workspace = true }
Expand Down
11 changes: 2 additions & 9 deletions crates/kftray-commons/src/models/config_model.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
use serde::{
Deserialize,
Deserializer,
Serialize,
};
use serde::{Deserialize, Deserializer, Serialize};

fn deserialize_bool_from_anything<'de, D>(deserializer: D) -> Result<Option<bool>, D::Error>
where
D: Deserializer<'de>,
{
use std::fmt;

use serde::de::{
self,
Visitor,
};
use serde::de::{self, Visitor};

struct BoolOrStringVisitor;

Expand Down
5 changes: 1 addition & 4 deletions crates/kftray-commons/src/models/config_state_model.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
use serde::{
Deserialize,
Serialize,
};
use serde::{Deserialize, Serialize};

#[derive(Clone, Deserialize, PartialEq, Serialize, Debug)]
pub struct ConfigState {
Expand Down
5 changes: 1 addition & 4 deletions crates/kftray-commons/src/models/hostfile.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
use std::net::IpAddr;

use serde::{
Deserialize,
Serialize,
};
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct HostEntry {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
use serde::{
Deserialize,
Serialize,
};
use serde::{Deserialize, Serialize};

#[derive(Clone, Deserialize, PartialEq, Serialize, Debug)]
pub struct HttpLogsConfig {
Expand Down
36 changes: 32 additions & 4 deletions crates/kftray-commons/src/models/settings_model.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
use serde::{
Deserialize,
Serialize,
};
use serde::{Deserialize, Serialize};

#[derive(Clone, Deserialize, Serialize, Debug)]
pub struct AppSettings {
Expand Down Expand Up @@ -40,6 +37,12 @@ pub struct AppSettings {

#[serde(default = "default_global_shortcut")]
pub global_shortcut: String,

#[serde(default = "default_env_auto_sync_enabled")]
pub env_auto_sync_enabled: bool,

#[serde(default)]
pub env_auto_sync_path: String,
}

fn default_network_monitor() -> bool {
Expand Down Expand Up @@ -73,6 +76,10 @@ fn default_global_shortcut() -> String {
return "Ctrl+Shift+F1".to_string();
}

fn default_env_auto_sync_enabled() -> bool {
true
}

impl Default for AppSettings {
fn default() -> Self {
Self {
Expand All @@ -88,11 +95,15 @@ impl Default for AppSettings {
ssl_auto_regenerate: default_ssl_auto_regenerate(),
ssl_ca_auto_install: false,
global_shortcut: default_global_shortcut(),
env_auto_sync_enabled: default_env_auto_sync_enabled(),
env_auto_sync_path: String::new(),
}
}
}

impl AppSettings {
/// Creates an `AppSettings` instance from a settings key-value map.
/// Missing keys use default values defined in `AppSettings::default()`.
pub fn from_settings_manager(settings: &std::collections::HashMap<String, String>) -> Self {
let mut app_settings = AppSettings::default();

Expand Down Expand Up @@ -144,9 +155,18 @@ impl AppSettings {
app_settings.global_shortcut = value.clone();
}

if let Some(value) = settings.get("env_auto_sync_enabled") {
app_settings.env_auto_sync_enabled = value.parse().unwrap_or(false);
}
Comment on lines +158 to +160
Copy link
Contributor

@coderabbitai coderabbitai bot Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Inconsistent default for env_auto_sync_enabled in from_settings_manager.

Line 157 uses unwrap_or(false), but the default everywhere else is true:

  • default_env_auto_sync_enabled() returns true (Line 80)
  • Default::default() sets it to true (Line 98)
  • get_env_auto_sync_enabled() in settings.rs defaults to true (Line 614/616)

If the stored value is somehow malformed, this path would produce false instead of the intended default true.

Proposed fix
         if let Some(value) = settings.get("env_auto_sync_enabled") {
-            app_settings.env_auto_sync_enabled = value.parse().unwrap_or(false);
+            app_settings.env_auto_sync_enabled = value.parse().unwrap_or(true);
         }
🤖 Prompt for AI Agents
In `@crates/kftray-commons/src/models/settings_model.rs` around lines 156 - 158,
The code path in from_settings_manager that reads
settings.get("env_auto_sync_enabled") uses value.parse().unwrap_or(false) which
conflicts with the intended default true from default_env_auto_sync_enabled(),
Default::default(), and get_env_auto_sync_enabled(); change the fallback to the
canonical default (e.g., use unwrap_or(true) or call
default_env_auto_sync_enabled()) so malformed values produce the same default
true as the rest of the codebase and update the env_auto_sync_enabled assignment
in from_settings_manager accordingly.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree with this one

unwrap_or(false) here and unwrap_or(true) in get_env_auto_sync_enabled mean two different code paths disagree on what happens with a bad stored value. i'd actually go further and suggest both should be false since the whole feature should be opt-in, but at minimum they need to match.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find the get_env_auto_sync_enabled function implementation
rg -n -A 10 "pub async fn get_env_auto_sync_enabled" crates/kftray-commons/src/utils/settings.rs

Length of output: 450


@hcavarsan Good call—auto-writing to the filesystem should definitely be opt-in. I found all four locations that need alignment:

Locations to change from truefalse:

  1. settings_model.rs:80default_env_auto_sync_enabled() currently returns true
  2. settings.rs:616unwrap_or(true) for parse error fallback
  3. settings.rs:618Ok(true) when the setting key is missing

Already correct:
4. settings_model.rs:157from_settings_manager already uses unwrap_or(false)

Would you like me to plan the changes to make all defaults consistently false?


🧬 Code Graph Analysis Results

[crates/kftray-commons/src/utils/settings.rs:263-265]

/// The default() implementation delegates to Self::new().
fn default() -> Self {
    Self::new()
}


if let Some(value) = settings.get("env_auto_sync_path") {
app_settings.env_auto_sync_path = value.clone();
}

app_settings
}

/// Converts this `AppSettings` instance to a key-value map for database storage.
pub fn to_settings_map(&self) -> std::collections::HashMap<String, String> {
let mut settings = std::collections::HashMap::new();

Expand Down Expand Up @@ -193,6 +213,14 @@ impl AppSettings {
self.ssl_ca_auto_install.to_string(),
);
settings.insert("global_shortcut".to_string(), self.global_shortcut.clone());
settings.insert(
"env_auto_sync_enabled".to_string(),
self.env_auto_sync_enabled.to_string(),
);
settings.insert(
"env_auto_sync_path".to_string(),
self.env_auto_sync_path.clone(),
);

settings
}
Expand Down
5 changes: 1 addition & 4 deletions crates/kftray-commons/src/models/tunnel_protocol.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
use std::collections::HashMap;

use serde::{
Deserialize,
Serialize,
};
use serde::{Deserialize, Serialize};

/// Messages sent over WebSocket tunnel
#[derive(Debug, Clone, Serialize, Deserialize)]
Expand Down
5 changes: 1 addition & 4 deletions crates/kftray-commons/src/models/window.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
use std::sync::Arc;
use std::sync::atomic::AtomicBool;

use serde::{
Deserialize,
Serialize,
};
use serde::{Deserialize, Serialize};
use tokio::runtime::Runtime;

pub struct SaveDialogState {
Expand Down
27 changes: 6 additions & 21 deletions crates/kftray-commons/src/utils/config.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,14 @@
use futures::stream::StreamExt;
use log::{
error,
info,
};
use log::{error, info};
use portpicker::pick_unused_port;
use serde_json::json;
use sqlx::{
Row,
SqlitePool,
};

use crate::db::{
create_db_table,
get_db_pool,
};
use sqlx::{Row, SqlitePool};

use crate::db::{create_db_table, get_db_pool};
use crate::hostsfile::HostsFile;
use crate::migration::migrate_configs;
use crate::models::config_model::Config;
use crate::utils::db_mode::{
DatabaseManager,
DatabaseMode,
};
use crate::utils::db_mode::{DatabaseManager, DatabaseMode};
use crate::utils::error::DbError;

pub async fn delete_config_with_pool(id: i64, pool: &SqlitePool) -> Result<(), DbError> {
Expand Down Expand Up @@ -739,10 +727,7 @@ mod tests {
use std::collections::BTreeMap;

use lazy_static::lazy_static;
use serde_json::{
Value,
json,
};
use serde_json::{Value, json};
use sqlx::SqlitePool;
use tokio::sync::Mutex;

Expand Down
6 changes: 1 addition & 5 deletions crates/kftray-commons/src/utils/config_dir.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
use std::{
env,
fs,
path::PathBuf,
};
use std::{env, fs, path::PathBuf};

use anyhow::Result;

Expand Down
10 changes: 2 additions & 8 deletions crates/kftray-commons/src/utils/config_state.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
use log::error;
use sqlx::{
Row,
SqlitePool,
};
use sqlx::{Row, SqlitePool};

use crate::db::get_db_pool;
use crate::models::config_state_model::ConfigState;
use crate::utils::db_mode::{
DatabaseManager,
DatabaseMode,
};
use crate::utils::db_mode::{DatabaseManager, DatabaseMode};

pub async fn update_config_state_with_pool(
config_state: &ConfigState, pool: &SqlitePool,
Expand Down
38 changes: 9 additions & 29 deletions crates/kftray-commons/src/utils/db.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,21 @@
use std::fs::{
self,
File,
};
use std::fs::{self, File};
use std::io::Write;
use std::path::Path;
use std::sync::Arc;
use std::sync::Mutex;

use lazy_static::lazy_static;
use log::{
error,
info,
};
use log::{error, info};
use serde_json::json;
use sqlx::SqlitePool;
use tokio::sync::OnceCell;

use crate::config_dir::{
get_db_file_path,
get_pod_manifest_path,
};
use crate::config_dir::{get_db_file_path, get_pod_manifest_path};
use crate::utils::manifests::{
create_expose_deployment_manifest,
create_expose_ingress_manifest,
create_expose_service_manifest,
create_proxy_deployment_manifest,
expose_deployment_manifest_exists,
expose_ingress_manifest_exists,
expose_service_manifest_exists,
proxy_deployment_manifest_exists,
create_expose_deployment_manifest, create_expose_ingress_manifest,
create_expose_service_manifest, create_proxy_deployment_manifest,
expose_deployment_manifest_exists, expose_ingress_manifest_exists,
expose_service_manifest_exists, proxy_deployment_manifest_exists,
};

lazy_static! {
Expand Down Expand Up @@ -297,22 +284,15 @@ fn create_db_file() -> Result<(), std::io::Error> {
#[cfg(test)]
mod tests {
use std::env;
use std::fs::{
self,
File,
};
use std::fs::{self, File};
use std::sync::Mutex;

use lazy_static::lazy_static;
use sqlx::SqlitePool;
use tempfile::tempdir;

use super::*;
use crate::config_dir::{
get_config_dir,
get_db_file_path,
get_pod_manifest_path,
};
use crate::config_dir::{get_config_dir, get_db_file_path, get_pod_manifest_path};

lazy_static! {
static ref ENV_TEST_MUTEX: Mutex<()> = Mutex::new(());
Expand Down
10 changes: 2 additions & 8 deletions crates/kftray-commons/src/utils/db_mode.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
use std::sync::Arc;
use std::sync::{
LazyLock,
Mutex,
};
use std::sync::{LazyLock, Mutex};

use sqlx::SqlitePool;

use crate::db::{
create_db_table,
get_db_pool,
};
use crate::db::{create_db_table, get_db_pool};

#[derive(Debug, Clone, PartialEq, Default, Copy)]
pub enum DatabaseMode {
Expand Down
Loading