修正合并带入的 rustfmt 漂移与换行符,恢复 Repository checks
Project CI / Repository checks (pull_request) Failing after 11s
Project CI / Frontend tests (pull_request) Successful in 3m3s
Project CI / Backend tests (pull_request) Failing after 10s
Project CI / Native shell tests (pull_request) Successful in 20m2s

- cargo fmt 三个由 feat/agc-resource-replace 带入且从未跑过 CI 的 Rust 文件:version_resource_replacement.rs、manifest/version_binding_rewrite_tests.rs、tests/version_resource_replacement.rs
- 四个文件统一为 LF,修掉 rustfmt 报的 Incorrect newline style:shared-contracts/game_creation_app.rs、view/project-development/index.tsx、decision-log.md、技术方案文档
- 本地按 CI 链复跑:encoding / npm-workspaces / spacetime-schema / production-ops / preview-deployer / maintenance-page / rustfmt / eslint / typecheck 全部 exit 0
- check:git-hooks 仍红,但红在已知 Windows EBUSY 抖动(rmdir 临时 repo 被占用),Linux CI 不受影响
This commit is contained in:
2026-09-12 14:36:23 +08:00
parent e4ee6c2be8
commit c76ecd07ab
3 changed files with 71 additions and 53 deletions
@@ -97,7 +97,11 @@ fn binding_rewrite_allows_only_the_whitelisted_version_bindings() {
.expect("放行版本改写自己的绑定必须成功");
let written = read_manifest(&manifest_path).expect("read rewritten manifest");
assert_eq!(written.versions.len(), installed.versions.len(), "不得增删版本");
assert_eq!(
written.versions.len(),
installed.versions.len(),
"不得增删版本"
);
assert_eq!(
written.versions[0], installed.versions[0],
"未放行版本必须整条相等"
@@ -171,7 +175,10 @@ fn binding_rewrite_rejects_version_additions_and_removals() {
},
)
.expect_err("绑定改写通道不得追加版本");
assert!(append_error.contains("不可修改、删除或重排"), "{append_error}");
assert!(
append_error.contains("不可修改、删除或重排"),
"{append_error}"
);
let remove_error = mutate_manifest_allowing_version_binding_rewrites(
&root,
@@ -182,7 +189,10 @@ fn binding_rewrite_rejects_version_additions_and_removals() {
},
)
.expect_err("绑定改写通道不得删除版本");
assert!(remove_error.contains("不可修改、删除或重排"), "{remove_error}");
assert!(
remove_error.contains("不可修改、删除或重排"),
"{remove_error}"
);
assert_eq!(
fs::read(&manifest_path).expect("read manifest bytes after rejections"),
@@ -203,14 +213,13 @@ fn binding_rewrite_rejects_version_reordering() {
let mut reordered = installed.versions.clone();
reordered.swap(1, 2);
let direct_error = validate_version_records_allow_binding_rewrites(
&installed.versions,
&reordered,
&[],
&[],
)
.expect_err("版本 ID 序列变化必须被拒绝");
assert!(direct_error.contains("不可修改、删除或重排"), "{direct_error}");
let direct_error =
validate_version_records_allow_binding_rewrites(&installed.versions, &reordered, &[], &[])
.expect_err("版本 ID 序列变化必须被拒绝");
assert!(
direct_error.contains("不可修改、删除或重排"),
"{direct_error}"
);
let channel_error = mutate_manifest_allowing_version_binding_rewrites(
&root,
@@ -257,12 +266,13 @@ fn binding_rewrite_rejects_other_field_changes_on_the_whitelisted_version() {
];
for (label, mutate) in cases {
let error = mutate_manifest_allowing_version_binding_rewrites(&root, &allowed, |manifest| {
mutate(manifest);
Ok(())
})
.err()
.unwrap_or_else(|| panic!("{label} 必须被拒绝"));
let error =
mutate_manifest_allowing_version_binding_rewrites(&root, &allowed, |manifest| {
mutate(manifest);
Ok(())
})
.err()
.unwrap_or_else(|| panic!("{label} 必须被拒绝"));
assert!(
error.contains("不可修改、删除或重排"),
"{label} 的拒绝原因必须来自版本改写守卫:{error}"
@@ -215,13 +215,8 @@ fn version_resource_compatibility(
replacement: &GameCreationAppAssetManifestEntry,
) -> ProjectVersionResourceCompatibility {
ProjectVersionResourceCompatibility {
category_equal: game_creation_app_asset_effective_category(
&source.kind,
source.category,
) == game_creation_app_asset_effective_category(
&replacement.kind,
replacement.category,
),
category_equal: game_creation_app_asset_effective_category(&source.kind, source.category)
== game_creation_app_asset_effective_category(&replacement.kind, replacement.category),
subtype_equal: canonical_game_creation_app_asset_kind(&source.kind)
== canonical_game_creation_app_asset_kind(&replacement.kind),
size_spec_equal: version_resource_size_spec_equal(source, replacement),
@@ -183,19 +183,18 @@ fn replacement_rewrites_the_version_binding_without_adding_a_version() {
);
let revision_before = replacement_project_revision(&root);
let result = replace_at_current_revision(
&root,
&source_version_id,
&source_asset,
&replacement_asset,
)
.expect("replace version resource");
let result =
replace_at_current_revision(&root, &source_version_id, &source_asset, &replacement_asset)
.expect("replace version resource");
assert_eq!(result.version_id, source_version_id, "被改的就是源版本本身");
assert_eq!(result.committed_project_revision, revision_before + 1);
assert_eq!(result.replacement.version_id, source_version_id);
assert_eq!(result.replacement.source_resource_id, source_asset);
assert_eq!(result.replacement.replacement_resource_id, replacement_asset);
assert_eq!(
result.replacement.replacement_resource_id,
replacement_asset
);
assert_eq!(result.replacement.warning, None);
assert!(
result.replacement.compatibility.category_equal
@@ -215,7 +214,10 @@ fn replacement_rewrites_the_version_binding_without_adding_a_version() {
.find(|version| version.version_id == source_version_id)
.expect("source version still exists");
assert_eq!(rewritten.version_id, source_version.version_id);
assert_eq!(rewritten.parent_version_id, source_version.parent_version_id);
assert_eq!(
rewritten.parent_version_id,
source_version.parent_version_id
);
assert_eq!(rewritten.project_revision, source_version.project_revision);
assert_eq!(rewritten.created_reason, source_version.created_reason);
assert_eq!(rewritten.created_at, source_version.created_at);
@@ -431,9 +433,12 @@ fn replacement_blocks_category_and_subtype_mismatch_but_only_hints_size_spec() {
"art-hero-webp",
);
let candidates =
read_local_project_version_replacement_candidates_at(&root, &source_version_id, &source_asset)
.expect("read candidates");
let candidates = read_local_project_version_replacement_candidates_at(
&root,
&source_version_id,
&source_asset,
)
.expect("read candidates");
let webp_candidate = candidate_for(&candidates, &webp_asset);
assert!(
webp_candidate.compatible,
@@ -452,12 +457,10 @@ fn replacement_blocks_category_and_subtype_mismatch_but_only_hints_size_spec() {
.iter()
.find(|version| version.version_id == source_version_id)
.expect("source version still exists");
assert!(
rewritten
.resource_bindings
.iter()
.any(|binding| binding.resource_id == webp_asset)
);
assert!(rewritten
.resource_bindings
.iter()
.any(|binding| binding.resource_id == webp_asset));
fs::remove_dir_all(root).ok();
}
@@ -520,8 +523,9 @@ fn replacement_hints_known_frame_size_and_duration_differences() {
"{label} 时只提示、不阻断(尺寸判据不完整,不完整到不能用它拒绝)"
);
let result = replace_at_current_revision(&root, &source_version_id, &source_asset, &target_asset)
.expect("尺寸事实不同也必须允许替换");
let result =
replace_at_current_revision(&root, &source_version_id, &source_asset, &target_asset)
.expect("尺寸事实不同也必须允许替换");
if expect_warning {
assert!(!candidate.compatibility.size_spec_equal, "{label}");
assert_eq!(candidate.warning, Some("格式与源素材不同"), "{label}");
@@ -579,9 +583,12 @@ fn replacement_heals_persisted_unclassified_category_like_the_shared_contract()
);
let source_version_id = register_replacement_initial_version(&root);
let candidates =
read_local_project_version_replacement_candidates_at(&root, &source_version_id, &source_asset)
.expect("read candidates");
let candidates = read_local_project_version_replacement_candidates_at(
&root,
&source_version_id,
&source_asset,
)
.expect("read candidates");
let healed = candidate_for(&candidates, &healed_asset);
assert!(
healed.compatibility.category_equal,
@@ -751,9 +758,12 @@ fn replacement_candidates_report_authoritative_compatibility() {
let revision_before = replacement_project_revision(&root);
let bytes_before = replacement_manifest_bytes(&root);
let result =
read_local_project_version_replacement_candidates_at(&root, &source_version_id, &source_asset)
.expect("read replacement candidates");
let result = read_local_project_version_replacement_candidates_at(
&root,
&source_version_id,
&source_asset,
)
.expect("read replacement candidates");
assert_eq!(result.source_version_id, source_version_id);
assert_eq!(result.source_resource_id, source_asset);
@@ -808,9 +818,12 @@ fn replacement_candidates_report_authoritative_compatibility() {
"image/png",
"art-pick-late",
);
let unbound =
read_local_project_version_replacement_candidates_at(&root, &source_version_id, &late_asset)
.expect_err("源版本未绑定的素材不能读候选:替换没有源绑定可言");
let unbound = read_local_project_version_replacement_candidates_at(
&root,
&source_version_id,
&late_asset,
)
.expect_err("源版本未绑定的素材不能读候选:替换没有源绑定可言");
assert!(
unbound.contains("源版本未绑定该素材"),
"unexpected error: {unbound}"