修复资源依赖本地身份解析
资源依赖图同时索引远端资源身份和 local-asset 本地资源身份 本地 canonical 引用与远端候选去重后再建立依赖连线 补充本地身份解析与候选不歧义回归测试 更新资源自由画板技术方案的依赖身份合同
This commit is contained in:
@@ -400,6 +400,12 @@ pub(crate) fn build_project_resource_graph(
|
||||
.push(resource_ids[0].clone());
|
||||
}
|
||||
|
||||
let resources_by_manifest_asset_id = resource_ids_by_manifest_asset
|
||||
.iter()
|
||||
.filter(|(_, resource_ids)| resource_ids.len() == 1)
|
||||
.map(|(asset_id, resource_ids)| (asset_id.clone(), resource_ids[0].clone()))
|
||||
.collect::<BTreeMap<_, _>>();
|
||||
|
||||
let mut unresolved_reference_resource_ids = BTreeSet::new();
|
||||
let mut reference_edge_by_id = BTreeMap::<String, ProjectResourceReferenceEdge>::new();
|
||||
for (asset_id, target_resource_ids) in &resource_ids_by_manifest_asset {
|
||||
@@ -418,16 +424,32 @@ pub(crate) fn build_project_resource_graph(
|
||||
.filter(|value| !value.is_empty())
|
||||
.collect::<BTreeSet<_>>()
|
||||
{
|
||||
let source_candidates = resources_by_external_id
|
||||
let mut source_candidates = resources_by_external_id
|
||||
.get(external_reference_id)
|
||||
.map(Vec::as_slice)
|
||||
.unwrap_or(&[]);
|
||||
.unwrap_or(&[])
|
||||
.iter()
|
||||
.collect::<BTreeSet<_>>();
|
||||
if let Some(referenced_asset_id) = external_reference_id
|
||||
.strip_prefix("local-asset:")
|
||||
.map(str::trim)
|
||||
.filter(|value| !value.is_empty())
|
||||
{
|
||||
if let Some(source_resource_id) =
|
||||
resources_by_manifest_asset_id.get(referenced_asset_id)
|
||||
{
|
||||
source_candidates.insert(source_resource_id);
|
||||
}
|
||||
}
|
||||
if source_candidates.len() != 1 {
|
||||
unresolved_reference_resource_ids.insert(external_reference_id.to_string());
|
||||
continue;
|
||||
}
|
||||
let source_resource_id = &source_candidates[0];
|
||||
if !resource_by_id.contains_key(source_resource_id)
|
||||
let source_resource_id = source_candidates
|
||||
.iter()
|
||||
.next()
|
||||
.expect("a non-empty candidate set must have one resource");
|
||||
if !resource_by_id.contains_key(source_resource_id.as_str())
|
||||
|| !resource_by_id.contains_key(target_resource_id)
|
||||
{
|
||||
continue;
|
||||
@@ -438,7 +460,7 @@ pub(crate) fn build_project_resource_graph(
|
||||
ProjectResourceReferenceEdge {
|
||||
id,
|
||||
kind: "asset-reference".to_string(),
|
||||
source_resource_id: source_resource_id.clone(),
|
||||
source_resource_id: source_resource_id.to_string(),
|
||||
target_resource_id: target_resource_id.clone(),
|
||||
cyclic: false,
|
||||
},
|
||||
@@ -835,6 +857,75 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn graph_resolves_local_asset_reference_identities() {
|
||||
let manifest = manifest(
|
||||
Vec::new(),
|
||||
vec![
|
||||
asset("source-1", None, &[], None),
|
||||
asset(
|
||||
"derivative-1",
|
||||
Some("local-asset:derivative-1"),
|
||||
&["local-asset:source-1"],
|
||||
None,
|
||||
),
|
||||
],
|
||||
);
|
||||
let graph = build_project_resource_graph(
|
||||
&manifest,
|
||||
vec![
|
||||
resource("asset:source-1", Some("source-1"), None),
|
||||
resource("asset:derivative-1", Some("derivative-1"), None),
|
||||
],
|
||||
&[],
|
||||
false,
|
||||
);
|
||||
|
||||
assert_eq!(graph.reference_edges.len(), 1);
|
||||
assert_eq!(
|
||||
graph.reference_edges[0].source_resource_id,
|
||||
"asset:source-1"
|
||||
);
|
||||
assert_eq!(
|
||||
graph.reference_edges[0].target_resource_id,
|
||||
"asset:derivative-1"
|
||||
);
|
||||
assert!(graph.unresolved_reference_resource_ids.is_empty());
|
||||
assert!(graph
|
||||
.connection_index
|
||||
.iter()
|
||||
.any(|index| index.resource_id == "asset:derivative-1"
|
||||
&& index.upstream_reference_resource_ids == vec!["asset:source-1"]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn graph_resolves_local_asset_identity_without_ambiguous_remote_duplicate() {
|
||||
let manifest = manifest(
|
||||
Vec::new(),
|
||||
vec![
|
||||
asset("source-1", Some("external-source"), &[], None),
|
||||
asset(
|
||||
"derivative-1",
|
||||
Some("local-asset:derivative-1"),
|
||||
&["local-asset:source-1"],
|
||||
None,
|
||||
),
|
||||
],
|
||||
);
|
||||
let graph = build_project_resource_graph(
|
||||
&manifest,
|
||||
vec![
|
||||
resource("asset:source-1", Some("source-1"), None),
|
||||
resource("asset:derivative-1", Some("derivative-1"), None),
|
||||
],
|
||||
&[],
|
||||
false,
|
||||
);
|
||||
|
||||
assert_eq!(graph.reference_edges.len(), 1);
|
||||
assert!(graph.unresolved_reference_resource_ids.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn graph_aggregates_flows_filters_missing_resources_and_detects_cycles_iteratively() {
|
||||
let manifest = manifest(
|
||||
|
||||
Reference in New Issue
Block a user