File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -38,9 +38,23 @@ mod validate;
3838mod 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.
4144fn 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.
Original file line number Diff line number Diff 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 ( ) ) ?
Original file line number Diff line number Diff line change 11// Copyright © 2025-2026 OpenVCS Contributors
22// SPDX-License-Identifier: GPL-3.0-or-later
33use 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 ) ]
615pub 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.
Original file line number Diff line number Diff 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 }
You can’t perform that action at this time.
0 commit comments