Normalize metadata into metadata per instance and metadata per path (#107)

* Begin the metadata merge trek

* Tidy up path metadata, entry API, begin implementing

* Flesh out use of PathMap Entry API

* Metadata per instance is a go

* Tidy up naming for metadata per instance

* SnapshotMetadata -> SnapshotContext
This commit is contained in:
Lucien Greathouse
2019-01-17 16:48:49 -08:00
committed by GitHub
parent 4cfdc72c00
commit bd3a4a719d
5 changed files with 185 additions and 108 deletions

View File

@@ -28,6 +28,9 @@ use crate::{
RbxSnapshotInstance,
snapshot_from_tree,
},
path_map::PathMap,
// TODO: Move MetadataPerPath into this module?
rbx_session::{MetadataPerPath, MetadataPerInstance},
};
const INIT_MODULE_NAME: &str = "init.lua";
@@ -36,8 +39,8 @@ const INIT_CLIENT_NAME: &str = "init.client.lua";
pub type SnapshotResult<'a> = Result<Option<RbxSnapshotInstance<'a>>, SnapshotError>;
pub struct SnapshotMetadata<'meta> {
pub sync_point_names: &'meta mut HashMap<PathBuf, String>,
pub struct SnapshotContext<'meta> {
pub metadata_per_path: &'meta mut PathMap<MetadataPerPath>,
}
#[derive(Debug, Fail)]
@@ -80,34 +83,34 @@ impl fmt::Display for SnapshotError {
pub fn snapshot_project_tree<'source>(
imfs: &'source Imfs,
metadata: &mut SnapshotMetadata,
context: &mut SnapshotContext,
project: &'source Project,
) -> SnapshotResult<'source> {
snapshot_project_node(imfs, metadata, &project.tree, Cow::Borrowed(&project.name))
snapshot_project_node(imfs, context, &project.tree, Cow::Borrowed(&project.name))
}
fn snapshot_project_node<'source>(
imfs: &'source Imfs,
metadata: &mut SnapshotMetadata,
context: &mut SnapshotContext,
node: &'source ProjectNode,
instance_name: Cow<'source, str>,
) -> SnapshotResult<'source> {
match node {
ProjectNode::Instance(instance_node) => snapshot_instance_node(imfs, metadata, instance_node, instance_name),
ProjectNode::SyncPoint(sync_node) => snapshot_sync_point_node(imfs, metadata, sync_node, instance_name),
ProjectNode::Instance(instance_node) => snapshot_instance_node(imfs, context, instance_node, instance_name),
ProjectNode::SyncPoint(sync_node) => snapshot_sync_point_node(imfs, context, sync_node, instance_name),
}
}
fn snapshot_instance_node<'source>(
imfs: &'source Imfs,
metadata: &mut SnapshotMetadata,
context: &mut SnapshotContext,
node: &'source InstanceProjectNode,
instance_name: Cow<'source, str>,
) -> SnapshotResult<'source> {
let mut children = Vec::new();
for (child_name, child_project_node) in &node.children {
if let Some(child) = snapshot_project_node(imfs, metadata, child_project_node, Cow::Borrowed(child_name))? {
if let Some(child) = snapshot_project_node(imfs, context, child_project_node, Cow::Borrowed(child_name))? {
children.push(child);
}
}
@@ -117,18 +120,20 @@ fn snapshot_instance_node<'source>(
name: instance_name,
properties: node.properties.clone(),
children,
source_path: None,
metadata: Some(node.metadata.clone()),
metadata: MetadataPerInstance {
source_path: None,
ignore_unknown_instances: node.metadata.ignore_unknown_instances,
},
}))
}
fn snapshot_sync_point_node<'source>(
imfs: &'source Imfs,
metadata: &mut SnapshotMetadata,
context: &mut SnapshotContext,
node: &'source SyncPointProjectNode,
instance_name: Cow<'source, str>,
) -> SnapshotResult<'source> {
let maybe_snapshot = snapshot_imfs_path(imfs, metadata, &node.path, Some(instance_name))?;
let maybe_snapshot = snapshot_imfs_path(imfs, context, &node.path, Some(instance_name))?;
// If the snapshot resulted in no instances, like if it targets an unknown
// file or an empty model file, we can early-return.
@@ -138,40 +143,41 @@ fn snapshot_sync_point_node<'source>(
};
// Otherwise, we can log the name of the sync point we just snapshotted.
metadata.sync_point_names.insert(node.path.to_owned(), snapshot.name.clone().into_owned());
let path_meta = context.metadata_per_path.entry(node.path.to_owned()).or_default();
path_meta.instance_name = Some(snapshot.name.clone().into_owned());
Ok(Some(snapshot))
}
pub fn snapshot_imfs_path<'source>(
imfs: &'source Imfs,
metadata: &mut SnapshotMetadata,
context: &mut SnapshotContext,
path: &Path,
instance_name: Option<Cow<'source, str>>,
) -> SnapshotResult<'source> {
// If the given path doesn't exist in the in-memory filesystem, we consider
// that an error.
match imfs.get(path) {
Some(imfs_item) => snapshot_imfs_item(imfs, metadata, imfs_item, instance_name),
Some(imfs_item) => snapshot_imfs_item(imfs, context, imfs_item, instance_name),
None => return Err(SnapshotError::DidNotExist(path.to_owned())),
}
}
fn snapshot_imfs_item<'source>(
imfs: &'source Imfs,
metadata: &mut SnapshotMetadata,
context: &mut SnapshotContext,
item: &'source ImfsItem,
instance_name: Option<Cow<'source, str>>,
) -> SnapshotResult<'source> {
match item {
ImfsItem::File(file) => snapshot_imfs_file(file, instance_name),
ImfsItem::Directory(directory) => snapshot_imfs_directory(imfs, metadata, directory, instance_name),
ImfsItem::Directory(directory) => snapshot_imfs_directory(imfs, context, directory, instance_name),
}
}
fn snapshot_imfs_directory<'source>(
imfs: &'source Imfs,
metadata: &mut SnapshotMetadata,
context: &mut SnapshotContext,
directory: &'source ImfsDirectory,
instance_name: Option<Cow<'source, str>>,
) -> SnapshotResult<'source> {
@@ -187,19 +193,21 @@ fn snapshot_imfs_directory<'source>(
});
let mut snapshot = if directory.children.contains(&init_path) {
snapshot_imfs_path(imfs, metadata, &init_path, Some(snapshot_name))?.unwrap()
snapshot_imfs_path(imfs, context, &init_path, Some(snapshot_name))?.unwrap()
} else if directory.children.contains(&init_server_path) {
snapshot_imfs_path(imfs, metadata, &init_server_path, Some(snapshot_name))?.unwrap()
snapshot_imfs_path(imfs, context, &init_server_path, Some(snapshot_name))?.unwrap()
} else if directory.children.contains(&init_client_path) {
snapshot_imfs_path(imfs, metadata, &init_client_path, Some(snapshot_name))?.unwrap()
snapshot_imfs_path(imfs, context, &init_client_path, Some(snapshot_name))?.unwrap()
} else {
RbxSnapshotInstance {
class_name: Cow::Borrowed("Folder"),
name: snapshot_name,
properties: HashMap::new(),
children: Vec::new(),
source_path: Some(directory.path.to_owned()),
metadata: None,
metadata: MetadataPerInstance {
source_path: Some(directory.path.to_owned()),
ignore_unknown_instances: false,
},
}
};
@@ -215,7 +223,7 @@ fn snapshot_imfs_directory<'source>(
// them here.
},
_ => {
if let Some(child) = snapshot_imfs_path(imfs, metadata, child_path, None)? {
if let Some(child) = snapshot_imfs_path(imfs, context, child_path, None)? {
snapshot.children.push(child);
}
},
@@ -281,8 +289,10 @@ fn snapshot_lua_file<'source>(
},
},
children: Vec::new(),
metadata: None,
source_path: Some(file.path.to_path_buf()),
metadata: MetadataPerInstance {
source_path: Some(file.path.to_path_buf()),
ignore_unknown_instances: false,
},
}))
}
@@ -317,8 +327,10 @@ fn snapshot_txt_file<'source>(
},
},
children: Vec::new(),
metadata: None,
source_path: Some(file.path.to_path_buf()),
metadata: MetadataPerInstance {
source_path: Some(file.path.to_path_buf()),
ignore_unknown_instances: false,
},
}))
}
@@ -348,8 +360,10 @@ fn snapshot_csv_file<'source>(
},
},
children: Vec::new(),
metadata: None,
source_path: Some(file.path.to_path_buf()),
metadata: MetadataPerInstance {
source_path: Some(file.path.to_path_buf()),
ignore_unknown_instances: false,
},
}))
}