first pass of merging in warp (doesn't build)
This commit is contained in:
@@ -10,16 +10,17 @@ use std::path::Path;
|
||||
|
||||
use galaxy_core::HostId;
|
||||
use galaxy_util::standardized_path::StandardizedPath;
|
||||
use galaxyui::{AppContext, ModelContext, ModelHandle, SingletonEntity};
|
||||
use galaxyui_core::{AppContext, ModelContext, ModelHandle, SingletonEntity};
|
||||
|
||||
use crate::file_tree_store::FileTreeState;
|
||||
use crate::file_tree_update::RepoMetadataUpdate;
|
||||
use crate::file_tree_update::{MetadataUpdateType, RepoMetadataUpdate};
|
||||
use crate::local_model::{
|
||||
GetContentsArgs, IndexedRepoState, LocalRepoMetadataModel, RepoContent, RepositoryMetadataEvent,
|
||||
GetContentsArgs, IndexedRepoState, LocalRepoMetadataModel, RepoContents,
|
||||
RepositoryMetadataEvent,
|
||||
};
|
||||
use crate::remote_model::{RemoteRepoMetadataModel, RemoteRepositoryMetadataEvent};
|
||||
use crate::repository_identifier::{RemoteRepositoryIdentifier, RepositoryIdentifier};
|
||||
use crate::RepoMetadataError;
|
||||
use crate::{RepoMetadataError, StandingQueryResults, StandingQueryResultsDelta};
|
||||
|
||||
/// Unified events emitted by the [`RepoMetadataModel`] wrapper.
|
||||
///
|
||||
@@ -34,7 +35,17 @@ pub enum RepoMetadataEvent {
|
||||
/// File trees for repositories were updated.
|
||||
FileTreeUpdated { ids: Vec<RepositoryIdentifier> },
|
||||
/// A file tree entry was updated.
|
||||
FileTreeEntryUpdated { id: RepositoryIdentifier },
|
||||
FileTreeEntryUpdated {
|
||||
id: RepositoryIdentifier,
|
||||
/// Specifies whether this event contains a precise delta or requires a conservative
|
||||
/// refresh because the entry was replaced without one.
|
||||
update_type: MetadataUpdateType,
|
||||
},
|
||||
/// Stored standing-query paths changed for a repository.
|
||||
StandingQueryResultsUpdated {
|
||||
id: RepositoryIdentifier,
|
||||
delta: StandingQueryResultsDelta,
|
||||
},
|
||||
/// Updating a repository failed.
|
||||
UpdatingRepositoryFailed { id: RepositoryIdentifier },
|
||||
/// An incremental file tree update is ready to be sent to the remote
|
||||
@@ -88,6 +99,7 @@ impl RepoMetadataModel {
|
||||
|
||||
fn forward_local_event(
|
||||
&mut self,
|
||||
_: ModelHandle<LocalRepoMetadataModel>,
|
||||
event: &RepositoryMetadataEvent,
|
||||
ctx: &mut ModelContext<Self>,
|
||||
) {
|
||||
@@ -110,9 +122,16 @@ impl RepoMetadataModel {
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
RepositoryMetadataEvent::FileTreeEntryUpdated { path } => {
|
||||
RepositoryMetadataEvent::FileTreeEntryUpdated { path, update_type } => {
|
||||
RepoMetadataEvent::FileTreeEntryUpdated {
|
||||
id: RepositoryIdentifier::local(path.clone()),
|
||||
update_type: update_type.clone(),
|
||||
}
|
||||
}
|
||||
RepositoryMetadataEvent::StandingQueryResultsUpdated { path, delta } => {
|
||||
RepoMetadataEvent::StandingQueryResultsUpdated {
|
||||
id: RepositoryIdentifier::local(path.clone()),
|
||||
delta: delta.clone(),
|
||||
}
|
||||
}
|
||||
RepositoryMetadataEvent::UpdatingRepositoryFailed { path } => {
|
||||
@@ -131,6 +150,7 @@ impl RepoMetadataModel {
|
||||
|
||||
fn forward_remote_event(
|
||||
&mut self,
|
||||
_: ModelHandle<RemoteRepoMetadataModel>,
|
||||
event: &RemoteRepositoryMetadataEvent,
|
||||
ctx: &mut ModelContext<Self>,
|
||||
) {
|
||||
@@ -154,9 +174,16 @@ impl RepoMetadataModel {
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
RemoteRepositoryMetadataEvent::FileTreeEntryUpdated { id } => {
|
||||
RemoteRepositoryMetadataEvent::FileTreeEntryUpdated { id, update_type } => {
|
||||
RepoMetadataEvent::FileTreeEntryUpdated {
|
||||
id: RepositoryIdentifier::Remote(id.clone()),
|
||||
update_type: update_type.clone(),
|
||||
}
|
||||
}
|
||||
RemoteRepositoryMetadataEvent::StandingQueryResultsUpdated { id, delta } => {
|
||||
RepoMetadataEvent::StandingQueryResultsUpdated {
|
||||
id: RepositoryIdentifier::Remote(id.clone()),
|
||||
delta: delta.clone(),
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -179,6 +206,21 @@ impl RepoMetadataModel {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn standing_query_results<'a>(
|
||||
&self,
|
||||
id: &RepositoryIdentifier,
|
||||
ctx: &'a AppContext,
|
||||
) -> Option<&'a StandingQueryResults> {
|
||||
match id {
|
||||
RepositoryIdentifier::Local(path) => {
|
||||
self.local.as_ref(ctx).standing_query_results(path)
|
||||
}
|
||||
RepositoryIdentifier::Remote(remote_id) => {
|
||||
self.remote.as_ref(ctx).standing_query_results(remote_id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns whether the given repository is indexed.
|
||||
pub fn has_repository(&self, id: &RepositoryIdentifier, ctx: &AppContext) -> bool {
|
||||
match id {
|
||||
@@ -203,13 +245,42 @@ impl RepoMetadataModel {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a future that resolves once repository indexing has completed at least once.
|
||||
///
|
||||
/// Callers should inspect [`Self::repository_state`] after awaiting this future to see whether
|
||||
/// indexing succeeded or failed.
|
||||
pub fn repository_indexed(
|
||||
&self,
|
||||
id: &RepositoryIdentifier,
|
||||
ctx: &mut ModelContext<Self>,
|
||||
) -> futures::future::BoxFuture<'static, ()> {
|
||||
match id {
|
||||
RepositoryIdentifier::Local(path) => {
|
||||
let path = path.clone();
|
||||
self.local
|
||||
.update(ctx, |local, _| local.repository_indexed(&path))
|
||||
}
|
||||
RepositoryIdentifier::Remote(remote_id) => {
|
||||
let remote_id = remote_id.clone();
|
||||
self.remote
|
||||
.update(ctx, |remote, _| remote.repository_indexed(&remote_id))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns repository contents for the specified repository.
|
||||
///
|
||||
/// The number of returned entries is capped; when the repository contains
|
||||
/// more matching entries, the result is truncated and
|
||||
/// [`RepoContents::truncated`] is set to `true`.
|
||||
///
|
||||
/// Returns an error if the repository is not indexed, indexing is pending, or indexing failed.
|
||||
pub fn get_repo_contents<'a>(
|
||||
&self,
|
||||
id: &RepositoryIdentifier,
|
||||
args: GetContentsArgs,
|
||||
ctx: &'a AppContext,
|
||||
) -> Option<Vec<RepoContent<'a>>> {
|
||||
) -> Result<RepoContents<'a>, RepoMetadataError> {
|
||||
match id {
|
||||
RepositoryIdentifier::Local(path) => {
|
||||
self.local.as_ref(ctx).get_repo_contents(path, args)
|
||||
@@ -234,6 +305,18 @@ impl RepoMetadataModel {
|
||||
// These delegate to the local sub-model. Remote equivalents will be
|
||||
// added once the remote client ↔ server sync layer is in place.
|
||||
|
||||
/// Fully indexes a local directory identified by a standardized path.
|
||||
#[cfg(feature = "local_fs")]
|
||||
pub fn index_local_directory_path(
|
||||
&self,
|
||||
path: &StandardizedPath,
|
||||
ctx: &mut ModelContext<Self>,
|
||||
) -> Result<(), RepoMetadataError> {
|
||||
let path = path.clone();
|
||||
self.local
|
||||
.update(ctx, |local, ctx| local.index_directory_path(&path, ctx))
|
||||
}
|
||||
|
||||
/// Indexes a local repository from the given repository handle.
|
||||
#[cfg(feature = "local_fs")]
|
||||
pub fn index_directory(
|
||||
@@ -272,6 +355,34 @@ impl RepoMetadataModel {
|
||||
})
|
||||
}
|
||||
|
||||
/// Registers paths that must be loaded even when gitignored or beyond the
|
||||
/// tree's size limit.
|
||||
///
|
||||
/// This delegates to the local model because force-included path matching
|
||||
/// happens while building local file trees. Remote repositories receive the
|
||||
/// resulting file-tree metadata over the existing remote sync protocol.
|
||||
pub fn register_force_included_paths(
|
||||
&self,
|
||||
paths: impl IntoIterator<Item = std::path::PathBuf>,
|
||||
ctx: &mut ModelContext<Self>,
|
||||
) {
|
||||
let paths: Vec<_> = paths.into_iter().collect();
|
||||
self.local.update(ctx, |local, _| {
|
||||
local.register_force_included_paths(paths);
|
||||
});
|
||||
}
|
||||
|
||||
pub fn set_project_skill_provider_paths(
|
||||
&self,
|
||||
paths: impl IntoIterator<Item = std::path::PathBuf>,
|
||||
ctx: &mut ModelContext<Self>,
|
||||
) {
|
||||
let paths: Vec<_> = paths.into_iter().collect();
|
||||
self.local.update(ctx, |local, _| {
|
||||
local.set_project_skill_provider_paths(paths);
|
||||
});
|
||||
}
|
||||
|
||||
/// Removes a lazily-loaded local standalone path from tracking.
|
||||
#[cfg(feature = "local_fs")]
|
||||
pub fn remove_lazy_loaded_path(&self, path: &StandardizedPath, ctx: &mut ModelContext<Self>) {
|
||||
@@ -356,7 +467,7 @@ impl RepoMetadataModel {
|
||||
}
|
||||
}
|
||||
|
||||
impl galaxyui::Entity for RepoMetadataModel {
|
||||
impl galaxyui_core::Entity for RepoMetadataModel {
|
||||
type Event = RepoMetadataEvent;
|
||||
}
|
||||
|
||||
@@ -375,4 +486,15 @@ impl RepoMetadataModel {
|
||||
local.insert_test_state(repo_path, state);
|
||||
});
|
||||
}
|
||||
|
||||
pub fn insert_test_standing_results(
|
||||
&self,
|
||||
repo_path: StandardizedPath,
|
||||
standing_results: StandingQueryResults,
|
||||
ctx: &mut ModelContext<Self>,
|
||||
) {
|
||||
self.local.update(ctx, |local, _ctx| {
|
||||
local.insert_test_standing_results(repo_path, standing_results);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user