feat(startup): wire startup repo path from CLI to UI
The app now supports opening a repository at startup by reading a --repo argument and passing the path to the UI. A new startup repository state is managed in the backend and exposed via a tauri command and event, enabling the frontend to auto-open the repository when ready. The UI adds a small startup flow with retry handling to ensure the path is consumed once available. - Reads --repo or --repo=PATH and resolves relative paths - Signals UI to open startup repo via open-startup-repository - Frontend retries opening the repo until it succeeds
This commit is contained in:
+86
-3
@@ -31,9 +31,79 @@ use git::{
|
||||
stash_drop, stash_pop, stash_push, undo_last_commit, unlock_worktree, unstage_files,
|
||||
update_remote,
|
||||
};
|
||||
use tauri::Manager;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Mutex;
|
||||
use tauri::{Emitter, Manager};
|
||||
use telemetry::{emit_frontend_log, emit_frontend_span, set_telemetry_enabled};
|
||||
|
||||
struct StartupRepository(Mutex<Option<String>>);
|
||||
|
||||
fn repository_path_from_args(args: impl IntoIterator<Item = String>, cwd: &Path) -> Option<String> {
|
||||
let mut args = args.into_iter();
|
||||
let mut repository = None;
|
||||
|
||||
while let Some(arg) = args.next() {
|
||||
if arg == "--repo" {
|
||||
repository = args.next();
|
||||
break;
|
||||
}
|
||||
if let Some(path) = arg.strip_prefix("--repo=") {
|
||||
repository = Some(path.to_string());
|
||||
break;
|
||||
}
|
||||
if !arg.starts_with('-') {
|
||||
repository = Some(arg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
repository.filter(|path| !path.trim().is_empty()).map(|path| {
|
||||
let path = PathBuf::from(path);
|
||||
if path.is_absolute() {
|
||||
path
|
||||
} else {
|
||||
cwd.join(path)
|
||||
}
|
||||
.to_string_lossy()
|
||||
.into_owned()
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod startup_repository_tests {
|
||||
use super::repository_path_from_args;
|
||||
use std::path::Path;
|
||||
|
||||
#[test]
|
||||
fn accepts_direct_relative_repository_path() {
|
||||
let path = repository_path_from_args(["projects/repo".to_string()], Path::new("/home/user"));
|
||||
assert_eq!(path.as_deref(), Some("/home/user/projects/repo"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn accepts_repo_option() {
|
||||
let path = repository_path_from_args(
|
||||
["--repo".to_string(), "/projects/repo".to_string()],
|
||||
Path::new("/home/user"),
|
||||
);
|
||||
assert_eq!(path.as_deref(), Some("/projects/repo"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn accepts_repo_equals_option() {
|
||||
let path = repository_path_from_args(
|
||||
["--repo=projects/repo".to_string()],
|
||||
Path::new("/home/user"),
|
||||
);
|
||||
assert_eq!(path.as_deref(), Some("/home/user/projects/repo"));
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn take_startup_repository(state: tauri::State<'_, StartupRepository>) -> Option<String> {
|
||||
state.0.lock().ok()?.take()
|
||||
}
|
||||
|
||||
struct ConsoleLogger;
|
||||
|
||||
impl log::Log for ConsoleLogger {
|
||||
@@ -96,8 +166,19 @@ async fn main() {
|
||||
return;
|
||||
}
|
||||
|
||||
let startup_repository = repository_path_from_args(
|
||||
std::env::args().skip(1),
|
||||
&std::env::current_dir().unwrap_or_default(),
|
||||
);
|
||||
|
||||
let builder = tauri::Builder::default()
|
||||
.plugin(tauri_plugin_single_instance::init(|app, _, _| {
|
||||
.plugin(tauri_plugin_single_instance::init(|app, args, cwd| {
|
||||
if let Some(path) = repository_path_from_args(args.into_iter().skip(1), Path::new(&cwd)) {
|
||||
if let Ok(mut pending) = app.state::<StartupRepository>().0.lock() {
|
||||
*pending = Some(path);
|
||||
}
|
||||
let _ = app.emit("open-startup-repository", ());
|
||||
}
|
||||
#[cfg(desktop)]
|
||||
let _ = app
|
||||
.get_webview_window("main")
|
||||
@@ -112,6 +193,7 @@ async fn main() {
|
||||
})
|
||||
.build(),
|
||||
)
|
||||
.manage(StartupRepository(Mutex::new(startup_repository)))
|
||||
.manage(SearchCancellationState::default())
|
||||
.manage(commit_ai::CommitAiEngine::new())
|
||||
.plugin(tauri_plugin_dialog::init());
|
||||
@@ -226,7 +308,8 @@ async fn main() {
|
||||
close_splashscreen,
|
||||
set_telemetry_enabled,
|
||||
emit_frontend_log,
|
||||
emit_frontend_span
|
||||
emit_frontend_span,
|
||||
take_startup_repository
|
||||
])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
|
||||
Reference in New Issue
Block a user