Skip to content

Latest commit

 

History

History
178 lines (122 loc) · 7.66 KB

File metadata and controls

178 lines (122 loc) · 7.66 KB

Contributing Guide

← Home


Before You Start

For significant changes, open a discussion in Discord or file an issue on the source repository before writing code. This avoids duplicated effort and ensures alignment with the roadmap.


Repository Structure

Editor/
├── Domain/             Core types — no Unity dependencies, with one documented
│                       exception: BuildSnapshot.Platform is a UnityEditor.BuildTarget,
│                       since the alternative (a parallel BuildLens-local enum) isn't
│                       worth the indirection for a value that's just stored and displayed.
├── Application/        Coordinator, engines, session manager
├── Analysis/           Build report reading, dependency graph walking, the post-build hook
├── Export/             JSON / CSV export
├── Storage/            Snapshot persistence (.blsnapshot files, index)
├── Demo/               Synthetic dataset, triggered on demand from the menu
├── Presentation/       IMGUI window and panels
│   └── Panels/
└── ToolsStudio.BuildLens.Editor.asmdef

There is no Runtime/ assembly. BuildLens is Editor-only, and an Editor-only tool has no need to ship an empty placeholder Runtime assembly.


Architecture Rules

These rules are enforced at code review. PRs that violate them will not be merged.

Layer Dependency Direction

Presentation → Application → Domain ← Analysis / Storage / Demo
Presentation → Export → Domain
Layer May Reference Must Not Reference
Presentation Application, Domain, Export Analysis, Storage, Demo
Application Domain, Analysis, Storage, Demo Presentation, Export
Analysis / Storage / Demo Domain Presentation, Application, Export
Export Domain Presentation, Application, Analysis, Storage, Demo
Domain Nothing All other layers, Unity Editor, IO — with one narrow, documented exception (see the Repository Structure note on BuildSnapshot.Platform)

Export is the one layer Presentation calls directly rather than through AnalysisCoordinator — the export buttons in the Overview tab call ExportPipeline in place. This is a deliberate, narrow exception: export is a one-shot, read-only operation on data the panel already has, not something that needs to flow through the coordinator's state.

No Analysis Logic in Panels

Panels read from AnalysisViewModel. They never call AssetDatabase, BuildReport, or any analysis engine. If a panel needs data not on the ViewModel, add it to the ViewModel and compute it in AnalysisCoordinator.

No Unity API Calls Outside Analysis / Storage / Export / Demo

AssetDatabase.*, BuildPipeline.*, PlayerSettings.*, EditorUserBuildSettings.*, File.* belong exclusively in Analysis, Storage, Export, or Demo. The exception: EditorApplication.* is used in BuildLensWindow and AnalysisCoordinator for lifecycle management only.

BuildSnapshot Is Immutable, With One Exception

Once created by FinalizeSnapshot(), no property is mutated except IsPinned — pin state is deliberately mutable in place, since reconstructing an entire snapshot to flip one flag would be worse than the exception.

AnalysisViewModel Is Mutated Only by AnalysisCoordinator

No other class may assign properties on AnalysisViewModel. Panels call coordinator methods to change state.


Code Standards

Naming

Element Convention Example
Classes PascalCase DependencyGraph
Interfaces I + PascalCase Not currently used anywhere in the codebase — every type is a static or sealed class. Convention only, for if one is ever introduced.
Methods PascalCase BuildDependencyGraph()
Private fields _camelCase _viewModel, _scroll
Constants k_ prefix k_StorageRoot, BuildLensConstants.k_Version
Enum values PascalCase AssetType.Texture
Local variables camelCase assetNode

Error Handling

  • Analysis/Storage/Export/Demo methods return (result, string error) tuples. Never throw to callers.
  • Application methods catch exceptions from those calls, log via AnalysisCoordinator.Log(), and call SetFailed().
  • Presentation methods wrap coordinator calls in EditorApplication.delayCall.

GUIStyle Creation

Styles must not be created inside Draw() or OnGUI(). All styles are initialised in EnsureStyles(), guarded by a _stylesReady bool. No colour literal outside BuildLensStyles.cs.

File I/O

  • All file writes use atomic temp-then-rename.
  • All file paths use Path.Combine().
  • All text I/O uses explicit Encoding.UTF8 (no BOM).
  • No Windows-specific path separators.

Adding a New Panel

  1. Create Editor/Presentation/Panels/NewPanel.cs in namespace ToolsStudio.BuildLens.Editor.Presentation.Panels.
  2. Implement the panel contract: internal sealed class NewPanel { public void Draw(AnalysisViewModel vm) { } }.
  3. Add a Tab enum value in BuildLensWindow.
  4. Instantiate the panel in BuildLensWindow.OnEnable().
  5. Add the tab button to the toolbar loop.
  6. Add the Draw() call to the switch in OnGUI().
  7. Create a .meta file with a stable GUID.

Adding a New ViewModel Field

  1. Add the property to AnalysisViewModel.cs.
  2. Add the setter call in the appropriate AnalysisCoordinator method.
  3. Confirm no panel Draw() method mutates the field.
  4. If the field must survive domain reloads, persist it in SnapshotStore and reload it in AnalysisCoordinator.ReloadSnapshots().

Adding a New Analysis / Storage / Export / Demo Class

  1. Create the class in Editor/Analysis/, Editor/Storage/, Editor/Export/, or Editor/Demo/ — whichever matches what it does. Don't add a new top-level folder for one class.
  2. Verify no reference to Presentation or Application namespaces.
  3. All public entry points return tuples or result objects — never throw.
  4. Add a unit test in Tests/Editor/ using a mock or serialised fixture.
  5. Call the class from AnalysisCoordinator, not from panels — unless it's a read-only, one-shot operation on data the panel already owns (the precedent is ExportPipeline; see the Layer Dependency Direction note above).

Testing

Tests live in Tests/Editor/ using Unity Test Framework (EditMode). Fixtures (serialised BuildReport outputs, sample .blsnapshot files) live in Tests/Fixtures/.

Each Analysis, Storage, Export, or Demo class should have at minimum:

  • A success path test with representative data.
  • An error path test (null input, missing file, malformed JSON).

Domain types should have invariant tests (constructor validation, computed property accuracy).


Pull Request Process

  1. Fork the repository.
  2. Create a branch: feature/your-feature or fix/issue-description.
  3. Ensure all existing tests pass.
  4. Add tests for any new functionality.
  5. Update the relevant documentation files if the change affects user-visible behaviour or public API.
  6. Open a PR against main with:
    • A description of the change and its motivation
    • Screenshots or Console output if the change affects UI or output format
    • Reference to any related Discord discussion or issue

PRs changing architecture layer boundaries, the .blsnapshot schema, or the export format require a maintainer review before merge.


Support