Skip to content

Commit ead22ff

Browse files
committed
Fixed issues
1 parent 2ec18d0 commit ead22ff

4 files changed

Lines changed: 46 additions & 21 deletions

File tree

Backend/src/lib.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,23 @@ mod validate;
3838
mod workarounds;
3939

4040
/// Loads `Client/.env` for local development without overwriting existing env vars.
41+
///
42+
/// Missing .env file is silently ignored. Malformed or unreadable .env files
43+
/// are reported with context for debugging before structured logging is ready.
4144
fn load_local_dotenv() {
4245
let dotenv_path = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("../.env");
43-
let _ = dotenvy::from_path(&dotenv_path);
46+
47+
match dotenvy::from_path(&dotenv_path) {
48+
Ok(_) => {}
49+
Err(dotenvy::Error::Io(error)) if error.kind() == std::io::ErrorKind::NotFound => {}
50+
Err(err) => {
51+
eprintln!(
52+
"warning: failed to load local .env from {}: {}",
53+
dotenv_path.display(),
54+
err
55+
);
56+
}
57+
}
4458
}
4559

4660
/// Selects preferred backend from settings or first available plugin backend.

Backend/src/tauri_commands/commit.rs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -145,12 +145,10 @@ pub async fn commit_selected<R: Runtime>(
145145
on(VcsEvent::Info {
146146
msg: "Staging selected files…".into(),
147147
});
148-
repo.inner()
149-
.stage_paths(&paths)
150-
.map_err(|e| {
151-
error!("stage_paths failed: {e}");
152-
e.to_string()
153-
})?;
148+
repo.inner().stage_paths(&paths).map_err(|e| {
149+
error!("stage_paths failed: {e}");
150+
e.to_string()
151+
})?;
154152

155153
on(VcsEvent::Info {
156154
msg: "Writing commit…".into(),
@@ -322,12 +320,10 @@ pub async fn commit_patch_and_files<R: Runtime>(
322320
on(VcsEvent::Info {
323321
msg: "Staging selected files…".into(),
324322
});
325-
repo.inner()
326-
.stage_paths(&paths)
327-
.map_err(|e| {
328-
error!("stage_paths failed: {e}");
329-
e.to_string()
330-
})?;
323+
repo.inner().stage_paths(&paths).map_err(|e| {
324+
error!("stage_paths failed: {e}");
325+
e.to_string()
326+
})?;
331327
repo.inner()
332328
.commit(&message, &name, &email, &paths)
333329
.map_err(|e| e.to_string())?

Backend/src/validate.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
// Copyright © 2025-2026 OpenVCS Contributors
22
// SPDX-License-Identifier: GPL-3.0-or-later
33
use std::path::Path;
4+
use std::sync::LazyLock;
5+
6+
/// Regex pattern for scp-like Git URLs.
7+
static SCP_LIKE_RE: LazyLock<regex::Regex> =
8+
LazyLock::new(|| regex::Regex::new(r"^[\w.-]+@[\w.-]+:[\w./-]+\.git$").unwrap());
9+
10+
/// Regex pattern for Windows absolute paths.
11+
static WIN_ABS_RE: LazyLock<regex::Regex> =
12+
LazyLock::new(|| regex::Regex::new(r"^[A-Za-z]:[\\/]").unwrap());
413

514
#[derive(serde::Serialize)]
615
pub struct Validation {
@@ -51,8 +60,7 @@ fn is_probably_git_url(u: &str) -> bool {
5160
return true;
5261
}
5362
// scp-like: git@host:org/repo.git
54-
let scp_like = regex::Regex::new(r"^[\w.-]+@[\w.-]+:[\w./-]+\.git$").unwrap();
55-
if scp_like.is_match(u) {
63+
if SCP_LIKE_RE.is_match(u) {
5664
return true;
5765
}
5866
false
@@ -76,8 +84,7 @@ fn looks_like_path(s: &str) -> bool {
7684
return true;
7785
}
7886
// Windows drive letter absolute, e.g. C:\...
79-
let win_abs = regex::Regex::new(r"^[A-Za-z]:[\\/]").unwrap();
80-
win_abs.is_match(s)
87+
WIN_ABS_RE.is_match(s)
8188
}
8289

8390
/// Validates whether a string looks like a supported Git URL.

Frontend/src/scripts/main.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -390,14 +390,22 @@ async function boot() {
390390
break;
391391
case '__plugin_menu_action__': {
392392
if (!TAURI.has) { notify('Plugin actions are available in the desktop app'); break; }
393-
const pluginId = String(payload?.pluginId || '').trim();
394-
const actionId = String(payload?.actionId || '').trim();
395-
if (!pluginId || !actionId) break;
393+
const pluginId = typeof payload?.pluginId === 'string' ? payload.pluginId.trim() : '';
394+
const actionId = typeof payload?.actionId === 'string' ? payload.actionId.trim() : '';
395+
if (!pluginId || !actionId) {
396+
console.warn(`Plugin menu action skipped: missing pluginId (${!!pluginId}) or actionId (${!!actionId})`);
397+
notify(!pluginId && !actionId
398+
? 'Plugin action is missing plugin and action IDs'
399+
: !pluginId
400+
? 'Plugin action missing plugin ID'
401+
: `Plugin action missing action for "${pluginId}"`);
402+
break;
403+
}
396404
try {
397405
await invokePluginAction(pluginId, actionId);
398406
} catch (e) {
399407
console.error(`Plugin menu action failed: ${pluginId}/${actionId}`, e);
400-
notify('Plugin action failed');
408+
notify(`Plugin action for "${pluginId}" failed`);
401409
}
402410
break;
403411
}

0 commit comments

Comments
 (0)