From acd641e6a32bb9b5907cb26dc9f1186044670f15 Mon Sep 17 00:00:00 2001 From: Dervex Date: Sun, 24 Mar 2024 19:58:55 +0100 Subject: [PATCH] Instance source tracking and meta management, fix `.src` files (WIP) --- CHANGELOG.md | 49 ++++--- src/core/changes.rs | 16 +- src/core/meta.rs | 275 ++++++++++++++++++----------------- src/core/mod.rs | 4 +- src/core/processor.rs | 88 +++++------ src/core/snapshot.rs | 78 ++-------- src/core/tree.rs | 30 ++-- src/middleware/data.rs | 10 +- src/middleware/dir.rs | 14 +- src/middleware/json_model.rs | 4 +- src/middleware/lua.rs | 1 - src/middleware/mod.rs | 65 +++++---- src/middleware/project.rs | 53 ++++--- src/project.rs | 10 +- 14 files changed, 336 insertions(+), 361 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 707a7d6..e1e2290 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,69 +6,72 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), ## [Unreleased] +### Improved + +- Instance source tracking and meta management + +### Fixed + +- `.src` and `init` files + ## [2.0.0-pre5] - 2024-03-22 ### Improved -- `plugin` subcommand now creates directory if the provided one does not exist -- Argon plugin gets installed automatically at the first Argon launch -- Config is now only read once +- `plugin` subcommand now creates directory if the provided one does not exist +- Argon plugin gets installed automatically at the first Argon launch +- Config is now only read once ## [2.0.0-pre4] - 2024-03-21 ### Added -- `plugin` subcommand that installs Argon plugin locally -- Argon CLI and plugin updater -- More customization with global config +- `plugin` subcommand that installs Argon plugin locally +- Argon CLI and plugin updater +- More customization with global config ### Changed -- `run` subcommand is now `serve` -- Changed default project name from `.argon.project.json` to `default.project.json` +- `run` subcommand is now `serve` +- Changed default project name from `.argon.project.json` to `default.project.json` ### Fixed -- Sync rules no longer ignore specified project path, reported by [@Arid](https://github.com/AridAjd) and [@EthanMichalicek](https://github.com/EthanMichalicek) in [#23](https://github.com/argon-rbx/argon/issues/23) +- Sync rules no longer ignore specified project path, reported by [@Arid](https://github.com/AridAjd) and [@EthanMichalicek](https://github.com/EthanMichalicek) in [#23](https://github.com/argon-rbx/argon/issues/23) ## [2.0.0-pre3] - 2024-03-19 ### Changed -- `run_async` option is now disabled by default +- `run_async` option is now disabled by default ### Improved -- Free port searching speed -- Subcommand descriptions +- Free port searching speed +- Subcommand descriptions ### Fixed -- Path canonicalization on Windows -- Session management on Windows -- Crash reporting on Windows -- Release workflow +- Path canonicalization on Windows +- Session management on Windows +- Crash reporting on Windows +- Release workflow ## [2.0.0-pre2] - 2024-03-18 ### Fixed -- Argon installer not working properly with GitHub Actions +- Argon installer not working properly with GitHub Actions ## [2.0.0-pre1] - 2024-03-18 ### Added -- Brand new Argon CLI, written in Rust +- Brand new Argon CLI, written in Rust [Unreleased]: https://github.com/argon-rbx/argon/compare/2.0.0-pre5...HEAD - [2.0.0-pre5]: https://github.com/argon-rbx/argon/compare/2.0.0-pre4...2.0.0-pre5 - [2.0.0-pre4]: https://github.com/argon-rbx/argon/compare/2.0.0-pre3...2.0.0-pre4 - [2.0.0-pre3]: https://github.com/argon-rbx/argon/compare/2.0.0-pre2...2.0.0-pre3 - [2.0.0-pre2]: https://github.com/argon-rbx/argon/compare/2.0.0-pre1...2.0.0-pre2 - [2.0.0-pre1]: https://github.com/argon-rbx/argon/compare/3057ca895492519fc29e7ab0bd8bdebc86d3e53c...2.0.0-pre1 diff --git a/src/core/changes.rs b/src/core/changes.rs index 0ec2861..d060088 100644 --- a/src/core/changes.rs +++ b/src/core/changes.rs @@ -1,4 +1,3 @@ -use log::error; use rbx_dom_weak::types::{Ref, Variant}; use serde::Serialize; use std::collections::HashMap; @@ -54,20 +53,9 @@ impl Changes { } } - pub fn add(&mut self, mut snapshot: Snapshot, parent: Ref) { - let id = if let Some(id) = snapshot.id { - id - } else { - error!("Attempted to add a snapshot without an ID to changes: {:?}", snapshot); - return; - }; - - // Is this necessary? - snapshot.meta = None; - snapshot.paths.clear(); - + pub fn add(&mut self, snapshot: Snapshot, parent: Ref) { self.additions.push(AddedSnapshot { - id, + id: snapshot.id, parent, name: snapshot.name, class: snapshot.class, diff --git a/src/core/meta.rs b/src/core/meta.rs index c61884a..cf6913a 100644 --- a/src/core/meta.rs +++ b/src/core/meta.rs @@ -1,16 +1,80 @@ use serde::{Deserialize, Serialize}; use std::{ - fmt::{self, Debug, Formatter}, path::{Path, PathBuf}, + sync::OnceLock, }; -use crate::{ext::PathExt, glob::Glob, middleware::FileType, project::Project}; +use crate::{ + ext::PathExt, + glob::Glob, + middleware::FileType, + project::{Project, ProjectNode}, +}; + +#[derive(Debug, Clone, PartialEq)] +pub enum SourceType { + File(PathBuf), + Folder(PathBuf), + Data(PathBuf), + Project(PathBuf, String, ProjectNode), +} + +impl SourceType { + pub fn path(&self) -> &Path { + match self { + SourceType::File(path) => path, + SourceType::Folder(path) => path, + SourceType::Data(path) => path, + SourceType::Project(path, _, _) => path, + } + } +} -#[derive(Clone, Debug, PartialEq)] -pub enum Source { - Single(PathBuf), - Double(PathBuf, PathBuf), - Project(PathBuf, String), +#[derive(Debug, Clone, PartialEq)] +pub struct Source { + sources: Vec, +} + +impl Source { + pub fn new() -> Self { + Self { sources: Vec::new() } + } + + pub fn file(path: &Path) -> Self { + Self { + sources: vec![SourceType::File(path.to_owned())], + } + } + + pub fn folder(path: &Path) -> Self { + Self { + sources: vec![SourceType::Folder(path.to_owned())], + } + } + + pub fn data(path: &Path) -> Self { + Self { + sources: vec![SourceType::Data(path.to_owned())], + } + } + + pub fn project(path: &Path, name: &str, node: ProjectNode) -> Self { + Self { + sources: vec![SourceType::Project(path.to_owned(), name.to_owned(), node)], + } + } + + /// Add second source first entry + pub fn add(&mut self, source: Self) { + if let Some(source) = source.sources.first() { + self.sources.push(source.clone()); + } + } + + /// Get first source path + pub fn path(&self) -> Option<&Path> { + self.sources.first().map(|source| source.path()) + } } #[derive(Debug, Clone)] @@ -131,157 +195,113 @@ impl IgnoreRule { } } -#[derive(Clone, PartialEq)] -pub struct Meta { - /// Instance source that is guaranteed to exist - pub source: Option, +#[derive(Debug, Clone, PartialEq)] +pub struct Context { /// Rules that define how files are synced - pub sync_rules: Vec, + sync_rules: Vec, /// Rules that define which files are ignored - pub ignore_rules: Vec, - /// Whether to keep unknown child instances - pub keep_unknowns: bool, - /// Whether to use Scripts with contexts instead of LocalScripts - pub use_contexts: bool, + ignore_rules: Vec, + /// Whether to use legacy script context + legacy_scripts: bool, } -impl Meta { - // Creating new meta - - pub fn new() -> Self { +impl Context { + fn new() -> Self { Self { - source: None, sync_rules: Vec::new(), ignore_rules: Vec::new(), - keep_unknowns: false, - use_contexts: false, + legacy_scripts: true, } } - pub fn from_project(project: &Project) -> Self { - let sync_rules = if project.sync_rules.is_empty() { - Self::default().sync_rules + pub fn sync_rules(&self) -> &Vec { + if self.sync_rules.is_empty() { + default_sync_rules() } else { - project.sync_rules.clone() - }; - - let ignore_rules = project - .ignore_globs - .clone() - .into_iter() - .map(|glob| IgnoreRule { - pattern: glob, - path: project.workspace_dir.clone(), - }) - .collect(); - - Self { - source: None, // ? - sync_rules, - ignore_rules, - keep_unknowns: project.keep_unknowns, - use_contexts: project.use_contexts, + &self.sync_rules } } - pub fn with_sync_rules(mut self, sync_rules: Vec) -> Self { - self.sync_rules = sync_rules; - self - } - - pub fn with_ignore_rules(mut self, ignore_rules: Vec) -> Self { - self.ignore_rules = ignore_rules; - self - } - - // Overwriting meta fields - - pub fn set_sync_rules(&mut self, sync_rules: Vec) { - self.sync_rules = sync_rules; - } - - pub fn set_ignore_rules(&mut self, ignore_rules: Vec) { - self.ignore_rules = ignore_rules; + pub fn sync_rules_of_type(&self, file_type: &FileType) -> Vec<&SyncRule> { + self.sync_rules() + .iter() + .filter(|rule| rule.file_type == *file_type) + .collect() } - // Adding to meta fields - - pub fn add_sync_rule(&mut self, sync_rule: SyncRule) { - self.sync_rules.push(sync_rule); + pub fn ignore_rules(&self) -> &Vec { + &self.ignore_rules } - pub fn add_ignore_rule(&mut self, ignore_rule: IgnoreRule) { - self.ignore_rules.push(ignore_rule); + pub fn use_legacy_scripts(&self) -> bool { + self.legacy_scripts } +} - // Joining meta fields - - pub fn extend_sync_rules(&mut self, sync_rules: Vec) { - self.sync_rules.extend(sync_rules); - } +#[derive(Debug, Clone, PartialEq)] +pub struct Meta { + /// Instance source that is guaranteed to exist + pub source: Source, + /// Project context + pub context: Context, + /// Whether to keep unknown child instances + pub keep_unknowns: bool, +} - pub fn extend_ignore_rules(&mut self, ignore_rules: Vec) { - self.ignore_rules.extend(ignore_rules); +impl Meta { + pub fn new() -> Self { + Self { + source: Source::new(), + context: Context::new(), + keep_unknowns: false, + } } - pub fn extend(&mut self, meta: Meta) { - self.extend_sync_rules(meta.sync_rules); - self.extend_ignore_rules(meta.ignore_rules); - - // if meta.project_data.is_some() { - // self.project_data = meta.project_data; - // } + pub fn with_source>(mut self, source: S) -> Self { + self.source = source.into(); + self } - // Misc - - pub fn is_empty(&self) -> bool { - self.source.is_none() - && self.sync_rules.is_empty() - && self.ignore_rules.is_empty() - && !self.keep_unknowns - && !self.use_contexts + pub fn with_context(mut self, context: &Context) -> Self { + self.context = context.clone(); + self } - pub fn get_sync_rules(&self, file_type: &FileType) -> Vec<&SyncRule> { - self.sync_rules - .iter() - .filter(|rule| rule.file_type == *file_type) - .collect() + pub fn with_keep_unknowns(mut self, keep_unknowns: bool) -> Self { + self.keep_unknowns = keep_unknowns; + self } -} - -impl Debug for Meta { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - let mut debug = f.debug_struct("Meta"); - - if let Some(source) = &self.source { - debug.field("source", source); - } - - if !self.sync_rules.is_empty() { - debug.field("sync_rules", &self.sync_rules); - } - if !self.ignore_rules.is_empty() { - debug.field("ignore_rules", &self.ignore_rules); - } + pub fn from_project(project: &Project) -> Self { + let ignore_rules = project + .ignore_globs + .clone() + .into_iter() + .map(|glob| IgnoreRule { + pattern: glob, + path: project.workspace_dir.clone(), + }) + .collect(); - if self.keep_unknowns { - debug.field("keep_unknowns", &self.keep_unknowns); - } + let context = Context { + sync_rules: project.sync_rules.clone(), + ignore_rules, + legacy_scripts: project.legacy_scripts, + }; - if self.use_contexts { - debug.field("use_contexts", &self.use_contexts); + Self { + source: Source::new(), + context, + keep_unknowns: project.keep_unknowns, } - - debug.finish() } } -impl Default for Meta { - fn default() -> Self { - let sync_rules = vec![ +fn default_sync_rules() -> &'static Vec { + static SYNC_RULES: OnceLock> = OnceLock::new(); + + SYNC_RULES.get_or_init(|| { + vec![ SyncRule::new(FileType::Project) .with_pattern("*.project.json") .with_child_pattern("default.project.json"), @@ -373,11 +393,6 @@ impl Default for Meta { SyncRule::new(FileType::RbxmxModel) .with_pattern("*.rbxmx") .with_child_pattern(".src.rbxmx"), - ]; - - Self { - sync_rules, - ..Self::new() - } - } + ] + }) } diff --git a/src/core/mod.rs b/src/core/mod.rs index 8b1df54..26d61f0 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -40,7 +40,9 @@ impl Core { trace!("Snapshotting root project"); let meta = Meta::from_project(&project); - let snapshot = new_snapshot(&project.path, &meta, &vfs)?; + let snapshot = new_snapshot(&project.path, &meta.context, &vfs)?; + + println!("{:#?}", snapshot); trace!("Building Tree and Queue"); diff --git a/src/core/processor.rs b/src/core/processor.rs index 5d389cf..1a7cfcf 100644 --- a/src/core/processor.rs +++ b/src/core/processor.rs @@ -149,12 +149,14 @@ fn process_changes(id: Ref, tree: &mut Tree, vfs: &Vfs) -> Changes { }; // Merge all meta entries associated with the given `id` - let meta = tree.get_meta_all(id).into_iter().fold(Meta::new(), |mut acc, meta| { - acc.extend(meta.clone()); - acc - }); + // let meta = tree.get_meta_all(id).into_iter().fold(Meta::new(), |mut acc, meta| { + // acc.extend(meta.clone()); + // acc + // }); - let snapshot = match new_snapshot(path, &meta, vfs) { + let meta = Meta::new(); + + let snapshot = match new_snapshot(path, &meta.context, vfs) { Ok(snapshot) => snapshot, Err(err) => { error!("Failed to process changes: {}, path", err); @@ -177,37 +179,37 @@ fn process_changes(id: Ref, tree: &mut Tree, vfs: &Vfs) -> Changes { fn process_child_changes(id: Ref, mut snapshot: Snapshot, changes: &mut Changes, tree: &mut Tree) { // Update meta if it's different - match (snapshot.meta, tree.get_meta_mut(id)) { - (Some(snapshot_meta), Some(meta)) => { - if snapshot_meta != *meta { - if snapshot_meta.is_empty() { - tree.remove_meta(id); - } else { - *meta = snapshot_meta; - } - } - } - (Some(snapshot_meta), None) => { - tree.insert_meta(id, snapshot_meta); - } - _ => {} - } + // match (snapshot.meta, tree.get_meta_mut(id)) { + // (Some(snapshot_meta), Some(meta)) => { + // if snapshot_meta != *meta { + // if snapshot_meta.is_empty() { + // tree.remove_meta(id); + // } else { + // *meta = snapshot_meta; + // } + // } + // } + // (Some(snapshot_meta), None) => { + // tree.insert_meta(id, snapshot_meta); + // } + // _ => {} + // } // Update paths if they're different let paths: Vec = tree.get_paths(id).into_iter().cloned().collect(); - for path in &paths { - if !snapshot.paths.contains(path) { - tree.remove_path(path, id); - } - } + // for path in &paths { + // if !snapshot.paths.contains(path) { + // tree.remove_path(path, id); + // } + // } - for path in &snapshot.paths { - if !paths.contains(path) { - tree.insert_path(path, id); - } - } + // for path in &snapshot.paths { + // if !paths.contains(path) { + // tree.insert_path(path, id); + // } + // } // Process instance changes @@ -249,13 +251,13 @@ fn process_child_changes(id: Ref, mut snapshot: Snapshot, changes: &mut Changes, // Assign instances with known path to snapshot children if !paths.is_empty() { - for child in snapshot.children.iter_mut() { - if paths.iter().any(|path| child.paths.contains(path)) { - child.set_id(child_id); + // for child in snapshot.children.iter_mut() { + // if paths.iter().any(|path| child.paths.contains(path)) { + // child.set_id(child_id); - continue 'outer; - } - } + // continue 'outer; + // } + // } // Skip instances that are part of the project // but have different paths @@ -297,15 +299,15 @@ fn process_child_changes(id: Ref, mut snapshot: Snapshot, changes: &mut Changes, // Process child changes and find new children for child in snapshot.children { - if let Some(child_id) = child.id { - process_child_changes(child_id, child, changes, tree); - } else { - let mut child = child; + // if let Some(child_id) = child.id { + // process_child_changes(child_id, child, changes, tree); + // } else { + // let mut child = child; - insert_children(&mut child, id, tree); + // insert_children(&mut child, id, tree); - changes.add(child, id); - } + // changes.add(child, id); + // } } } diff --git a/src/core/snapshot.rs b/src/core/snapshot.rs index 1667a55..f459476 100644 --- a/src/core/snapshot.rs +++ b/src/core/snapshot.rs @@ -6,21 +6,15 @@ use serde::Serialize; use std::{ collections::HashMap, fmt::{self, Debug, Formatter}, - path::{Path, PathBuf}, }; use super::meta::Meta; #[derive(Clone, Serialize)] pub struct Snapshot { - // Dom indentification - pub id: Option, - - // For middleware & change processing, not serialized - #[serde(skip)] - pub meta: Option, + pub id: Ref, #[serde(skip)] - pub paths: Vec, + pub meta: Meta, // Roblox related pub name: String, @@ -34,9 +28,8 @@ impl Snapshot { pub fn new() -> Self { Self { - id: None, - meta: None, - paths: Vec::new(), + id: Ref::none(), + meta: Meta::new(), name: String::from(""), class: String::from("Folder"), properties: HashMap::new(), @@ -45,62 +38,48 @@ impl Snapshot { } pub fn with_id(mut self, id: Ref) -> Self { - self.id = Some(id); + self.set_id(id); self } pub fn with_meta(mut self, meta: Meta) -> Self { - self.meta = Some(meta); - self - } - - pub fn with_path(mut self, path: &Path) -> Self { - self.paths.push(path.to_owned()); + self.set_meta(meta); self } pub fn with_name(mut self, name: &str) -> Self { - self.name = name.to_owned(); + self.set_name(name); self } pub fn with_class(mut self, class: &str) -> Self { - self.class = class.to_owned(); + self.set_class(class); self } pub fn with_properties(mut self, properties: HashMap) -> Self { - self.properties = properties; + self.set_properties(properties); self } pub fn with_children(mut self, children: Vec) -> Self { - self.children = children; + self.set_children(children); self } pub fn with_data(mut self, data: Self) -> Self { - if self.class == "Folder" { - self.class = data.class; - } - - self.extend_properties(data.properties); - + self.set_data(data); self } // Overwriting snapshot fields pub fn set_id(&mut self, id: Ref) { - self.id = Some(id); + self.id = id; } pub fn set_meta(&mut self, meta: Meta) { - self.meta = Some(meta); - } - - pub fn set_paths(&mut self, paths: Vec) { - self.paths = paths; + self.meta = meta; } pub fn set_name(&mut self, name: &str) { @@ -125,14 +104,11 @@ impl Snapshot { } self.extend_properties(data.properties); + self.meta.source.add(data.meta.source); } // Adding to snapshot fields - pub fn add_path(&mut self, path: &Path) { - self.paths.push(path.to_owned()); - } - pub fn add_property(&mut self, name: &str, value: Variant) { self.properties.insert(name.to_owned(), value); } @@ -143,10 +119,6 @@ impl Snapshot { // Joining snapshot fields - pub fn extend_paths(&mut self, paths: Vec) { - self.paths.extend(paths); - } - pub fn extend_properties(&mut self, properties: HashMap) { self.properties.extend(properties); } @@ -155,14 +127,6 @@ impl Snapshot { self.children.extend(children); } - pub fn extend_meta(&mut self, meta: Meta) { - if let Some(snapshot_meta) = &mut self.meta { - snapshot_meta.extend(meta); - } else { - self.meta = Some(meta); - } - } - // Based on Rojo's InstanceSnapshot::from_tree (https://github.com/rojo-rbx/rojo/blob/master/src/snapshot/instance_snapshot.rs#L105) pub fn from_dom(dom: WeakDom, id: Ref) -> Self { let (_, mut raw_dom) = dom.into_raw(); @@ -195,18 +159,8 @@ impl Debug for Snapshot { debug.field("name", &self.name); debug.field("class", &self.class); - - if !self.paths.is_empty() { - debug.field("paths", &self.paths); - } - - if let Some(id) = &self.id { - debug.field("id", id); - } - - if let Some(meta) = &self.meta { - debug.field("meta", meta); - } + debug.field("id", &self.id); + debug.field("meta", &self.meta); if !self.properties.is_empty() { let mut properties = self.properties.clone(); diff --git a/src/core/tree.rs b/src/core/tree.rs index d7b67c8..cc5701a 100644 --- a/src/core/tree.rs +++ b/src/core/tree.rs @@ -28,16 +28,18 @@ impl Tree { let root_ref = tree.dom.root_ref(); - tree.id_to_meta.insert(root_ref, snapshot.meta.unwrap()); - - for path in snapshot.paths { - tree.path_to_ids.insert(path, root_ref); + if let Some(path) = snapshot.meta.source.path() { + tree.path_to_ids.insert(path.to_owned(), root_ref); } + tree.id_to_meta.insert(root_ref, snapshot.meta); + for child in snapshot.children { tree.insert_instance(child, root_ref); } + // println!("{:#?}", tree); + tree } @@ -48,15 +50,11 @@ impl Tree { let referent = self.dom.insert(parent, builder); - for path in snapshot.paths { - self.path_to_ids.insert(path, referent); + if let Some(path) = snapshot.meta.source.path() { + self.path_to_ids.insert(path.to_owned(), referent); } - if let Some(meta) = snapshot.meta { - if !meta.is_empty() { - self.id_to_meta.insert(referent, meta); - } - } + self.id_to_meta.insert(referent, snapshot.meta); for child in snapshot.children { self.insert_instance(child, referent); @@ -72,15 +70,11 @@ impl Tree { let referent = self.dom.insert(parent, builder); - for path in snapshot.paths { - self.path_to_ids.insert(path, referent); + if let Some(path) = snapshot.meta.source.path() { + self.path_to_ids.insert(path.to_owned(), referent); } - if let Some(meta) = snapshot.meta { - if !meta.is_empty() { - self.id_to_meta.insert(referent, meta); - } - } + self.id_to_meta.insert(referent, snapshot.meta); referent } diff --git a/src/middleware/data.rs b/src/middleware/data.rs index 1d424c9..f8ed464 100644 --- a/src/middleware/data.rs +++ b/src/middleware/data.rs @@ -5,13 +5,7 @@ use serde::Deserialize; use serde_json::Value; use std::{collections::HashMap, path::Path}; -use crate::{ - core::{meta::Meta, snapshot::Snapshot}, - ext::PathExt, - resolution::UnresolvedValue, - util, - vfs::Vfs, -}; +use crate::{core::snapshot::Snapshot, ext::PathExt, resolution::UnresolvedValue, util, vfs::Vfs}; #[derive(Deserialize, Debug)] struct ArgonData(HashMap); @@ -26,7 +20,7 @@ struct RojoData { } #[profiling::function] -pub fn snapshot_data(path: &Path, _meta: &Meta, vfs: &Vfs) -> Result { +pub fn snapshot_data(path: &Path, vfs: &Vfs) -> Result { let data = vfs.read(path)?; let data: Value = serde_json::from_str(&data)?; diff --git a/src/middleware/dir.rs b/src/middleware/dir.rs index 2265d09..f944b3f 100644 --- a/src/middleware/dir.rs +++ b/src/middleware/dir.rs @@ -3,18 +3,24 @@ use std::path::Path; use super::new_snapshot; use crate::{ - core::{meta::Meta, snapshot::Snapshot}, + core::{ + meta::{Context, Meta, Source}, + snapshot::Snapshot, + }, ext::PathExt, vfs::Vfs, }; #[profiling::function] -pub fn snapshot_dir(path: &Path, meta: &Meta, vfs: &Vfs) -> Result { +pub fn snapshot_dir(path: &Path, context: &Context, vfs: &Vfs) -> Result { let name = path.get_file_name(); - let mut snapshot = Snapshot::new().with_name(name).with_path(path); + + let mut snapshot = Snapshot::new() + .with_name(name) + .with_meta(Meta::new().with_context(context).with_source(Source::folder(path))); for path in vfs.read_dir(path)? { - if let Some(child_snapshot) = new_snapshot(&path, meta, vfs)? { + if let Some(child_snapshot) = new_snapshot(&path, context, vfs)? { snapshot.add_child(child_snapshot); } } diff --git a/src/middleware/json_model.rs b/src/middleware/json_model.rs index fffee39..b639f59 100644 --- a/src/middleware/json_model.rs +++ b/src/middleware/json_model.rs @@ -27,9 +27,7 @@ struct JsonModel { #[profiling::function] pub fn snapshot_json_model(path: &Path, vfs: &Vfs) -> Result { - let model = vfs.read(path)?; - let model: JsonModel = serde_json::from_str(&model)?; - + let model = serde_json::from_str(&vfs.read(path)?)?; let snapshot = walk(model)?; Ok(snapshot) diff --git a/src/middleware/lua.rs b/src/middleware/lua.rs index d37cdb7..7b95e3b 100644 --- a/src/middleware/lua.rs +++ b/src/middleware/lua.rs @@ -59,7 +59,6 @@ pub fn snapshot_lua(path: &Path, vfs: &Vfs, script_type: ScriptType) -> Result Result { + fn middleware(&self, path: &Path, vfs: &Vfs) -> Result { let result = match self { FileType::Project => snapshot_project(path, vfs), - FileType::InstanceData => snapshot_data(path, meta, vfs), + FileType::InstanceData => snapshot_data(path, vfs), // FileType::ServerScript | FileType::ClientScript | FileType::ModuleScript => { snapshot_lua(path, vfs, self.clone().into()) @@ -88,9 +91,9 @@ impl FileType { } /// Returns a snapshot of the given path, `None` if path no longer exists -pub fn new_snapshot(path: &Path, meta: &Meta, vfs: &Vfs) -> Result> { +pub fn new_snapshot(path: &Path, context: &Context, vfs: &Vfs) -> Result> { if BLACKLISTED_PATHS.iter().any(|blacklisted| path.ends_with(blacklisted)) - || meta.ignore_rules.iter().any(|rule| rule.matches(path)) + || context.ignore_rules().iter().any(|rule| rule.matches(path)) { trace!("Snapshot of {} not created: ignored or blacklisted", path.display()); return Ok(None); @@ -104,14 +107,14 @@ pub fn new_snapshot(path: &Path, meta: &Meta, vfs: &Vfs) -> Result Result Result> { - if let Some(resolved) = meta.sync_rules.iter().find_map(|rule| rule.resolve(path)) { +fn new_snapshot_file(path: &Path, context: &Context, vfs: &Vfs) -> Result> { + if let Some(resolved) = context.sync_rules().iter().find_map(|rule| rule.resolve(path)) { let file_type = resolved.file_type; let name = resolved.name; - let mut snapshot = file_type.middleware(path, meta, vfs)?.with_path(path); + let mut snapshot = file_type.middleware(path, vfs)?; if file_type != FileType::Project { snapshot.set_name(&name); + snapshot.set_meta(Meta::new().with_context(context).with_source(Source::file(path))); } - if let Some(instance_data) = get_instance_data(&name, path, meta, vfs)? { + if let Some(instance_data) = get_instance_data(&name, path, context, vfs)? { snapshot.set_data(instance_data); } @@ -154,29 +158,30 @@ fn new_snapshot_file(path: &Path, meta: &Meta, vfs: &Vfs) -> Result Result> { - if let Some(resolved) = meta.sync_rules.iter().find_map(|rule| rule.resolve_child(path)) { +fn new_snapshot_file_child(path: &Path, context: &Context, vfs: &Vfs) -> Result> { + if let Some(resolved) = context.sync_rules().iter().find_map(|rule| rule.resolve_child(path)) { let file_type = resolved.file_type; let name = resolved.name; let parent = path.get_parent(); - let mut snapshot = file_type.middleware(path, meta, vfs)?.with_path(parent); + let mut snapshot = file_type.middleware(path, vfs)?; if file_type != FileType::Project { snapshot.set_name(&name); + snapshot.set_meta(Meta::new().with_context(context).with_source(Source::folder(parent))); for entry in vfs.read_dir(parent)? { if entry == path { continue; } - if let Some(child_snapshot) = new_snapshot(&entry, meta, vfs)? { + if let Some(child_snapshot) = new_snapshot(&entry, context, vfs)? { snapshot.add_child(child_snapshot); } } } - if let Some(instance_data) = get_instance_data(&name, parent, meta, vfs)? { + if let Some(instance_data) = get_instance_data(&name, parent, context, vfs)? { snapshot.set_data(instance_data); } @@ -188,24 +193,27 @@ fn new_snapshot_file_child(path: &Path, meta: &Meta, vfs: &Vfs) -> Result