Skip to content

[#51] Clear error for duplicate SerializedFile/archive names#104

Merged
SkowronskiAndrew merged 2 commits into
mainfrom
issue51
Jul 21, 2026
Merged

[#51] Clear error for duplicate SerializedFile/archive names#104
SkowronskiAndrew merged 2 commits into
mainfrom
issue51

Conversation

@SkowronskiAndrew

Copy link
Copy Markdown
Collaborator

Summary

Fixes #51.

analyze only supports a single build at a time: Unity resolves references between
SerializedFiles by file name, so two files sharing a name are indistinguishable to those
references. Previously, analyzing more than one copy of the same content produced a raw
SQLite Error 19: 'UNIQUE constraint failed: serialized_files.id' that was only visible with
-v, and two archives sharing a name were silently recorded as two ambiguous rows.

This detects those cases and reports a distinctive, self-contained one-line message, skips the
offending file/archive, and continues (counting it as a failed file). The archive-name invariant
is now also enforced at the schema level.

Changes

  • New AnalyzeDuplicateException carrying the colliding name; its message leads with a
    distinctive phrase (Duplicate SerializedFile name / Duplicate archive name) that is
    documented, so a user can find the explanation from the message text.
  • SerializedFileSQLiteWriter tracks already-written SerializedFile ids and archive names and
    rejects a duplicate before the insert (no failed transaction, no reliance on parsing SQLite
    error codes). BeginArchive assigns its id before the check so the caller's EndArchive
    (in its finally) unwinds cleanly rather than masking the exception.
  • SerializedFileParser and AnalyzerTool catch the new exception and print one clean line,
    always visible (not gated on -v).
  • Schema: archives.name is now UNIQUE; user_version bumped 5 → 6.
  • Docs: rewrote the "SQL Constraint Errors" section of command-analyze.md around the new
    messages (why only a single build can be analyzed; expected for AssetBundle variants; analyze
    continues and ignores the duplicate).

Testing

  • dotnet test — full suite green (Analyzer.Tests 62, UnityFileSystem.Tests 425/10 skipped,
    UnityDataTool.Tests 259).
  • New AnalyzeDuplicateNameTests covers the three issue scenarios: loose files with the same
    name, archives with the same name, and differently-named archives (hashed bundle names) that
    share the same inner SerializedFile.
  • Manually verified against the three reproduction folders from the issue: each now prints a
    clean single-line message with no raw SQLite error.

Analyze only supports a single build at a time. A second SerializedFile or
archive with a name already processed used to fail with a raw
'UNIQUE constraint failed' SQLite error (only visible with -v), and two
archives sharing a name were silently recorded as duplicate rows.

Detect these cases and report a distinctive, self-contained one-line message,
skipping the offending file/archive and continuing. Enforce unique archive
names at the schema level (bump user_version to 6) and add tests plus docs.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses issue #51 by detecting duplicate SerializedFile and archive names during analyze, replacing raw SQLite UNIQUE-constraint failures (or silent ambiguity) with a clear, documented, one-line skip message while continuing the run and counting the input as failed.

Changes:

  • Introduces AnalyzeDuplicateException and surfaces it in AnalyzerTool / SerializedFileParser to print a consistent “Duplicate … name …” message (not gated on -v) and continue.
  • Adds in-memory duplicate detection in SerializedFileSQLiteWriter to reject duplicates before inserts/transactions.
  • Enforces archive-name uniqueness in the schema (archives.name UNIQUE), updates docs, and adds regression tests covering the reported scenarios.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
UnityDataTool.Tests/AnalyzeDuplicateNameTests.cs Adds tests covering duplicate loose files, duplicate archive names, and duplicate inner CAB files across differently named bundles.
Documentation/command-analyze.md Reframes the prior “SQL constraint errors” section into the new duplicate-name messages with guidance on single-build analysis.
Analyzer/SQLite/Writers/SerializedFileSQLiteWriter.cs Tracks written archive names and SerializedFile ids and throws AnalyzeDuplicateException before hitting SQLite constraint failures.
Analyzer/SQLite/Parsers/SerializedFileParser.cs Catches AnalyzeDuplicateException for duplicate inner SerializedFiles in archives and prints a clean skip message.
Analyzer/SQLite/Commands/SerializedFile/AddArchive.cs Updates the documented table definition to match the schema’s uniqueness rule.
Analyzer/Resources/Init.sql Makes archives.name unique and bumps schema user_version to 6, with updated commentary.
Analyzer/AnalyzerTool.cs Catches AnalyzeDuplicateException at the top level and prints a clean one-line message while continuing and counting failure.
Analyzer/AnalyzeDuplicateException.cs New exception type carrying duplicate name and archive-vs-SerializedFile context with a self-contained message.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread Documentation/command-analyze.md Outdated
Comment on lines 16 to +20
id INTEGER,
name TEXT,
file_size INTEGER,
PRIMARY KEY (id)
PRIMARY KEY (id),
UNIQUE (name)
Comment on lines 8 to 14
(
id INTEGER,
name TEXT,
file_size INTEGER,
PRIMARY KEY (id)
PRIMARY KEY (id),
UNIQUE (name)
);
Comment on lines +57 to +59
// Case 2 / Case 3: two build folders each contain an archive named "assetbundle" (and "scenes").
// The second archive of each name is rejected before it is opened, so exactly one row per name
// survives and no UNIQUE constraint error is shown.
…comments

- Compare archive names case-sensitively so the code matches the case-sensitive
  archives.name UNIQUE constraint and the name as it exists on the file system
  (drops the OrdinalIgnoreCase set).
- Fix the comparing-builds.md link to be same-folder relative.
- Clarify the schema comment and a test comment.
@SkowronskiAndrew

Copy link
Copy Markdown
Collaborator Author

Addressed the Copilot review in 2e74649:

  • Case-sensitivity mismatch (Init.sql / AddArchive.cs): made archive-name handling case-sensitive rather than adding COLLATE NOCASE. UnityDataTool records archive names as they exist on the file system, so the in-memory duplicate check now uses the default (ordinal) comparer, matching the case-sensitive archives.name UNIQUE constraint. (The legacy lowercasing of AssetBundle names doesn't need to be mirrored here.)
  • Doc link: fixed ../../Documentation/comparing-builds.md → same-folder comparing-builds.md.
  • Test comment: reworded 'before it is opened' → 'before it is recorded (its contents are never processed)', since the archive is mounted before BeginArchive.

Full suite green (Analyzer 62, UnityFileSystem 425/10 skipped, UnityDataTool 259).

@SkowronskiAndrew
SkowronskiAndrew marked this pull request as ready for review July 21, 2026 13:28
@SkowronskiAndrew
SkowronskiAndrew merged commit fb41219 into main Jul 21, 2026
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Provide a clear error message when more than 1 SerializedFile with the same name is analyzed

2 participants